Fix mishandling of signing account.

Fix failure to set transaction type.
This commit is contained in:
JoelKatz
2012-04-20 13:30:18 -07:00
parent 3b6fca362b
commit ad8ff12803
3 changed files with 54 additions and 42 deletions

View File

@@ -1,9 +1,9 @@
#include "SerializedTransaction.h" #include "SerializedTransaction.h"
SerializedTransaction::SerializedTransaction(TransactionType type) SerializedTransaction::SerializedTransaction(TransactionType type) : mType(type)
{ {
mFormat=getTxnFormat(type); mFormat = getTxnFormat(type);
if (mFormat == NULL) throw std::runtime_error("invalid transaction type"); if (mFormat == NULL) throw std::runtime_error("invalid transaction type");
mMiddleTxn.giveObject(new STUInt32("Magic", TransactionMagic)); mMiddleTxn.giveObject(new STUInt32("Magic", TransactionMagic));
@@ -31,13 +31,21 @@ SerializedTransaction::SerializedTransaction(SerializerIterator& sit, int length
mMiddleTxn.giveObject(new STVariableLength("SigningAccount", sit.getVL())); mMiddleTxn.giveObject(new STVariableLength("SigningAccount", sit.getVL()));
mMiddleTxn.giveObject(new STUInt32("Sequence", sit.get32())); mMiddleTxn.giveObject(new STUInt32("Sequence", sit.get32()));
int type = sit.get32(); mType = static_cast<TransactionType>(sit.get32());
mMiddleTxn.giveObject(new STUInt32("Type", type)); mMiddleTxn.giveObject(new STUInt32("Type", static_cast<uint32>(mType)));
mFormat = getTxnFormat(static_cast<TransactionType>(type)); mFormat = getTxnFormat(mType);
if (!mFormat) throw std::runtime_error("Transaction has invalid type"); if (!mFormat) throw std::runtime_error("Transaction has invalid type");
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");
updateSigningAccount();
}
void SerializedTransaction::updateSigningAccount()
{
NewcoinAddress a;
a.setAccountPublic(peekRawSigningAccount());
mSigningAccount = a.getAccountID();
} }
int SerializedTransaction::getLength() const int SerializedTransaction::getLength() const
@@ -81,7 +89,7 @@ bool SerializedTransaction::isEquivalent(const SerializedType& t) const
{ // Signatures are not compared { // Signatures are not compared
const SerializedTransaction* v = dynamic_cast<const SerializedTransaction*>(&t); const SerializedTransaction* v = dynamic_cast<const SerializedTransaction*>(&t);
if (!v) return false; if (!v) return false;
if (type != v->type) return false; if (mType != v->mType) return false;
if (mMiddleTxn != v->mMiddleTxn) return false; if (mMiddleTxn != v->mMiddleTxn) return false;
if (mInnerTxn != v->mInnerTxn) return false; if (mInnerTxn != v->mInnerTxn) return false;
return true; return true;
@@ -171,7 +179,7 @@ void SerializedTransaction::setSequence(uint32 seq)
v->setValue(seq); v->setValue(seq);
} }
std::vector<unsigned char> SerializedTransaction::getSigningAccount() const std::vector<unsigned char> SerializedTransaction::getRawSigningAccount() const
{ {
const STVariableLength* v = const STVariableLength* v =
dynamic_cast<const STVariableLength*>(mMiddleTxn.peekAtPIndex(TransactionISigningAccount)); dynamic_cast<const STVariableLength*>(mMiddleTxn.peekAtPIndex(TransactionISigningAccount));
@@ -179,7 +187,7 @@ std::vector<unsigned char> SerializedTransaction::getSigningAccount() const
return v->getValue(); return v->getValue();
} }
const std::vector<unsigned char>& SerializedTransaction::peekSigningAccount() const const std::vector<unsigned char>& SerializedTransaction::peekRawSigningAccount() const
{ {
const STVariableLength* v= const STVariableLength* v=
dynamic_cast<const STVariableLength*>(mMiddleTxn.peekAtPIndex(TransactionISigningAccount)); dynamic_cast<const STVariableLength*>(mMiddleTxn.peekAtPIndex(TransactionISigningAccount));
@@ -187,7 +195,7 @@ const std::vector<unsigned char>& SerializedTransaction::peekSigningAccount() co
return v->peekValue(); return v->peekValue();
} }
std::vector<unsigned char>& SerializedTransaction::peekSigningAccount() std::vector<unsigned char>& SerializedTransaction::peekRawSigningAccount()
{ {
STVariableLength* v = dynamic_cast<STVariableLength*>(mMiddleTxn.getPIndex(TransactionISigningAccount)); STVariableLength* v = dynamic_cast<STVariableLength*>(mMiddleTxn.getPIndex(TransactionISigningAccount));
if (!v) throw std::runtime_error("corrupt transaction"); if (!v) throw std::runtime_error("corrupt transaction");
@@ -199,6 +207,7 @@ void SerializedTransaction::setSigningAccount(const std::vector<unsigned char>&
STVariableLength* v = dynamic_cast<STVariableLength*>(mMiddleTxn.getPIndex(TransactionISigningAccount)); STVariableLength* v = dynamic_cast<STVariableLength*>(mMiddleTxn.getPIndex(TransactionISigningAccount));
if (!v) throw std::runtime_error("corrupt transaction"); if (!v) throw std::runtime_error("corrupt transaction");
v->setValue(s); v->setValue(s);
updateSigningAccount();
} }
int SerializedTransaction::getITFieldIndex(SOE_Field field) const int SerializedTransaction::getITFieldIndex(SOE_Field field) const

View File

@@ -15,11 +15,14 @@ public:
typedef boost::shared_ptr<SerializedTransaction> pointer; typedef boost::shared_ptr<SerializedTransaction> pointer;
protected: protected:
TransactionType type; uint160 mSigningAccount;
TransactionType mType;
STVariableLength mSignature; STVariableLength mSignature;
STObject mMiddleTxn, mInnerTxn; STObject mMiddleTxn, mInnerTxn;
TransactionFormat* mFormat; TransactionFormat* mFormat;
void updateSigningAccount();
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);
@@ -42,12 +45,13 @@ public:
// middle transaction functions // middle transaction functions
uint32 getVersion() const; uint32 getVersion() const;
void setVersion(uint32); void setVersion(uint32);
TransactionType getTxnType() const { return type; } TransactionType getTxnType() const { return mType; }
uint64 getTransactionFee() const; uint64 getTransactionFee() const;
void setTransactionFee(uint64); void setTransactionFee(uint64);
std::vector<unsigned char> getSigningAccount() const; uint160 getSigningAccount() const;
const std::vector<unsigned char>& peekSigningAccount() const; std::vector<unsigned char> getRawSigningAccount() const;
std::vector<unsigned char>& peekSigningAccount(); const std::vector<unsigned char>& peekRawSigningAccount() const;
std::vector<unsigned char>& peekRawSigningAccount();
void setSigningAccount(const std::vector<unsigned char>& s); void setSigningAccount(const std::vector<unsigned char>& s);
std::string getTransactionType() const { return mFormat->t_name; } std::string getTransactionType() const { return mFormat->t_name; }

