Merge branch 'master' of github.com:jedmccaleb/NewCoin

This commit is contained in:
JoelKatz
2012-05-15 13:05:42 -07:00
10 changed files with 208 additions and 67 deletions

View File

@@ -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<Ledger>(rootAddress, 100000000);

View File

@@ -303,6 +303,25 @@ void NewcoinAddress::setAccountPublic(const NewcoinAddress& generator, int seq)
setAccountPublic(pubkey.GetPubKey());
}
bool NewcoinAddress::accountPublicVerify(const uint256& uHash, const std::vector<unsigned char>& 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
//

View File

@@ -76,6 +76,8 @@ public:
void setAccountPublic(const std::vector<unsigned char>& vPublic);
void setAccountPublic(const NewcoinAddress& generator, int seq);
bool accountPublicVerify(const uint256& uHash, const std::vector<unsigned char>& vucSig) const;
//
// Accounts Private
//

View File

@@ -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>|<nickname>|<account_public_key>
// account_info <seed>|<pass_phrase>|<key> [<index>]
Json::Value RPCServer::doAccountInfo(Json::Value &params)
{ // accountinfo <family>:<number>
// accountinfo <account>
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<int>(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 &params)
{ // newaccount <family> [<name>]
std::string fParam;
@@ -262,6 +309,7 @@ Json::Value RPCServer::doNewAccount(Json::Value &params)
return account->getJson();
}
#endif
Json::Value RPCServer::doLock(Json::Value &params)
{ // lock <family>
@@ -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<unsigned char> 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);

View File

@@ -45,6 +45,7 @@ class RPCServer : public boost::enable_shared_from_this<RPCServer>
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);

View File

@@ -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<unsigned char>& sig)

View File

@@ -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

View File

@@ -1,5 +1,6 @@
#include <cassert>
#include <boost/format.hpp>
#include "boost/lexical_cast.hpp"
#include "boost/make_shared.hpp"
#include "boost/ref.hpp"
@@ -65,6 +66,8 @@ Transaction::Transaction(
mTransaction = boost::make_shared<SerializedTransaction>(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);

View File

@@ -1,15 +1,21 @@
#include "TransactionEngine.h"
#include "TransactionFormats.h"
#include <boost/format.hpp>
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<AffectedAccount>& 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;
}

View File

@@ -36,13 +36,12 @@ void printHelp(const po::options_description& desc)
cout << desc << endl;
cout << "Commands: " << endl;
cout << " accountinfo <family>:<key>" << endl;
cout << " account_info <account>|<nickname>" << endl;
cout << " account_info <seed>|<pass_phrase>|<key> [<index>]" << endl;
cout << " connect <ip> [<port>]" << endl;
cout << " createfamily [<key>]" << endl;
cout << " familyinfo" << endl;
cout << " ledger" << endl;
cout << " lock <family>" << endl;
cout << " newaccount <family> [<name>]" << endl;
cout << " peers" << endl;
cout << " sendto <destination> <amount> [<tag>]" << endl;
cout << " stop" << endl;