More work on core ledger and transaction processing code.

This commit is contained in:
JoelKatz
2011-11-22 15:42:03 -08:00
parent 41309b6f72
commit 6c7fd5f195
10 changed files with 253 additions and 106 deletions

View File

@@ -11,65 +11,83 @@ Transaction::Transaction() : mTransactionID(0), mAccountFrom(0), mAccountTo(0),
{
}
Transaction::Transaction(TransStatus status, LocalAccount& fromLocalAccount, Account& fromAccount,
uint32 fromSeq, const uint160& toAccount, uint64 amount, uint32 ident, uint32 ledger) :
mAccountTo(toAccount), mAmount(amount), mFromAccountSeq(fromSeq), mSourceLedger(ledger),
mIdent(ident), mInLedger(0), mStatus(NEW)
Transaction::Transaction(TransStatus status, LocalAccount& fromLocalAccount, uint32 fromSeq,
const uint160& toAccount, uint64 amount, uint32 ident, uint32 ledger) :
mAccountTo(toAccount), mAmount(amount), mFromAccountSeq(fromSeq), mSourceLedger(ledger),
mIdent(ident), mInLedger(0), mStatus(NEW)
{
assert(fromAccount.getAddress()==fromLocalAccount.mAddress);
assert(fromLocalAccount.mAmount>=amount);
assert((fromSeq+1)==fromLocalAccount.mSeqNum);
mAccountFrom=fromAccount.getAddress();
mAccountFrom=fromLocalAccount.getAddress();
updateFee();
mFromPubKey.SetPubKey(fromLocalAccount.peekPubKey().GetPubKey());
sign(fromLocalAccount);
}
Transaction::Transaction(const std::vector<unsigned char> &t, bool validate) : mStatus(INVALID)
{
Serializer s(t);
if(s.getLength()<145) return;
if(!s.get160(mAccountTo, 0)) return;
if(!s.get64(mAmount, 20)) return;
if(!s.get32(mFromAccountSeq, 28)) return;
if(!s.get32(mSourceLedger, 32)) return;
if(!s.get32(mIdent, 36)) return;
if(!s.getRaw(mSignature, 69, 72)) return;
std::vector<unsigned char> pubKey;
if(!s.getRaw(pubKey, 40, 33)) return;
if(!mFromPubKey.SetPubKey(pubKey)) return;
updateID();
if(validate && !checkSign()) return;
mStatus=NEW;
}
bool Transaction::sign(LocalAccount& fromLocalAccount)
{
if( (mAmount==0) || (mSourceLedger==0) || (mAccountTo==0) )
return false;
if(mpAccountFrom == Account::pointer())
if(mAccountFrom!=fromLocalAccount.mAddress)
return false;
if((mpAccountFrom->getAddress()!=fromLocalAccount.mAddress) || (mAccountFrom!=mpAccountFrom->getAddress()))
return false;
Serializer::pointer signBuf(getRawUnsigned());
Serializer::pointer signBuf=getRaw(true);
if(!signBuf->makeSignature(mSignature, fromLocalAccount.peekPrivKey()))
return false;
signBuf->addRaw(mSignature);
mTransactionID=signBuf->getSHA512Half();
updateID();
return true;
}
void Transaction::updateFee()
{ // for now, all transactions have a 1,000 unit fee
mFee=1000;
}
bool Transaction::checkSign() const
{
if(mpAccountFrom == Account::pointer()) return false;
if(mpAccountFrom->getAddress()!=mAccountFrom) return false;
Serializer::pointer toSign(getRawUnsigned());
return toSign->checkSignature(mSignature, mpAccountFrom->peekPubKey());
return mFromPubKey.Verify(getRaw(true)->getSHA512Half(), mSignature);
}
Serializer::pointer Transaction::getRawUnsigned() const
Serializer::pointer Transaction::getRaw(bool prefix) const
{
Serializer::pointer ret(new Serializer(104));
ret->add32(0x54584e00u);
ret->addRaw(mpAccountFrom->peekPubKey().GetPubKey());
Serializer::pointer ret(new Serializer(77));
if(prefix) ret->add32(0x54584e00u);
ret->addRaw(mFromPubKey.GetPubKey());
ret->add64(mAmount);
ret->add32(mFromAccountSeq);
ret->add32(mInLedger);
ret->add32(mIdent);
assert( (prefix&&(ret->getLength()==77)) || (!prefix&&(ret->getLength()==73)) );
return ret;
}
Serializer::pointer Transaction::getRawSigned() const
Serializer::pointer Transaction::getSigned() const
{
Serializer::pointer ret(getRawUnsigned());
Serializer::pointer ret(getRaw(false));
ret->addRaw(mSignature);
return ret;
}
void Transaction::updateID()
{
if( (mpAccountFrom!=Account::pointer()) && (mpAccountFrom->getAddress()==mAccountFrom))
mTransactionID=getRawSigned()->getSHA512Half();
mTransactionID=getSigned()->getSHA512Half();
}