Browse Source

Nasty little State fix.

cl-refactor
Gav Wood 11 years ago
parent
commit
3276fb6adc
  1. 2
      libethereum/AddressState.h
  2. 3
      libethereum/Client.cpp
  3. 47
      libethereum/State.cpp
  4. 8
      libethereum/State.h

2
libethereum/AddressState.h

@ -52,7 +52,7 @@ public:
bool isFreshCode() const { return !m_codeHash; }
h256 codeHash() const { assert(m_codeHash); return m_codeHash; }
bool haveCode() const { return m_codeHash == EmptySHA3 || !m_codeHash || m_codeCache.size(); }
bool haveCode() const { return m_codeHash != EmptySHA3 || m_codeCache.size(); }
bytes const& code() const { assert(m_codeHash == EmptySHA3 || !m_codeHash || m_codeCache.size()); return m_codeCache; }
void setCode(bytesConstRef _code) { assert(!m_codeHash); m_codeCache = _code.toBytes(); }
void noteCode(bytesConstRef _code) { assert(sha3(_code) == m_codeHash); m_codeCache = _code.toBytes(); }

3
libethereum/Client.cpp

@ -207,11 +207,10 @@ void Client::work()
m_restartMining = true; // need to re-commit to mine.
m_postMine = m_preMine;
}
if (m_postMine.sync(m_tq))
if (m_postMine.sync(m_tq, &changed))
{
if (m_doMine)
cnote << "Additional transaction ready: Restarting mining operation.";
changed = true;
m_restartMining = true;
}
}

47
libethereum/State.cpp

@ -153,7 +153,7 @@ void State::commit()
bool State::sync(BlockChain const& _bc)
{
return sync(_bc, _bc.currentHash());
return sync(_bc, _bc.currentHash());
}
bool State::sync(BlockChain const& _bc, h256 _block)
@ -272,7 +272,7 @@ bool State::cull(TransactionQueue& _tq) const
return ret;
}
bool State::sync(TransactionQueue& _tq)
bool State::sync(TransactionQueue& _tq, bool* _changed)
{
// TRANSACTIONS
bool ret = false;
@ -289,8 +289,11 @@ bool State::sync(TransactionQueue& _tq)
// don't have it yet! Execute it now.
try
{
execute(i.second);
ret = true;
uncommitToMine();
execute(i.second);
if (_changed)
*_changed = true;
_tq.noteGood(i);
++goodTxs;
}
@ -300,7 +303,8 @@ bool State::sync(TransactionQueue& _tq)
{
// too old
_tq.drop(i.first);
ret = true;
if (_changed)
*_changed = true;
}
else
_tq.setFuture(i);
@ -309,7 +313,8 @@ bool State::sync(TransactionQueue& _tq)
{
// Something else went wrong - drop it.
_tq.drop(i.first);
ret = true;
if (_changed)
*_changed = true;
}
}
}
@ -364,9 +369,9 @@ u256 State::playbackRaw(bytesConstRef _block, BlockInfo const& _grandParent, boo
if (tr[1].toInt<u256>() != m_state.root())
{
// Invalid state root
cnote << m_state.root() << m_state;
cnote << m_state.root() << "\n" << m_state;
cnote << *this;
cnote << "INVALID: " << tr[1].toInt<u256>();
cnote << "INVALID: " << hex << tr[1].toInt<u256>();
throw InvalidTransactionStateRoot();
}
if (tr[2].toInt<u256>() != gasUsed())
@ -437,17 +442,26 @@ u256 State::playbackRaw(bytesConstRef _block, BlockInfo const& _grandParent, boo
return tdIncrease;
}
// @returns the block that represents the difference between m_previousBlock and m_currentBlock.
// (i.e. all the transactions we executed).
void State::commitToMine(BlockChain const& _bc)
void State::uncommitToMine()
{
if (m_currentBlock.sha3Uncles != h256())
{
// cnote << "Unapplying rewards: " << balance(m_currentBlock.coinbaseAddress);
Addresses uncleAddresses;
for (auto i: RLP(m_currentUncles))
uncleAddresses.push_back(i[2].toHash<Address>());
unapplyRewards(uncleAddresses);
// cnote << "Unapplied rewards: " << balance(m_currentBlock.coinbaseAddress);
m_currentBlock.sha3Uncles = h256();
}
}
// @returns the block that represents the difference between m_previousBlock and m_currentBlock.
// (i.e. all the transactions we executed).
void State::commitToMine(BlockChain const& _bc)
{
uncommitToMine();
cnote << "Commiting to mine on" << m_previousBlock.hash;
@ -472,12 +486,14 @@ void State::commitToMine(BlockChain const& _bc)
else
uncles.appendList(0);
cnote << *this;
applyRewards(uncleAddresses);
if (m_transactionManifest.isNull())
m_transactionManifest.init();
else
while(!m_transactionManifest.isEmpty())
m_transactionManifest.remove((*m_transactionManifest.begin()).first);
cnote << *this;
RLPStream txs;
txs.appendList(m_transactions.size());
@ -665,12 +681,13 @@ bytes const& State::code(Address _contract) const
u256 State::execute(bytesConstRef _rlp)
{
// cnote << m_state.root() << m_state;
// cnote << *this;
Executive e(*this);
e.setup(_rlp);
// cnote << "Executing " << e.t();
// cnote << m_state.root() << "\n" << m_state;
// cnote << *this;
u256 startGasUSed = gasUsed();
if (startGasUSed + e.t().gas > m_currentBlock.gasLimit)
throw BlockGasLimitReached(); // TODO: make sure this is handled.
@ -680,8 +697,8 @@ u256 State::execute(bytesConstRef _rlp)
commit();
// cnote << "Done TX";
// cnote << m_state.root() << m_state;
// cnote << "Executed.";
// cnote << m_state.root() << "\n" << m_state;
// cnote << *this;
// Add to the user-originated transactions that we've executed.

8
libethereum/State.h

@ -127,8 +127,9 @@ public:
/// Sync with the block chain, but rather than synching to the latest block, instead sync to the given block.
bool sync(BlockChain const& _bc, h256 _blockHash);
// TODO: Cleaner interface.
/// Sync our transactions, killing those from the queue that we have and assimilating those that we don't.
bool sync(TransactionQueue& _tq);
bool sync(TransactionQueue& _tq, bool* _changed = nullptr);
/// Like sync but only operate on _tq, killing the invalid/old ones.
bool cull(TransactionQueue& _tq) const;
@ -199,6 +200,9 @@ public:
u256 callGas(uint _dataCount, u256 _gas = 0) const { return c_txDataGas * _dataCount + c_callGas + _gas; }
private:
/// Undo the changes to the state for committing to mine.
void uncommitToMine();
/// Retrieve all information about a given address into the cache.
/// If _requireMemory is true, grab the full memory should it be a contract item.
/// If _forceCreate is true, then insert a default item into the cache, in the case it doesn't
@ -305,7 +309,7 @@ inline std::ostream& operator<<(std::ostream& _out, State const& _s)
else
{
_out << (d.count(i.first) ? "[ ! " : "[ * ") << "]" << i.first << ": " << std::dec << i.second.nonce() << "@" << i.second.balance();
if (i.second.codeHash() != EmptySHA3)
if (i.second.isFreshCode() || i.second.haveCode())
{
_out << " *" << i.second.oldRoot();
TrieDB<h256, Overlay> memdb(const_cast<Overlay*>(&_s.m_db), i.second.oldRoot()); // promise we won't alter the overlay! :)

Loading…
Cancel
Save