From ebe06b37de98d383adc3e955511c9c3e72f8a58e Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 14 May 2015 16:58:56 +0300 Subject: [PATCH] More stringent checking for ancestors in uncles. Minor fixes to AZ. Optimisations for NewBlockHashes handling. --- alethzero/MainWin.cpp | 3 ++- libethereum/BlockChain.cpp | 5 +++-- libethereum/EthereumHost.cpp | 4 ++-- libethereum/EthereumHost.h | 2 +- libethereum/EthereumPeer.cpp | 2 +- libethereum/State.cpp | 16 +++++++--------- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 7551eaa35..7026cb7c8 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -1010,7 +1010,7 @@ void Main::refreshBalances() u256 b = ethereum()->balanceAt(i.first); QListWidgetItem* li = new QListWidgetItem(QString("%4 %2: %1 [%3]").arg(formatBalance(b).c_str()).arg(QString::fromStdString(render(i.first))).arg((unsigned)ethereum()->countAt(i.first)).arg(QString::fromStdString(i.second.first)), ui->ourAccounts); li->setData(Qt::UserRole, QByteArray((char const*)i.first.data(), Address::size)); - li->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); + li->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable); li->setCheckState(m_beneficiary == i.first ? Qt::Checked : Qt::Unchecked); totalBalance += b; @@ -1990,6 +1990,7 @@ void Main::on_killAccount_triggered() m_keyManager.kill(h); if (m_keyManager.accounts().empty()) m_keyManager.import(Secret::random(), "Default account"); + m_beneficiary = *m_keyManager.accounts().begin(); keysChanged(); if (m_beneficiary == h) setBeneficiary(*m_keyManager.accounts().begin()); diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 32a11ee53..7c03bc24f 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -984,11 +984,12 @@ vector BlockChain::withBlockBloom(LogBloom const& _b, unsigned _earlie h256Hash BlockChain::allUnclesFrom(h256 const& _parent) const { // Get all uncles cited given a parent (i.e. featured as uncles/main in parent, parent + 1, ... parent + 5). - h256Hash ret; h256 p = _parent; + h256Hash ret = { p }; + // p and (details(p).parent: i == 5) is likely to be overkill, but can't hurt to be cautious. for (unsigned i = 0; i < 6 && p != m_genesisHash; ++i, p = details(p).parent) { - ret.insert(p); // TODO: check: should this be details(p).parent? + ret.insert(details(p).parent); auto b = block(p); for (auto i: RLP(b)[2]) ret.insert(sha3(i.data())); diff --git a/libethereum/EthereumHost.cpp b/libethereum/EthereumHost.cpp index 72ee1854d..1ca77cd1c 100644 --- a/libethereum/EthereumHost.cpp +++ b/libethereum/EthereumHost.cpp @@ -83,7 +83,7 @@ void EthereumHost::noteNeedsSyncing(EthereumPeer* _who) _who->attemptSync(); } -void EthereumHost::changeSyncer(EthereumPeer* _syncer) +void EthereumHost::changeSyncer(EthereumPeer* _syncer, bool _needHelp) { if (_syncer) clog(NetAllDetail) << "Changing syncer to" << _syncer->session()->socketId(); @@ -93,7 +93,7 @@ void EthereumHost::changeSyncer(EthereumPeer* _syncer) m_syncer = _syncer; if (isSyncing()) { - if (_syncer->m_asking == Asking::Blocks) + if (_needHelp && _syncer->m_asking == Asking::Blocks) for (auto j: peerSessions()) { auto e = j.first->cap().get(); diff --git a/libethereum/EthereumHost.h b/libethereum/EthereumHost.h index d53c3cc79..95c7f147a 100644 --- a/libethereum/EthereumHost.h +++ b/libethereum/EthereumHost.h @@ -108,7 +108,7 @@ private: virtual void onStarting() { startWorking(); } virtual void onStopping() { stopWorking(); } - void changeSyncer(EthereumPeer* _ignore); + void changeSyncer(EthereumPeer* _ignore, bool _needHelp = true); BlockChain const& m_chain; TransactionQueue& m_tq; ///< Maintains a list of incoming transactions not yet in a block on the blockchain. diff --git a/libethereum/EthereumPeer.cpp b/libethereum/EthereumPeer.cpp index 85bdf33e9..1d0c9fa0d 100644 --- a/libethereum/EthereumPeer.cpp +++ b/libethereum/EthereumPeer.cpp @@ -600,7 +600,7 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r) if (unknowns > 0) { host()->m_man.resetToChain(m_syncingNeededBlocks); - host()->changeSyncer(this); + host()->changeSyncer(this, false); transition(Asking::Blocks); } return true; diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 167d6236e..ccc6c4512 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -650,25 +650,23 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement if (rlp[2].itemCount() > 2) BOOST_THROW_EXCEPTION(TooManyUncles()); - unordered_set nonces = { m_currentBlock.nonce }; vector rewarded; - h256Hash knownUncles = _bc.allUnclesFrom(m_currentBlock.parentHash); + h256Hash excluded = _bc.allUnclesFrom(m_currentBlock.parentHash); + excluded.insert(m_currentBlock.hash()); for (auto const& i: rlp[2]) { - if (knownUncles.count(sha3(i.data()))) - BOOST_THROW_EXCEPTION(UncleInChain() << errinfo_comment("Uncle in block already mentioned") << errinfo_data(toString(knownUncles)) << errinfo_hash256(sha3(i.data())) ); - - BlockInfo uncle = BlockInfo::fromHeader(i.data()); - if (nonces.count(uncle.nonce)) - BOOST_THROW_EXCEPTION(DuplicateUncleNonce()); + auto h = sha3(i.data()); + if (excluded.count(h)) + BOOST_THROW_EXCEPTION(UncleInChain() << errinfo_comment("Uncle in block already mentioned") << errinfo_data(toString(excluded)) << errinfo_hash256(sha3(i.data()))); + excluded.insert(h); + BlockInfo uncle = BlockInfo::fromHeader(i.data(), CheckEverything, h); BlockInfo uncleParent(_bc.block(uncle.parentHash)); if ((bigint)uncleParent.number < (bigint)m_currentBlock.number - 7) BOOST_THROW_EXCEPTION(UncleTooOld()); uncle.verifyParent(uncleParent); - nonces.insert(uncle.nonce); // tdIncrease += uncle.difficulty; rewarded.push_back(uncle); }