diff --git a/src/Application.cpp b/src/Application.cpp index 7651c126eb..84f0771709 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -118,16 +118,7 @@ void Application::run() std::cerr << "Master seed: " << rootSeedMaster.humanFamilySeed() << std::endl; std::cerr << "Master generator: " << rootGeneratorMaster.humanFamilyGenerator() << std::endl; - std::cerr << "Root address: " << rootAddress.humanAccountPublic() << std::endl; - - // Temporary root account will be ["This is my payphrase."]:0 - NewcoinAddress rootFamilySeed; // Hold the 128 password. - NewcoinAddress rootFamilyGenerator; // Hold the generator. - // NewcoinAddress rootAddress; - - rootFamilySeed.setFamilySeed(CKey::PassPhraseToKey("This is my payphrase.")); - rootFamilyGenerator.setFamilyGenerator(rootFamilySeed); - rootAddress.setAccountPublic(rootFamilyGenerator, 0); + std::cerr << "Root public key: " << rootAddress.humanAccountPublic() << std::endl; std::cerr << "Root account: " << rootAddress.humanAccountID() << std::endl; Ledger::pointer firstLedger = boost::make_shared(rootAddress, 100000000); diff --git a/src/NewcoinAddress.cpp b/src/NewcoinAddress.cpp index 1f2745639c..7cf62467e3 100644 --- a/src/NewcoinAddress.cpp +++ b/src/NewcoinAddress.cpp @@ -303,6 +303,25 @@ void NewcoinAddress::setAccountPublic(const NewcoinAddress& generator, int seq) setAccountPublic(pubkey.GetPubKey()); } +bool NewcoinAddress::accountPublicVerify(const uint256& uHash, const std::vector& vucSig) const +{ + CKey ckPublic; + bool bVerified; + + if (!ckPublic.SetPubKey(getAccountPublic())) + { + // Bad private key. + std::cerr << "accountPublicVerify: Bad private key." << std::endl; + bVerified = false; + } + else + { + bVerified = ckPublic.Verify(uHash, vucSig); + } + + return bVerified; +} + // // AccountPrivate // diff --git a/src/NewcoinAddress.h b/src/NewcoinAddress.h index 46d90233da..6ea8fa1e2e 100644 --- a/src/NewcoinAddress.h +++ b/src/NewcoinAddress.h @@ -76,6 +76,8 @@ public: void setAccountPublic(const std::vector& vPublic); void setAccountPublic(const NewcoinAddress& generator, int seq); + bool accountPublicVerify(const uint256& uHash, const std::vector& vucSig) const; + // // Accounts Private // diff --git a/src/RPCServer.cpp b/src/RPCServer.cpp index 92d33ed5bf..b0a7536c0a 100644 --- a/src/RPCServer.cpp +++ b/src/RPCServer.cpp @@ -172,6 +172,7 @@ NewcoinAddress RPCServer::parseFamily(const std::string& fParam) return family; } +#if 0 Json::Value RPCServer::doCreateFamily(Json::Value& params) { // createfamily FXXXX @@ -216,37 +217,83 @@ Json::Value RPCServer::doCreateFamily(Json::Value& params) return ret; } +#endif +// account_info || +// account_info || [] Json::Value RPCServer::doAccountInfo(Json::Value ¶ms) -{ // accountinfo : - // accountinfo - std::string acct; - if (!extractString(acct, params, 0)) - return JSONRPCError(500, "Invalid account identifier"); - - LocalAccount::pointer account = theApp->getWallet().parseAccount(acct); - if (account) return account->getJson(); - - NewcoinAddress acctid; - if (!acctid.setAccountID(acct)) - return JSONRPCError(500, "Unable to parse account"); - - LocalAccount::pointer lac(theApp->getWallet().getLocalAccount(acctid)); - if (!!lac) return lac->getJson(); - - AccountState::pointer as=theApp->getMasterLedger().getCurrentLedger()->getAccountState(acctid); - Json::Value ret(Json::objectValue); - if (as) - as->addJson(ret); +{ + if (params.size() < 1 || params.size() > 2) + { + return "invalid params"; + } else { - NewcoinAddress ad; - ad.setAccountID(acct); - ret[ad.humanAccountID()]="NotFound"; + std::string strIdent = params[0u].asString(); + bool bIndex = 2 == params.size(); + int iIndex = bIndex ? boost::lexical_cast(params[1u].asString()) : 0; + + NewcoinAddress naAccount; + NewcoinAddress naSeed; + + if (!bIndex && (naAccount.setAccountPublic(strIdent) || naAccount.setAccountID(strIdent))) + { + // Got the account. + nothing(); + } + else + { + // Must be a seed. + naSeed.setFamilySeedGeneric(strIdent); + + NewcoinAddress naGenerator; + NewcoinAddress naRegularReservedPublic; + + naGenerator.setFamilyGenerator(naSeed); + + naRegularReservedPublic.setAccountPublic(naGenerator, -1); + + uint160 uGeneratorID = naRegularReservedPublic.getAccountID(); + + // if (probe (uGeneratorID)) + if (false) + { + // Found master public key. + + } + else + { + // Didn't find a generator map, assume it is a master generator. + nothing(); + } + + bIndex = true; + + naAccount.setAccountPublic(naGenerator, iIndex); + } + + // Get info on account. + Json::Value ret(Json::objectValue); + + AccountState::pointer as=theApp->getMasterLedger().getCurrentLedger()->getAccountState(naAccount); + if (as) + { + as->addJson(ret); + } + else + { + ret["account"] = naAccount.humanAccountID(); + ret["status"] = "NotFound"; + ret["bIndex"] = bIndex; + if (bIndex) + ret["index"] = iIndex; + } + + return ret; } - return ret; } +#if 0 Json::Value RPCServer::doNewAccount(Json::Value ¶ms) { // newaccount [] std::string fParam; @@ -262,6 +309,7 @@ Json::Value RPCServer::doNewAccount(Json::Value ¶ms) return account->getJson(); } +#endif Json::Value RPCServer::doLock(Json::Value ¶ms) { // lock @@ -597,10 +645,26 @@ Json::Value RPCServer::doValidatorCreate(Json::Value& params) { // To provide an example to client writers, we do everything we expect a client to do here. Json::Value RPCServer::doWalletClaim(Json::Value& params) { + NewcoinAddress naTemp; + if (params.size() < 2 || params.size() > 4) { return "invalid params"; } + else if (naTemp.setAccountID(params[0u].asString()) + || naTemp.setAccountPublic(params[0u].asString()) + || naTemp.setAccountPrivate(params[0u].asString())) + { + // Should also not allow account id's as seeds. + return "master seed expected"; + } + else if (naTemp.setAccountID(params[1u].asString()) + || naTemp.setAccountPublic(params[1u].asString()) + || naTemp.setAccountPrivate(params[1u].asString())) + { + // Should also not allow account id's as seeds. + return "regular seed expected"; + } else { // Trying to build: @@ -623,7 +687,6 @@ Json::Value RPCServer::doWalletClaim(Json::Value& params) NewcoinAddress naAccountPublic; NewcoinAddress naAccountPrivate; - NewcoinAddress naUnset; naMasterSeed.setFamilySeedGeneric(params[0u].asString()); naRegularSeed.setFamilySeedGeneric(params[1u].asString()); @@ -641,7 +704,6 @@ Json::Value RPCServer::doWalletClaim(Json::Value& params) uint160 uGeneratorID = naRegularReservedPublic.getAccountID(); std::vector vucGeneratorCipher = naRegularReservedPrivate.accountPrivateEncrypt(naRegularReservedPublic, naMasterGenerator.getFamilyGenerator()); - Transaction::pointer trns = Transaction::sharedClaim( naAccountPublic, naAccountPrivate, naAccountPublic, @@ -649,6 +711,8 @@ Json::Value RPCServer::doWalletClaim(Json::Value& params) naRegularReservedPublic, // GeneratorID vucGeneratorCipher); + (void) theApp->getOPs().processTransaction(trns); + Json::Value obj(Json::objectValue); // We "echo" the seeds so they can be checked. @@ -663,6 +727,7 @@ Json::Value RPCServer::doWalletClaim(Json::Value& params) obj["annotation"] = strAnnotation; obj["transaction"] = trns->getSTransaction()->getJson(0); + obj["status"] = trns->getStatus(); return obj; } @@ -811,38 +876,47 @@ Json::Value RPCServer::doUnlScore(Json::Value& params) { else return "invalid params"; } -Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params) -{ - std::cerr << "RPC:" << command << std::endl; - - if (command== "stop") +Json::Value RPCServer::doStop(Json::Value& params) { + if (!params.size()) { theApp->stop(); return SYSTEM_NAME " server stopping"; } + else return "invalid params"; +} - if (command=="unl_add") return doUnlAdd(params); - if (command=="unl_default") return doUnlDefault(params); - if (command=="unl_delete") return doUnlDelete(params); - if (command=="unl_list") return doUnlList(params); - if (command=="unl_reset") return doUnlReset(params); - if (command=="unl_score") return doUnlScore(params); +Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params) +{ + std::cerr << "RPC:" << command << std::endl; - if (command=="validation_create") return doValidatorCreate(params); + if (command == "account_info") return doAccountInfo(params); + if (command == "connect") return doConnect(params); + if (command == "peers") return doPeers(params); + if (command == "stop") return doStop(params); - if (command=="wallet_claim") return doWalletClaim(params); - if (command=="wallet_propose") return doWalletPropose(params); + if (command == "unl_add") return doUnlAdd(params); + if (command == "unl_default") return doUnlDefault(params); + if (command == "unl_delete") return doUnlDelete(params); + if (command == "unl_list") return doUnlList(params); + if (command == "unl_reset") return doUnlReset(params); + if (command == "unl_score") return doUnlScore(params); - if (command=="createfamily") return doCreateFamily(params); + if (command == "validation_create") return doValidatorCreate(params); + + if (command == "wallet_claim") return doWalletClaim(params); + if (command == "wallet_propose") return doWalletPropose(params); + + // + // Obsolete or need rewrite: + // + +// if (command=="createfamily") return doCreateFamily(params); if (command=="familyinfo") return doFamilyInfo(params); - if (command=="accountinfo") return doAccountInfo(params); - if (command=="newaccount") return doNewAccount(params); +// if (command=="newaccount") return doNewAccount(params); if (command=="lock") return doLock(params); if (command=="unlock") return doUnlock(params); if (command=="sendto") return doSendTo(params); - if (command=="connect") return doConnect(params); - if (command=="peers") return doPeers(params); if (command=="tx") return doTx(params); if (command=="ledger") return doLedger(params); diff --git a/src/RPCServer.h b/src/RPCServer.h index c2c3286c61..904603dcd7 100644 --- a/src/RPCServer.h +++ b/src/RPCServer.h @@ -45,6 +45,7 @@ class RPCServer : public boost::enable_shared_from_this Json::Value doTx(Json::Value& params); Json::Value doLedger(Json::Value& params); Json::Value doAccount(Json::Value& params); + Json::Value doStop(Json::Value& params); Json::Value doUnlAdd(Json::Value& params); Json::Value doUnlDefault(Json::Value& params); diff --git a/src/SerializedTransaction.cpp b/src/SerializedTransaction.cpp index 67a067ea2e..a007be1122 100644 --- a/src/SerializedTransaction.cpp +++ b/src/SerializedTransaction.cpp @@ -136,9 +136,9 @@ bool SerializedTransaction::sign(const NewcoinAddress& naAccountPrivate) return naAccountPrivate.accountPrivateSign(getSigningHash(), mSignature.peekValue()); } -bool SerializedTransaction::checkSign(const NewcoinAddress& naAccountPrivate) const +bool SerializedTransaction::checkSign(const NewcoinAddress& naAccountPublic) const { - return naAccountPrivate.accountPrivateVerify(getSigningHash(), mSignature.getValue()); + return naAccountPublic.accountPublicVerify(getSigningHash(), mSignature.getValue()); } void SerializedTransaction::setSignature(const std::vector& sig) diff --git a/src/SerializedTransaction.h b/src/SerializedTransaction.h index 5ce70312ed..fe03d1c181 100644 --- a/src/SerializedTransaction.h +++ b/src/SerializedTransaction.h @@ -112,7 +112,7 @@ public: virtual Json::Value getJson(int options) const; bool sign(const NewcoinAddress& naAccountPrivate); - bool checkSign(const NewcoinAddress& naAccountPrivate) const; + bool checkSign(const NewcoinAddress& naAccountPublic) const; }; #endif diff --git a/src/Transaction.cpp b/src/Transaction.cpp index 25d7bf7d8e..4b663dec99 100644 --- a/src/Transaction.cpp +++ b/src/Transaction.cpp @@ -1,5 +1,6 @@ #include +#include #include "boost/lexical_cast.hpp" #include "boost/make_shared.hpp" #include "boost/ref.hpp" @@ -65,6 +66,8 @@ Transaction::Transaction( mTransaction = boost::make_shared(ttKind); + std::cerr << str(boost::format("Transaction: account: %s") % naSourceAccount.humanAccountID()) << std::endl; + std::cerr << str(boost::format("Transaction: mAccountFrom: %s") % mAccountFrom.humanAccountID()) << std::endl; mTransaction->setSigningPubKey(mFromPubKey); mTransaction->setSourceAccount(mAccountFrom); mTransaction->setSequence(uSeq); diff --git a/src/TransactionEngine.cpp b/src/TransactionEngine.cpp index a7c2dd1008..0900987df8 100644 --- a/src/TransactionEngine.cpp +++ b/src/TransactionEngine.cpp @@ -1,15 +1,21 @@ - #include "TransactionEngine.h" - #include "TransactionFormats.h" +#include + TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTransaction& txn, TransactionEngineParams params) { + std::cerr << "applyTransaction>" << std::endl; + TransactionEngineResult result = terSUCCESS; uint256 txID = txn.getTransactionID(); - if(!txID) return tenINVALID; + if (!txID) + { + std::cerr << "applyTransaction: invalid transaction id" << std::endl; + return tenINVALID; + } // Extract signing key // Transactions contain a signing key. This allows us to trivially verify a transaction has at least been properly signed @@ -22,7 +28,10 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran // check signature if (!txn.checkSign(naPubKey)) + { + std::cerr << "applyTransaction: invalid signature" << std::endl; return tenINVALID; + } bool bPrepaid = false; @@ -40,10 +49,12 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran break; case ttINVALID: + std::cerr << "applyTransaction: ttINVALID transaction type" << std::endl; result = tenINVALID; break; default: + std::cerr << "applyTransaction: unknown transaction type" << std::endl; result = tenUNKNOWN; break; } @@ -57,20 +68,30 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran if (bPrepaid) { if (txnFee) + { // Transaction is malformed. + std::cerr << "applyTransaction: fee not allowed" << std::endl; return tenINSUF_FEE_P; + } } else { // WRITEME: Check if fee is adequate if (txnFee == 0) + { + std::cerr << "applyTransaction: insufficient fee" << std::endl; return tenINSUF_FEE_P; + } } } // get source account ID uint160 srcAccount = txn.getSourceAccount().getAccountID(); - if (!srcAccount) return tenINVALID; + if (!srcAccount) + { + std::cerr << "applyTransaction: bad source id" << std::endl; + return tenINVALID; + } boost::recursive_mutex::scoped_lock sl(mLedger->mLock); @@ -78,7 +99,11 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran // If we are only verifying some transactions, this would be probablistic. LedgerStateParms qry = lepNONE; SerializedLedgerEntry::pointer src = mLedger->getAccountRoot(qry, srcAccount); - if (!src) return terNO_ACCOUNT; + if (!src) + { + std::cerr << str(boost::format("applyTransaction: no such account: %s") % txn.getSourceAccount().humanAccountID()) << std::endl; + return terNO_ACCOUNT; + } // deduct the fee, so it's not available during the transaction // we only write the account back if the transaction succeeds @@ -87,7 +112,10 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran uint64 balance = src->getIFieldU64(sfBalance); if (balance < txnFee) + { + std::cerr << "applyTransaction: insufficent balance" << std::endl; return terINSUF_FEE_B; + } src->setIFieldU64(sfBalance, balance - txnFee); } @@ -98,7 +126,10 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran if (bPrepaid) { if (t_seq) + { + std::cerr << "applyTransaction: bad sequence for pre-paid transaction" << std::endl; return terPAST_SEQ; + } } else { @@ -107,9 +138,18 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran if (t_seq != a_seq) { // WRITEME: Special case code for changing transaction key - if (a_seq < t_seq) return terPRE_SEQ; + if (a_seq < t_seq) + { + std::cerr << "applyTransaction: future sequence number" << std::endl; + return terPRE_SEQ; + } if (mLedger->hasTransaction(txID)) + { + std::cerr << "applyTransaction: duplicate sequence number" << std::endl; return terALREADY; + } + + std::cerr << "applyTransaction: past sequence number" << std::endl; return terPAST_SEQ; } else src->setIFieldU32(sfSequence, t_seq); @@ -121,6 +161,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran switch(txn.getTxnType()) { case ttINVALID: + std::cerr << "applyTransaction: invalid type" << std::endl; result = tenINVALID; break; @@ -178,6 +219,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran TransactionEngineResult TransactionEngine::doClaim(const SerializedTransaction& txn, std::vector& accounts) { + std::cerr << "doClaim>" << std::endl; NewcoinAddress naSigningPubKey; naSigningPubKey.setAccountPublic(txn.peekSigningPubKey()); @@ -185,15 +227,24 @@ TransactionEngineResult TransactionEngine::doClaim(const SerializedTransaction& uint160 sourceAccountID = naSigningPubKey.getAccountID(); if (sourceAccountID != txn.getSourceAccount().getAccountID()) + { // 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; return tenINVALID; + } LedgerStateParms qry = lepNONE; SerializedLedgerEntry::pointer dest = mLedger->getAccountRoot(qry, sourceAccountID); if (!dest) + { // Source account does not exist. Could succeed if it was created first. + std::cerr << str(boost::format("doClaim: no such account: %s") % txn.getSourceAccount().humanAccountID()) << std::endl; return terNO_ACCOUNT; + } + + std::cerr << str(boost::format("doClaim: %s") % dest->getFullText()) << std::endl; if (dest->getIFieldPresent(sfAuthorizedKey)) // Source account already claimed. @@ -225,6 +276,7 @@ TransactionEngineResult TransactionEngine::doClaim(const SerializedTransaction& accounts.push_back(std::make_pair(taaCREATE, gen)); + std::cerr << "doClaim<" << std::endl; return terSUCCESS; } diff --git a/src/main.cpp b/src/main.cpp index d770187722..2497515764 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,13 +36,12 @@ void printHelp(const po::options_description& desc) cout << desc << endl; cout << "Commands: " << endl; - cout << " accountinfo :" << endl; + cout << " account_info |" << endl; + cout << " account_info || []" << endl; cout << " connect []" << endl; - cout << " createfamily []" << endl; cout << " familyinfo" << endl; cout << " ledger" << endl; cout << " lock " << endl; - cout << " newaccount []" << endl; cout << " peers" << endl; cout << " sendto []" << endl; cout << " stop" << endl;