diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 3ad65a7d9..39b997cc5 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -38,6 +38,35 @@ BlockChain::~BlockChain() void BlockChain::import(bytes const& _block) { + BlockInfo bi; + try + { + bi.populate(_block, 0); + auto newHash = sha256(_block); + + // Check block doesn't already exist first! + if (m_numberAndParent.count(newHash)) + return; + + // Work out its number as the parent's number + 1 + auto it = m_numberAndParent.find(bi.parentHash); + if (it == m_numberAndParent.end()) + // We don't know the parent (yet) - discard for now. It'll get resent to us if we find out about its ancestry later on. + return; + bi.number = it->second.first + 1; + + // Insert into DB + m_numberAndParent[newHash] = make_pair(bi.number, bi.parentHash); + m_children.insert(make_pair(bi.parentHash, newHash)); + // TODO: put _block onto disk and load into cache. + + // This might be the new last block; count back through ancestors to common shared ancestor and compare to current. + } + catch (...) + { + // Exit silently on exception(?) + return; + } } bytesConstRef BlockChain::block(u256 _hash) const diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index 30d7a7ab2..3fbaac9ae 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -48,7 +48,7 @@ public: BlockChain(); ~BlockChain(); - /// (Potentiall) renders invalid existing bytesConstRef returned by lastBlock. + /// (Potentially) renders invalid existing bytesConstRef returned by lastBlock. /// To be called from main loop every 100ms or so. void process(); @@ -78,5 +78,3 @@ private: }; } - - diff --git a/libethereum/BlockInfo.cpp b/libethereum/BlockInfo.cpp index 06eb638ed..28a351984 100644 --- a/libethereum/BlockInfo.cpp +++ b/libethereum/BlockInfo.cpp @@ -73,18 +73,23 @@ void BlockInfo::populate(bytesConstRef _block, u256 _number) } } -void BlockInfo::verify(bytesConstRef _block, u256 _number) +void BlockInfo::verify(bytesConstRef _block, u256 _number, u256 _parentHash) { populate(_block, _number); RLP root(_block); + if (root[0][0].toInt() != _parentHash) + throw InvalidParentHash(); + if (sha256Transactions != sha256(root[1].data())) throw InvalidTransactionsHash(); if (sha256Uncles != sha256(root[2].data())) throw InvalidUnclesHash(); - // TODO: check timestamp. + // TODO: check timestamp after previous timestamp. + // TODO: check parent's hash + // TODO: check difficulty against timestamp. // TODO: check proof of work. diff --git a/libethereum/BlockInfo.h b/libethereum/BlockInfo.h index 9d54465fc..1533d5d9a 100644 --- a/libethereum/BlockInfo.h +++ b/libethereum/BlockInfo.h @@ -47,7 +47,7 @@ public: static BlockInfo const& genesis() { if (!s_genesis) (s_genesis = new BlockInfo)->populateGenesis(); return *s_genesis; } void populate(bytesConstRef _block, u256 _number); - void verify(bytesConstRef _block, u256 _number); + void verify(bytesConstRef _block, u256 _number, u256 _parentHash); static bytes createGenesisBlock();