From 058d4fd480b14bf6ab9d5a7622c97808e357fd3e Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Thu, 17 May 2012 00:42:12 -0700 Subject: [PATCH] Class to handle ledger proposals. We need this because they're signed and so must be canonicalized. --- src/LedgerProposal.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++ src/LedgerProposal.h | 48 +++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 src/LedgerProposal.cpp create mode 100644 src/LedgerProposal.h diff --git a/src/LedgerProposal.cpp b/src/LedgerProposal.cpp new file mode 100644 index 0000000000..dba8532917 --- /dev/null +++ b/src/LedgerProposal.cpp @@ -0,0 +1,61 @@ + +#include "LedgerProposal.h" + +#include + +LedgerProposal::LedgerProposal(SerializerIterator& it) : mKey(boost::make_shared()) +{ + if (it.get32() != sProposeMagic) + throw std::runtime_error("Not a ledger proposal"); + + mPreviousLedger = it.get256(); + mCurrentHash = it.get256(); + mPrevHash = it.get256(); + mProposeSeq = it.get32(); + if (mKey->SetPubKey(it.getVL())) + throw std::runtime_error("Unable to set public key"); + mSignature = it.getVL(); + + mPeerID = Serializer::getSHA512Half(mKey->GetPubKey()); + + if (!mKey->Verify(getSigningHash(), mSignature)) + throw std::runtime_error("Ledger proposal invalid"); +} + +LedgerProposal::LedgerProposal(CKey::pointer mPrivateKey, const uint256& prevLgr, const uint256& position) : + mPreviousLedger(prevLgr), mCurrentHash(position), mProposeSeq(0), mKey(mPrivateKey) +{ + mPeerID = Serializer::getSHA512Half(mKey->GetPubKey()); + if (!mKey->Sign(getSigningHash(), mSignature)) + throw std::runtime_error("Unable to sign proposal"); +} + +LedgerProposal::LedgerProposal(LedgerProposal::pointer previous, const uint256& newp) : + mPeerID(previous->mPeerID), mPreviousLedger(previous->mPreviousLedger), mPrevHash(previous->mCurrentHash), + mCurrentHash(newp), mProposeSeq(previous->mProposeSeq + 1), mKey(previous->mKey) +{ + if (!mKey->Sign(getSigningHash(), mSignature)) + throw std::runtime_error("Unable to sign proposal"); +} + +void LedgerProposal::add(Serializer& s, bool for_signature) const +{ + s.add32(sProposeMagic); + s.add256(mPreviousLedger); + s.add256(mCurrentHash); + s.add256(mPrevHash); + s.add32(mProposeSeq); + + if (for_signature) + return; + + s.addVL(mKey->GetPubKey()); + s.addVL(mSignature); +} + +uint256 LedgerProposal::getSigningHash() const +{ + Serializer s(104); + add(s, true); + return s.getSHA512Half(); +} diff --git a/src/LedgerProposal.h b/src/LedgerProposal.h new file mode 100644 index 0000000000..a36c3a77f9 --- /dev/null +++ b/src/LedgerProposal.h @@ -0,0 +1,48 @@ +#ifndef __PROPOSELEDGER__ +#define __PROPOSELEDEGR__ + +#include + +#include + +#include "uint256.h" +#include "key.h" +#include "Serializer.h" + +class LedgerProposal +{ +protected: + + uint256 mPeerID, mPreviousLedger, mPrevHash, mCurrentHash; + uint32 mProposeSeq; + CKey::pointer mKey; + std::vector mSignature; +// std::vector mAddedTx, mRemovedTx; + + static const uint32 sProposeMagic = 0x50525000; // PRP + +public: + + typedef boost::shared_ptr pointer; + + // proposal from peer + LedgerProposal(SerializerIterator& it); + + // our first proposal + LedgerProposal(CKey::pointer privateKey, const uint256& prevLedger, const uint256& position); + + // our following proposals + LedgerProposal(LedgerProposal::pointer previous, const uint256& newPosition); + + void add(Serializer&, bool for_signature) const; + uint256 getSigningHash() const; + + const uint256& getPeerID() const { return mPeerID; } + const uint256& getPrevHash() const { return mPrevHash; } + const uint256& getCurrentHash() const { return mCurrentHash; } + const uint256& getPrevLedger() const { return mPreviousLedger; } + uint32 getProposeSeq() const { return mProposeSeq; } + +}; + +#endif