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

This commit is contained in:
JoelKatz
2012-06-01 19:33:33 -07:00
10 changed files with 360 additions and 61 deletions

View File

@@ -83,3 +83,4 @@ public:
extern Config theConfig;
#endif
// vim:ts=4

View File

@@ -205,7 +205,8 @@ Json::Value RPCServer::getGenerator(const uint256& uLedger, const NewcoinAddress
Json::Value RPCServer::authorize(const uint256& uLedger,
const NewcoinAddress& naSeed, const NewcoinAddress& naSrcAccountID,
NewcoinAddress& naAccountPublic, NewcoinAddress& naAccountPrivate,
AccountState::pointer& asSrc)
AccountState::pointer& asSrc,
const NewcoinAddress& naVerifyGenerator)
{
asSrc = mNetOps->getAccountState(uLedger, naSrcAccountID);
if (!asSrc)
@@ -225,6 +226,13 @@ Json::Value RPCServer::authorize(const uint256& uLedger,
if (!obj.empty())
return obj;
if (naVerifyGenerator.isValid() && naMasterGenerator != naVerifyGenerator)
{
std::cerr << "naAccountPublic: wrong seed" << std::endl;
return JSONRPCError(500, "wrong seed");
}
//
// Find the index of the account from the master generator, so we can generate the public and private keys.
//
@@ -322,7 +330,8 @@ Json::Value RPCServer::doAccountInfo(Json::Value &params)
{
return "invalid params";
}
else if (!mNetOps->available()) {
else if (!mNetOps->available())
{
return JSONRPCError(503, "network not available");
}
else
@@ -368,7 +377,8 @@ Json::Value RPCServer::doAccountLines(Json::Value &params)
{
return "invalid params";
}
else if (!mNetOps->available()) {
else if (!mNetOps->available())
{
return JSONRPCError(503, "network not available");
}
else
@@ -525,16 +535,18 @@ Json::Value RPCServer::doCreditSet(Json::Value& params)
{
return JSONRPCError(500, "bad src amount/currency");
}
else if (!mNetOps->available()) {
else if (!mNetOps->available())
{
return JSONRPCError(503, "network not available");
}
else
{
NewcoinAddress naMasterGenerator;
NewcoinAddress naAccountPublic;
NewcoinAddress naAccountPrivate;
AccountState::pointer asSrc;
uint256 uLedger = mNetOps->getClosedLedger();
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate, asSrc);
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate, asSrc, naMasterGenerator);
if (!obj.empty())
return obj;
@@ -613,16 +625,18 @@ Json::Value RPCServer::doSend(Json::Value& params)
{
return JSONRPCError(500, "bad src amount/currency");
}
else if (!mNetOps->available()) {
else if (!mNetOps->available())
{
return JSONRPCError(503, "network not available");
}
else
{
NewcoinAddress naMasterGenerator;
NewcoinAddress naAccountPublic;
NewcoinAddress naAccountPrivate;
AccountState::pointer asSrc;
uint256 uLedger = mNetOps->getClosedLedger();
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate, asSrc);
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate, asSrc, naMasterGenerator);
if (!obj.empty())
{
@@ -704,16 +718,18 @@ Json::Value RPCServer::doTransitSet(Json::Value& params)
{
return JSONRPCError(500, "source account id needed");
}
else if (!mNetOps->available()) {
else if (!mNetOps->available())
{
return JSONRPCError(503, "network not available");
}
else
{
NewcoinAddress naMasterGenerator;
NewcoinAddress naAccountPublic;
NewcoinAddress naAccountPrivate;
AccountState::pointer asSrc;
uint256 uLedger = mNetOps->getClosedLedger();
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate, asSrc);
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate, asSrc, naMasterGenerator);
if (!obj.empty())
{
@@ -917,7 +933,8 @@ Json::Value RPCServer::doWalletAccounts(Json::Value& params)
{
return "seed expected";
}
else if (!mNetOps->available()) {
else if (!mNetOps->available())
{
return JSONRPCError(503, "network not available");
}
else if ((uLedger = mNetOps->getClosedLedger()).isZero())
@@ -955,9 +972,122 @@ Json::Value RPCServer::doWalletAccounts(Json::Value& params)
}
}
// wallet_add <regular_seed> <paying_account> <master_seed> [<initial_funds>] [<account_annotation>]
Json::Value RPCServer::doWalletAdd(Json::Value& params)
{
return "not implemented";
NewcoinAddress naMasterSeed;
NewcoinAddress naRegularSeed;
NewcoinAddress naSrcAccountID;
STAmount saAmount;
std::string sDstCurrency;
if (params.size() < 3 || params.size() > 5)
{
return "invalid params";
}
else if (!naRegularSeed.setFamilySeedGeneric(params[0u].asString()))
{
return "regular seed expected";
}
else if (!naSrcAccountID.setAccountID(params[1u].asString()))
{
return JSONRPCError(500, "source account id needed");
}
else if (!naMasterSeed.setFamilySeedGeneric(params[2u].asString()))
{
return "master seed expected";
}
else if (params.size() >= 4 && !saAmount.setValue(params[3u].asString(), sDstCurrency))
{
return JSONRPCError(500, "bad dst amount/currency");
}
else if (!mNetOps->available())
{
return JSONRPCError(503, "network not available");
}
else
{
NewcoinAddress naMasterGenerator;
NewcoinAddress naRegularGenerator;
naMasterGenerator.setFamilyGenerator(naMasterSeed);
naRegularGenerator.setFamilyGenerator(naRegularSeed);
NewcoinAddress naAccountPublic;
NewcoinAddress naAccountPrivate;
AccountState::pointer asSrc;
uint256 uLedger = mNetOps->getClosedLedger();
Json::Value obj = authorize(uLedger, naRegularSeed, naSrcAccountID, naAccountPublic, naAccountPrivate, asSrc, naMasterGenerator);
if (!obj.empty())
{
return obj;
}
// XXX Confirm total funds.
STAmount saSrcBalance = asSrc->getBalance();
if (saSrcBalance < theConfig.FEE_CREATE)
{
return JSONRPCError(500, "insufficent funds");
}
else
{
NewcoinAddress naNewAccountPublic;
NewcoinAddress naNewAccountPrivate;
NewcoinAddress naAuthKeyID;
uint160 uAuthKeyID;
AccountState::pointer asNew;
std::vector<unsigned char> vucSignature;
bool bAgain = true;
int iIndex = -1;
// Find an unmade account.
do {
++iIndex;
naNewAccountPublic.setAccountPublic(naMasterGenerator, iIndex);
asNew = mNetOps->getAccountState(uLedger, naNewAccountPublic);
if (!asNew)
bAgain = false;
} while (bAgain);
// XXX Have a maximum number of accounts per wallet?
// Determine corrisponding master private key.
naNewAccountPrivate.setAccountPrivate(naMasterGenerator, naMasterSeed, iIndex);
// Determine new accounts authorized regular key.
naAuthKeyID.setAccountPublic(naRegularGenerator, iIndex);
uAuthKeyID = naAuthKeyID.getAccountID();
// Sign anything (naAuthKeyID) to prove we know new master private key.
naNewAccountPrivate.accountPrivateSign(Serializer::getSHA512Half(uAuthKeyID.begin(), uAuthKeyID.size()), vucSignature);
Transaction::pointer trans = Transaction::sharedWalletAdd(
naAccountPublic, naAccountPrivate,
naSrcAccountID,
asSrc->getSeq(),
theConfig.FEE_CREATE,
0, // YYY No source tag
saAmount,
naAuthKeyID,
naNewAccountPublic,
vucSignature);
(void) mNetOps->processTransaction(trans);
obj["transaction"] = trans->getSTransaction()->getJson(0);
obj["status"] = trans->getStatus();
obj["srcAccountID"] = naSrcAccountID.humanAccountID();
obj["newAccountID"] = naNewAccountPublic.humanAccountID();
obj["amount"] = saAmount.getText();
return obj;
}
}
}
// wallet_claim <master_seed> <regular_seed> [<source_tag>] [<account_annotation>]
@@ -1013,12 +1143,13 @@ Json::Value RPCServer::doWalletClaim(Json::Value& params)
naRegular0Public.setAccountPublic(naRegularGenerator, 0);
naRegular0Private.setAccountPrivate(naRegularGenerator, naRegularSeed, 0);
// hash of regular account #reserved public key.
// Hash of regular account #0 public key.
uint160 uGeneratorID = naRegular0Public.getAccountID();
std::vector<unsigned char> vucGeneratorCipher = naRegular0Private.accountPrivateEncrypt(naRegular0Public, naMasterGenerator.getFamilyGenerator());
std::vector<unsigned char> vucGeneratorSig;
// XXX Check result.
// Prove that we have the corrisponding private key to the generator id. So, we can get the generator id.
naRegular0Private.accountPrivateSign(Serializer::getSHA512Half(vucGeneratorCipher), vucGeneratorSig);
Transaction::pointer trns = Transaction::sharedClaim(
@@ -1078,7 +1209,8 @@ Json::Value RPCServer::doWalletCreate(Json::Value& params)
{
return "create account id needed";
}
else if (!mNetOps->available()) {
else if (!mNetOps->available())
{
// We require access to the paying account's sequence number and key information.
return JSONRPCError(503, "network not available");
}
@@ -1095,11 +1227,12 @@ Json::Value RPCServer::doWalletCreate(Json::Value& params)
// Trying to build:
// peer_wallet_create <paying_account> <paying_signature> <account_id> [<initial_funds>] [<annotation>]
NewcoinAddress naMasterGenerator;
NewcoinAddress naAccountPublic;
NewcoinAddress naAccountPrivate;
AccountState::pointer asSrc;
uint256 uLedger = mNetOps->getClosedLedger();
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate, asSrc);
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate, asSrc, naMasterGenerator);
STAmount saSrcBalance = asSrc->getBalance();
STAmount saInitialFunds = (params.size() < 4) ? 0 : boost::lexical_cast<uint64>(params[3u].asString());

View File

@@ -42,7 +42,8 @@ private:
Json::Value getGenerator(const uint256& uLedger, const NewcoinAddress& naSeed, NewcoinAddress& naMasterGenerator);
Json::Value authorize(const uint256& uLedger, const NewcoinAddress& naSeed, const NewcoinAddress& naSrcAccountID,
NewcoinAddress& naAccountPublic, NewcoinAddress& naAccountPrivate,
AccountState::pointer& asSrc);
AccountState::pointer& asSrc,
const NewcoinAddress& naVerifyGenerator);
Json::Value accounts(const uint256& uLedger, const NewcoinAddress& naMasterGenerator);
Json::Value accountFromString(const uint256& uLedger, NewcoinAddress& naAccount, bool& bIndex, const std::string& strIdent, const int iIndex);

View File

@@ -305,6 +305,45 @@ Transaction::pointer Transaction::sharedTransitSet(
return tResult->setTransitSet(naPrivateKey, uTransitRate, uTransitStart, uTransitExpire);
}
//
// WalletAdd
//
Transaction::pointer Transaction::setWalletAdd(
const NewcoinAddress& naPrivateKey,
const STAmount& saAmount,
const NewcoinAddress& naAuthKeyID,
const NewcoinAddress& naNewPubKey,
const std::vector<unsigned char>& vucSignature)
{
mTransaction->setITFieldAmount(sfAmount, saAmount);
mTransaction->setITFieldAccount(sfAuthorizedKey, naAuthKeyID);
mTransaction->setITFieldVL(sfPubKey, naNewPubKey.getAccountPublic());
mTransaction->setITFieldVL(sfSignature, vucSignature);
sign(naPrivateKey);
return shared_from_this();
}
Transaction::pointer Transaction::sharedWalletAdd(
const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey,
const NewcoinAddress& naSourceAccount,
uint32 uSeq,
const STAmount& saFee,
uint32 uSourceTag,
const STAmount& saAmount,
const NewcoinAddress& naAuthKeyID,
const NewcoinAddress& naNewPubKey,
const std::vector<unsigned char>& vucSignature)
{
pointer tResult = boost::make_shared<Transaction>(ttWALLET_ADD,
naPublicKey, naSourceAccount,
uSeq, saFee, uSourceTag);
return tResult->setWalletAdd(naPrivateKey, saAmount, naAuthKeyID, naNewPubKey, vucSignature);
}
//
// Misc.
//

View File

@@ -76,6 +76,13 @@ private:
uint32 uTransitStart,
uint32 uTransitExpire);
Transaction::pointer setWalletAdd(
const NewcoinAddress& naPrivateKey,
const STAmount& saAmount,
const NewcoinAddress& naAuthKeyID,
const NewcoinAddress& naNewPubKey,
const std::vector<unsigned char>& vucSignature);
public:
Transaction(const SerializedTransaction::pointer st, bool bValidate);
@@ -142,6 +149,18 @@ public:
uint32 uTransitStart,
uint32 uTransitExpire);
// Add an account to a wallet.
static Transaction::pointer sharedWalletAdd(
const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey,
const NewcoinAddress& naSourceAccount,
uint32 uSeq,
const STAmount& saFee,
uint32 uSourceTag,
const STAmount& saAmount, // Initial funds in XNC.
const NewcoinAddress& naAuthKeyID, // ID of regular public to auth.
const NewcoinAddress& naNewPubKey, // Public key of new account
const std::vector<unsigned char>& vucSignature); // Proof know new account's private key.
bool sign(const NewcoinAddress& naAccountPrivate);
bool checkSign() const;
void updateID() { mTransactionID=mTransaction->getTransactionID(); }

View File

@@ -90,6 +90,7 @@ TransactionEngineResult TransactionEngine::dirAdd(
std::cerr << "dirAdd: last: " << strHex(uNodeDir) << std::endl;
sleRoot->setIFieldU64(sfLastNode, uNodeDir);
accounts.push_back(std::make_pair(taaMODIFY, sleRoot));
}
}
@@ -262,17 +263,21 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
return tenINVALID;
}
//
// Verify transaction is signed properly.
//
// Extract signing key
// Transactions contain a signing key. This allows us to trivially verify a transaction has at least been properly signed
// without going to disk. Each transaction also notes a source account id. This is used to verify that the signing key is
// associated with the account.
// XXX This could be a lot cleaner to prevent unnecessary copying.
NewcoinAddress naPubKey;
NewcoinAddress naSigningPubKey;
naPubKey.setAccountPublic(txn.peekSigningPubKey());
naSigningPubKey.setAccountPublic(txn.peekSigningPubKey());
// check signature
if (!txn.checkSign(naPubKey))
// Consistency: really signed.
if (!txn.checkSign(naSigningPubKey))
{
std::cerr << "applyTransaction: Invalid transaction: bad signature" << std::endl;
return tenINVALID;
@@ -298,6 +303,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
case ttOFFER:
case ttCREDIT_SET:
case ttTRANSIT_SET:
case ttWALLET_ADD:
result = terSUCCESS;
break;
@@ -348,15 +354,46 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
boost::recursive_mutex::scoped_lock sl(mLedger->mLock);
// find source account
// If we are only verifying some transactions, this would be probablistic.
// If are only forwarding, due to resource limitations, we might verifying only some transactions, this would be probablistic.
LedgerStateParms lspRoot = lepNONE;
SLE::pointer sleSrc = mLedger->getAccountRoot(lspRoot, srcAccountID);
if (!sleSrc)
{
std::cerr << str(boost::format("applyTransaction: Delay transaction: source account does not exisit: %s") % txn.getSourceAccount().humanAccountID()) << std::endl;
return terNO_ACCOUNT;
}
// Consistency: Check signature
switch (txn.getTxnType())
{
case ttCLAIM:
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;
return tenINVALID;
}
break;
default:
if (!sleSrc->getIFieldPresent(sfAuthorizedKey))
{
std::cerr << "applyTransaction: Can not use unclaimed account." << std::endl;
return tenUNCLAIMED;
}
else if (naSigningPubKey.getAccountID() != sleSrc->getIFieldH160(sfAuthorizedKey))
{
std::cerr << "applyTransaction: Not authorized to use account." << std::endl;
return tenBAD_AUTH;
}
break;
}
// deduct the fee, so it's not available during the transaction
// we only write the account back if the transaction succeeds
if (!saCost.isZero())
@@ -389,15 +426,18 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
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 sleSrc->setIFieldU32(sfSequence, t_seq);
@@ -407,6 +447,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
if (t_seq)
{
std::cerr << "applyTransaction: bad sequence for pre-paid transaction" << std::endl;
return terPAST_SEQ;
}
}
@@ -445,6 +486,10 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
result = doTransitSet(txn, accounts);
break;
case ttWALLET_ADD:
result = doWalletAdd(txn, accounts);
break;
default:
result = tenUNKNOWN;
break;
@@ -485,41 +530,23 @@ TransactionEngineResult TransactionEngine::doClaim(const SerializedTransaction&
std::vector<AffectedAccount>& accounts)
{
std::cerr << "doClaim>" << std::endl;
NewcoinAddress naSigningPubKey;
naSigningPubKey.setAccountPublic(txn.peekSigningPubKey());
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;
SLE::pointer sleDst = accounts[0].second;
if (!sleDst)
{
// 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") % sleDst->getFullText()) << std::endl;
// Verify not already claimed.
if (sleDst->getIFieldPresent(sfAuthorizedKey))
{
// Source account already claimed.
std::cerr << "doClaim: source already claimed" << std::endl;
return terCLAIMED;
}
//
// Verify claim is authorized for public key.
// 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<unsigned char> vucCipher = txn.getITFieldVL(sfGenerator);
@@ -532,22 +559,24 @@ TransactionEngineResult TransactionEngine::doClaim(const SerializedTransaction&
if (!naAccountPublic.accountPublicVerify(Serializer::getSHA512Half(vucCipher), vucSignature))
{
std::cerr << "doClaim: bad signature unauthorized claim" << std::endl;
return tenINVALID;
std::cerr << "doClaim: bad signature unauthorized generator claim" << std::endl;
return tenBAD_GEN_AUTH;
}
//
// Verify generator not already in use.
//
uint160 hGeneratorID = naAccountPublic.getAccountID();
uint160 hGeneratorID = naAccountPublic.getAccountID();
qry = lepNONE;
SLE::pointer sleGen = mLedger->getGenerator(qry, hGeneratorID);
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;
}
@@ -587,6 +616,7 @@ TransactionEngineResult TransactionEngine::doCreditSet(const SerializedTransacti
std::cerr << "doCreditSet: Invalid transaction: Payment destination account not specifed." << std::endl;
return tenDST_NEEDED;
}
// XXX Might make sense for ripple.
else if (uSrcAccountID == uDstAccountID)
{
std::cerr << "doCreditSet: Invalid transaction: Source account is the same as destination." << std::endl;
@@ -613,16 +643,16 @@ TransactionEngineResult TransactionEngine::doCreditSet(const SerializedTransacti
SLE::pointer sleRippleState = mLedger->getRippleState(qry, uSrcAccountID, uDstAccountID, uCurrency);
if (sleRippleState)
{
std::cerr << "doCreditSet: Modifying ripple line." << std::endl;
bAddIndex = !(sleRippleState->getFlags() & uFlags);
std::cerr << "doCreditSet: Modifying ripple line: bAddIndex=" << bAddIndex << std::endl;
sleRippleState->setIFieldAmount(bSltD ? sfLowLimit : sfHighLimit, saLimitAmount);
accounts.push_back(std::make_pair(taaMODIFY, sleRippleState));
if (bAddIndex)
sleRippleState->setFlag(uFlags);
accounts.push_back(std::make_pair(taaMODIFY, sleRippleState));
}
// Line does not exist.
else if (saLimitAmount.isZero())
@@ -881,6 +911,72 @@ TransactionEngineResult TransactionEngine::doTransitSet(const SerializedTransact
return tenINVALID;
}
TransactionEngineResult TransactionEngine::doWalletAdd(const SerializedTransaction& txn,
std::vector<AffectedAccount>& accounts)
{
std::cerr << "WalletAdd>" << std::endl;
SLE::pointer sleDst = accounts[0].second;
std::cerr << str(boost::format("WalletAdd: %s") % sleDst->getFullText()) << std::endl;
// Verify not already claimed.
if (sleDst->getIFieldPresent(sfAuthorizedKey))
{
std::cerr << "WalletAdd: 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<unsigned char> vucCipher = txn.getITFieldVL(sfGenerator);
std::vector<unsigned char> vucPubKey = txn.getITFieldVL(sfPubKey);
std::vector<unsigned char> vucSignature = txn.getITFieldVL(sfSignature);
NewcoinAddress naAccountPublic;
naAccountPublic.setAccountPublic(vucPubKey);
if (!naAccountPublic.accountPublicVerify(Serializer::getSHA512Half(vucCipher), vucSignature))
{
std::cerr << "WalletAdd: 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 << "WalletAdd: generator already in use" << std::endl;
return tenGEN_IN_USE;
}
//
// Claim the account.
//
// Set the public key needed to use the account.
sleDst->setIFieldH160(sfAuthorizedKey, hGeneratorID);
std::cerr << "WalletAdd<" << std::endl;
return terSUCCESS;
}
TransactionEngineResult TransactionEngine::doInvoice(const SerializedTransaction& txn,
std::vector<AffectedAccount>& accounts)
{
@@ -899,12 +995,6 @@ TransactionEngineResult TransactionEngine::doTake(const SerializedTransaction& t
return tenUNKNOWN;
}
TransactionEngineResult TransactionEngine::doCancel(const SerializedTransaction& txn,
std::vector<AffectedAccount>& accounts)
{
return tenUNKNOWN;
}
TransactionEngineResult TransactionEngine::doStore(const SerializedTransaction& txn,
std::vector<AffectedAccount>& accounts)
{

View File

@@ -18,7 +18,11 @@ enum TransactionEngineResult
tenEXPLICITXNC, // XNC is used by default, don't specify it.
tenDST_NEEDED, // Destination not specified.
tenDST_IS_SRC, // Destination may not be source.
tenBAD_GEN_AUTH, // Not authorized to claim generator.
// Invalid: Ledger won't allow.
tenUNCLAIMED = -200, // Can not use an unclaimed account.
tenBAD_AUTH, // Transaction's public key is not authorized.
// Other
tenFAILED = -100, // Something broke horribly
@@ -86,7 +90,6 @@ private:
protected:
Ledger::pointer mLedger;
TransactionEngineResult doCancel(const SerializedTransaction&, std::vector<AffectedAccount>&);
TransactionEngineResult doClaim(const SerializedTransaction&, std::vector<AffectedAccount>&);
TransactionEngineResult doCreditSet(const SerializedTransaction&, std::vector<AffectedAccount>&,
const uint160& srcAccountID);
@@ -98,6 +101,7 @@ protected:
TransactionEngineResult doStore(const SerializedTransaction&, std::vector<AffectedAccount>&);
TransactionEngineResult doTake(const SerializedTransaction&, std::vector<AffectedAccount>&);
TransactionEngineResult doTransitSet(const SerializedTransaction&, std::vector<AffectedAccount>&);
TransactionEngineResult doWalletAdd(const SerializedTransaction&, std::vector<AffectedAccount>&);
public:
TransactionEngine() { ; }

View File

@@ -69,6 +69,16 @@ TransactionFormat InnerTxnFormats[]=
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
{ "WalletAdd", ttWALLET_ADD, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Amount), STI_AMOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(AuthorizedKey), STI_ACCOUNT, 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 } }
},
{ NULL, ttINVALID }
};

View File

@@ -8,8 +8,9 @@ enum TransactionType
ttINVALID = -1,
ttPAYMENT = 0,
ttCLAIM = 1,
ttINVOICE = 2,
ttOFFER = 3,
ttWALLET_ADD = 2,
ttINVOICE = 3,
ttOFFER = 4,
ttCREDIT_SET = 20,
ttTRANSIT_SET = 21,
};

View File

@@ -53,6 +53,7 @@ void printHelp(const po::options_description& desc)
cout << " unl_list" << endl;
cout << " unl_reset" << endl;
cout << " validation_create [<seed>|<pass_phrase>|<key>]" << endl;
cout << " wallet_add <regular_seed> <paying_account> <master_seed> [<initial_funds>] [<account_annotation>]" << endl;
cout << " wallet_accounts <seed>" << endl;
cout << " wallet_claim <master_seed> <regular_seed> [<source_tag>] [<account_annotation>]" << endl;
cout << " wallet_seed [<seed>|<passphrase>|<passkey>]" << endl;