Work towards Claim.

This commit is contained in:
Arthur Britto
2012-05-11 18:29:41 -07:00
parent 3679d824c4
commit 5ad3eb6d4d
11 changed files with 180 additions and 75 deletions

View File

@@ -108,35 +108,29 @@ void Application::run()
// New stuff.
NewcoinAddress rootSeedMaster;
NewcoinAddress rootSeedRegular;
NewcoinAddress rootGeneratorMaster;
NewcoinAddress rootGeneratorRegular;
NewcoinAddress reservedPublicRegular;
NewcoinAddress reservedPrivateRegular;
NewcoinAddress rootAddress;
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);
rootGeneratorRegular.setFamilyGenerator(rootSeedRegular);
std::cerr << "Master generator: " << rootGeneratorMaster.humanFamilyGenerator() << std::endl;
std::cerr << "Regular generator: " << rootGeneratorRegular.humanFamilyGenerator() << std::endl;
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);
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.
uint160 uiGeneratorID = reservedPublicRegular.getAccountID();
@@ -152,6 +146,11 @@ void Application::run()
std::vector<unsigned char> vucGeneratorText = reservedPrivateRegular.accountPrivateDecrypt(reservedPublicRegular, vucGeneratorCipher);
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
NewcoinAddress rootFamilySeed; // Hold the 128 password.
@@ -163,7 +162,6 @@ void Application::run()
rootAddress.setAccountPublic(rootFamilyGenerator, 0);
std::cerr << "Root account: " << rootAddress.humanAccountID() << std::endl;
Ledger::pointer firstLedger = boost::make_shared<Ledger>(rootAddress, 100000000);
assert(!!firstLedger->getAccountState(rootAddress));
firstLedger->updateHash();

View File

@@ -8,14 +8,14 @@ LedgerEntryFormat LedgerFormats[]=
{ "AccountRoot", ltACCOUNT_ROOT, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 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(Balance), STI_UINT64, SOE_REQUIRED, 0 },
{ S_FIELD(LastReceive), STI_UINT32, SOE_REQUIRED, 0 },
{ S_FIELD(LastTxn), STI_UINT32, SOE_REQUIRED, 0 },
{ S_FIELD(EmailHash), STI_HASH128, SOE_IFFLAG, 1 },
{ S_FIELD(WalletLocator),STI_HASH256, SOE_IFFLAG, 2 },
{ S_FIELD(MessageKey), STI_VL, SOE_IFFLAG, 4 },
{ S_FIELD(AuthorizedKey),STI_VL, 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(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
@@ -34,6 +34,13 @@ LedgerEntryFormat LedgerFormats[]=
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
{ 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, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Nickname), STI_HASH256, SOE_REQUIRED, 0 },

View File

@@ -5,10 +5,11 @@
enum LedgerEntryType
{
ltINVALID=-1,
ltACCOUNT_ROOT=0,
ltRIPPLE_STATE=1,
ltNICKNAME=2
ltINVALID =-1,
ltACCOUNT_ROOT =0,
ltRIPPLE_STATE =1,
ltGENERATOR_MAP =2,
ltNICKNAME =3
};
struct LedgerEntryFormat

View File

@@ -32,7 +32,7 @@ enum SOE_Field
sfBorrower, sfLender, sfLimit, sfOfferCurrency, sfLedgerHash,
sfLastReceive, sfLastTxn, sfNextRate, sfNextRateLgr, sfNextRateExp,
sfNickname, sfMinimumOffer,
sfAuthorizedKey,
sfAuthorizedKey, sfGenerator, sfGeneratorID, sfAccountID,
// test fields
sfTest1, sfTest2, sfTest3, sfTest4

View File

@@ -38,14 +38,6 @@ SerializedTransaction::SerializedTransaction(SerializerIterator& sit, int length
mMiddleTxn.giveObject(new STUInt64("Fee", sit.get64()));
mInnerTxn = STObject(mFormat->elements, sit, "InnerTransaction");
updateSourceAccount();
}
void SerializedTransaction::updateSourceAccount()
{
NewcoinAddress a;
a.setAccountPublic(peekSigningPubKey());
mSourceAccount.setAccountID(a.getAccountID());
}
int SerializedTransaction::getLength() const
@@ -217,12 +209,25 @@ std::vector<unsigned char>& SerializedTransaction::peekSigningPubKey()
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));
if (!v) throw std::runtime_error("corrupt transaction");
v->setValue(s);
updateSourceAccount();
v->setValue(mSignPubKey.getAccountPublic());
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;
}
@@ -283,3 +288,4 @@ Json::Value SerializedTransaction::getJson(int options) const
ret["Inner"] = mInnerTxn.getJson(options);
return ret;
}
// vim:ts=4

