From 908d797e7ae19bdeb7bab2d3020df4ce31fe44e1 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Tue, 18 Sep 2012 15:43:58 -0700 Subject: [PATCH 1/6] UT start adding WS support. --- test/server.js | 11 ++++++++++- test/utils.js | 4 ++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/test/server.js b/test/server.js index 0be028cc59..9a939f0147 100644 --- a/test/server.js +++ b/test/server.js @@ -12,6 +12,7 @@ var fs = require("fs"); var path = require("path"); var util = require("util"); var child = require("child_process"); +var WebSocket = require("ws"); var servers = {}; @@ -78,6 +79,14 @@ var makeBase = function(name, done) { }); }; +var wsOpen = function(done) { + var socket = new WebSocket(util.format("ws:://%s:%s", server.websocket_ip, server.websocket_port)); + + socket.on('open') { + done(); + }); +}; + // Prepare the working directory and spawn the server. exports.start = function(name, done) { makeBase(name, function (e) { @@ -86,7 +95,7 @@ exports.start = function(name, done) { } else { serverSpawnSync(name); - done(); + wsOpen(done); } }); }; diff --git a/test/utils.js b/test/utils.js index 0bf10b18ea..e15052294a 100644 --- a/test/utils.js +++ b/test/utils.js @@ -4,7 +4,7 @@ var path = require("path"); var filterErr = function(code, done) { return function (e) { - done(e.code !== code ? e : undefined); + done(e && e.code === code ? undefined : e); }; }; @@ -38,7 +38,7 @@ var mapOr = function(func, array, done) { // Make a directory and sub-directories. var mkPath = function(dirPath, mode, done) { fs.mkdir(dirPath, typeof mode === "string" ? parseInt(mode, 8) : mode, function (e) { - if (!e || e.code === "EEXIST") { + if (!e || e.code === "EEXIST") { // Created or already exists, done. done(); } From 958ea8a6cd5744dbf031a6ca1a4bfa81401348ee Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Tue, 18 Sep 2012 15:44:25 -0700 Subject: [PATCH 2/6] Checking sketch of JS libs. --- js/ledger.js | 34 ++++++++++++++++++++++++++++++++++ js/serializer.js | 44 ++++++++++++++++++++++++++++++++++++++++++++ js/transaction.js | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 js/ledger.js create mode 100644 js/serializer.js create mode 100644 js/transaction.js diff --git a/js/ledger.js b/js/ledger.js new file mode 100644 index 0000000000..42c04fc156 --- /dev/null +++ b/js/ledger.js @@ -0,0 +1,34 @@ +// +// Tools for working with ledger entries. +// +// Fundamentally, we work in the more strict case of not trusting the ledger as presented. If we have a server we trust, then the +// burden of verify the ledger entries is left to the server. But, we work in the same fundamental units of information, ledger +// entries, to keep the code orthagonal. +// + +var serializer = require("./serializer"); + +exports.getLedgerEntry = function(key, done) { + var id = (ws.id += 1); + + ws.response[id] = done; + + ws.send({ + 'command': 'getLedgerEntry', + 'id': id, + 'ledger': ledger, + 'account': accountId, + 'proof': false // Eventually, we will want proof if the server is untrusted. + }); +}; + +exports.getAccountRootNode = function(ledger, accountId, done) { + var s = new Serializer(); + + s.addUInt16('a'); + s.addUInt160(accountId); + + getLedgerEntry(s.getSHA512Half(), done); +}; + +// vim:ts=4 diff --git a/js/serializer.js b/js/serializer.js new file mode 100644 index 0000000000..00f9e070b5 --- /dev/null +++ b/js/serializer.js @@ -0,0 +1,44 @@ +// + +var serializer = {}; + +serializer.addUInt16 = function(value) { + switch (typeof value) { + case 'string': + addUInt16(value.charCodeAt(0)); + break; + + case 'integer': + for (i = 16/8; i; i -=1) { + raw.push(value & 255); + value >>= 8; + } + break; + + default: + throw 'UNEXPECTED_TYPE'; + } +}; + +serializer.addUInt160 = function(value) { + switch (typeof value) { + case 'array': + raw.concat(value); + break; + + case 'integer': + for (i = 160/8; i; i -=1) { + raw.push(value & 255); + value >>= 8; + } + break; + + default: + throw 'UNEXPECTED_TYPE'; + } +}; + +serializer.getSHA512Half = function() { +}; + +// vim:ts=4 diff --git a/js/transaction.js b/js/transaction.js new file mode 100644 index 0000000000..3706a24a1c --- /dev/null +++ b/js/transaction.js @@ -0,0 +1,38 @@ +// Work with transactions. +// +// This works for both trusted and untrusted servers. +// +// For untrusted servers: +// - We never send a secret to an untrusted server. +// - Convert transactions to and from JSON. +// - Sign and verify signatures. +// - Encrypt and decrypt. +// +// For trusted servers: +// - We need a websocket way of working with transactions as JSON. +// - This allows us to not need to port the transaction tools to so many +// languages. +// + +var commands = {}; + +commands.buildSend = function(params) { + var srcAccountID = params.srcAccountID; + var fee = params.fee; + var dstAccountID = params.dstAccountID; + var amount = params.amount; + var sendMax = params.sendMax; + var partial = params.partial; + var limit = params.limit; +}; + + +exports.trustedCreate = function() { + +}; + +exports.untrustedCreate = function() { + +}; + +// vim:ts=4 From 3cd90687930e3b387302d7e8591d0fa782af2ba0 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Fri, 28 Sep 2012 12:44:39 -0700 Subject: [PATCH 3/6] Clean up js. --- js/ledger.js | 34 ---------------------------------- js/transaction.js | 38 -------------------------------------- test/server.js | 1 - 3 files changed, 73 deletions(-) delete mode 100644 js/ledger.js delete mode 100644 js/transaction.js diff --git a/js/ledger.js b/js/ledger.js deleted file mode 100644 index 42c04fc156..0000000000 --- a/js/ledger.js +++ /dev/null @@ -1,34 +0,0 @@ -// -// Tools for working with ledger entries. -// -// Fundamentally, we work in the more strict case of not trusting the ledger as presented. If we have a server we trust, then the -// burden of verify the ledger entries is left to the server. But, we work in the same fundamental units of information, ledger -// entries, to keep the code orthagonal. -// - -var serializer = require("./serializer"); - -exports.getLedgerEntry = function(key, done) { - var id = (ws.id += 1); - - ws.response[id] = done; - - ws.send({ - 'command': 'getLedgerEntry', - 'id': id, - 'ledger': ledger, - 'account': accountId, - 'proof': false // Eventually, we will want proof if the server is untrusted. - }); -}; - -exports.getAccountRootNode = function(ledger, accountId, done) { - var s = new Serializer(); - - s.addUInt16('a'); - s.addUInt160(accountId); - - getLedgerEntry(s.getSHA512Half(), done); -}; - -// vim:ts=4 diff --git a/js/transaction.js b/js/transaction.js deleted file mode 100644 index 3706a24a1c..0000000000 --- a/js/transaction.js +++ /dev/null @@ -1,38 +0,0 @@ -// Work with transactions. -// -// This works for both trusted and untrusted servers. -// -// For untrusted servers: -// - We never send a secret to an untrusted server. -// - Convert transactions to and from JSON. -// - Sign and verify signatures. -// - Encrypt and decrypt. -// -// For trusted servers: -// - We need a websocket way of working with transactions as JSON. -// - This allows us to not need to port the transaction tools to so many -// languages. -// - -var commands = {}; - -commands.buildSend = function(params) { - var srcAccountID = params.srcAccountID; - var fee = params.fee; - var dstAccountID = params.dstAccountID; - var amount = params.amount; - var sendMax = params.sendMax; - var partial = params.partial; - var limit = params.limit; -}; - - -exports.trustedCreate = function() { - -}; - -exports.untrustedCreate = function() { - -}; - -// vim:ts=4 diff --git a/test/server.js b/test/server.js index 83ed044f39..9e20569a58 100644 --- a/test/server.js +++ b/test/server.js @@ -15,7 +15,6 @@ var fs = require("fs"); var path = require("path"); var util = require("util"); var child = require("child_process"); -var WebSocket = require("ws"); var servers = {}; From 7bd25b8688598441db41d9265616fb3829bcfb98 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Fri, 28 Sep 2012 14:59:34 -0700 Subject: [PATCH 4/6] Remove LowID and HighID from ripple state nodes. --- src/LedgerEntrySet.cpp | 12 +++++++----- src/LedgerFormats.cpp | 2 -- src/RippleState.cpp | 6 +++--- src/SerializedLedger.cpp | 27 ++++++++++++++++++--------- src/TransactionAction.cpp | 22 ++++++++++++++-------- src/Version.h | 4 ++-- 6 files changed, 44 insertions(+), 29 deletions(-) diff --git a/src/LedgerEntrySet.cpp b/src/LedgerEntrySet.cpp index dbb364ebca..8588f8f294 100644 --- a/src/LedgerEntrySet.cpp +++ b/src/LedgerEntrySet.cpp @@ -394,10 +394,9 @@ void LedgerEntrySet::calcRawMeta(Serializer& s) if (origNode->getType() == ltRIPPLE_STATE) { - metaNode.addAccount(TMSLowID, origNode->getIValueFieldAccount(sfLowID)); - metaNode.addAccount(TMSHighID, origNode->getIValueFieldAccount(sfHighID)); + metaNode.addAccount(TMSLowID, NewcoinAddress::createAccountID(origNode->getIValueFieldAmount(sfLowLimit).getIssuer())); + metaNode.addAccount(TMSHighID, NewcoinAddress::createAccountID(origNode->getIValueFieldAmount(sfHighLimit).getIssuer())); } - } if (origNode->getType() == ltOFFER) @@ -1011,6 +1010,7 @@ STAmount LedgerEntrySet::rippleTransferFee(const uint160& uSenderID, const uint1 void LedgerEntrySet::rippleCredit(const uint160& uSenderID, const uint160& uReceiverID, const STAmount& saAmount, bool bCheckIssuer) { uint160 uIssuerID = saAmount.getIssuer(); + uint160 uCurrencyID = saAmount.getCurrency(); assert(!bCheckIssuer || uSenderID == uIssuerID || uReceiverID == uIssuerID); @@ -1024,14 +1024,16 @@ void LedgerEntrySet::rippleCredit(const uint160& uSenderID, const uint160& uRece STAmount saBalance = saAmount; + saBalance.setIssuer(ACCOUNT_ONE); + sleRippleState = entryCreate(ltRIPPLE_STATE, uIndex); if (!bFlipped) saBalance.negate(); sleRippleState->setIFieldAmount(sfBalance, saBalance); - sleRippleState->setIFieldAccount(bFlipped ? sfHighID : sfLowID, uSenderID); - sleRippleState->setIFieldAccount(bFlipped ? sfLowID : sfHighID, uReceiverID); + sleRippleState->setIFieldAmount(bFlipped ? sfHighLimit : sfLowLimit, STAmount(uCurrencyID, uSenderID)); + sleRippleState->setIFieldAmount(bFlipped ? sfLowLimit : sfHighLimit, STAmount(uCurrencyID, uReceiverID)); } else { diff --git a/src/LedgerFormats.cpp b/src/LedgerFormats.cpp index 1db310a4c1..fc70296bab 100644 --- a/src/LedgerFormats.cpp +++ b/src/LedgerFormats.cpp @@ -73,9 +73,7 @@ LedgerEntryFormat LedgerFormats[]= { "RippleState", ltRIPPLE_STATE, { { S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 }, { S_FIELD(Balance), STI_AMOUNT, SOE_REQUIRED, 0 }, - { S_FIELD(LowID), STI_ACCOUNT, SOE_REQUIRED, 0 }, { S_FIELD(LowLimit), STI_AMOUNT, SOE_REQUIRED, 0 }, - { S_FIELD(HighID), STI_ACCOUNT, SOE_REQUIRED, 0 }, { S_FIELD(HighLimit), STI_AMOUNT, SOE_REQUIRED, 0 }, { S_FIELD(LastTxnID), STI_HASH256, SOE_REQUIRED, 0 }, { S_FIELD(LastTxnSeq), STI_UINT32, SOE_REQUIRED, 0 }, diff --git a/src/RippleState.cpp b/src/RippleState.cpp index 26a5bb7072..72b9efd10d 100644 --- a/src/RippleState.cpp +++ b/src/RippleState.cpp @@ -7,12 +7,12 @@ RippleState::RippleState(SerializedLedgerEntry::pointer ledgerEntry) : { if (!mLedgerEntry || mLedgerEntry->getType() != ltRIPPLE_STATE) return; - mLowID = mLedgerEntry->getIValueFieldAccount(sfLowID); - mHighID = mLedgerEntry->getIValueFieldAccount(sfHighID); - mLowLimit = mLedgerEntry->getIValueFieldAmount(sfLowLimit); mHighLimit = mLedgerEntry->getIValueFieldAmount(sfHighLimit); + mLowID = NewcoinAddress::createAccountID(mLowLimit.getIssuer()); + mHighID = NewcoinAddress::createAccountID(mHighLimit.getIssuer()); + mLowQualityIn = mLedgerEntry->getIFieldU32(sfLowQualityIn); mLowQualityOut = mLedgerEntry->getIFieldU32(sfLowQualityOut); diff --git a/src/SerializedLedger.cpp b/src/SerializedLedger.cpp index 0353df8b69..08b807890e 100644 --- a/src/SerializedLedger.cpp +++ b/src/SerializedLedger.cpp @@ -128,12 +128,12 @@ NewcoinAddress SerializedLedgerEntry::getOwner() NewcoinAddress SerializedLedgerEntry::getFirstOwner() { - return getIValueFieldAccount(sfLowID); + return NewcoinAddress::createAccountID(getIValueFieldAmount(sfLowLimit).getIssuer()); } NewcoinAddress SerializedLedgerEntry::getSecondOwner() { - return getIValueFieldAccount(sfHighID); + return NewcoinAddress::createAccountID(getIValueFieldAmount(sfHighLimit).getIssuer()); } std::vector SerializedLedgerEntry::getOwners() @@ -146,16 +146,25 @@ std::vector SerializedLedgerEntry::getOwners() switch (getIFieldSType(i)) { case sfAccount: - case sfLowID: - case sfHighID: - { - const STAccount* entry = dynamic_cast(mObject.peekAtPIndex(i)); - if ((entry != NULL) && entry->getValueH160(account)) - owners.push_back(Ledger::getAccountRootIndex(account)); - } + { + const STAccount* entry = dynamic_cast(mObject.peekAtPIndex(i)); + if ((entry != NULL) && entry->getValueH160(account)) + owners.push_back(Ledger::getAccountRootIndex(account)); + } + break; + + case sfLowLimit: + case sfHighLimit: + { + const STAmount* entry = dynamic_cast(mObject.peekAtPIndex(i)); + if ((entry != NULL)) + owners.push_back(Ledger::getAccountRootIndex(entry->getIssuer())); + } + break; default: nothing(); + break; } } diff --git a/src/TransactionAction.cpp b/src/TransactionAction.cpp index f37ef5a31c..786ed762f3 100644 --- a/src/TransactionAction.cpp +++ b/src/TransactionAction.cpp @@ -246,13 +246,13 @@ TER TransactionEngine::doCreditSet(const SerializedTransaction& txn) if (!uDstAccountID) { - Log(lsINFO) << "doCreditSet: Invalid transaction: Destination account not specifed."; + Log(lsINFO) << "doCreditSet: Malformed transaction: Destination account not specifed."; return temDST_NEEDED; } else if (mTxnAccountID == uDstAccountID) { - Log(lsINFO) << "doCreditSet: Invalid transaction: Can not extend credit to self."; + Log(lsINFO) << "doCreditSet: Malformed transaction: Can not extend credit to self."; return temDST_IS_SRC; } @@ -275,6 +275,13 @@ TER TransactionEngine::doCreditSet(const SerializedTransaction& txn) const uint160 uCurrencyID = saLimitAmount.getCurrency(); bool bDelIndex = false; + if (bLimitAmount && saLimitAmount.getIssuer() != mTxnAccountID) + { + Log(lsINFO) << "doCreditSet: Malformed transaction: issuer must be signer"; + + return temBAD_ISSUER; + } + SLE::pointer sleRippleState = entryCache(ltRIPPLE_STATE, Ledger::getRippleStateIndex(mTxnAccountID, uDstAccountID, uCurrencyID)); if (sleRippleState) { @@ -283,8 +290,8 @@ TER TransactionEngine::doCreditSet(const SerializedTransaction& txn) if (!saLimitAmount) { // Zeroing line. - uint160 uLowID = sleRippleState->getIValueFieldAccount(sfLowID).getAccountID(); - uint160 uHighID = sleRippleState->getIValueFieldAccount(sfHighID).getAccountID(); + uint160 uLowID = sleRippleState->getIValueFieldAmount(sfLowLimit).getIssuer(); + uint160 uHighID = sleRippleState->getIValueFieldAmount(sfHighLimit).getIssuer(); bool bLow = uLowID == uSrcAccountID; bool bHigh = uLowID == uDstAccountID; bool bBalanceZero = !sleRippleState->getIValueFieldAmount(sfBalance); @@ -306,7 +313,7 @@ TER TransactionEngine::doCreditSet(const SerializedTransaction& txn) if (!bDelIndex) { if (bLimitAmount) - sleRippleState->setIFieldAmount(bFlipped ? sfHighLimit: sfLowLimit , saLimitAmount); + sleRippleState->setIFieldAmount(bFlipped ? sfHighLimit: sfLowLimit, saLimitAmount); if (!bQualityIn) { @@ -355,9 +362,8 @@ TER TransactionEngine::doCreditSet(const SerializedTransaction& txn) sleRippleState->setIFieldAmount(sfBalance, STAmount(uCurrencyID, ACCOUNT_ONE)); // Zero balance in currency. sleRippleState->setIFieldAmount(bFlipped ? sfHighLimit : sfLowLimit, saLimitAmount); - sleRippleState->setIFieldAmount(bFlipped ? sfLowLimit : sfHighLimit, STAmount(uCurrencyID, ACCOUNT_ONE)); - sleRippleState->setIFieldAccount(bFlipped ? sfHighID : sfLowID, mTxnAccountID); - sleRippleState->setIFieldAccount(bFlipped ? sfLowID : sfHighID, uDstAccountID); + sleRippleState->setIFieldAmount(bFlipped ? sfLowLimit : sfHighLimit, STAmount(uCurrencyID, uDstAccountID)); + if (uQualityIn) sleRippleState->setIFieldU32(bFlipped ? sfHighQualityIn : sfLowQualityIn, uQualityIn); if (uQualityOut) diff --git a/src/Version.h b/src/Version.h index d7cd3a02aa..f35da8166c 100644 --- a/src/Version.h +++ b/src/Version.h @@ -16,11 +16,11 @@ // Version we prefer to speak: #define PROTO_VERSION_MAJOR 0 -#define PROTO_VERSION_MINOR 7 +#define PROTO_VERSION_MINOR 8 // Version we will speak to: #define MIN_PROTO_MAJOR 0 -#define MIN_PROTO_MINOR 7 +#define MIN_PROTO_MINOR 8 #define MAKE_VERSION_INT(maj,min) ((maj << 16) | min) #define GET_VERSION_MAJOR(ver) (ver >> 16) From c74cb38e0915b8b26ce0319af60e342d87381a7e Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Fri, 28 Sep 2012 17:46:32 -0700 Subject: [PATCH 5/6] Do not do SNTP in standalone mode. --- src/Application.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Application.cpp b/src/Application.cpp index 00aea956aa..2011ca8e78 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -73,7 +73,8 @@ void Application::run() boost::thread auxThread(boost::bind(&boost::asio::io_service::run, &mAuxService)); auxThread.detach(); - mSNTPClient.init(theConfig.SNTP_SERVERS); + if (!theConfig.RUN_STANDALONE) + mSNTPClient.init(theConfig.SNTP_SERVERS); // // Construct databases. From 40b51892093394abaff50f26f1c5f5c49c3c49a5 Mon Sep 17 00:00:00 2001 From: MJK Date: Fri, 28 Sep 2012 18:34:42 -0700 Subject: [PATCH 6/6] Changes to logrotate per arthur's comment --- src/RPCServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RPCServer.cpp b/src/RPCServer.cpp index 4028d8496c..91bb578b4b 100644 --- a/src/RPCServer.cpp +++ b/src/RPCServer.cpp @@ -2540,7 +2540,7 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params { "data_fetch", &RPCServer::doDataFetch, 1, 1, true }, { "data_store", &RPCServer::doDataStore, 2, 2, true }, { "ledger", &RPCServer::doLedger, 0, 2, false, optNetwork }, - { "logrotate", &RPCServer::doLogRotate, 0, 0, false, optCurrent }, + { "logrotate", &RPCServer::doLogRotate, 0, 0, true, 0 }, { "nickname_info", &RPCServer::doNicknameInfo, 1, 1, false, optCurrent }, { "nickname_set", &RPCServer::doNicknameSet, 2, 3, false, optCurrent }, { "offer_create", &RPCServer::doOfferCreate, 9, 10, false, optCurrent },