diff --git a/src/RPCServer.cpp b/src/RPCServer.cpp index 3934a6af96..92d33ed5bf 100644 --- a/src/RPCServer.cpp +++ b/src/RPCServer.cpp @@ -608,8 +608,9 @@ Json::Value RPCServer::doWalletClaim(Json::Value& params) // // Which has no confidential information. + // XXX Need better parsing. + uint32 uSourceTag = (params.size() == 2) ? 0 : boost::lexical_cast(params[2u].asString()); // XXX Annotation is ignored. - uint32 uSourceTag = (params.size() == 2) ? 0 : params[2u].asUInt(); std::string strAnnotation = (params.size() == 3) ? "" : params[3u].asString(); NewcoinAddress naMasterSeed; @@ -641,13 +642,12 @@ Json::Value RPCServer::doWalletClaim(Json::Value& params) std::vector vucGeneratorCipher = naRegularReservedPrivate.accountPrivateEncrypt(naRegularReservedPublic, naMasterGenerator.getFamilyGenerator()); - Transaction::pointer trns = boost::make_shared( + Transaction::pointer trns = Transaction::sharedClaim( naAccountPublic, naAccountPrivate, - naAccountPublic, naUnset, - 0, // Free - 0, // Seq - uSourceTag, // Source tag - 0); // Ledger not specified. + naAccountPublic, + uSourceTag, + naRegularReservedPublic, // GeneratorID + vucGeneratorCipher); Json::Value obj(Json::objectValue); @@ -662,6 +662,8 @@ Json::Value RPCServer::doWalletClaim(Json::Value& params) obj["generator"] = strHex(vucGeneratorCipher); obj["annotation"] = strAnnotation; + obj["transaction"] = trns->getSTransaction()->getJson(0); + return obj; } } diff --git a/src/Transaction.cpp b/src/Transaction.cpp index ef39a564c0..f1620b12e8 100644 --- a/src/Transaction.cpp +++ b/src/Transaction.cpp @@ -11,47 +11,6 @@ #include "Serializer.h" #include "SerializedTransaction.h" -Transaction::Transaction(const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, - const NewcoinAddress& naFromAccount, const NewcoinAddress& toAccount, - uint64 amount, - uint32 iSeq, uint32 ident, uint32 ledger) : mInLedger(0), mStatus(NEW) -{ - mAccountFrom = naFromAccount; - - mFromPubKey = naPublicKey; - assert(mFromPubKey.isValid()); - - mTransaction = boost::make_shared(ttMAKE_PAYMENT); - - mTransaction->setSigningPubKey(mFromPubKey); - mTransaction->setSourceAccount(mAccountFrom); - - mTransaction->setSequence(iSeq); - - mTransaction->setTransactionFee(100); // for now - - mTransaction->setITFieldAccount(sfDestination, toAccount); - mTransaction->setITFieldU64(sfAmount, amount); - if (ledger != 0) - { - mTransaction->makeITFieldPresent(sfTargetLedger); - mTransaction->setITFieldU32(sfTargetLedger, ledger); - } - if (ident != 0) - { - mTransaction->makeITFieldPresent(sfSourceTag); - mTransaction->setITFieldU32(sfSourceTag, ident); - } - - if (!sign(naPrivateKey)) - { -#ifdef DEBUG - std::cerr << "Unable to sign transaction" << std::endl; -#endif - mStatus = INCOMPLETE; - } -} - Transaction::Transaction(const SerializedTransaction::pointer sit, bool bValidate) : mInLedger(0), mStatus(INVALID), mTransaction(sit) { @@ -87,67 +46,126 @@ Transaction::pointer Transaction::sharedTransaction(const std::vector& signature, uint32 ledgerSeq, TransStatus st) : - mAccountFrom(fromID), mFromPubKey(pubKey), mInLedger(ledgerSeq), mStatus(st) +Transaction::Transaction( + TransactionType ttKind, + const NewcoinAddress& naPublicKey, + const NewcoinAddress& naSourceAccount, + uint32 uSeq, + uint64 uFee, + uint32 uSourceTag) : + mInLedger(0), mStatus(NEW) { - mTransaction = boost::make_shared(ttMAKE_PAYMENT); - mTransaction->setSignature(signature); - mTransaction->setTransactionFee(fee); - mTransaction->setSigningPubKey(pubKey); // BROKEN - mTransaction->setSourceAccount(mAccountFrom); // BROKEN - mTransaction->setSequence(fromSeq); - if (fromLedger != 0) - { - mTransaction->makeITFieldPresent(sfTargetLedger); - mTransaction->setITFieldU32(sfTargetLedger, fromLedger); - } - if (ident != 0) + mAccountFrom = naSourceAccount; + mFromPubKey = naPublicKey; + assert(mFromPubKey.isValid()); + + mTransaction = boost::make_shared(ttKind); + + mTransaction->setSigningPubKey(mFromPubKey); + mTransaction->setSourceAccount(mAccountFrom); + mTransaction->setSequence(uSeq); + mTransaction->setTransactionFee(uFee); + + if (uSourceTag) { mTransaction->makeITFieldPresent(sfSourceTag); - mTransaction->setITFieldU32(sfSourceTag, ident); + mTransaction->setITFieldU32(sfSourceTag, uSourceTag); } - mTransaction->setITFieldU64(sfAmount, amount); - mTransaction->setITFieldAccount(sfDestination, toID.getAccountID()); - updateID(); } -#endif + +Transaction::pointer Transaction::setPayment( + const NewcoinAddress& naPrivateKey, + const NewcoinAddress& toAccount, + uint64 uAmount, + uint32 ledger) +{ + mTransaction->setITFieldAccount(sfDestination, toAccount); + mTransaction->setITFieldU64(sfAmount, uAmount); + + if (ledger != 0) + { + mTransaction->makeITFieldPresent(sfTargetLedger); + mTransaction->setITFieldU32(sfTargetLedger, ledger); + } + + sign(naPrivateKey); + + return shared_from_this(); +} + +Transaction::pointer Transaction::sharedPayment( + const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, + const NewcoinAddress& naSourceAccount, + uint32 uSeq, + uint64 uFee, + uint32 uSourceTag, + const NewcoinAddress& toAccount, + uint64 uAmount, + uint32 ledger) +{ + pointer tResult = boost::make_shared(ttMAKE_PAYMENT, + naPublicKey, naSourceAccount, + uSeq, uFee, uSourceTag); + + return tResult->setPayment(naPrivateKey, toAccount, uAmount, ledger); +} + +Transaction::pointer Transaction::setClaim( + const NewcoinAddress& naPrivateKey, + const NewcoinAddress& naGeneratorID, + const std::vector& vucGenerator) +{ + sign(naPrivateKey); + + return shared_from_this(); +} + +Transaction::pointer Transaction::sharedClaim( + const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, + const NewcoinAddress& naSourceAccount, + uint32 uSourceTag, + const NewcoinAddress& naGeneratorID, + const std::vector& vucGenerator) +{ + pointer tResult = boost::make_shared(ttCLAIM, + naPublicKey, naSourceAccount, + 0, // Sequence of 0. + 0, // Free. + uSourceTag); + + return tResult->setClaim(naPrivateKey, naGeneratorID, vucGenerator); +} bool Transaction::sign(const NewcoinAddress& naAccountPrivate) { - if(!naAccountPrivate.isValid()) + bool bResult = true; + + if (!naAccountPrivate.isValid()) { #ifdef DEBUG std::cerr << "No private key for signing" << std::endl; #endif - return false; + bResult = false; } - -#if 0 - if( (mTransaction->getITFieldU64(sfAmount)==0) ) - { -#ifdef DEBUG - std::cerr << "Bad amount or destination" << std::endl; -#endif - assert(false); - return false; - } -#endif - - if(!getSTransaction()->sign(naAccountPrivate)) + else if (!getSTransaction()->sign(naAccountPrivate)) { #ifdef DEBUG std::cerr << "Failed to make signature" << std::endl; #endif assert(false); - return false; + bResult = false; } - updateID(); + if (bResult) + { + updateID(); + } + else + { + mStatus = INCOMPLETE; + } - return true; + return bResult; } bool Transaction::checkSign() const diff --git a/src/Transaction.h b/src/Transaction.h index 20f068c657..9a336db450 100644 --- a/src/Transaction.h +++ b/src/Transaction.h @@ -30,35 +30,66 @@ enum TransStatus INCOMPLETE = 8 // needs more signatures }; +// This class is for constructing and examining transactions. Transactions are static so manipulation functions are unnecessary. class Transaction : public boost::enable_shared_from_this { public: - typedef boost::shared_ptr pointer; private: uint256 mTransactionID; NewcoinAddress mAccountFrom; - NewcoinAddress mFromPubKey; + NewcoinAddress mFromPubKey; // Sign transaction with this. mSignPubKey + NewcoinAddress mSourcePrivate; // Sign transaction with this. - uint32 mInLedger; - TransStatus mStatus; + uint32 mInLedger; + TransStatus mStatus; SerializedTransaction::pointer mTransaction; + Transaction::pointer setPayment( + const NewcoinAddress& naPrivateKey, + const NewcoinAddress& toAccount, + uint64 uAmount, + uint32 ledger); + + Transaction::pointer setClaim( + const NewcoinAddress& naPrivateKey, + const NewcoinAddress& naGeneratorID, + const std::vector& vucGenerator); + public: Transaction(const SerializedTransaction::pointer st, bool bValidate); static Transaction::pointer sharedTransaction(const std::vector&vucTransaction, bool bValidate); - Transaction(const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, - const NewcoinAddress& naFromAccount, const NewcoinAddress& toAccount, - uint64 amount, - uint32 iSeq, uint32 ident, uint32 ledger); + Transaction( + TransactionType ttKind, + const NewcoinAddress& naPublicKey, + const NewcoinAddress& naSourceAccount, + uint32 uSeq, + uint64 uFee, + uint32 uSourceTag); + static Transaction::pointer sharedPayment( + const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, + const NewcoinAddress& naSourceAccount, + uint32 uSeq, + uint64 uFee, + uint32 uSourceTag, + const NewcoinAddress& toAccount, + uint64 uAmount, + uint32 ledger); + + static Transaction::pointer sharedClaim( + const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey, + const NewcoinAddress& naSourceAccount, + uint32 uSourceTag, + const NewcoinAddress& naGeneratorID, + const std::vector& vucGenerator); #if 0 Transaction(const NewcoinAddress& fromID, const NewcoinAddress& toID, - CKey::pointer pubKey, uint64 amount, uint64 fee, uint32 fromSeq, uint32 fromLedger, + CKey::pointer pubKey, uint64 uAmount, uint64 fee, uint32 fromSeq, uint32 fromLedger, uint32 ident, const std::vector& signature, uint32 ledgerSeq, TransStatus st); #endif @@ -106,9 +137,11 @@ public: protected: static Transaction::pointer transactionFromSQL(const std::string& statement); +#if 0 Transaction(const uint256& transactionID, const NewcoinAddress& accountFrom, const NewcoinAddress& accountTo, - CKey::pointer key, uint64 amount, uint64 fee, uint32 fromAccountSeq, uint32 sourceLedger, + CKey::pointer key, uint64 uAmount, uint64 fee, uint32 fromAccountSeq, uint32 sourceLedger, uint32 ident, const std::vector& signature, uint32 inLedger, TransStatus status); +#endif }; #endif diff --git a/src/main.cpp b/src/main.cpp index bc2b1fcb2d..d770187722 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -115,12 +115,14 @@ int main(int argc, char* argv[]) if (iCmd) vCmd = vm["parameters"].as >(); - char* pvCmd[iCmd]; + std::vector pvCmd; + + pvCmd.resize(iCmd); for (int i=0; i != iCmd; ++i) pvCmd[i] = (char*) (vCmd[0].c_str()); - iResult = unit_test_main(init_unit_test, iCmd, pvCmd); + iResult = unit_test_main(init_unit_test, iCmd, &pvCmd.front()); } else if (!vm.count("parameters")) {