diff --git a/src/LedgerProposal.cpp b/src/LedgerProposal.cpp new file mode 100644 index 000000000..dba853291 --- /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 000000000..a36c3a77f --- /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 diff --git a/src/SerializedLedger.h b/src/SerializedLedger.h index 51974fbe4..925704968 100644 --- a/src/SerializedLedger.h +++ b/src/SerializedLedger.h @@ -54,6 +54,7 @@ public: std::vector getIFieldVL(SOE_Field field) const { return mObject.getValueFieldVL(field); } std::vector getIFieldTL(SOE_Field field) const { return mObject.getValueFieldTL(field); } NewcoinAddress getIValueFieldAccount(SOE_Field field) const { return mObject.getValueFieldAccount(field); } + STAmount getIValueFieldAmount(SOE_Field field) const { return mObject.getValueFieldAmount(field); } void setIFieldU8(SOE_Field field, unsigned char v) { return mObject.setValueFieldU8(field, v); } void setIFieldU16(SOE_Field field, uint16 v) { return mObject.setValueFieldU16(field, v); } void setIFieldU32(SOE_Field field, uint32 v) { return mObject.setValueFieldU32(field, v); } @@ -68,6 +69,8 @@ public: { return mObject.setValueFieldAccount(field, account); } void setIFieldAccount(SOE_Field field, const NewcoinAddress& account) { return mObject.setValueFieldAccount(field, account); } + void setIFeldAmount(SOE_Field field, const STAmount& amount) + { return mObject.setValueFieldAmount(field, amount); } bool getIFieldPresent(SOE_Field field) const { return mObject.isFieldPresent(field); } void makeIFieldPresent(SOE_Field field) { mObject.makeFieldPresent(field); } diff --git a/src/SerializedObject.cpp b/src/SerializedObject.cpp index aef0f9cf7..c2cf3c267 100644 --- a/src/SerializedObject.cpp +++ b/src/SerializedObject.cpp @@ -429,6 +429,17 @@ std::vector STObject::getValueFieldTL(SOE_Field field) const return cf->getValue(); } +STAmount STObject::getValueFieldAmount(SOE_Field field) const +{ + const SerializedType* rf = peekAtPField(field); + if (!rf) throw std::runtime_error("Field not found"); + SerializedTypeID id = rf->getSType(); + if (id == STI_NOTPRESENT) return STAmount(); // optional field not present + const STAmount *cf = dynamic_cast(rf); + if (!cf) throw std::runtime_error("Wrong field type"); + return *cf; +} + void STObject::setValueFieldU8(SOE_Field field, unsigned char v) { SerializedType* rf = getPField(field); @@ -519,6 +530,16 @@ void STObject::setValueFieldTL(SOE_Field field, const std::vectorsetValue(v); } +void STObject::setValueFieldAmount(SOE_Field field, const STAmount &v) +{ + SerializedType* rf = getPField(field); + if (!rf) throw std::runtime_error("Field not found"); + if (rf->getSType() == STI_NOTPRESENT) rf = makeFieldPresent(field); + STAmount* cf = dynamic_cast(rf); + if (!cf) throw std::runtime_error("Wrong field type"); + (*cf) = v; +} + Json::Value STObject::getJson(int options) const { Json::Value ret(Json::objectValue); diff --git a/src/SerializedObject.h b/src/SerializedObject.h index 88e5d902f..9a2815171 100644 --- a/src/SerializedObject.h +++ b/src/SerializedObject.h @@ -145,6 +145,7 @@ public: NewcoinAddress getValueFieldAccount(SOE_Field field) const; std::vector getValueFieldVL(SOE_Field field) const; std::vector getValueFieldTL(SOE_Field field) const; + STAmount getValueFieldAmount(SOE_Field field) const; void setValueFieldU8(SOE_Field field, unsigned char); void setValueFieldU16(SOE_Field field, uint16); @@ -157,6 +158,7 @@ public: void setValueFieldAccount(SOE_Field field, const uint160&); void setValueFieldAccount(SOE_Field field, const NewcoinAddress& addr) { setValueFieldAccount(field, addr.getAccountID()); } + void setValueFieldAmount(SOE_Field field, const STAmount&); bool isFieldPresent(SOE_Field field) const; SerializedType* makeFieldPresent(SOE_Field field); diff --git a/src/SerializedTransaction.h b/src/SerializedTransaction.h index ff30e63e0..587387e73 100644 --- a/src/SerializedTransaction.h +++ b/src/SerializedTransaction.h @@ -84,6 +84,7 @@ public: uint256 getITFieldH256(SOE_Field field) const { return mInnerTxn.getValueFieldH256(field); } std::vector getITFieldVL(SOE_Field field) const { return mInnerTxn.getValueFieldVL(field); } std::vector getITFieldTL(SOE_Field field) const { return mInnerTxn.getValueFieldTL(field); } + STAmount getITFieldAmount(SOE_Field field) const { return mInnerTxn.getValueFieldAmount(field); } void setITFieldU8(SOE_Field field, unsigned char v) { return mInnerTxn.setValueFieldU8(field, v); } void setITFieldU16(SOE_Field field, uint16 v) { return mInnerTxn.setValueFieldU16(field, v); } void setITFieldU32(SOE_Field field, uint32 v) { return mInnerTxn.setValueFieldU32(field, v); } @@ -98,6 +99,8 @@ public: { return mInnerTxn.setValueFieldAccount(field, v); } void setITFieldAccount(SOE_Field field, const NewcoinAddress& v) { return mInnerTxn.setValueFieldAccount(field, v); } + void setITFieldAmount(SOE_Field field, const STAmount& v) + { return mInnerTxn.setValueFieldAmount(field, v); } // optional field functions bool getITFieldPresent(SOE_Field field) const;