View File

@@ -16,14 +16,13 @@ public:
typedef boost::shared_ptr<SerializedTransaction> pointer;
protected:
NewcoinAddress mSignPubKey;
NewcoinAddress mSourceAccount;
TransactionType mType;
STVariableLength mSignature;
STObject mMiddleTxn, mInnerTxn;
TransactionFormat* mFormat;
void updateSourceAccount();
public:
SerializedTransaction(SerializerIterator& sit, int length); // -1=all remaining, 0=get from sit
SerializedTransaction(TransactionType type);
@@ -42,7 +41,7 @@ public:
const std::vector<unsigned char>& peekSignature() const;
void setSignature(const std::vector<unsigned char>& s);
uint256 getSigningHash() const;
// middle transaction functions
uint32 getVersion() const;
void setVersion(uint32);
@@ -55,14 +54,15 @@ public:
std::vector<unsigned char> getSigningPubKey() const;
const std::vector<unsigned char>& peekSigningPubKey() const;
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; }
// inner transaction functions
uint32 getFlags() const { return mInnerTxn.getFlags(); }
void setFlag(uint32 v) { mInnerTxn.setFlag(v); }
void clearFlag(uint32 v) { mInnerTxn.clearFlag(v); }
uint32 getSequence() const;
void setSequence(uint32);
@@ -116,3 +116,4 @@ public:
};
#endif
// vim:ts=4

View File

