From 480ca5d1e7e96d25364314c54968e282a06c9ee7 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 28 Oct 2014 01:31:25 +0100 Subject: [PATCH] Paranoia mining fix. --- libethcore/BlockInfo.cpp | 7 ++++--- libethcore/BlockInfo.h | 2 +- libethcore/Exceptions.h | 3 ++- libethereum/State.cpp | 41 ++++++++++++++++++++++++++++++++-------- libethereum/State.h | 3 +++ 5 files changed, 43 insertions(+), 13 deletions(-) diff --git a/libethcore/BlockInfo.cpp b/libethcore/BlockInfo.cpp index ea9cc3055..60c190470 100644 --- a/libethcore/BlockInfo.cpp +++ b/libethcore/BlockInfo.cpp @@ -37,9 +37,9 @@ BlockInfo::BlockInfo(): timestamp(Invalid256) { } -BlockInfo::BlockInfo(bytesConstRef _block) +BlockInfo::BlockInfo(bytesConstRef _block, bool _checkNonce) { - populate(_block); + populate(_block, _checkNonce); } BlockInfo BlockInfo::fromHeader(bytesConstRef _block) @@ -103,6 +103,7 @@ void BlockInfo::populateFromHeader(RLP const& _header, bool _checkNonce) } // check it hashes according to proof of work or that it's the genesis block. + cnote << "Verifying" << headerHashWithoutNonce().abridged() << nonce.abridged() << difficulty; if (_checkNonce && parentHash && !ProofOfWork::verify(headerHashWithoutNonce(), nonce, difficulty)) BOOST_THROW_EXCEPTION(InvalidBlockNonce(headerHashWithoutNonce(), nonce, difficulty)); @@ -142,7 +143,7 @@ void BlockInfo::verifyInternals(bytesConstRef _block) const { bytes k = rlp(i); t.insert(&k, tr.data()); - u256 gp = tr[0][1].toInt(); + u256 gp = tr[1].toInt(); mgp = min(mgp, gp); ++i; } diff --git a/libethcore/BlockInfo.h b/libethcore/BlockInfo.h index 18628e2ec..d91ff244d 100644 --- a/libethcore/BlockInfo.h +++ b/libethcore/BlockInfo.h @@ -75,7 +75,7 @@ public: BlockInfo(); explicit BlockInfo(bytes const& _block): BlockInfo(&_block) {} - explicit BlockInfo(bytesConstRef _block); + explicit BlockInfo(bytesConstRef _block, bool _checkNonce = true); static h256 headerHash(bytes const& _block) { return headerHash(&_block); } static h256 headerHash(bytesConstRef _block); diff --git a/libethcore/Exceptions.h b/libethcore/Exceptions.h index 8e4fcb2d2..5a07407d2 100644 --- a/libethcore/Exceptions.h +++ b/libethcore/Exceptions.h @@ -57,7 +57,8 @@ struct InvalidDifficulty: virtual dev::Exception {}; class InvalidGasLimit: virtual public dev::Exception { public: InvalidGasLimit(u256 _provided = 0, u256 _valid = 0): provided(_provided), valid(_valid) {} u256 provided; u256 valid; virtual const char* what() const noexcept; }; class InvalidMinGasPrice: virtual public dev::Exception { public: InvalidMinGasPrice(u256 _provided = 0, u256 _limit = 0): provided(_provided), limit(_limit) {} u256 provided; u256 limit; virtual const char* what() const noexcept; }; struct InvalidTransactionGasUsed: virtual dev::Exception {}; -struct InvalidTransactionStateRoot: virtual dev::Exception {}; +struct InvalidTransactionsStateRoot: virtual dev::Exception {}; +struct InvalidReceiptsStateRoot: virtual dev::Exception {}; struct InvalidTimestamp: virtual dev::Exception {}; class InvalidNonce: virtual public dev::Exception { public: InvalidNonce(u256 _required = 0, u256 _candidate = 0): required(_required), candidate(_candidate) {} u256 required; u256 candidate; virtual const char* what() const noexcept; }; class InvalidBlockNonce: virtual public dev::Exception { public: InvalidBlockNonce(h256 _h = h256(), h256 _n = h256(), u256 _d = 0): h(_h), n(_n), d(_d) {} h256 h; h256 n; u256 d; virtual const char* what() const noexcept; }; diff --git a/libethereum/State.cpp b/libethereum/State.cpp index e49fa8082..d6bdc74d1 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -591,7 +591,7 @@ u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce) // m_currentBlock is assumed to be prepopulated and reset. #if !ETH_RELEASE - BlockInfo bi(_block); + BlockInfo bi(_block, _checkNonce); assert(m_previousBlock.hash == bi.parentHash); assert(m_currentBlock.parentHash == bi.parentHash); assert(rootHash() == m_previousBlock.stateRoot); @@ -608,16 +608,32 @@ u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce) // cnote << m_state; MemoryDB tm; - GenericTrieDB transactionManifest(&tm); - transactionManifest.init(); + GenericTrieDB transactionsTrie(&tm); + transactionsTrie.init(); + + MemoryDB rm; + GenericTrieDB receiptsTrie(&rm); + receiptsTrie.init(); // All ok with the block generally. Play back the transactions now... unsigned i = 0; for (auto const& tr: RLP(_block)[1]) { + RLPStream k; + k << i; + + RLPStream txrlp; + m_transactions[i].streamRLP(txrlp); + transactionsTrie.insert(&k.out(), tr.data()); + // cnote << m_state.root() << m_state; // cnote << *this; - execute(tr[0].data()); + execute(tr.data()); + + RLPStream receiptrlp; + m_receipts.back().streamRLP(receiptrlp); + receiptsTrie.insert(&k.out(), &receiptrlp.out()); +/* if (tr[1].toHash() != m_state.root()) { // Invalid state root @@ -628,15 +644,20 @@ u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce) } if (tr[2].toInt() != gasUsed()) BOOST_THROW_EXCEPTION(InvalidTransactionGasUsed()); - bytes k = rlp(i); - transactionManifest.insert(&k, tr.data()); +*/ ++i; } - if (m_currentBlock.transactionsRoot && transactionManifest.root() != m_currentBlock.transactionsRoot) + if (transactionsTrie.root() != m_currentBlock.transactionsRoot) { cwarn << "Bad transactions state root!"; - BOOST_THROW_EXCEPTION(InvalidTransactionStateRoot()); + BOOST_THROW_EXCEPTION(InvalidTransactionsStateRoot()); + } + + if (receiptsTrie.root() != m_currentBlock.receiptsRoot) + { + cwarn << "Bad receipts state root!"; + BOOST_THROW_EXCEPTION(InvalidReceiptsStateRoot()); } // Initialise total difficulty calculation. @@ -877,6 +898,10 @@ MineInfo State::mine(unsigned _msTimeout, bool _turbo) if (!ret.completed) m_currentBytes.clear(); + else + { + cnote << "Completed" << m_currentBlock.headerHashWithoutNonce().abridged() << m_currentBlock.nonce.abridged() << m_currentBlock.difficulty << ProofOfWork::verify(m_currentBlock.headerHashWithoutNonce(), m_currentBlock.nonce, m_currentBlock.difficulty); + } return ret; } diff --git a/libethereum/State.h b/libethereum/State.h index aa241fbef..b32bb6c7c 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -249,6 +249,9 @@ public: /// Get the bloom filter of a particular transaction that happened in the block. TODO: PoC-7: KILL h256 oldBloom(unsigned _i) const { return m_receipts[_i].changes().bloom(); } + /// Get the transaction receipt for the transaction of the given index. + TransactionReceipt const& receipt(unsigned _i) const { return m_receipts[_i]; } + /// Get the list of pending transactions. LogEntries const& log(unsigned _i) const { return m_receipts[_i].log(); }