diff --git a/src/Config.cpp b/src/Config.cpp index 3b40d38c69..a1e767cde1 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -26,6 +26,7 @@ #define SECTION_VALIDATION_QUORUM "validation_quorum" #define SECTION_FEE_CREATE "fee_create" #define SECTION_FEE_DEFAULT "fee_default" +#define SECTION_ACCOUNT_PROBE_MAX "account_probe_max" Config theConfig; @@ -60,6 +61,8 @@ Config::Config() FEE_CREATE = DEFAULT_FEE_CREATE; FEE_DEFAULT = DEFAULT_FEE_DEFAULT; + + ACCOUNT_PROBE_MAX = 10; } void Config::load() @@ -120,6 +123,9 @@ void Config::load() if (sectionSingleB(secConfig, SECTION_FEE_DEFAULT, strTemp)) FEE_DEFAULT = boost::lexical_cast(strTemp); + + if (sectionSingleB(secConfig, SECTION_ACCOUNT_PROBE_MAX, strTemp)) + ACCOUNT_PROBE_MAX = boost::lexical_cast(strTemp); } } } diff --git a/src/Config.h b/src/Config.h index ad737bd35b..51290f0bd8 100644 --- a/src/Config.h +++ b/src/Config.h @@ -78,9 +78,12 @@ public: uint64 FEE_CREATE; // Fee to create an account uint64 FEE_DEFAULT; // Default fee. - // configuration parameters + // Configuration parameters std::string DATA_DIR; + // Client behavior + int ACCOUNT_PROBE_MAX; // How far to scan for accounts. + Config(); void load(); diff --git a/src/LedgerFormats.cpp b/src/LedgerFormats.cpp index 55ee30d0ff..df6fb2350e 100644 --- a/src/LedgerFormats.cpp +++ b/src/LedgerFormats.cpp @@ -6,32 +6,32 @@ LedgerEntryFormat LedgerFormats[]= { { "AccountRoot", ltACCOUNT_ROOT, { - { S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 }, - { S_FIELD(Account), STI_ACCOUNT, SOE_REQUIRED, 0 }, - { S_FIELD(Sequence), STI_UINT32, SOE_REQUIRED, 0 }, - { S_FIELD(Balance), STI_AMOUNT, SOE_REQUIRED, 0 }, - { S_FIELD(LastReceive), STI_UINT32, SOE_REQUIRED, 0 }, - { S_FIELD(LastTxn), STI_UINT32, SOE_REQUIRED, 0 }, - { S_FIELD(AuthorizedKey), STI_ACCOUNT, SOE_IFFLAG, 1 }, - { S_FIELD(EmailHash), STI_HASH128, SOE_IFFLAG, 2 }, - { S_FIELD(WalletLocator), STI_HASH256, SOE_IFFLAG, 4 }, - { S_FIELD(MessageKey), STI_VL, SOE_IFFLAG, 8 }, - { S_FIELD(TransitRate), STI_UINT32, SOE_IFFLAG, 16 }, - { S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 }, - { sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } } + { S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 }, + { S_FIELD(Account), STI_ACCOUNT, SOE_REQUIRED, 0 }, + { S_FIELD(Sequence), STI_UINT32, SOE_REQUIRED, 0 }, + { S_FIELD(Balance), STI_AMOUNT, SOE_REQUIRED, 0 }, + { S_FIELD(LastReceive), STI_UINT32, SOE_REQUIRED, 0 }, + { S_FIELD(LastTxn), STI_UINT32, SOE_REQUIRED, 0 }, + { S_FIELD(AuthorizedKey), STI_ACCOUNT, SOE_IFFLAG, 1 }, + { S_FIELD(EmailHash), STI_HASH128, SOE_IFFLAG, 2 }, + { S_FIELD(WalletLocator), STI_HASH256, SOE_IFFLAG, 4 }, + { S_FIELD(MessageKey), STI_VL, SOE_IFFLAG, 8 }, + { S_FIELD(TransitRate), STI_UINT32, SOE_IFFLAG, 16 }, + { S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 }, + { sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } } }, { "DirectoryRoot", ltDIR_ROOT, { - { S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 }, + { S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 }, { S_FIELD(FirstNode), STI_UINT64, SOE_REQUIRED, 0 }, { S_FIELD(LastNode), STI_UINT64, SOE_REQUIRED, 0 }, { S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 }, - { sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } } + { sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } } }, { "DirectoryNode", ltDIR_NODE, { - { S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 }, + { S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 }, { S_FIELD(Indexes), STI_VECTOR256, SOE_REQUIRED, 0 }, { S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 }, - { sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } } + { sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } } }, { "GeneratorMap", ltGENERATOR_MAP, { { S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 }, @@ -41,24 +41,24 @@ LedgerEntryFormat LedgerFormats[]= { sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } } }, { "Nickname", ltNICKNAME, { - { S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 }, - { S_FIELD(Nickname), STI_HASH256, SOE_REQUIRED, 0 }, - { S_FIELD(Account), STI_ACCOUNT, SOE_REQUIRED, 0 }, - { S_FIELD(MinimumOffer), STI_AMOUNT, SOE_IFFLAG, 1 }, - { S_FIELD(OfferCurrency), STI_HASH160, SOE_IFFLAG, 2 }, - { S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 }, - { sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } } + { S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 }, + { S_FIELD(Nickname), STI_HASH256, SOE_REQUIRED, 0 }, + { S_FIELD(Account), STI_ACCOUNT, SOE_REQUIRED, 0 }, + { S_FIELD(MinimumOffer), STI_AMOUNT, SOE_IFFLAG, 1 }, + { S_FIELD(OfferCurrency), STI_HASH160, SOE_IFFLAG, 2 }, + { S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 }, + { sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } } }, { "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(AcceptRate), STI_UINT32, SOE_IFFLAG, 1 }, - { S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 }, - { sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } } + { 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(AcceptRate), STI_UINT32, SOE_IFFLAG, 1 }, + { S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 }, + { sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } } }, { NULL, ltINVALID } }; diff --git a/src/LedgerFormats.h b/src/LedgerFormats.h index d1a18ea4b0..d90d0114d8 100644 --- a/src/LedgerFormats.h +++ b/src/LedgerFormats.h @@ -32,8 +32,12 @@ enum LedgerNameSpace enum LedgerSpecificFlags { - lsfLowIndexed = 0x00010000, - lsfHighIndexed = 0x00020000, + // ltRIPPLE_STATE + lsfLowIndexed = 0x00010000, + lsfHighIndexed = 0x00020000, + + // ltACCOUNT_ROOT + lsfPasswordSpent = 0x00010000, // True if password set fee is spent. }; struct LedgerEntryFormat diff --git a/src/NewcoinAddress.h b/src/NewcoinAddress.h index e0675b37b3..daf30cdb9c 100644 --- a/src/NewcoinAddress.h +++ b/src/NewcoinAddress.h @@ -67,6 +67,10 @@ public: static NewcoinAddress createAccountID(const uint160& uiAccountID); + static std::string createHumanAccountID(const std::vector& vPrivate) { + return createAccountPrivate(vPrivate).humanAccountID(); + } + // // Accounts Public // diff --git a/src/RPCServer.cpp b/src/RPCServer.cpp index d530d87684..73f7670103 100644 --- a/src/RPCServer.cpp +++ b/src/RPCServer.cpp @@ -174,15 +174,15 @@ bool RPCServer::extractString(std::string& param, const Json::Value& params, int } // Get the generator for a regular seed so we may index source accounts from the master public generator. -Json::Value RPCServer::getGenerator(const uint256& uLedger, const NewcoinAddress& naSeed, NewcoinAddress& naMasterGenerator) +Json::Value RPCServer::getMasterGenerator(const uint256& uLedger, const NewcoinAddress& naRegularSeed, NewcoinAddress& naMasterGenerator) { NewcoinAddress naGenerator; - NewcoinAddress na0Public; // To find the generator index. + NewcoinAddress na0Public; // To find the generator's index. NewcoinAddress na0Private; // To decrypt the master generator's cipher. - naGenerator.setFamilyGenerator(naSeed); + naGenerator.setFamilyGenerator(naRegularSeed); na0Public.setAccountPublic(naGenerator, 0); - na0Private.setAccountPrivate(naGenerator, naSeed, 0); + na0Private.setAccountPrivate(naGenerator, naRegularSeed, 0); SLE::pointer sleGen = mNetOps->getGenerator(uLedger, na0Public.getAccountID()); @@ -205,18 +205,25 @@ Json::Value RPCServer::getGenerator(const uint256& uLedger, const NewcoinAddress } // Given a seed and a source account get the public and private key for authorizing transactions for the account. +// --> naRegularSeed : To find the generator +// --> naSrcAccountID : Account we want the public and private regular keys to. +// --> naVerifyGenerator : If provided, the found master public generator must match. +// <-- naAccountPublic : Regular public key for naSrcAccountID +// <-- naAccountPrivate : Regular private key for naSrcAccountID Json::Value RPCServer::authorize(const uint256& uLedger, - const NewcoinAddress& naSeed, const NewcoinAddress& naSrcAccountID, + const NewcoinAddress& naRegularSeed, const NewcoinAddress& naSrcAccountID, NewcoinAddress& naAccountPublic, NewcoinAddress& naAccountPrivate, AccountState::pointer& asSrc, const NewcoinAddress& naVerifyGenerator) { + // Source/paying account must exist. asSrc = mNetOps->getAccountState(uLedger, naSrcAccountID); if (!asSrc) { return JSONRPCError(500, "source account does not exist"); } + // Source must have been claimed. if (!asSrc->bHaveAuthorizedKey()) { return JSONRPCError(500, "source account has not been claimed"); @@ -224,11 +231,12 @@ Json::Value RPCServer::authorize(const uint256& uLedger, NewcoinAddress naMasterGenerator; - Json::Value obj = getGenerator(uLedger, naSeed, naMasterGenerator); + Json::Value obj = getMasterGenerator(uLedger, naRegularSeed, naMasterGenerator); if (!obj.empty()) return obj; + // If naVerifyGenerator is provided, make sure it is the master generator. if (naVerifyGenerator.isValid() && naMasterGenerator != naVerifyGenerator) { std::cerr << "naAccountPublic: wrong seed" << std::endl; @@ -236,9 +244,7 @@ Json::Value RPCServer::authorize(const uint256& uLedger, return JSONRPCError(500, "wrong seed"); } - // // Find the index of the account from the master generator, so we can generate the public and private keys. - // NewcoinAddress naMasterAccountPublic; uint iIndex = -1; // Compensate for initial increment. @@ -253,9 +259,9 @@ Json::Value RPCServer::authorize(const uint256& uLedger, // Use the regular generator to determine the associated public and private keys. NewcoinAddress naGenerator; - naGenerator.setFamilyGenerator(naSeed); + naGenerator.setFamilyGenerator(naRegularSeed); naAccountPublic.setAccountPublic(naGenerator, iIndex); - naAccountPrivate.setAccountPrivate(naGenerator, naSeed, iIndex); + naAccountPrivate.setAccountPrivate(naGenerator, naRegularSeed, iIndex); if (asSrc->getAuthorizedKey().getAccountID() != naAccountPublic.getAccountID()) { @@ -727,12 +733,6 @@ Json::Value RPCServer::doConnect(Json::Value& params) return "connecting"; } -Json::Value RPCServer::doPeers(Json::Value& params) -{ - // peers - return theApp->getConnectionPool().getPeersJson(); -} - // credit_set [] [] Json::Value RPCServer::doCreditSet(Json::Value& params) { @@ -811,6 +811,183 @@ Json::Value RPCServer::doCreditSet(Json::Value& params) } } +// password_fund [] +// YYY Make making account default to first account for seed. +Json::Value RPCServer::doPasswordFund(Json::Value ¶ms) +{ + NewcoinAddress naSrcAccountID; + NewcoinAddress naDstAccountID; + NewcoinAddress naSeed; + uint256 uLedger; + + if (params.size() < 2 || params.size() > 3) + { + return "invalid params"; + } + else if (!naSeed.setFamilySeedGeneric(params[0u].asString())) + { + return "disallowed seed"; + } + else if (!naSrcAccountID.setAccountID(params[1u].asString())) + { + return "bad source account id needed"; + } + else if (!naDstAccountID.setAccountID(params[params.size() == 3 ? 2u : 1u].asString())) + { + return "bad destination account id needed"; + } + else if (!mNetOps->available()) + { + return JSONRPCError(503, "network not available"); + } + else if ((uLedger = mNetOps->getClosedLedger()).isZero()) + { + return JSONRPCError(503, "no closed ledger"); + } + + NewcoinAddress naMasterGenerator; + NewcoinAddress naAccountPublic; + NewcoinAddress naAccountPrivate; + AccountState::pointer asSrc; + Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate, asSrc, naMasterGenerator); + + STAmount saSrcBalance = asSrc->getBalance(); + + if (!obj.empty()) + { + return obj; + } + else if (saSrcBalance < theConfig.FEE_DEFAULT) + { + return JSONRPCError(500, "insufficent funds"); + } + + // YYY Could verify dst exists and isn't already funded. + + Transaction::pointer trans = Transaction::sharedPasswordFund( + naAccountPublic, naAccountPrivate, + naSrcAccountID, + asSrc->getSeq(), + theConfig.FEE_DEFAULT, + 0, // YYY No source tag + naDstAccountID); + + (void) mNetOps->processTransaction(trans); + + obj["transaction"] = trans->getSTransaction()->getJson(0); + obj["status"] = trans->getStatus(); + + return obj; +} + +// password_set [] +Json::Value RPCServer::doPasswordSet(Json::Value& params) +{ + NewcoinAddress naMasterSeed; + NewcoinAddress naRegularSeed; + NewcoinAddress naAccountID; + + if (params.size() < 2 || params.size() > 3) + { + return "invalid params"; + } + else if (!naMasterSeed.setFamilySeedGeneric(params[0u].asString())) + { + // Should also not allow account id's as seeds. + return "master seed expected"; + } + else if (!naRegularSeed.setFamilySeedGeneric(params[1u].asString())) + { + // Should also not allow account id's as seeds. + return "regular seed expected"; + } + // YYY Might use account from string to be more flexible. + else if (params.size() >= 3 && !naAccountID.setAccountID(params[2u].asString())) + { + return "bad account"; + } + else + { + NewcoinAddress naMasterGenerator; + NewcoinAddress naRegularGenerator; + NewcoinAddress naRegular0Public; + NewcoinAddress naRegular0Private; + + NewcoinAddress naAccountPublic; + NewcoinAddress naAccountPrivate; + + naMasterGenerator.setFamilyGenerator(naMasterSeed); + naAccountPublic.setAccountPublic(naMasterGenerator, 0); + naAccountPrivate.setAccountPrivate(naMasterGenerator, naMasterSeed, 0); + + naRegularGenerator.setFamilyGenerator(naRegularSeed); + + naRegular0Public.setAccountPublic(naRegularGenerator, 0); + naRegular0Private.setAccountPrivate(naRegularGenerator, naRegularSeed, 0); + + // Hash of regular account #0 public key. + uint160 uGeneratorID = naRegular0Public.getAccountID(); + std::vector vucGeneratorCipher = naRegular0Private.accountPrivateEncrypt(naRegular0Public, naMasterGenerator.getFamilyGenerator()); + std::vector vucGeneratorSig; + + // Prove that we have the corrisponding private key to the generator id. So, we can get the generator id. + // XXX Check result. + naRegular0Private.accountPrivateSign(Serializer::getSHA512Half(vucGeneratorCipher), vucGeneratorSig); + + NewcoinAddress naMasterXPublic; + NewcoinAddress naRegularXPublic; + uint iIndex = -1; // Compensate for initial increment. + int iMax = theConfig.ACCOUNT_PROBE_MAX; + + // YYY Could probe peridoically to see if accounts exists. + // YYY Max could be set randomly. + // Don't look at ledger entries to determine if the account exists. Don't want to leak to thin server that these accounts are + // related. + do { + ++iIndex; + naMasterXPublic.setAccountPublic(naMasterGenerator, iIndex); + naRegularXPublic.setAccountPublic(naRegularGenerator, iIndex); + + std::cerr << iIndex << ": " << naRegularXPublic.humanAccountID() << std::endl; + + } while (naAccountID.getAccountID() != naMasterXPublic.getAccountID() && --iMax); + + if (!iMax) + { + return "account not found"; + } + + Transaction::pointer trns = Transaction::sharedPasswordSet( + naAccountPublic, naAccountPrivate, + 0, + naRegularXPublic, + vucGeneratorCipher, + naRegular0Public.getAccountPublic(), + vucGeneratorSig); + + (void) mNetOps->processTransaction(trns); + + Json::Value obj(Json::objectValue); + + // We "echo" the seeds so they can be checked. + obj["master_seed"] = naMasterSeed.humanFamilySeed(); + obj["master_key"] = naMasterSeed.humanFamilySeed1751(); + obj["regular_seed"] = naRegularSeed.humanFamilySeed(); + obj["regular_key"] = naRegularSeed.humanFamilySeed1751(); + + obj["transaction"] = trns->getSTransaction()->getJson(0); + obj["status"] = trns->getStatus(); + + return obj; + } +} + +Json::Value RPCServer::doPeers(Json::Value& params) +{ + // peers + return theApp->getConnectionPool().getPeersJson(); +} + // send regular_seed paying_account account_id amount [currency] [send_max] [send_currency] Json::Value RPCServer::doSend(Json::Value& params) { @@ -1183,7 +1360,7 @@ Json::Value RPCServer::doWalletAccounts(Json::Value& params) if (jsonAccounts.empty()) { // No account via seed as master, try seed a regular. - Json::Value ret = getGenerator(uLedger, naSeed, naMasterGenerator); + Json::Value ret = getMasterGenerator(uLedger, naSeed, naMasterGenerator); if (!ret.empty()) return ret; @@ -1379,13 +1556,12 @@ Json::Value RPCServer::doWalletClaim(Json::Value& params) std::vector vucGeneratorCipher = naRegular0Private.accountPrivateEncrypt(naRegular0Public, naMasterGenerator.getFamilyGenerator()); std::vector vucGeneratorSig; - // XXX Check result. // Prove that we have the corrisponding private key to the generator id. So, we can get the generator id. + // XXX Check result. naRegular0Private.accountPrivateSign(Serializer::getSHA512Half(vucGeneratorCipher), vucGeneratorSig); Transaction::pointer trns = Transaction::sharedClaim( naAccountPublic, naAccountPrivate, - naAccountPublic, uSourceTag, vucGeneratorCipher, naRegular0Public.getAccountPublic(), @@ -1700,6 +1876,8 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params if (command == "account_wallet_set") return doAccountWalletSet(params); if (command == "connect") return doConnect(params); if (command == "credit_set") return doCreditSet(params); + if (command == "password_fund") return doPasswordFund(params); + if (command == "password_set") return doPasswordSet(params); if (command == "peers") return doPeers(params); if (command == "send") return doSend(params); if (command == "stop") return doStop(params); diff --git a/src/RPCServer.h b/src/RPCServer.h index 79f80099a7..b42af44aba 100644 --- a/src/RPCServer.h +++ b/src/RPCServer.h @@ -39,8 +39,8 @@ private: int getParamCount(const Json::Value& params); bool extractString(std::string& param, const Json::Value& params, int index); - Json::Value getGenerator(const uint256& uLedger, const NewcoinAddress& naSeed, NewcoinAddress& naMasterGenerator); - Json::Value authorize(const uint256& uLedger, const NewcoinAddress& naSeed, const NewcoinAddress& naSrcAccountID, + Json::Value getMasterGenerator(const uint256& uLedger, const NewcoinAddress& naRegularSeed, NewcoinAddress& naMasterGenerator); + Json::Value authorize(const uint256& uLedger, const NewcoinAddress& naRegularSeed, const NewcoinAddress& naSrcAccountID, NewcoinAddress& naAccountPublic, NewcoinAddress& naAccountPrivate, AccountState::pointer& asSrc, const NewcoinAddress& naVerifyGenerator); @@ -56,6 +56,8 @@ private: Json::Value doConnect(Json::Value& params); Json::Value doCreditSet(Json::Value& params); Json::Value doLedger(Json::Value& params); + Json::Value doPasswordFund(Json::Value& params); + Json::Value doPasswordSet(Json::Value& params); Json::Value doPeers(Json::Value& params); Json::Value doSend(Json::Value& params); Json::Value doSessionClose(Json::Value& params); diff --git a/src/SerializedTypes.cpp b/src/SerializedTypes.cpp index 6b7d9e52b2..1160ea429a 100644 --- a/src/SerializedTypes.cpp +++ b/src/SerializedTypes.cpp @@ -219,7 +219,7 @@ bool STAccount::isValueH160() const void STAccount::setValueH160(const uint160& v) { - peekValue().empty(); + peekValue().clear(); peekValue().insert(peekValue().end(), v.begin(), v.end()); assert(peekValue().size() == (160/8)); } diff --git a/src/Transaction.cpp b/src/Transaction.cpp index 4a60814ffb..303b267a15 100644 --- a/src/Transaction.cpp +++ b/src/Transaction.cpp @@ -180,14 +180,13 @@ Transaction::pointer Transaction::setClaim( Transaction::pointer Transaction::sharedClaim( const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, - const NewcoinAddress& naSourceAccount, uint32 uSourceTag, const std::vector& vucGenerator, const std::vector& vucPubKey, const std::vector& vucSignature) { pointer tResult = boost::make_shared(ttCLAIM, - naPublicKey, naSourceAccount, + naPublicKey, naPublicKey, 0, // Sequence of 0. 0, // Free. uSourceTag); @@ -262,6 +261,72 @@ Transaction::pointer Transaction::sharedCreditSet( return tResult->setCreditSet(naPrivateKey, naDstAccountID, saLimitAmount, uAcceptRate); } +// +// PasswordFund +// + +Transaction::pointer Transaction::setPasswordFund( + const NewcoinAddress& naPrivateKey, + const NewcoinAddress& naDstAccountID) +{ + mTransaction->setITFieldAccount(sfDestination, naDstAccountID); + + sign(naPrivateKey); + + return shared_from_this(); +} + +Transaction::pointer Transaction::sharedPasswordFund( + const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, + const NewcoinAddress& naSourceAccount, + uint32 uSeq, + const STAmount& saFee, + uint32 uSourceTag, + const NewcoinAddress& naDstAccountID) +{ + pointer tResult = boost::make_shared(ttPASSWORD_FUND, naPublicKey, naSourceAccount, uSeq, saFee, uSourceTag); + + return tResult->setPasswordFund(naPrivateKey, naDstAccountID); +} + +// +// PasswordSet +// + +Transaction::pointer Transaction::setPasswordSet( + const NewcoinAddress& naPrivateKey, + const NewcoinAddress& naAuthKeyID, + const std::vector& vucGenerator, + const std::vector& vucPubKey, + const std::vector& vucSignature) +{ + mTransaction->setITFieldAccount(sfAuthorizedKey, naAuthKeyID); + mTransaction->setITFieldVL(sfGenerator, vucGenerator); + mTransaction->setITFieldVL(sfPubKey, vucPubKey); + mTransaction->setITFieldVL(sfSignature, vucSignature); + + sign(naPrivateKey); + + return shared_from_this(); +} + +Transaction::pointer Transaction::sharedPasswordSet( + const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, + uint32 uSourceTag, + const NewcoinAddress& naAuthKeyID, + const std::vector& vucGenerator, + const std::vector& vucPubKey, + const std::vector& vucSignature) +{ + pointer tResult = boost::make_shared(ttPASSWORD_SET, + naPublicKey, naPublicKey, + 0, // Sequence of 0. + 0, // Free. + uSourceTag); + + return tResult->setPasswordSet(naPrivateKey, naAuthKeyID, vucGenerator, vucPubKey, vucSignature); +} + // // Payment // diff --git a/src/Transaction.h b/src/Transaction.h index 9f40951ee4..90cb1b934d 100644 --- a/src/Transaction.h +++ b/src/Transaction.h @@ -61,28 +61,39 @@ private: const std::vector& vucSignature); Transaction::pointer setCreate( - const NewcoinAddress& naPrivateKey, - const NewcoinAddress& naCreateAccountID, - const STAmount& saFund); + const NewcoinAddress& naPrivateKey, + const NewcoinAddress& naCreateAccountID, + const STAmount& saFund); Transaction::pointer setCreditSet( - const NewcoinAddress& naPrivateKey, - const NewcoinAddress& naDstAccountID, - const STAmount& saLimitAmount, - uint32 uAcceptRate); + const NewcoinAddress& naPrivateKey, + const NewcoinAddress& naDstAccountID, + const STAmount& saLimitAmount, + uint32 uAcceptRate); + + Transaction::pointer setPasswordFund( + const NewcoinAddress& naPrivateKey, + const NewcoinAddress& naDstAccountID); + + Transaction::pointer setPasswordSet( + const NewcoinAddress& naPrivateKey, + const NewcoinAddress& naAuthKeyID, + const std::vector& vucGenerator, + const std::vector& vucPubKey, + const std::vector& vucSignature); Transaction::pointer setPayment( - const NewcoinAddress& naPrivateKey, - const NewcoinAddress& naDstAccountID, - const STAmount& saAmount, - const STAmount& saSendMax, - const STPathSet& spPaths); + const NewcoinAddress& naPrivateKey, + const NewcoinAddress& naDstAccountID, + const STAmount& saAmount, + const STAmount& saSendMax, + const STPathSet& spPaths); Transaction::pointer setTransitSet( - const NewcoinAddress& naPrivateKey, - uint32 uTransitRate, - uint32 uTransitStart, - uint32 uTransitExpire); + const NewcoinAddress& naPrivateKey, + uint32 uTransitRate, + uint32 uTransitStart, + uint32 uTransitExpire); Transaction::pointer setWalletAdd( const NewcoinAddress& naPrivateKey, @@ -120,7 +131,6 @@ public: // Claim a wallet. static Transaction::pointer sharedClaim( const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, - const NewcoinAddress& naSourceAccount, uint32 uSourceTag, const std::vector& vucGenerator, const std::vector& vucPubKey, @@ -129,46 +139,64 @@ public: // Create an account. static Transaction::pointer sharedCreate( const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, - const NewcoinAddress& naSourceAccount, - uint32 uSeq, - const STAmount& saFee, - uint32 uSourceTag, - const NewcoinAddress& naCreateAccountID, // Account to create. - const STAmount& saFund); // Initial funds in XNC. + const NewcoinAddress& naSourceAccount, + uint32 uSeq, + const STAmount& saFee, + uint32 uSourceTag, + const NewcoinAddress& naCreateAccountID, // Account to create. + const STAmount& saFund); // Initial funds in XNC. // Set credit limit and borrow fees. static Transaction::pointer sharedCreditSet( const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, - const NewcoinAddress& naSourceAccount, - uint32 uSeq, - const STAmount& saFee, - uint32 uSourceTag, - const NewcoinAddress& naDstAccountID, - const STAmount& saLimitAmount, - uint32 uAcceptRate); + const NewcoinAddress& naSourceAccount, + uint32 uSeq, + const STAmount& saFee, + uint32 uSourceTag, + const NewcoinAddress& naDstAccountID, + const STAmount& saLimitAmount, + uint32 uAcceptRate); + + // Pre-fund password change. + static Transaction::pointer sharedPasswordFund( + const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, + const NewcoinAddress& naSourceAccount, + uint32 uSeq, + const STAmount& saFee, + uint32 uSourceTag, + const NewcoinAddress& naDstAccountID); + + // Change a password. + static Transaction::pointer sharedPasswordSet( + const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, + uint32 uSourceTag, + const NewcoinAddress& naAuthKeyID, // ID of regular public to auth. + const std::vector& vucGenerator, + const std::vector& vucPubKey, + const std::vector& vucSignature); // Make a payment. static Transaction::pointer sharedPayment( const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, - const NewcoinAddress& naSourceAccount, - uint32 uSeq, - const STAmount& saFee, - uint32 uSourceTag, - const NewcoinAddress& naDstAccountID, - const STAmount& saAmount, - const STAmount& saSendMax, - const STPathSet& saPaths); + const NewcoinAddress& naSourceAccount, + uint32 uSeq, + const STAmount& saFee, + uint32 uSourceTag, + const NewcoinAddress& naDstAccountID, + const STAmount& saAmount, + const STAmount& saSendMax, + const STPathSet& saPaths); // Set transit fees. static Transaction::pointer sharedTransitSet( const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, - const NewcoinAddress& naSourceAccount, - uint32 uSeq, - const STAmount& saFee, - uint32 uSourceTag, - uint32 uTransitRate, - uint32 uTransitStart, - uint32 uTransitExpire); + const NewcoinAddress& naSourceAccount, + uint32 uSeq, + const STAmount& saFee, + uint32 uSourceTag, + uint32 uTransitRate, + uint32 uTransitStart, + uint32 uTransitExpire); // Add an account to a wallet. static Transaction::pointer sharedWalletAdd( diff --git a/src/TransactionEngine.cpp b/src/TransactionEngine.cpp index ccfc88be41..fba4c8ab55 100644 --- a/src/TransactionEngine.cpp +++ b/src/TransactionEngine.cpp @@ -10,10 +10,6 @@ #include "utils.h" #include "Log.h" -typedef SerializedLedgerEntry SLE; - - - #define DIR_NODE_MAX 32 // We return the uNodeDir so that on delete we can quickly know where the element is mentioned in the directory. @@ -231,6 +227,64 @@ TransactionEngineResult TransactionEngine::dirDelete( } } +// Set the authorized public ket for an account. May also set the generator map. +TransactionEngineResult TransactionEngine::setAuthorized(const SerializedTransaction& txn, std::vector& accounts, bool bMustSetGenerator) +{ + // + // Verify that submitter knows the private key for the generator. + // Otherwise, people could deny access to generators. + // + + std::vector vucCipher = txn.getITFieldVL(sfGenerator); + std::vector vucPubKey = txn.getITFieldVL(sfPubKey); + std::vector vucSignature = txn.getITFieldVL(sfSignature); + NewcoinAddress naAccountPublic = NewcoinAddress::createAccountPublic(vucPubKey); + + if (!naAccountPublic.accountPublicVerify(Serializer::getSHA512Half(vucCipher), vucSignature)) + { + std::cerr << "createGenerator: bad signature unauthorized generator claim" << std::endl; + + return tenBAD_GEN_AUTH; + } + + // Create generator. + uint160 hGeneratorID = naAccountPublic.getAccountID(); + + LedgerStateParms qry = lepNONE; + SLE::pointer sleGen = mLedger->getGenerator(qry, hGeneratorID); + if (!sleGen) + { + std::cerr << "createGenerator: creating generator" << std::endl; + // Create the generator. + sleGen = boost::make_shared(ltGENERATOR_MAP); + + sleGen->setIndex(Ledger::getGeneratorIndex(hGeneratorID)); + sleGen->setIFieldH160(sfGeneratorID, hGeneratorID); + sleGen->setIFieldVL(sfGenerator, vucCipher); + + accounts.push_back(std::make_pair(taaCREATE, sleGen)); + } + else if (bMustSetGenerator) + { + // Doing a claim. Must set generator. + // Generator is already in use. Regular passphrases limited to one wallet. + std::cerr << "createGenerator: generator already in use" << std::endl; + + return tenGEN_IN_USE; + } + + // Set the public key needed to use the account. + SLE::pointer sleDst = accounts[0].second; + + uint160 uAuthKeyID = bMustSetGenerator + ? hGeneratorID // Claim + : txn.getITFieldAccount(sfAuthorizedKey); // PasswordSet + + sleDst->setIFieldAccount(sfAuthorizedKey, uAuthKeyID); + + return terSUCCESS; +} + TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTransaction& txn, TransactionEngineParams params, uint32 targetLedger) { @@ -297,6 +351,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran switch(txn.getTxnType()) { case ttCLAIM: + case ttPASSWORD_SET: saCost = 0; break; @@ -311,6 +366,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran case ttCREDIT_SET: case ttINVOICE: case ttOFFER: + case ttPASSWORD_FUND: case ttTRANSIT_SET: case ttWALLET_ADD: nothing(); @@ -378,28 +434,64 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran return terNO_ACCOUNT; } - // Consistency: Check signature + // Check if account cliamed. switch (txn.getTxnType()) { case ttCLAIM: - if (naSigningPubKey.getAccountID() != srcAccountID) + if (sleSrc->getIFieldPresent(sfAuthorizedKey)) { - // Signing Pub Key must be for Source Account ID. - std::cerr << "sourceAccountID: " << naSigningPubKey.humanAccountID() << std::endl; - std::cerr << "txn accountID: " << txn.getSourceAccount().humanAccountID() << std::endl; - mLedger = Ledger::pointer(); - return tenINVALID; + std::cerr << "applyTransaction: Account already claimed." << std::endl; + + return tenCLAIMED; } break; default: if (!sleSrc->getIFieldPresent(sfAuthorizedKey)) { - std::cerr << "applyTransaction: Can not use unclaimed account." << std::endl; - mLedger = Ledger::pointer(); + std::cerr << "applyTransaction: Souce is an unclaimed account." << std::endl; + return tenUNCLAIMED; } - else if (naSigningPubKey.getAccountID() != sleSrc->getIValueFieldAccount(sfAuthorizedKey).getAccountID()) + break; + } + + // Consistency: Check signature + switch (txn.getTxnType()) + { + case ttCLAIM: + // Transaction's signing public key must be for the source account. + // To prove the master private key made this transaction. + if (naSigningPubKey.getAccountID() != srcAccountID) + { + // Signing Pub Key must be for Source Account ID. + std::cerr << "sourceAccountID: " << naSigningPubKey.humanAccountID() << std::endl; + std::cerr << "txn accountID: " << txn.getSourceAccount().humanAccountID() << std::endl; + + mLedger = Ledger::pointer(); + + return tenBAD_CLAIM_ID; + } + break; + + case ttPASSWORD_SET: + // Transaction's signing public key must be for the source account. + // To prove the master private key made this transaction. + if (naSigningPubKey.getAccountID() != srcAccountID) + { + // Signing Pub Key must be for Source Account ID. + std::cerr << "sourceAccountID: " << naSigningPubKey.humanAccountID() << std::endl; + std::cerr << "txn accountID: " << txn.getSourceAccount().humanAccountID() << std::endl; + + mLedger = Ledger::pointer(); + + return tenBAD_SET_ID; + } + break; + + default: + // Verify the transaction's signing public key is the key authorized for signing. + if (naSigningPubKey.getAccountID() != sleSrc->getIValueFieldAccount(sfAuthorizedKey).getAccountID()) { std::cerr << "applyTransaction: Not authorized to use account." << std::endl; mLedger = Ledger::pointer(); @@ -497,6 +589,14 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran result = doOffer(txn, accounts); break; + case ttPASSWORD_FUND: + result = doPasswordFund(txn, accounts, srcAccountID); + break; + + case ttPASSWORD_SET: + result = doPasswordSet(txn, accounts); + break; + case ttPAYMENT: result = doPayment(txn, accounts, srcAccountID); break; @@ -522,16 +622,22 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran { if (it->first == taaCREATE) { + std::cerr << "applyTransaction: taaCREATE: " << it->second->getText() << std::endl; + if (mLedger->writeBack(lepCREATE, it->second) & lepERROR) assert(false); } else if (it->first == taaMODIFY) { + std::cerr << "applyTransaction: taaMODIFY: " << it->second->getText() << std::endl; + if (mLedger->writeBack(lepNONE, it->second) & lepERROR) assert(false); } else if (it->first == taaDELETE) { + std::cerr << "applyTransaction: taaDELETE: " << it->second->getText() << std::endl; + if (!mLedger->peekAccountStateMap()->delItem(it->second->getIndex())) assert(false); } @@ -561,13 +667,13 @@ TransactionEngineResult TransactionEngine::doAccountSet(const SerializedTransact if (txFlags & tfUnsetEmailHash) { - std::cerr << "doClaim: unset email hash" << std::endl; + std::cerr << "doAccountSet: unset email hash" << std::endl; sleSrc->makeIFieldAbsent(sfEmailHash); } else if (txn.getITFieldPresent(sfEmailHash)) { - std::cerr << "doClaim: set email hash" << std::endl; + std::cerr << "doAccountSet: set email hash" << std::endl; sleSrc->setIFieldH128(sfEmailHash, txn.getITFieldH128(sfEmailHash)); } @@ -578,13 +684,13 @@ TransactionEngineResult TransactionEngine::doAccountSet(const SerializedTransact if (txFlags & tfUnsetWalletLocator) { - std::cerr << "doClaim: unset wallet locator" << std::endl; + std::cerr << "doAccountSet: unset wallet locator" << std::endl; sleSrc->makeIFieldAbsent(sfWalletLocator); } else if (txn.getITFieldPresent(sfWalletLocator)) { - std::cerr << "doClaim: set wallet locator" << std::endl; + std::cerr << "doAccountSet: set wallet locator" << std::endl; sleSrc->setIFieldH256(sfWalletLocator, txn.getITFieldH256(sfWalletLocator)); } @@ -600,13 +706,13 @@ TransactionEngineResult TransactionEngine::doAccountSet(const SerializedTransact } else if (sleSrc->getIFieldPresent(sfMessageKey)) { - std::cerr << "doClaim: can not change message key" << std::endl; + std::cerr << "doAccountSet: can not change message key" << std::endl; return tenMSG_SET; } else { - std::cerr << "doClaim: set message key" << std::endl; + std::cerr << "doAccountSet: set message key" << std::endl; sleSrc->setIFieldVL(sfMessageKey, txn.getITFieldVL(sfMessageKey)); } @@ -621,71 +727,11 @@ TransactionEngineResult TransactionEngine::doClaim(const SerializedTransaction& { std::cerr << "doClaim>" << std::endl; - SLE::pointer sleDst = accounts[0].second; - - std::cerr << str(boost::format("doClaim: %s") % sleDst->getFullText()) << std::endl; - - // Verify not already claimed. - if (sleDst->getIFieldPresent(sfAuthorizedKey)) - { - std::cerr << "doClaim: source already claimed" << std::endl; - - return terCLAIMED; - } - - // - // Generator ID is based on regular account #0 public key. - // Verify that submitter knows the private key for the generator. - // Otherwise, people could deny access to generators. - // - - std::vector vucCipher = txn.getITFieldVL(sfGenerator); - std::vector vucPubKey = txn.getITFieldVL(sfPubKey); - std::vector vucSignature = txn.getITFieldVL(sfSignature); - NewcoinAddress naAccountPublic = NewcoinAddress::createAccountPublic(vucPubKey); - - if (!naAccountPublic.accountPublicVerify(Serializer::getSHA512Half(vucCipher), vucSignature)) - { - std::cerr << "doClaim: bad signature unauthorized generator claim" << std::endl; - - return tenBAD_GEN_AUTH; - } - - // - // Verify generator not already in use. - // - - uint160 hGeneratorID = naAccountPublic.getAccountID(); - - LedgerStateParms qry = lepNONE; - SLE::pointer sleGen = mLedger->getGenerator(qry, hGeneratorID); - if (sleGen) - { - // Generator is already in use. Regular passphrases limited to one wallet. - std::cerr << "doClaim: generator already in use" << std::endl; - - return tenGEN_IN_USE; - } - - // - // Claim the account. - // - - // Set the public key needed to use the account. - sleDst->setIFieldAccount(sfAuthorizedKey, hGeneratorID); - - // Construct a generator map entry. - sleGen = boost::make_shared(ltGENERATOR_MAP); - - sleGen->setIndex(Ledger::getGeneratorIndex(hGeneratorID)); - sleGen->setIFieldH160(sfGeneratorID, hGeneratorID); - sleGen->setIFieldVL(sfGenerator, vucCipher); - - accounts.push_back(std::make_pair(taaCREATE, sleGen)); + TransactionEngineResult result = setAuthorized(txn, accounts, true); std::cerr << "doClaim<" << std::endl; - return terSUCCESS; + return result; } TransactionEngineResult TransactionEngine::doCreditSet(const SerializedTransaction& txn, @@ -787,6 +833,60 @@ TransactionEngineResult TransactionEngine::doCreditSet(const SerializedTransacti return terResult; } +TransactionEngineResult TransactionEngine::doPasswordFund(const SerializedTransaction& txn, std::vector& accounts, const uint160& uSrcAccountID) +{ + std::cerr << "doPasswordFund>" << std::endl; + + uint160 uDstAccountID = txn.getITFieldAccount(sfDestination); + LedgerStateParms qry = lepNONE; + SLE::pointer sleDst = mLedger->getAccountRoot(qry, uDstAccountID); + if (!sleDst) + { + // Destination account does not exist. + std::cerr << "doPasswordFund: Delay transaction: Destination account does not exist." << std::endl; + + return terSET_MISSING_DST; + } + + if (sleDst->getFlags() & lsfPasswordSpent) + { + sleDst->clearFlag(lsfPasswordSpent); + + std::cerr << "doPasswordFund: Clearing spent." << sleDst->getFlags() << std::endl; + + if (uSrcAccountID != uDstAccountID) { + std::cerr << "doPasswordFund: Destination modified." << std::endl; + accounts.push_back(std::make_pair(taaMODIFY, sleDst)); + } + } + + std::cerr << "doPasswordFund<" << std::endl; + + return terSUCCESS; +} + +TransactionEngineResult TransactionEngine::doPasswordSet(const SerializedTransaction& txn, std::vector& accounts) +{ + std::cerr << "doPasswordSet>" << std::endl; + + SLE::pointer sleSrc = accounts[0].second; + + if (sleSrc->getFlags() & lsfPasswordSpent) + { + std::cerr << "doPasswordSet: Delay transaction: Funds already spent." << std::endl; + + return terFUNDS_SPENT; + } + + sleSrc->setFlag(lsfPasswordSpent); + + TransactionEngineResult result = setAuthorized(txn, accounts, false); + + std::cerr << "doPasswordSet<" << std::endl; + + return result; +} + TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction& txn, std::vector& accounts, const uint160& srcAccountID) diff --git a/src/TransactionEngine.h b/src/TransactionEngine.h index 6db706735e..75b79aca07 100644 --- a/src/TransactionEngine.h +++ b/src/TransactionEngine.h @@ -20,9 +20,12 @@ enum TransactionEngineResult tenDST_IS_SRC, // Destination may not be source. tenBAD_GEN_AUTH, // Not authorized to claim generator. tenBAD_ADD_AUTH, // Not authorized to add account. + tenBAD_CLAIM_ID, // Malformed. + tenBAD_SET_ID, // Malformed. // Invalid: Ledger won't allow. tenUNCLAIMED = -200, // Can not use an unclaimed account. + tenCLAIMED, // Can not claim a previously claimed account. tenBAD_AUTH, // Transaction's public key is not authorized. tenCREATED, // Can't add an already created account. tenMSG_SET, // Can't change a message key. @@ -40,7 +43,6 @@ enum TransactionEngineResult // Might succeed if not conflict is not caused by transaction ordering. terALREADY, // The transaction was already in the ledger terBAD_SEQ, // This sequence number should be zero for prepaid transactions. - terCLAIMED, // Can not claim a previously claimed account. terCREATED, // Can not create a previously created account. terDIR_FULL, // Can not add entry to full dir. terINSUF_FEE_B, // Account balance can't pay fee @@ -56,6 +58,8 @@ enum TransactionEngineResult terPRE_SEQ, // Missing/inapplicable prior transaction terUNFUNDED, // Source account had insufficient balance for transaction. terNO_LINE_NO_ZERO, // Can't zero non-existant line, destination might make it. + terSET_MISSING_DST, // Can't set password, destination missing. + terFUNDS_SPENT, // Can't set password, password set funds already spent. }; enum TransactionEngineParams @@ -91,6 +95,8 @@ private: const uint256& uBase, // Key of item. const uint256& uLedgerIndex); // Item being deleted + TransactionEngineResult setAuthorized(const SerializedTransaction& txn, std::vector& accounts, bool bMustSetGenerator); + protected: Ledger::pointer mDefaultLedger, mAlternateLedger; Ledger::pointer mLedger; @@ -98,12 +104,15 @@ protected: TransactionEngineResult doAccountSet(const SerializedTransaction& txn, std::vector& accounts); TransactionEngineResult doClaim(const SerializedTransaction& txn, std::vector& accounts); TransactionEngineResult doCreditSet(const SerializedTransaction& txn, std::vector& accounts, - const uint160& srcAccountID); + const uint160& uSrcAccountID); TransactionEngineResult doDelete(const SerializedTransaction& txn, std::vector& accounts); TransactionEngineResult doInvoice(const SerializedTransaction& txn, std::vector& accounts); TransactionEngineResult doOffer(const SerializedTransaction& txn, std::vector& accounts); + TransactionEngineResult doPasswordFund(const SerializedTransaction& txn, std::vector& accounts, + const uint160& uSrcAccountID); + TransactionEngineResult doPasswordSet(const SerializedTransaction& txn, std::vector& accounts); TransactionEngineResult doPayment(const SerializedTransaction& txn, std::vector& accounts, - const uint160& srcAccountID); + const uint160& uSrcAccountID); TransactionEngineResult doStore(const SerializedTransaction& txn, std::vector& accounts); TransactionEngineResult doTake(const SerializedTransaction& txn, std::vector& accounts); TransactionEngineResult doTransitSet(const SerializedTransaction& txn, std::vector& accounts); diff --git a/src/TransactionFormats.cpp b/src/TransactionFormats.cpp index 09f95d226b..66995e5a92 100644 --- a/src/TransactionFormats.cpp +++ b/src/TransactionFormats.cpp @@ -55,6 +55,23 @@ TransactionFormat InnerTxnFormats[]= { S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 }, { sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } } }, + { "PasswordFund", ttPASSWORD_FUND, { + { S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 }, + { S_FIELD(Destination), STI_ACCOUNT, SOE_REQUIRED, 0 }, + { S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 }, + { S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 }, + { sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } } + }, + { "PasswordSet", ttPASSWORD_SET, { + { S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 }, + { S_FIELD(AuthorizedKey), STI_ACCOUNT, SOE_REQUIRED, 0 }, + { S_FIELD(Generator), STI_VL, SOE_REQUIRED, 0 }, + { S_FIELD(PubKey), STI_VL, SOE_REQUIRED, 0 }, + { S_FIELD(Signature), STI_VL, SOE_REQUIRED, 0 }, + { S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 }, + { S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 }, + { sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } } + }, { "Payment", ttPAYMENT, { { S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 }, { S_FIELD(Destination), STI_ACCOUNT, SOE_REQUIRED, 0 }, diff --git a/src/TransactionFormats.h b/src/TransactionFormats.h index f8e8a34ed2..6833560696 100644 --- a/src/TransactionFormats.h +++ b/src/TransactionFormats.h @@ -10,10 +10,12 @@ enum TransactionType ttCLAIM = 1, ttWALLET_ADD = 2, ttACCOUNT_SET = 3, - ttINVOICE = 4, - ttOFFER = 5, + ttPASSWORD_FUND = 4, + ttPASSWORD_SET = 5, ttCREDIT_SET = 20, ttTRANSIT_SET = 21, + ttINVOICE = 10, + ttOFFER = 11, }; struct TransactionFormat diff --git a/src/main.cpp b/src/main.cpp index f35aba83bb..3e05f8be9e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,6 +46,8 @@ void printHelp(const po::options_description& desc) cout << " connect []" << endl; cout << " credit_set []" << endl; cout << " ledger" << endl; + cout << " password_fund []" << endl; + cout << " password_set []" << endl; cout << " peers" << endl; cout << " send [] [] []" << endl; cout << " stop" << endl; diff --git a/src/utils.h b/src/utils.h index 0e11312cbf..e0f3869480 100644 --- a/src/utils.h +++ b/src/utils.h @@ -7,9 +7,9 @@ #include #include "types.h" -// #include "uint256.h" #define nothing() do {} while (0) +#define fallthru() do {} while (0) #ifndef MAX #define MAX(x,y) ((x) < (y) ? (y) : (x))