mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Merge branch 'misc'
Conflicts: src/TransactionEngine.cpp
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 }
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
//
|
||||
|
||||
@@ -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 ¶ms)
|
||||
{
|
||||
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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
//
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user