forked from bcosorg/bcos
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathClientBase.h
194 lines (156 loc) · 8.96 KB
/
ClientBase.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file ClientBase.h
* @author Gav Wood <i@gavwood.com>
* @author Marek Kotewicz <marek@ethdev.com>
* @date 2015
*/
#pragma once
#include <libdevcore/easylog.h>
#include <chrono>
#include "Interface.h"
#include "LogFilter.h"
#include "TransactionQueue.h"
#include "Block.h"
#include "CommonNet.h"
namespace dev
{
namespace eth
{
struct InstalledFilter
{
InstalledFilter(LogFilter const& _f): filter(_f) {}
LogFilter filter;
unsigned refCount = 1;
LocalisedLogEntries changes;
};
static const h256 PendingChangedFilter = u256(0);
static const h256 ChainChangedFilter = u256(1);
static const LogEntry SpecialLogEntry = LogEntry(Address(), h256s(), bytes());
static const LocalisedLogEntry InitialChange(SpecialLogEntry);
struct ClientWatch
{
ClientWatch(): lastPoll(std::chrono::system_clock::now()) {}
explicit ClientWatch(h256 _id, Reaping _r): id(_id), lastPoll(_r == Reaping::Automatic ? std::chrono::system_clock::now() : std::chrono::system_clock::time_point::max()) {}
h256 id;
#if INITIAL_STATE_AS_CHANGES
LocalisedLogEntries changes = LocalisedLogEntries{ InitialChange };
#else
LocalisedLogEntries changes;
#endif
mutable std::chrono::system_clock::time_point lastPoll = std::chrono::system_clock::now();
};
class ClientBase: public Interface
{
public:
ClientBase(TransactionQueue::Limits const& _l = TransactionQueue::Limits{1024, 1024}): m_tq(std::shared_ptr<Interface>(this),_l) {}
virtual ~ClientBase() {}
/// Submits the given transaction.
/// @returns the new transaction's hash.
virtual std::pair<h256, Address> submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) override;
using Interface::submitTransaction;
/// Makes the given call. Nothing is recorded into the state.
virtual ExecutionResult call(Address const& _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) override;
using Interface::call;
/// Makes the given create. Nothing is recorded into the state.
virtual ExecutionResult create(Address const& _secret, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) override;
/// Estimate gas usage for call/create.
/// @param _maxGas An upper bound value for estimation, if not provided default value of c_maxGasEstimate will be used.
/// @param _callback Optional callback function for progress reporting
virtual std::pair<u256, ExecutionResult> estimateGas(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _maxGas, u256 _gasPrice, BlockNumber _blockNumber, GasEstimationCallback const& _callback) override;
using Interface::create;
using Interface::balanceAt;
using Interface::countAt;
using Interface::stateAt;
using Interface::codeAt;
using Interface::codeHashAt;
using Interface::storageAt;
virtual u256 balanceAt(Address _a, BlockNumber _block) const override;
virtual u256 countAt(Address _a, BlockNumber _block) const override;
virtual u256 stateAt(Address _a, u256 _l, BlockNumber _block) const override;
virtual h256 stateRootAt(Address _a, BlockNumber _block) const override;
virtual bytes codeAt(Address _a, BlockNumber _block) const override;
virtual h256 codeHashAt(Address _a, BlockNumber _block) const override;
virtual std::map<h256, std::pair<u256, u256>> storageAt(Address _a, BlockNumber _block) const override;
virtual LocalisedLogEntries logs(unsigned _watchId) const override;
virtual LocalisedLogEntries logs(LogFilter const& _filter) const override;
virtual void prependLogsFromBlock(LogFilter const& _filter, h256 const& _blockHash, BlockPolarity _polarity, LocalisedLogEntries& io_logs) const;
/// Install, uninstall and query watches.
virtual unsigned installWatch(LogFilter const& _filter, Reaping _r = Reaping::Automatic) override;
virtual unsigned installWatch(h256 _filterId, Reaping _r = Reaping::Automatic) override;
virtual bool uninstallWatch(unsigned _watchId) override;
virtual LocalisedLogEntries peekWatch(unsigned _watchId) const override;
virtual LocalisedLogEntries checkWatch(unsigned _watchId) override;
virtual h256 hashFromNumber(BlockNumber _number) const override;
virtual BlockNumber numberFromHash(h256 _blockHash) const override;
virtual int compareBlockHashes(h256 _h1, h256 _h2) const override;
virtual BlockHeader blockInfo(h256 _hash) const override;
virtual BlockDetails blockDetails(h256 _hash) const override;
virtual Transaction transaction(h256 _transactionHash) const override;
virtual LocalisedTransaction localisedTransaction(h256 const& _transactionHash) const override;
virtual Transaction transaction(h256 _blockHash, unsigned _i) const override;
virtual LocalisedTransaction localisedTransaction(h256 const& _blockHash, unsigned _i) const override;
virtual TransactionReceipt transactionReceipt(h256 const& _transactionHash) const override;
virtual LocalisedTransactionReceipt localisedTransactionReceipt(h256 const& _transactionHash) const override;
virtual std::pair<h256, unsigned> transactionLocation(h256 const& _transactionHash) const override;
virtual Transactions transactions(h256 _blockHash) const override;
virtual TransactionHashes transactionHashes(h256 _blockHash) const override;
virtual BlockHeader uncle(h256 _blockHash, unsigned _i) const override;
virtual UncleHashes uncleHashes(h256 _blockHash) const override;
virtual unsigned transactionCount(h256 _blockHash) const override;
virtual unsigned uncleCount(h256 _blockHash) const override;
virtual unsigned number() const override;
virtual Transactions pending() const override;
virtual h256s pendingHashes() const override;
virtual BlockHeader pendingInfo() const override;
virtual BlockDetails pendingDetails() const override;
virtual EVMSchedule evmSchedule() const override { return sealEngine()->evmSchedule(EnvInfo(pendingInfo())); }
virtual ImportResult injectTransaction(bytes const& _rlp, IfDropped _id = IfDropped::Ignore) override { prepareForTransaction(); return m_tq.import(_rlp, _id); }
virtual ImportResult injectBlock(bytes const& _block) override;
using Interface::addresses;
virtual Addresses addresses(BlockNumber _block) const override;
virtual u256 gasLimitRemaining() const override;
virtual u256 gasBidPrice() const override { return DefaultGasPrice; }
/// Get the block author
virtual Address author() const override;
virtual bool isKnown(h256 const& _hash) const override;
virtual bool isKnown(BlockNumber _block) const override;
virtual bool isKnownTransaction(h256 const& _transactionHash) const override;
virtual bool isKnownTransaction(h256 const& _blockHash, unsigned _i) const override;
virtual void startSealing() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::startSealing")); }
virtual void stopSealing() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::stopSealing")); }
virtual bool wouldSeal() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::wouldSeal")); }
virtual SyncStatus syncStatus() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::syncStatus")); }
Block block(BlockNumber _h) const;
virtual bool isNonceOk(Transaction const&_ts) const override;
virtual bool isBlockLimitOk(Transaction const&_ts) const override;
protected:
/// The interface that must be implemented in any class deriving this.
/// {
virtual BlockChain& bc() = 0;
virtual BlockChain const& bc() const = 0;
virtual Block block(h256 const& _h) const = 0;
virtual Block preSeal() const = 0;
virtual Block postSeal() const = 0;
virtual void prepareForTransaction() = 0;
/// }
TransactionQueue m_tq; ///< Maintains a list of incoming transactions not yet in a block on the blockchain.
// filters
mutable Mutex x_filtersWatches; ///< Our lock.
std::unordered_map<h256, InstalledFilter> m_filters; ///< The dictionary of filters that are active.
std::unordered_map<h256, h256s> m_specialFilters = std::unordered_map<h256, std::vector<h256>>{{PendingChangedFilter, {}}, {ChainChangedFilter, {}}};
///< The dictionary of special filters and their additional data
std::map<unsigned, ClientWatch> m_watches; ///< Each and every watch - these reference a filter.
};
}}