Merge branch 'master' into pay

This commit is contained in:
Arthur Britto
2012-05-22 14:36:54 -07:00
13 changed files with 423 additions and 221 deletions

View File

@@ -23,7 +23,7 @@ uint160 humanTo160(const std::string& buf)
vector<unsigned char> retVec;
DecodeBase58(buf,retVec);
uint160 ret;
memcpy(reinterpret_cast<unsigned char*>(&ret), &retVec[0], ret.GetSerializeSize());
memcpy(ret.begin(), &retVec[0], ret.GetSerializeSize());
return(ret);

View File

@@ -238,19 +238,19 @@ void LedgerAcquire::trigger(Peer::pointer peer)
resetTimer();
}
void LedgerAcquire::sendRequest(boost::shared_ptr<newcoin::TMGetLedger> tmGL, Peer::pointer peer)
void PeerSet::sendRequest(boost::shared_ptr<newcoin::TMGetLedger> tmGL, Peer::pointer peer)
{
peer->sendPacket(boost::make_shared<PackedMessage>(tmGL, newcoin::mtGET_LEDGER));
}
void LedgerAcquire::sendRequest(boost::shared_ptr<newcoin::TMGetLedger> tmGL)
void PeerSet::sendRequest(boost::shared_ptr<newcoin::TMGetLedger> tmGL)
{
boost::recursive_mutex::scoped_lock sl(mLock);
if (mPeers.empty()) return;
PackedMessage::pointer packet = boost::make_shared<PackedMessage>(tmGL, newcoin::mtGET_LEDGER);
std::vector<boost::weak_ptr<Peer> >::iterator it = mPeers.begin();
std::vector< boost::weak_ptr<Peer> >::iterator it = mPeers.begin();
while (it != mPeers.end())
{
if (it->expired())
@@ -291,11 +291,11 @@ bool LedgerAcquire::takeBase(const std::string& data, Peer::pointer peer)
}
bool LedgerAcquire::takeTxNode(const std::list<SHAMapNode>& nodeIDs,
const std::list<std::vector<unsigned char> >& data, Peer::pointer peer)
const std::list< std::vector<unsigned char> >& data, Peer::pointer peer)
{
if (!mHaveBase) return false;
std::list<SHAMapNode>::const_iterator nodeIDit = nodeIDs.begin();
std::list<std::vector<unsigned char> >::const_iterator nodeDatait = data.begin();
std::list< std::vector<unsigned char> >::const_iterator nodeDatait = data.begin();
while (nodeIDit != nodeIDs.end())
{
if (nodeIDit->isRoot())
@@ -318,7 +318,7 @@ bool LedgerAcquire::takeTxNode(const std::list<SHAMapNode>& nodeIDs,
}
bool LedgerAcquire::takeAsNode(const std::list<SHAMapNode>& nodeIDs,
const std::list<std::vector<unsigned char> >& data, Peer::pointer peer)
const std::list< std::vector<unsigned char> >& data, Peer::pointer peer)
{
#ifdef DEBUG
std::cerr << "got ASdata acquiring ledger " << mHash.GetHex() << std::endl;
@@ -391,7 +391,7 @@ bool LedgerAcquireMaster::gotLedgerData(newcoin::TMLedgerData& packet, Peer::poi
#endif
return false;
}
memcpy(&hash, packet.ledgerhash().data(), 32);
memcpy(hash.begin(), packet.ledgerhash().data(), 32);
#ifdef DEBUG
std::cerr << hash.GetHex() << std::endl;
#endif
@@ -409,7 +409,7 @@ bool LedgerAcquireMaster::gotLedgerData(newcoin::TMLedgerData& packet, Peer::poi
else if ((packet.type() == newcoin::liTX_NODE) || (packet.type() == newcoin::liAS_NODE))
{
std::list<SHAMapNode> nodeIDs;
std::list<std::vector<unsigned char> > nodeData;
std::list< std::vector<unsigned char> > nodeData;
if (packet.nodes().size() <= 0) return false;
for (int i = 0; i < packet.nodes().size(); ++i)

View File

@@ -29,6 +29,9 @@ protected:
PeerSet(const uint256& hash, int interval);
virtual ~PeerSet() { ; }
void sendRequest(boost::shared_ptr<newcoin::TMGetLedger> message);
void sendRequest(boost::shared_ptr<newcoin::TMGetLedger> message, Peer::pointer peer);
public:
const uint256& getHash() const { return mHash; }
bool isComplete() const { return mComplete; }
@@ -64,8 +67,6 @@ protected:
void done();
void onTimer() { trigger(Peer::pointer()); }
void sendRequest(boost::shared_ptr<newcoin::TMGetLedger> message);
void sendRequest(boost::shared_ptr<newcoin::TMGetLedger> message, Peer::pointer peer);
void newPeer(Peer::pointer peer) { trigger(peer); }
void trigger(Peer::pointer);
@@ -88,29 +89,6 @@ public:
Peer::pointer);
};
class TransactionAcquire : public PeerSet, public boost::enable_shared_from_this<TransactionAcquire>
{ // A transaction set we are trying to acquire
public:
typedef boost::shared_ptr<TransactionAcquire> pointer;
protected:
SHAMap::pointer mMap;
void onTimer() { trigger(Peer::pointer()); }
void newPeer(Peer::pointer peer) { trigger(peer); }
void done();
void trigger(Peer::pointer);
boost::weak_ptr<PeerSet> pmDowncast();
public:
TransactionAcquire(const uint256& hash);
SHAMap::pointer getMap();
bool takeNode(const std::list<SHAMapNode>& IDs, const std::list<std::vector<unsigned char> >& data,
Peer::pointer);
};
class LedgerAcquireMaster
{
protected:

View File

@@ -1,16 +1,169 @@
#include "LedgerConsensus.h"
TransactionAcquire::TransactionAcquire(const uint256& hash) : PeerSet(hash, 1), mHaveRoot(false)
{
mMap = boost::make_shared<SHAMap>();
mMap->setSynching();
}
void TransactionAcquire::done()
{
// insert SHAMap in finished set (as valid or invalid), remove ourselves from current set
// WRITEME
}
boost::weak_ptr<PeerSet> TransactionAcquire::pmDowncast()
{
return boost::shared_polymorphic_downcast<PeerSet, TransactionAcquire>(shared_from_this());
}
void TransactionAcquire::trigger(Peer::pointer peer)
{
if (mComplete || mFailed)
return;
if (!mHaveRoot)
{
boost::shared_ptr<newcoin::TMGetLedger> tmGL = boost::make_shared<newcoin::TMGetLedger>();
tmGL->set_ledgerhash(mHash.begin(), mHash.size());
tmGL->set_itype(newcoin::liTS_CANDIDATE);
*(tmGL->add_nodeids()) = SHAMapNode().getRawString();
sendRequest(tmGL);
}
if (mHaveRoot)
{
std::vector<SHAMapNode> nodeIDs;
std::vector<uint256> nodeHashes;
mMap->getMissingNodes(nodeIDs, nodeHashes, 256);
if (nodeIDs.empty())
{
if (mMap->isValid())
mComplete = true;
else
mFailed = true;
}
else
{
boost::shared_ptr<newcoin::TMGetLedger> tmGL = boost::make_shared<newcoin::TMGetLedger>();
tmGL->set_ledgerhash(mHash.begin(), mHash.size());
tmGL->set_itype(newcoin::liTS_CANDIDATE);
for (std::vector<SHAMapNode>::iterator it = nodeIDs.begin(); it != nodeIDs.end(); ++it)
*(tmGL->add_nodeids()) = it->getRawString();
if (peer)
sendRequest(tmGL, peer);
else
sendRequest(tmGL);
return;
}
}
if (mComplete || mFailed)
done();
else
resetTimer();
}
bool TransactionAcquire::takeNode(const std::list<SHAMapNode>& nodeIDs,
const std::list< std::vector<unsigned char> >& data, Peer::pointer peer)
{
if (mComplete || mFailed)
return true;
std::list<SHAMapNode>::const_iterator nodeIDit = nodeIDs.begin();
std::list< std::vector<unsigned char> >::const_iterator nodeDatait = data.begin();
while (nodeIDit != nodeIDs.end())
{
if (nodeIDit->isRoot())
{
if (!mMap->addRootNode(getHash(), *nodeDatait))
return false;
}
else if (!mMap->addKnownNode(*nodeIDit, *nodeDatait))
return false;
++nodeIDit;
++nodeDatait;
}
trigger(peer);
return true;
}
void LedgerConsensus::abort()
{
}
int LedgerConsensus::startup()
{
return 5;
return 1;
}
int LedgerConsensus::timerEntry()
{
return 5;
}
return 1;
}
SHAMap::pointer LedgerConsensus::getTransactionTree(const uint256& hash, bool doAcquire)
{
boost::unordered_map<uint256, SHAMap::pointer>::iterator it = mComplete.find(hash);
if (it == mComplete.end())
{ // we have not completed acuiqiring this ledger
if (doAcquire)
{
TransactionAcquire::pointer& acquiring = mAcquiring[hash];
if (!acquiring)
{
acquiring = boost::make_shared<TransactionAcquire>(hash);
startAcquiring(acquiring);
}
}
return SHAMap::pointer();
}
return it->second;
}
void LedgerConsensus::startAcquiring(TransactionAcquire::pointer acquire)
{
boost::unordered_map< uint256, std::vector< boost::weak_ptr<Peer> > >::iterator it =
mPeerData.find(acquire->getHash());
if (it != mPeerData.end())
{ // Add any peers we already know have his transaction set
std::vector< boost::weak_ptr<Peer> >& peerList = it->second;
std::vector< boost::weak_ptr<Peer> >::iterator pit = peerList.begin();
while (pit != peerList.end())
{
Peer::pointer pr = pit->lock();
if (!pr)
pit = peerList.erase(pit);
else
{
acquire->peerHas(pr);
++pit;
}
}
}
}
void LedgerConsensus::removePosition(LedgerProposal& position)
{
// WRITEME
}
void LedgerConsensus::addPosition(LedgerProposal& position)
{
// WRITEME
}
bool LedgerConsensus::peerPosition(LedgerProposal::pointer newPosition)
{
LedgerProposal::pointer& currentPosition = mPeerPositions[newPosition->getPeerID()];
if (!currentPosition)
{
if (newPosition->getProposeSeq() <= currentPosition->getProposeSeq())
return false;
// change in position
removePosition(*currentPosition);
}
currentPosition = newPosition;
addPosition(*currentPosition);
return true;
}

View File

@@ -12,36 +12,32 @@
#include "LedgerProposal.h"
#include "Peer.h"
class LCPosition
{ // A position taken by one of our trusted peers
class TransactionAcquire : public PeerSet, public boost::enable_shared_from_this<TransactionAcquire>
{ // A transaction set we are trying to acquire
public:
typedef boost::shared_ptr<TransactionAcquire> pointer;
protected:
uint256 mPubKeyHash;
CKey::pointer mPubKey;
uint256 mPreviousPosition, mCurrentPosition;
uint32 mSequence;
SHAMap::pointer mMap;
bool mHaveRoot;
void onTimer() { trigger(Peer::pointer()); }
void newPeer(Peer::pointer peer) { trigger(peer); }
void done();
void trigger(Peer::pointer);
boost::weak_ptr<PeerSet> pmDowncast();
public:
typedef boost::shared_ptr<LCPosition> pointer;
// for remote positions
LCPosition(uint32 closingSeq, uint32 proposeSeq, const uint256& previousTxHash,
const uint256& currentTxHash, CKey::pointer nodePubKey, const std::string& signature);
TransactionAcquire(const uint256& hash);
// for our initial position
LCPosition(CKey::pointer privKey, uint32 ledgerSeq, const uint256& currentPosition);
SHAMap::pointer getMap() { return mMap; }
// for our subsequent positions
LCPosition(LCPosition::pointer previousPosition, CKey::pointer privKey, const uint256& newPosition);
const uint256& getPubKeyHash() const { return mPubKeyHash; }
const uint256& getCurrentPosition() const { return mCurrentPosition; }
uint32 getSeq() const { return mSequence; }
bool verifySignature(const uint256& hash, const std::vector<unsigned char>& signature) const;
void setPosition(const uint256& position, uint32 sequence);
bool takeNode(const std::list<SHAMapNode>& IDs, const std::list< std::vector<unsigned char> >& data,
Peer::pointer);
};
class LCTransaction
{ // A transaction that may be disputed
protected:
@@ -75,19 +71,24 @@ protected:
Ledger::pointer mPreviousLedger, mCurrentLedger;
LedgerProposal::pointer mCurrentProposal;
LCPosition::pointer mOurPosition;
LedgerProposal::pointer mOurPosition;
// Convergence tracking, trusted peers indexed by hash of public key
boost::unordered_map<uint256, LCPosition::pointer> mPeerPositions;
boost::unordered_map<uint256, LedgerProposal::pointer, hash_SMN> mPeerPositions;
// Transaction Sets, indexed by hash of transaction tree
boost::unordered_map<uint256, SHAMap::pointer> mComplete;
boost::unordered_map<uint256, TransactionAcquire::pointer> mAcquiring;
boost::unordered_map<uint256, SHAMap::pointer, hash_SMN> mComplete;
boost::unordered_map<uint256, TransactionAcquire::pointer, hash_SMN> mAcquiring;
// Peer sets
boost::unordered_map<uint256, std::vector< boost::weak_ptr<Peer> > > mPeerData;
boost::unordered_map<uint256, std::vector< boost::weak_ptr<Peer> >, hash_SMN> mPeerData;
void weHave(const uint256& id, Peer::pointer avoidPeer);
void startAcquiring(TransactionAcquire::pointer);
SHAMap::pointer find(const uint256& hash);
void addPosition(LedgerProposal&);
void removePosition(LedgerProposal&);
public:
LedgerConsensus(Ledger::pointer previousLedger, Ledger::pointer currentLedger) :
@@ -98,21 +99,19 @@ public:
Ledger::pointer peekPreviousLedger() { return mPreviousLedger; }
Ledger::pointer peekCurrentLedger() { return mCurrentLedger; }
LCPosition::pointer getCreatePeerPosition(const uint256& pubKeyHash);
SHAMap::pointer getTransactionTree(const uint256& hash);
SHAMap::pointer getTransactionTree(const uint256& hash, bool doAcquire);
TransactionAcquire::pointer getAcquiring(const uint256& hash);
void acquireComplete(const uint256& hash);
LCPosition::pointer getPeerPosition(const uint256& peer);
// high-level functions
void abort();
bool peerPosition(Peer::pointer peer, const Serializer& report);
int timerEntry(void);
bool peerPosition(LedgerProposal::pointer);
bool peerHasSet(Peer::pointer peer, const std::vector<uint256>& sets);
bool peerGaveNodes(Peer::pointer peer, const uint256& setHash,
const std::list<SHAMapNode>& nodeIDs, const std::list< std::vector<unsigned char> >& nodeData);
int timerEntry(void);
};

View File

@@ -3,59 +3,44 @@
#include <boost/make_shared.hpp>
LedgerProposal::LedgerProposal(SerializerIterator& it) : mKey(boost::make_shared<CKey>())
#include "key.h"
#include "Application.h"
LedgerProposal::LedgerProposal(uint32 closingSeq, uint32 proposeSeq, const uint256& proposeTx,
const std::string& pubKey) : mCurrentHash(proposeTx),
mProposeSeq(proposeSeq), mKey(boost::make_shared<CKey>())
{
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();
if (!mKey->SetPubKey(pubKey))
throw std::runtime_error("Invalid public key in proposal");
mPreviousLedger = theApp->getMasterLedger().getClosedLedger()->getHash();
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)
mPeerID(previous->mPeerID), mPreviousLedger(previous->mPreviousLedger),
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);
Serializer s(72);
s.add32(sProposeMagic);
s.add32(mProposeSeq);
s.add256(mPreviousLedger);
s.add256(mCurrentHash);
return s.getSHA512Half();
}
bool LedgerProposal::checkSign(const std::string& signature)
{
return mKey->Verify(getSigningHash(), signature);
}

View File

@@ -13,10 +13,9 @@ class LedgerProposal
{
protected:
uint256 mPeerID, mPreviousLedger, mPrevHash, mCurrentHash;
uint256 mPeerID, mPreviousLedger, mCurrentHash;
uint32 mProposeSeq;
CKey::pointer mKey;
std::vector<unsigned char> mSignature;
// std::vector<uint256> mAddedTx, mRemovedTx;
static const uint32 sProposeMagic = 0x50525000; // PRP
@@ -26,7 +25,7 @@ public:
typedef boost::shared_ptr<LedgerProposal> pointer;
// proposal from peer
LedgerProposal(SerializerIterator& it);
LedgerProposal(uint32 closingSeq, uint32 proposeSeq, const uint256& propose, const std::string& pubKey);
// our first proposal
LedgerProposal(CKey::pointer privateKey, const uint256& prevLedger, const uint256& position);
@@ -34,11 +33,10 @@ public:
// our following proposals
LedgerProposal(LedgerProposal::pointer previous, const uint256& newPosition);
void add(Serializer&, bool for_signature) const;
uint256 getSigningHash() const;
bool checkSign(const std::string& signature);
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; }

View File

@@ -386,18 +386,42 @@ int NetworkOPs::beginConsensus(Ledger::pointer closingLedger)
return mConsensus->startup();
}
bool NetworkOPs::proposeLedger(uint32 closingSeq, uint32 proposeSeq,
const uint256& prevHash, const uint256& proposeHash, const std::string& pubKey, const std::string& signature)
bool NetworkOPs::proposeLedger(uint32 closingSeq, uint32 proposeSeq, const uint256& proposeHash,
const std::string& pubKey, const std::string& signature)
{
uint256 nodeID = Serializer::getSHA512Half(pubKey);
if (mMode != omFULL)
return true;
LedgerProposal::pointer proposal =
boost::make_shared<LedgerProposal>(closingSeq, proposeSeq, proposeHash, pubKey);
if (!proposal->checkSign(signature))
{
std::cerr << "Ledger proposal fails signature check" << std::endl;
return false;
}
// Is this node on our UNL?
// WRITEME
// Are we currently closing?
Ledger::pointer currentLedger = theApp->getMasterLedger().getCurrentLedger();
// Yes: Is it an update?
// WRITEME
if (!mConsensus)
{
if ((getNetworkTimeNC() + 2) >= currentLedger->getCloseTimeNC())
setStateTimer(beginConsensus(currentLedger));
if (!mConsensus) return true;
}
return mConsensus->peerPosition(proposal);
}
SHAMap::pointer NetworkOPs::getTXMap(const uint256& hash)
{ // WRITEME
return SHAMap::pointer();
}
bool NetworkOPs::gotTXData(boost::shared_ptr<Peer> peer, const uint256& hash,
const std::list<SHAMapNode>& nodeIDs, const std::list< std::vector<unsigned char> >& nodeData)
{ // WRITEME
return true;
}

