Rewrite a lot of the SerializedTransaction code. Mostly just removing obsolete code.

This commit is contained in:
JoelKatz
2012-09-28 19:12:56 -07:00
parent dc2e47b67c
commit 01c164c6fb
3 changed files with 91 additions and 261 deletions

View File

@@ -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<uint16>(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<TransactionType>(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<TransactionType>(sit.get16());
mMiddleTxn.giveObject(new STUInt16(sfTransactionType, static_cast<uint16>(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<NewcoinAddress> SerializedTransaction::getAffectedAccounts() const
{
std::vector<NewcoinAddress> accounts;
accounts.push_back(mSourceAccount);
BOOST_FOREACH(const SerializedType& it, mInnerTxn.peekData())
BOOST_FOREACH(const SerializedType& it, peekData())
{
const STAccount* sa = dynamic_cast<const STAccount*>(&it);
if (sa != NULL)
@@ -103,197 +81,70 @@ std::vector<NewcoinAddress> 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<const SerializedTransaction*>(&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<unsigned char> SerializedTransaction::getSignature() const
{
return mSignature.getValue();
try
{
return getValueFieldVL(sfSignature);
}
catch (...)
{
return std::vector<unsigned char>();
}
}
const std::vector<unsigned char>& 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<unsigned char> 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<unsigned char>& 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<const STAmount*>(mMiddleTxn.peekAtPIndex(TransactionIFee));
if (!v) throw std::runtime_error("corrupt transaction");
return *v;
}
void SerializedTransaction::setTransactionFee(const STAmount& fee)
{
STAmount* v = dynamic_cast<STAmount*>(mMiddleTxn.getPIndex(TransactionIFee));
if (!v) throw std::runtime_error("corrupt transaction");
v->setValue(fee);
}
uint32 SerializedTransaction::getSequence() const
{
const STUInt32* v = dynamic_cast<const STUInt32*>(mMiddleTxn.peekAtPIndex(TransactionISequence));
if (!v) throw std::runtime_error("corrupt transaction");
return v->getValue();
}
void SerializedTransaction::setSequence(uint32 seq)
{
STUInt32* v = dynamic_cast<STUInt32*>(mMiddleTxn.getPIndex(TransactionISequence));
if (!v) throw std::runtime_error("corrupt transaction");
v->setValue(seq);
}
std::vector<unsigned char> SerializedTransaction::getSigningPubKey() const
{
const STVariableLength* v =
dynamic_cast<const STVariableLength*>(mMiddleTxn.peekAtPIndex(TransactionISigningPubKey));
if (!v) throw std::runtime_error("corrupt transaction");
return v->getValue();
}
const std::vector<unsigned char>& SerializedTransaction::peekSigningPubKey() const
{
const STVariableLength* v=
dynamic_cast<const STVariableLength*>(mMiddleTxn.peekAtPIndex(TransactionISigningPubKey));
if (!v) throw std::runtime_error("corrupt transaction");
return v->peekValue();
}
std::vector<unsigned char>& SerializedTransaction::peekSigningPubKey()
{
STVariableLength* v = dynamic_cast<STVariableLength*>(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<STVariableLength*>(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<STAccount*>(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<const STAccount*>(st);
if (!ac) return r;
ac->getValueH160(r);
const STAccount* ac = dynamic_cast<const STAccount*>(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;
}