Fabcoin Core  0.16.2
P2P Digital Currency
Block.cpp
Go to the documentation of this file.
1 /*
2  This file is part of cpp-ethereum.
3 
4  cpp-ethereum is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  cpp-ethereum is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16 */
23 #include <libethereum/BlockQueue.h>
24 #include <libethereum/Block.h>
28 
29 using namespace std;
30 using namespace dev;
31 using namespace dev::eth;
32 using namespace dev::test;
33 
35 
36 #if !defined(_WIN32)
38 {
39  BlockChat chat;
40  BlockTrace trace;
41  BlockDetail details;
42  BlockSafeExceptions exeptions;
43 
44  BOOST_REQUIRE(string(chat.name()).find("◌") != string::npos);
45  BOOST_REQUIRE(string(trace.name()).find("◎") != string::npos);
46  BOOST_REQUIRE(string(details.name()).find("◌") != string::npos);
47  BOOST_REQUIRE(string(exeptions.name()).find("ℹ") != string::npos);
48 }
49 #endif
50 
52 {
53  if (!dev::test::Options::get().quadratic)
54  return;
55  try
56  {
57  TestBlockChain testBlockchain(TestBlockChain::defaultGenesisBlock());
58  TestBlock const& genesisBlock = testBlockchain.testGenesis();
59  OverlayDB const& genesisDB = genesisBlock.state().db();
60  BlockChain const& blockchain = testBlockchain.interface();
61 
62  State stateBofore = testBlockchain.topBlock().state();
63 
64  TestBlock testBlock;
65  TestTransaction transaction1 = TestTransaction::defaultTransaction(1);
66  testBlock.addTransaction(transaction1);
67  TestTransaction transaction2 = TestTransaction::defaultTransaction(2);
68  testBlock.addTransaction(transaction2);
69 
70  testBlock.mine(testBlockchain);
71  testBlockchain.addBlock(testBlock);
72 
73  //Block2 is synced to latest blockchain block
74  Block block1 = blockchain.genesisBlock(genesisDB);
75  block1.populateFromChain(blockchain, testBlock.blockHeader().hash());
76 
77  Block block2 = blockchain.genesisBlock(genesisDB);
78  block2.populateFromChain(blockchain, testBlock.blockHeader().hash());
79  State stateAfterInsert = block2.fromPending(0); //get the state of blockchain on previous block
80  BOOST_REQUIRE(ImportTest::compareStates(stateBofore, stateAfterInsert) == 0);
81 
82  State stateAfterInsert1 = block2.fromPending(1); //get the state of blockchain on current block executed
83  BOOST_REQUIRE(ImportTest::compareStates(stateAfterInsert, stateAfterInsert1, eth::AccountMaskMap(), WhenError::DontThrow) == 1);
84 
85  State stateAfterInsert2 = block2.fromPending(2); //get the state of blockchain on current block executed
86  BOOST_REQUIRE(ImportTest::compareStates(stateBofore, stateAfterInsert2, eth::AccountMaskMap(), WhenError::DontThrow) == 1);
87  BOOST_REQUIRE(ImportTest::compareStates(stateAfterInsert1, stateAfterInsert2, eth::AccountMaskMap(), WhenError::DontThrow) == 1);
88 
89  //Block2 will start a new block on top of blockchain
90  BOOST_REQUIRE(block1.info() == block2.info());
91  block2.sync(blockchain);
92  BOOST_REQUIRE(block1.info() != block2.info());
93 
94  try
95  {
96  Block block(Block::Null);
97  //Invalid state root exception if block not initialized by genesis root
98  block.populateFromChain(blockchain, testBlock.blockHeader().hash());
99  }
100  catch (std::exception const& _e)
101  {
102  BOOST_REQUIRE(string(_e.what()).find("InvalidStateRoot") != string::npos);
103  }
104  }
105  catch (Exception const& _e)
106  {
107  BOOST_ERROR("Failed test with Exception: " << diagnostic_information(_e));
108  }
109  catch (std::exception const& _e)
110  {
111  BOOST_ERROR("Failed test with Exception: " << _e.what());
112  }
113  catch(...)
114  {
115  BOOST_ERROR("Exception thrown when trying to mine or import a block!");
116  }
117 }
118 
120 {
121  TestBlockChain testBlockchain(TestBlockChain::defaultGenesisBlock(63000));
122  TestBlock const& genesisBlock = testBlockchain.testGenesis();
123  OverlayDB const& genesisDB = genesisBlock.state().db();
124  BlockChain const& blockchain = testBlockchain.interface();
125 
126  TestBlock testBlock;
127  TestTransaction transaction1 = TestTransaction::defaultTransaction(1, 1, 21000);
128  testBlock.addTransaction(transaction1);
129  TestTransaction transaction2 = TestTransaction::defaultTransaction(2, 1, 21000);
130  testBlock.addTransaction(transaction2);
131 
132  {
133  //Normal transaction input
134  ZeroGasPricer gp;
135  Block block = blockchain.genesisBlock(genesisDB);
136  block.sync(blockchain);
137  TestBlock testBlockT = testBlock;
138  block.sync(blockchain, testBlockT.transactionQueue(), gp);
139  BOOST_REQUIRE(testBlockT.transactionQueue().topTransactions(4).size() == 2);
140  }
141 
142  {
143  //Block not synced to blockchain
144  TestBlock testBlockT = testBlock;
145  ZeroGasPricer gp;
146  Block block = blockchain.genesisBlock(genesisDB);
147  block.sync(blockchain, testBlockT.transactionQueue(), gp);
148  BOOST_REQUIRE(testBlockT.transactionQueue().topTransactions(4).size() == 2);
149  }
150 
151  {
152  //Transactions valid but exceed block gasLimit - BlockGasLimitReached
153  TestBlock testBlockT = testBlock;
154  TestTransaction transaction = TestTransaction::defaultTransaction(3, 1, 1500000);
155  testBlockT.addTransaction(transaction);
156 
157  ZeroGasPricer gp;
158  Block block = blockchain.genesisBlock(genesisDB);
159  block.sync(blockchain);
160  block.sync(blockchain, testBlockT.transactionQueue(), gp);
161  BOOST_REQUIRE(testBlockT.transactionQueue().topTransactions(4).size() == 2);
162  }
163 
164  {
165  //Temporary no gas left in the block
166  TestBlock testBlockT = testBlock;
167  TestTransaction transaction = TestTransaction::defaultTransaction(3, 1, 25000, importByteArray("238479601324597364057623047523945623847562387450234857263485723459273645345234689563486749"));
168  testBlockT.addTransaction(transaction);
169 
170  ZeroGasPricer gp;
171  Block block = blockchain.genesisBlock(genesisDB);
172  block.sync(blockchain);
173  block.sync(blockchain, testBlockT.transactionQueue(), gp);
174  BOOST_REQUIRE(testBlockT.transactionQueue().topTransactions(4).size() == 3);
175  }
176 
177  {
178  //Invalid nonce - nonces ahead
179  TestBlock testBlockT = testBlock;
180  TestTransaction transaction = TestTransaction::defaultTransaction(12, 1, 21000);
181  testBlockT.addTransaction(transaction);
182 
183  ZeroGasPricer gp;
184  Block block = blockchain.genesisBlock(genesisDB);
185  block.sync(blockchain);
186  block.sync(blockchain, testBlockT.transactionQueue(), gp);
187  BOOST_REQUIRE(testBlockT.transactionQueue().topTransactions(4).size() == 2);
188  }
189 
190  {
191  //Invalid nonce - nonce too low
192  TestBlock testBlockT = testBlock;
193  TestTransaction transaction = TestTransaction::defaultTransaction(0, 1, 21000);
194  testBlockT.addTransaction(transaction);
195 
196  ZeroGasPricer gp;
197  Block block = blockchain.genesisBlock(genesisDB);
198  block.sync(blockchain);
199  block.sync(blockchain, testBlockT.transactionQueue(), gp);
200  BOOST_REQUIRE(testBlockT.transactionQueue().topTransactions(4).size() == 2);
201  }
202 }
203 
204 BOOST_AUTO_TEST_CASE(bCopyOperator)
205 {
206  try
207  {
208  TestBlockChain testBlockchain(TestBlockChain::defaultGenesisBlock());
209  TestBlock const& genesisBlock = testBlockchain.testGenesis();
210 
211  OverlayDB const& genesisDB = genesisBlock.state().db();
212  BlockChain const& blockchain = testBlockchain.interface();
213  Block block = blockchain.genesisBlock(genesisDB);
214  block.setAuthor(genesisBlock.beneficiary());
215 
216  block = block;
217  Block block2 = block;
218  BOOST_REQUIRE(ImportTest::compareStates(block.state(), block2.state()) == 0);
219  BOOST_REQUIRE(block2.pending() == block.pending());
220  BOOST_REQUIRE(block2.author() == block.author());
221  BOOST_REQUIRE(block2.info() == block.info());
222 
223  TestBlock testBlock;
224  TestTransaction transaction1 = TestTransaction::defaultTransaction(1);
225  testBlock.addTransaction(transaction1);
226  testBlock.mine(testBlockchain);
227  testBlockchain.addBlock(testBlock);
228 
229  Block block3 = blockchain.genesisBlock(genesisDB);
230  block3.populateFromChain(blockchain, testBlock.blockHeader().hash());
231  BOOST_REQUIRE(block3.info() == testBlock.blockHeader());
232 
233  //Genesis is populating wrong???
234  //Block block31 = blockchain.genesisBlock(genesisDB);
235  //block31.populateFromChain(blockchain, genesisBlock.getBlockHeader().hash());
236  //BOOST_REQUIRE(block31.info() == (BlockInfo)genesisBlock.getBlockHeader());
237 
238  Block block32 = blockchain.genesisBlock(genesisDB);
239  auto is_critical = []( std::exception const& _e) { return string(_e.what()).find("BlockNotFound") != string::npos; };
240  BOOST_CHECK_EXCEPTION(block32.populateFromChain(blockchain, h256("0x0000000000000000000000000000000000000000000000000000000000000001")), BlockNotFound, is_critical);
241  }
242  catch (Exception const& _e)
243  {
244  BOOST_ERROR("Failed test with Exception: " << diagnostic_information(_e));
245  }
246  catch (std::exception const& _e)
247  {
248  BOOST_ERROR("Failed test with Exception: " << _e.what());
249  }
250  catch(...)
251  {
252  BOOST_ERROR("Exception thrown when trying to mine or import a block!");
253  }
254 }
255 
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
TestBlock const & topBlock()
State const & state() const
Get the backing state object.
Definition: Block.h:163
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&#39;t...
Definition: Block.cpp:301
static Options const & get(int argc=0, char **argv=0)
Get reference to options The first time used, options are parsed with argc, argv. ...
Definition: Options.cpp:203
State fromPending(unsigned _i) const
Get the State immediately after the given number of pending transactions have been applied...
Definition: Block.cpp:832
static const char * name()
Definition: Block.cpp:50
Implements the blockchain database.
Definition: BlockChain.h:105
h256 hash(IncludeSeal _i=WithSeal) const
Definition: BlockHeader.cpp:64
BlockChain const & interface() const
BOOST_AUTO_TEST_CASE(bStructures)
Definition: Block.cpp:37
Block genesisBlock(OverlayDB const &_db) const
Get a pre-made genesis State object.
static const char * name()
Definition: Block.cpp:53
std::hash for asio::adress
Definition: Common.h:323
BlockHeader const & blockHeader() const
Model of an Ethereum state, essentially a facade for the trie.
Definition: State.h:161
OverlayDB const & db() const
Definition: State.h:195
Transactions topTransactions(unsigned _limit, h256Hash const &_avoid=h256Hash()) const
Get top transactions from the queue.
Active model of a block within the block chain.
Definition: Block.h:73
TestBlock const & testGenesis() const
Base class for all exceptions.
Definition: Exceptions.h:39
PopulationStatistics populateFromChain(BlockChain const &_bc, h256 const &_hash, ImportRequirements::value _ir=ImportRequirements::None)
Construct state object from arbitrary point in blockchain.
Definition: Block.cpp:150
Transactions const & pending() const
Get the list of pending transactions.
Definition: Block.h:188
std::unordered_map< Address, AccountMask > AccountMaskMap
Definition: Account.h:240
bool addBlock(TestBlock const &_block)
Address author() const
Get the author address for any transactions we do and rewards we get.
Definition: Block.h:114
void mine(TestBlockChain const &_bc)
void setAuthor(Address const &_id)
Set the author address for any transactions we do and rewards we get.
Definition: Block.h:118
static const char * name()
Definition: Block.cpp:52
TransactionQueue const & transactionQueue() const
State const & state() const
#define BOOST_FIXTURE_TEST_SUITE(a, b)
Definition: object.cpp:14
static const char * name()
Definition: Block.cpp:51
#define BOOST_AUTO_TEST_SUITE_END()
Definition: object.cpp:16
void addTransaction(TestTransaction const &_tr)
bytes importByteArray(std::string const &_str)
Definition: TestHelper.cpp:221
Address const & beneficiary() const
BlockHeader const & info() const
Get the header information on the present block.
Definition: Block.h:279
Helper functions to work with json::spirit and test files.