From 8328220471475b2733a9f4a2cc4c3710ee2d7d5c Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 20 Apr 2015 11:49:37 +0200 Subject: [PATCH] Fixes for reimporting, make block availability atomic. --- alethzero/MainWin.cpp | 2 +- libethcore/EthashAux.cpp | 6 +++--- libethereum/BlockChain.cpp | 38 +++++++++++++++++++++++++++----------- libethereum/BlockChain.h | 3 ++- 4 files changed, 33 insertions(+), 16 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 270996a30..3ec5febd2 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -164,7 +164,7 @@ Main::Main(QWidget *parent) : statusBar()->addPermanentWidget(ui->chainStatus); statusBar()->addPermanentWidget(ui->blockCount); - ui->blockCount->setText(QString("PV%2 D%3 %4-%5 v%6").arg(eth::c_protocolVersion).arg(c_databaseVersion).arg(QString::fromStdString(ProofOfWork::name())).arg(ProofOfWork::revision()).arg(dev::Version)); + ui->blockCount->setText(QString("PV%1.%2 D%3 %4-%5 v%6").arg(eth::c_protocolVersion).arg(eth::c_minorProtocolVersion).arg(c_databaseVersion).arg(QString::fromStdString(ProofOfWork::name())).arg(ProofOfWork::revision()).arg(dev::Version)); connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved())); diff --git a/libethcore/EthashAux.cpp b/libethcore/EthashAux.cpp index 68c5f3057..750d80082 100644 --- a/libethcore/EthashAux.cpp +++ b/libethcore/EthashAux.cpp @@ -75,11 +75,11 @@ h256 EthashAux::seedHash(unsigned _number) n = get()->m_seedHashes.size() - 1; } get()->m_seedHashes.resize(epoch + 1); - cdebug << "Searching for seedHash of epoch " << epoch; +// cdebug << "Searching for seedHash of epoch " << epoch; for (; n <= epoch; ++n, ret = sha3(ret)) { get()->m_seedHashes[n] = ret; - cdebug << "Epoch" << n << "is" << ret.abridged(); +// cdebug << "Epoch" << n << "is" << ret.abridged(); } } return get()->m_seedHashes[epoch]; @@ -95,7 +95,7 @@ ethash_params EthashAux::params(h256 const& _seedHash) } catch (...) { - cdebug << "Searching for seedHash " << _seedHash.abridged(); +// cdebug << "Searching for seedHash " << _seedHash.abridged(); for (h256 h; h != _seedHash && epoch < 2048; ++epoch, h = sha3(h), get()->m_epochs[h] = epoch) {} if (epoch == 2048) { diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 4e3349a31..6705349f4 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -167,6 +167,7 @@ void BlockChain::open(std::string const& _path, WithExisting _we) std::string l; m_extrasDB->Get(m_readOptions, ldb::Slice("best"), &l); m_lastBlockHash = l.empty() ? m_genesisHash : *(h256*)l.data(); + m_lastBlockNumber = number(m_lastBlockHash); cnote << "Opened blockchain DB. Latest: " << currentHash(); } @@ -177,6 +178,7 @@ void BlockChain::close() delete m_extrasDB; delete m_blocksDB; m_lastBlockHash = m_genesisHash; + m_lastBlockNumber = 0; m_details.clear(); m_blocks.clear(); } @@ -191,8 +193,7 @@ void BlockChain::rebuild(std::string const& _path, std::functionPut(m_writeOptions, ldb::Slice("best"), ldb::Slice((char const*)&(bi.hash()), 32)); // Most of the time these two will be equal - only when we're doing a chain revert will they not be if (common != last) @@ -601,6 +597,14 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import m_extrasDB->Put(m_writeOptions, toSlice(h, ExtraTransactionAddress), (ldb::Slice)dev::ref(m_transactionAddresses[h].rlp())); } + // FINALLY! change our best hash. + { + WriteGuard l(x_lastBlockHash); + m_lastBlockHash = bi.hash(); + m_lastBlockNumber = (unsigned)bi.number; + m_extrasDB->Put(m_writeOptions, ldb::Slice("best"), ldb::Slice((char const*)&(bi.hash()), 32)); + } + clog(BlockChainNote) << " Imported and best" << td << " (#" << bi.number << "). Has" << (details(bi.parentHash).children.size() - 1) << "siblings. Route:" << toString(route); noteCanonChanged(); @@ -960,14 +964,26 @@ bool BlockChain::isKnown(h256 const& _hash) const { if (_hash == m_genesisHash) return true; + { ReadGuard l(x_blocks); - if (m_blocks.count(_hash)) - return true; + auto it = m_blocks.find(_hash); + if (it != m_blocks.end()) + { + noteUsed(_hash); + BlockInfo bi(it->second, CheckNothing, _hash); + return bi.number <= m_lastBlockNumber; // TODO: m_lastBlockNumber + } } + string d; m_blocksDB->Get(m_readOptions, toSlice(_hash), &d); - return !!d.size(); + + if (!d.size()) + return false; + + BlockInfo bi(bytesConstRef(&d), CheckNothing, _hash); + return bi.number <= m_lastBlockNumber; // TODO: m_lastBlockNumber } bytes BlockChain::block(h256 const& _hash) const diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index 8061487d7..be5b931ee 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -185,7 +185,7 @@ public: /// Get a number for the given hash (or the most recent mined if none given). Thread-safe. unsigned number(h256 const& _hash) const { return details(_hash).number; } - unsigned number() const { return number(currentHash()); } + unsigned number() const { return m_lastBlockNumber; } /// Get a given block (RLP format). Thread-safe. h256 currentHash() const { ReadGuard l(x_lastBlockHash); return m_lastBlockHash; } @@ -315,6 +315,7 @@ private: /// Hash of the last (valid) block on the longest chain. mutable boost::shared_mutex x_lastBlockHash; h256 m_lastBlockHash; + unsigned m_lastBlockNumber = 0; /// Genesis block info. h256 m_genesisHash;