View File

@@ -14,53 +14,52 @@
Transaction::Transaction(LocalAccount::pointer fromLocalAccount, const NewcoinAddress& toAccount, uint64 amount, Transaction::Transaction(LocalAccount::pointer fromLocalAccount, const NewcoinAddress& toAccount, uint64 amount,
uint32 ident, uint32 ledger) : mInLedger(0), mStatus(NEW) uint32 ident, uint32 ledger) : mInLedger(0), mStatus(NEW)
{ {
mAccountFrom=fromLocalAccount->getAddress(); mAccountFrom = fromLocalAccount->getAddress();
mAccountTo=toAccount; mAccountTo = toAccount;
mTransaction=boost::make_shared<SerializedTransaction>(ttMAKE_PAYMENT); mTransaction = boost::make_shared<SerializedTransaction>(ttMAKE_PAYMENT);
mFromPubKey=fromLocalAccount->getPublicKey(); mFromPubKey = fromLocalAccount->getPublicKey();
assert(mFromPubKey); assert(mFromPubKey);
mTransaction->setSigningAccount(mFromPubKey->GetPubKey()); mTransaction->setSigningAccount(mFromPubKey->GetPubKey());
mTransaction->setSequence(fromLocalAccount->getTxnSeq()); mTransaction->setSequence(fromLocalAccount->getTxnSeq());
assert(mTransaction->getSequence()!=0); assert(mTransaction->getSequence() != 0);
mTransaction->setTransactionFee(100); // for now mTransaction->setTransactionFee(100); // for now
mTransaction->setITFieldVL(sfDestination, toAccount.getAccountPublic()); mTransaction->setITFieldVL(sfDestination, toAccount.getAccountPublic());
mTransaction->setITFieldU64(sfAmount, amount); mTransaction->setITFieldU64(sfAmount, amount);
if(ledger!=0) if (ledger != 0)
{ {
mTransaction->makeITFieldPresent(sfTargetLedger); mTransaction->makeITFieldPresent(sfTargetLedger);
mTransaction->setITFieldU32(sfTargetLedger, ledger); mTransaction->setITFieldU32(sfTargetLedger, ledger);
} }
if(ident!=0) if (ident != 0)
{ {
mTransaction->makeITFieldPresent(sfSourceTag); mTransaction->makeITFieldPresent(sfSourceTag);
mTransaction->setITFieldU32(sfSourceTag, ident); mTransaction->setITFieldU32(sfSourceTag, ident);
} }
assert(mFromPubKey); assert(mFromPubKey);
if(!sign(fromLocalAccount)) if (!sign(fromLocalAccount))
{ {
#ifdef DEBUG #ifdef DEBUG
std::cerr << "Unable to sign transaction" << std::endl; std::cerr << "Unable to sign transaction" << std::endl;
#endif #endif
mStatus=INCOMPLETE; mStatus = INCOMPLETE;
} }
} }
Transaction::Transaction(SerializedTransaction::pointer sit, bool validate) : mStatus(INVALID), mTransaction(sit) Transaction::Transaction(SerializedTransaction::pointer sit, bool validate) : mStatus(INVALID), mTransaction(sit)
{ {
uint160 toAccountID; uint160 toAccountID, fromAccountID;
uint160 fromAccountID;
std::vector<unsigned char> pubKey; std::vector<unsigned char> pubKey;
try try
{ {
toAccountID=mTransaction->getITFieldH160(sfDestination); toAccountID = mTransaction->getITFieldH160(sfDestination);
pubKey=mTransaction->getSigningAccount(); pubKey = mTransaction->getRawSigningAccount();
mTransactionID=mTransaction->getTransactionID(); mTransactionID = mTransaction->getTransactionID();
} }
catch(...) catch(...)
{ {
@@ -70,13 +69,13 @@ Transaction::Transaction(SerializedTransaction::pointer sit, bool validate) : mS
mAccountTo.setAccountID(toAccountID); mAccountTo.setAccountID(toAccountID);
mAccountFrom.setAccountID(fromAccountID); mAccountFrom.setAccountID(fromAccountID);
mFromPubKey=boost::make_shared<CKey>(); mFromPubKey = boost::make_shared<CKey>();
if(!mFromPubKey->SetPubKey(pubKey)) return; if (!mFromPubKey->SetPubKey(pubKey)) return;
mAccountFrom.setAccountPublic(pubKey); mAccountFrom.setAccountPublic(pubKey);
mFromPubKey=theApp->getPubKeyCache().store(mAccountFrom, mFromPubKey); mFromPubKey = theApp->getPubKeyCache().store(mAccountFrom, mFromPubKey);
if(!validate || checkSign()) if (!validate || checkSign())
mStatus=NEW; mStatus = NEW;
} }
Transaction::Transaction(const std::vector<unsigned char>& raw, bool validate) : mStatus(INVALID) Transaction::Transaction(const std::vector<unsigned char>& raw, bool validate) : mStatus(INVALID)
@@ -89,22 +88,22 @@ Transaction::Transaction(const std::vector<unsigned char>& raw, bool validate) :
{ {
Serializer s(raw); Serializer s(raw);
SerializerIterator sit(s); SerializerIterator sit(s);
mTransaction=boost::make_shared<SerializedTransaction>(boost::ref(sit), -1); mTransaction = boost::make_shared<SerializedTransaction>(boost::ref(sit), -1);
mFromPubKey=boost::make_shared<CKey>(); mFromPubKey = boost::make_shared<CKey>();
if(!mFromPubKey->SetPubKey(pubKey)) return; if (!mFromPubKey->SetPubKey(pubKey)) return;
mAccountFrom.setAccountPublic(pubKey); mAccountFrom.setAccountPublic(pubKey);
mFromPubKey=theApp->getPubKeyCache().store(mAccountFrom, mFromPubKey); mFromPubKey = theApp->getPubKeyCache().store(mAccountFrom, mFromPubKey);
if(!mFromPubKey->SetPubKey(pubKey)) return; if (!mFromPubKey->SetPubKey(pubKey)) return;
mAccountFrom.setAccountPublic(pubKey); mAccountFrom.setAccountPublic(pubKey);
mFromPubKey=theApp->getPubKeyCache().store(mAccountFrom, mFromPubKey); mFromPubKey = theApp->getPubKeyCache().store(mAccountFrom, mFromPubKey);
} }
catch(...) catch (...)
{ {
return; return;
} }
if(!validate || checkSign()) if (!validate || checkSign())
mStatus=NEW; mStatus = NEW;
} }
Transaction::Transaction(const NewcoinAddress& fromID, const NewcoinAddress& toID, Transaction::Transaction(const NewcoinAddress& fromID, const NewcoinAddress& toID,