|
@ -161,6 +161,7 @@ State::State(State const& _s): |
|
|
m_db(_s.m_db), |
|
|
m_db(_s.m_db), |
|
|
m_state(&m_db, _s.m_state.root()), |
|
|
m_state(&m_db, _s.m_state.root()), |
|
|
m_transactions(_s.m_transactions), |
|
|
m_transactions(_s.m_transactions), |
|
|
|
|
|
m_receipts(_s.m_receipts), |
|
|
m_transactionSet(_s.m_transactionSet), |
|
|
m_transactionSet(_s.m_transactionSet), |
|
|
m_cache(_s.m_cache), |
|
|
m_cache(_s.m_cache), |
|
|
m_previousBlock(_s.m_previousBlock), |
|
|
m_previousBlock(_s.m_previousBlock), |
|
@ -192,6 +193,7 @@ State& State::operator=(State const& _s) |
|
|
m_db = _s.m_db; |
|
|
m_db = _s.m_db; |
|
|
m_state.open(&m_db, _s.m_state.root()); |
|
|
m_state.open(&m_db, _s.m_state.root()); |
|
|
m_transactions = _s.m_transactions; |
|
|
m_transactions = _s.m_transactions; |
|
|
|
|
|
m_receipts = _s.m_receipts; |
|
|
m_transactionSet = _s.m_transactionSet; |
|
|
m_transactionSet = _s.m_transactionSet; |
|
|
m_cache = _s.m_cache; |
|
|
m_cache = _s.m_cache; |
|
|
m_previousBlock = _s.m_previousBlock; |
|
|
m_previousBlock = _s.m_previousBlock; |
|
@ -353,7 +355,7 @@ void State::ensureCached(std::map<Address, AddressState>& _cache, Address _a, bo |
|
|
RLP state(stateBack); |
|
|
RLP state(stateBack); |
|
|
AddressState s; |
|
|
AddressState s; |
|
|
if (state.isNull()) |
|
|
if (state.isNull()) |
|
|
s = AddressState(0, 0, ZeroRLPSHA3, EmptySHA3); |
|
|
s = AddressState(0, 0, EmptyTrie, EmptySHA3); |
|
|
else |
|
|
else |
|
|
s = AddressState(state[0].toInt<u256>(), state[1].toInt<u256>(), state[2].toHash<h256>(), state[3].toHash<h256>()); |
|
|
s = AddressState(state[0].toInt<u256>(), state[1].toInt<u256>(), state[2].toHash<h256>(), state[3].toHash<h256>()); |
|
|
bool ok; |
|
|
bool ok; |
|
@ -484,6 +486,7 @@ map<Address, u256> State::addresses() const |
|
|
void State::resetCurrent() |
|
|
void State::resetCurrent() |
|
|
{ |
|
|
{ |
|
|
m_transactions.clear(); |
|
|
m_transactions.clear(); |
|
|
|
|
|
m_receipts.clear(); |
|
|
m_transactionSet.clear(); |
|
|
m_transactionSet.clear(); |
|
|
m_cache.clear(); |
|
|
m_cache.clear(); |
|
|
m_currentBlock = BlockInfo(); |
|
|
m_currentBlock = BlockInfo(); |
|
@ -547,7 +550,7 @@ h256s State::sync(TransactionQueue& _tq, bool* o_transactionQueueChanged) |
|
|
{ |
|
|
{ |
|
|
uncommitToMine(); |
|
|
uncommitToMine(); |
|
|
execute(i.second); |
|
|
execute(i.second); |
|
|
ret.push_back(m_transactions.back().changes.bloom()); |
|
|
ret.push_back(m_receipts.back().changes().bloom()); |
|
|
_tq.noteGood(i); |
|
|
_tq.noteGood(i); |
|
|
++goodTxs; |
|
|
++goodTxs; |
|
|
} |
|
|
} |
|
@ -713,7 +716,7 @@ void State::uncommitToMine() |
|
|
if (!m_transactions.size()) |
|
|
if (!m_transactions.size()) |
|
|
m_state.setRoot(m_previousBlock.stateRoot); |
|
|
m_state.setRoot(m_previousBlock.stateRoot); |
|
|
else |
|
|
else |
|
|
m_state.setRoot(m_transactions[m_transactions.size() - 1].stateRoot); |
|
|
m_state.setRoot(m_receipts[m_receipts.size() - 1].stateRoot()); |
|
|
m_db = m_lastTx; |
|
|
m_db = m_lastTx; |
|
|
paranoia("Uncommited to mine", true); |
|
|
paranoia("Uncommited to mine", true); |
|
|
m_currentBlock.sha3Uncles = h256(); |
|
|
m_currentBlock.sha3Uncles = h256(); |
|
@ -730,7 +733,7 @@ bool State::amIJustParanoid(BlockChain const& _bc) |
|
|
// Compile block:
|
|
|
// Compile block:
|
|
|
RLPStream block; |
|
|
RLPStream block; |
|
|
block.appendList(3); |
|
|
block.appendList(3); |
|
|
m_currentBlock.fillStream(block, true); |
|
|
m_currentBlock.streamRLP(block, true); |
|
|
block.appendRaw(m_currentTxs); |
|
|
block.appendRaw(m_currentTxs); |
|
|
block.appendRaw(m_currentUncles); |
|
|
block.appendRaw(m_currentUncles); |
|
|
|
|
|
|
|
@ -757,11 +760,20 @@ bool State::amIJustParanoid(BlockChain const& _bc) |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
h256 State::bloom() const |
|
|
h256 State::oldBloom() const |
|
|
{ |
|
|
{ |
|
|
h256 ret = m_currentBlock.coinbaseAddress.bloom(); |
|
|
h256 ret = m_currentBlock.coinbaseAddress.bloom(); |
|
|
for (auto const& i: m_transactions) |
|
|
for (auto const& i: m_receipts) |
|
|
ret |= i.changes.bloom(); |
|
|
ret |= i.changes().bloom(); |
|
|
|
|
|
return ret; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
LogBloom State::logBloom() const |
|
|
|
|
|
{ |
|
|
|
|
|
LogBloom ret; |
|
|
|
|
|
ret.shiftBloom<3>(sha3(m_currentBlock.coinbaseAddress.ref())); |
|
|
|
|
|
for (TransactionReceipt const& i: m_receipts) |
|
|
|
|
|
ret |= i.bloom(); |
|
|
return ret; |
|
|
return ret; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -797,7 +809,7 @@ void State::commitToMine(BlockChain const& _bc) |
|
|
if (!knownUncles.count(u)) // ignore any uncles/mainline blocks that we know about.
|
|
|
if (!knownUncles.count(u)) // ignore any uncles/mainline blocks that we know about.
|
|
|
{ |
|
|
{ |
|
|
BlockInfo ubi(_bc.block(u)); |
|
|
BlockInfo ubi(_bc.block(u)); |
|
|
ubi.fillStream(unclesData, true); |
|
|
ubi.streamRLP(unclesData, true); |
|
|
++unclesCount; |
|
|
++unclesCount; |
|
|
uncleAddresses.push_back(ubi.coinbaseAddress); |
|
|
uncleAddresses.push_back(ubi.coinbaseAddress); |
|
|
} |
|
|
} |
|
@ -805,8 +817,8 @@ void State::commitToMine(BlockChain const& _bc) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
MemoryDB tm; |
|
|
MemoryDB tm; |
|
|
GenericTrieDB<MemoryDB> transactionReceipts(&tm); |
|
|
GenericTrieDB<MemoryDB> receipts(&tm); |
|
|
transactionReceipts.init(); |
|
|
receipts.init(); |
|
|
|
|
|
|
|
|
RLPStream txs; |
|
|
RLPStream txs; |
|
|
txs.appendList(m_transactions.size()); |
|
|
txs.appendList(m_transactions.size()); |
|
@ -816,16 +828,20 @@ void State::commitToMine(BlockChain const& _bc) |
|
|
RLPStream k; |
|
|
RLPStream k; |
|
|
k << i; |
|
|
k << i; |
|
|
RLPStream v; |
|
|
RLPStream v; |
|
|
m_transactions[i].fillStream(v); |
|
|
m_receipts[i].streamRLP(v); |
|
|
transactionReceipts.insert(&k.out(), &v.out()); |
|
|
receipts.insert(&k.out(), &v.out()); |
|
|
txs.appendRaw(v.out()); |
|
|
|
|
|
|
|
|
RLPStream txrlp; |
|
|
|
|
|
m_transactions[i].streamRLP(txrlp); |
|
|
|
|
|
txs.appendRaw(txrlp.out()); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
txs.swapOut(m_currentTxs); |
|
|
txs.swapOut(m_currentTxs); |
|
|
|
|
|
|
|
|
RLPStream(unclesCount).appendRaw(unclesData.out(), unclesCount).swapOut(m_currentUncles); |
|
|
RLPStream(unclesCount).appendRaw(unclesData.out(), unclesCount).swapOut(m_currentUncles); |
|
|
|
|
|
|
|
|
m_currentBlock.transactionsRoot = transactionReceipts.root(); |
|
|
m_currentBlock.receiptsRoot = receipts.root(); |
|
|
|
|
|
m_currentBlock.logBloom = logBloom(); |
|
|
m_currentBlock.sha3Uncles = sha3(m_currentUncles); |
|
|
m_currentBlock.sha3Uncles = sha3(m_currentUncles); |
|
|
|
|
|
|
|
|
// Apply rewards last of all.
|
|
|
// Apply rewards last of all.
|
|
@ -865,7 +881,7 @@ void State::completeMine() |
|
|
// Compile block:
|
|
|
// Compile block:
|
|
|
RLPStream ret; |
|
|
RLPStream ret; |
|
|
ret.appendList(3); |
|
|
ret.appendList(3); |
|
|
m_currentBlock.fillStream(ret, true); |
|
|
m_currentBlock.streamRLP(ret, true); |
|
|
ret.appendRaw(m_currentTxs); |
|
|
ret.appendRaw(m_currentTxs); |
|
|
ret.appendRaw(m_currentUncles); |
|
|
ret.appendRaw(m_currentUncles); |
|
|
ret.swapOut(m_currentBytes); |
|
|
ret.swapOut(m_currentBytes); |
|
@ -875,6 +891,7 @@ void State::completeMine() |
|
|
// Quickly reset the transactions.
|
|
|
// Quickly reset the transactions.
|
|
|
// TODO: Leave this in a better state than this limbo, or at least record that it's in limbo.
|
|
|
// TODO: Leave this in a better state than this limbo, or at least record that it's in limbo.
|
|
|
m_transactions.clear(); |
|
|
m_transactions.clear(); |
|
|
|
|
|
m_receipts.clear(); |
|
|
m_transactionSet.clear(); |
|
|
m_transactionSet.clear(); |
|
|
m_lastTx = m_db; |
|
|
m_lastTx = m_db; |
|
|
} |
|
|
} |
|
@ -1114,7 +1131,8 @@ u256 State::execute(bytesConstRef _rlp, bytes* o_output, bool _commit) |
|
|
// TODO: CHECK TRIE after level DB flush to make sure exactly the same.
|
|
|
// TODO: CHECK TRIE after level DB flush to make sure exactly the same.
|
|
|
|
|
|
|
|
|
// Add to the user-originated transactions that we've executed.
|
|
|
// Add to the user-originated transactions that we've executed.
|
|
|
m_transactions.push_back(TransactionReceipt(e.t(), rootHash(), startGasUsed + e.gasUsed(), ms, e.logs())); |
|
|
m_transactions.push_back(e.t()); |
|
|
|
|
|
m_receipts.push_back(TransactionReceipt(rootHash(), startGasUsed + e.gasUsed(), e.logs(), ms)); |
|
|
m_transactionSet.insert(e.t().sha3()); |
|
|
m_transactionSet.insert(e.t().sha3()); |
|
|
return e.gasUsed(); |
|
|
return e.gasUsed(); |
|
|
} |
|
|
} |
|
@ -1185,6 +1203,12 @@ bool State::call(Address _receiveAddress, Address _codeAddress, Address _senderA |
|
|
|
|
|
|
|
|
return !revert; |
|
|
return !revert; |
|
|
} |
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
// non-contract call
|
|
|
|
|
|
if (o_sub) |
|
|
|
|
|
o_sub->logs.push_back(LogEntry(_receiveAddress, {u256((u160)_senderAddress) + 1}, bytes())); |
|
|
|
|
|
} |
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -1261,11 +1285,12 @@ State State::fromPending(unsigned _i) const |
|
|
if (!_i) |
|
|
if (!_i) |
|
|
ret.m_state.setRoot(m_previousBlock.stateRoot); |
|
|
ret.m_state.setRoot(m_previousBlock.stateRoot); |
|
|
else |
|
|
else |
|
|
ret.m_state.setRoot(m_transactions[_i - 1].stateRoot); |
|
|
ret.m_state.setRoot(m_receipts[_i - 1].stateRoot()); |
|
|
while (ret.m_transactions.size() > _i) |
|
|
while (ret.m_transactions.size() > _i) |
|
|
{ |
|
|
{ |
|
|
ret.m_transactionSet.erase(ret.m_transactions.back().transaction.sha3()); |
|
|
ret.m_transactionSet.erase(ret.m_transactions.back().sha3()); |
|
|
ret.m_transactions.pop_back(); |
|
|
ret.m_transactions.pop_back(); |
|
|
|
|
|
ret.m_receipts.pop_back(); |
|
|
} |
|
|
} |
|
|
return ret; |
|
|
return ret; |
|
|
} |
|
|
} |
|
|