mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Work towards Claim.
This commit is contained in:
@@ -108,35 +108,29 @@ void Application::run()
|
|||||||
|
|
||||||
// New stuff.
|
// New stuff.
|
||||||
NewcoinAddress rootSeedMaster;
|
NewcoinAddress rootSeedMaster;
|
||||||
NewcoinAddress rootSeedRegular;
|
|
||||||
NewcoinAddress rootGeneratorMaster;
|
NewcoinAddress rootGeneratorMaster;
|
||||||
NewcoinAddress rootGeneratorRegular;
|
|
||||||
NewcoinAddress reservedPublicRegular;
|
|
||||||
NewcoinAddress reservedPrivateRegular;
|
|
||||||
NewcoinAddress rootAddress;
|
NewcoinAddress rootAddress;
|
||||||
|
|
||||||
rootSeedMaster.setFamilySeed(CKey::PassPhraseToKey("Master passphrase."));
|
rootSeedMaster.setFamilySeed(CKey::PassPhraseToKey("Master passphrase."));
|
||||||
rootSeedRegular.setFamilySeed(CKey::PassPhraseToKey("Regular passphrase."));
|
|
||||||
|
|
||||||
std::cerr << "Master seed: " << rootSeedMaster.humanFamilySeed() << std::endl;
|
|
||||||
std::cerr << "Regular seed: " << rootSeedRegular.humanFamilySeed() << std::endl;
|
|
||||||
|
|
||||||
rootGeneratorMaster.setFamilyGenerator(rootSeedMaster);
|
rootGeneratorMaster.setFamilyGenerator(rootSeedMaster);
|
||||||
rootGeneratorRegular.setFamilyGenerator(rootSeedRegular);
|
|
||||||
|
|
||||||
std::cerr << "Master generator: " << rootGeneratorMaster.humanFamilyGenerator() << std::endl;
|
|
||||||
std::cerr << "Regular generator: " << rootGeneratorRegular.humanFamilyGenerator() << std::endl;
|
|
||||||
|
|
||||||
rootAddress.setAccountPublic(rootGeneratorMaster, 0);
|
rootAddress.setAccountPublic(rootGeneratorMaster, 0);
|
||||||
|
|
||||||
std::cerr << "Regular address: " << rootAddress.humanAccountPublic() << std::endl;
|
std::cerr << "Master seed: " << rootSeedMaster.humanFamilySeed() << std::endl;
|
||||||
|
std::cerr << "Master generator: " << rootGeneratorMaster.humanFamilyGenerator() << std::endl;
|
||||||
|
std::cerr << "Root address: " << rootAddress.humanAccountPublic() << std::endl;
|
||||||
|
#if 0
|
||||||
|
NewcoinAddress rootSeedRegular;
|
||||||
|
NewcoinAddress rootGeneratorRegular;
|
||||||
|
NewcoinAddress reservedPublicRegular;
|
||||||
|
NewcoinAddress reservedPrivateRegular;
|
||||||
|
|
||||||
|
rootSeedRegular.setFamilySeed(CKey::PassPhraseToKey("Regular passphrase."));
|
||||||
|
rootGeneratorRegular.setFamilyGenerator(rootSeedRegular);
|
||||||
|
|
||||||
reservedPublicRegular.setAccountPublic(rootGeneratorRegular, -1);
|
reservedPublicRegular.setAccountPublic(rootGeneratorRegular, -1);
|
||||||
reservedPrivateRegular.setAccountPrivate(rootGeneratorRegular, rootSeedRegular, -1);
|
reservedPrivateRegular.setAccountPrivate(rootGeneratorRegular, rootSeedRegular, -1);
|
||||||
|
|
||||||
std::cerr << "Reserved public regular: " << reservedPublicRegular.humanAccountPublic() << std::endl;
|
|
||||||
std::cerr << "Reserved private regular: " << reservedPrivateRegular.humanAccountPrivate() << std::endl;
|
|
||||||
|
|
||||||
// hash of regular account #reserved public key.
|
// hash of regular account #reserved public key.
|
||||||
uint160 uiGeneratorID = reservedPublicRegular.getAccountID();
|
uint160 uiGeneratorID = reservedPublicRegular.getAccountID();
|
||||||
|
|
||||||
@@ -152,6 +146,11 @@ void Application::run()
|
|||||||
std::vector<unsigned char> vucGeneratorText = reservedPrivateRegular.accountPrivateDecrypt(reservedPublicRegular, vucGeneratorCipher);
|
std::vector<unsigned char> vucGeneratorText = reservedPrivateRegular.accountPrivateDecrypt(reservedPublicRegular, vucGeneratorCipher);
|
||||||
|
|
||||||
std::cerr << "Plain: " << strHex(vucGeneratorText) << std::endl;
|
std::cerr << "Plain: " << strHex(vucGeneratorText) << std::endl;
|
||||||
|
std::cerr << "Regular seed: " << rootSeedRegular.humanFamilySeed() << std::endl;
|
||||||
|
std::cerr << "Regular generator: " << rootGeneratorRegular.humanFamilyGenerator() << std::endl;
|
||||||
|
std::cerr << "Reserved public regular: " << reservedPublicRegular.humanAccountPublic() << std::endl;
|
||||||
|
std::cerr << "Reserved private regular: " << reservedPrivateRegular.humanAccountPrivate() << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Temporary root account will be ["This is my payphrase."]:0
|
// Temporary root account will be ["This is my payphrase."]:0
|
||||||
NewcoinAddress rootFamilySeed; // Hold the 128 password.
|
NewcoinAddress rootFamilySeed; // Hold the 128 password.
|
||||||
@@ -163,7 +162,6 @@ void Application::run()
|
|||||||
rootAddress.setAccountPublic(rootFamilyGenerator, 0);
|
rootAddress.setAccountPublic(rootFamilyGenerator, 0);
|
||||||
std::cerr << "Root account: " << rootAddress.humanAccountID() << std::endl;
|
std::cerr << "Root account: " << rootAddress.humanAccountID() << std::endl;
|
||||||
|
|
||||||
|
|
||||||
Ledger::pointer firstLedger = boost::make_shared<Ledger>(rootAddress, 100000000);
|
Ledger::pointer firstLedger = boost::make_shared<Ledger>(rootAddress, 100000000);
|
||||||
assert(!!firstLedger->getAccountState(rootAddress));
|
assert(!!firstLedger->getAccountState(rootAddress));
|
||||||
firstLedger->updateHash();
|
firstLedger->updateHash();
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ LedgerEntryFormat LedgerFormats[]=
|
|||||||
{ "AccountRoot", ltACCOUNT_ROOT, {
|
{ "AccountRoot", ltACCOUNT_ROOT, {
|
||||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||||
{ S_FIELD(Account), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
{ S_FIELD(Account), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||||
{ S_FIELD(AuthorizedKey),STI_VL, SOE_REQUIRED, 0 },
|
|
||||||
{ S_FIELD(Sequence), STI_UINT32, SOE_REQUIRED, 0 },
|
{ S_FIELD(Sequence), STI_UINT32, SOE_REQUIRED, 0 },
|
||||||
{ S_FIELD(Balance), STI_UINT64, SOE_REQUIRED, 0 },
|
{ S_FIELD(Balance), STI_UINT64, SOE_REQUIRED, 0 },
|
||||||
{ S_FIELD(LastReceive), STI_UINT32, SOE_REQUIRED, 0 },
|
{ S_FIELD(LastReceive), STI_UINT32, SOE_REQUIRED, 0 },
|
||||||
{ S_FIELD(LastTxn), STI_UINT32, SOE_REQUIRED, 0 },
|
{ S_FIELD(LastTxn), STI_UINT32, SOE_REQUIRED, 0 },
|
||||||
{ S_FIELD(EmailHash), STI_HASH128, SOE_IFFLAG, 1 },
|
{ S_FIELD(AuthorizedKey),STI_VL, SOE_IFFLAG, 1 },
|
||||||
{ S_FIELD(WalletLocator),STI_HASH256, SOE_IFFLAG, 2 },
|
{ S_FIELD(EmailHash), STI_HASH128, SOE_IFFLAG, 2 },
|
||||||
{ S_FIELD(MessageKey), STI_VL, SOE_IFFLAG, 4 },
|
{ S_FIELD(WalletLocator),STI_HASH256, SOE_IFFLAG, 4 },
|
||||||
|
{ S_FIELD(MessageKey), STI_VL, SOE_IFFLAG, 8 },
|
||||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||||
},
|
},
|
||||||
@@ -34,6 +34,13 @@ LedgerEntryFormat LedgerFormats[]=
|
|||||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
{ 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 },
|
||||||
|
{ S_FIELD(GeneratorID), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||||
|
{ S_FIELD(Generator), STI_VL, SOE_REQUIRED, 0 },
|
||||||
|
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||||
|
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||||
|
},
|
||||||
{ "Nickname", ltNICKNAME, {
|
{ "Nickname", ltNICKNAME, {
|
||||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||||
{ S_FIELD(Nickname), STI_HASH256, SOE_REQUIRED, 0 },
|
{ S_FIELD(Nickname), STI_HASH256, SOE_REQUIRED, 0 },
|
||||||
|
|||||||
@@ -5,10 +5,11 @@
|
|||||||
|
|
||||||
enum LedgerEntryType
|
enum LedgerEntryType
|
||||||
{
|
{
|
||||||
ltINVALID=-1,
|
ltINVALID =-1,
|
||||||
ltACCOUNT_ROOT=0,
|
ltACCOUNT_ROOT =0,
|
||||||
ltRIPPLE_STATE=1,
|
ltRIPPLE_STATE =1,
|
||||||
ltNICKNAME=2
|
ltGENERATOR_MAP =2,
|
||||||
|
ltNICKNAME =3
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LedgerEntryFormat
|
struct LedgerEntryFormat
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ enum SOE_Field
|
|||||||
sfBorrower, sfLender, sfLimit, sfOfferCurrency, sfLedgerHash,
|
sfBorrower, sfLender, sfLimit, sfOfferCurrency, sfLedgerHash,
|
||||||
sfLastReceive, sfLastTxn, sfNextRate, sfNextRateLgr, sfNextRateExp,
|
sfLastReceive, sfLastTxn, sfNextRate, sfNextRateLgr, sfNextRateExp,
|
||||||
sfNickname, sfMinimumOffer,
|
sfNickname, sfMinimumOffer,
|
||||||
sfAuthorizedKey,
|
sfAuthorizedKey, sfGenerator, sfGeneratorID, sfAccountID,
|
||||||
|
|
||||||
// test fields
|
// test fields
|
||||||
sfTest1, sfTest2, sfTest3, sfTest4
|
sfTest1, sfTest2, sfTest3, sfTest4
|
||||||
|
|||||||
@@ -38,14 +38,6 @@ SerializedTransaction::SerializedTransaction(SerializerIterator& sit, int length
|
|||||||
mMiddleTxn.giveObject(new STUInt64("Fee", sit.get64()));
|
mMiddleTxn.giveObject(new STUInt64("Fee", sit.get64()));
|
||||||
|
|
||||||
mInnerTxn = STObject(mFormat->elements, sit, "InnerTransaction");
|
mInnerTxn = STObject(mFormat->elements, sit, "InnerTransaction");
|
||||||
updateSourceAccount();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SerializedTransaction::updateSourceAccount()
|
|
||||||
{
|
|
||||||
NewcoinAddress a;
|
|
||||||
a.setAccountPublic(peekSigningPubKey());
|
|
||||||
mSourceAccount.setAccountID(a.getAccountID());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SerializedTransaction::getLength() const
|
int SerializedTransaction::getLength() const
|
||||||
@@ -217,12 +209,25 @@ std::vector<unsigned char>& SerializedTransaction::peekSigningPubKey()
|
|||||||
return v->peekValue();
|
return v->peekValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
const NewcoinAddress& SerializedTransaction::setSigningPubKey(const std::vector<unsigned char>& s)
|
const NewcoinAddress& SerializedTransaction::setSigningPubKey(const NewcoinAddress& naSignPubKey)
|
||||||
{
|
{
|
||||||
|
mSignPubKey = naSignPubKey;
|
||||||
|
|
||||||
STVariableLength* v = dynamic_cast<STVariableLength*>(mMiddleTxn.getPIndex(TransactionISigningPubKey));
|
STVariableLength* v = dynamic_cast<STVariableLength*>(mMiddleTxn.getPIndex(TransactionISigningPubKey));
|
||||||
if (!v) throw std::runtime_error("corrupt transaction");
|
if (!v) throw std::runtime_error("corrupt transaction");
|
||||||
v->setValue(s);
|
v->setValue(mSignPubKey.getAccountPublic());
|
||||||
updateSourceAccount();
|
|
||||||
|
return mSignPubKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NewcoinAddress& SerializedTransaction::setSourceAccount(const NewcoinAddress& naSource)
|
||||||
|
{
|
||||||
|
mSourceAccount = naSource;
|
||||||
|
|
||||||
|
STHash160* v = dynamic_cast<STHash160*>(mMiddleTxn.getPIndex(TransactionISourceID));
|
||||||
|
if (!v) throw std::runtime_error("corrupt transaction");
|
||||||
|
v->setValue(mSourceAccount.getAccountID());
|
||||||
|
|
||||||
return mSourceAccount;
|
return mSourceAccount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,3 +288,4 @@ Json::Value SerializedTransaction::getJson(int options) const
|
|||||||
ret["Inner"] = mInnerTxn.getJson(options);
|
ret["Inner"] = mInnerTxn.getJson(options);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
// vim:ts=4
|
||||||
|
|||||||
@@ -16,14 +16,13 @@ public:
|
|||||||
typedef boost::shared_ptr<SerializedTransaction> pointer;
|
typedef boost::shared_ptr<SerializedTransaction> pointer;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
NewcoinAddress mSignPubKey;
|
||||||
NewcoinAddress mSourceAccount;
|
NewcoinAddress mSourceAccount;
|
||||||
TransactionType mType;
|
TransactionType mType;
|
||||||
STVariableLength mSignature;
|
STVariableLength mSignature;
|
||||||
STObject mMiddleTxn, mInnerTxn;
|
STObject mMiddleTxn, mInnerTxn;
|
||||||
TransactionFormat* mFormat;
|
TransactionFormat* mFormat;
|
||||||
|
|
||||||
void updateSourceAccount();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SerializedTransaction(SerializerIterator& sit, int length); // -1=all remaining, 0=get from sit
|
SerializedTransaction(SerializerIterator& sit, int length); // -1=all remaining, 0=get from sit
|
||||||
SerializedTransaction(TransactionType type);
|
SerializedTransaction(TransactionType type);
|
||||||
@@ -55,7 +54,8 @@ public:
|
|||||||
std::vector<unsigned char> getSigningPubKey() const;
|
std::vector<unsigned char> getSigningPubKey() const;
|
||||||
const std::vector<unsigned char>& peekSigningPubKey() const;
|
const std::vector<unsigned char>& peekSigningPubKey() const;
|
||||||
std::vector<unsigned char>& peekSigningPubKey();
|
std::vector<unsigned char>& peekSigningPubKey();
|
||||||
const NewcoinAddress& setSigningPubKey(const std::vector<unsigned char>& s);
|
const NewcoinAddress& setSigningPubKey(const NewcoinAddress& naSignPubKey);
|
||||||
|
const NewcoinAddress& setSourceAccount(const NewcoinAddress& naSource);
|
||||||
std::string getTransactionType() const { return mFormat->t_name; }
|
std::string getTransactionType() const { return mFormat->t_name; }
|
||||||
|
|
||||||
// inner transaction functions
|
// inner transaction functions
|
||||||
@@ -116,3 +116,4 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
// vim:ts=4
|
||||||
|
|||||||
@@ -23,7 +23,14 @@ Transaction::Transaction(LocalAccount::pointer fromLocalAccount, const NewcoinAd
|
|||||||
|
|
||||||
mFromPubKey = fromLocalAccount->getPublicKey();
|
mFromPubKey = fromLocalAccount->getPublicKey();
|
||||||
assert(mFromPubKey);
|
assert(mFromPubKey);
|
||||||
mTransaction->setSigningPubKey(mFromPubKey->GetPubKey());
|
|
||||||
|
// XXX Temporary: We don't really have local accounts.
|
||||||
|
NewcoinAddress signPubKey;
|
||||||
|
|
||||||
|
signPubKey.setAccountPublic(mFromPubKey->GetPubKey());
|
||||||
|
|
||||||
|
mTransaction->setSigningPubKey(signPubKey);
|
||||||
|
mTransaction->setSourceAccount(mAccountFrom);
|
||||||
|
|
||||||
mTransaction->setSequence(accountState->getSeq());
|
mTransaction->setSequence(accountState->getSeq());
|
||||||
assert(mTransaction->getSequence() != 0);
|
assert(mTransaction->getSequence() != 0);
|
||||||
@@ -105,6 +112,7 @@ Transaction::Transaction(const std::vector<unsigned char>& raw, bool validate) :
|
|||||||
mStatus = NEW;
|
mStatus = NEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
Transaction::Transaction(const NewcoinAddress& fromID, const NewcoinAddress& toID,
|
Transaction::Transaction(const NewcoinAddress& fromID, const NewcoinAddress& toID,
|
||||||
CKey::pointer pubKey, uint64 amount, uint64 fee, uint32 fromSeq, uint32 fromLedger,
|
CKey::pointer pubKey, uint64 amount, uint64 fee, uint32 fromSeq, uint32 fromLedger,
|
||||||
uint32 ident, const std::vector<unsigned char>& signature, uint32 ledgerSeq, TransStatus st) :
|
uint32 ident, const std::vector<unsigned char>& signature, uint32 ledgerSeq, TransStatus st) :
|
||||||
@@ -113,7 +121,8 @@ Transaction::Transaction(const NewcoinAddress& fromID, const NewcoinAddress& toI
|
|||||||
mTransaction = boost::make_shared<SerializedTransaction>(ttMAKE_PAYMENT);
|
mTransaction = boost::make_shared<SerializedTransaction>(ttMAKE_PAYMENT);
|
||||||
mTransaction->setSignature(signature);
|
mTransaction->setSignature(signature);
|
||||||
mTransaction->setTransactionFee(fee);
|
mTransaction->setTransactionFee(fee);
|
||||||
mTransaction->setSigningPubKey(pubKey->GetPubKey());
|
mTransaction->setSigningPubKey(pubKey); // BROKEN
|
||||||
|
mTransaction->setSourceAccount(mAccountFrom); // BROKEN
|
||||||
mTransaction->setSequence(fromSeq);
|
mTransaction->setSequence(fromSeq);
|
||||||
if (fromLedger != 0)
|
if (fromLedger != 0)
|
||||||
{
|
{
|
||||||
@@ -129,6 +138,7 @@ Transaction::Transaction(const NewcoinAddress& fromID, const NewcoinAddress& toI
|
|||||||
mTransaction->setITFieldAccount(sfDestination, toID.getAccountID());
|
mTransaction->setITFieldAccount(sfDestination, toID.getAccountID());
|
||||||
updateID();
|
updateID();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool Transaction::sign(LocalAccount::pointer fromLocalAccount)
|
bool Transaction::sign(LocalAccount::pointer fromLocalAccount)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,21 +6,63 @@
|
|||||||
TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTransaction& txn,
|
TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTransaction& txn,
|
||||||
TransactionEngineParams params)
|
TransactionEngineParams params)
|
||||||
{
|
{
|
||||||
|
TransactionEngineResult result = terSUCCESS;
|
||||||
|
|
||||||
uint256 txID = txn.getTransactionID();
|
uint256 txID = txn.getTransactionID();
|
||||||
if(!txID) return terINVALID;
|
if(!txID) return terINVALID;
|
||||||
|
|
||||||
// extract signing key
|
// Extract signing key
|
||||||
|
// Transactions contain a signing key. This allows us to trivially verify a transaction has at least been properly signed
|
||||||
|
// without going to disk. Each transaction also notes a source account id. This is used to verify that the signing key is
|
||||||
|
// associated with the account.
|
||||||
CKey acctKey;
|
CKey acctKey;
|
||||||
if (!acctKey.SetPubKey(txn.peekSigningPubKey())) return terINVALID;
|
if (!acctKey.SetPubKey(txn.peekSigningPubKey())) return terINVALID;
|
||||||
|
|
||||||
// check signature
|
// check signature
|
||||||
if (!txn.checkSign(acctKey)) return terINVALID;
|
if (!txn.checkSign(acctKey)) return terINVALID;
|
||||||
|
|
||||||
|
bool bPrepaid = false;
|
||||||
|
|
||||||
|
// Customize behavoir based on transaction type.
|
||||||
|
switch(txn.getTxnType())
|
||||||
|
{
|
||||||
|
case ttCLAIM:
|
||||||
|
bPrepaid = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ttMAKE_PAYMENT:
|
||||||
|
case ttINVOICE:
|
||||||
|
case ttEXCHANGE_OFFER:
|
||||||
|
result = terSUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ttINVALID:
|
||||||
|
result = terINVALID;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
result = terUNKNOWN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (terSUCCESS != result)
|
||||||
|
return result;
|
||||||
|
|
||||||
uint64 txnFee = txn.getTransactionFee();
|
uint64 txnFee = txn.getTransactionFee();
|
||||||
if ( (params & tepNO_CHECK_FEE) != tepNONE)
|
if ( (params & tepNO_CHECK_FEE) != tepNONE)
|
||||||
|
{
|
||||||
|
if (bPrepaid)
|
||||||
|
{
|
||||||
|
if (txnFee)
|
||||||
|
// Transaction is malformed.
|
||||||
|
return terINSUF_FEE_P;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// WRITEME: Check if fee is adequate
|
// WRITEME: Check if fee is adequate
|
||||||
if (txnFee == 0) return terINSUF_FEE_P;
|
if (txnFee == 0)
|
||||||
|
return terINSUF_FEE_P;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get source account ID
|
// get source account ID
|
||||||
@@ -30,20 +72,35 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
|||||||
boost::recursive_mutex::scoped_lock sl(mLedger->mLock);
|
boost::recursive_mutex::scoped_lock sl(mLedger->mLock);
|
||||||
|
|
||||||
// find source account
|
// find source account
|
||||||
|
// If we are only verifying some transactions, this would be probablistic.
|
||||||
LedgerStateParms qry = lepNONE;
|
LedgerStateParms qry = lepNONE;
|
||||||
SerializedLedgerEntry::pointer src = mLedger->getAccountRoot(qry, srcAccount);
|
SerializedLedgerEntry::pointer src = mLedger->getAccountRoot(qry, srcAccount);
|
||||||
if (!src) return terNO_ACCOUNT;
|
if (!src) return terNO_ACCOUNT;
|
||||||
|
|
||||||
// deduct the fee, so it's not available during the transaction
|
// deduct the fee, so it's not available during the transaction
|
||||||
// we only write the account back if the transaction succeeds
|
// we only write the account back if the transaction succeeds
|
||||||
|
if (txnFee)
|
||||||
|
{
|
||||||
uint64 balance = src->getIFieldU64(sfBalance);
|
uint64 balance = src->getIFieldU64(sfBalance);
|
||||||
|
|
||||||
if (balance < txnFee)
|
if (balance < txnFee)
|
||||||
return terINSUF_FEE_B;
|
return terINSUF_FEE_B;
|
||||||
src->setIFieldU64(sfBalance, balance - txnFee);
|
|
||||||
|
|
||||||
// validate sequence
|
src->setIFieldU64(sfBalance, balance - txnFee);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate sequence
|
||||||
uint32 t_seq = txn.getSequence();
|
uint32 t_seq = txn.getSequence();
|
||||||
|
|
||||||
|
if (bPrepaid)
|
||||||
|
{
|
||||||
|
if (t_seq)
|
||||||
|
return terPAST_SEQ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
uint32 a_seq = src->getIFieldU32(sfSequence);
|
uint32 a_seq = src->getIFieldU32(sfSequence);
|
||||||
|
|
||||||
if (t_seq != a_seq)
|
if (t_seq != a_seq)
|
||||||
{
|
{
|
||||||
// WRITEME: Special case code for changing transaction key
|
// WRITEME: Special case code for changing transaction key
|
||||||
@@ -53,16 +110,21 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
|||||||
return terPAST_SEQ;
|
return terPAST_SEQ;
|
||||||
}
|
}
|
||||||
else src->setIFieldU32(sfSequence, t_seq);
|
else src->setIFieldU32(sfSequence, t_seq);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<AffectedAccount> accounts;
|
std::vector<AffectedAccount> accounts;
|
||||||
accounts.push_back(std::make_pair(taaMODIFY, src));
|
accounts.push_back(std::make_pair(taaMODIFY, src));
|
||||||
TransactionEngineResult result = terUNKNOWN;
|
|
||||||
switch(txn.getTxnType())
|
switch(txn.getTxnType())
|
||||||
{
|
{
|
||||||
case ttINVALID:
|
case ttINVALID:
|
||||||
result = terINVALID;
|
result = terINVALID;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ttCLAIM:
|
||||||
|
result = doClaim(txn, accounts);
|
||||||
|
break;
|
||||||
|
|
||||||
case ttMAKE_PAYMENT:
|
case ttMAKE_PAYMENT:
|
||||||
result = doPayment(txn, accounts);
|
result = doPayment(txn, accounts);
|
||||||
break;
|
break;
|
||||||
@@ -110,6 +172,12 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TransactionEngineResult TransactionEngine::doClaim(const SerializedTransaction& txn,
|
||||||
|
std::vector<AffectedAccount>& accounts)
|
||||||
|
{
|
||||||
|
return terUNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction& txn,
|
TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction& txn,
|
||||||
std::vector<AffectedAccount>& accounts)
|
std::vector<AffectedAccount>& accounts)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ enum TransactionEngineResult
|
|||||||
terUNFUNDED, // Source account had insufficient balance for transactin
|
terUNFUNDED, // Source account had insufficient balance for transactin
|
||||||
terNO_PATH, // No path existed or met transaction/balance requirements
|
terNO_PATH, // No path existed or met transaction/balance requirements
|
||||||
terPAST_SEQ, // This sequence number has already past
|
terPAST_SEQ, // This sequence number has already past
|
||||||
|
terBAD_SEQ, // This sequence number should be zero for prepaid transactions.
|
||||||
terPRE_SEQ, // Missing/inapplicable prior transaction
|
terPRE_SEQ, // Missing/inapplicable prior transaction
|
||||||
terPAST_LEDGER, // The transaction expired and can't be applied
|
terPAST_LEDGER, // The transaction expired and can't be applied
|
||||||
};
|
};
|
||||||
@@ -51,13 +52,14 @@ class TransactionEngine
|
|||||||
protected:
|
protected:
|
||||||
Ledger::pointer mLedger;
|
Ledger::pointer mLedger;
|
||||||
|
|
||||||
TransactionEngineResult doPayment(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
TransactionEngineResult doCancel(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
||||||
|
TransactionEngineResult doClaim(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
||||||
|
TransactionEngineResult doDelete(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
||||||
TransactionEngineResult doInvoice(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
TransactionEngineResult doInvoice(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
||||||
TransactionEngineResult doOffer(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
TransactionEngineResult doOffer(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
||||||
TransactionEngineResult doTake(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
TransactionEngineResult doPayment(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
||||||
TransactionEngineResult doCancel(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
|
||||||
TransactionEngineResult doStore(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
TransactionEngineResult doStore(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
||||||
TransactionEngineResult doDelete(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
TransactionEngineResult doTake(const SerializedTransaction&, std::vector<AffectedAccount>&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TransactionEngine() { ; }
|
TransactionEngine() { ; }
|
||||||
|
|||||||
@@ -16,6 +16,13 @@ TransactionFormat InnerTxnFormats[]=
|
|||||||
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
|
||||||
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||||
},
|
},
|
||||||
|
{ "Claim", ttCLAIM, {
|
||||||
|
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||||
|
{ S_FIELD(GeneratorID), STI_AMOUNT, SOE_REQUIRED, 0 },
|
||||||
|
{ S_FIELD(Generator), STI_VL, SOE_REQUIRED, 0 },
|
||||||
|
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 },
|
||||||
|
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
|
||||||
|
},
|
||||||
{ "Invoice", ttINVOICE, {
|
{ "Invoice", ttINVOICE, {
|
||||||
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
|
||||||
{ S_FIELD(Target), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
{ S_FIELD(Target), STI_ACCOUNT, SOE_REQUIRED, 0 },
|
||||||
|
|||||||
@@ -5,10 +5,11 @@
|
|||||||
|
|
||||||
enum TransactionType
|
enum TransactionType
|
||||||
{
|
{
|
||||||
ttINVALID=-1,
|
ttINVALID = -1,
|
||||||
ttMAKE_PAYMENT=0,
|
ttMAKE_PAYMENT = 0,
|
||||||
ttINVOICE=1,
|
ttCLAIM = 1,
|
||||||
ttEXCHANGE_OFFER=2
|
ttINVOICE = 2,
|
||||||
|
ttEXCHANGE_OFFER = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TransactionFormat
|
struct TransactionFormat
|
||||||
@@ -18,10 +19,14 @@ struct TransactionFormat
|
|||||||
SOElement elements[16];
|
SOElement elements[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
const int32 TransactionMagic=0x54584E00;
|
const int32 TransactionMagic = 0x54584E00; // 'TXN'
|
||||||
|
|
||||||
const int TransactionIVersion=0, TransactionISigningPubKey=1, TransactionISequence=2;
|
const int TransactionIVersion = 0;
|
||||||
const int TransactionIType=3, TransactionIFee=4;
|
const int TransactionISigningPubKey = 1;
|
||||||
|
const int TransactionISourceID = 2;
|
||||||
|
const int TransactionISequence = 3;
|
||||||
|
const int TransactionIType = 4;
|
||||||
|
const int TransactionIFee = 5;
|
||||||
|
|
||||||
const int TransactionMinLen=32;
|
const int TransactionMinLen=32;
|
||||||
const int TransactionMaxLen=1048576;
|
const int TransactionMaxLen=1048576;
|
||||||
|
|||||||
Reference in New Issue
Block a user