diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 3c87f649a..1921e80cd 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -1209,8 +1209,9 @@ string Main::renderDiff(StateDiff const& _d) const if (ad.balance) { - s << "
" << indent << "Balance " << dec << formatBalance(ad.balance.to()); - s << " " << showpos << (((dev::bigint)ad.balance.to()) - ((dev::bigint)ad.balance.from())) << noshowpos << ""; + s << "
" << indent << "Balance " << dec << ad.balance.to() << " [=" << formatBalance(ad.balance.to()) << "]"; + auto d = (((dev::bigint)ad.balance.to()) - ((dev::bigint)ad.balance.from())); + s << " " << showpos << dec << d << " [=" << formatBalance(d) << "]" << noshowpos << ""; } if (ad.nonce) { @@ -1219,7 +1220,7 @@ string Main::renderDiff(StateDiff const& _d) const } if (ad.code) { - s << "
" << indent << "Code " << hex << ad.code.to().size() << " bytes"; + s << "
" << indent << "Code " << dec << ad.code.to().size() << " bytes"; if (ad.code.from().size()) s << " (" << ad.code.from().size() << " bytes)"; } diff --git a/libethcore/CommonEth.cpp b/libethcore/CommonEth.cpp index 8de20c21d..c530beef1 100644 --- a/libethcore/CommonEth.cpp +++ b/libethcore/CommonEth.cpp @@ -63,22 +63,31 @@ vector> const& units() return g_units; } -std::string formatBalance(u256 _b) +std::string formatBalance(bigint const& _b) { ostringstream ret; - if (_b > g_units[0].first * 10000) + u256 b; + if (_b < 0) { - ret << (_b / g_units[0].first) << " " << g_units[0].second; + ret << "-"; + b = (u256)-_b; + } + else + b = (u256)_b; + + if (b > g_units[0].first * 10000) + { + ret << (b / g_units[0].first) << " " << g_units[0].second; return ret.str(); } ret << setprecision(5); for (auto const& i: g_units) - if (i.first != 1 && _b >= i.first * 100) + if (i.first != 1 && b >= i.first * 100) { - ret << (double(_b / (i.first / 1000)) / 1000.0) << " " << i.second; + ret << (double(b / (i.first / 1000)) / 1000.0) << " " << i.second; return ret.str(); } - ret << _b << " wei"; + ret << b << " wei"; return ret.str(); } diff --git a/libethcore/CommonEth.h b/libethcore/CommonEth.h index 704e354a2..966794953 100644 --- a/libethcore/CommonEth.h +++ b/libethcore/CommonEth.h @@ -39,7 +39,7 @@ extern const unsigned c_protocolVersion; extern const unsigned c_databaseVersion; /// User-friendly string representation of the amount _b in wei. -std::string formatBalance(u256 _b); +std::string formatBalance(bigint const& _b); /// Get information concerning the currency denominations. std::vector> const& units(); diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index ccff335b6..9cfd18b2d 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -226,7 +226,7 @@ void Client::uninstallWatch(unsigned _i) void Client::noteChanged(h256Set const& _filters) { Guard l(m_filterLock); - cnote << "noteChanged(" << _filters << ")"; +// cnote << "noteChanged(" << _filters << ")"; // accrue all changes left in each filter into the watches. for (auto& i: m_watches) if (_filters.count(i.second.id)) @@ -361,13 +361,12 @@ void Client::setupState(State& _s) cwork << "SETUP MINE"; _s = m_postMine; } - _s.setUncles(m_bc); if (m_paranoia) { if (_s.amIJustParanoid(m_bc)) { cnote << "I'm just paranoid. Block is fine."; - _s.commitToMine(); + _s.commitToMine(m_bc); } else { @@ -375,7 +374,7 @@ void Client::setupState(State& _s) } } else - _s.commitToMine(); + _s.commitToMine(m_bc); } void Client::transact(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice) diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 831696beb..ecb5b2606 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -639,8 +639,7 @@ void State::uncommitToMine() bool State::amIJustParanoid(BlockChain const& _bc) { - setUncles(_bc); - commitToMine(); + commitToMine(_bc); // Update difficulty according to timestamp. m_currentBlock.difficulty = m_currentBlock.calculateDifficulty(m_previousBlock); @@ -683,8 +682,20 @@ LogBloom State::logBloom() const return ret; } -void State::setUncles(BlockChain const& _bc) +void State::commitToMine(BlockChain const& _bc) { + uncommitToMine(); + +// cnote << "Committing to mine on block" << m_previousBlock.hash.abridged(); +#ifdef ETH_PARANOIA + commit(); + cnote << "Pre-reward stateRoot:" << m_state.root(); +#endif + + m_lastTx = m_db; + + Addresses uncleAddresses; + RLPStream unclesData; unsigned unclesCount = 0; if (m_previousBlock != BlockChain::genesis()) @@ -703,26 +714,11 @@ void State::setUncles(BlockChain const& _bc) BlockInfo ubi(_bc.block(u)); ubi.streamRLP(unclesData, WithNonce); ++unclesCount; + uncleAddresses.push_back(ubi.coinbaseAddress); } } } - RLPStream(unclesCount).appendRaw(unclesData.out(), unclesCount).swapOut(m_currentUncles); - m_currentBlock.sha3Uncles = sha3(m_currentUncles); -} - -void State::commitToMine() -{ - uncommitToMine(); - -// cnote << "Committing to mine on block" << m_previousBlock.hash.abridged(); -#ifdef ETH_PARANOIA - commit(); - cnote << "Pre-reward stateRoot:" << m_state.root(); -#endif - - m_lastTx = m_db; - MemoryDB tm; GenericTrieDB transactionsTrie(&tm); transactionsTrie.init(); @@ -752,13 +748,12 @@ void State::commitToMine() txs.swapOut(m_currentTxs); + RLPStream(unclesCount).appendRaw(unclesData.out(), unclesCount).swapOut(m_currentUncles); + m_currentBlock.transactionsRoot = transactionsTrie.root(); m_currentBlock.receiptsRoot = receiptsTrie.root(); m_currentBlock.logBloom = logBloom(); - - Addresses uncleAddresses; - for (const auto& r: RLP(m_currentUncles)) - uncleAddresses.push_back(BlockInfo::fromHeader(r.data()).coinbaseAddress); + m_currentBlock.sha3Uncles = sha3(m_currentUncles); // Apply rewards last of all. applyRewards(uncleAddresses); diff --git a/libethereum/State.h b/libethereum/State.h index 313cc5c44..0a288238d 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -105,16 +105,13 @@ public: /// @returns true if all is ok. If it's false, worry. bool amIJustParanoid(BlockChain const& _bc); - /// @brief Loads current block uncles from blockchain - void setUncles(BlockChain const& _bc); - /// Prepares the current state for mining. /// Commits all transactions into the trie, compiles uncles and transactions list, applies all /// rewards and populates the current block header with the appropriate hashes. /// The only thing left to do after this is to actually mine(). /// /// This may be called multiple times and without issue. - void commitToMine(); + void commitToMine(BlockChain const& _bc); /// Attempt to find valid nonce for block that this state represents. /// This function is thread-safe. You can safely have other interactions with this object while it is happening. @@ -125,11 +122,14 @@ public: /** Commit to DB and build the final block if the previous call to mine()'s result is completion. * Typically looks like: * @code + * while (notYetMined) + * { * // lock - * commitToMine(); + * commitToMine(_blockChain); // will call uncommitToMine if a repeat. * // unlock * MineInfo info; * for (info.complete = false; !info.complete; info = mine()) {} + * } * // lock * completeMine(); * // unlock diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index 293d4036e..a6c833532 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -56,16 +56,15 @@ void MixClient::resetState(u256 _balance) genesis.state = m_state; Block open; m_blocks = Blocks { genesis, open }; //last block contains a list of pending transactions to be finalized - m_lastHashes.clear(); - m_lastHashes.resize(256); - m_lastHashes[0] = genesis.hash; +// m_lastHashes.clear(); +// m_lastHashes.resize(256); +// m_lastHashes[0] = genesis.hash; } void MixClient::executeTransaction(Transaction const& _t, State& _state) { bytes rlp = _t.rlp(); - - Executive execution(_state, m_lastHashes, 0); + Executive execution(_state, LastHashes(), 0); execution.setup(&rlp); std::vector machineStates; std::vector levels; @@ -165,14 +164,12 @@ void MixClient::mine() Block& block = m_blocks.back(); m_state.mine(0, true); m_state.completeMine(); - m_state.commitToMine(); + m_state.commitToMine(BlockChain()); + m_state.cleanup(true); block.state = m_state; block.info = m_state.info(); block.hash = block.info.hash; - m_state.cleanup(true); m_blocks.push_back(Block()); - m_lastHashes.insert(m_lastHashes.begin(), block.hash); - m_lastHashes.resize(256); h256Set changed { dev::eth::PendingChangedFilter, dev::eth::ChainChangedFilter }; noteChanged(changed); diff --git a/mix/MixClient.h b/mix/MixClient.h index dceb9ce7b..fede1891e 100644 --- a/mix/MixClient.h +++ b/mix/MixClient.h @@ -145,7 +145,6 @@ private: std::map m_filters; std::map m_watches; Blocks m_blocks; - eth::LastHashes m_lastHashes; }; } diff --git a/test/stateOriginal.cpp b/test/stateOriginal.cpp index f4804c43b..b1a7c0d8e 100644 --- a/test/stateOriginal.cpp +++ b/test/stateOriginal.cpp @@ -51,7 +51,7 @@ int stateTest() cout << s; // Mine to get some ether! - s.commitToMine(); + s.commitToMine(bc); while (!s.mine(100).completed) {} s.completeMine(); bc.attemptImport(s.blockData(), stateDB); @@ -74,8 +74,9 @@ int stateTest() cout << s; // Mine to get some ether and set in stone. - s.commitToMine(); - while (!s.mine(100).completed) {} + s.commitToMine(bc); + s.commitToMine(bc); + while (!s.mine(50).completed) { s.commitToMine(bc); } s.completeMine(); bc.attemptImport(s.blockData(), stateDB);