Merge branch 'misc'

Conflicts:
	src/TransactionEngine.cpp
This commit is contained in:
Arthur Britto
2012-06-04 01:25:48 -07:00
16 changed files with 613 additions and 193 deletions

View File

@@ -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<int>(strTemp);
if (sectionSingleB(secConfig, SECTION_ACCOUNT_PROBE_MAX, strTemp))
ACCOUNT_PROBE_MAX = boost::lexical_cast<int>(strTemp);
}
}
}

View File

@@ -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();

View File

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

View File

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

View File

@@ -67,6 +67,10 @@ public:
static NewcoinAddress createAccountID(const uint160& uiAccountID);
static std::string createHumanAccountID(const std::vector<unsigned char>& vPrivate) {
return createAccountPrivate(vPrivate).humanAccountID();
}
//
// Accounts Public
//

View File

@@ -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 <seed> <paying_account> <destination_account> <limit_amount> [<currency>] [<accept_rate>]
Json::Value RPCServer::doCreditSet(Json::Value& params)
{
@@ -811,6 +811,183 @@ Json::Value RPCServer::doCreditSet(Json::Value& params)
}
}
// password_fund <seed> <paying_account> [<account>]
// YYY Make making account default to first account for seed.
Json::Value RPCServer::doPasswordFund(Json::Value &params)
{
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 <master_seed> <regular_seed> [<account>]
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<unsigned char> vucGeneratorCipher = naRegular0Private.accountPrivateEncrypt(naRegular0Public, naMasterGenerator.getFamilyGenerator());
std::vector<unsigned char> 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<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.
// 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);

View File

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

View File

@@ -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));
}

View File

@@ -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<unsigned char>& vucGenerator,
const std::vector<unsigned char>& vucPubKey,
const std::vector<unsigned char>& vucSignature)
{
pointer tResult = boost::make_shared<Transaction>(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<Transaction>(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<unsigned char>& vucGenerator,
const std::vector<unsigned char>& vucPubKey,
const std::vector<unsigned char>& 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<unsigned char>& vucGenerator,
const std::vector<unsigned char>& vucPubKey,
const std::vector<unsigned char>& vucSignature)
{
pointer tResult = boost::make_shared<Transaction>(ttPASSWORD_SET,
naPublicKey, naPublicKey,
0, // Sequence of 0.
0, // Free.
uSourceTag);
return tResult->setPasswordSet(naPrivateKey, naAuthKeyID, vucGenerator, vucPubKey, vucSignature);
}
//
// Payment
//

View File

@@ -61,28 +61,39 @@ private:
const std::vector<unsigned char>& 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<unsigned char>& vucGenerator,
const std::vector<unsigned char>& vucPubKey,
const std::vector<unsigned char>& 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<unsigned char>& vucGenerator,
const std::vector<unsigned char>& 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<unsigned char>& vucGenerator,
const std::vector<unsigned char>& vucPubKey,
const std::vector<unsigned char>& 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(

View File

@@ -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<AffectedAccount>& accounts, bool bMustSetGenerator)
{
//
// 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 = 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<SerializedLedgerEntry>(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<unsigned char> vucCipher = txn.getITFieldVL(sfGenerator);
std::vector<unsigned char> vucPubKey = txn.getITFieldVL(sfPubKey);
std::vector<unsigned char> 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<SerializedLedgerEntry>(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<AffectedAccount>& 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<AffectedAccount>& 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<AffectedAccount>& accounts,
const uint160& srcAccountID)

View File

@@ -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<AffectedAccount>& accounts, bool bMustSetGenerator);
protected:
Ledger::pointer mDefaultLedger, mAlternateLedger;
Ledger::pointer mLedger;
@@ -98,12 +104,15 @@ protected:
TransactionEngineResult doAccountSet(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
TransactionEngineResult doClaim(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
TransactionEngineResult doCreditSet(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts,
const uint160& srcAccountID);
const uint160& uSrcAccountID);
TransactionEngineResult doDelete(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
TransactionEngineResult doInvoice(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
TransactionEngineResult doOffer(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
TransactionEngineResult doPasswordFund(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts,
const uint160& uSrcAccountID);
TransactionEngineResult doPasswordSet(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
TransactionEngineResult doPayment(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts,
const uint160& srcAccountID);
const uint160& uSrcAccountID);
TransactionEngineResult doStore(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
TransactionEngineResult doTake(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
TransactionEngineResult doTransitSet(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);

View File

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

View File

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

View File

@@ -46,6 +46,8 @@ void printHelp(const po::options_description& desc)
cout << " connect <ip> [<port>]" << endl;
cout << " credit_set <seed> <paying_account> <destination_account> <limit_amount> <currency> [<account_rate>]" << endl;
cout << " ledger" << endl;
cout << " password_fund <seed> <paying_account> [<account>]" << endl;
cout << " password_set <master_seed> <regular_seed> [<account>]" << endl;
cout << " peers" << endl;
cout << " send <seed> <paying_account> <account_id> <amount> [<currency>] [<send_max>] [<send_currency>]" << endl;
cout << " stop" << endl;

View File

@@ -7,9 +7,9 @@
#include <openssl/dh.h>
#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))