26 #include <boost/filesystem.hpp> 39 static_assert(BOOST_VERSION == 106300,
"Wrong boost headers version");
43 _out <<
"Since " <<
toString(_r.
since) <<
" (" << std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - _r.
since).
count();
44 _out <<
"): " << _r.
ticks <<
"ticks";
64 std::shared_ptr<GasPricer> _gpForAdoption,
65 std::string
const& _dbPath,
71 m_bc(_params, _dbPath, _forceAction, [](unsigned
d, unsigned t){ std::cerr <<
"REVISING BLOCKCHAIN: Processed " <<
d <<
" of " << t <<
"...\r"; }),
72 m_gp(_gpForAdoption ? _gpForAdoption : make_shared<TrivialGasPricer>()),
77 init(_host, _dbPath, _forceAction, _networkID);
99 m_lastGetWork = std::chrono::system_clock::now() - chrono::seconds(30);
107 h->onBlockImported(_info);
130 this_thread::sleep_for(std::chrono::milliseconds(500));
143 bytes const*
block = boost::get_error_info<errinfo_block>(_ex);
146 cwarn <<
"ODD: onBadBlock called but exception (" << _ex.
what() <<
") has no block in it.";
147 cwarn << boost::diagnostic_information(_ex);
175 return h->networkId();
188 return h->isSyncing();
304 template <
class S,
class T>
305 static S& filtersStreamOut(
S& _out,
T const& _fs)
309 for (
h256 const&
f: _fs)
311 _out << (i++ ?
", " :
"");
312 if (
f == PendingChangedFilter)
314 else if (
f == ChainChangedFilter)
315 _out << LogTag::Special <<
"chain";
326 io_changed.insert(PendingChangedFilter);
328 for (pair<h256 const, InstalledFilter>& i:
m_filters)
331 auto m = i.second.filter.matches(_receipt);
337 io_changed.insert(i.first);
348 io_changed.insert(ChainChangedFilter);
350 for (pair<h256 const, InstalledFilter>& i:
m_filters)
353 for (
size_t j = 0; j < receipts.size(); j++)
355 auto tr = receipts[j];
356 auto m = i.second.filter.matches(tr);
363 io_changed.insert(i.first);
381 if (!e.
call(_dest, _from, _value, _gasPrice, &_data, _gas))
387 cwarn <<
"Client::call failed: " << boost::current_exception_diagnostic_information();
392 unsigned static const c_syncMin = 1;
393 unsigned static const c_syncMax = 1000;
394 double static const c_targetDuration = 1;
408 clog(
ClientNote) << count <<
"blocks imported in" << unsigned(elapsed * 1000) <<
"ms (" << (count / elapsed) <<
"blocks/s) in #" <<
bc().
number();
411 if (elapsed > c_targetDuration * 1.1 && count > c_syncMin)
431 ctrace <<
"Skipping txq sync for a sealed block.";
438 if (newPendingReceipts.empty())
441 ctrace <<
"No transactions to process. " <<
m_working.
pending().size() <<
" pending, " << s.current <<
" queued, " << s.future <<
" future, " << s.unverified <<
" unverified";
450 for (
size_t i = 0; i < newPendingReceipts.size(); i++)
461 h->noteNewTransactions();
469 for (
auto const&
h: _blocks)
480 for (
auto const&
h: _blocks)
487 for (
auto const&
h: _blocks)
493 for (
auto const&
h: _blocks)
505 bool preChanged =
false;
511 preChanged = newPreMine.
sync(
bc());
573 return chrono::system_clock::now() -
m_lastGetWork < chrono::seconds(30);
594 clog(
ClientNote) <<
"You need to set an author in order to seal!";
643 filtersStreamOut(
cwatch <<
"noteChanged:", _filters);
646 if (_filters.count(w.second.id))
650 cwatch <<
"!!!" << w.first << w.second.id.abridged();
651 w.second.changes +=
m_filters.at(w.second.id).changes;
656 cwatch <<
"!!!" << w.first <<
LogTag::Special << (w.second.id == PendingChangedFilter ?
"pending" : w.second.id == ChainChangedFilter ?
"chain" :
"???");
662 i.second.changes.clear();
680 bool isSealed =
false;
705 if (chrono::system_clock::now() -
m_lastTick > chrono::seconds(1))
721 vector<unsigned> toUninstall;
726 toUninstall.push_back(key);
727 clog(
ClientTrace) <<
"GC: Uninstall" << key <<
"(" << chrono::duration_cast<chrono::seconds>(chrono::system_clock::now() -
m_watches[key].lastPoll).
count() <<
"s old)";
729 for (
auto i: toUninstall)
841 for (
unsigned i = 0; i < 10; ++i)
848 this_thread::sleep_for(std::chrono::milliseconds(50));
bytes const & blockData() const
Get the complete current block, including valid nonce.
virtual bool uninstallWatch(unsigned _watchId) override
void stopSealing() override
Stop sealing.
void resetState()
Clear working state of transactions.
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
boost::error_info< struct tag_block, bytes > errinfo_block
bool call(Address _receiveAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256 _gas)
Set up the executive for evaluating a bare CALL (message call) operation.
BlockHeader m_sealingInfo
The header we're attempting to seal on (derived from m_postSeal).
Block m_working
The state of the client which we're sealing (i.e. it'll have all the rewards added), while we're actually working on it.
void syncTransactionQueue()
Signal handler for when the block queue needs processing.
std::vector< T > keysOf(std::map< T, U > const &_m)
std::pair< TransactionReceipts, bool > sync(BlockChain const &_bc, TransactionQueue &_tq, GasPricer const &_gp, unsigned _msTimeout=100)
Sync our transactions, killing those from the queue that we have and assimilating those that we don't...
void rewind(unsigned _n)
Rewind to a prior head.
std::chrono::system_clock::time_point m_lastGarbageCollection
When did we last both doing GC on the watches?
State fromPending(unsigned _i) const
Get the State immediately after the given number of pending transactions have been applied...
void onPostStateChanged()
Called when the post state has changed (i.e.
void swap(dev::eth::Watch &_a, dev::eth::Watch &_b)
dev::eth::Block block(h256 const &_blockHash, PopulationStatistics *o_stats) const
Get the block.
dev::eth::State state(unsigned _txi, h256 const &_block) const
Get the state of the given block part way through execution, immediately before transaction index _tx...
void setOnBad(T const &_t)
void onTransactionQueueReady()
Magically called when m_tq needs syncing. Be nice and don't block.
void doneWorking() override
Called when Worker is exiting.
Block m_postSeal
The state of the client which we're sealing (i.e. it'll have all the rewards added).
static OverlayDB openDB(std::string const &_path, h256 const &_genesisHash, WithExisting _we=WithExisting::Trust)
Open a DB - useful for passing into the constructor & keeping for other states that are necessary...
Handler onReady(T const &_t)
Register a handler that will be called once there is a new transaction imported.
std::ostream & operator<<(std::ostream &_out, BlockHeader const &_bi)
BlockReceipts receipts(h256 const &_hash) const
Get the transactions' receipts of a block (or the most recent mined if none given).
The Host class Capabilities should be registered prior to startNetwork, since m_capabilities is not t...
const char * what() const noexceptoverride
ImportResult import(bytesConstRef _block, bool _isOurs=false)
Import a block into the queue.
virtual void generateSeal(BlockHeader const &_bi)=0
TransactionReceipts receipts
virtual bool submitSealed(bytes const &_s)
Submit.
void reopenChain(ChainParams const &_p, WithExisting _we=WithExisting::Trust)
Reloads the blockchain. Just for debug use.
void init(p2p::Host *_extNet, std::string const &_dbPath, WithExisting _forceAction, u256 _networkId)
Perform critical setup functions.
bool isSyncing() const override
Are we updating the chain (syncing or importing a new block)?
SharedMutex x_preSeal
Lock on m_preSeal.
boost::upgrade_to_unique_lock< boost::shared_mutex > UpgradeGuard
Block genesisBlock(OverlayDB const &_db) const
Get a pre-made genesis State object.
virtual ~Client()
Destructor.
void commitToSeal(BlockChain const &_bc, bytes const &_extraData={})
Prepares the current state for mining.
std::hash for asio::adress
assert(len-trim+(2 *lenIndices)<=WIDTH)
u256 transactionsFrom(Address const &_address) const
Get the number of transactions a particular address has sent (used for the transaction nonce)...
void startedWorking() override
Called when Worker is starting.
ChainParams const & chainParams() const
Get information on this chain.
std::chrono::system_clock::time_point m_lastTick
When did we last tick()?
std::string toString(string32 const &_s)
Make normal string from fixed-length string.
bool m_wouldButShouldnot
True if the last time we called rejigSealing wouldSeal() was true but sealer's shouldSeal() was false...
boost::upgrade_lock< boost::shared_mutex > UpgradableGuard
void noteChanged(h256Hash const &_filters)
Record that the set of filters _filters have changed.
Description of the result of executing a transaction.
Model of an Ethereum state, essentially a facade for the trie.
bool go(OnOpFunc const &_onOp=OnOpFunc())
Executes (or continues execution of) the VM.
void tick()
Notes that time has moved on and some blocks that used to be "in the future" may no be valid...
void clear()
Clear everything.
void setOnBlockImport(std::function< void(BlockHeader const &)> _t)
Change the function that is called when a new block is imported.
virtual Transactions transactions(h256 _blockHash) const override
BlockQueue m_bq
Maintains a list of incoming blocks not yet on the blockchain (to be imported).
Initial chain sync complete. Waiting for new packets.
Import transaction even if it was dropped before.
void doWork() override
Called continuously following sleep for m_idleWaitMs.
void rejigSealing()
Called when wouldSeal(), pendingTransactions() have changed.
#define DEV_GUARDED(MUTEX)
Simple block guard.
virtual Address author() const override
Get the block author.
bool isMajorSyncing() const override
Are we syncing the chain?
Active model of a block within the block chain.
std::shared_ptr< GasPricer > m_gp
The gas pricer.
void onBlockQueueReady()
Magically called when m_bq needs syncing. Be nice and don't block.
std::vector< TransactionReceipt > TransactionReceipts
void appendFromNewPending(TransactionReceipt const &_receipt, h256Hash &io_changed, h256 _sha3)
Collate the changed filters for the bloom filter of the given pending transaction.
bool wouldSeal() const override
Are we sealing now?
unsigned m_syncAmount
Number of blocks to sync in each go.
void stopWorking()
Stop worker thread; causes call to stopWorking().
void badBlock(bytesConstRef _block, string const &_err)
Base class for all exceptions.
SyncStatus syncStatus() const override
Get some information on the block syncing.
std::tuple< ImportRoute, bool, unsigned > syncQueue(unsigned _max=1)
Freeze worker thread and sync some of the block queue.
static unsigned const c_oldProtocolVersion
std::lock_guard< std::mutex > Guard
PopulationStatistics populateFromChain(BlockChain const &_bc, h256 const &_hash, ImportRequirements::value _ir=ImportRequirements::None)
Construct state object from arbitrary point in blockchain.
virtual void flushTransactions() override
Blocks until all pending transactions have been processed.
BlockChain & bc() override
InterfaceStub methods.
void onDeadBlocks(h256s const &_blocks, h256Hash &io_changed)
Called on chain changes.
unsigned number(h256 const &_hash) const
Get a number for the given hash (or the most recent mined if none given). Thread-safe.
std::chrono::system_clock::time_point since
void clearPending()
Clears pending transactions. Just for debug use.
#define DEV_WRITE_GUARDED(MUTEX)
void rewind(unsigned _newHead)
Alter the head of the chain to some prior block along it.
void finalize()
Finalise a transaction previously set up with initialize().
u256 networkId() const override
Gets the network id.
BlockGetAndPut< word32, BigEndian > Block
virtual void onSealGenerated(std::function< void(bytes const &s)> const &_f)=0
void resyncStateFromChain()
Called after processing blocks by onChainChanged(_ir)
std::atomic< bool > m_syncBlockQueue
#define DEV_READ_GUARDED(MUTEX)
std::vector< byte > bytes
void clear()
Clear the queue.
ExecutionResult call(Address _dest, bytes const &_data=bytes(), u256 _gas=125000, u256 _value=0, u256 _gasPrice=1 *ether, Address const &_from=Address())
Makes the given call. Nothing is recorded into the state. This cheats by creating a null address and ...
h256 sha3(IncludeSignature _sig=WithSignature) const
void garbageCollect(bool _force=false)
Deallocate unused data.
Message-call/contract-creation executor; useful for executing transactions.
bool sealBlock(bytes const &_header)
Pass in a properly sealed header matching this block.
std::atomic< bool > m_needStateReset
Need reset working state to premin on next sync.
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u256
static std::string const & dbPath()
static void setDBPath(std::string const &_dbPath)
ImportResult import(bytes const &_tx, IfDropped _ik=IfDropped::Ignore)
Verify and add transaction to the queue synchronously.
void startWorking()
Starts worker thread; causes startedWorking() to be called.
Transactions const & pending() const
Get the list of pending transactions.
Encodes a transaction, ready to be exported to or freshly imported from RLP.
boost::unique_lock< boost::shared_mutex > WriteGuard
void reopen(WithExisting _we=WithExisting::Trust, ProgressCallback const &_pc=ProgressCallback())
Reopen everything.
virtual void onNewBlocks(h256s const &_blocks, h256Hash &io_changed)
Called on chain changes.
void addCapability(std::shared_ptr< T > const &_p, std::string const &_name, u256 const &_version)
BlockQueueStatus status() const
Get some infomration on the current status.
Address author() const
Get the author address for any transactions we do and rewards we get.
Handler onReady(T const &_t)
std::queue< std::function< void()> > m_functionQueue
Functions waiting to be executed in the main thread.
void setAuthor(Address const &_id)
Set the author address for any transactions we do and rewards we get.
void dropGood(Transaction const &_t)
Drop a trasnaction from the list if exists and move following future trasnactions to current (if any)...
std::shared_ptr< T > registerCapability(std::shared_ptr< T > const &_t)
Register a peer-capability; all new peer connections will have this capability.
std::chrono::system_clock::time_point m_lastGetWork
Is there an active and valid remote worker?
State & mutableState()
Get a mutable State object which is backing this block.
void callQueuedFunctions()
Executes the pending functions in m_functionQueue.
std::unordered_map< h256, h256s > m_specialFilters
The dictionary of special filters and their additional data.
void setChain(BlockChain const &_bc)
void executeInMainThread(std::function< void()> const &_function)
Queues a function to be executed in the main thread (that owns the blockchain, etc).
bool remoteActive() const
Is there an active and valid remote worker?
void setOnBad(std::function< void(Exception &)> _t)
Change the function that is called with a bad block.
SharedMutex x_functionQueue
Block m_preSeal
The present state of the client.
virtual void addBalance(Address const &_id, u256 const &_amount)
Add some amount to balance.
std::weak_ptr< EthereumHost > m_host
Our Ethereum Host. Don't do anything if we can't lock.
void checkWatchGarbage()
Does garbage collection on watches.
void syncBlockQueue()
Signal handler for when the block queue needs processing.
std::unordered_set< h256 > h256Hash
SealEngineFace * sealEngine() const override
Get the seal engine.
virtual unsigned number() const override
static std::string staticName()
void appendFromBlock(h256 const &_blockHash, BlockPolarity _polarity, h256Hash &io_changed)
Collate the changed filters for the hash of the given block.
bool m_wouldSeal
True if we /should/ be sealing.
ActivityReport activityReport()
Get a report of activity.
std::atomic< bool > m_syncTransactionQueue
Mutex x_filtersWatches
Our lock.
void startSealing() override
Start sealing.
std::tuple< ImportRoute, bool, unsigned > sync(BlockQueue &_bq, OverlayDB const &_stateDB, unsigned _max)
Sync the chain with any incoming blocks.
SharedMutex x_working
Lock on m_working.
OverlayDB m_stateDB
Acts as the central point for the state database, so multiple States can share it.
std::vector< Transaction > goodTranactions
std::vector< h256 > h256s
virtual Transaction transaction(h256 _transactionHash) const override
void rescue(OverlayDB const &_db)
Rescue the database.
void onBadBlock(Exception &_ex) const
Called when we have attempted to import a bad block.
SharedMutex x_postSeal
Lock on m_postSeal.
std::condition_variable m_signalled
void onChainChanged(ImportRoute const &_ir)
Magically called when the chain has changed.
Downloading blocks learned from NewHashes packet.
std::map< unsigned, ClientWatch > m_watches
Each and every watch - these reference a filter.
#define DEV_TIMED_FUNCTION_ABOVE(MS)
Handler< h256 const & > onReplaced(T const &_t)
Register a handler that will be called once asynchronous verification is comeplte an transaction has ...
void setNetworkId(u256 const &_n) override
Sets the network id.
Handler< h256 const & > m_tqReplaced
BlockHeader const & info() const
Get the header information on the present block.
std::unordered_map< h256, InstalledFilter > m_filters
The dictionary of filters that are active.
void tick()
Ticks various system-level objects.
virtual void cancelGeneration()
void setResultRecipient(ExecutionResult &_res)
Collect execution results in the result storage provided.
bool m_remoteWorking
Has the remote worker recently been reset?
ImportResult queueBlock(bytes const &_block, bool _isSafe=false)
Queues a block for import.
virtual void prepareForTransaction() override