@@ -23,7 +23,14 @@ Transaction::Transaction(LocalAccount::pointer fromLocalAccount, const NewcoinAd
mFromPubKey = fromLocalAccount->getPublicKey();
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());
assert(mTransaction->getSequence() != 0);
@@ -105,6 +112,7 @@ Transaction::Transaction(const std::vector<unsigned char>& raw, bool validate) :
mStatus = NEW;
}
#if 0
Transaction::Transaction(const NewcoinAddress& fromID, const NewcoinAddress& toID,
CKey::pointer pubKey, uint64 amount, uint64 fee, uint32 fromSeq, uint32 fromLedger,
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->setSignature(signature);
mTransaction->setTransactionFee(fee);
mTransaction->setSigningPubKey(pubKey->GetPubKey());
mTransaction->setSigningPubKey(pubKey); // BROKEN
mTransaction->setSourceAccount(mAccountFrom); // BROKEN
mTransaction->setSequence(fromSeq);
if (fromLedger != 0)
{
@@ -129,6 +138,7 @@ Transaction::Transaction(const NewcoinAddress& fromID, const NewcoinAddress& toI
mTransaction->setITFieldAccount(sfDestination, toID.getAccountID());
updateID();
}
#endif
bool Transaction::sign(LocalAccount::pointer fromLocalAccount)
{

View File

@@ -6,21 +6,63 @@
TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTransaction& txn,
TransactionEngineParams params)
{
TransactionEngineResult result = terSUCCESS;
uint256 txID = txn.getTransactionID();
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;
if (!acctKey.SetPubKey(txn.peekSigningPubKey())) return terINVALID;
// check signature
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();
if ( (params & tepNO_CHECK_FEE) != tepNONE)
{
// WRITEME: Check if fee is adequate
if (txnFee == 0) return terINSUF_FEE_P;
if (bPrepaid)
{
if (txnFee)
// Transaction is malformed.
return terINSUF_FEE_P;
}
else
{
// WRITEME: Check if fee is adequate
if (txnFee == 0)
return terINSUF_FEE_P;
}
}
// get source account ID
@@ -30,39 +72,59 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
boost::recursive_mutex::scoped_lock sl(mLedger->mLock);
// find source account
// If we are only verifying some transactions, this would be probablistic.
LedgerStateParms qry = lepNONE;
SerializedLedgerEntry::pointer src = mLedger->getAccountRoot(qry, srcAccount);
if (!src) return terNO_ACCOUNT;
// deduct the fee, so it's not available during the transaction
// we only write the account back if the transaction succeeds
uint64 balance = src->getIFieldU64(sfBalance);
if (balance < txnFee)
return terINSUF_FEE_B;
src->setIFieldU64(sfBalance, balance - txnFee);
// validate sequence
uint32 t_seq = txn.getSequence();
uint32 a_seq = src->getIFieldU32(sfSequence);
if (t_seq != a_seq)
if (txnFee)
{
// WRITEME: Special case code for changing transaction key
if (a_seq < t_seq) return terPRE_SEQ;
if (mLedger->hasTransaction(txID))
return terALREADY;
return terPAST_SEQ;
uint64 balance = src->getIFieldU64(sfBalance);
if (balance < txnFee)
return terINSUF_FEE_B;
src->setIFieldU64(sfBalance, balance - txnFee);
}
// Validate sequence
uint32 t_seq = txn.getSequence();
if (bPrepaid)
{
if (t_seq)
return terPAST_SEQ;
}
else
{
uint32 a_seq = src->getIFieldU32(sfSequence);
if (t_seq != a_seq)
{
// WRITEME: Special case code for changing transaction key
if (a_seq < t_seq) return terPRE_SEQ;
if (mLedger->hasTransaction(txID))
return terALREADY;
return terPAST_SEQ;
}
else src->setIFieldU32(sfSequence, t_seq);
}
else src->setIFieldU32(sfSequence, t_seq);
std::vector<AffectedAccount> accounts;
accounts.push_back(std::make_pair(taaMODIFY, src));
TransactionEngineResult result = terUNKNOWN;
switch(txn.getTxnType())
{
case ttINVALID:
result = terINVALID;
break;
case ttCLAIM:
result = doClaim(txn, accounts);
break;
case ttMAKE_PAYMENT:
result = doPayment(txn, accounts);
break;
@@ -110,6 +172,12 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
return result;
}
TransactionEngineResult TransactionEngine::doClaim(const SerializedTransaction& txn,
std::vector<AffectedAccount>& accounts)
{
return terUNKNOWN;
}
TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction& txn,
std::vector<AffectedAccount>& accounts)
{

View File

@@ -25,6 +25,7 @@ enum TransactionEngineResult
terUNFUNDED, // Source account had insufficient balance for transactin
terNO_PATH, // No path existed or met transaction/balance requirements
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
terPAST_LEDGER, // The transaction expired and can't be applied
};
@@ -51,13 +52,14 @@ class TransactionEngine
protected:
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 doOffer(const SerializedTransaction&, std::vector<AffectedAccount>&);
TransactionEngineResult doTake(const SerializedTransaction&, std::vector<AffectedAccount>&);
TransactionEngineResult doCancel(const SerializedTransaction&, std::vector<AffectedAccount>&);
TransactionEngineResult doPayment(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:
TransactionEngine() { ; }

View File

@@ -16,6 +16,13 @@ TransactionFormat InnerTxnFormats[]=
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
{ 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, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Target), STI_ACCOUNT, SOE_REQUIRED, 0 },

View File

@@ -5,10 +5,11 @@
enum TransactionType
{
ttINVALID=-1,
ttMAKE_PAYMENT=0,
ttINVOICE=1,
ttEXCHANGE_OFFER=2
ttINVALID = -1,
ttMAKE_PAYMENT = 0,
ttCLAIM = 1,
ttINVOICE = 2,
ttEXCHANGE_OFFER = 3
};
struct TransactionFormat
@@ -18,10 +19,14 @@ struct TransactionFormat
SOElement elements[16];
};
const int32 TransactionMagic=0x54584E00;
const int32 TransactionMagic = 0x54584E00; // 'TXN'
const int TransactionIVersion=0, TransactionISigningPubKey=1, TransactionISequence=2;
const int TransactionIType=3, TransactionIFee=4;
const int TransactionIVersion = 0;
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 TransactionMaxLen=1048576;