View File

@@ -66,13 +66,16 @@ public:
// tree synchronization operations
bool getTransactionTreeNodes(uint32 ledgerSeq, const uint256& myNodeID,
const std::vector<unsigned char>& myNode, std::list<std::vector<unsigned char> >& newNodes);
const std::vector<unsigned char>& myNode, std::list< std::vector<unsigned char> >& newNodes);
bool getAccountStateNodes(uint32 ledgerSeq, const uint256& myNodeId,
const std::vector<unsigned char>& myNode, std::list<std::vector<unsigned char> >& newNodes);
const std::vector<unsigned char>& myNode, std::list< std::vector<unsigned char> >& newNodes);
// ledger proposal/close functions
bool proposeLedger(uint32 closingSeq, uint32 proposeSeq, const uint256& prevHash, const uint256& proposeHash,
bool proposeLedger(uint32 closingSeq, uint32 proposeSeq, const uint256& proposeHash,
const std::string& pubKey, const std::string& signature);
bool gotTXData(boost::shared_ptr<Peer> peer, const uint256& hash,
const std::list<SHAMapNode>& nodeIDs, const std::list< std::vector<unsigned char> >& nodeData);
SHAMap::pointer getTXMap(const uint256& hash);
// network state machine
void checkState(const boost::system::error_code& result);

View File

@@ -603,16 +603,15 @@ void Peer::recvTransaction(newcoin::TMTransaction& packet)
void Peer::recvPropose(boost::shared_ptr<newcoin::TMProposeSet> packet)
{
if ((packet->previoustxhash().size() != 32) || (packet->currenttxhash().size() != 32) ||
(packet->nodepubkey().size() < 28) || (packet->signature().size() < 56))
if ((packet->currenttxhash().size() != 32) || (packet->nodepubkey().size() < 28) ||
(packet->signature().size() < 56))
return;
uint32 closingSeq = packet->closingseq(), proposeSeq = packet->proposeseq();
uint256 previousTxHash, currentTxHash;
memcpy(previousTxHash.begin(), packet->previoustxhash().data(), 32);
uint256 currentTxHash;
memcpy(currentTxHash.begin(), packet->currenttxhash().data(), 32);
if(theApp->getOPs().proposeLedger(closingSeq, proposeSeq, previousTxHash, currentTxHash,
if(theApp->getOPs().proposeLedger(closingSeq, proposeSeq, currentTxHash,
packet->nodepubkey(), packet->signature()))
{ // FIXME: Not all nodes will want proposals
PackedMessage::pointer message = boost::make_shared<PackedMessage>(packet, newcoin::mtPROPOSE_LEDGER);
@@ -693,106 +692,161 @@ void Peer::recvStatus(newcoin::TMStatusChange& packet)
void Peer::recvGetLedger(newcoin::TMGetLedger& packet)
{
// Figure out what ledger they want
Ledger::pointer ledger;
if (packet.has_ledgerhash())
{
uint256 ledgerhash;
if (packet.ledgerhash().size() != 32)
SHAMap::pointer map;
boost::shared_ptr<newcoin::TMLedgerData> reply = boost::make_shared<newcoin::TMLedgerData>();
if (packet.itype() == newcoin::liTS_CANDIDATE)
{ // Request is for a transaction candidate set
Ledger::pointer ledger;
if ((!packet.has_ledgerhash() || packet.ledgerhash().size() != 32))
{
punishPeer(PP_INVALID_REQUEST);
return;
}
memcpy(&ledgerhash, packet.ledgerhash().data(), 32);
ledger = theApp->getMasterLedger().getLedgerByHash(ledgerhash);
}
else if (packet.has_ledgerseq())
ledger = theApp->getMasterLedger().getLedgerBySeq(packet.ledgerseq());
else if (packet.has_ltype() && (packet.ltype() == newcoin::ltCURRENT))
ledger = theApp->getMasterLedger().getCurrentLedger();
else if (packet.has_ltype() && (packet.ltype() == newcoin::ltCLOSING))
{
ledger = theApp->getMasterLedger().getClosedLedger();
}
else if (packet.has_ltype() && (packet.ltype() == newcoin::ltCLOSED) )
{
ledger = theApp->getMasterLedger().getClosedLedger();
if (ledger && !ledger->isClosed())
ledger = theApp->getMasterLedger().getLedgerBySeq(ledger->getLedgerSeq() - 1);
uint256 txHash;
memcpy(txHash.begin(), packet.ledgerhash().data(), 32);
map = theApp->getOPs().getTXMap(txHash);
if (!map)
{
punishPeer(PP_INVALID_REQUEST);
return;
}
reply->set_ledgerhash(txHash.begin(), txHash.size());
reply->set_type(newcoin::liTS_CANDIDATE);
}
else
{
punishPeer(PP_INVALID_REQUEST);
return;
}
if( (!ledger) || (packet.has_ledgerseq() && (packet.ledgerseq()!=ledger->getLedgerSeq())) )
{
punishPeer(PP_UNKNOWN_REQUEST);
return;
}
// Figure out what information they want
boost::shared_ptr<newcoin::TMLedgerData> data = boost::make_shared<newcoin::TMLedgerData>();
uint256 lHash = ledger->getHash();
data->set_ledgerhash(lHash.begin(), lHash.size());
data->set_ledgerseq(ledger->getLedgerSeq());
data->set_type(packet.itype());
if(packet.itype() == newcoin::liBASE)
{
Serializer nData(116);
ledger->addRaw(nData);
data->add_nodes()->set_nodedata(nData.getDataPtr(), nData.getLength());
}
else if ( (packet.itype()==newcoin::liTX_NODE) || (packet.itype()==newcoin::liAS_NODE) )
{
SHAMap::pointer map=(packet.itype()==newcoin::liTX_NODE) ? ledger->peekTransactionMap()
: ledger->peekAccountStateMap();
if(!map) return;
if(packet.nodeids_size()==0)
{ // Figure out what ledger they want
Ledger::pointer ledger;
if (packet.has_ledgerhash())
{
punishPeer(PP_INVALID_REQUEST);
return;
}
for(int i=0; i<packet.nodeids().size(); i++)
{
SHAMapNode mn(packet.nodeids(0).data(), packet.nodeids(i).size());
if(!mn.isValid())
uint256 ledgerhash;
if (packet.ledgerhash().size() != 32)
{
punishPeer(PP_INVALID_REQUEST);
return;
}
std::vector<SHAMapNode> nodeIDs;
std::list<std::vector<unsigned char> > rawNodes;
if(map->getNodeFat(mn, nodeIDs, rawNodes))
{
std::vector<SHAMapNode>::iterator nodeIDIterator;
std::list<std::vector<unsigned char> >::iterator rawNodeIterator;
for(nodeIDIterator = nodeIDs.begin(), rawNodeIterator = rawNodes.begin();
nodeIDIterator != nodeIDs.end(); ++nodeIDIterator, ++rawNodeIterator)
{
Serializer nID(33);
nodeIDIterator->addIDRaw(nID);
newcoin::TMLedgerNode* node = data->add_nodes();
node->set_nodeid(nID.getDataPtr(), nID.getLength());
node->set_nodedata(&rawNodeIterator->front(), rawNodeIterator->size());
}
}
memcpy(ledgerhash.begin(), packet.ledgerhash().data(), 32);
ledger = theApp->getMasterLedger().getLedgerByHash(ledgerhash);
}
else if (packet.has_ledgerseq())
ledger = theApp->getMasterLedger().getLedgerBySeq(packet.ledgerseq());
else if (packet.has_ltype() && (packet.ltype() == newcoin::ltCURRENT))
ledger = theApp->getMasterLedger().getCurrentLedger();
else if (packet.has_ltype() && (packet.ltype() == newcoin::ltCLOSED) )
{
ledger = theApp->getMasterLedger().getClosedLedger();
if (ledger && !ledger->isClosed())
ledger = theApp->getMasterLedger().getLedgerBySeq(ledger->getLedgerSeq() - 1);
}
else
{
punishPeer(PP_INVALID_REQUEST);
return;
}
if( (!ledger) || (packet.has_ledgerseq() && (packet.ledgerseq()!=ledger->getLedgerSeq())) )
{
punishPeer(PP_UNKNOWN_REQUEST);
return;
}
// Fill out the reply
uint256 lHash = ledger->getHash();
reply->set_ledgerhash(lHash.begin(), lHash.size());
reply->set_ledgerseq(ledger->getLedgerSeq());
reply->set_type(packet.itype());
if(packet.itype() == newcoin::liBASE)
{ // they want the ledger base data
Serializer nData(128);
ledger->addRaw(nData);
reply->add_nodes()->set_nodedata(nData.getDataPtr(), nData.getLength());
PackedMessage::pointer oPacket = boost::make_shared<PackedMessage>
(PackedMessage::MessagePointer(reply), newcoin::mtLEDGER);
sendPacket(oPacket);
return;
}
if ((packet.itype() == newcoin::liTX_NODE) || (packet.itype() == newcoin::liAS_NODE))
map = (packet.itype() == newcoin::liTX_NODE) ?
ledger->peekTransactionMap() : ledger->peekAccountStateMap();
}
else
if ((!map) || (packet.nodeids_size() == 0))
{
punishPeer(PP_INVALID_REQUEST);
return;
}
for(int i = 0; i<packet.nodeids().size(); ++i)
{
SHAMapNode mn(packet.nodeids(0).data(), packet.nodeids(i).size());
if(!mn.isValid())
{
punishPeer(PP_INVALID_REQUEST);
return;
}
std::vector<SHAMapNode> nodeIDs;
std::list< std::vector<unsigned char> > rawNodes;
if(map->getNodeFat(mn, nodeIDs, rawNodes))
{
std::vector<SHAMapNode>::iterator nodeIDIterator;
std::list< std::vector<unsigned char> >::iterator rawNodeIterator;
for(nodeIDIterator = nodeIDs.begin(), rawNodeIterator = rawNodes.begin();
nodeIDIterator != nodeIDs.end(); ++nodeIDIterator, ++rawNodeIterator)
{
Serializer nID(33);
nodeIDIterator->addIDRaw(nID);
newcoin::TMLedgerNode* node = reply->add_nodes();
node->set_nodeid(nID.getDataPtr(), nID.getLength());
node->set_nodedata(&rawNodeIterator->front(), rawNodeIterator->size());
}
}
}
PackedMessage::pointer oPacket = boost::make_shared<PackedMessage>
(PackedMessage::MessagePointer(data), newcoin::mtLEDGER);
(PackedMessage::MessagePointer(reply), newcoin::mtLEDGER);
sendPacket(oPacket);
}
void Peer::recvLedger(newcoin::TMLedgerData& packet)
{
if (packet.nodes().size() <= 0)
{
punishPeer(PP_INVALID_REQUEST);
return;
}
if (packet.type() == newcoin::liTS_CANDIDATE)
{ // got data for a candidate transaction set
uint256 hash;
if(packet.ledgerhash().size() != 32)
{
punishPeer(PP_INVALID_REQUEST);
return;
}
memcpy(hash.begin(), packet.ledgerhash().data(), 32);
std::list<SHAMapNode> nodeIDs;
std::list< std::vector<unsigned char> > nodeData;
for (int i = 0; i < packet.nodes().size(); ++i)
{
const newcoin::TMLedgerNode& node = packet.nodes(i);
if (!node.has_nodeid() || !node.has_nodedata())
{
punishPeer(PP_INVALID_REQUEST);
return;
}
nodeIDs.push_back(SHAMapNode(node.nodeid().data(), node.nodeid().size()));
nodeData.push_back(std::vector<unsigned char>(node.nodedata().begin(), node.nodedata().end()));
}
if (!theApp->getOPs().gotTXData(shared_from_this(), hash, nodeIDs, nodeData))
punishPeer(PP_UNWANTED_DATA);
return;
}
if (!theApp->getMasterLedgerAcquire().gotLedgerData(packet, shared_from_this()))
punishPeer(PP_UNWANTED_DATA);
}

View File

@@ -144,7 +144,7 @@ uint256 Serializer::get256(int offset) const
{
uint256 ret;
if ((offset + (256 / 8)) > mData.size()) return ret;
memcpy(&ret, &(mData.front()) + offset, (256 / 8));
memcpy(ret.begin(), &(mData.front()) + offset, (256 / 8));
return ret;
}

View File

@@ -188,7 +188,7 @@ public:
return true;
}
CSecret GetSecret() const
CSecret GetSecret()
{
CSecret vchRet;
vchRet.resize(32);
@@ -207,7 +207,7 @@ public:
return BN_dup(EC_KEY_get0_private_key(pkey));
}
CPrivKey GetPrivKey() const
CPrivKey GetPrivKey()
{
unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);
if (!nSize)
@@ -260,7 +260,7 @@ public:
vchSig.clear();
unsigned char pchSig[10000];
unsigned int nSize = 0;
if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey))
if (!ECDSA_sign(0, (unsigned char*)hash.begin(), hash.size(), pchSig, &nSize, pkey))
return false;
vchSig.resize(nSize);
@@ -268,14 +268,24 @@ public:
return true;
}
bool Verify(const uint256& hash, const std::vector<unsigned char>& vchSig) const
bool Verify(const uint256& hash, const void *sig, size_t sigLen) const
{
// -1 = error, 0 = bad sig, 1 = good
if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
if (ECDSA_verify(0, hash.begin(), hash.size(), (const unsigned char *) sig, sigLen, pkey) != 1)
return false;
return true;
}
bool Verify(const uint256& hash, const std::vector<unsigned char>& vchSig) const
{
return Verify(hash, &vchSig[0], vchSig.size());
}
bool Verify(const uint256& hash, const std::string sig) const
{
return Verify(hash, sig.data(), sig.size());
}
// ECIES functions. These throw on failure
// returns a 32-byte secret unique to these two keys. At least one private key must be known.

View File

@@ -103,12 +103,11 @@ message TMStatusChange {
message TMProposeSet {
required uint32 closingSeq = 1;
required uint32 proposeSeq = 2;
required bytes previousTxHash = 3; // 0 if first proposal, hash we no longer propose
required bytes currentTxHash = 4; // the hash of the ledger we are proposing
required bytes nodePubKey = 5;
required bytes signature = 6; // signature of above fields
repeated bytes addedTransactions = 7; // not required if number is large
repeated bytes removedTransactions = 8; // not required if number is large
required bytes currentTxHash = 3; // the hash of the ledger we are proposing
required bytes nodePubKey = 4;
required bytes signature = 5; // signature of above fields
repeated bytes addedTransactions = 6; // not required if number is large
repeated bytes removedTransactions = 7; // not required if number is large
}
// Announce to a peer that we have fully acquired a transaction set
@@ -221,13 +220,12 @@ enum TMLedgerInfoType {
enum TMLedgerType {
ltACCEPTED = 0;
ltCURRENT = 1;
ltCLOSING = 2;
ltCLOSED = 3;
ltCLOSED = 2;
}
message TMGetLedger {
optional TMLedgerType ltype = 1;
optional bytes ledgerHash = 2;
optional bytes ledgerHash = 2; // Can also be the transaction set hash if liTS_CANDIDATE
optional uint32 ledgerSeq = 3;
required TMLedgerInfoType itype = 4;
repeated bytes nodeIDs = 5;