@ -72,8 +72,8 @@ OverlayDB State::openDB(std::string const& _basePath, WithExisting _we)
o . max_open_files = 256 ;
o . create_if_missing = true ;
ldb : : DB * db = nullptr ;
ldb : : DB : : Open ( o , path + " /state " , & db ) ;
if ( ! db )
ldb : : Status status = ldb : : DB : : Open ( o , path + " /state " , & db ) ;
if ( ! status . ok ( ) | | ! db )
{
if ( boost : : filesystem : : space ( path + " /state " ) . available < 1024 )
{
@ -82,6 +82,7 @@ OverlayDB State::openDB(std::string const& _basePath, WithExisting _we)
}
else
{
cwarn < < status . ToString ( ) ;
cwarn < < " Database already open. You appear to have another instance of ethereum running. Bailing. " ;
BOOST_THROW_EXCEPTION ( DatabaseAlreadyOpen ( ) ) ;
}
@ -129,7 +130,7 @@ PopulationStatistics State::populateFromChain(BlockChain const& _bc, h256 const&
{
// Might be worth throwing here.
cwarn < < " Invalid block given for state population: " < < _h ;
return ret ;
BOOST_THROW_EXCEPTION ( BlockNotFound ( ) < < errinfo_target ( _h ) ) ;
}
auto b = _bc . block ( _h ) ;
@ -244,9 +245,6 @@ StateDiff State::diff(State const& _c, bool _quick) const
for ( auto const & i : _c . m_cache )
ads . insert ( i . first ) ;
// cnote << *this;
// cnote << _c;
for ( auto const & i : ads )
{
auto it = m_cache . find ( i ) ;
@ -305,14 +303,14 @@ bool State::sync(BlockChain const& _bc, h256 _block, BlockInfo const& _bi, Impor
bool ret = false ;
// BLOCK
BlockInfo bi = _bi ? _bi : _bc . info ( _block ) ;
/* if (!bi)
# if ETH_PARANOIA
if ( ! bi )
while ( 1 )
{
try
{
auto b = _bc . block ( _block ) ;
bi . populate ( b ) ;
// bi.verifyInternals(_bc.block(_block)); // Unneeded - we already verify on import into the blockchain.
break ;
}
catch ( Exception const & _e )
@ -327,7 +325,8 @@ bool State::sync(BlockChain const& _bc, h256 _block, BlockInfo const& _bi, Impor
cerr < < " ERROR: Corrupt block-chain! Delete your block-chain DB and restart. " < < endl ;
cerr < < _e . what ( ) < < endl ;
}
} */
}
# endif
if ( bi = = m_currentBlock )
{
// We mined the last block.
@ -352,7 +351,7 @@ bool State::sync(BlockChain const& _bc, h256 _block, BlockInfo const& _bi, Impor
cwarn < < " Unable to sync to " < < bi . hash ( ) < < " ; state root " < < bi . stateRoot < < " not found in database. " ;
cwarn < < " Database corrupt: contains block without stateRoot: " < < bi ;
cwarn < < " Bailing. " ;
exit ( - 1 ) ;
BOOST_THROW_EXCEPTION ( InvalidStateRoot ( ) < < errinfo_target ( bi . stateRoot ) ) ;
}
m_previousBlock = bi ;
resetCurrent ( ) ;
@ -477,7 +476,6 @@ void State::resetCurrent()
m_currentBlock . sha3Uncles = h256 ( ) ;
m_currentBlock . populateFromParent ( m_previousBlock ) ;
// Update timestamp according to clock.
// TODO: check.
m_lastTx = m_db ;
@ -557,7 +555,6 @@ pair<TransactionReceipts, bool> State::sync(BlockChain const& _bc, TransactionQu
// Temporarily no gas left in current block.
// OPTIMISE: could note this and then we don't evaluate until a block that does have the gas left.
// for now, just leave alone.
// _tq.setFuture(t.sha3());
}
}
catch ( Exception const & _e )
@ -782,7 +779,8 @@ void State::cleanup(bool _fullCommit)
if ( isChannelVisible < StateTrace > ( ) ) // Avoid calling toHex if not needed
clog ( StateTrace ) < < " Committing to disk: stateRoot " < < m_currentBlock . stateRoot < < " = " < < rootHash ( ) < < " = " < < toHex ( asBytes ( m_db . lookup ( rootHash ( ) ) ) ) ;
try {
try
{
EnforceRefs er ( m_db , true ) ;
rootHash ( ) ;
}
@ -835,12 +833,6 @@ void State::commitToMine(BlockChain const& _bc, bytes const& _extraData)
{
uncommitToMine ( ) ;
// cnote << "Committing to mine on block" << m_previousBlock.hash;
# if ETH_PARANOIA && 0
commit ( ) ;
cnote < < " Pre-reward stateRoot: " < < m_state . root ( ) ;
# endif
m_lastTx = m_db ;
vector < BlockInfo > uncleBlockHeaders ;
@ -850,7 +842,7 @@ void State::commitToMine(BlockChain const& _bc, bytes const& _extraData)
if ( m_previousBlock . number ! = 0 )
{
// Find great-uncles (or second-cousins or whatever they are) - children of great-grandparents, great-great-grandparents... that were not already uncles in previous generations.
// cout << "Checking " << m_previousBlock.hash << ", parent=" << m_previousBlock.parentHash << endl;
clog ( StateDetail ) < < " Checking " < < m_previousBlock . hash ( ) < < " , parent= " < < m_previousBlock . parentHash ;
h256Hash excluded = _bc . allKinFrom ( m_currentBlock . parentHash , 6 ) ;
auto p = m_previousBlock . parentHash ;
for ( unsigned gen = 0 ; gen < 6 & & p ! = _bc . genesisHash ( ) & & unclesCount < 2 ; + + gen , p = _bc . details ( p ) . parent )
@ -907,9 +899,9 @@ void State::commitToMine(BlockChain const& _bc, bytes const& _extraData)
// Commit any and all changes to the trie that are in the cache, then update the state root accordingly.
commit ( ) ;
// cnote << "Post-reward stateRoot:" << m_state.root();
// cnote << m_state;
// cnote << *this;
clog ( StateDetail ) < < " Post-reward stateRoot: " < < m_state . root ( ) ;
clog ( StateDetail ) < < m_state ;
clog ( StateDetail ) < < * this ;
m_currentBlock . gasUsed = gasUsed ( ) ;
m_currentBlock . stateRoot = m_state . root ( ) ;
@ -923,7 +915,7 @@ void State::commitToMine(BlockChain const& _bc, bytes const& _extraData)
void State : : completeMine ( )
{
cdebug < < " Completing mine! " ;
clog ( StateDetail ) < < " Completing mine! " ;
// Got it!
// Compile block:
@ -1086,6 +1078,17 @@ unordered_map<u256, u256> State::storage(Address const& _id) const
return ret ;
}
h256 State : : storageRoot ( Address const & _id ) const
{
string s = m_state . at ( _id ) ;
if ( s . size ( ) )
{
RLP r ( s ) ;
return r [ 2 ] . toHash < h256 > ( ) ;
}
return EmptyTrie ;
}
bytes const & State : : code ( Address const & _contract ) const
{
if ( ! addressHasCode ( _contract ) )
@ -1115,7 +1118,7 @@ bool State::isTrieGood(bool _enforceRefs, bool _requireNoLeftOvers) const
cwarn < < " LEFTOVERS " < < ( e ? " [enforced " : " [unenforced " ) < < " refs] " ;
cnote < < " Left: " < < lo ;
cnote < < " Keys: " < < m_db . keys ( ) ;
// m_state.debugStructure(cerr);
m_state . debugStructure ( cerr ) ;
return false ;
}
// TODO: Enable once fixed.
@ -1132,14 +1135,12 @@ bool State::isTrieGood(bool _enforceRefs, bool _requireNoLeftOvers) const
{
cwarn < < " BAD TRIE " < < ( e ? " [enforced " : " [unenforced " ) < < " refs] " ;
cnote < < m_db . keys ( ) ;
// m_state.debugStructure(cerr);
m_state . debugStructure ( cerr ) ;
return false ;
}
return true ;
}
# define ETH_VMTIMER 1
ExecutionResult State : : execute ( LastHashes const & _lh , Transaction const & _t , Permanence _p , OnOpFunc const & _onOp )
{
# if ETH_PARANOIA