From 01c164c6fbdb796ff241c8fcdd19305006756b5b Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Fri, 28 Sep 2012 19:12:56 -0700 Subject: [PATCH] Rewrite a lot of the SerializedTransaction code. Mostly just removing obsolete code. --- src/SerializedTransaction.cpp | 241 +++++++--------------------------- src/SerializedTransaction.h | 105 +++++++-------- src/TransactionFormats.h | 6 - 3 files changed, 91 insertions(+), 261 deletions(-) diff --git a/src/SerializedTransaction.cpp b/src/SerializedTransaction.cpp index b8a5f96c9a..5d1bdc6fe2 100644 --- a/src/SerializedTransaction.cpp +++ b/src/SerializedTransaction.cpp @@ -7,21 +7,16 @@ #include "Log.h" #include "HashPrefixes.h" -SerializedTransaction::SerializedTransaction(TransactionType type) : mType(type) +SerializedTransaction::SerializedTransaction(TransactionType type) : STObject(sfTransaction), mType(type) { mFormat = getTxnFormat(type); - if (mFormat == NULL) throw std::runtime_error("invalid transaction type"); - - mMiddleTxn.giveObject(new STVariableLength(sfSigningPubKey)); - mMiddleTxn.giveObject(new STAccount(sfAccount)); - mMiddleTxn.giveObject(new STUInt32(sfSequence)); - mMiddleTxn.giveObject(new STUInt16(sfTransactionType, static_cast(type))); - mMiddleTxn.giveObject(new STAmount(sfFee)); - - mInnerTxn = STObject(mFormat->elements, sfInnerTransaction); + if (mFormat == NULL) + throw std::runtime_error("invalid transaction type"); + set(mFormat->elements); + setValueFieldU16(sfTransactionType, mFormat->t_type); } -SerializedTransaction::SerializedTransaction(SerializerIterator& sit) +SerializedTransaction::SerializedTransaction(SerializerIterator& sit) : STObject(sfTransaction) { int length = sit.getBytesLeft(); if ((length < TransactionMinLen) || (length > TransactionMaxLen)) @@ -30,27 +25,18 @@ SerializedTransaction::SerializedTransaction(SerializerIterator& sit) throw std::runtime_error("Transaction length invalid"); } - mSignature.setValue(sit.getVL()); + set(sit); + mType = static_cast(getValueFieldU16(sfTransactionType)); - mMiddleTxn.giveObject(new STVariableLength(sfSigningPubKey, sit.getVL())); - - STAccount sa(sfAccount, sit.getVL()); - mSourceAccount = sa.getValueNCA(); - mMiddleTxn.giveObject(new STAccount(sa)); - - mMiddleTxn.giveObject(new STUInt32(sfSequence, sit.get32())); - - mType = static_cast(sit.get16()); - mMiddleTxn.giveObject(new STUInt16(sfTransactionType, static_cast(mType))); mFormat = getTxnFormat(mType); if (!mFormat) + throw std::runtime_error("invalid transction type"); + setType(mFormat->elements); + if (!isValidForType()) { - Log(lsERROR) << "Transaction has invalid type"; - throw std::runtime_error("Transaction has invalid type"); + Log(lsDEBUG) << "Transaction not valid for type " << getJson(0); + throw std::runtime_error("transaction not valid"); } - mMiddleTxn.giveObject(STAmount::deserialize(sit, sfFee)); - - mInnerTxn = STObject(mFormat->elements, sit, sfInnerTransaction); } std::string SerializedTransaction::getFullText() const @@ -58,29 +44,21 @@ std::string SerializedTransaction::getFullText() const std::string ret = "\""; ret += getTransactionID().GetHex(); ret += "\" = {"; - ret += mSignature.getFullText(); - ret += mMiddleTxn.getFullText(); - ret += mInnerTxn.getFullText(); + ret += STObject::getFullText(); ret += "}"; return ret; } std::string SerializedTransaction::getText() const { - std::string ret = "{"; - ret += mSignature.getText(); - ret += mMiddleTxn.getText(); - ret += mInnerTxn.getText(); - ret += "}"; - return ret; + return STObject::getText(); } std::vector SerializedTransaction::getAffectedAccounts() const { std::vector accounts; - accounts.push_back(mSourceAccount); - BOOST_FOREACH(const SerializedType& it, mInnerTxn.peekData()) + BOOST_FOREACH(const SerializedType& it, peekData()) { const STAccount* sa = dynamic_cast(&it); if (sa != NULL) @@ -103,197 +81,70 @@ std::vector SerializedTransaction::getAffectedAccounts() const return accounts; } -void SerializedTransaction::add(Serializer& s) const -{ - mSignature.add(s); - mMiddleTxn.add(s); - mInnerTxn.add(s); -} - -bool SerializedTransaction::isEquivalent(const SerializedType& t) const -{ // Signatures are not compared - const SerializedTransaction* v = dynamic_cast(&t); - if (!v) return false; - if (mType != v->mType) return false; - if (mMiddleTxn != v->mMiddleTxn) return false; - if (mInnerTxn != v->mInnerTxn) return false; - return true; -} - uint256 SerializedTransaction::getSigningHash() const { - Serializer s; - s.add32(sHP_TransactionSign); - mMiddleTxn.add(s); - mInnerTxn.add(s); - return s.getSHA512Half(); + return STObject::getSigningHash(sHP_TransactionSign); } uint256 SerializedTransaction::getTransactionID() const { // perhaps we should cache this - Serializer s; - s.add32(sHP_TransactionID); - mSignature.add(s); - mMiddleTxn.add(s); - mInnerTxn.add(s); - return s.getSHA512Half(); + return getHash(sHP_TransactionID); } std::vector SerializedTransaction::getSignature() const { - return mSignature.getValue(); + try + { + return getValueFieldVL(sfSignature); + } + catch (...) + { + return std::vector(); + } } -const std::vector& SerializedTransaction::peekSignature() const +void SerializedTransaction::sign(const NewcoinAddress& naAccountPrivate) { - return mSignature.peekValue(); -} - -bool SerializedTransaction::sign(const NewcoinAddress& naAccountPrivate) -{ - return naAccountPrivate.accountPrivateSign(getSigningHash(), mSignature.peekValue()); + std::vector signature; + naAccountPrivate.accountPrivateSign(getSigningHash(), signature); + setValueFieldVL(sfSignature, signature); } bool SerializedTransaction::checkSign(const NewcoinAddress& naAccountPublic) const { - return naAccountPublic.accountPublicVerify(getSigningHash(), mSignature.getValue()); + try + { + return naAccountPublic.accountPublicVerify(getSigningHash(), getValueFieldVL(sfSignature)); + } + catch (...) + { + return false; + } } -void SerializedTransaction::setSignature(const std::vector& sig) +void SerializedTransaction::setSigningPubKey(const NewcoinAddress& naSignPubKey) { - mSignature.setValue(sig); + setValueFieldVL(sfSigningPubKey, naSignPubKey.getAccountPublic()); } -STAmount SerializedTransaction::getTransactionFee() const +void SerializedTransaction::setSourceAccount(const NewcoinAddress& naSource) { - const STAmount* v = dynamic_cast(mMiddleTxn.peekAtPIndex(TransactionIFee)); - if (!v) throw std::runtime_error("corrupt transaction"); - return *v; -} - -void SerializedTransaction::setTransactionFee(const STAmount& fee) -{ - STAmount* v = dynamic_cast(mMiddleTxn.getPIndex(TransactionIFee)); - if (!v) throw std::runtime_error("corrupt transaction"); - v->setValue(fee); -} - -uint32 SerializedTransaction::getSequence() const -{ - const STUInt32* v = dynamic_cast(mMiddleTxn.peekAtPIndex(TransactionISequence)); - if (!v) throw std::runtime_error("corrupt transaction"); - return v->getValue(); -} - -void SerializedTransaction::setSequence(uint32 seq) -{ - STUInt32* v = dynamic_cast(mMiddleTxn.getPIndex(TransactionISequence)); - if (!v) throw std::runtime_error("corrupt transaction"); - v->setValue(seq); -} - -std::vector SerializedTransaction::getSigningPubKey() const -{ - const STVariableLength* v = - dynamic_cast(mMiddleTxn.peekAtPIndex(TransactionISigningPubKey)); - if (!v) throw std::runtime_error("corrupt transaction"); - return v->getValue(); -} - -const std::vector& SerializedTransaction::peekSigningPubKey() const -{ - const STVariableLength* v= - dynamic_cast(mMiddleTxn.peekAtPIndex(TransactionISigningPubKey)); - if (!v) throw std::runtime_error("corrupt transaction"); - return v->peekValue(); -} - -std::vector& SerializedTransaction::peekSigningPubKey() -{ - STVariableLength* v = dynamic_cast(mMiddleTxn.getPIndex(TransactionISigningPubKey)); - if (!v) throw std::runtime_error("corrupt transaction"); - return v->peekValue(); -} - -const NewcoinAddress& SerializedTransaction::setSigningPubKey(const NewcoinAddress& naSignPubKey) -{ - mSignPubKey = naSignPubKey; - - STVariableLength* v = dynamic_cast(mMiddleTxn.getPIndex(TransactionISigningPubKey)); - if (!v) throw std::runtime_error("corrupt transaction"); - v->setValue(mSignPubKey.getAccountPublic()); - - return mSignPubKey; -} - -const NewcoinAddress& SerializedTransaction::setSourceAccount(const NewcoinAddress& naSource) -{ - mSourceAccount = naSource; - - STAccount* v = dynamic_cast(mMiddleTxn.getPIndex(TransactionISourceID)); - if (!v) throw std::runtime_error("corrupt transaction"); - v->setValueNCA(mSourceAccount); - return mSourceAccount; + setValueFieldAccount(sfAccount, naSource); } uint160 SerializedTransaction::getITFieldAccount(SField::ref field) const { uint160 r; - const SerializedType* st = mInnerTxn.peekAtPField(field); - if (!st) return r; - - const STAccount* ac = dynamic_cast(st); - if (!ac) return r; - ac->getValueH160(r); + const STAccount* ac = dynamic_cast(peekAtPField(field)); + if (ac) + ac->getValueH160(r); return r; } -int SerializedTransaction::getITFieldIndex(SField::ref field) const -{ - return mInnerTxn.getFieldIndex(field); -} - -int SerializedTransaction::getITFieldCount() const -{ - return mInnerTxn.getCount(); -} - -bool SerializedTransaction::getITFieldPresent(SField::ref field) const -{ - return mInnerTxn.isFieldPresent(field); -} - -const SerializedType& SerializedTransaction::peekITField(SField::ref field) const -{ - return mInnerTxn.peekAtField(field); -} - -SerializedType& SerializedTransaction::getITField(SField::ref field) -{ - return mInnerTxn.getField(field); -} - -void SerializedTransaction::makeITFieldPresent(SField::ref field) -{ - mInnerTxn.makeFieldPresent(field); -} - -void SerializedTransaction::makeITFieldAbsent(SField::ref field) -{ - return mInnerTxn.makeFieldAbsent(field); -} - Json::Value SerializedTransaction::getJson(int options) const { - Json::Value ret = Json::objectValue; + Json::Value ret = STObject::getJson(0); ret["id"] = getTransactionID().GetHex(); - ret["signature"] = mSignature.getText(); - - Json::Value middle = mMiddleTxn.getJson(options); - middle["type"] = mFormat->t_name; - ret["middle"] = middle; - - ret["inner"] = mInnerTxn.getJson(options); return ret; } diff --git a/src/SerializedTransaction.h b/src/SerializedTransaction.h index ce997b5b8c..953cf20947 100644 --- a/src/SerializedTransaction.h +++ b/src/SerializedTransaction.h @@ -17,17 +17,13 @@ #define TXN_SQL_INCLUDED 'I' #define TXN_SQL_UNKNOWN 'U' -class SerializedTransaction : public SerializedType +class SerializedTransaction : public STObject { public: typedef boost::shared_ptr pointer; protected: - NewcoinAddress mSignPubKey; - NewcoinAddress mSourceAccount; TransactionType mType; - STVariableLength mSignature; - STObject mMiddleTxn, mInnerTxn; const TransactionFormat* mFormat; SerializedTransaction* duplicate() const { return new SerializedTransaction(*this); } @@ -40,80 +36,69 @@ public: SerializedTypeID getSType() const { return STI_TRANSACTION; } std::string getFullText() const; std::string getText() const; - void add(Serializer& s) const; - virtual bool isEquivalent(const SerializedType& t) const; // outer transaction functions / signature functions std::vector getSignature() const; - const std::vector& peekSignature() const; - void setSignature(const std::vector& s); + void setSignature(const std::vector& s) { setValueFieldVL(sfSignature, s); } uint256 getSigningHash() const; - TransactionType getTxnType() const { return mType; } - STAmount getTransactionFee() const; - void setTransactionFee(const STAmount& fee); + TransactionType getTxnType() const { return mType; } + STAmount getTransactionFee() const { return getValueFieldAmount(sfFee); } + void setTransactionFee(const STAmount& fee) { setValueFieldAmount(sfFee, fee); } - const NewcoinAddress& getSourceAccount() const { return mSourceAccount; } + NewcoinAddress getSourceAccount() const { return getValueFieldAccount(sfAccount); } std::vector getSigningPubKey() const; - const std::vector& peekSigningPubKey() const; - std::vector& peekSigningPubKey(); - const NewcoinAddress& setSigningPubKey(const NewcoinAddress& naSignPubKey); - const NewcoinAddress& setSourceAccount(const NewcoinAddress& naSource); + void setSigningPubKey(const NewcoinAddress& naSignPubKey); + void 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 { return getValueFieldU32(sfSequence); } + void setSequence(uint32 seq) { return setValueFieldU32(sfSequence, seq); } - uint32 getSequence() const; - void setSequence(uint32); + // inner transaction field functions (OBSOLETE - use STObject functions) + int getITFieldIndex(SField::ref field) const { return getFieldIndex(field); } + const SerializedType& peekITField(SField::ref field) const { return peekAtField(field); } + SerializedType& getITField(SField::ref field) { return getField(field); } - // inner transaction field functions - int getITFieldIndex(SField::ref field) const; - int getITFieldCount() const; - const SerializedType& peekITField(SField::ref field) const; - SerializedType& getITField(SField::ref field); - - // inner transaction field value functions - std::string getITFieldString(SField::ref field) const { return mInnerTxn.getFieldString(field); } - unsigned char getITFieldU8(SField::ref field) const { return mInnerTxn.getValueFieldU8(field); } - uint16 getITFieldU16(SField::ref field) const { return mInnerTxn.getValueFieldU16(field); } - uint32 getITFieldU32(SField::ref field) const { return mInnerTxn.getValueFieldU32(field); } - uint64 getITFieldU64(SField::ref field) const { return mInnerTxn.getValueFieldU64(field); } - uint128 getITFieldH128(SField::ref field) const { return mInnerTxn.getValueFieldH128(field); } - uint160 getITFieldH160(SField::ref field) const { return mInnerTxn.getValueFieldH160(field); } + // inner transaction field value functions (OBSOLETE - use STObject functions) + std::string getITFieldString(SField::ref field) const { return getFieldString(field); } + unsigned char getITFieldU8(SField::ref field) const { return getValueFieldU8(field); } + uint16 getITFieldU16(SField::ref field) const { return getValueFieldU16(field); } + uint32 getITFieldU32(SField::ref field) const { return getValueFieldU32(field); } + uint64 getITFieldU64(SField::ref field) const { return getValueFieldU64(field); } + uint128 getITFieldH128(SField::ref field) const { return getValueFieldH128(field); } + uint160 getITFieldH160(SField::ref field) const { return getValueFieldH160(field); } uint160 getITFieldAccount(SField::ref field) const; - uint256 getITFieldH256(SField::ref field) const { return mInnerTxn.getValueFieldH256(field); } - std::vector getITFieldVL(SField::ref field) const { return mInnerTxn.getValueFieldVL(field); } - std::vector getITFieldTL(SField::ref field) const { return mInnerTxn.getValueFieldTL(field); } - STAmount getITFieldAmount(SField::ref field) const { return mInnerTxn.getValueFieldAmount(field); } - STPathSet getITFieldPathSet(SField::ref field) const { return mInnerTxn.getValueFieldPathSet(field); } + uint256 getITFieldH256(SField::ref field) const { return getValueFieldH256(field); } + std::vector getITFieldVL(SField::ref field) const { return getValueFieldVL(field); } + std::vector getITFieldTL(SField::ref field) const { return getValueFieldTL(field); } + STAmount getITFieldAmount(SField::ref field) const { return getValueFieldAmount(field); } + STPathSet getITFieldPathSet(SField::ref field) const { return getValueFieldPathSet(field); } - void setITFieldU8(SField::ref field, unsigned char v) { return mInnerTxn.setValueFieldU8(field, v); } - void setITFieldU16(SField::ref field, uint16 v) { return mInnerTxn.setValueFieldU16(field, v); } - void setITFieldU32(SField::ref field, uint32 v) { return mInnerTxn.setValueFieldU32(field, v); } - void setITFieldU64(SField::ref field, uint32 v) { return mInnerTxn.setValueFieldU64(field, v); } - void setITFieldH128(SField::ref field, const uint128& v) { return mInnerTxn.setValueFieldH128(field, v); } - void setITFieldH160(SField::ref field, const uint160& v) { return mInnerTxn.setValueFieldH160(field, v); } - void setITFieldH256(SField::ref field, const uint256& v) { return mInnerTxn.setValueFieldH256(field, v); } + void setITFieldU8(SField::ref field, unsigned char v) { return setValueFieldU8(field, v); } + void setITFieldU16(SField::ref field, uint16 v) { return setValueFieldU16(field, v); } + void setITFieldU32(SField::ref field, uint32 v) { return setValueFieldU32(field, v); } + void setITFieldU64(SField::ref field, uint32 v) { return setValueFieldU64(field, v); } + void setITFieldH128(SField::ref field, const uint128& v) { return setValueFieldH128(field, v); } + void setITFieldH160(SField::ref field, const uint160& v) { return setValueFieldH160(field, v); } + void setITFieldH256(SField::ref field, const uint256& v) { return setValueFieldH256(field, v); } void setITFieldVL(SField::ref field, const std::vector& v) - { return mInnerTxn.setValueFieldVL(field, v); } + { return setValueFieldVL(field, v); } void setITFieldTL(SField::ref field, const std::vector& v) - { return mInnerTxn.setValueFieldTL(field, v); } + { return setValueFieldTL(field, v); } void setITFieldAccount(SField::ref field, const uint160& v) - { return mInnerTxn.setValueFieldAccount(field, v); } + { return setValueFieldAccount(field, v); } void setITFieldAccount(SField::ref field, const NewcoinAddress& v) - { return mInnerTxn.setValueFieldAccount(field, v); } + { return setValueFieldAccount(field, v); } void setITFieldAmount(SField::ref field, const STAmount& v) - { return mInnerTxn.setValueFieldAmount(field, v); } + { return setValueFieldAmount(field, v); } void setITFieldPathSet(SField::ref field, const STPathSet& v) - { return mInnerTxn.setValueFieldPathSet(field, v); } + { return setValueFieldPathSet(field, v); } - // optional field functions - bool getITFieldPresent(SField::ref field) const; - void makeITFieldPresent(SField::ref field); - void makeITFieldAbsent(SField::ref field); + // optional field functions (OBSOLETE - use STObject functions) + bool getITFieldPresent(SField::ref field) const { return isFieldPresent(field); } + void makeITFieldPresent(SField::ref field) { makeFieldPresent(field); } + void makeITFieldAbsent(SField::ref field) { makeFieldAbsent(field); } std::vector getAffectedAccounts() const; @@ -121,7 +106,7 @@ public: virtual Json::Value getJson(int options) const; - bool sign(const NewcoinAddress& naAccountPrivate); + void sign(const NewcoinAddress& naAccountPrivate); bool checkSign(const NewcoinAddress& naAccountPublic) const; // SQL Functions diff --git a/src/TransactionFormats.h b/src/TransactionFormats.h index 0efaf03397..edbccf3a69 100644 --- a/src/TransactionFormats.h +++ b/src/TransactionFormats.h @@ -28,12 +28,6 @@ struct TransactionFormat SOElement elements[24]; }; -const int TransactionISigningPubKey = 0; -const int TransactionISourceID = 1; -const int TransactionISequence = 2; -const int TransactionIType = 3; -const int TransactionIFee = 4; - const int TransactionMinLen = 32; const int TransactionMaxLen = 1048576;