diff --git a/libdevcore/OverlayDB.cpp b/libdevcore/OverlayDB.cpp index a96dcee06..65851b300 100644 --- a/libdevcore/OverlayDB.cpp +++ b/libdevcore/OverlayDB.cpp @@ -41,7 +41,6 @@ OverlayDB::~OverlayDB() = default; void OverlayDB::commit() { if ( m_db ) { for ( unsigned commitTry = 0; commitTry < 10; ++commitTry ) { -// cnote << "Committing nodes to disk DB:"; #if DEV_GUARDED_DB DEV_READ_GUARDED( x_this ) #endif diff --git a/libdevcore/RLP.cpp b/libdevcore/RLP.cpp index 8bbd3e2fe..bb571f9ee 100644 --- a/libdevcore/RLP.cpp +++ b/libdevcore/RLP.cpp @@ -221,7 +221,6 @@ RLPStream& RLPStream::appendRaw( bytesConstRef _s, size_t _itemCount ) { void RLPStream::noteAppended( size_t _itemCount ) { if ( !_itemCount ) return; - // cdebug << "noteAppended(" << _itemCount << ")"; while ( m_listStack.size() ) { if ( m_listStack.back().first < _itemCount ) BOOST_THROW_EXCEPTION( RLPException() @@ -257,7 +256,6 @@ void RLPStream::noteAppended( size_t _itemCount ) { } RLPStream& RLPStream::appendList( size_t _items ) { - // cdebug << "appendList(" << _items << ")"; if ( _items ) m_listStack.push_back( std::make_pair( _items, m_out.size() ) ); else diff --git a/libdevcore/TransientDirectory.cpp b/libdevcore/TransientDirectory.cpp index fbce27281..afd950413 100644 --- a/libdevcore/TransientDirectory.cpp +++ b/libdevcore/TransientDirectory.cpp @@ -53,7 +53,7 @@ TransientDirectory::~TransientDirectory() { if ( !ec ) return; - // In some cases, antivirus runnig on Windows will scan all the newly created directories. + // In some cases, antivirus running on Windows will scan all the newly created directories. // As a consequence, directory is locked and can not be deleted immediately. // Retry after 10 milliseconds usually is successful. // This will help our tests run smoothly in such environment. diff --git a/libdevcore/TrieDB.h b/libdevcore/TrieDB.h index cd5e71528..3daba689a 100644 --- a/libdevcore/TrieDB.h +++ b/libdevcore/TrieDB.h @@ -885,7 +885,6 @@ bytes GenericTrieDB< DB >::mergeAt( } auto sh = _k.shared( k ); - // std::cout << _k << " sh " << k << " = " << sh << std::endl; if ( sh ) { // shared stuff - cleve at disagreement. auto cleved = cleve( _orig, sh ); @@ -1059,11 +1058,6 @@ bool GenericTrieDB< DB >::deleteAtAux( RLPStream& _out, RLP const& _orig, Nibble if ( !b.size() ) // not found - no change. return false; - /* if (_orig.isList()) - killNode(_orig); - else - killNode(_orig.toHash());*/ - streamNode( _out, b ); return true; } @@ -1146,9 +1140,6 @@ bytes GenericTrieDB< DB >::graft( RLP const& _orig ) { assert( n.itemCount() == 2 ); return rlpList( hexPrefixEncode( keyOf( _orig ), keyOf( n ), isLeaf( n ) ), n[1] ); - // auto ret = - // std::cout << keyOf(_orig) << " ++ " << keyOf(n) << " == " << keyOf(RLP(ret)) << std::endl; - // return ret; } template < class DB > diff --git a/libethashseal/Ethash.cpp b/libethashseal/Ethash.cpp index e87b27237..86cfafe23 100644 --- a/libethashseal/Ethash.cpp +++ b/libethashseal/Ethash.cpp @@ -43,9 +43,6 @@ Ethash::Ethash() { m_farm.setSealers( sealers ); m_farm.onSolutionFound( [this]( EthashProofOfWork::Solution const& sol ) { std::unique_lock< Mutex > l( m_submitLock ); - // cdebug << m_farm.work().seedHash << m_farm.work().headerHash << sol.nonce << - // EthashAux::eval(m_farm.work().seedHash, m_farm.work().headerHash, - // sol.nonce).value; setMixHash( m_sealing, sol.mixHash ); setNonce( m_sealing, sol.nonce ); if ( !quickVerifySeal( m_sealing ) ) diff --git a/libethcore/Common.h b/libethcore/Common.h index 686c2f266..b538f9edc 100644 --- a/libethcore/Common.h +++ b/libethcore/Common.h @@ -246,8 +246,6 @@ inline void badBlock( bytes const& _header, std::string const& _err ) { * @brief Describes the progress of a mining operation. */ struct WorkingProgress { - // MiningProgress& operator+=(MiningProgress const& _mp) { hashes += _mp.hashes; ms = - // std::max(ms, _mp.ms); return *this; } uint64_t hashes = 0; ///< Total number of hashes computed. uint64_t ms = 0; ///< Total number of milliseconds of mining thus far. u256 rate() const { return ms == 0 ? 0 : hashes * 1000 / ms; } diff --git a/libethcore/EVMSchedule.h b/libethcore/EVMSchedule.h index 3f0b645c3..70d916834 100644 --- a/libethcore/EVMSchedule.h +++ b/libethcore/EVMSchedule.h @@ -181,15 +181,12 @@ static const EVMSchedule IstanbulSchedule = [] { schedule.extcodehashGas = 700; schedule.haveChainID = true; schedule.haveSelfbalance = true; - // schedule.eip2200Mode = true; schedule.sstoreUnchangedGas = 800; return schedule; }(); static const EVMSchedule BerlinSchedule = [] { EVMSchedule schedule = IstanbulSchedule; - // schedule.precompileStaticCallGas = 40; - // schedule.callSelfGas = 40; return schedule; }(); diff --git a/libethcore/TransactionBase.h b/libethcore/TransactionBase.h index 531a1511b..3a72df09d 100644 --- a/libethcore/TransactionBase.h +++ b/libethcore/TransactionBase.h @@ -521,7 +521,7 @@ class TransactionBase { #ifdef BITE // called in TransactionBase constructor // sets m_isBITETxn to true if a txn 'to' field - // maches BITE address + // matches BITE address void checkIfBITETxnAndSet( const Address& _to ); #endif diff --git a/libethereum/Block.cpp b/libethereum/Block.cpp index be9b4815c..414dc4208 100644 --- a/libethereum/Block.cpp +++ b/libethereum/Block.cpp @@ -110,7 +110,6 @@ Block::Block( BlockChain const& _bc, boost::filesystem::path const& _dbPath, noteChain( _bc ); m_previousBlock.clear(); m_currentBlock.clear(); - // assert(m_state.root() == m_previousBlock.stateRoot()); } Block::Block( const BlockChain& _bc, h256 const& _hash, const State& _state, BaseState /*_bs*/, @@ -141,9 +140,6 @@ Block::Block( const BlockChain& _bc, h256 const& _hash, const State& _state, Bas if ( !bi.number() ) { // Genesis required: // We know there are no transactions, so just populate directly. - - // m_state = State(m_state.accountStartNonce(), m_state.db(), - // BaseState::Empty); // TODO: try with PreExisting. sync( _bc, _hash, bi ); } else { auto parentHash = bi.parentHash(); @@ -298,8 +294,6 @@ PopulationStatistics Block::populateFromChain( // Genesis required: // We know there are no transactions, so just populate directly. std::logic_error( "Not implemented" ); - // m_state = State(m_state.accountStartNonce(), m_state.db(), - // BaseState::Empty); // TODO: try with PreExisting. sync( _bc, _h, bi ); } @@ -435,7 +429,6 @@ pair< TransactionReceipts, bool > Block::sync( if ( !m_transactionSet.count( t.sha3() ) ) { try { if ( t.gasPrice() >= _gp.ask( *this ) ) { - // Timer t; execute( _bc.lastBlockHashes(), t, Permanence::Uncommitted ); #ifdef FAIR ret.first = m_receipts; @@ -443,7 +436,6 @@ pair< TransactionReceipts, bool > Block::sync( ret.first.push_back( m_receipts.back() ); #endif ++goodTxs; - // cnote << "TX took:" << t.elapsed() * 1000; } else if ( t.gasPrice() < _gp.ask( *this ) * 9 / 10 ) { BOOST_LOG( m_loggerDebug ) << t.sha3() << " Dropping El Cheapo transaction (<90% of ask price)"; @@ -479,7 +471,6 @@ pair< TransactionReceipts, bool > Block::sync( << t.sha3() << " Temporarily no gas left in current block (txs gas > " "block's gas limit)"; - //_tq.drop(t.sha3()); // 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. @@ -978,9 +969,6 @@ u256 Block::enact( VerifiedBlockRef const& _block, BlockChain const& _bc ) { m_currentBlock.noteDirty(); m_currentBlock = _block.info; - // cnote << "playback begins:" << m_currentBlock.hash() << "(without: " << - // m_currentBlock.hash(WithoutSeal) << ")"; cnote << m_state; - RLP rlp( _block.block ); vector< bytes > receipts; @@ -1024,7 +1012,6 @@ u256 Block::enact( VerifiedBlockRef const& _block, BlockChain const& _bc ) { InvalidReceiptsStateRoot ex; ex << Hash256RequirementError( m_currentBlock.receiptsRoot(), receiptsRoot ); ex << errinfo_receipts( receipts ); - // ex << errinfo_vmtrace(vmTrace(_block.block, _bc, ImportRequirements::None)); for ( auto const& receipt : m_receipts ) { if ( !receipt.hasStatusCode() ) { BOOST_LOG( m_loggerWarning ) << "Skale does not support state root in receipt"; @@ -1153,16 +1140,6 @@ u256 Block::enact( VerifiedBlockRef const& _block, BlockChain const& _bc ) { m_state.commit( removeEmptyAccounts ? dev::eth::CommitBehaviour::RemoveEmptyAccounts : dev::eth::CommitBehaviour::KeepEmptyAccounts ); - // // Hash the state trie and check against the state_root hash in m_currentBlock. - // if (m_currentBlock.stateRoot() != m_previousBlock.stateRoot() && - // m_currentBlock.stateRoot() != globalRoot()) - // { - // auto r = globalRoot(); - // m_state.db().rollback(); // TODO: API in State for this? - // BOOST_THROW_EXCEPTION( - // InvalidStateRoot() << Hash256RequirementError(m_currentBlock.stateRoot(), r)); - // } - return tdIncrease; } @@ -1268,7 +1245,7 @@ ExecutionResult Block::execute( LastBlockHashesFace const& _lh, Transaction cons // use fake receipt created above if execution throws!! } catch ( const TransactionException& ex ) { - // shoul not happen as exception in execute() means that tx should not be in block + // should not happen as exception in execute() means that tx should not be in block BOOST_LOG( m_loggerError ) << DETAILED_ERROR; assert( false ); } catch ( const std::exception& ex ) { @@ -1414,7 +1391,7 @@ void Block::commitToSeal( unsigned unclesCount = 0; // here was code to handle 6 generations of uncles - // it was wtiting its results in two variables above + // it was waiting its results in two variables above BytesMap transactionsMap; BytesMap receiptsMap; @@ -1517,8 +1494,6 @@ bool Block::sealBlock( bytesConstRef _header ) { ret.appendRaw( m_currentUncles ); ret.swapOut( m_currentBytes ); m_currentBlock = BlockHeader( _header, HeaderData ); - // cnote << "Mined " << m_currentBlock.hash() << "(parent: " << m_currentBlock.parentHash() << - //")"; // TODO: move into SealEngine m_state = m_precommit; diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index a421931d5..c903c3475 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -265,8 +265,6 @@ void BlockChain::open( fs::path const& _path, bool _applyPatches, WithExisting _ m_db_splitter = std::make_unique< batched_io::db_splitter >( m_db ); m_blocksDB = m_db_splitter->new_interface(); m_extrasDB = m_db_splitter->new_interface(); - // m_blocksDB.reset( new db::DBImpl( chainPath / fs::path( "blocks" ) ) ); - // m_extrasDB.reset( new db::DBImpl( extrasPath / fs::path( "extras" ) ) ); } catch ( db::DatabaseError const& ex ) { // Check the exact reason of errror, in case of IOError we can display user-friendly message if ( *boost::get_error_info< db::errinfo_dbStatusCode >( ex ) != @@ -332,8 +330,6 @@ void BlockChain::open( fs::path const& _path, bool _applyPatches, WithExisting _ BOOST_LOG( m_loggerDebug ) << "Opened blockchain DB. Latest: " << currentHash() << ' ' << m_lastBlockNumber; - // dump_blocks_and_extras_db( *this, 0 ); - if ( _applyPatches && TotalStorageUsedPatch::isInitOnChainNeeded( *m_db ) ) TotalStorageUsedPatch::initOnChain( *this ); } @@ -423,8 +419,6 @@ tuple< ImportRoute, bool, unsigned > BlockChain::sync( BlockQueue& _bq, State& _state, unsigned _max ) { MICROPROFILE_SCOPEI( "BlockChain", "sync many blocks", MP_LIGHTGOLDENROD ); - // _bq.tick(*this); - VerifiedBlocks blocks; _bq.drain( blocks, _max ); @@ -453,10 +447,7 @@ tuple< ImportRoute, bool, unsigned > BlockChain::sync( continue; } catch ( dev::eth::UnknownParent const& ) { BOOST_LOG( m_loggerWarning ) - << "ODD: Import queue contains block with unknown parent."; // << - // LogTag::Error - // << - // boost::current_exception_diagnostic_information(); + << "ODD: Import queue contains block with unknown parent."; // NOTE: don't reimport since the queue should guarantee everything in the right // order. Can't continue - chain bad. badBlocks.push_back( block.verified.info.hash() ); @@ -811,11 +802,10 @@ void BlockChain::insertTransactionsDetailsToDb( dev::Address to = dev::Address( txFields.to.data(), dev::Address::ConstructFromPointer ); DecryptedTransactionData txData( txFields.data, to ); - _extrasWriteBatch.insert( - toSlice( sha3( txBytes ), ExtraTransactionDecryptedData ), + _extrasWriteBatch.insert( toSlice( txHash, ExtraTransactionDecryptedData ), ( db::Slice ) dev::ref( txData.rlp() ) ); - ++regularTxnsIterator; } + ++regularTxnsIterator; } else if ( _block.transactions.at( ta.index ).isCTX() && Bite2Patch::isEnabledInWorkingBlock() ) { dev::h256 ctxOriginHash = _block.transactions[ta.index].getCTXOrigin(); @@ -840,7 +830,7 @@ void BlockChain::insertBloomsDetailsToDb( // // We need to compute log blooms directly here without using Block::logBloom() // method because _receipts may contain extra receipt items corresponding to - // partially cought-up transactions + // partially caught-up transactions // // old code was: // LogBloom blockBloom = tbi.logBloom(); // @@ -869,7 +859,6 @@ void BlockChain::insertBloomsDetailsToDb( noteUsed( h, ExtraBlocksBlooms ); // Update database with them. - // ReadGuard l1( x_blocksBlooms ); WriteGuard l1( x_blocksBlooms ); { MICROPROFILE_SCOPEI( "insertBlockAndExtras", "insert_to_extras", MP_LIGHTSKYBLUE ); @@ -882,7 +871,7 @@ void BlockChain::insertBloomsDetailsToDb( } } -// TOOD ACHTUNG This function must be kept in sync with the next one! +// TODO ACHTUNG This function must be kept in sync with the next one! size_t BlockChain::prepareDbDataAndReturnSize( VerifiedBlockRef const& _block, bytesConstRef _receipts, u256 const& _totalDifficulty, const LogBloom* pLogBloomFull, ImportPerformanceLogger& _performanceLogger ) { @@ -907,7 +896,7 @@ size_t BlockChain::prepareDbDataAndReturnSize( VerifiedBlockRef const& _block, return writeSize; } -// TOOD ACHTUNG This function must be kept in sync with prepareDbDataAndReturnSize defined above!! +// TODO ACHTUNG This function must be kept in sync with prepareDbDataAndReturnSize defined above!! // TODO move it to TotalStorageUsedPatch! void BlockChain::recomputeExistingOccupiedSpaceForBlockRotation() try { unsigned number = this->number(); @@ -1201,8 +1190,6 @@ void BlockChain::rescue( State const& /*_state*/ ) { details( h ); BOOST_LOG( m_loggerInfo ) << "state..." << flush; BOOST_LOG( m_loggerInfo ) << "STATE VALIDITY CHECK IS NOT SUPPORTED" << flush; - // if (_db.exists(bi.stateRoot())) - // break; } catch ( ... ) { } } @@ -1400,10 +1387,9 @@ void BlockChain::garbageCollect( bool _force ) { if ( m_lastStats.memTotal() < c_minCacheSize ) return; - m_lastCollection = chrono::system_clock::now(); - // We subtract memory that blockhashes occupy because it is treated sepaparately + // We subtract memory that blockhashes occupy because it is treated separately while ( m_lastStats.memTotal() - m_lastStats.memBlockHashes >= c_maxCacheSize ) { Guard l( x_cacheUsage ); for ( CacheID const& id : m_cacheUsage.back() ) { @@ -1606,9 +1592,6 @@ static inline unsigned upow( unsigned a, unsigned b ) { static inline unsigned ceilDiv( unsigned n, unsigned d ) { return ( n + d - 1 ) / d; } -// static inline unsigned floorDivPow(unsigned n, unsigned a, unsigned b) { return n / upow(a, -// b); } static inline unsigned ceilDivPow(unsigned n, unsigned a, unsigned b) { return -// ceilDiv(n, upow(a, b)); } // Level 1 // [xxx. ] diff --git a/libethereum/BlockDetails.cpp b/libethereum/BlockDetails.cpp index 3c2dc5577..dbbd3368d 100644 --- a/libethereum/BlockDetails.cpp +++ b/libethereum/BlockDetails.cpp @@ -39,7 +39,6 @@ BlockDetails::BlockDetails( RLP const& _r ) { bytes BlockDetails::rlp() const { auto ret = rlpList( number, totalDifficulty, parent, children, blockSizeBytes ); - // size = ret.size(); return ret; } diff --git a/libethereum/ChainParams.cpp b/libethereum/ChainParams.cpp index 443419f5c..8384d7b31 100644 --- a/libethereum/ChainParams.cpp +++ b/libethereum/ChainParams.cpp @@ -695,10 +695,6 @@ const std::string& ChainParams::getOriginalJson() const { params[c_tieBreakingGas] = tieBreakingGas; params[c_blockReward] = toHex( toBigEndian( blockReward( DefaultSchedule ) ) ); - // auto setOptionalU256Parameter = [¶ms](u256 &_destination, string const &_name) { - // if (params.count(_name)) - // _destination = u256(fromBigEndian(fromHex(params.at(_name).get_str()))); - // }; params[c_minGasLimit] = toHex( toBigEndian( minGasLimit ) ); params[c_maxGasLimit] = toHex( toBigEndian( maxGasLimit ) ); params[c_gasLimitBoundDivisor] = toHex( toBigEndian( gasLimitBoundDivisor ) ); diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 7d4987867..12f9ffa30 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -777,7 +777,6 @@ void Client::restartMining() { if ( !m_postSeal.isSealed() || m_postSeal.info().hash() != newPreMine.info().parentHash() ) for ( auto const& t : m_postSeal.pending() ) { BOOST_LOG( m_loggerTrace ) << "Resubmitting post-seal transaction " << t; - // ctrace << "Resubmitting post-seal transaction " << t; auto ir = m_tq.import( t, IfDropped::Retry, chainParams().isMultiTransactionModeEnabled(), state().getNonce( t.sender() ) ); if ( ir != ImportResult::Success ) @@ -1034,13 +1033,6 @@ void Client::doWork( bool _doWait ) { bool isSealed = false; DEV_READ_GUARDED( x_working ) isSealed = m_working.isSealed(); - // if (!isSealed && !isMajorSyncing() && !m_remoteWorking && - // m_syncTransactionQueue.compare_exchange_strong(t, false)) - // syncTransactionQueue(); - - // TEMPRORARY FIX! - // TODO: REVIEW - // tick(); // SKALE Mine only empty blocks! (for tests passing/account balancing) rejigSealing(); @@ -1397,7 +1389,7 @@ Json::Value Client::traceBlock( BlockNumber _blockNumber, Json::Value const& _js auto traceOptions = TraceOptions::make( _jsonTraceConfig ); - // cache results for better peformance + // cache results for better performance string key = to_string( _blockNumber ) + traceOptions.toString(); auto cachedResult = m_blockTraceCache.getIfExists( key ); @@ -1585,7 +1577,7 @@ const dev::h256 Client::empty_str_hash = #ifdef HISTORIC_STATE -u256 Client::historicStateBalanceAt( Address _a, BlockNumber _block ) const { +u256 Client::historicStateBalanceAt( Address const& _a, BlockNumber _block ) const { auto block = blockByNumber( _block ); auto aState = block.mutableState().mutableHistoricState(); @@ -1593,19 +1585,19 @@ u256 Client::historicStateBalanceAt( Address _a, BlockNumber _block ) const { return aState.balance( _a ); } -u256 Client::historicStateCountAt( Address _a, BlockNumber _block ) const { +u256 Client::historicStateCountAt( Address const& _a, BlockNumber _block ) const { return blockByNumber( _block ).mutableState().mutableHistoricState().getNonce( _a ); } -u256 Client::historicStateAt( Address _a, u256 _l, BlockNumber _block ) const { +u256 Client::historicStateAt( Address const& _a, u256 const& _l, BlockNumber _block ) const { return blockByNumber( _block ).mutableState().mutableHistoricState().storage( _a, _l ); } -h256 Client::historicStateRootAt( Address _a, BlockNumber _block ) const { +h256 Client::historicStateRootAt( Address const& _a, BlockNumber _block ) const { return blockByNumber( _block ).mutableState().mutableHistoricState().storageRoot( _a ); } -bytes Client::historicStateCodeAt( Address _a, BlockNumber _block ) const { +bytes Client::historicStateCodeAt( Address const& _a, BlockNumber _block ) const { return blockByNumber( _block ).mutableState().mutableHistoricState().code( _a ); } #endif diff --git a/libethereum/Client.h b/libethereum/Client.h index 572237283..6bf4f0225 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -718,11 +718,11 @@ class Client : public ClientBase, protected Worker { #ifdef HISTORIC_STATE - u256 historicStateBalanceAt( Address _a, BlockNumber _block ) const override; - u256 historicStateCountAt( Address _a, BlockNumber _block ) const override; - u256 historicStateAt( Address _a, u256 _l, BlockNumber _block ) const override; - h256 historicStateRootAt( Address _a, BlockNumber _block ) const override; - bytes historicStateCodeAt( Address _a, BlockNumber _block ) const override; + u256 historicStateBalanceAt( Address const& _a, BlockNumber _block ) const override; + u256 historicStateCountAt( Address const& _a, BlockNumber _block ) const override; + u256 historicStateAt( Address const& _a, u256 const& _l, BlockNumber _block ) const override; + h256 historicStateRootAt( Address const& _a, BlockNumber _block ) const override; + bytes historicStateCodeAt( Address const& _a, BlockNumber _block ) const override; #endif void initStateFromDiskOrGenesis(); void populateNewChainStateFromGenesis(); diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 9724fa886..4a780e4b2 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -115,9 +115,9 @@ std::pair< bool, ExecutionResult > ClientBase::estimateGasStep( int64_t _gas, Bl } } -std::pair< u256, ExecutionResult > ClientBase::estimateGas( Address const& _from, u256 _value, - Address _dest, bytes const& _data, int64_t _maxGas, u256 _gasPrice, - GasEstimationCallback const& _callback ) { +std::pair< u256, ExecutionResult > ClientBase::estimateGas( Address const& _from, + u256 const& _value, Address const& _dest, bytes const& _data, int64_t _maxGas, + u256 const& _gasPrice, GasEstimationCallback const& _callback ) { try { int64_t upperBound = _maxGas; if ( upperBound == Invalid256 || upperBound > c_maxGasEstimate ) @@ -316,7 +316,7 @@ unsigned ClientBase::installWatch( } unsigned ClientBase::installWatch( - h256 _h, Reaping _r, fnClientWatchHandlerMulti_t fnOnNewChanges, bool isWS ) { + h256 const& _h, Reaping _r, fnClientWatchHandlerMulti_t fnOnNewChanges, bool isWS ) { unsigned ret; { Guard l( x_filtersWatches ); @@ -371,17 +371,17 @@ LocalisedLogEntries ClientBase::checkWatch( unsigned _watchId ) { return ret; } -BlockHeader ClientBase::blockInfo( h256 _hash ) const { +BlockHeader ClientBase::blockInfo( h256 const& _hash ) const { if ( _hash == PendingBlockHash ) return preSeal().info(); return BlockHeader( bc().block( _hash ) ); } -BlockDetails ClientBase::blockDetails( h256 _hash ) const { +BlockDetails ClientBase::blockDetails( h256 const& _hash ) const { return bc().details( _hash ); } -Transaction ClientBase::transaction( h256 _transactionHash ) const { +Transaction ClientBase::transaction( h256 const& _transactionHash ) const { // allow invalid! auto tl = bc().transactionLocation( _transactionHash ); auto blockTimestamp = blockInfo( numberFromHash( tl.first ) - 1 ).timestamp(); @@ -401,7 +401,7 @@ LocalisedTransaction ClientBase::localisedTransaction( h256 const& _transactionH return localisedTransaction( tl.first, tl.second ); } -Transaction ClientBase::transaction( h256 _blockHash, unsigned _i ) const { +Transaction ClientBase::transaction( h256 const& _blockHash, unsigned _i ) const { auto bl = bc().block( _blockHash ); RLP b( bl ); auto blockTimestamp = blockInfo( numberFromHash( _blockHash ) - 1 ).timestamp(); @@ -506,7 +506,7 @@ pair< h256, unsigned > ClientBase::transactionLocation( h256 const& _transaction return bc().transactionLocation( _transactionHash ); } -Transactions ClientBase::transactions( h256 _blockHash ) const { +Transactions ClientBase::transactions( h256 const& _blockHash ) const { auto bl = bc().block( _blockHash ); RLP b( bl ); Transactions res; @@ -526,12 +526,13 @@ Transactions ClientBase::transactions( h256 _blockHash ) const { return res; } -TransactionHashes ClientBase::transactionHashes( h256 _blockHash ) const { +TransactionHashes ClientBase::transactionHashes( h256 const& _blockHash ) const { return bc().transactionHashes( _blockHash ); } #ifdef BITE -DecryptedTransactionData ClientBase::decryptedTransactionData( h256 _transactionHash ) const { +DecryptedTransactionData ClientBase::decryptedTransactionData( + h256 const& _transactionHash ) const { return bc().decryptedTransactionData( _transactionHash ); } @@ -551,7 +552,7 @@ std::vector< dev::h256 > ClientBase::craftedCTXs( const dev::h256& _transactionH } #endif // BITE -BlockHeader ClientBase::uncle( h256 _blockHash, unsigned _i ) const { +BlockHeader ClientBase::uncle( h256 const& _blockHash, unsigned _i ) const { auto bl = bc().block( _blockHash ); RLP b( bl ); if ( _i < b[2].itemCount() ) @@ -560,17 +561,17 @@ BlockHeader ClientBase::uncle( h256 _blockHash, unsigned _i ) const { return BlockHeader(); } -UncleHashes ClientBase::uncleHashes( h256 _blockHash ) const { +UncleHashes ClientBase::uncleHashes( h256 const& _blockHash ) const { return bc().uncleHashes( _blockHash ); } -unsigned ClientBase::transactionCount( h256 _blockHash ) const { +unsigned ClientBase::transactionCount( h256 const& _blockHash ) const { auto bl = bc().block( _blockHash ); RLP b( bl ); return b[1].itemCount(); } -unsigned ClientBase::uncleCount( h256 _blockHash ) const { +unsigned ClientBase::uncleCount( h256 const& _blockHash ) const { auto bl = bc().block( _blockHash ); RLP b( bl ); return b[2].itemCount(); @@ -615,7 +616,7 @@ h256 ClientBase::hashFromNumber( BlockNumber _number ) const { return bc().numberHash( _number ); } -BlockNumber ClientBase::numberFromHash( h256 _blockHash ) const { +BlockNumber ClientBase::numberFromHash( h256 const& _blockHash ) const { if ( _blockHash == PendingBlockHash ) return bc().number() + 1; else if ( _blockHash == LatestBlockHash ) @@ -625,7 +626,7 @@ BlockNumber ClientBase::numberFromHash( h256 _blockHash ) const { return bc().number( _blockHash ); } -int ClientBase::compareBlockHashes( h256 _h1, h256 _h2 ) const { +int ClientBase::compareBlockHashes( h256 const& _h1, h256 const& _h2 ) const { BlockNumber n1 = numberFromHash( _h1 ); BlockNumber n2 = numberFromHash( _h2 ); @@ -678,26 +679,26 @@ uint64_t ClientBase::chainId() const { } -u256 ClientBase::countAt( Address _a ) const { +u256 ClientBase::countAt( Address const& _a ) const { return getReadOnlyLatestBlockCopy().state().getNonce( _a ); } -u256 ClientBase::balanceAt( Address _a ) const { +u256 ClientBase::balanceAt( Address const& _a ) const { return getReadOnlyLatestBlockCopy().state().balance( _a ); } -u256 ClientBase::stateAt( Address _a, u256 _l ) const { +u256 ClientBase::stateAt( Address const& _a, u256 const& _l ) const { return getReadOnlyLatestBlockCopy().state().storage( _a, _l ); } -bytes ClientBase::codeAt( Address _a ) const { +bytes ClientBase::codeAt( Address const& _a ) const { return getReadOnlyLatestBlockCopy().state().code( _a ); } -h256 ClientBase::codeHashAt( Address _a ) const { +h256 ClientBase::codeHashAt( Address const& _a ) const { return getReadOnlyLatestBlockCopy().state().codeHash( _a ); } -map< h256, pair< u256, u256 > > ClientBase::storageAt( Address _a ) const { +map< h256, pair< u256, u256 > > ClientBase::storageAt( Address const& _a ) const { return getReadOnlyLatestBlockCopy().state().storage( _a ); } diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h index 131456b7b..29bb8f7ac 100644 --- a/libethereum/ClientBase.h +++ b/libethereum/ClientBase.h @@ -97,7 +97,7 @@ class ClientBase : public Interface { unsigned installWatch( LogFilter const& _filter, Reaping _r = Reaping::Automatic, fnClientWatchHandlerMulti_t fnOnNewChanges = fnClientWatchHandlerMulti_t(), bool isWS = false ) override; - unsigned installWatch( h256 _filterId, Reaping _r = Reaping::Automatic, + unsigned installWatch( h256 const& _filterId, Reaping _r = Reaping::Automatic, fnClientWatchHandlerMulti_t fnOnNewChanges = fnClientWatchHandlerMulti_t(), bool isWS = false ) override; bool uninstallWatch( unsigned _watchId ) override; @@ -111,28 +111,28 @@ class ClientBase : public Interface { using Interface::uncleHashes; h256 hashFromNumber( BlockNumber _number ) const override; - BlockNumber numberFromHash( h256 _blockHash ) const override; - int compareBlockHashes( h256 _h1, h256 _h2 ) const override; - BlockHeader blockInfo( h256 _hash ) const override; - BlockDetails blockDetails( h256 _hash ) const override; - Transaction transaction( h256 _transactionHash ) const override; + BlockNumber numberFromHash( h256 const& _blockHash ) const override; + int compareBlockHashes( h256 const& _h1, h256 const& _h2 ) const override; + BlockHeader blockInfo( h256 const& _hash ) const override; + BlockDetails blockDetails( h256 const& _hash ) const override; + Transaction transaction( h256 const& _transactionHash ) const override; LocalisedTransaction localisedTransaction( h256 const& _transactionHash ) const override; - Transaction transaction( h256 _blockHash, unsigned _i ) const override; + Transaction transaction( h256 const& _blockHash, unsigned _i ) const override; LocalisedTransaction localisedTransaction( h256 const& _blockHash, unsigned _i ) const override; TransactionReceipt transactionReceipt( h256 const& _transactionHash ) const override; LocalisedTransactionReceipt localisedTransactionReceipt( h256 const& _transactionHash ) const override; std::pair< h256, unsigned > transactionLocation( h256 const& _transactionHash ) const override; - Transactions transactions( h256 _blockHash ) const override; + Transactions transactions( h256 const& _blockHash ) const override; Transactions transactions( BlockNumber _block ) const override { if ( _block == PendingBlock ) return postSeal().pending(); return transactions( hashFromNumber( _block ) ); } - TransactionHashes transactionHashes( h256 _blockHash ) const override; - BlockHeader uncle( h256 _blockHash, unsigned _i ) const override; - UncleHashes uncleHashes( h256 _blockHash ) const override; - unsigned transactionCount( h256 _blockHash ) const override; + TransactionHashes transactionHashes( h256 const& _blockHash ) const override; + BlockHeader uncle( h256 const& _blockHash, unsigned _i ) const override; + UncleHashes uncleHashes( h256 const& _blockHash ) const override; + unsigned transactionCount( h256 const& _blockHash ) const override; unsigned transactionCount( BlockNumber _block ) const override { if ( _block == PendingBlock ) { auto p = postSeal().pending(); @@ -140,14 +140,14 @@ class ClientBase : public Interface { } return transactionCount( hashFromNumber( _block ) ); } - unsigned uncleCount( h256 _blockHash ) const override; + unsigned uncleCount( h256 const& _blockHash ) const override; unsigned number() const override; h256s pendingHashes() const override; BlockHeader pendingInfo() const override; BlockDetails pendingDetails() const override; #ifdef BITE - DecryptedTransactionData decryptedTransactionData( h256 _transactionHash ) const; + DecryptedTransactionData decryptedTransactionData( const dev::h256& _transactionHash ) const; dev::h256 ctxOrigin( const dev::h256& _ctxHash ) const; std::vector< dev::h256 > craftedCTXs( const dev::h256& _transactionHash ) const; #endif // BITE @@ -189,19 +189,19 @@ class ClientBase : public Interface { uint64_t chainId() const override; - u256 countAt( Address _a ) const override; - u256 balanceAt( Address _a ) const override; - u256 stateAt( Address _a, u256 _l ) const override; - bytes codeAt( Address _a ) const override; - h256 codeHashAt( Address _a ) const override; - std::map< h256, std::pair< u256, u256 > > storageAt( Address _a ) const override; + u256 countAt( Address const& _a ) const override; + u256 balanceAt( Address const& _a ) const override; + u256 stateAt( Address const& _a, u256 const& _l ) const override; + bytes codeAt( Address const& _a ) const override; + h256 codeHashAt( Address const& _a ) const override; + std::map< h256, std::pair< u256, u256 > > storageAt( Address const& _a ) const 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 - std::pair< u256, ExecutionResult > estimateGas( Address const& _from, u256 _value, - Address _dest, bytes const& _data, int64_t _maxGas, u256 _gasPrice, + std::pair< u256, ExecutionResult > estimateGas( Address const& _from, u256 const& _value, + Address const& _dest, bytes const& _data, int64_t _maxGas, u256 const& _gasPrice, GasEstimationCallback const& _callback = GasEstimationCallback() ) override; protected: diff --git a/libethereum/ClientTest.cpp b/libethereum/ClientTest.cpp index 8bfa7d5ec..38ab8ed00 100644 --- a/libethereum/ClientTest.cpp +++ b/libethereum/ClientTest.cpp @@ -112,7 +112,7 @@ h256 ClientTest::importRawBlock( const string& _blockRLP ) { if ( result != ImportResult::Success ) BOOST_THROW_EXCEPTION( ImportBlockFailed() << errinfo_importResult( result ) ); - // TOOD notify some sync component + // TODO notify some sync component bool moreToImport = true; while ( moreToImport ) { diff --git a/libethereum/ConsensusStub.cpp b/libethereum/ConsensusStub.cpp index 052089a30..586a6911a 100644 --- a/libethereum/ConsensusStub.cpp +++ b/libethereum/ConsensusStub.cpp @@ -100,9 +100,6 @@ void ConsensusStub::doWork() { ++it; } - // this_thread::sleep_for( std::chrono::milliseconds( - // static_cast< unsigned int >( rand() ) % ( max_sleep - 1000 ) + 1000 ) ); - try { ++blockCounter; m_extFace.createBlock( out_vector, diff --git a/libethereum/ExtVM.cpp b/libethereum/ExtVM.cpp index f50e1aa0a..f8e85eb8c 100644 --- a/libethereum/ExtVM.cpp +++ b/libethereum/ExtVM.cpp @@ -29,7 +29,6 @@ #include #include "LastBlockHashesFace.h" - #include "SchainPatch.h" using namespace dev; diff --git a/libethereum/Interface.h b/libethereum/Interface.h index af34f5d71..1c765b221 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -116,8 +116,9 @@ class Interface { /// @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, int64_t _maxGas, u256 _gasPrice, + virtual std::pair< u256, ExecutionResult > estimateGas( Address const& _from, + u256 const& _value, Address const& _dest, bytes const& _data, int64_t _maxGas, + u256 const& _gasPrice, GasEstimationCallback const& _callback = GasEstimationCallback() ) = 0; // [STATE-QUERY API] @@ -127,23 +128,23 @@ class Interface { throw std::logic_error( "setDefault is not supported" ); } - virtual u256 balanceAt( Address _a ) const = 0; - virtual u256 countAt( Address _a ) const = 0; - virtual u256 stateAt( Address _a, u256 _l ) const = 0; - virtual bytes codeAt( Address _a ) const = 0; - virtual h256 codeHashAt( Address _a ) const = 0; + virtual u256 balanceAt( Address const& _a ) const = 0; + virtual u256 countAt( Address const& _a ) const = 0; + virtual u256 stateAt( Address const& _a, u256 const& _l ) const = 0; + virtual bytes codeAt( Address const& _a ) const = 0; + virtual h256 codeHashAt( Address const& _a ) const = 0; #ifdef HISTORIC_STATE - virtual u256 historicStateBalanceAt( Address _a, BlockNumber _block ) const = 0; - virtual u256 historicStateCountAt( Address _a, BlockNumber _block ) const = 0; - virtual u256 historicStateAt( Address _a, u256 _l, BlockNumber _block ) const = 0; - virtual h256 historicStateRootAt( Address _a, BlockNumber _block ) const = 0; - virtual bytes historicStateCodeAt( Address _a, BlockNumber _block ) const = 0; + virtual u256 historicStateBalanceAt( Address const& _a, BlockNumber _block ) const = 0; + virtual u256 historicStateCountAt( Address const& _a, BlockNumber _block ) const = 0; + virtual u256 historicStateAt( Address const& _a, u256 const& _l, BlockNumber _block ) const = 0; + virtual h256 historicStateRootAt( Address const& _a, BlockNumber _block ) const = 0; + virtual bytes historicStateCodeAt( Address const& _a, BlockNumber _block ) const = 0; #endif - virtual std::map< h256, std::pair< u256, u256 > > storageAt( Address _a ) const = 0; + virtual std::map< h256, std::pair< u256, u256 > > storageAt( Address const& _a ) const = 0; // [LOGS API] @@ -154,7 +155,7 @@ class Interface { virtual unsigned installWatch( LogFilter const& _filter, Reaping _r = Reaping::Automatic, fnClientWatchHandlerMulti_t fnOnNewChanges = fnClientWatchHandlerMulti_t(), bool isWS = false ) = 0; - virtual unsigned installWatch( h256 _filterId, Reaping _r = Reaping::Automatic, + virtual unsigned installWatch( h256 const& _filterId, Reaping _r = Reaping::Automatic, fnClientWatchHandlerMulti_t fnOnNewChanges = fnClientWatchHandlerMulti_t(), bool isWS = false ) = 0; virtual bool uninstallWatch( unsigned _watchId ) = 0; @@ -171,7 +172,7 @@ class Interface { virtual bool isKnownTransaction( h256 const& _transactionHash ) const = 0; virtual bool isKnownTransaction( h256 const& _blockHash, unsigned _i ) const = 0; - virtual Transaction transaction( h256 _transactionHash ) const = 0; + virtual Transaction transaction( h256 const& _transactionHash ) const = 0; virtual LocalisedTransaction localisedTransaction( h256 const& _transactionHash ) const = 0; virtual TransactionReceipt transactionReceipt( h256 const& _transactionHash ) const = 0; virtual LocalisedTransactionReceipt localisedTransactionReceipt( @@ -179,24 +180,24 @@ class Interface { virtual std::pair< h256, unsigned > transactionLocation( h256 const& _transactionHash ) const = 0; virtual h256 hashFromNumber( BlockNumber _number ) const = 0; - virtual BlockNumber numberFromHash( h256 _blockHash ) const = 0; - virtual int compareBlockHashes( h256 _h1, h256 _h2 ) const = 0; + virtual BlockNumber numberFromHash( h256 const& _blockHash ) const = 0; + virtual int compareBlockHashes( h256 const& _h1, h256 const& _h2 ) const = 0; virtual bool isKnown( BlockNumber _block ) const = 0; virtual bool isKnown( h256 const& _hash ) const = 0; - virtual BlockHeader blockInfo( h256 _hash ) const = 0; - virtual BlockDetails blockDetails( h256 _hash ) const = 0; - virtual Transaction transaction( h256 _blockHash, unsigned _i ) const = 0; + virtual BlockHeader blockInfo( h256 const& _hash ) const = 0; + virtual BlockDetails blockDetails( h256 const& _hash ) const = 0; + virtual Transaction transaction( h256 const& _blockHash, unsigned _i ) const = 0; virtual LocalisedTransaction localisedTransaction( h256 const& _blockHash, unsigned _i ) const = 0; - virtual BlockHeader uncle( h256 _blockHash, unsigned _i ) const = 0; - virtual UncleHashes uncleHashes( h256 _blockHash ) const = 0; - virtual unsigned transactionCount( h256 _blockHash ) const = 0; + virtual BlockHeader uncle( h256 const& _blockHash, unsigned _i ) const = 0; + virtual UncleHashes uncleHashes( h256 const& _blockHash ) const = 0; + virtual unsigned transactionCount( h256 const& _blockHash ) const = 0; virtual unsigned transactionCount( BlockNumber _block ) const = 0; - virtual unsigned uncleCount( h256 _blockHash ) const = 0; - virtual Transactions transactions( h256 _blockHash ) const = 0; + virtual unsigned uncleCount( h256 const& _blockHash ) const = 0; + virtual Transactions transactions( h256 const& _blockHash ) const = 0; virtual Transactions transactions( BlockNumber _block ) const = 0; - virtual TransactionHashes transactionHashes( h256 _blockHash ) const = 0; + virtual TransactionHashes transactionHashes( h256 const& _blockHash ) const = 0; virtual BlockHeader pendingInfo() const { return BlockHeader(); } virtual BlockDetails pendingDetails() const { return BlockDetails(); } @@ -316,7 +317,7 @@ class Watch : public boost::noncopyable { public: Watch() {} - Watch( Interface& _c, h256 _f ) : m_c( &_c ), m_id( _c.installWatch( _f ) ) {} + Watch( Interface& _c, h256 const& _f ) : m_c( &_c ), m_id( _c.installWatch( _f ) ) {} Watch( Interface& _c, LogFilter const& _tf ) : m_c( &_c ), m_id( _c.installWatch( _tf ) ) {} ~Watch() { if ( m_c ) diff --git a/libethereum/SkaleHost.cpp b/libethereum/SkaleHost.cpp index e1c5c73da..e38273633 100644 --- a/libethereum/SkaleHost.cpp +++ b/libethereum/SkaleHost.cpp @@ -320,7 +320,6 @@ SkaleHost::SkaleHost( dev::eth::Client& _client, const ConsensusFactory* _consFa << "TRACEPOINT " << name << " " << m_debugTracer.get_tracepoint_count( name ); } ); - // m_broadcaster.reset( new HttpBroadcaster( _client ) ); m_broadcaster.reset( new ZmqBroadcaster( _client, *this ) ); m_extFace.reset( new ConsensusExtImpl( *this ) ); @@ -912,10 +911,6 @@ void SkaleHost::startWorking() { return; } - // comment out as this hack is in consensus now - // HACK Prevent consensus from hanging up for emptyBlockIntervalMs at bootstrapAll()! - // uint64_t tmp_interval = m_consensus->getEmptyBlockIntervalMs(); - // m_consensus->setEmptyBlockIntervalMs( 50 ); try { static const char g_strThreadName[] = "bootStrapAll"; dev::setThreadName( g_strThreadName ); diff --git a/libethereum/SnapshotAgent.cpp b/libethereum/SnapshotAgent.cpp index f13d3a665..9a1c1e7e7 100644 --- a/libethereum/SnapshotAgent.cpp +++ b/libethereum/SnapshotAgent.cpp @@ -52,7 +52,7 @@ void SnapshotAgent::init( unsigned _currentBlockNumber, int64_t _timestampOfBloc assert( _timestampOfBlock1 > 0 ); // we created snapshot somehow // whether it is local or downloaded - we shall ignore it's hash but use it's time - // see also how last_snapshoted_block_with_hash is updated in importTransactionsAsBlock + // see also how last_snapshotted_block_with_hash is updated in importTransactionsAsBlock // h256 h2 = this->hashFromNumber( latest_snapshots.second ); // uint64_t time_of_second = blockInfo( h2 ).timestamp(); diff --git a/libethereum/db_repair.cpp b/libethereum/db_repair.cpp index 9156588e4..a22f4e7c5 100644 --- a/libethereum/db_repair.cpp +++ b/libethereum/db_repair.cpp @@ -31,10 +31,6 @@ void dump_blocks_and_extras_db( const BlockChain& _bc, size_t _startBlock ) { LogBloom bloom = _bc.blockBloom( bn ); - // block_json["hash"] = "suppressed"; - // block_json["parentHash"] = "suppressed"; - // block_json["stateRoot"] = "suppressed"; - cdebug << "Block " << bn << "\n"; if ( transaction_hashes.size() || header.timestamp() == prev_ts ) { cdebug << block_json << "\n"; diff --git a/libhistoric/AlethExecutive.cpp b/libhistoric/AlethExecutive.cpp index f50826da7..0a258c30e 100644 --- a/libhistoric/AlethExecutive.cpp +++ b/libhistoric/AlethExecutive.cpp @@ -41,30 +41,7 @@ std::string dumpStorage( AlethExtVM const& _ext ) { return o.str(); }; } // namespace -/* -AlethExecutive::AlethExecutive(Block &_s, BlockChain const &_bc, unsigned _level) - : m_s(_s.mutableState().mutableHistoricState()), - m_envInfo(_s.info(), _bc.lastBlockHashes(), 0, _bc.chainID()), - m_depth(_level), - m_sealEngine(*_bc.sealEngine()) { -} - -AlethExecutive::AlethExecutive(Block &_s, LastBlockHashesFace const &_lh, unsigned _level) - : m_s(_s.mutableState().mutableHistoricState()), - m_envInfo(_s.info(), _lh, 0, _s.sealEngine()->chainParams().chainID), - m_depth(_level), - m_sealEngine(*_s.sealEngine()) { -} -AlethExecutive::AlethExecutive( - dev::eth::HistoricState &io_s, Block const &_block, unsigned _txIndex, BlockChain const -&_bc, unsigned _level) : m_s(createIntermediateState(io_s, _block, _txIndex, _bc)), - m_envInfo(_block.info(), _bc.lastBlockHashes(), - _txIndex ? _block.receipt(_txIndex - 1).cumulativeGasUsed() : 0, _bc.chainID()), - m_depth(_level), - m_sealEngine(*_bc.sealEngine()) { -} -*/ u256 AlethExecutive::gasUsed() const { return m_t.gas() - m_gas; } diff --git a/libskale/OverlayDB.cpp b/libskale/OverlayDB.cpp index d4fe076cb..4d95948d6 100644 --- a/libskale/OverlayDB.cpp +++ b/libskale/OverlayDB.cpp @@ -81,14 +81,6 @@ dev::db::Slice toSlice( std::string const& _s ) { OverlayDB::OverlayDB( std::unique_ptr< batched_io::db_face > _db_face ) : m_db_face( _db_face.release(), []( batched_io::db_face* db ) { delete db; } ) {} -// ClassicOverlayDB::ClassicOverlayDB( std::unique_ptr< batched_io::db_face > _db_face ) -// : m_db_face( _db_face.release(), []( batched_io::db_face* db ) { -// // clog(dev::VerbosityDebug, "overlaydb") << "Closing state DB"; -// // std::cerr << "!!! Closing state DB !!!" << std::endl; -// // std::cerr.flush(); -// delete db; -// } ) {} - dev::h256 OverlayDB::getLastExecutedTransactionHash() const { if ( lastExecutedTransactionHash.has_value() ) return lastExecutedTransactionHash.value(); @@ -278,7 +270,6 @@ void OverlayDB::commit() { if ( m_db_face ) { for ( unsigned commitTry = 0; commitTry < 10; ++commitTry ) { -// cnote << "Committing nodes to disk DB:"; #if DEV_GUARDED_DB DEV_READ_GUARDED( x_this ) #endif diff --git a/libweb3jsonrpc/Eth.cpp b/libweb3jsonrpc/Eth.cpp index 8ce8973da..9e92b5aab 100644 --- a/libweb3jsonrpc/Eth.cpp +++ b/libweb3jsonrpc/Eth.cpp @@ -237,12 +237,7 @@ Json::Value Eth::eth_pendingTransactions() { // Return list of transaction that being sent by local accounts Transactions ours; for ( Transaction const& pending : client()->pending() ) { - // for ( Address const& account : m_ethAccounts.allAccounts() ) { - // if ( pending.sender() == account ) { ours.push_back( pending ); - // break; - // } - //} } return toJson( ours ); @@ -856,14 +851,6 @@ string Eth::eth_newFilter( Json::Value const& _json ) { } } -// string Eth::eth_newFilterEx( Json::Value const& _json ) { -// try { -// return toJS( client()->installWatch( toLogFilter( _json ) ) ); -// } catch ( ... ) { -// BOOST_THROW_EXCEPTION( JsonRpcException( Errors::ERROR_RPC_INVALID_PARAMS ) ); -// } -//} - string Eth::eth_newBlockFilter() { h256 filter = dev::eth::ChainChangedFilter; return toJS( client()->installWatch( filter ) ); diff --git a/libweb3jsonrpc/EthFace.h b/libweb3jsonrpc/EthFace.h index 9fbbe1954..9de55306f 100644 --- a/libweb3jsonrpc/EthFace.h +++ b/libweb3jsonrpc/EthFace.h @@ -126,11 +126,6 @@ class EthFace : public ServerInterface< EthFace > { this->bindAndAddMethod( jsonrpc::Procedure( "eth_newFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1", jsonrpc::JSON_OBJECT, NULL ), &dev::rpc::EthFace::eth_newFilterI ); - // this->bindAndAddMethod( jsonrpc::Procedure( "eth_newFilterEx", - // jsonrpc::PARAMS_BY_POSITION, - // jsonrpc::JSON_STRING, "param1", jsonrpc::JSON_OBJECT, - // NULL ), - // &dev::rpc::EthFace::eth_newFilterExI ); this->bindAndAddMethod( jsonrpc::Procedure( "eth_newBlockFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL ), &dev::rpc::EthFace::eth_newBlockFilterI ); @@ -153,18 +148,9 @@ class EthFace : public ServerInterface< EthFace > { jsonrpc::Procedure( "eth_getFilterLogs", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1", jsonrpc::JSON_STRING, NULL ), &dev::rpc::EthFace::eth_getFilterLogsI ); - // this->bindAndAddMethod( - // jsonrpc::Procedure( "eth_getFilterLogsEx", jsonrpc::PARAMS_BY_POSITION, - // jsonrpc::JSON_ARRAY, "param1", jsonrpc::JSON_STRING, NULL ), - // &dev::rpc::EthFace::eth_getFilterLogsExI ); this->bindAndAddMethod( jsonrpc::Procedure( "eth_getLogs", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1", jsonrpc::JSON_OBJECT, NULL ), &dev::rpc::EthFace::eth_getLogsI ); - // this->bindAndAddMethod( jsonrpc::Procedure( "eth_getLogsEx", - // jsonrpc::PARAMS_BY_POSITION, - // jsonrpc::JSON_ARRAY, "param1", jsonrpc::JSON_OBJECT, - // NULL ), - // &dev::rpc::EthFace::eth_getLogsExI ); this->bindAndAddMethod( jsonrpc::Procedure( "eth_getWork", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, NULL ), &dev::rpc::EthFace::eth_getWorkI ); @@ -349,10 +335,6 @@ class EthFace : public ServerInterface< EthFace > { inline virtual void eth_newFilterI( const Json::Value& request, Json::Value& response ) { response = this->eth_newFilter( request[0u] ); } - // inline virtual void eth_newFilterExI( const Json::Value& request, Json::Value& response ) - // { - // response = this->eth_newFilterEx( request[0u] ); - // } inline virtual void eth_newBlockFilterI( const Json::Value& request, Json::Value& response ) { ( void ) request; response = this->eth_newBlockFilter(); @@ -375,17 +357,9 @@ class EthFace : public ServerInterface< EthFace > { inline virtual void eth_getFilterLogsI( const Json::Value& request, Json::Value& response ) { response = this->eth_getFilterLogsAsJson( request[0u].asString() ); } - // inline virtual void eth_getFilterLogsExI( const Json::Value& request, Json::Value& - // response ) { - // response = this->eth_getFilterLogsEx( request[0u].asString() ); - // } inline virtual void eth_getLogsI( const Json::Value& request, Json::Value& response ) { response = this->eth_getLogs( request[0u] ); } - // inline virtual void eth_getLogsExI( const Json::Value& request, Json::Value& response ) { - // response = this->eth_getLogsEx( request[0u] ); - // } - inline virtual void eth_getWorkI( const Json::Value& request, Json::Value& response ) { ( void ) request; response = this->eth_getWork(); @@ -504,16 +478,13 @@ class EthFace : public ServerInterface< EthFace > { virtual Json::Value eth_getUncleByBlockNumberAndIndex( const std::string& param1, const std::string& param2 ) = 0; virtual std::string eth_newFilter( const Json::Value& param1 ) = 0; - // virtual std::string eth_newFilterEx( const Json::Value& param1 ) = 0; virtual std::string eth_newBlockFilter() = 0; virtual std::string eth_newPendingTransactionFilter() = 0; virtual bool eth_uninstallFilter( const std::string& param1 ) = 0; virtual Json::Value eth_getFilterChanges( const std::string& param1 ) = 0; virtual Json::Value eth_getFilterChangesEx( const std::string& param1 ) = 0; - // virtual Json::Value eth_getFilterLogsEx( const std::string& param1 ) = 0; virtual Json::Value eth_getFilterLogsAsJson( std::string const& _filterId ) = 0; virtual Json::Value eth_getLogs( const Json::Value& param1 ) = 0; - // virtual Json::Value eth_getLogsEx( const Json::Value& param1 ) = 0; virtual Json::Value eth_getWork() = 0; virtual bool eth_submitWork( const std::string& param1, const std::string& param2, const std::string& param3 ) = 0; diff --git a/libweb3jsonrpc/JsonHelper.cpp b/libweb3jsonrpc/JsonHelper.cpp index 7dd0b92e4..65ccf3634 100644 --- a/libweb3jsonrpc/JsonHelper.cpp +++ b/libweb3jsonrpc/JsonHelper.cpp @@ -185,7 +185,7 @@ Json::Value toJson( dev::eth::TransactionSkeleton const& _t ) { Json::Value toJson( dev::eth::TransactionReceipt const& _t ) { Json::Value res; if ( _t.hasStatusCode() ) - res["status"] = toString0x< uint8_t >( _t.statusCode() ); // toString( _t.statusCode() ); + res["status"] = toString0x< uint8_t >( _t.statusCode() ); else res["stateRoot"] = toJS( _t.stateRoot() ); res["gasUsed"] = toJS( _t.cumulativeGasUsed() ); @@ -223,7 +223,7 @@ Json::Value toJson( dev::eth::LocalisedTransactionReceipt const& _t ) { res["logs"] = dev::toJson( _t.localisedLogs() ); res["logsBloom"] = toJS( _t.bloom() ); if ( _t.hasStatusCode() ) - res["status"] = toString0x< uint8_t >( _t.statusCode() ); // toString( _t.statusCode() ); + res["status"] = toString0x< uint8_t >( _t.statusCode() ); else res["stateRoot"] = toJS( _t.stateRoot() ); diff --git a/libweb3jsonrpc/Skale.cpp b/libweb3jsonrpc/Skale.cpp index 83e682d28..fc84a9e61 100644 --- a/libweb3jsonrpc/Skale.cpp +++ b/libweb3jsonrpc/Skale.cpp @@ -677,7 +677,7 @@ Json::Value Skale::bite_getCraftedCtxs( const std::string& _transactionHash ) { // skip invalid auto rcp = m_client.localisedTransactionReceipt( h ); if ( rcp.gasUsed() == 0 ) - return std::string(); + return Json::Value( Json::arrayValue ); #endif // HISTORIC_STATE auto craftedCTXs = m_client.craftedCTXs( h ); @@ -872,7 +872,6 @@ bool download( const std::string& strURLWeb3, unsigned& block_number, const fs:: << " " << s; return false; } - // size_t sizeArrived = joFragment["size"]; std::string strBase64orBinary = joFragment["data"]; buffer = skutils::tools::base64::decodeBin( strBase64orBinary ); diff --git a/skaled/main.cpp b/skaled/main.cpp index fec8c0468..65aa94f1c 100644 --- a/skaled/main.cpp +++ b/skaled/main.cpp @@ -1270,7 +1270,6 @@ int main( int argc, char** argv ) { BOOST_LOG( loggerInfo ) << "Using " << std::to_string( nDispatchThreads ) << " threads in task dispatcher"; skutils::dispatch::default_domain( nDispatchThreads ); - // skutils::dispatch::default_domain( 48 ); bool chainConfigIsSet = false, chainConfigParsed = false; static nlohmann::json joConfig; @@ -1772,7 +1771,6 @@ int main( int argc, char** argv ) { if ( vm.count( "sgx-url" ) ) { std::string strURL = vm["sgx-url"].as< string >(); - // chainParams.nodeInfo.sgxServerUrl = strURL; skutils::url u( strURL ); u.user_info( "" ); u.user_name_and_password( "", "", true ); @@ -1929,13 +1927,6 @@ int main( int argc, char** argv ) { auto nodesState = contents( getDataDir() / fs::path( "network.rlp" ) ); auto caps = set< string >{ "eth" }; - // dev::WebThreeDirect web3( WebThreeDirect::composeClientVersion( "skaled" ), - // getDataDir(), - // "", - // chainParams, withExisting, nodeMode == NodeMode::Full ? caps : set< string >(), - // false - // ); - std::shared_ptr< GasPricer > gasPricer; auto rotationFlagDirPath = configPath.parent_path(); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0c10f65ae..7b9c5343d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -11,11 +11,16 @@ endif() set(excludeSuites jsonrpc \"customTestSuite\" BlockQueueSuite) set(allSuites jsonrpc) foreach(file ${sources}) - file(STRINGS ${file} test_list_raw REGEX "BOOST_.*TEST_(SUITE|CASE|SUITE_END)") + file(READ ${file} test_source_raw) + string(REGEX REPLACE "[\r\n]+" " " test_source_flat "${test_source_raw}") + string(REGEX MATCHALL + "BOOST_[A-Z_]*TEST_SUITE[ \t]*\\([ \t]*[A-Za-z_][A-Za-z_0-9]*|BOOST_[A-Z_]*TEST_CASE[ \t]*\\([ \t]*[A-Za-z_][A-Za-z_0-9]*|BOOST_AUTO_TEST_SUITE_END[ \t]*\\(" + test_list_raw + "${test_source_flat}") set(TestSuite "DEFAULT") set(TestSuitePath "") foreach(test_raw ${test_list_raw}) - string(REGEX REPLACE ".*TEST_(SUITE|CASE)\\(( [^ ,\\)]*).*" "\\1 \\2" test ${test_raw}) + string(REGEX REPLACE ".*TEST_(SUITE|CASE)[ \t]*\\([ \t]*([^ ,\\)]*).*" "\\1 \\2" test ${test_raw}) #skip disabled if (";${excludeSuites};" MATCHES ";${TestSuite};") @@ -24,7 +29,7 @@ foreach(file ${sources}) if(test MATCHES "^SUITE .*") - string(SUBSTRING ${test} 6 -1 TestSuite) + string(SUBSTRING "${test}" 6 -1 TestSuite) set(TestSuitePath "${TestSuitePath}/${TestSuite}") if(FASTCTEST) @@ -32,7 +37,11 @@ foreach(file ${sources}) continue() endif() if (NOT ";${allSuites};" MATCHES ";${TestSuite};") - string(SUBSTRING ${TestSuitePath} 1 -1 TestSuitePathFixed) + if(TestSuitePath STREQUAL "") + set(TestSuitePathFixed "") + else() + string(SUBSTRING "${TestSuitePath}" 1 -1 TestSuitePathFixed) + endif() list(APPEND allSuites ${TestSuite}) separate_arguments(TESTETH_ARGS) set(TestEthArgs -t ${TestSuitePathFixed} -- ${TESTETH_ARGS}) @@ -42,17 +51,26 @@ foreach(file ${sources}) elseif(test MATCHES "^CASE .*") if(NOT FASTCTEST) if(NOT test MATCHES "^CASE &createRandom.*") - string(SUBSTRING ${test} 5 -1 TestCase) - string(SUBSTRING ${TestSuitePath} 1 -1 TestSuitePathFixed) + string(SUBSTRING "${test}" 5 -1 TestCase) + if(TestSuitePath STREQUAL "") + set(TestSelector "${TestCase}") + else() + string(SUBSTRING "${TestSuitePath}" 1 -1 TestSuitePathFixed) + set(TestSelector "${TestSuitePathFixed}/${TestCase}") + endif() separate_arguments(TESTETH_ARGS) - set(TestEthArgs -t ${TestSuitePathFixed}/${TestCase} -- ${TESTETH_ARGS}) - add_test(NAME ${TestSuitePathFixed}/${TestCase} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/test COMMAND testeth ${TestEthArgs}) + set(TestEthArgs -t ${TestSelector} -- ${TESTETH_ARGS}) + add_test(NAME ${TestSelector} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/test COMMAND testeth ${TestEthArgs}) endif() endif() elseif (";${test_raw};" MATCHES "BOOST_AUTO_TEST_SUITE_END()") #encountered SUITE_END block. remove one test suite from the suite path. - string(FIND ${TestSuitePath} "/" Position REVERSE) - string(SUBSTRING ${TestSuitePath} 0 ${Position} TestSuitePath) + string(FIND "${TestSuitePath}" "/" Position REVERSE) + if(Position GREATER_EQUAL 0) + string(SUBSTRING "${TestSuitePath}" 0 ${Position} TestSuitePath) + else() + set(TestSuitePath "") + endif() endif() endforeach(test_raw) endforeach(file) diff --git a/test/tools/fuzzTesting/BoostRandomCode.cpp b/test/tools/fuzzTesting/BoostRandomCode.cpp index 595ee45ef..43224e39b 100644 --- a/test/tools/fuzzTesting/BoostRandomCode.cpp +++ b/test/tools/fuzzTesting/BoostRandomCode.cpp @@ -55,13 +55,14 @@ BoostRandomCode::BoostRandomCode() { u256 BoostRandomCode::randomUniInt( u256 const& _minVal, u256 const& _maxVal ) { assert( _minVal <= _maxVal ); - std::uniform_int_distribution< uint64_t > uint64Dist{0, std::numeric_limits< uint64_t >::max()}; + std::uniform_int_distribution< uint64_t > uint64Dist{ 0, + std::numeric_limits< uint64_t >::max() }; u256 value = _minVal + ( u256 ) uint64Dist( gen ) % ( _maxVal - _minVal ); return value; } uint8_t BoostRandomCode::weightedOpcode( std::vector< int > const& _weights ) { - DescreteDistrib opCodeProbability = DescreteDistrib{_weights.begin(), _weights.end()}; + DescreteDistrib opCodeProbability = DescreteDistrib{ _weights.begin(), _weights.end() }; return opCodeProbability( gen ); } } // namespace test diff --git a/test/tools/fuzzTesting/fuzzHelper.cpp b/test/tools/fuzzTesting/fuzzHelper.cpp index 3b1df9682..2207923b6 100644 --- a/test/tools/fuzzTesting/fuzzHelper.cpp +++ b/test/tools/fuzzTesting/fuzzHelper.cpp @@ -31,7 +31,7 @@ using namespace dev; using namespace std; -const static std::array< eth::Instruction, 47 > invalidOpcodes{{eth::Instruction::INVALID, +const static std::array< eth::Instruction, 47 > invalidOpcodes{ { eth::Instruction::INVALID, eth::Instruction::PUSHC, eth::Instruction::JUMPC, eth::Instruction::JUMPCI, eth::Instruction::JUMPTO, eth::Instruction::JUMPIF, eth::Instruction::JUMPSUB, eth::Instruction::JUMPV, eth::Instruction::JUMPSUBV, eth::Instruction::BEGINSUB, @@ -45,7 +45,7 @@ const static std::array< eth::Instruction, 47 > invalidOpcodes{{eth::Instruction eth::Instruction::XROR, eth::Instruction::XPUSH, eth::Instruction::XMLOAD, eth::Instruction::XMSTORE, eth::Instruction::XSLOAD, eth::Instruction::XSSTORE, eth::Instruction::XVTOWIDE, eth::Instruction::XWIDETOV, eth::Instruction::XPUT, - eth::Instruction::XGET, eth::Instruction::XSWIZZLE, eth::Instruction::XSHUFFLE}}; + eth::Instruction::XGET, eth::Instruction::XSWIZZLE, eth::Instruction::XSHUFFLE } }; namespace dev { namespace test { @@ -227,7 +227,7 @@ std::string RandomCodeBase::generate( int _maxOpNumber, RandomCodeOptions const& opcode = makeOpcodeDefined( opcode ); eth::Instruction inst = ( eth::Instruction ) opcode; eth::InstructionInfo info = eth::instructionInfo( inst ); - if ( std::string{info.name}.find( "PUSH" ) != std::string::npos ) { + if ( std::string{ info.name }.find( "PUSH" ) != std::string::npos ) { code += toCompactHex( opcode ); code += fillArguments( inst, _options ); } else { diff --git a/test/tools/jsontests/BlockChainTests.cpp b/test/tools/jsontests/BlockChainTests.cpp index 0ef573128..8d1185cad 100644 --- a/test/tools/jsontests/BlockChainTests.cpp +++ b/test/tools/jsontests/BlockChainTests.cpp @@ -237,7 +237,7 @@ json_spirit::mObject fillBCTest( json_spirit::mObject const& _input ) { size_t importBlockNumber = 0; string chainname = "default"; string chainnetwork = "default"; - std::map< string, ChainBranch* > chainMap = {{chainname, new ChainBranch( genesisBlock )}}; + std::map< string, ChainBranch* > chainMap = { { chainname, new ChainBranch( genesisBlock ) } }; if ( _input.count( "network" ) > 0 ) output["network"] = _input.at( "network" ); @@ -384,8 +384,8 @@ json_spirit::mObject fillBCTest( json_spirit::mObject const& _input ) { #ifdef FAIR unordered_set< Address > owners; owners.insert( testChain.topBlock().blockHeader().author() ); - if ( ImportTest::compareStatesFAIR( - stateExpect, testChain.topBlock().state(), owners, expectStateMap, WhenError::Throw ) ) + if ( ImportTest::compareStatesFAIR( stateExpect, testChain.topBlock().state(), owners, + expectStateMap, WhenError::Throw ) ) cerr << testName << "\n"; #else if ( ImportTest::compareStates( @@ -395,13 +395,13 @@ json_spirit::mObject fillBCTest( json_spirit::mObject const& _input ) { } output["blocks"] = blArray; - output["postState"] = fillJsonWithState(testChain.topBlock().state() ); + output["postState"] = fillJsonWithState( testChain.topBlock().state() ); output["lastblockhash"] = toHexPrefixed( testChain.topBlock().blockHeader().hash( WithSeal ) ); // make all values hex in pre section State prestate = State(); ImportTest::importState( _input.at( "pre" ).get_obj(), prestate ); - output["pre"] = fillJsonWithState(prestate ); + output["pre"] = fillJsonWithState( prestate ); for ( auto iterator = chainMap.begin(); iterator != chainMap.end(); iterator++ ) delete iterator->second; @@ -515,7 +515,8 @@ void testBCTest( json_spirit::mObject const& _o ) { if ( blockFromFields.blockHeader().parentHash() == preHash ) { State const postState = testChain.topBlock().state(); assert( testChain.getInterface().sealEngine() ); - bigint reward = calculateMiningReward( testChain.topBlock().blockHeader().timestamp(), testChain.topBlock().blockHeader().number(), + bigint reward = calculateMiningReward( testChain.topBlock().blockHeader().timestamp(), + testChain.topBlock().blockHeader().number(), uncleNumbers.size() >= 1 ? uncleNumbers[0] : 0, uncleNumbers.size() >= 2 ? uncleNumbers[1] : 0, testChain.getInterface().sealEngine()->chainParams() ); @@ -546,7 +547,7 @@ void testBCTest( json_spirit::mObject const& _o ) { State postState = State(); // Compare post states #ifndef FAIR - postState.setStorageLimit(1000000000); + postState.setStorageLimit( 1000000000 ); #endif BOOST_REQUIRE( ( _o.count( "postState" ) > 0 ) ); ImportTest::importState( _o.at( "postState" ).get_obj(), postState ); @@ -561,8 +562,8 @@ void testBCTest( json_spirit::mObject const& _o ) { #endif } -bigint calculateMiningReward( time_t _committedBlockTimestamp, u256 const& _blNumber, u256 const& _unNumber1, u256 const& _unNumber2, - ChainOperationParams const& _cp ) { +bigint calculateMiningReward( time_t _committedBlockTimestamp, u256 const& _blNumber, + u256 const& _unNumber1, u256 const& _unNumber2, ChainOperationParams const& _cp ) { bigint const baseReward = _cp.blockReward( _committedBlockTimestamp, _blNumber ); bigint reward = baseReward; // INCLUDE_UNCLE = BASE_REWARD / 32 @@ -601,10 +602,9 @@ void overwriteBlockHeaderForTest( header.transactionsRoot(), ho.count( "receiptTrie" ) ? h256( ho["receiptTrie"].get_str() ) : header.receiptsRoot(), ho.count( "bloom" ) ? LogBloom( ho["bloom"].get_str() ) : header.logBloom(), - ho.count( "difficulty" ) ? - toInt( ho["difficulty"] ) : - ho.count( "relDifficulty" ) ? header.difficulty() + toInt( ho["relDifficulty"] ) : - header.difficulty(), + ho.count( "difficulty" ) ? toInt( ho["difficulty"] ) : + ho.count( "relDifficulty" ) ? header.difficulty() + toInt( ho["relDifficulty"] ) : + header.difficulty(), ho.count( "number" ) ? toInt( ho["number"] ) : header.number(), ho.count( "gasLimit" ) ? toInt( ho["gasLimit"] ) : header.gasLimit(), ho.count( "gasUsed" ) ? toInt( ho["gasUsed"] ) : header.gasUsed(), @@ -771,11 +771,10 @@ void overwriteUncleHeaderForTest( mObject& uncleHeaderObj, TestBlock& uncle, uncleHeader.transactionsRoot(), uncleHeader.receiptsRoot(), uncleHeader.logBloom(), overwrite == "difficulty" ? toInt( uncleHeaderObj.at( "difficulty" ) ) : - overwrite == "timestamp" ? + overwrite == "timestamp" ? ( ( const Ethash* ) sealEngine ) - ->calculateDifficulty( - uncleHeader, importedBlocks.at( ( size_t ) uncleHeader.number() - 1 ) - .blockHeader() ) : + ->calculateDifficulty( uncleHeader, + importedBlocks.at( ( size_t ) uncleHeader.number() - 1 ).blockHeader() ) : uncleHeader.difficulty(), overwrite == "number" ? toInt( uncleHeaderObj.at( "number" ) ) : uncleHeader.number(), overwrite == "gasLimit" ? toInt( uncleHeaderObj.at( "gasLimit" ) ) : @@ -850,7 +849,7 @@ mObject writeBlockHeaderToJson( BlockHeader const& _bi ) { } void checkExpectedException( mObject& _blObj, Exception const& _e ) { - string exWhat{_e.what()}; + string exWhat{ _e.what() }; bool isNetException = ( _blObj.count( "expectException" + test::netIdToString( test::TestBlockChain::s_sealEngineNetwork ) ) > 0 ); @@ -1045,10 +1044,10 @@ BOOST_AUTO_TEST_CASE( bcGasPricerTest ) {} BOOST_AUTO_TEST_CASE( bcUncleHeaderValidity ) {} // Commenting this out as we do not support this BOOST_AUTO_TEST_CASE( bcValidBlockTest ) {} -BOOST_AUTO_TEST_CASE( bcWalletTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( bcForgedTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + bcWalletTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + bcForgedTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} BOOST_AUTO_TEST_CASE( bcRandomBlockhashTest ) {} BOOST_AUTO_TEST_SUITE_END() @@ -1066,110 +1065,103 @@ BOOST_AUTO_TEST_SUITE_END() BOOST_FIXTURE_TEST_SUITE( BCGeneralStateTests, bcGeneralTestsFixture ) // Frontier Tests -BOOST_AUTO_TEST_CASE( stCallCodes, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( stCallCodes, *boost::unit_test::precondition( dev::test::run_not_express ) ) { } -BOOST_AUTO_TEST_CASE( stCallCreateCallCodeTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stExample, - *boost::unit_test::precondition( dev::test::run_not_express ) * +BOOST_AUTO_TEST_CASE( + stCallCreateCallCodeTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stExample, *boost::unit_test::precondition( dev::test::run_not_express ) * boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stInitCodeTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stLogTests, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stMemoryTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stPreCompiledContracts, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stPreCompiledContracts2, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stRandom, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stRandom2, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stRecursiveCreate, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stRefundTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stSolidityTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stSpecialTest, - *boost::unit_test::expected_failures( 4 ) * boost::unit_test::disabled() ) {} -BOOST_AUTO_TEST_CASE( stSystemOperationsTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stTransactionTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stTransitionTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stWalletTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stInitCodeTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( stLogTests, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stMemoryTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stPreCompiledContracts, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stPreCompiledContracts2, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( stRandom, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( stRandom2, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stRecursiveCreate, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stRefundTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stSolidityTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stSpecialTest, *boost::unit_test::expected_failures( 4 ) * boost::unit_test::disabled() ) {} +BOOST_AUTO_TEST_CASE( + stSystemOperationsTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stTransactionTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stTransitionTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stWalletTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} // Homestead Tests BOOST_AUTO_TEST_CASE( stCallDelegateCodesCallCodeHomestead, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stCallDelegateCodesHomestead, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stHomesteadSpecific, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stDelegatecallTestHomestead, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stCallDelegateCodesHomestead, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stHomesteadSpecific, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stDelegatecallTestHomestead, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} // EIP150 Tests -BOOST_AUTO_TEST_CASE( stChangedEIP150, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stEIP150singleCodeGasPrices, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stMemExpandingEIP150Calls, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stEIP150Specific, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stChangedEIP150, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stEIP150singleCodeGasPrices, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stMemExpandingEIP150Calls, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stEIP150Specific, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} // EIP158 Tests -BOOST_AUTO_TEST_CASE( stEIP158Specific, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stNonZeroCallsTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stZeroCallsTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stZeroCallsRevert, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stRevertTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stEIP158Specific, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stNonZeroCallsTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stZeroCallsTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stZeroCallsRevert, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stRevertTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} // Metropolis Tests -BOOST_AUTO_TEST_CASE( stStackTests, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stStaticCall, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stReturnDataTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stZeroKnowledge, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stZeroKnowledge2, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stBugs, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stStackTests, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stStaticCall, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stReturnDataTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stZeroKnowledge, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stZeroKnowledge2, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( stBugs, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} // Constantinople Tests -BOOST_AUTO_TEST_CASE( stShift, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( stShift, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} // Stress Tests -BOOST_AUTO_TEST_CASE( stAttackTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stMemoryStressTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stQuadraticComplexityTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stAttackTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stMemoryStressTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stQuadraticComplexityTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} // Bad opcodes test -BOOST_AUTO_TEST_CASE( stBadOpcode, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( stBadOpcode, *boost::unit_test::precondition( dev::test::run_not_express ) ) { } // New Tests -BOOST_AUTO_TEST_CASE( stArgsZeroOneBalance, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stArgsZeroOneBalance, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} BOOST_AUTO_TEST_SUITE_END() diff --git a/test/tools/jsontests/BlockChainTests.h b/test/tools/jsontests/BlockChainTests.h index 0312859b9..870258539 100644 --- a/test/tools/jsontests/BlockChainTests.h +++ b/test/tools/jsontests/BlockChainTests.h @@ -77,8 +77,8 @@ void checkJsonSectionForInvalidBlock( mObject& _blObj ); void checkExpectedException( mObject& _blObj, Exception const& _e ); void checkBlocks( TestBlock const& _blockFromFields, TestBlock const& _blockFromRlp, string const& _testname ); -bigint calculateMiningReward( time_t _committedBlockTimestamp, u256 const& _blNumber, u256 const& _unNumber1, u256 const& _unNumber2, - ChainOperationParams const& _cp ); +bigint calculateMiningReward( time_t _committedBlockTimestamp, u256 const& _blNumber, + u256 const& _unNumber1, u256 const& _unNumber2, ChainOperationParams const& _cp ); json_spirit::mObject fillBCTest( json_spirit::mObject const& _input ); void testBCTest( json_spirit::mObject const& _o ); diff --git a/test/tools/jsontests/StateTests.cpp b/test/tools/jsontests/StateTests.cpp index 85e886413..9ca46cbcd 100644 --- a/test/tools/jsontests/StateTests.cpp +++ b/test/tools/jsontests/StateTests.cpp @@ -78,7 +78,7 @@ json_spirit::mValue StateTestSuite::doTests( inputTest.count( "transaction" ) > 0, testname + " transaction not set!" ); ImportTest importer( inputTest, outputTest ); - Listener::ExecTimeGuard guard{i.first}; + Listener::ExecTimeGuard guard{ i.first }; importer.executeTest( _fillin ); if ( _fillin ) { @@ -162,43 +162,40 @@ class GeneralTestFixture { BOOST_FIXTURE_TEST_SUITE( GeneralStateTests, GeneralTestFixture ) // Frontier Tests -BOOST_AUTO_TEST_CASE( stCallCodes, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( stCallCodes, *boost::unit_test::precondition( dev::test::run_not_express ) ) { } -BOOST_AUTO_TEST_CASE( stCallCreateCallCodeTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stExample, *boost::unit_test::precondition( dev::test::run_not_express ) * +BOOST_AUTO_TEST_CASE( + stCallCreateCallCodeTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stExample, *boost::unit_test::precondition( dev::test::run_not_express ) * boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stInitCodeTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stLogTests, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stMemoryTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stPreCompiledContracts, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stPreCompiledContracts2, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stRandom, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stRandom2, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stRecursiveCreate, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stRefundTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stSolidityTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stSpecialTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stSystemOperationsTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stTransactionTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stTransitionTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stWalletTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stInitCodeTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( stLogTests, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stMemoryTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stPreCompiledContracts, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stPreCompiledContracts2, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( stRandom, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( stRandom2, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stRecursiveCreate, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stRefundTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stSolidityTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stSpecialTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stSystemOperationsTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stTransactionTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stTransitionTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stWalletTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} // Homestead Tests BOOST_AUTO_TEST_CASE( stCallDelegateCodesCallCodeHomestead, @@ -207,72 +204,71 @@ BOOST_AUTO_TEST_CASE( stCallDelegateCodesCallCodeHomestead, BOOST_AUTO_TEST_CASE( stCallDelegateCodesHomestead, *boost::unit_test::precondition( dev::test::run_not_express ) * boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stHomesteadSpecific, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stDelegatecallTestHomestead, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stHomesteadSpecific, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stDelegatecallTestHomestead, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} // EIP150 Tests -BOOST_AUTO_TEST_CASE( stChangedEIP150, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stEIP150singleCodeGasPrices, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stMemExpandingEIP150Calls, *boost::unit_test::precondition( dev::test::run_not_express ) * +BOOST_AUTO_TEST_CASE( + stChangedEIP150, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stEIP150singleCodeGasPrices, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stMemExpandingEIP150Calls, *boost::unit_test::precondition( dev::test::run_not_express ) * boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stEIP150Specific, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stEIP150Specific, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} // EIP158 Tests -BOOST_AUTO_TEST_CASE( stEIP158Specific, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stNonZeroCallsTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stZeroCallsTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stZeroCallsRevert, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stCodeSizeLimit, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stCreateTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stRevertTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stEIP158Specific, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stNonZeroCallsTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stZeroCallsTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stZeroCallsRevert, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stCodeSizeLimit, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stCreateTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stRevertTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} // Metropolis Tests -BOOST_AUTO_TEST_CASE( stStackTests, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stStaticCall, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stReturnDataTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stZeroKnowledge, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stZeroKnowledge2, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stStackTests, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stStaticCall, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stReturnDataTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stZeroKnowledge, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stZeroKnowledge2, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} BOOST_AUTO_TEST_CASE( stCodeCopyTest ) {} -BOOST_AUTO_TEST_CASE( stBugs, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( stBugs, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} // Constantinople Tests -BOOST_AUTO_TEST_CASE( stShift, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( stShift, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} // Stress Tests -BOOST_AUTO_TEST_CASE( stAttackTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stMemoryStressTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stQuadraticComplexityTest, *boost::unit_test::precondition( dev::test::run_not_express ) * +BOOST_AUTO_TEST_CASE( + stAttackTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stMemoryStressTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stQuadraticComplexityTest, *boost::unit_test::precondition( dev::test::run_not_express ) * boost::unit_test::precondition( dev::test::run_not_express ) ) {} // Invalid Opcode Tests -BOOST_AUTO_TEST_CASE( stBadOpcode, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( stBadOpcode, *boost::unit_test::precondition( dev::test::run_not_express ) ) { } // New Tests -BOOST_AUTO_TEST_CASE( stArgsZeroOneBalance, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( stEWASMTests, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stArgsZeroOneBalance, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + stEWASMTests, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} BOOST_AUTO_TEST_SUITE_END() diff --git a/test/tools/jsontests/TransactionTests.cpp b/test/tools/jsontests/TransactionTests.cpp index 5f82c8247..899f28729 100644 --- a/test/tools/jsontests/TransactionTests.cpp +++ b/test/tools/jsontests/TransactionTests.cpp @@ -103,7 +103,8 @@ json_spirit::mObject FillTransactionTest( json_spirit::mObject const& _o ) { "transaction from RLP signature is invalid" ) ); // TODO Remove SealEngine from tests too! - se->verifyTransaction( se->chainParams(), ImportRequirements::Everything, txFromFields, 0, bh, 0 ); + se->verifyTransaction( + se->chainParams(), ImportRequirements::Everything, txFromFields, 0, bh, 0 ); if ( expectSection.count( "sender" ) > 0 ) { string expectSender = toString( expectSection["sender"].get_str() ); BOOST_CHECK_MESSAGE( toString( txFromFields.sender() ) == expectSender, @@ -162,7 +163,8 @@ void TestTransactionTest( json_spirit::mObject const& _o ) { txFromRlp = Transaction( rlp.data(), CheckTransaction::Everything ); bool onExperimentalAndZeroSig = onExperimental && txFromRlp.hasZeroSignature(); // TODO Remove SealEngine from tests too! - se->verifyTransaction( se->chainParams(), ImportRequirements::Everything, txFromRlp, 0, bh, 0 ); + se->verifyTransaction( + se->chainParams(), ImportRequirements::Everything, txFromRlp, 0, bh, 0 ); if ( !( txFromRlp.signature().isValid() || onExperimentalAndZeroSig ) ) BOOST_THROW_EXCEPTION( Exception() << errinfo_comment( testname + diff --git a/test/tools/jsontests/vm.cpp b/test/tools/jsontests/vm.cpp index e9faa7c31..08b2ed29b 100644 --- a/test/tools/jsontests/vm.cpp +++ b/test/tools/jsontests/vm.cpp @@ -50,13 +50,13 @@ CreateResult FakeExtVM::create( u256 _endowment, u256& io_gas, bytesConstRef _init, Instruction, u256, OnOpFunc const& ) { Address address = right160( sha3( rlpList( myAddress, get< 1 >( addresses[myAddress] ) ) ) ); callcreates.emplace_back( _endowment, gasPrice, io_gas, _init.toBytes() ); - return {EVMC_SUCCESS, {}, address}; + return { EVMC_SUCCESS, {}, address }; } CallResult FakeExtVM::call( CallParameters& _p ) { Transaction t( _p.valueTransfer, gasPrice, _p.gas, _p.receiveAddress, _p.data.toVector() ); callcreates.push_back( t ); - return {EVMC_SUCCESS, {}}; // Return empty output. + return { EVMC_SUCCESS, {} }; // Return empty output. } h256 FakeExtVM::blockHash( u256 _number ) { @@ -92,7 +92,8 @@ mObject FakeExtVM::exportEnv() { return ret; } -EnvInfo FakeExtVM::importEnv( mObject const& _o, LastBlockHashesFace const& _lastBlockHashes, time_t _committedBlockTimestamp ) { +EnvInfo FakeExtVM::importEnv( mObject const& _o, LastBlockHashesFace const& _lastBlockHashes, + time_t _committedBlockTimestamp ) { // cant use BOOST_REQUIRE, because this function is used outside boost test (createRandomTest) assert( _o.count( "currentGasLimit" ) > 0 ); assert( _o.count( "currentDifficulty" ) > 0 ); @@ -227,67 +228,68 @@ void FakeExtVM::importCallCreates( mArray const& _callcreates ) { } eth::OnOpFunc FakeExtVM::simpleTrace() const { - return []( uint64_t steps, uint64_t pc, eth::Instruction inst, bigint newMemSize, - bigint gasCost, bigint gas, dev::eth::VMFace const* _vm, - dev::eth::ExtVMFace const* voidExt ) { - FakeExtVM const& ext = *static_cast< FakeExtVM const* >( voidExt ); - auto const& vm = dynamic_cast< LegacyVM const& >( *_vm ); - - std::ostringstream o; - o << "\n STACK\n"; - for ( auto i : vm.stack() ) - o << ( h256 ) i << "\n"; - o << " MEMORY\n" << memDump( vm.memory() ); - o << " STORAGE\n"; - - for ( auto const& i : std::get< 2 >( ext.addresses.find( ext.myAddress )->second ) ) - o << std::showbase << std::hex << i.first << ": " << i.second << "\n"; - - BOOST_LOG( ext.m_loggerTrace ) << o.str(); - BOOST_LOG( ext.m_loggerTrace ) << " | " << std::dec << ext.depth << " | " << ext.myAddress << " | #" - << steps << " | " << std::hex << std::setw( 4 ) << std::setfill( '0' ) - << pc << " : " << instructionInfo( inst ).name << " | " << std::dec - << gas << " | -" << std::dec << gasCost << " | " << newMemSize << "x32" - << " ]"; - - /*creates json stack trace*/ - Object o_step; - - /*add the stack*/ - Array a_stack; - for ( auto i : vm.stack() ) { - a_stack.push_back( i.str() ); - } + return + []( uint64_t steps, uint64_t pc, eth::Instruction inst, bigint newMemSize, bigint gasCost, + bigint gas, dev::eth::VMFace const* _vm, dev::eth::ExtVMFace const* voidExt ) { + FakeExtVM const& ext = *static_cast< FakeExtVM const* >( voidExt ); + auto const& vm = dynamic_cast< LegacyVM const& >( *_vm ); + + std::ostringstream o; + o << "\n STACK\n"; + for ( auto i : vm.stack() ) + o << ( h256 ) i << "\n"; + o << " MEMORY\n" << memDump( vm.memory() ); + o << " STORAGE\n"; + + for ( auto const& i : std::get< 2 >( ext.addresses.find( ext.myAddress )->second ) ) + o << std::showbase << std::hex << i.first << ": " << i.second << "\n"; + + BOOST_LOG( ext.m_loggerTrace ) << o.str(); + BOOST_LOG( ext.m_loggerTrace ) + << " | " << std::dec << ext.depth << " | " << ext.myAddress << " | #" << steps + << " | " << std::hex << std::setw( 4 ) << std::setfill( '0' ) << pc << " : " + << instructionInfo( inst ).name << " | " << std::dec << gas << " | -" << std::dec + << gasCost << " | " << newMemSize << "x32" + << " ]"; + + /*creates json stack trace*/ + Object o_step; + + /*add the stack*/ + Array a_stack; + for ( auto i : vm.stack() ) { + a_stack.push_back( i.str() ); + } - o_step.push_back( Pair( "stack", a_stack ) ); - - /*add the memory*/ - Array a_mem; - for ( auto i : vm.memory() ) - a_mem.push_back( i ); - - o_step.push_back( Pair( "memory", a_mem ) ); - - /*add the storage*/ - Object storage; - for ( auto const& i : std::get< 2 >( ext.addresses.find( ext.myAddress )->second ) ) - storage.push_back( Pair( i.first.str(), i.second.str() ) ); - - /*add all the other details*/ - o_step.push_back( Pair( "storage", storage ) ); - o_step.push_back( Pair( "depth", to_string( ext.depth ) ) ); - o_step.push_back( Pair( "gas", gas.str() ) ); - o_step.push_back( Pair( "address", toString( ext.myAddress ) ) ); - o_step.push_back( Pair( "step", steps ) ); - o_step.push_back( Pair( "pc", pc ) ); - o_step.push_back( Pair( "opcode", instructionInfo( inst ).name ) ); - - /*append the JSON object to the log file*/ - Value v( o_step ); - ofstream os( "./stackTrace.json", ofstream::app ); - os << write_string( v, true ) << ","; - os.close(); - }; + o_step.push_back( Pair( "stack", a_stack ) ); + + /*add the memory*/ + Array a_mem; + for ( auto i : vm.memory() ) + a_mem.push_back( i ); + + o_step.push_back( Pair( "memory", a_mem ) ); + + /*add the storage*/ + Object storage; + for ( auto const& i : std::get< 2 >( ext.addresses.find( ext.myAddress )->second ) ) + storage.push_back( Pair( i.first.str(), i.second.str() ) ); + + /*add all the other details*/ + o_step.push_back( Pair( "storage", storage ) ); + o_step.push_back( Pair( "depth", to_string( ext.depth ) ) ); + o_step.push_back( Pair( "gas", gas.str() ) ); + o_step.push_back( Pair( "address", toString( ext.myAddress ) ) ); + o_step.push_back( Pair( "step", steps ) ); + o_step.push_back( Pair( "pc", pc ) ); + o_step.push_back( Pair( "opcode", instructionInfo( inst ).name ) ); + + /*append the JSON object to the log file*/ + Value v( o_step ); + ofstream os( "./stackTrace.json", ofstream::app ); + os << write_string( v, true ) << ","; + os.close(); + }; } namespace dev { @@ -313,7 +315,8 @@ json_spirit::mValue VmTestSuite::doTests( json_spirit::mValue const& _input, boo BOOST_REQUIRE_MESSAGE( testInput.count( "expect" ) == 0, testname + " expect set!" ); TestLastBlockHashes lastBlockHashes( h256s( 256, h256() ) ); - eth::EnvInfo env = FakeExtVM::importEnv( testInput.at( "env" ).get_obj(), lastBlockHashes, 0 ); + eth::EnvInfo env = + FakeExtVM::importEnv( testInput.at( "env" ).get_obj(), lastBlockHashes, 0 ); FakeExtVM fev( env ); fev.importState( testInput.at( "pre" ).get_obj() ); @@ -336,7 +339,7 @@ json_spirit::mValue VmTestSuite::doTests( json_spirit::mValue const& _input, boo auto vm = eth::VMFactory::create(); auto vmtrace = Options::get().vmtrace ? fev.simpleTrace() : OnOpFunc{}; { - Listener::ExecTimeGuard guard{i.first}; + Listener::ExecTimeGuard guard{ i.first }; auto gas = static_cast< int64_t >( fev.gas ); output = vm->exec( fev.gas, fev, vmtrace ); gas -= static_cast< int64_t >( fev.gas ); @@ -369,11 +372,11 @@ json_spirit::mValue VmTestSuite::doTests( json_spirit::mValue const& _input, boo testInput.count( "expect" ) == 1, testname + " multiple expect set!" ); State postState = State(); #ifndef FAIR - postState.setStorageLimit(1000000000); + postState.setStorageLimit( 1000000000 ); #endif State expectState = State(); #ifndef FAIR - expectState.setStorageLimit(1000000000); + expectState.setStorageLimit( 1000000000 ); #endif AccountMaskMap expectStateMap; ImportTest::importState( mValue( fev.exportState() ).get_obj(), postState ); @@ -401,11 +404,11 @@ json_spirit::mValue VmTestSuite::doTests( json_spirit::mValue const& _input, boo State postState = State(); #ifndef FAIR - postState.setStorageLimit(1000000000); + postState.setStorageLimit( 1000000000 ); #endif State expectState = State(); #ifndef FAIR - expectState.setStorageLimit(1000000000); + expectState.setStorageLimit( 1000000000 ); #endif AccountMaskMap expectStateMap; @@ -467,7 +470,8 @@ json_spirit::mValue VmTestSuite::doTests( json_spirit::mValue const& _input, boo testname + " logs field is not a string." ); // use all patches here ("1") - dev::test::FakeExtVM test( eth::EnvInfo{BlockHeader{}, lastBlockHashes, 1, 0, 0} ); + dev::test::FakeExtVM test( + eth::EnvInfo{ BlockHeader{}, lastBlockHashes, 1, 0, 0 } ); test.importState( testInput.at( "post" ).get_obj() ); test.importCallCreates( testInput.at( "callcreates" ).get_array() ); @@ -477,11 +481,11 @@ json_spirit::mValue VmTestSuite::doTests( json_spirit::mValue const& _input, boo State postState = State(); #ifndef FAIR - postState.setStorageLimit(1000000000); + postState.setStorageLimit( 1000000000 ); #endif State expectState = State(); #ifndef FAIR - expectState.setStorageLimit(1000000000); + expectState.setStorageLimit( 1000000000 ); #endif mObject mPostState = fev.exportState(); ImportTest::importState( mPostState, postState ); @@ -533,21 +537,20 @@ class VmTestFixture { BOOST_FIXTURE_TEST_SUITE( VMTests, VmTestFixture ) BOOST_AUTO_TEST_CASE( vmArithmeticTest ) {} -BOOST_AUTO_TEST_CASE( vmBitwiseLogicOperation, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( vmBlockInfoTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( vmEnvironmentalInfo, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + vmBitwiseLogicOperation, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + vmBlockInfoTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + vmEnvironmentalInfo, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} BOOST_AUTO_TEST_CASE( vmIOandFlowOperations ) {} BOOST_AUTO_TEST_CASE( vmLogTest ) {} -BOOST_AUTO_TEST_CASE( vmPerformance, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + vmPerformance, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} BOOST_AUTO_TEST_CASE( vmPushDupSwapTest ) {} -BOOST_AUTO_TEST_CASE( vmRandomTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( vmSha3Test, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + vmRandomTest, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( vmSha3Test, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} BOOST_AUTO_TEST_CASE( vmSystemOperations ) {} BOOST_AUTO_TEST_CASE( vmTests ) {} diff --git a/test/tools/jsontests/vm.h b/test/tools/jsontests/vm.h index eecadc3e6..25e540190 100644 --- a/test/tools/jsontests/vm.h +++ b/test/tools/jsontests/vm.h @@ -76,8 +76,8 @@ class FakeExtVM : public eth::ExtVMFace { void reset( u256 _myBalance, u256 _myNonce, std::map< u256, u256 > const& _storage ); u256 doPosts(); json_spirit::mObject exportEnv(); - static dev::eth::EnvInfo importEnv( - json_spirit::mObject const& _o, eth::LastBlockHashesFace const& _lastBlockHashes, time_t _committedBlockTimestamp ); + static dev::eth::EnvInfo importEnv( json_spirit::mObject const& _o, + eth::LastBlockHashesFace const& _lastBlockHashes, time_t _committedBlockTimestamp ); json_spirit::mObject exportState(); void importState( json_spirit::mObject const& _object ); json_spirit::mObject exportExec(); @@ -94,7 +94,7 @@ class FakeExtVM : public eth::ExtVMFace { u256 gas; u256 execGas; - mutable Logger m_loggerTrace{createLogger( VerbosityTrace, "EVM" )}; + mutable Logger m_loggerTrace{ createLogger( VerbosityTrace, "EVM" ) }; }; class VmTestSuite : public TestSuite { diff --git a/test/tools/libtesteth/BlockChainHelper.cpp b/test/tools/libtesteth/BlockChainHelper.cpp index 2507080b4..c308e4c5b 100644 --- a/test/tools/libtesteth/BlockChainHelper.cpp +++ b/test/tools/libtesteth/BlockChainHelper.cpp @@ -99,11 +99,12 @@ void TestBlock::initBlockFromJsonHeader( mObject const& _blockHeader, mObject co m_state = std::unique_ptr< State >( new State( 0, m_tempDirState.get()->path(), h256{}, BaseState::Empty, 0 #ifndef FAIR - , 1000000000 + , + 1000000000 #endif - ) ); + ) ); ImportTest::importState( _stateObj, *m_state ); - m_state->createStateCopyAndClearCaches().commit(dev::eth::CommitBehaviour::KeepEmptyAccounts ); + m_state->createStateCopyAndClearCaches().commit( dev::eth::CommitBehaviour::KeepEmptyAccounts ); json_spirit::mObject state = _stateObj; dev::test::replaceCodeInState( state ); @@ -203,7 +204,7 @@ void TestBlock::mine( TestBlockChain const& _bc ) { size_t transactionsOnImport = m_transactionQueue.topTransactions( 100 ).size(); block.sync( blockchain, m_transactionQueue, - gp ); //Invalid transactions could be dropped from queue here + gp ); // Invalid transactions could be dropped from queue here // if (transactionsOnImport > m_transactionQueue.topTransactions(1000).size()) // BOOST_ERROR(TestOutputHelper::get().testName() + " Dropped invalid Transactions before // mining!"); @@ -362,11 +363,12 @@ void TestBlock::verify( TestBlockChain const& _bc ) const { _bc.getInterface().sealEngine()->verify( CheckNothingNew, m_blockHeader, BlockHeader(), &m_bytes ); } catch ( Exception const& _e ) { - u256 const& daoHardfork = _bc.getInterface().sealEngine()->chainParams().getDaoHardforkBlock(); + u256 const& daoHardfork = + _bc.getInterface().sealEngine()->chainParams().getDaoHardforkBlock(); if ( ( m_blockHeader.number() >= daoHardfork && m_blockHeader.number() <= daoHardfork + 9 ) || m_blockHeader.number() == 0 ) { - string exWhat{_e.what()}; + string exWhat{ _e.what() }; string exExpect = "InvalidTransactionsRoot"; BOOST_REQUIRE_MESSAGE( exWhat.find( exExpect ) != string::npos, TestOutputHelper::get().testName() + @@ -465,8 +467,8 @@ void TestBlockChain::reset( TestBlock const& _genesisBlock ) { m_chainParams.reset( new ChainParams( genesisInfo( TestBlockChain::s_sealEngineNetwork ), _genesisBlock.bytes(), _genesisBlock.accountMap() ) ); - m_blockChain.reset( - new BlockChain( m_chainParams, m_tempDirBlockchain.get()->path(), true, WithExisting::Kill ) ); + m_blockChain.reset( new BlockChain( + m_chainParams, m_tempDirBlockchain.get()->path(), true, WithExisting::Kill ) ); if ( !m_blockChain->isKnown( BlockHeader::headerHashFromBlock( _genesisBlock.bytes() ) ) ) { cdebug << "Not known:" << BlockHeader::headerHashFromBlock( _genesisBlock.bytes() ) << BlockHeader( m_chainParams->genesisBlock() ).hash(); @@ -478,8 +480,7 @@ void TestBlockChain::reset( TestBlock const& _genesisBlock ) { } bool TestBlockChain::addBlock( TestBlock const& _block ) { - - SchainPatch::useLatestBlockTimestamp(m_blockChain->info().timestamp()); + SchainPatch::useLatestBlockTimestamp( m_blockChain->info().timestamp() ); while ( true ) { try { @@ -503,7 +504,7 @@ bool TestBlockChain::addBlock( TestBlock const& _block ) { State st( block.state() ); m_lastBlock.setState( st ); - SchainPatch::useLatestBlockTimestamp(m_blockChain->info().timestamp()); + SchainPatch::useLatestBlockTimestamp( m_blockChain->info().timestamp() ); return true; } diff --git a/test/tools/libtesteth/FillJsonFunctions.cpp b/test/tools/libtesteth/FillJsonFunctions.cpp index 142344bc0..3b42f2983 100644 --- a/test/tools/libtesteth/FillJsonFunctions.cpp +++ b/test/tools/libtesteth/FillJsonFunctions.cpp @@ -61,7 +61,9 @@ json_spirit::mObject fillJsonWithStateChange( // Sort the vector by address field skale::ChangeLog changeLog = _changeLog; std::sort( changeLog.begin(), changeLog.end(), - []( const skale::Change& lhs, const skale::Change& rhs ) { return lhs.address < rhs.address; } ); + []( const skale::Change& lhs, const skale::Change& rhs ) { + return lhs.address < rhs.address; + } ); std::ostringstream log; json_spirit::mObject o; diff --git a/test/tools/libtesteth/ImportTest.cpp b/test/tools/libtesteth/ImportTest.cpp index 800f4b29f..510b6e9d4 100644 --- a/test/tools/libtesteth/ImportTest.cpp +++ b/test/tools/libtesteth/ImportTest.cpp @@ -61,8 +61,8 @@ ImportTest::ImportTest( json_spirit::mObject const& _input, json_spirit::mObject m_testInputObject( _input ), m_testOutputObject( _output ) { #ifndef FAIR - m_statePre.setStorageLimit(1000000000); - m_statePost.setStorageLimit(1000000000); + m_statePre.setStorageLimit( 1000000000 ); + m_statePost.setStorageLimit( 1000000000 ); #endif importEnv( _input.at( "env" ).get_obj() ); importTransaction( _input.at( "transaction" ).get_obj() ); @@ -95,7 +95,7 @@ void ImportTest::makeBlockchainTestFromStateTest( set< eth::Network > const& _ne State s = State( 0 ); AccountMaskMap m; - StateAndMap smap{s, m}; + StateAndMap smap{ s, m }; vector< size_t > stateIndexesToPrint; json_spirit::mArray expetSectionArray; @@ -103,14 +103,14 @@ void ImportTest::makeBlockchainTestFromStateTest( set< eth::Network > const& _ne auto trDup = tr; trDup.netId = net; - TrExpectSection search{trDup, smap}; + TrExpectSection search{ trDup, smap }; for ( auto const& exp : m_testInputObject.at( "expect" ).get_array() ) { TrExpectSection* search2 = &search; checkGeneralTestSectionSearch( exp.get_obj(), stateIndexesToPrint, "", search2 ); throw std::logic_error( "Skale state does not support addresses list" ); } // for exp - } // for net + } // for net testObj["expect"] = expetSectionArray; @@ -154,14 +154,14 @@ set< eth::Network > ImportTest::getAllNetworksFromExpectSections( BOOST_REQUIRE( exp.get_obj().count( "network" ) > 0 ); if ( exp.get_obj().at( "network" ).type() == json_spirit::str_type ) requireJsonFields( exp.get_obj(), "expect", - {{"network", jsonVType::str_type}, {"result", jsonVType::obj_type}} ); + { { "network", jsonVType::str_type }, { "result", jsonVType::obj_type } } ); else requireJsonFields( exp.get_obj(), "expect", - {{"network", jsonVType::array_type}, {"result", jsonVType::obj_type}} ); + { { "network", jsonVType::array_type }, { "result", jsonVType::obj_type } } ); } else if ( _testType == testType::StateTest ) requireJsonFields( exp.get_obj(), "expect", - {{"indexes", jsonVType::obj_type}, {"network", jsonVType::array_type}, - {"result", jsonVType::obj_type}} ); + { { "indexes", jsonVType::obj_type }, { "network", jsonVType::array_type }, + { "result", jsonVType::obj_type } } ); ImportTest::parseJsonStrValueIntoSet( exp.get_obj().at( "network" ), allNetworks ); } @@ -207,7 +207,7 @@ bytes ImportTest::executeTest( bool _isFilling ) { // revert changes in m_statePre m_statePre = State( 0 ); #ifndef FAIR - m_statePre.setStorageLimit(1000000000); + m_statePre.setStorageLimit( 1000000000 ); #endif importState( m_testInputObject.at( "pre" ).get_obj(), m_statePre ); } @@ -260,7 +260,8 @@ std::tuple< State, ImportTest::ExecOutput, skale::ChangeLog > ImportTest::execut StandardTrace st; st.setShowMnemonics(); st.setOptions( Options::get().jsontraceOptions ); - out = initialState.execute( _env, se->chainParams(), _tr, Permanence::Committed, st.onOp() ); + out = initialState.execute( + _env, se->chainParams(), _tr, Permanence::Committed, st.onOp() ); cout << st.json(); cout << "{\"stateRoot\": \"Is not supported\"}"; } else @@ -294,9 +295,9 @@ std::tuple< State, ImportTest::ExecOutput, skale::ChangeLog > ImportTest::execut json_spirit::mObject ImportTest::makeAllFieldsHex( json_spirit::mObject const& _input, bool _isHeader ) { - static const set< string > hashes{"bloom", "coinbase", "hash", "mixHash", "parentHash", + static const set< string > hashes{ "bloom", "coinbase", "hash", "mixHash", "parentHash", "receiptTrie", "stateRoot", "transactionsTrie", "uncleHash", "currentCoinbase", - "previousHash", "to", "address", "caller", "origin", "secretKey", "data", "extraData"}; + "previousHash", "to", "address", "caller", "origin", "secretKey", "data", "extraData" }; json_spirit::mObject output = _input; @@ -342,9 +343,10 @@ json_spirit::mObject ImportTest::makeAllFieldsHex( void ImportTest::importEnv( json_spirit::mObject const& _o ) { requireJsonFields( _o, "env", - {{"currentCoinbase", jsonVType::str_type}, {"currentDifficulty", jsonVType::str_type}, - {"currentGasLimit", jsonVType::str_type}, {"currentNumber", jsonVType::str_type}, - {"currentTimestamp", jsonVType::str_type}, {"previousHash", jsonVType::str_type}} ); + { { "currentCoinbase", jsonVType::str_type }, { "currentDifficulty", jsonVType::str_type }, + { "currentGasLimit", jsonVType::str_type }, { "currentNumber", jsonVType::str_type }, + { "currentTimestamp", jsonVType::str_type }, + { "previousHash", jsonVType::str_type } } ); auto gasLimit = toInt( _o.at( "currentGasLimit" ) ); BOOST_REQUIRE( gasLimit <= std::numeric_limits< int64_t >::max() ); BlockHeader header; @@ -371,7 +373,7 @@ void ImportTest::importState( validation::validateAccountMaskObj( accountMaskJson ); } std::string jsondata = json_spirit::write_string( ( json_spirit::mValue ) o, false ); - _state.populateFrom(jsonToAccountMap(jsondata, 0, &o_mask ) ); + _state.populateFrom( jsonToAccountMap( jsondata, 0, &o_mask ) ); } void ImportTest::importState( json_spirit::mObject const& _o, State& _state ) { @@ -379,8 +381,8 @@ void ImportTest::importState( json_spirit::mObject const& _o, State& _state ) { BOOST_REQUIRE_MESSAGE( account.second.type() == jsonVType::obj_type, "State account is required to be json Object!" ); requireJsonFields( account.second.get_obj(), account.first, - {{"balance", jsonVType::str_type}, {"code", jsonVType::str_type}, - {"nonce", jsonVType::str_type}, {"storage", jsonVType::obj_type}} ); + { { "balance", jsonVType::str_type }, { "code", jsonVType::str_type }, + { "nonce", jsonVType::str_type }, { "storage", jsonVType::obj_type } } ); } AccountMaskMap mask; @@ -390,10 +392,10 @@ void ImportTest::importState( json_spirit::mObject const& _o, State& _state ) { void ImportTest::importTransaction( json_spirit::mObject const& _o, eth::Transaction& o_tr ) { if ( _o.count( "secretKey" ) > 0 ) { requireJsonFields( _o, "transaction", - {{"data", jsonVType::str_type}, {"gasLimit", jsonVType::str_type}, - {"gasPrice", jsonVType::str_type}, {"nonce", jsonVType::str_type}, - {"secretKey", jsonVType::str_type}, {"to", jsonVType::str_type}, - {"value", jsonVType::str_type}} ); + { { "data", jsonVType::str_type }, { "gasLimit", jsonVType::str_type }, + { "gasPrice", jsonVType::str_type }, { "nonce", jsonVType::str_type }, + { "secretKey", jsonVType::str_type }, { "to", jsonVType::str_type }, + { "value", jsonVType::str_type } } ); if ( bigint( _o.at( "nonce" ).get_str() ) >= c_max256plus1 ) BOOST_THROW_EXCEPTION( ValueTooLarge() << errinfo_comment( @@ -421,10 +423,11 @@ void ImportTest::importTransaction( json_spirit::mObject const& _o, eth::Transac #endif } else { requireJsonFields( _o, "transaction", - {{"data", jsonVType::str_type}, {"gasLimit", jsonVType::str_type}, - {"gasPrice", jsonVType::str_type}, {"nonce", jsonVType::str_type}, - {"v", jsonVType::str_type}, {"r", jsonVType::str_type}, {"s", jsonVType::str_type}, - {"to", jsonVType::str_type}, {"value", jsonVType::str_type}} ); + { { "data", jsonVType::str_type }, { "gasLimit", jsonVType::str_type }, + { "gasPrice", jsonVType::str_type }, { "nonce", jsonVType::str_type }, + { "v", jsonVType::str_type }, { "r", jsonVType::str_type }, + { "s", jsonVType::str_type }, { "to", jsonVType::str_type }, + { "value", jsonVType::str_type } } ); RLPStream transactionRLPStream = createRLPStreamFromTransactionFields( _o ); RLP transactionRLP( transactionRLPStream.out() ); @@ -454,16 +457,17 @@ void ImportTest::importTransaction( json_spirit::mObject const& _o, eth::Transac void ImportTest::importTransaction( json_spirit::mObject const& o_tr ) { if ( o_tr.count( "secretKey" ) ) requireJsonFields( o_tr, "transaction", - {{"data", jsonVType::array_type}, {"gasLimit", jsonVType::array_type}, - {"gasPrice", jsonVType::str_type}, {"nonce", jsonVType::str_type}, - {"secretKey", jsonVType::str_type}, {"to", jsonVType::str_type}, - {"value", jsonVType::array_type}} ); + { { "data", jsonVType::array_type }, { "gasLimit", jsonVType::array_type }, + { "gasPrice", jsonVType::str_type }, { "nonce", jsonVType::str_type }, + { "secretKey", jsonVType::str_type }, { "to", jsonVType::str_type }, + { "value", jsonVType::array_type } } ); else requireJsonFields( o_tr, "transaction", - {{"data", jsonVType::array_type}, {"gasLimit", jsonVType::array_type}, - {"gasPrice", jsonVType::str_type}, {"nonce", jsonVType::str_type}, - {"v", jsonVType::str_type}, {"r", jsonVType::str_type}, {"s", jsonVType::str_type}, - {"to", jsonVType::str_type}, {"value", jsonVType::array_type}} ); + { { "data", jsonVType::array_type }, { "gasLimit", jsonVType::array_type }, + { "gasPrice", jsonVType::str_type }, { "nonce", jsonVType::str_type }, + { "v", jsonVType::str_type }, { "r", jsonVType::str_type }, + { "s", jsonVType::str_type }, { "to", jsonVType::str_type }, + { "value", jsonVType::array_type } } ); // Parse extended transaction size_t dataVectorSize = o_tr.at( "data" ).get_array().size(); @@ -495,18 +499,18 @@ void ImportTest::importTransaction( json_spirit::mObject const& o_tr ) { #ifdef FAIR int ImportTest::compareStatesFAIR( State const& _stateExpect, State const& _statePost, - unordered_set
const& owners, - AccountMaskMap const _expectedStateOptions, WhenError _throw ) { + unordered_set< Address > const& owners, AccountMaskMap const _expectedStateOptions, + WhenError _throw ) { bool wasError = false; #define CHECK( a, b ) \ { \ - if ( _throw == WhenError::Throw ) { \ - BOOST_CHECK_MESSAGE( a, b ); \ - if ( !a ) \ + if ( _throw == WhenError::Throw ) { \ + BOOST_CHECK_MESSAGE( a, b ); \ + if ( !a ) \ return 1; \ } else { \ - BOOST_WARN_MESSAGE( a, b ); \ - if ( !a ) \ + BOOST_WARN_MESSAGE( a, b ); \ + if ( !a ) \ wasError = true; \ } \ } @@ -539,16 +543,20 @@ int ImportTest::compareStatesFAIR( State const& _stateExpect, State const& _stat // Check only non owner accounts if ( owners.find( accountAddress ) == owners.end() ) { if ( addressOptions.hasBalance() ) - CHECK( ( _stateExpect.balance( accountAddress ) == _statePost.balance( accountAddress ) ), + CHECK( ( _stateExpect.balance( accountAddress ) == + _statePost.balance( accountAddress ) ), TestOutputHelper::get().testName() + " Check State: " - << accountAddress << ": incorrect balance " << _statePost.balance( accountAddress ) - << ", expected " << _stateExpect.balance( accountAddress ) ); + << accountAddress << ": incorrect balance " + << _statePost.balance( accountAddress ) << ", expected " + << _stateExpect.balance( accountAddress ) ); } if ( addressOptions.hasNonce() ) - CHECK( ( _stateExpect.getNonce( accountAddress ) == _statePost.getNonce( accountAddress ) ), + CHECK( ( _stateExpect.getNonce( accountAddress ) == + _statePost.getNonce( accountAddress ) ), TestOutputHelper::get().testName() + " Check State: " - << accountAddress << ": incorrect nonce " << _statePost.getNonce( accountAddress ) - << ", expected " << _stateExpect.getNonce( accountAddress ) ); + << accountAddress << ": incorrect nonce " + << _statePost.getNonce( accountAddress ) << ", expected " + << _stateExpect.getNonce( accountAddress ) ); if ( addressOptions.hasStorage() ) { map< h256, pair< u256, u256 > > stateStorage = _statePost.storage( accountAddress ); @@ -561,10 +569,11 @@ int ImportTest::compareStatesFAIR( State const& _stateExpect, State const& _stat << ", expected [" << toCompactHexPrefixed( s.second.first ) << "] = " << toCompactHexPrefixed( s.second.second ) ); - // Check for unexpected storage values - map< h256, pair< u256, u256 > > expectedStorage = _stateExpect.storage( accountAddress ); + // Check for unexpected storage values + map< h256, pair< u256, u256 > > expectedStorage = + _stateExpect.storage( accountAddress ); for ( auto const& s : _statePost.storage( accountAddress ) ) { - if (s.second.second == 0 && expectedStorage.count( s.first ) == 0 ) { + if ( s.second.second == 0 && expectedStorage.count( s.first ) == 0 ) { // take into account fact that storage() in skaled historically // can return zero values of storage, which could just be omitted // since Ethereum default value for storage is zero anyway @@ -581,7 +590,7 @@ int ImportTest::compareStatesFAIR( State const& _stateExpect, State const& _stat } if ( addressOptions.hasCode() ) - CHECK( ( _stateExpect.code( accountAddress ) == _statePost.code( accountAddress) ), + CHECK( ( _stateExpect.code( accountAddress ) == _statePost.code( accountAddress ) ), TestOutputHelper::get().testName() + " Check State: " << accountAddress << ": incorrect code '" << toHexPrefixed( _statePost.code( accountAddress ) ) << "', expected '" @@ -635,16 +644,20 @@ int ImportTest::compareStates( State const& _stateExpect, State const& _statePos if ( _statePost.addressInUse( accountAddress ) ) { if ( addressOptions.hasBalance() ) - CHECK( ( _stateExpect.balance( accountAddress ) == _statePost.balance( accountAddress ) ), + CHECK( ( _stateExpect.balance( accountAddress ) == + _statePost.balance( accountAddress ) ), TestOutputHelper::get().testName() + " Check State: " - << accountAddress << ": incorrect balance " << _statePost.balance( accountAddress ) - << ", expected " << _stateExpect.balance( accountAddress ) ); + << accountAddress << ": incorrect balance " + << _statePost.balance( accountAddress ) << ", expected " + << _stateExpect.balance( accountAddress ) ); if ( addressOptions.hasNonce() ) - CHECK( ( _stateExpect.getNonce( accountAddress ) == _statePost.getNonce( accountAddress ) ), + CHECK( ( _stateExpect.getNonce( accountAddress ) == + _statePost.getNonce( accountAddress ) ), TestOutputHelper::get().testName() + " Check State: " - << accountAddress << ": incorrect nonce " << _statePost.getNonce( accountAddress ) - << ", expected " << _stateExpect.getNonce( accountAddress ) ); + << accountAddress << ": incorrect nonce " + << _statePost.getNonce( accountAddress ) << ", expected " + << _stateExpect.getNonce( accountAddress ) ); if ( addressOptions.hasStorage() ) { map< h256, pair< u256, u256 > > stateStorage = _statePost.storage( accountAddress ); @@ -658,9 +671,10 @@ int ImportTest::compareStates( State const& _stateExpect, State const& _statePos << "] = " << toCompactHexPrefixed( s.second.second ) ); // Check for unexpected storage values - map< h256, pair< u256, u256 > > expectedStorage = _stateExpect.storage( accountAddress ); + map< h256, pair< u256, u256 > > expectedStorage = + _stateExpect.storage( accountAddress ); for ( auto const& s : _statePost.storage( accountAddress ) ) { - if (s.second.second == 0 && expectedStorage.count( s.first ) == 0 ) { + if ( s.second.second == 0 && expectedStorage.count( s.first ) == 0 ) { // take into account fact that storage() in skaled historically // can return zero values of storage, which could just be omitted // since Ethereum default value for storage is zero anyway @@ -677,7 +691,7 @@ int ImportTest::compareStates( State const& _stateExpect, State const& _statePos } if ( addressOptions.hasCode() ) - CHECK( ( _stateExpect.code( accountAddress ) == _statePost.code( accountAddress) ), + CHECK( ( _stateExpect.code( accountAddress ) == _statePost.code( accountAddress ) ), TestOutputHelper::get().testName() + " Check State: " << accountAddress << ": incorrect code '" << toHexPrefixed( _statePost.code( accountAddress ) ) << "', expected '" @@ -738,13 +752,13 @@ bool ImportTest::checkGeneralTestSectionSearch( json_spirit::mObject const& _exp vector< size_t >& _errorTransactions, string const& _network, TrExpectSection* _search ) const { if ( _expects.count( "result" ) ) { requireJsonFields( _expects, "expect", - {{"indexes", jsonVType::obj_type}, {"network", jsonVType::array_type}, - {"result", jsonVType::obj_type}} ); + { { "indexes", jsonVType::obj_type }, { "network", jsonVType::array_type }, + { "result", jsonVType::obj_type } } ); } else { // Expect section in filled test requireJsonFields( _expects, "expect", - {{"indexes", jsonVType::obj_type}, {"hash", jsonVType::str_type}, - {"logs", jsonVType::str_type}} ); + { { "indexes", jsonVType::obj_type }, { "hash", jsonVType::str_type }, + { "logs", jsonVType::str_type } } ); } vector< int > d; @@ -763,7 +777,7 @@ bool ImportTest::checkGeneralTestSectionSearch( json_spirit::mObject const& _exp if ( !Options::get().singleTestNet.empty() ) { // skip this check if we execute transactions only on another specified network - if ( !network.count( Options::get().singleTestNet ) && !network.count( string{"ALL"} ) ) + if ( !network.count( Options::get().singleTestNet ) && !network.count( string{ "ALL" } ) ) return false; } @@ -820,9 +834,11 @@ bool ImportTest::checkGeneralTestSectionSearch( json_spirit::mObject const& _exp return true; } #ifdef FAIR - int errcode = ImportTest::compareStatesFAIR( expectState, postState, unordered_set< Address >(), stateMap, WhenError::Throw ); + int errcode = ImportTest::compareStatesFAIR( expectState, postState, + unordered_set< Address >(), stateMap, WhenError::Throw ); #else - int errcode = ImportTest::compareStates( expectState, postState, stateMap, WhenError::Throw ); + int errcode = ImportTest::compareStates( + expectState, postState, stateMap, WhenError::Throw ); #endif if ( errcode > 0 ) { cerr << trInfo << "\n"; diff --git a/test/tools/libtesteth/ImportTest.h b/test/tools/libtesteth/ImportTest.h index a2950ba70..71f301c98 100644 --- a/test/tools/libtesteth/ImportTest.h +++ b/test/tools/libtesteth/ImportTest.h @@ -60,7 +60,7 @@ class ImportTest { int exportTest(); #ifdef FAIR static int compareStatesFAIR( skale::State const& _stateExpect, skale::State const& _statePost, - std::unordered_set
const& owners, + std::unordered_set< Address > const& owners, eth::AccountMaskMap const _expectedStateOptions = eth::AccountMaskMap(), WhenError _throw = WhenError::Throw ); #endif @@ -118,7 +118,7 @@ class ImportTest { json_spirit::mObject const& m_testInputObject; json_spirit::mObject& m_testOutputObject; - Logger m_loggerInfo{createLogger( VerbosityInfo, "state" )}; + Logger m_loggerInfo{ createLogger( VerbosityInfo, "state" ) }; }; template < class T > diff --git a/test/tools/libtesteth/Options.cpp b/test/tools/libtesteth/Options.cpp index ba78eb15b..8aed53eee 100644 --- a/test/tools/libtesteth/Options.cpp +++ b/test/tools/libtesteth/Options.cpp @@ -134,7 +134,7 @@ Options::Options( int argc, const char** argv ) { // For some reason boost is confused by -- separator. This extra parser "skips" the --. auto skipDoubleDash = []( const std::string& s ) -> std::pair< std::string, std::string > { if ( s == "--" ) - return {"--", {}}; + return { "--", {} }; return {}; }; @@ -156,7 +156,7 @@ Options::Options( int argc, const char** argv ) { setDatabaseKind( DatabaseKind::LevelDB ); // default to LevelDB in the interest of reduced // test execution time for ( auto i = 0; i < argc; ++i ) { - auto arg = std::string{argv[i]}; + auto arg = std::string{ argv[i] }; auto throwIfNoArgumentFollows = [&i, &argc, &arg]() { if ( i + 1 >= argc ) BOOST_THROW_EXCEPTION( @@ -203,7 +203,7 @@ Options::Options( int argc, const char** argv ) { } else if ( arg == "--jsontrace" ) { throwIfNoArgumentFollows(); jsontrace = true; - auto arg = std::string{argv[++i]}; + auto arg = std::string{ argv[++i] }; Json::Value value; Json::Reader().parse( arg, value ); StandardTrace::DebugOptions op; @@ -229,10 +229,10 @@ Options::Options( int argc, const char** argv ) { else if ( arg == "--singletest" ) { throwIfNoArgumentFollows(); singleTest = true; - auto name1 = std::string{argv[++i]}; + auto name1 = std::string{ argv[++i] }; if ( i + 1 < argc ) // two params { - auto name2 = std::string{argv[++i]}; + auto name2 = std::string{ argv[++i] }; if ( name2[0] == '-' ) // not param, another option { singleTestName = std::move( name1 ); @@ -245,7 +245,7 @@ Options::Options( int argc, const char** argv ) { singleTestName = std::move( name1 ); } else if ( arg == "--singlenet" ) { throwIfNoArgumentFollows(); - singleTestNet = std::string{argv[++i]}; + singleTestNet = std::string{ argv[++i] }; ImportTest::checkAllowedNetwork( singleTestNet ); } else if ( arg == "--fulloutput" ) fulloutput = true; @@ -254,7 +254,7 @@ Options::Options( int argc, const char** argv ) { verbosity = std::max( verbosity, atoi( argv[++i] ) ); } else if ( arg == "--options" ) { throwIfNoArgumentFollows(); - boost::filesystem::path file( std::string{argv[++i]} ); + boost::filesystem::path file( std::string{ argv[++i] } ); if ( boost::filesystem::exists( file ) ) randomCodeOptionsPath = file; else { @@ -267,7 +267,7 @@ Options::Options( int argc, const char** argv ) { } else if ( arg == "-t" ) { throwIfAfterSeparator(); throwIfNoArgumentFollows(); - rCurrentTestSuite = std::string{argv[++i]}; + rCurrentTestSuite = std::string{ argv[++i] }; } else if ( arg == "-d" ) { throwIfNoArgumentFollows(); trDataIndex = atoi( argv[++i] ); @@ -279,7 +279,7 @@ Options::Options( int argc, const char** argv ) { trValueIndex = atoi( argv[++i] ); } else if ( arg == "--testpath" ) { throwIfNoArgumentFollows(); - testpath = std::string{argv[++i]}; + testpath = std::string{ argv[++i] }; } else if ( arg == "--statediff" ) { statediff = true; verbosity = VerbosityTrace; @@ -297,7 +297,7 @@ Options::Options( int argc, const char** argv ) { createRandomTest = true; if ( i + 1 < argc ) // two params { - auto options = std::string{argv[++i]}; + auto options = std::string{ argv[++i] }; if ( options[0] == '-' ) // not param, another option i--; else { diff --git a/test/tools/libtesteth/Stats.cpp b/test/tools/libtesteth/Stats.cpp index 2350415e6..733228cf6 100644 --- a/test/tools/libtesteth/Stats.cpp +++ b/test/tools/libtesteth/Stats.cpp @@ -41,7 +41,7 @@ void Stats::testStarted( std::string const& _name ) { } void Stats::testFinished( int64_t _gasUsed ) { - m_stats.push_back( {clock::now() - m_tp, _gasUsed, m_currentSuite + "/" + m_currentTest} ); + m_stats.push_back( { clock::now() - m_tp, _gasUsed, m_currentSuite + "/" + m_currentTest } ); } std::ostream& operator<<( std::ostream& out, Stats::clock::duration const& d ) { @@ -81,7 +81,7 @@ Stats::~Stats() { out << "\n"; } else if ( !Options::get().statsOutFile.empty() ) { // Output stats to file - std::ofstream file{Options::get().statsOutFile}; + std::ofstream file{ Options::get().statsOutFile }; for ( auto&& s : m_stats ) { auto usecs = std::chrono::duration_cast< std::chrono::microseconds >( s.duration ).count(); diff --git a/test/tools/libtesteth/TestHelper.cpp b/test/tools/libtesteth/TestHelper.cpp index f710a287c..8731452aa 100644 --- a/test/tools/libtesteth/TestHelper.cpp +++ b/test/tools/libtesteth/TestHelper.cpp @@ -114,7 +114,7 @@ void mine( BlockHeader& _bi, SealEngineFace* _sealer, bool _verify ) { _sealer->verify( JustSeal, _bi ); } -void simulateMining( Client& client, size_t numBlocks, const dev::Address &address ) { +void simulateMining( Client& client, size_t numBlocks, dev::Address const& address ) { const auto balanceBefore = client.balanceAt( address ); State state = client.state(); u256 reward = 0; @@ -123,15 +123,15 @@ void simulateMining( Client& client, size_t numBlocks, const dev::Address &addre } state.addBalance( address, reward ); state.commit(); - state.getOriginalDb()->createBlockSnap(1); + state.getOriginalDb()->createBlockSnap( 1 ); const auto balanceAfter = client.balanceAt( address ); - balanceAfter > balanceBefore; // make compiler happy + balanceAfter > balanceBefore; // make compiler happy assert( balanceAfter > balanceBefore ); } -void simulateMining( Client& client, size_t numBlocks, const bool waitForConsensusRotation ) { +void simulateMining( Client& client, size_t numBlocks, const bool waitForConsensusRotation ) { const dev::Address address = client.author(); - shared_ptr skaleHost = client.skaleHost(); + shared_ptr< SkaleHost > skaleHost = client.skaleHost(); simulateMining( client, numBlocks, address ); } @@ -176,13 +176,13 @@ string netIdToString( eth::Network _netId ) { eth::Network stringToNetId( string const& _netname ) { // Networks that used in .json tests - static vector< eth::Network > const networks{ - {eth::Network::FrontierTest, eth::Network::HomesteadTest, eth::Network::EIP150Test, - eth::Network::EIP158Test, eth::Network::ByzantiumTest, eth::Network::ConstantinopleTest, - eth::Network::ConstantinopleFixTest, eth::Network::IstanbulTest, - eth::Network::FrontierToHomesteadAt5, eth::Network::HomesteadToDaoAt5, - eth::Network::HomesteadToEIP150At5, eth::Network::EIP158ToByzantiumAt5, - eth::Network::ByzantiumToConstantinopleFixAt5, eth::Network::TransitionnetTest}}; + static vector< eth::Network > const networks{ { eth::Network::FrontierTest, + eth::Network::HomesteadTest, eth::Network::EIP150Test, eth::Network::EIP158Test, + eth::Network::ByzantiumTest, eth::Network::ConstantinopleTest, + eth::Network::ConstantinopleFixTest, eth::Network::IstanbulTest, + eth::Network::FrontierToHomesteadAt5, eth::Network::HomesteadToDaoAt5, + eth::Network::HomesteadToEIP150At5, eth::Network::EIP158ToByzantiumAt5, + eth::Network::ByzantiumToConstantinopleFixAt5, eth::Network::TransitionnetTest } }; for ( auto const& net : networks ) if ( netIdToString( net ) == _netname ) @@ -213,10 +213,10 @@ bool isDisabledNetwork( eth::Network _net ) { set< eth::Network > const& getNetworks() { // Networks for the test case execution when filling the tests - static set< eth::Network > const networks{ - {eth::Network::FrontierTest, eth::Network::HomesteadTest, eth::Network::EIP150Test, - eth::Network::EIP158Test, eth::Network::ByzantiumTest, eth::Network::ConstantinopleTest, - eth::Network::ConstantinopleFixTest, eth::Network::IstanbulTest}}; + static set< eth::Network > const networks{ { eth::Network::FrontierTest, + eth::Network::HomesteadTest, eth::Network::EIP150Test, eth::Network::EIP158Test, + eth::Network::ByzantiumTest, eth::Network::ConstantinopleTest, + eth::Network::ConstantinopleFixTest, eth::Network::IstanbulTest } }; return networks; } @@ -315,7 +315,7 @@ u256 toInt( json_spirit::mValue const& _v ) { return 0; } -int64_t toPositiveInt64( const json_spirit::mValue& _v ) { +int64_t toPositiveInt64( json_spirit::mValue const& _v ) { int64_t n = 0; switch ( _v.type() ) { case json_spirit::str_type: @@ -329,7 +329,7 @@ int64_t toPositiveInt64( const json_spirit::mValue& _v ) { } if ( n < 0 ) - throw std::out_of_range{"unexpected negative value: " + std::to_string( n )}; + throw std::out_of_range{ "unexpected negative value: " + std::to_string( n ) }; return n; } @@ -393,9 +393,9 @@ string replaceCode( string const& _code ) { } void replaceCodeInState( json_spirit::mObject& _o ) { - json_spirit::mObject& fieldsObj = _o.count( "alloc" ) ? - _o["alloc"].get_obj() : - _o.count( "accounts" ) ? _o["accounts"].get_obj() : _o; + json_spirit::mObject& fieldsObj = _o.count( "alloc" ) ? _o["alloc"].get_obj() : + _o.count( "accounts" ) ? _o["accounts"].get_obj() : + _o; for ( auto& account : fieldsObj ) { auto obj = account.second.get_obj(); if ( obj.count( "code" ) && obj["code"].type() == json_spirit::str_type ) @@ -600,7 +600,7 @@ void requireJsonFields( json_spirit::mObject const& _o, string const& _section, } string prepareVersionString() { - return string{"testeth "} + skale_get_buildinfo()->project_version; + return string{ "testeth " } + skale_get_buildinfo()->project_version; } // A simple C++ implementation of the Levenshtein distance algorithm to measure the amount of @@ -738,7 +738,6 @@ void Listener::notifySuiteStarted( string const& _name ) { } void Listener::notifyTestStarted( string const& _name ) { - if ( g_listener ) g_listener->testStarted( _name ); } diff --git a/test/tools/libtesteth/TestHelper.h b/test/tools/libtesteth/TestHelper.h index f2bbbfe70..723643565 100644 --- a/test/tools/libtesteth/TestHelper.h +++ b/test/tools/libtesteth/TestHelper.h @@ -66,8 +66,9 @@ void mine( Client& c, int numBlocks ); * @brief simulateMining gives money to miner but do not create block. Use it only for testing * instead of mine( Client& c, int numBlocks ) */ -void simulateMining( Client& client, size_t numBlocks, const dev::Address &address ); -void simulateMining( Client& client, size_t numBlocks, [[ maybe_unused ]] const bool handleConsensusUpdate = false ); +void simulateMining( Client& client, size_t numBlocks, dev::Address const& address ); +void simulateMining( + Client& client, size_t numBlocks, [[maybe_unused]] const bool handleConsensusUpdate = false ); void mineMoney( Client& c, int numBlocks ); void mineTransaction( Client& c, int numBlocks ); void connectClients( Client& c1, Client& c2 ); @@ -84,7 +85,8 @@ typedef json_spirit::Value_type jsonVType; class ZeroGasPricer : public eth::GasPricer { protected: u256 ask( eth::Block const& ) const override { return 0; } - u256 bid( unsigned = dev::eth::LatestBlock, eth::TransactionPriority = eth::TransactionPriority::Medium ) const override { + u256 bid( unsigned = dev::eth::LatestBlock, + eth::TransactionPriority = eth::TransactionPriority::Medium ) const override { return 0; } }; @@ -108,7 +110,7 @@ u256 toInt( json_spirit::mValue const& _v ); /// Parses a JSON value as an 64-bit signed integer. /// Throws std::out_of_range exception in case the value is too big or negative. -int64_t toPositiveInt64( const json_spirit::mValue& _v ); +int64_t toPositiveInt64( json_spirit::mValue const& _v ); _byte_ toByte( json_spirit::mValue const& _v ); bytes processDataOrCode( json_spirit::mObject const& _o, std::string const& nodeName ); diff --git a/test/tools/libtesteth/TestOutputHelper.cpp b/test/tools/libtesteth/TestOutputHelper.cpp index 745896c64..f2e0fed72 100644 --- a/test/tools/libtesteth/TestOutputHelper.cpp +++ b/test/tools/libtesteth/TestOutputHelper.cpp @@ -20,9 +20,9 @@ * Fixture class for boost output when running testeth */ -#include #include #include +#include #include #include @@ -108,5 +108,5 @@ TestOutputHelperFixture::TestOutputHelperFixture() { TestOutputHelperFixture::~TestOutputHelperFixture() { TestOutputHelper::get().finishTest(); // XXX used in Personal test. do it more nicely! - unsetenv("DATA_DIR"); + unsetenv( "DATA_DIR" ); } diff --git a/test/tools/libtesteth/TestSuite.cpp b/test/tools/libtesteth/TestSuite.cpp index d581bf1a8..015b75967 100644 --- a/test/tools/libtesteth/TestSuite.cpp +++ b/test/tools/libtesteth/TestSuite.cpp @@ -143,7 +143,7 @@ void TestSuite::runAllTestsInFolder( string const& _testFolder ) const { string() : test::Options::get().singleTestName; vector< fs::path > const compiledFiles = - test::getFiles( getFullPath( _testFolder ), {".json", ".yml"}, filter ); + test::getFiles( getFullPath( _testFolder ), { ".json", ".yml" }, filter ); for ( auto const& file : compiledFiles ) { fs::path const expectedFillerName = getFullPathFiller( _testFolder ) / @@ -177,36 +177,38 @@ void TestSuite::runAllTestsInFolder( string const& _testFolder ) const { // run all tests vector< fs::path > files = test::getFiles( getFullPathFiller( _testFolder ), - {".json", ".yml"}, filter.empty() ? filter : filter + "Filler" ); + { ".json", ".yml" }, filter.empty() ? filter : filter + "Filler" ); // Use FAIR_ test state file if FAIR_ is available - std:: string commonPrefix = "FAIR_"; + std::string commonPrefix = "FAIR_"; if ( filter.empty() ) { - std::unordered_map> filesByPrefix; - for (auto const& file : files) { + std::unordered_map< std::string, std::vector< fs::path > > filesByPrefix; + for ( auto const& file : files ) { std::string fileName = file.stem().string(); std::string prefix; - if ( fileName.size() > commonPrefix.size() && fileName.substr( 0, commonPrefix.size() ) == commonPrefix ) { + if ( fileName.size() > commonPrefix.size() && + fileName.substr( 0, commonPrefix.size() ) == commonPrefix ) { prefix = fileName.substr( commonPrefix.size() ); } else { prefix = fileName; } - filesByPrefix[prefix].push_back(file); + filesByPrefix[prefix].push_back( file ); } - std::vector filteredFiles; - for (auto const& entry : filesByPrefix) { - if (entry.second.size() == 1) { - filteredFiles.push_back(entry.second[0]); + std::vector< fs::path > filteredFiles; + for ( auto const& entry : filesByPrefix ) { + if ( entry.second.size() == 1 ) { + filteredFiles.push_back( entry.second[0] ); } else { // We have multiple files with the same prefix bool hasFair = false; fs::path fairFile; fs::path nonFairFile; - for (auto const& file : entry.second) { + for ( auto const& file : entry.second ) { std::string fileName = file.stem().string(); - if ( fileName.size() > commonPrefix.size() && fileName.substr( 0, commonPrefix.size() ) == commonPrefix ) { + if ( fileName.size() > commonPrefix.size() && + fileName.substr( 0, commonPrefix.size() ) == commonPrefix ) { hasFair = true; fairFile = file; } else { @@ -214,16 +216,16 @@ void TestSuite::runAllTestsInFolder( string const& _testFolder ) const { } } - if (hasFair) { - #ifdef FAIR - filteredFiles.push_back(fairFile); - #else - filteredFiles.push_back(nonFairFile); - #endif + if ( hasFair ) { +#ifdef FAIR + filteredFiles.push_back( fairFile ); +#else + filteredFiles.push_back( nonFairFile ); +#endif } else { // If no fair/non-fair distinction, add all files - for (auto const& file : entry.second) { - filteredFiles.push_back(file); + for ( auto const& file : entry.second ) { + filteredFiles.push_back( file ); } } } diff --git a/test/tools/libtesteth/TestUtils.cpp b/test/tools/libtesteth/TestUtils.cpp index 09bdb3a34..5ff74ccd4 100644 --- a/test/tools/libtesteth/TestUtils.cpp +++ b/test/tools/libtesteth/TestUtils.cpp @@ -92,7 +92,7 @@ void ClientBaseFixture::enumerateClients( cerr << "void ClientBaseFixture::enumerateClients. FixedClient now accepts block not sate!" << endl; _state.commit( dev::eth::CommitBehaviour::KeepEmptyAccounts ); // unused variable. remove - // this line + // this line eth::Block b( Block::Null ); b.noteChain( _bc ); FixedClient client( _bc, b ); diff --git a/test/tools/libtesteth/boostTest.cpp b/test/tools/libtesteth/boostTest.cpp index 4dcf7a5b6..4b35969f9 100644 --- a/test/tools/libtesteth/boostTest.cpp +++ b/test/tools/libtesteth/boostTest.cpp @@ -43,9 +43,9 @@ #include #include #include +#include #include #include -#include using namespace boost::unit_test; @@ -92,8 +92,7 @@ class FailureSummaryObserver : public test_observer { std::cout << " Failed/errored/aborted test cases (" << run.entries.size() << "):" << std::endl; for ( auto const& entry : run.entries ) { - std::cout << " - " << entry.name << " [" << statusToString( entry.status ) - << "]"; + std::cout << " - " << entry.name << " [" << statusToString( entry.status ) << "]"; if ( !entry.details.empty() ) std::cout << ": " << entry.details; std::cout << std::endl; @@ -109,7 +108,8 @@ class FailureSummaryObserver : public test_observer { }; static Status classify( boost::unit_test::test_results const& results ) { - if ( results.aborted() || results.p_test_cases_aborted > 0 || results.p_test_cases_timed_out > 0 ) + if ( results.aborted() || results.p_test_cases_aborted > 0 || + results.p_test_cases_timed_out > 0 ) return Status::Aborted; if ( results.p_assertions_failed > 0 ) return Status::Failed; @@ -155,7 +155,8 @@ class FailureSummaryObserver : public test_observer { }; void storeAndPrintCurrentRun() { - RunSummary summary{mRunLabel.empty() ? std::string( "default-run" ) : mRunLabel, mEntries}; + RunSummary summary{ mRunLabel.empty() ? std::string( "default-run" ) : mRunLabel, + mEntries }; printSummary( summary ); sRunSummaries.push_back( std::move( summary ) ); mEntries.clear(); @@ -168,7 +169,8 @@ class FailureSummaryObserver : public test_observer { return; } - std::cout << "Failed/errored/aborted test cases (" << summary.entries.size() << "):" << std::endl; + std::cout << "Failed/errored/aborted test cases (" << summary.entries.size() + << "):" << std::endl; for ( auto const& entry : summary.entries ) { std::cout << " - " << entry.name << " [" << statusToString( entry.status ) << "]"; if ( !entry.details.empty() ) @@ -181,7 +183,8 @@ class FailureSummaryObserver : public test_observer { static std::vector< RunSummary > sRunSummaries; }; -std::unique_ptr< FailureSummaryObserver > gFailureSummaryObserver = std::make_unique< FailureSummaryObserver >(); +std::unique_ptr< FailureSummaryObserver > gFailureSummaryObserver = + std::make_unique< FailureSummaryObserver >(); std::vector< FailureSummaryObserver::RunSummary > FailureSummaryObserver::sRunSummaries; } // namespace @@ -280,7 +283,7 @@ void setCLocale() { // Custom Boost Unit Test Main int main( int argc, const char* argv[] ) { MicroProfileSetEnableAllGroups( true ); - UnsafeRegion::init("."); + UnsafeRegion::init( "." ); std::string const dynamicTestSuiteName = "customTestSuite"; setCLocale(); @@ -294,7 +297,8 @@ int main( int argc, const char* argv[] ) { } dev::test::Options const& opt = dev::test::Options::get(); - std::string runLabel = opt.rCurrentTestSuite.empty() ? std::string( "full-workflow" ) : opt.rCurrentTestSuite; + std::string runLabel = + opt.rCurrentTestSuite.empty() ? std::string( "full-workflow" ) : opt.rCurrentTestSuite; if ( opt.singleTestFile.is_initialized() ) runLabel += ":" + opt.singleTestFile.get(); gFailureSummaryObserver->setRunLabel( runLabel ); @@ -303,7 +307,7 @@ int main( int argc, const char* argv[] ) { bool testSuiteFound = false; for ( int i = 0; i < argc; i++ ) { // replace test suite to custom tests - std::string arg = std::string{argv[i]}; + std::string arg = std::string{ argv[i] }; if ( arg == "-t" && i + 1 < argc ) { testSuiteFound = true; argv[i + 1] = ( char* ) dynamicTestSuiteName.c_str(); @@ -342,7 +346,7 @@ int main( int argc, const char* argv[] ) { std::cout << "Running tests using path: " << test::getTestPath() << std::endl; int result = 0; - auto fakeInit = []( int, char* [] ) -> boost::unit_test::test_suite* { return nullptr; }; + auto fakeInit = []( int, char*[] ) -> boost::unit_test::test_suite* { return nullptr; }; if ( opt.jsontrace || opt.vmtrace || opt.statediff ) { // Do not use travis '.' output thread if debug is defined result = unit_test_main( fakeInit, argc, const_cast< char** >( argv ) ); @@ -354,7 +358,7 @@ int main( int argc, const char* argv[] ) { return result; } else { // Initialize travis '.' output thread for log activity - std::atomic_bool stopTravisOut{false}; + std::atomic_bool stopTravisOut{ false }; std::thread outputThread( travisOut, &stopTravisOut ); result = unit_test_main( fakeInit, argc, const_cast< char** >( argv ) ); stopTravisOut = true; diff --git a/test/tools/libtestutils/BlockChainLoader.cpp b/test/tools/libtestutils/BlockChainLoader.cpp index 0be8f974f..934749fb1 100644 --- a/test/tools/libtestutils/BlockChainLoader.cpp +++ b/test/tools/libtestutils/BlockChainLoader.cpp @@ -38,7 +38,7 @@ BlockChainLoader::BlockChainLoader( Json::Value const& _json, eth::Network _seal Json::FastWriter a; m_chainParams.reset( new ChainParams( genesisInfo( _sealEngineNetwork ), genesisBlock, - jsonToAccountMap( a.write( _json["pre"] ) ) ) ); + jsonToAccountMap( a.write( _json["pre"] ) ) ) ); m_bc.reset( new BlockChain( m_chainParams, m_dir.path(), false, WithExisting::Kill ) ); // load pre state diff --git a/test/tools/libtestutils/Common.cpp b/test/tools/libtestutils/Common.cpp index f9420bd88..238c5be7f 100644 --- a/test/tools/libtestutils/Common.cpp +++ b/test/tools/libtestutils/Common.cpp @@ -92,6 +92,7 @@ boost::unit_test::assertion_result dev::test::run_not_express( boost::unit_test: ( !!dev::test::Options::get().all ) || ( !dev::test::Options::get().express ) ); } -boost::unit_test::assertion_result dev::test::manuallyRunningTest( boost::unit_test::test_unit_id ) { +boost::unit_test::assertion_result dev::test::manuallyRunningTest( + boost::unit_test::test_unit_id ) { return boost::unit_test::assertion_result( dev::test::Options::get().manual ); } diff --git a/test/tools/libtestutils/FixedClient.h b/test/tools/libtestutils/FixedClient.h index a5e02c24c..1fb5797be 100644 --- a/test/tools/libtestutils/FixedClient.h +++ b/test/tools/libtestutils/FixedClient.h @@ -69,11 +69,12 @@ class FixedClient : public dev::eth::ClientBase { h256 submitTransaction( eth::TransactionSkeleton const&, Secret const& ) override { return {}; }; - h256 importTransaction( eth::Transaction const&, dev::eth::TransactionBroadcast ) override { return {}; } - eth::ExecutionResult call( - Address const&, u256, Address, bytes const&, u256, u256, + h256 importTransaction( eth::Transaction const&, dev::eth::TransactionBroadcast ) override { + return {}; + } + eth::ExecutionResult call( Address const&, u256, Address, bytes const&, u256, u256, #ifdef HISTORIC_STATE - BlockNumber, + BlockNumber, #endif bool, eth::FudgeFactor ) override { return {}; @@ -84,16 +85,11 @@ class FixedClient : public dev::eth::ClientBase { }; #ifdef HISTORIC_STATE - u256 historicStateBalanceAt(Address, BlockNumber) const override - {return 0;} - u256 historicStateCountAt(Address, BlockNumber) const override - {return 0;} - u256 historicStateAt(Address, u256, BlockNumber) const override - {return 0;} - h256 historicStateRootAt(Address, BlockNumber) const override - {return h256();} - bytes historicStateCodeAt(Address, BlockNumber) const override - {return bytes();}; + u256 historicStateBalanceAt( Address const&, BlockNumber ) const override { return 0; } + u256 historicStateCountAt( Address const&, BlockNumber ) const override { return 0; } + u256 historicStateAt( Address const&, u256 const&, BlockNumber ) const override { return 0; } + h256 historicStateRootAt( Address const&, BlockNumber ) const override { return h256(); } + bytes historicStateCodeAt( Address const&, BlockNumber ) const override { return bytes(); }; #endif private: @@ -103,6 +99,5 @@ class FixedClient : public dev::eth::ClientBase { }; - } // namespace test } // namespace dev diff --git a/test/unittests/external-dependencies/boost.cpp b/test/unittests/external-dependencies/boost.cpp index 39d1fbc00..af1f78e13 100644 --- a/test/unittests/external-dependencies/boost.cpp +++ b/test/unittests/external-dependencies/boost.cpp @@ -31,7 +31,8 @@ using namespace boost::multiprecision; BOOST_FIXTURE_TEST_SUITE( boostTests, TestOutputHelperFixture ) // test that reproduces issue https://github.com/ethereum/cpp-ethereum/issues/1977 -BOOST_AUTO_TEST_CASE( u256_overflow_test, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + u256_overflow_test, *boost::unit_test::precondition( dev::test::run_not_express ) ) { dev::u256 a = 14; dev::bigint b = dev::bigint( "115792089237316195423570985008687907853269984665640564039457584007913129639948" ); @@ -39,13 +40,14 @@ BOOST_AUTO_TEST_CASE( u256_overflow_test, *boost::unit_test::precondition( dev:: BOOST_CHECK( a < b ); } -BOOST_AUTO_TEST_CASE( u256_shift_left, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + u256_shift_left, *boost::unit_test::precondition( dev::test::run_not_express ) ) { u256 a = 1; uint64_t amount = 1; auto b = a << amount; BOOST_CHECK_EQUAL( b, 2 ); - auto high_bit = u256{0}; + auto high_bit = u256{ 0 }; bit_set( high_bit, 255 ); BOOST_CHECK_EQUAL( a << 255, high_bit ); BOOST_CHECK_EQUAL( a << uint64_t( 256 ), 0 ); @@ -60,13 +62,15 @@ BOOST_AUTO_TEST_CASE( u256_shift_left, *boost::unit_test::precondition( dev::tes BOOST_CHECK_EQUAL( static_cast< u256 >( bigint( u256( 3 ) ) << 255 ), u256( 1 ) << 255 ); } -BOOST_AUTO_TEST_CASE( u256_shift_left_bug, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + u256_shift_left_bug, *boost::unit_test::precondition( dev::test::run_not_express ) ) { // Bug reported: https://github.com/boostorg/multiprecision/issues/31 using uint256 = number< cpp_int_backend< 256, 256, unsigned_magnitude, unchecked, void > >; BOOST_CHECK_EQUAL( uint256( 3 ) << 255, uint256( 1 ) << 255 ); } -BOOST_AUTO_TEST_CASE( u256_logical_shift_right, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + u256_logical_shift_right, *boost::unit_test::precondition( dev::test::run_not_express ) ) { u256 a = 1; uint64_t amount = 1; auto b = a >> amount; @@ -109,7 +113,8 @@ BOOST_AUTO_TEST_CASE( u256_logical_shift_right, *boost::unit_test::precondition( constexpr auto int64_min = std::numeric_limits< int64_t >::min(); static_assert( int64_min >> 1 == int64_min / 2, "I cannot shift!" ); -BOOST_AUTO_TEST_CASE( u256_arithmetic_shift_right, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + u256_arithmetic_shift_right, *boost::unit_test::precondition( dev::test::run_not_express ) ) { s256 a = 1; uint64_t amount = 1; auto b = a >> amount; diff --git a/test/unittests/libdevcore/CommonJS.cpp b/test/unittests/libdevcore/CommonJS.cpp index 4896d9b76..7a8ecf5bf 100644 --- a/test/unittests/libdevcore/CommonJS.cpp +++ b/test/unittests/libdevcore/CommonJS.cpp @@ -36,7 +36,7 @@ BOOST_AUTO_TEST_CASE( test_toJS, *boost::unit_test::precondition( dev::test::run h64 a( "0xbaadf00ddeadbeef" ); u64 b( "0xffff0000bbbaaaa" ); uint64_t c = 38990234243; - bytes d = {0xff, 0x0, 0xef, 0xbc}; + bytes d = { 0xff, 0x0, 0xef, 0xbc }; BOOST_CHECK( toJS( a ) == "0xbaadf00ddeadbeef" ); BOOST_CHECK( toJS( b ) == "0xffff0000bbbaaaa" ); @@ -44,9 +44,10 @@ BOOST_AUTO_TEST_CASE( test_toJS, *boost::unit_test::precondition( dev::test::run BOOST_CHECK( toJS( d ) == "0xff00efbc" ); } -BOOST_AUTO_TEST_CASE( test_jsToBytes, *boost::unit_test::precondition( dev::test::run_not_express ) ) { - bytes a = {0xff, 0xaa, 0xbb, 0xcc}; - bytes b = {0x03, 0x89, 0x90, 0x23, 0x42, 0x43}; +BOOST_AUTO_TEST_CASE( + test_jsToBytes, *boost::unit_test::precondition( dev::test::run_not_express ) ) { + bytes a = { 0xff, 0xaa, 0xbb, 0xcc }; + bytes b = { 0x03, 0x89, 0x90, 0x23, 0x42, 0x43 }; BOOST_CHECK( a == jsToBytes( "0xffaabbcc" ) ); BOOST_CHECK( b == jsToBytes( "38990234243" ) ); BOOST_CHECK( bytes() == jsToBytes( "" ) ); @@ -54,42 +55,46 @@ BOOST_AUTO_TEST_CASE( test_jsToBytes, *boost::unit_test::precondition( dev::test } BOOST_AUTO_TEST_CASE( test_padded, *boost::unit_test::precondition( dev::test::run_not_express ) ) { - bytes a = {0xff, 0xaa}; - BOOST_CHECK( bytes( {0x00, 0x00, 0xff, 0xaa} ) == padded( a, 4 ) ); + bytes a = { 0xff, 0xaa }; + BOOST_CHECK( bytes( { 0x00, 0x00, 0xff, 0xaa } ) == padded( a, 4 ) ); bytes b = {}; - BOOST_CHECK( bytes( {0x00, 0x00, 0x00, 0x00} ) == padded( b, 4 ) ); - bytes c = {0xff, 0xaa, 0xbb, 0xcc}; - BOOST_CHECK( bytes{0xcc} == padded( c, 1 ) ); + BOOST_CHECK( bytes( { 0x00, 0x00, 0x00, 0x00 } ) == padded( b, 4 ) ); + bytes c = { 0xff, 0xaa, 0xbb, 0xcc }; + BOOST_CHECK( bytes{ 0xcc } == padded( c, 1 ) ); } -BOOST_AUTO_TEST_CASE( test_paddedRight, *boost::unit_test::precondition( dev::test::run_not_express ) ) { - bytes a = {0xff, 0xaa}; - BOOST_CHECK( bytes( {0xff, 0xaa, 0x00, 0x00} ) == paddedRight( a, 4 ) ); +BOOST_AUTO_TEST_CASE( + test_paddedRight, *boost::unit_test::precondition( dev::test::run_not_express ) ) { + bytes a = { 0xff, 0xaa }; + BOOST_CHECK( bytes( { 0xff, 0xaa, 0x00, 0x00 } ) == paddedRight( a, 4 ) ); bytes b = {}; - BOOST_CHECK( bytes( {0x00, 0x00, 0x00, 0x00} ) == paddedRight( b, 4 ) ); - bytes c = {0xff, 0xaa, 0xbb, 0xcc}; - BOOST_CHECK( bytes{0xff} == paddedRight( c, 1 ) ); + BOOST_CHECK( bytes( { 0x00, 0x00, 0x00, 0x00 } ) == paddedRight( b, 4 ) ); + bytes c = { 0xff, 0xaa, 0xbb, 0xcc }; + BOOST_CHECK( bytes{ 0xff } == paddedRight( c, 1 ) ); } -BOOST_AUTO_TEST_CASE( test_unpadded, *boost::unit_test::precondition( dev::test::run_not_express ) ) { - bytes a = {0xff, 0xaa, 0x00, 0x00, 0x00}; - BOOST_CHECK( bytes( {0xff, 0xaa} ) == unpadded( a ) ); - bytes b = {0x00, 0x00}; +BOOST_AUTO_TEST_CASE( + test_unpadded, *boost::unit_test::precondition( dev::test::run_not_express ) ) { + bytes a = { 0xff, 0xaa, 0x00, 0x00, 0x00 }; + BOOST_CHECK( bytes( { 0xff, 0xaa } ) == unpadded( a ) ); + bytes b = { 0x00, 0x00 }; BOOST_CHECK( bytes() == unpadded( b ) ); bytes c = {}; BOOST_CHECK( bytes() == unpadded( c ) ); } -BOOST_AUTO_TEST_CASE( test_unpaddedLeft, *boost::unit_test::precondition( dev::test::run_not_express ) ) { - bytes a = {0x00, 0x00, 0x00, 0xff, 0xaa}; - BOOST_CHECK( bytes( {0xff, 0xaa} ) == unpadLeft( a ) ); - bytes b = {0x00, 0x00}; +BOOST_AUTO_TEST_CASE( + test_unpaddedLeft, *boost::unit_test::precondition( dev::test::run_not_express ) ) { + bytes a = { 0x00, 0x00, 0x00, 0xff, 0xaa }; + BOOST_CHECK( bytes( { 0xff, 0xaa } ) == unpadLeft( a ) ); + bytes b = { 0x00, 0x00 }; BOOST_CHECK( bytes() == unpadLeft( b ) ); bytes c = {}; BOOST_CHECK( bytes() == unpadLeft( c ) ); } -BOOST_AUTO_TEST_CASE( test_fromRaw, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + test_fromRaw, *boost::unit_test::precondition( dev::test::run_not_express ) ) { // non ascii characters means empty string h256 a( "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ); BOOST_CHECK( "" == fromRaw( a ) ); @@ -99,7 +104,8 @@ BOOST_AUTO_TEST_CASE( test_fromRaw, *boost::unit_test::precondition( dev::test:: BOOST_CHECK( "AsciiCharacters" == fromRaw( c ) ); } -BOOST_AUTO_TEST_CASE( test_jsToFixed, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + test_jsToFixed, *boost::unit_test::precondition( dev::test::run_not_express ) ) { h256 a( "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ); BOOST_CHECK( a == jsToFixed< 32 >( "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ) ); @@ -108,7 +114,8 @@ BOOST_AUTO_TEST_CASE( test_jsToFixed, *boost::unit_test::precondition( dev::test BOOST_CHECK_THROW( jsToFixed< 32 >( "NotAHexadecimalOrDecimal" ), std::invalid_argument ); } -BOOST_AUTO_TEST_CASE( test_jsToInt, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + test_jsToInt, *boost::unit_test::precondition( dev::test::run_not_express ) ) { BOOST_CHECK( 43832124 == jsToInt( "43832124" ) ); BOOST_CHECK( 1342356623 == jsToInt( "0x5002bc8f" ) ); BOOST_CHECK( 3483942 == jsToInt( "015224446" ) ); @@ -122,7 +129,8 @@ BOOST_AUTO_TEST_CASE( test_jsToInt, *boost::unit_test::precondition( dev::test:: BOOST_CHECK_THROW( jsToInt< 16 >( "NotAHexadecimalOrDecimal" ), std::invalid_argument ); } -BOOST_AUTO_TEST_CASE( test_jsToU256, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + test_jsToU256, *boost::unit_test::precondition( dev::test::run_not_express ) ) { BOOST_CHECK( u256( "983298932490823474234" ) == jsToU256( "983298932490823474234" ) ); BOOST_CHECK_THROW( jsToU256( "NotAHexadecimalOrDecimal" ), std::invalid_argument ); } diff --git a/test/unittests/libdevcore/FixedHash.cpp b/test/unittests/libdevcore/FixedHash.cpp index 1bec7bbc7..b43ffdf9f 100644 --- a/test/unittests/libdevcore/FixedHash.cpp +++ b/test/unittests/libdevcore/FixedHash.cpp @@ -34,8 +34,8 @@ namespace test { BOOST_FIXTURE_TEST_SUITE( FixedHashTests, TestOutputHelperFixture ) -BOOST_AUTO_TEST_CASE( FixedHashComparisons, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + FixedHashComparisons, *boost::unit_test::precondition( dev::test::run_not_express ) ) { FixedHash< 4 > h1( sha3( "abcd" ) ); FixedHash< 4 > h2( sha3( "abcd" ) ); FixedHash< 4 > h3( sha3( "aadd" ) ); @@ -52,8 +52,8 @@ BOOST_AUTO_TEST_CASE( FixedHashComparisons, BOOST_CHECK( h6 >= h4 ); } -BOOST_AUTO_TEST_CASE( FixedHashXOR, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + FixedHashXOR, *boost::unit_test::precondition( dev::test::run_not_express ) ) { FixedHash< 2 > h1( "0xAAAA" ); FixedHash< 2 > h2( "0xBBBB" ); @@ -62,8 +62,7 @@ BOOST_AUTO_TEST_CASE( FixedHashXOR, BOOST_CHECK( h1 == FixedHash< 2 >( "0x1111" ) ); } -BOOST_AUTO_TEST_CASE( FixedHashOR, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( FixedHashOR, *boost::unit_test::precondition( dev::test::run_not_express ) ) { FixedHash< 4 > h1( "0xD3ADB33F" ); FixedHash< 4 > h2( "0xBAADF00D" ); FixedHash< 4 > res( "0xFBADF33F" ); @@ -73,8 +72,8 @@ BOOST_AUTO_TEST_CASE( FixedHashOR, BOOST_CHECK( h1 == res ); } -BOOST_AUTO_TEST_CASE( FixedHashAND, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + FixedHashAND, *boost::unit_test::precondition( dev::test::run_not_express ) ) { FixedHash< 4 > h1( "0xD3ADB33F" ); FixedHash< 4 > h2( "0xBAADF00D" ); FixedHash< 4 > h3( "0x92aDB00D" ); @@ -84,16 +83,16 @@ BOOST_AUTO_TEST_CASE( FixedHashAND, BOOST_CHECK( h1 = h3 ); } -BOOST_AUTO_TEST_CASE( FixedHashInvert, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + FixedHashInvert, *boost::unit_test::precondition( dev::test::run_not_express ) ) { FixedHash< 4 > h1( "0xD3ADB33F" ); FixedHash< 4 > h2( "0x2C524CC0" ); BOOST_CHECK( ~h1 == h2 ); } -BOOST_AUTO_TEST_CASE( FixedHashContains, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + FixedHashContains, *boost::unit_test::precondition( dev::test::run_not_express ) ) { FixedHash< 4 > h1( "0xD3ADB331" ); FixedHash< 4 > h2( "0x0000B331" ); FixedHash< 4 > h3( "0x0000000C" ); @@ -126,8 +125,8 @@ void incrementSingleIteration( unsigned seed ) { BOOST_CHECK_EQUAL( next, reverse2 ); } -BOOST_AUTO_TEST_CASE( FixedHashIncrement, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + FixedHashIncrement, *boost::unit_test::precondition( dev::test::run_not_express ) ) { incrementSingleIteration( 0 ); incrementSingleIteration( 1 ); incrementSingleIteration( 0xBAD ); diff --git a/test/unittests/libdevcore/RangeMask.cpp b/test/unittests/libdevcore/RangeMask.cpp index 13540eb55..8c5fcf344 100644 --- a/test/unittests/libdevcore/RangeMask.cpp +++ b/test/unittests/libdevcore/RangeMask.cpp @@ -34,11 +34,10 @@ namespace test { BOOST_FIXTURE_TEST_SUITE( RangeMaskTest, TestOutputHelperFixture ) -BOOST_AUTO_TEST_CASE( constructor, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( constructor, *boost::unit_test::precondition( dev::test::run_not_express ) ) { using RM = RangeMask; using Range = pair< unsigned, unsigned >; - for ( RM r : {RM(), RM( 1, 10 ), RM( Range( 2, 10 ) )} ) { + for ( RM r : { RM(), RM( 1, 10 ), RM( Range( 2, 10 ) ) } ) { BOOST_CHECK( r.empty() ); BOOST_CHECK( !r.contains( 0 ) ); BOOST_CHECK( !r.contains( 1 ) ); @@ -49,8 +48,8 @@ BOOST_AUTO_TEST_CASE( constructor, BOOST_CHECK( !RM( Range( 2, 10 ) ).full() ); } -BOOST_AUTO_TEST_CASE( simple_unions, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + simple_unions, *boost::unit_test::precondition( dev::test::run_not_express ) ) { using RM = RangeMask; using Range = pair< unsigned, unsigned >; RM m( Range( 0, 2000 ) ); @@ -70,8 +69,7 @@ BOOST_AUTO_TEST_CASE( simple_unions, BOOST_CHECK( !m.contains( 258 ) ); } -BOOST_AUTO_TEST_CASE( empty_union, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( empty_union, *boost::unit_test::precondition( dev::test::run_not_express ) ) { using RM = RangeMask; using Range = pair< unsigned, unsigned >; RM m( Range( 0, 2000 ) ); @@ -89,8 +87,8 @@ BOOST_AUTO_TEST_CASE( empty_union, BOOST_CHECK_EQUAL( m.size(), 3 ); } -BOOST_AUTO_TEST_CASE( overlapping_unions, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + overlapping_unions, *boost::unit_test::precondition( dev::test::run_not_express ) ) { using RM = RangeMask; using Range = pair< unsigned, unsigned >; RM m( Range( 0, 2000 ) ); @@ -112,8 +110,7 @@ BOOST_AUTO_TEST_CASE( overlapping_unions, BOOST_CHECK_EQUAL( 70 - 5, m.size() ); } -BOOST_AUTO_TEST_CASE( complement, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( complement, *boost::unit_test::precondition( dev::test::run_not_express ) ) { using RM = RangeMask; using Range = pair< unsigned, unsigned >; RM m( Range( 0, 2000 ) ); @@ -129,8 +126,7 @@ BOOST_AUTO_TEST_CASE( complement, BOOST_CHECK_EQUAL( m.size(), 1000 - 10 ); } -BOOST_AUTO_TEST_CASE( iterator, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( iterator, *boost::unit_test::precondition( dev::test::run_not_express ) ) { using RM = RangeMask; using Range = pair< unsigned, unsigned >; RM m( Range( 0, 2000 ) ); @@ -140,7 +136,7 @@ BOOST_AUTO_TEST_CASE( iterator, vector< unsigned > elements; copy( m.begin(), m.end(), back_inserter( elements ) ); - BOOST_CHECK( elements == ( vector< unsigned >{7, 8, 11, 200, 201, 202, 203, 204} ) ); + BOOST_CHECK( elements == ( vector< unsigned >{ 7, 8, 11, 200, 201, 202, 203, 204 } ) ); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/unittests/libdevcore/StatusAndControlTest.cpp b/test/unittests/libdevcore/StatusAndControlTest.cpp index fc6374fde..1bff360ca 100644 --- a/test/unittests/libdevcore/StatusAndControlTest.cpp +++ b/test/unittests/libdevcore/StatusAndControlTest.cpp @@ -19,23 +19,23 @@ class StatusAndControlTestFixture : public TestOutputHelperFixture { std::string statusFileName = "skaled.status"; StatusAndControlTestFixture() { - fs::create_directory(statusFolderPath); + fs::create_directory( statusFolderPath ); - statusFilePath = statusFolderPath/"skaled.status"; + statusFilePath = statusFolderPath / "skaled.status"; } fs::path statusFilePath; ~StatusAndControlTestFixture() override { return; - if (fs::exists(statusFilePath)) { - fs::remove(statusFilePath); + if ( fs::exists( statusFilePath ) ) { + fs::remove( statusFilePath ); } - if (fs::exists(statusFolderPath/"skaled.status")) { - fs::remove(statusFolderPath/"skaled.status"); + if ( fs::exists( statusFolderPath / "skaled.status" ) ) { + fs::remove( statusFolderPath / "skaled.status" ); } - if (fs::exists(statusFolderPath)) { - fs::remove(statusFolderPath); + if ( fs::exists( statusFolderPath ) ) { + fs::remove( statusFolderPath ); } }; }; @@ -44,43 +44,43 @@ BOOST_FIXTURE_TEST_SUITE( StatusAndControlSuite, StatusAndControlTestFixture ) nlohmann::json::object_t readJson( const fs::path& path ) { - std::ifstream File(path); + std::ifstream File( path ); std::stringstream Buffer; Buffer << File.rdbuf(); File.close(); - return nlohmann::json::parse(Buffer.str()); + return nlohmann::json::parse( Buffer.str() ); } -BOOST_AUTO_TEST_CASE(test_status_file_creation) { - auto Status = std::make_shared(statusFolderPath, statusFileName); +BOOST_AUTO_TEST_CASE( test_status_file_creation ) { + auto Status = std::make_shared< StatusAndControlFile >( statusFolderPath, statusFileName ); // Set and verify exit states - Status->setExitState(StatusAndControl::ExitState::ClearDataDir, true); - Status->setExitState(StatusAndControl::ExitState::StartAgain, true); - Status->setExitState(StatusAndControl::ExitState::StartFromSnapshot, true); - Status->setExitState(StatusAndControl::ExitState::ExitTimeReached, true); + Status->setExitState( StatusAndControl::ExitState::ClearDataDir, true ); + Status->setExitState( StatusAndControl::ExitState::StartAgain, true ); + Status->setExitState( StatusAndControl::ExitState::StartFromSnapshot, true ); + Status->setExitState( StatusAndControl::ExitState::ExitTimeReached, true ); // Set and verify subsystem running states - Status->setSubsystemRunning(StatusAndControl::Subsystem::SnapshotDownloader, true); - Status->setSubsystemRunning(StatusAndControl::Subsystem::WaitingForTimestamp, true); - Status->setSubsystemRunning(StatusAndControl::Subsystem::Blockchain, true); - Status->setSubsystemRunning(StatusAndControl::Subsystem::Rpc, true); + Status->setSubsystemRunning( StatusAndControl::Subsystem::SnapshotDownloader, true ); + Status->setSubsystemRunning( StatusAndControl::Subsystem::WaitingForTimestamp, true ); + Status->setSubsystemRunning( StatusAndControl::Subsystem::Blockchain, true ); + Status->setSubsystemRunning( StatusAndControl::Subsystem::Rpc, true ); // Verify all fields in JSON - auto StatusJson = readJson(statusFilePath); + auto StatusJson = readJson( statusFilePath ); // Verify subsystemRunning - BOOST_REQUIRE(StatusJson["subsystemRunning"]["SnapshotDownloader"] == true); - BOOST_REQUIRE(StatusJson["subsystemRunning"]["WaitingForTimestamp"] == true); - BOOST_REQUIRE(StatusJson["subsystemRunning"]["Blockchain"] == true); - BOOST_REQUIRE(StatusJson["subsystemRunning"]["Rpc"] == true); + BOOST_REQUIRE( StatusJson["subsystemRunning"]["SnapshotDownloader"] == true ); + BOOST_REQUIRE( StatusJson["subsystemRunning"]["WaitingForTimestamp"] == true ); + BOOST_REQUIRE( StatusJson["subsystemRunning"]["Blockchain"] == true ); + BOOST_REQUIRE( StatusJson["subsystemRunning"]["Rpc"] == true ); // Verify exitState - BOOST_REQUIRE(StatusJson["exitState"]["ClearDataDir"] == true); - BOOST_REQUIRE(StatusJson["exitState"]["StartAgain"] == true); - BOOST_REQUIRE(StatusJson["exitState"]["StartFromSnapshot"] == true); - BOOST_REQUIRE(StatusJson["exitState"]["ExitTimeReached"] == true); + BOOST_REQUIRE( StatusJson["exitState"]["ClearDataDir"] == true ); + BOOST_REQUIRE( StatusJson["exitState"]["StartAgain"] == true ); + BOOST_REQUIRE( StatusJson["exitState"]["StartFromSnapshot"] == true ); + BOOST_REQUIRE( StatusJson["exitState"]["ExitTimeReached"] == true ); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/unittests/libdevcore/core.cpp b/test/unittests/libdevcore/core.cpp index 54977d239..71a8d80de 100644 --- a/test/unittests/libdevcore/core.cpp +++ b/test/unittests/libdevcore/core.cpp @@ -36,8 +36,7 @@ using namespace dev::test; BOOST_FIXTURE_TEST_SUITE( CoreLibTests, TestOutputHelperFixture ) -BOOST_AUTO_TEST_CASE( toHex, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( toHex, *boost::unit_test::precondition( dev::test::run_not_express ) ) { dev::bytes b = dev::fromHex( "f0e1d2c3b4a59687" ); BOOST_CHECK_EQUAL( dev::toHex( b ), "f0e1d2c3b4a59687" ); BOOST_CHECK_EQUAL( dev::toHexPrefixed( b ), "0xf0e1d2c3b4a59687" ); @@ -49,15 +48,14 @@ BOOST_AUTO_TEST_CASE( toHex, "0x705a1849c02140e7197fbde82987a9eb623f97e32fc479a3cd8e4b3b52dcc4b2" ); } -BOOST_AUTO_TEST_CASE( toCompactHex, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + toCompactHex, *boost::unit_test::precondition( dev::test::run_not_express ) ) { dev::u256 i( "0x123456789abcdef" ); BOOST_CHECK_EQUAL( dev::toCompactHex( i ), "0123456789abcdef" ); BOOST_CHECK_EQUAL( dev::toCompactHexPrefixed( i ), "0x0123456789abcdef" ); } -BOOST_AUTO_TEST_CASE( byteRef, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( byteRef, *boost::unit_test::precondition( dev::test::run_not_express ) ) { cnote << "bytesRef copyTo and toString..."; dev::bytes originalSequence = dev::fromHex( "0102030405060708091011121314151617181920212223242526272829303132" ); @@ -71,8 +69,7 @@ BOOST_AUTO_TEST_CASE( byteRef, out.toBytes() == originalSequence, "Error when h256::ref().copyTo(dev::bytesRef out)" ); } -BOOST_AUTO_TEST_CASE( isHex, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( isHex, *boost::unit_test::precondition( dev::test::run_not_express ) ) { BOOST_CHECK( dev::isHex( "0x" ) ); BOOST_CHECK( dev::isHex( "0xA" ) ); BOOST_CHECK( dev::isHex( "0xAB" ) ); @@ -134,39 +131,39 @@ BOOST_AUTO_TEST_CASE( calculateShareWithPrecision ) { dev::u256 base = 1000; BOOST_CHECK_EQUAL( dev::calculateShareWithPrecision( base, 1000 ), base ); BOOST_CHECK_EQUAL( dev::calculateShareWithPrecision( base, 0 ), 0 ); - + // Test with simple decimal shares BOOST_CHECK_EQUAL( dev::calculateShareWithPrecision( base, 500 ), 500 ); BOOST_CHECK_EQUAL( dev::calculateShareWithPrecision( base, 100 ), 100 ); BOOST_CHECK_EQUAL( dev::calculateShareWithPrecision( base, 900 ), 900 ); - + // Test with two decimal places BOOST_CHECK_EQUAL( dev::calculateShareWithPrecision( base, 250 ), 250 ); BOOST_CHECK_EQUAL( dev::calculateShareWithPrecision( base, 750 ), 750 ); BOOST_CHECK_EQUAL( dev::calculateShareWithPrecision( base, 10 ), 10 ); BOOST_CHECK_EQUAL( dev::calculateShareWithPrecision( base, 990 ), 990 ); - + // Test with three decimal places BOOST_CHECK_EQUAL( dev::calculateShareWithPrecision( base, 125 ), 125 ); BOOST_CHECK_EQUAL( dev::calculateShareWithPrecision( base, 375 ), 375 ); BOOST_CHECK_EQUAL( dev::calculateShareWithPrecision( base, 1 ), 1 ); - + // Test with larger base values - dev::u256 largeBase = dev::u256("1000000000000000000"); // 10^18 - BOOST_CHECK_EQUAL( dev::calculateShareWithPrecision( largeBase, 500 ), - dev::u256("500000000000000000") ); - BOOST_CHECK_EQUAL( dev::calculateShareWithPrecision( largeBase, 250 ), - dev::u256("250000000000000000") ); - BOOST_CHECK_EQUAL( dev::calculateShareWithPrecision( largeBase, 1 ), - dev::u256("1000000000000000") ); - + dev::u256 largeBase = dev::u256( "1000000000000000000" ); // 10^18 + BOOST_CHECK_EQUAL( + dev::calculateShareWithPrecision( largeBase, 500 ), dev::u256( "500000000000000000" ) ); + BOOST_CHECK_EQUAL( + dev::calculateShareWithPrecision( largeBase, 250 ), dev::u256( "250000000000000000" ) ); + BOOST_CHECK_EQUAL( + dev::calculateShareWithPrecision( largeBase, 1 ), dev::u256( "1000000000000000" ) ); + // Test edge cases BOOST_CHECK_EQUAL( dev::calculateShareWithPrecision( 0, 500 ), 0 ); - BOOST_CHECK_EQUAL( dev::calculateShareWithPrecision( 1, 500 ), 0 ); // Due to integer division + BOOST_CHECK_EQUAL( dev::calculateShareWithPrecision( 1, 500 ), 0 ); // Due to integer division BOOST_CHECK_EQUAL( dev::calculateShareWithPrecision( 2, 500 ), 1 ); - + // Test with very small shares - BOOST_CHECK_EQUAL( dev::calculateShareWithPrecision( dev::u256("1000000"), 1 ), 1000 ); + BOOST_CHECK_EQUAL( dev::calculateShareWithPrecision( dev::u256( "1000000" ), 1 ), 1000 ); } #endif diff --git a/test/unittests/libdevcore/rlp.cpp b/test/unittests/libdevcore/rlp.cpp index f6edca2a0..6676b1c41 100644 --- a/test/unittests/libdevcore/rlp.cpp +++ b/test/unittests/libdevcore/rlp.cpp @@ -221,8 +221,8 @@ BOOST_AUTO_TEST_CASE( EmptyArrayList ) { } } -BOOST_AUTO_TEST_CASE( invalidRLPtest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + invalidRLPtest, *boost::unit_test::precondition( dev::test::run_not_express ) ) { runRlpTest( "invalidRLPTest", "/RLPTests" ); } @@ -234,7 +234,7 @@ BOOST_AUTO_TEST_CASE( rlpRandom ) { fs::path testPath = dev::test::getTestPath(); testPath /= fs::path( "RLPTests/RandomRLPTests" ); - vector< boost::filesystem::path > testFiles = test::getFiles( testPath, {".json"} ); + vector< boost::filesystem::path > testFiles = test::getFiles( testPath, { ".json" } ); for ( auto& path : testFiles ) { try { cnote << "Testing ..." << path.filename(); diff --git a/test/unittests/libdevcore/sharedspace.cpp b/test/unittests/libdevcore/sharedspace.cpp index f3305f609..8c885ad00 100644 --- a/test/unittests/libdevcore/sharedspace.cpp +++ b/test/unittests/libdevcore/sharedspace.cpp @@ -15,18 +15,16 @@ BOOST_FIXTURE_TEST_SUITE( SharedSpaceTests, TestOutputHelperFixture ) BOOST_AUTO_TEST_CASE( All ) { TransientDirectory td; - SharedSpace space(td.path()); + SharedSpace space( td.path() ); space.lock(); - BOOST_ASSERT(!space.try_lock()); + BOOST_ASSERT( !space.try_lock() ); - auto th = std::thread([&space](){ - space.unlock(); - }); + auto th = std::thread( [&space]() { space.unlock(); } ); th.join(); - BOOST_ASSERT(space.try_lock()); - BOOST_ASSERT(!space.try_lock()); + BOOST_ASSERT( space.try_lock() ); + BOOST_ASSERT( !space.try_lock() ); space.unlock(); } diff --git a/test/unittests/libdevcrypto/AES.cpp b/test/unittests/libdevcrypto/AES.cpp index 10545e8a5..e2c7edb3d 100644 --- a/test/unittests/libdevcrypto/AES.cpp +++ b/test/unittests/libdevcrypto/AES.cpp @@ -43,7 +43,8 @@ BOOST_AUTO_TEST_CASE( AesDecrypt, *boost::unit_test::precondition( dev::test::ru BOOST_CHECK( Address( "07746f871de684297923f933279555dda418f8a2" ) == kp.address() ); } -BOOST_AUTO_TEST_CASE( AesDecryptWrongSeed, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + AesDecryptWrongSeed, *boost::unit_test::precondition( dev::test::run_not_express ) ) { cnote << "AesDecryptWrongSeed"; bytes seed = fromHex( "badaead416c20cfd00c2fc9f1788ff9f965a2000799c96a624767cb0e1e90d2d7191efdd92349226742fdc73d1" @@ -53,7 +54,8 @@ BOOST_AUTO_TEST_CASE( AesDecryptWrongSeed, *boost::unit_test::precondition( dev: BOOST_CHECK( Address( "07746f871de684297923f933279555dda418f8a2" ) != kp.address() ); } -BOOST_AUTO_TEST_CASE( AesDecryptWrongPassword, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + AesDecryptWrongPassword, *boost::unit_test::precondition( dev::test::run_not_express ) ) { cnote << "AesDecryptWrongPassword"; bytes seed = fromHex( "2dbaead416c20cfd00c2fc9f1788ff9f965a2000799c96a624767cb0e1e90d2d7191efdd92349226742fdc73d1" @@ -63,7 +65,8 @@ BOOST_AUTO_TEST_CASE( AesDecryptWrongPassword, *boost::unit_test::precondition( BOOST_CHECK( Address( "07746f871de684297923f933279555dda418f8a2" ) != kp.address() ); } -BOOST_AUTO_TEST_CASE( AesDecryptFailInvalidSeed, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + AesDecryptFailInvalidSeed, *boost::unit_test::precondition( dev::test::run_not_express ) ) { cnote << "AesDecryptFailInvalidSeed"; bytes seed = fromHex( "xdbaead416c20cfd00c2fc9f1788ff9f965a2000799c96a624767cb0e1e90d2d7191efdd92349226742fdc73d1" @@ -72,13 +75,15 @@ BOOST_AUTO_TEST_CASE( AesDecryptFailInvalidSeed, *boost::unit_test::precondition BOOST_CHECK( bytes() == aesDecrypt( &seed, "test" ) ); } -BOOST_AUTO_TEST_CASE( AesDecryptFailInvalidSeedSize, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + AesDecryptFailInvalidSeedSize, *boost::unit_test::precondition( dev::test::run_not_express ) ) { cnote << "AesDecryptFailInvalidSeedSize"; bytes seed = fromHex( "000102030405060708090a0b0c0d0e0f" ); BOOST_CHECK( bytes() == aesDecrypt( &seed, "test" ) ); } -BOOST_AUTO_TEST_CASE( AesDecryptFailInvalidSeed2, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + AesDecryptFailInvalidSeed2, *boost::unit_test::precondition( dev::test::run_not_express ) ) { cnote << "AesDecryptFailInvalidSeed2"; bytes seed = fromHex( "000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f" ); BOOST_CHECK( bytes() == aesDecrypt( &seed, "test" ) ); diff --git a/test/unittests/libdevcrypto/LibSnark.cpp b/test/unittests/libdevcrypto/LibSnark.cpp index 232e46c71..de7c4cd8d 100644 --- a/test/unittests/libdevcrypto/LibSnark.cpp +++ b/test/unittests/libdevcrypto/LibSnark.cpp @@ -82,7 +82,8 @@ BOOST_AUTO_TEST_CASE( ecadd, *boost::unit_test::precondition( run_not_express ) BOOST_AUTO_TEST_CASE( fieldPointInvalid, *boost::unit_test::precondition( run_not_express ) ) { u256 const pMod{ - "21888242871839275222246405745257275088696311157297823662689037894645226208583"}; + "21888242871839275222246405745257275088696311157297823662689037894645226208583" + }; bytes input = toBigEndian( pMod ); BOOST_CHECK( !alt_bn128_G1_add( ref( input ) ).first ); @@ -512,7 +513,7 @@ BOOST_AUTO_TEST_CASE( benchECMULWorstCase1, *boost::unit_test::precondition( run bytes v = fromHex( "1fa111cf23c269b75957c715b762ef37074d341c280d113707ff342211b794571db10707e7cb4ba3c851f6bbb4" "3399701da0c7675ca0f9cfc595774fd055b2fb" ); - u256 const k{"21888242871839275222246405745257275088696311157297823662689037894645226208582"}; + u256 const k{ "21888242871839275222246405745257275088696311157297823662689037894645226208582" }; for ( int i = 0; i < 1000; ++i ) { bool success = false; @@ -531,7 +532,7 @@ BOOST_AUTO_TEST_CASE( benchECMULWorstCase2, *boost::unit_test::precondition( run bytes v = fromHex( "1fa111cf23c269b75957c715b762ef37074d341c280d113707ff342211b794571db10707e7cb4ba3c851f6bbb4" "3399701da0c7675ca0f9cfc595774fd055b2fb" ); - u256 const k{"10944121435919637611123202872628637544348155578648911831344518947322613104291"}; + u256 const k{ "10944121435919637611123202872628637544348155578648911831344518947322613104291" }; for ( int i = 0; i < 1000; ++i ) { bool success = false; @@ -564,7 +565,8 @@ BOOST_AUTO_TEST_CASE( benchECMULIdentity, *boost::unit_test::precondition( run_n BOOST_CHECK_EQUAL( toHex( v ), toHex( w ) ); } -BOOST_AUTO_TEST_CASE( ECMULuseCaseFromRopsten, *boost::unit_test::precondition( run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + ECMULuseCaseFromRopsten, *boost::unit_test::precondition( run_not_express ) ) { bytes const input = fromHex( "277a420332215ead37ba61fee84f0d216a345e762af8efd15453697170b3cdc5" "1b312cd37d4ad474fc299c9689fc0f347a2ec2b5b474a41b343142ee5fdd097a" diff --git a/test/unittests/libdevcrypto/SecretStore.cpp b/test/unittests/libdevcrypto/SecretStore.cpp index 3cd0ad024..cb50cff55 100644 --- a/test/unittests/libdevcrypto/SecretStore.cpp +++ b/test/unittests/libdevcrypto/SecretStore.cpp @@ -40,8 +40,7 @@ BOOST_AUTO_TEST_SUITE( Crypto ) BOOST_FIXTURE_TEST_SUITE( KeyStore, TestOutputHelperFixture ) -BOOST_AUTO_TEST_CASE( basic_tests, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( basic_tests, *boost::unit_test::precondition( dev::test::run_not_express ) ) { fs::path testPath = test::getTestPath(); testPath /= fs::path( "KeyStoreTests" ); @@ -66,8 +65,8 @@ BOOST_AUTO_TEST_CASE( basic_tests, } } -BOOST_AUTO_TEST_CASE( import_key_from_file, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + import_key_from_file, *boost::unit_test::precondition( dev::test::run_not_express ) ) { // Imports a key from an external file. Tests that the imported key is there // and that the external file is not deleted. TransientDirectory importDir; @@ -111,9 +110,9 @@ BOOST_AUTO_TEST_CASE( import_key_from_file, } } -BOOST_AUTO_TEST_CASE( import_secret, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { - for ( string const password : {"foobar", ""} ) { +BOOST_AUTO_TEST_CASE( + import_secret, *boost::unit_test::precondition( dev::test::run_not_express ) ) { + for ( string const password : { "foobar", "" } ) { TransientDirectory storeDir; string priv = "0202020202020202020202020202020202020202020202020202020202020202"; @@ -137,7 +136,7 @@ BOOST_AUTO_TEST_CASE( import_secret, } BOOST_AUTO_TEST_CASE( import_secret_bytesConstRef ) { - for ( string const password : {"foobar", ""} ) { + for ( string const password : { "foobar", "" } ) { TransientDirectory storeDir; string priv = "0202020202020202020202020202020202020202020202020202020202020202"; @@ -161,8 +160,8 @@ BOOST_AUTO_TEST_CASE( import_secret_bytesConstRef ) { } } -BOOST_AUTO_TEST_CASE( wrong_password, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + wrong_password, *boost::unit_test::precondition( dev::test::run_not_express ) ) { TransientDirectory storeDir; SecretStore store( storeDir.path() ); string password = "foobar"; @@ -188,8 +187,7 @@ BOOST_AUTO_TEST_CASE( wrong_password, } } -BOOST_AUTO_TEST_CASE( recode, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( recode, *boost::unit_test::precondition( dev::test::run_not_express ) ) { TransientDirectory storeDir; SecretStore store( storeDir.path() ); string password = "foobar"; @@ -228,8 +226,8 @@ BOOST_AUTO_TEST_CASE( recode, } } -BOOST_AUTO_TEST_CASE( keyImport_PBKDF2SHA256, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + keyImport_PBKDF2SHA256, *boost::unit_test::precondition( dev::test::run_not_express ) ) { // Imports a key from an external file. Tests that the imported key is there // and that the external file is not deleted. TransientDirectory importDir; @@ -269,8 +267,8 @@ BOOST_AUTO_TEST_CASE( keyImport_PBKDF2SHA256, fs::remove( importFile ); } -BOOST_AUTO_TEST_CASE( keyImport_Scrypt, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + keyImport_Scrypt, *boost::unit_test::precondition( dev::test::run_not_express ) ) { // Imports a key from an external file. Tests that the imported key is there // and that the external file is not deleted. TransientDirectory importDir; diff --git a/test/unittests/libdevcrypto/crypto.cpp b/test/unittests/libdevcrypto/crypto.cpp index 511955cf0..1e31d5485 100644 --- a/test/unittests/libdevcrypto/crypto.cpp +++ b/test/unittests/libdevcrypto/crypto.cpp @@ -75,16 +75,15 @@ static CryptoPP::DL_GroupParameters_EC< CryptoPP::ECP >& params() { return s_params; } -BOOST_AUTO_TEST_CASE( sha3general, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( sha3general, *boost::unit_test::precondition( dev::test::run_not_express ) ) { BOOST_REQUIRE_EQUAL( sha3( "" ), h256( "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" ) ); BOOST_REQUIRE_EQUAL( sha3( "hello" ), h256( "1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8" ) ); } -BOOST_AUTO_TEST_CASE( emptySHA3Types, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + emptySHA3Types, *boost::unit_test::precondition( dev::test::run_not_express ) ) { h256 emptySHA3( fromHex( "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" ) ); BOOST_REQUIRE_EQUAL( emptySHA3, EmptySHA3 ); @@ -93,14 +92,13 @@ BOOST_AUTO_TEST_CASE( emptySHA3Types, BOOST_REQUIRE_EQUAL( emptyListSHA3, EmptyListSHA3 ); } -BOOST_AUTO_TEST_CASE( pubkeyOfZero, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + pubkeyOfZero, *boost::unit_test::precondition( dev::test::run_not_express ) ) { auto pub = toPublic( {} ); BOOST_REQUIRE_EQUAL( pub, Public{} ); } -BOOST_AUTO_TEST_CASE( KeyPairMix, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( KeyPairMix, *boost::unit_test::precondition( dev::test::run_not_express ) ) { KeyPair k = KeyPair::create(); BOOST_REQUIRE( !!k.secret() ); BOOST_REQUIRE( !!k.pub() ); @@ -131,19 +129,19 @@ BOOST_AUTO_TEST_CASE( keypairs ) { BOOST_CHECK_EQUAL( t.sender(), p.address() ); } -BOOST_AUTO_TEST_CASE( KeyPairVerifySecret, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + KeyPairVerifySecret, *boost::unit_test::precondition( dev::test::run_not_express ) ) { auto keyPair = KeyPair::create(); auto* ctx = secp256k1_context_create( SECP256K1_CONTEXT_NONE ); BOOST_CHECK( secp256k1_ec_seckey_verify( ctx, keyPair.secret().data() ) ); secp256k1_context_destroy( ctx ); } -BOOST_AUTO_TEST_CASE( SignAndRecover, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + SignAndRecover, *boost::unit_test::precondition( dev::test::run_not_express ) ) { // This basic test that compares **fixed** results. Useful to test new // implementations or changes to implementations. - auto sec = Secret{sha3( "sec" )}; + auto sec = Secret{ sha3( "sec" ) }; auto msg = sha3( "msg" ); auto sig = sign( sec, msg ); auto expectedSig = @@ -158,8 +156,8 @@ BOOST_AUTO_TEST_CASE( SignAndRecover, BOOST_CHECK_EQUAL( pub.hex(), expectedPub ); } -BOOST_AUTO_TEST_CASE( SignAndRecoverLoop, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + SignAndRecoverLoop, *boost::unit_test::precondition( dev::test::run_not_express ) ) { auto num = 13; auto msg = h256::random(); while ( --num ) { @@ -179,8 +177,8 @@ BOOST_AUTO_TEST_CASE( cryptopp_patch ) { BOOST_REQUIRE_EQUAL( io_text.size(), 0 ); } -BOOST_AUTO_TEST_CASE( verify_secert, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + verify_secert, *boost::unit_test::precondition( dev::test::run_not_express ) ) { Secret empty; KeyPair kNot( empty ); BOOST_REQUIRE( !kNot.address() ); @@ -188,8 +186,8 @@ BOOST_AUTO_TEST_CASE( verify_secert, BOOST_REQUIRE( k.address() ); } -BOOST_AUTO_TEST_CASE( common_encrypt_decrypt, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + common_encrypt_decrypt, *boost::unit_test::precondition( dev::test::run_not_express ) ) { string message( "Now is the time for all good persons to come to the aid of humanity." ); bytes m = asBytes( message ); bytesConstRef bcr( &m ); @@ -206,8 +204,8 @@ BOOST_AUTO_TEST_CASE( common_encrypt_decrypt, BOOST_REQUIRE( plain == asBytes( message ) ); } -BOOST_AUTO_TEST_CASE( sha3_norestart, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + sha3_norestart, *boost::unit_test::precondition( dev::test::run_not_express ) ) { CryptoPP::Keccak_256 ctx; bytes input( asBytes( "test" ) ); ctx.Update( input.data(), 4 ); @@ -237,8 +235,7 @@ BOOST_AUTO_TEST_CASE( sha3_norestart, BOOST_REQUIRE( finalDigest2 != finalDigest3 ); } -BOOST_AUTO_TEST_CASE( ecies_kdf, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( ecies_kdf, *boost::unit_test::precondition( dev::test::run_not_express ) ) { KeyPair local = KeyPair::create(); KeyPair remote = KeyPair::create(); // nonce @@ -266,8 +263,8 @@ BOOST_AUTO_TEST_CASE( ecies_kdf, BOOST_REQUIRE( key1 == key2 ); } -BOOST_AUTO_TEST_CASE( ecdh_agree_invalid_pubkey, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + ecdh_agree_invalid_pubkey, *boost::unit_test::precondition( dev::test::run_not_express ) ) { KeyPair ok = KeyPair::create(); Public pubkey; ~pubkey; // Create a pubkey of all 1s. @@ -275,8 +272,8 @@ BOOST_AUTO_TEST_CASE( ecdh_agree_invalid_pubkey, BOOST_CHECK( !ecdh::agree( ok.secret(), pubkey, z ) ); } -BOOST_AUTO_TEST_CASE( ecdh_agree_invalid_seckey, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + ecdh_agree_invalid_seckey, *boost::unit_test::precondition( dev::test::run_not_express ) ) { KeyPair ok = KeyPair::create(); Secret seckey; // "Null" seckey is invalid. BOOST_CHECK( !ecdh::agree( seckey, ok.pub(), seckey ) ); @@ -320,8 +317,8 @@ BOOST_AUTO_TEST_CASE( ecies_sharedMacData ) { BOOST_CHECK_EQUAL( toHex( decrypted ), toHex( original ) ); } -BOOST_AUTO_TEST_CASE( ecies_eckeypair, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + ecies_eckeypair, *boost::unit_test::precondition( dev::test::run_not_express ) ) { KeyPair k = KeyPair::create(); string message( "Now is the time for all good persons to come to the aid of humanity." ); @@ -335,8 +332,8 @@ BOOST_AUTO_TEST_CASE( ecies_eckeypair, BOOST_REQUIRE( b == asBytes( original ) ); } -BOOST_AUTO_TEST_CASE( ecdhCryptopp, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + ecdhCryptopp, *boost::unit_test::precondition( dev::test::run_not_express ) ) { CryptoPP::ECDH< CryptoPP::ECP >::Domain dhLocal( curveOID() ); CryptoPP::SecByteBlock privLocal( dhLocal.PrivateKeyLength() ); CryptoPP::SecByteBlock pubLocal( dhLocal.PublicKeyLength() ); @@ -370,11 +367,11 @@ BOOST_AUTO_TEST_CASE( ecdhCryptopp, // Now use our keys KeyPair a = KeyPair::create(); - _byte_ puba[65] = {0x04}; + _byte_ puba[65] = { 0x04 }; memcpy( &puba[1], a.pub().data(), 64 ); KeyPair b = KeyPair::create(); - _byte_ pubb[65] = {0x04}; + _byte_ pubb[65] = { 0x04 }; memcpy( &pubb[1], b.pub().data(), 64 ); CryptoPP::ECDH< CryptoPP::ECP >::Domain dhA( curveOID() ); @@ -383,8 +380,7 @@ BOOST_AUTO_TEST_CASE( ecdhCryptopp, BOOST_REQUIRE( shared ); } -BOOST_AUTO_TEST_CASE( ecdhe, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( ecdhe, *boost::unit_test::precondition( dev::test::run_not_express ) ) { auto local = KeyPair::create(); auto remote = KeyPair::create(); BOOST_CHECK_NE( local.pub(), remote.pub() ); @@ -402,9 +398,8 @@ BOOST_AUTO_TEST_CASE( ecdhe, BOOST_CHECK_EQUAL( sremote, slocal ); } -BOOST_AUTO_TEST_CASE( ecdhAgree, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { - auto sec = Secret{sha3( "ecdhAgree" )}; +BOOST_AUTO_TEST_CASE( ecdhAgree, *boost::unit_test::precondition( dev::test::run_not_express ) ) { + auto sec = Secret{ sha3( "ecdhAgree" ) }; auto pub = toPublic( sec ); Secret sharedSec; BOOST_CHECK( ecdh::agree( sec, pub, sharedSec ) ); @@ -413,8 +408,8 @@ BOOST_AUTO_TEST_CASE( ecdhAgree, BOOST_CHECK_EQUAL( sharedSec.makeInsecure().hex(), expectedSharedSec ); } -BOOST_AUTO_TEST_CASE( handshakeNew, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + handshakeNew, *boost::unit_test::precondition( dev::test::run_not_express ) ) { // authInitiator -> E(remote-pubk, S(ecdhe-random, ecdh-shared-secret^nonce) || // H(ecdhe-random-pubk) || pubk || nonce || 0x0) authRecipient -> E(remote-pubk, // ecdhe-random-pubk || nonce || 0x0) @@ -436,13 +431,16 @@ BOOST_AUTO_TEST_CASE( handshakeNew, auto eA = KeyPair::create(); bytes nAbytes( fromHex( "0xAAAA" ) ); h256 nonceA( sha3( nAbytes ) ); - bytes auth( size_t( Signature::size ) + size_t( h256::size ) + size_t( Public::size ) + size_t( h256::size ) + 1 ); + bytes auth( size_t( Signature::size ) + size_t( h256::size ) + size_t( Public::size ) + + size_t( h256::size ) + 1 ); Secret ssA; { bytesRef sig( &auth[0], Signature::size ); bytesRef hepubk( &auth[Signature::size], h256::size ); - bytesRef pubk( &auth[size_t( Signature::size ) + size_t( h256::size ) ], Public::size ); - bytesRef nonce( &auth[size_t( Signature::size ) + size_t( h256::size ) + size_t( Public::size ) ], h256::size ); + bytesRef pubk( &auth[size_t( Signature::size ) + size_t( h256::size )], Public::size ); + bytesRef nonce( + &auth[size_t( Signature::size ) + size_t( h256::size ) + size_t( Public::size )], + h256::size ); BOOST_CHECK( crypto::ecdh::agree( nodeA.secret(), nodeB.pub(), ssA ) ); sign( eA.secret(), ( ssA ^ nonceA ).makeInsecure() ).ref().copyTo( sig ); @@ -466,7 +464,8 @@ BOOST_AUTO_TEST_CASE( handshakeNew, bytes authdecrypted; decrypt( nodeB.secret(), &authcipher, authdecrypted ); Public node; - bytesConstRef pubk( &authdecrypted[size_t( Signature::size ) + size_t( h256::size ) ], Public::size ); + bytesConstRef pubk( + &authdecrypted[size_t( Signature::size ) + size_t( h256::size )], Public::size ); pubk.copyTo( node.ref() ); bytesRef epubk( &ack[0], Public::size ); @@ -551,9 +550,11 @@ BOOST_AUTO_TEST_CASE( handshakeNew, h256 nonceAAuth; bytesConstRef sig( &authdecrypted[0], Signature::size ); bytesConstRef hepubk( &authdecrypted[Signature::size], h256::size ); - bytesConstRef pubk( &authdecrypted[size_t( Signature::size ) + size_t( h256::size ) ], Public::size ); - bytesConstRef nonce( - &authdecrypted[size_t( Signature::size ) + size_t( h256::size ) + size_t( Public::size ) ], h256::size ); + bytesConstRef pubk( + &authdecrypted[size_t( Signature::size ) + size_t( h256::size )], Public::size ); + bytesConstRef nonce( &authdecrypted[size_t( Signature::size ) + size_t( h256::size ) + + size_t( Public::size )], + h256::size ); nonce.copyTo( nonceAAuth.ref() ); pubk.copyTo( nodeAAuth.ref() ); @@ -605,12 +606,12 @@ BOOST_AUTO_TEST_CASE( handshakeNew, BOOST_REQUIRE_EQUAL( bEgressMac, aIngressMac ); } -BOOST_AUTO_TEST_CASE( ecies_aes128_ctr_unaligned, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + ecies_aes128_ctr_unaligned, *boost::unit_test::precondition( dev::test::run_not_express ) ) { SecureFixedHash< 16 > encryptK( sha3( "..." ), h128::AlignLeft ); h256 egressMac( sha3( "+++" ) ); // TESTING: send encrypt magic sequence - bytes magic{0x22, 0x40, 0x08, 0x91}; + bytes magic{ 0x22, 0x40, 0x08, 0x91 }; bytes magicCipherAndMac; magicCipherAndMac = encryptSymNoAuth( encryptK, h128(), &magic ); @@ -628,8 +629,8 @@ BOOST_AUTO_TEST_CASE( ecies_aes128_ctr_unaligned, BOOST_REQUIRE( magic == plaintext ); } -BOOST_AUTO_TEST_CASE( ecies_aes128_ctr, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + ecies_aes128_ctr, *boost::unit_test::precondition( dev::test::run_not_express ) ) { SecureFixedHash< 16 > k( sha3( "0xAAAA" ), h128::AlignLeft ); string m = "AAAAAAAAAAAAAAAA"; bytesConstRef msg( ( _byte_* ) m.data(), m.size() ); @@ -642,8 +643,8 @@ BOOST_AUTO_TEST_CASE( ecies_aes128_ctr, BOOST_REQUIRE_EQUAL( asString( plaintext ), m ); } -BOOST_AUTO_TEST_CASE( cryptopp_aes128_ctr, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + cryptopp_aes128_ctr, *boost::unit_test::precondition( dev::test::run_not_express ) ) { const int aesKeyLen = 16; BOOST_REQUIRE( sizeof( char ) == sizeof( _byte_ ) ); @@ -707,8 +708,8 @@ BOOST_AUTO_TEST_CASE( cryptopp_aes128_ctr, } } -BOOST_AUTO_TEST_CASE( cryptopp_aes128_cbc, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + cryptopp_aes128_cbc, *boost::unit_test::precondition( dev::test::run_not_express ) ) { const int aesKeyLen = 16; BOOST_REQUIRE( sizeof( char ) == sizeof( _byte_ ) ); @@ -750,8 +751,7 @@ BOOST_AUTO_TEST_CASE( cryptopp_aes128_cbc, BOOST_REQUIRE( string192 == plainOriginal ); } -BOOST_AUTO_TEST_CASE( recoverVgt3, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( recoverVgt3, *boost::unit_test::precondition( dev::test::run_not_express ) ) { // base secret Secret secret( sha3( "privacy" ) ); diff --git a/test/unittests/libdevcrypto/hexPrefix.cpp b/test/unittests/libdevcrypto/hexPrefix.cpp index 200d11eda..d9f579efb 100644 --- a/test/unittests/libdevcrypto/hexPrefix.cpp +++ b/test/unittests/libdevcrypto/hexPrefix.cpp @@ -37,8 +37,8 @@ BOOST_AUTO_TEST_SUITE( Crypto ) BOOST_FIXTURE_TEST_SUITE( Basic, TestOutputHelperFixture ) -BOOST_AUTO_TEST_CASE( hexPrefix_test, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + hexPrefix_test, *boost::unit_test::precondition( dev::test::run_not_express ) ) { fs::path testPath = test::getTestPath(); testPath /= fs::path( "BasicTests" ); @@ -61,29 +61,29 @@ BOOST_AUTO_TEST_CASE( hexPrefix_test, } } -BOOST_AUTO_TEST_CASE( base64, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { - static char const* const s_tests[][2] = {{"", ""}, {"f", "Zg=="}, {"fo", "Zm8="}, - {"foo", "Zm9v"}, {"foob", "Zm9vYg=="}, {"fooba", "Zm9vYmE="}, {"foobar", "Zm9vYmFy"}, - {"So?

" - "This 4, 5, 6, 7, 8, 9, z, {, |, } tests Base64 encoder. " - "Show me: @, A, B, C, D, E, F, G, H, I, J, K, L, M, " - "N, O, P, Q, R, S, T, U, V, W, X, Y, Z, [, \\, ], ^, _, `, " - "a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s.", +BOOST_AUTO_TEST_CASE( base64, *boost::unit_test::precondition( dev::test::run_not_express ) ) { + static char const* const s_tests[][2] = { { "", "" }, { "f", "Zg==" }, { "fo", "Zm8=" }, + { "foo", "Zm9v" }, { "foob", "Zm9vYg==" }, { "fooba", "Zm9vYmE=" }, + { "foobar", "Zm9vYmFy" }, + { "So?

" + "This 4, 5, 6, 7, 8, 9, z, {, |, } tests Base64 encoder. " + "Show me: @, A, B, C, D, E, F, G, H, I, J, K, L, M, " + "N, O, P, Q, R, S, T, U, V, W, X, Y, Z, [, \\, ], ^, _, `, " + "a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s.", "U28/PHA+VGhpcyA0LCA1LCA2LCA3LCA4LCA5LCB6LCB7LCB8LCB9IHRlc3RzIEJhc2U2NCBlbmNv" "ZGVyLiBTaG93IG1lOiBALCBBLCBCLCBDLCBELCBFLCBGLCBHLCBILCBJLCBKLCBLLCBMLCBNLCBO" "LCBPLCBQLCBRLCBSLCBTLCBULCBVLCBWLCBXLCBYLCBZLCBaLCBbLCBcLCBdLCBeLCBfLCBgLCBh" - "LCBiLCBjLCBkLCBlLCBmLCBnLCBoLCBpLCBqLCBrLCBsLCBtLCBuLCBvLCBwLCBxLCByLCBzLg=="}}; + "LCBiLCBjLCBkLCBlLCBmLCBnLCBoLCBpLCBqLCBrLCBsLCBtLCBuLCBvLCBwLCBxLCByLCBzLg==" } }; static const auto c_numTests = sizeof( s_tests ) / sizeof( s_tests[0] ); for ( size_t i = 0; i < c_numTests; ++i ) { - auto expectedDecoded = std::string{s_tests[i][0]}; - auto expectedEncoded = std::string{s_tests[i][1]}; + auto expectedDecoded = std::string{ s_tests[i][0] }; + auto expectedEncoded = std::string{ s_tests[i][1] }; auto encoded = toBase64( expectedDecoded ); BOOST_CHECK_EQUAL( expectedEncoded, encoded ); auto decodedBytes = fromBase64( expectedEncoded ); - auto decoded = bytesConstRef{decodedBytes.data(), decodedBytes.size()}.toString(); + auto decoded = bytesConstRef{ decodedBytes.data(), decodedBytes.size() }.toString(); BOOST_CHECK_EQUAL( decoded, expectedDecoded ); } } diff --git a/test/unittests/libethashseal/EthashTest.cpp b/test/unittests/libethashseal/EthashTest.cpp index 156b07aac..f30ff83cf 100644 --- a/test/unittests/libethashseal/EthashTest.cpp +++ b/test/unittests/libethashseal/EthashTest.cpp @@ -117,12 +117,12 @@ BOOST_AUTO_TEST_CASE( epochSeed, *boost::unit_test::precondition( dev::test::run header.setNumber( 30000 ); seed = Ethash::seedHash( header ); BOOST_CHECK_EQUAL( - seed, h256{"290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563"} ); + seed, h256{ "290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563" } ); header.setNumber( 2048 * 30000 ); seed = Ethash::seedHash( header ); BOOST_CHECK_EQUAL( - seed, h256{"20a7678ca7b50829183baac2e1e3c43fa3c4bcbc171b11cf5a9f30bebd172920"} ); + seed, h256{ "20a7678ca7b50829183baac2e1e3c43fa3c4bcbc171b11cf5a9f30bebd172920" } ); } namespace { @@ -190,9 +190,9 @@ BOOST_AUTO_TEST_CASE( ethashEvalHeader ) { // FIXME: Drop this test as ethash library has this test cases in its test suite. for ( auto& t : ethashTestCases ) { - BlockHeader header{fromHex( t.header ), HeaderData}; - h256 headerHash{t.headerHash}; - eth::Nonce nonce{t.nonce}; + BlockHeader header{ fromHex( t.header ), HeaderData }; + h256 headerHash{ t.headerHash }; + eth::Nonce nonce{ t.nonce }; BOOST_REQUIRE_EQUAL( headerHash, header.hash( WithoutSeal ) ); BOOST_REQUIRE_EQUAL( nonce, Ethash::nonce( header ) ); @@ -201,10 +201,10 @@ BOOST_AUTO_TEST_CASE( ethashEvalHeader ) { ethash::hash256_from_bytes( header.hash( WithoutSeal ).data() ), ( uint64_t )( u64 ) nonce ); - h256 mix{result.mix_hash.bytes, h256::ConstructFromPointer}; - h256 final{result.final_hash.bytes, h256::ConstructFromPointer}; + h256 mix{ result.mix_hash.bytes, h256::ConstructFromPointer }; + h256 final{ result.final_hash.bytes, h256::ConstructFromPointer }; - BOOST_REQUIRE_EQUAL( final, h256{t.result} ); + BOOST_REQUIRE_EQUAL( final, h256{ t.result } ); BOOST_REQUIRE_EQUAL( mix, Ethash::mixHash( header ) ); } } diff --git a/test/unittests/libethcore/SealEngineTest.cpp b/test/unittests/libethcore/SealEngineTest.cpp index f6a51182a..671cc6912 100644 --- a/test/unittests/libethcore/SealEngineTest.cpp +++ b/test/unittests/libethcore/SealEngineTest.cpp @@ -45,7 +45,8 @@ class UnsignedTransactionFixture : public TestOutputHelperFixture { ChainOperationParams params; Ethash ethash; BlockHeader header; - Transaction tx{0, 0, 21000, Address( "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" ), bytes(), 0}; + Transaction tx{ 0, 0, 21000, Address( "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" ), bytes(), + 0 }; }; } // namespace @@ -61,15 +62,15 @@ BOOST_AUTO_TEST_CASE( UnsignedTransactionIsValidBeforeExperimental, header.setNumber( 1 ); - SealEngineFace::verifyTransaction( params, ImportRequirements::TransactionSignatures, - tx, 1, header, 0 ); // check that it doesn't throw + SealEngineFace::verifyTransaction( params, ImportRequirements::TransactionSignatures, tx, 1, + header, 0 ); // check that it doesn't throw } BOOST_AUTO_TEST_CASE( UnsignedTransactionIsValidInExperimental ) { header.setNumber( 0x1010 ); - SealEngineFace::verifyTransaction( params, ImportRequirements::TransactionSignatures, - tx, 1, header, 0 ); // check that it doesn't throw + SealEngineFace::verifyTransaction( params, ImportRequirements::TransactionSignatures, tx, 1, + header, 0 ); // check that it doesn't throw } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/unittests/libethcore/difficulty.cpp b/test/unittests/libethcore/difficulty.cpp index fd26f197d..8e463d1ae 100644 --- a/test/unittests/libethcore/difficulty.cpp +++ b/test/unittests/libethcore/difficulty.cpp @@ -162,8 +162,8 @@ BOOST_AUTO_TEST_CASE( difficultyTestsFrontier ) { testDifficulty( testFileFullName, sealEngine ); } -BOOST_AUTO_TEST_CASE( difficultyTestsRopsten, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + difficultyTestsRopsten, *boost::unit_test::precondition( dev::test::run_not_express ) ) { fs::path const testFileFullName = test::getTestPath() / fs::path( "BasicTests/difficultyRopsten.json" ); @@ -189,8 +189,8 @@ BOOST_AUTO_TEST_CASE( difficultyTestsHomestead ) { testDifficulty( testFileFullName, sealEngine ); } -BOOST_AUTO_TEST_CASE( difficultyByzantium, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + difficultyByzantium, *boost::unit_test::precondition( dev::test::run_not_express ) ) { fs::path const testFileFullName = test::getTestPath() / fs::path( "BasicTests/difficultyByzantium.json" ); @@ -203,8 +203,8 @@ BOOST_AUTO_TEST_CASE( difficultyByzantium, testDifficulty( testFileFullName, sealEngine ); } -BOOST_AUTO_TEST_CASE( difficultyTestsMainNetwork, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + difficultyTestsMainNetwork, *boost::unit_test::precondition( dev::test::run_not_express ) ) { fs::path const testFileFullName = test::getTestPath() / fs::path( "BasicTests/difficultyMainNetwork.json" ); @@ -226,10 +226,10 @@ BOOST_AUTO_TEST_CASE( difficultyTestsCustomMainNetwork ) { if ( dev::test::Options::get().filltests ) { int64_t byzantiumBlockNumber = 4370000; - std::vector< int64_t > blockNumberVector = { - byzantiumBlockNumber - 100000, byzantiumBlockNumber, byzantiumBlockNumber + 100000}; - std::vector< u256 > parentDifficultyVector = {1000, 2048, 4000, 1000000}; - std::vector< int > timestampDeltaVector = {0, 1, 8, 10, 13, 20, 100, 800, 1000, 1500}; + std::vector< int64_t > blockNumberVector = { byzantiumBlockNumber - 100000, + byzantiumBlockNumber, byzantiumBlockNumber + 100000 }; + std::vector< u256 > parentDifficultyVector = { 1000, 2048, 4000, 1000000 }; + std::vector< int > timestampDeltaVector = { 0, 1, 8, 10, 13, 20, 100, 800, 1000, 1500 }; int testN = 0; ostringstream finalTest; diff --git a/test/unittests/libethcore/keymanager.cpp b/test/unittests/libethcore/keymanager.cpp index 0e9e8a44e..b6a3fec77 100644 --- a/test/unittests/libethcore/keymanager.cpp +++ b/test/unittests/libethcore/keymanager.cpp @@ -37,15 +37,15 @@ namespace fs = boost::filesystem; BOOST_FIXTURE_TEST_SUITE( KeyManagerTests, TestOutputHelperFixture ) BOOST_AUTO_TEST_CASE( KeyInfoDefaultConstructor, - + *boost::unit_test::precondition( dev::test::run_not_express ) ) { KeyInfo kiDefault; BOOST_CHECK_EQUAL( kiDefault.accountName, "" ); BOOST_CHECK( kiDefault.passHash == h256() ); } -BOOST_AUTO_TEST_CASE( KeyInfoConstructor, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + KeyInfoConstructor, *boost::unit_test::precondition( dev::test::run_not_express ) ) { h256 passHash( "0x2a" ); string accountName = "myAccount"; KeyInfo ki( passHash, accountName ); @@ -53,8 +53,8 @@ BOOST_AUTO_TEST_CASE( KeyInfoConstructor, BOOST_CHECK( ki.passHash == h256( "0x2a" ) ); } -BOOST_AUTO_TEST_CASE( KeyManagerConstructor, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + KeyManagerConstructor, *boost::unit_test::precondition( dev::test::run_not_express ) ) { KeyManager km; BOOST_CHECK_EQUAL( km.keysFile(), km.defaultPath() ); BOOST_CHECK_EQUAL( km.defaultPath(), getDataDir( "ethereum" ) / fs::path( "keys.info" ) ); @@ -63,8 +63,8 @@ BOOST_AUTO_TEST_CASE( KeyManagerConstructor, km.kill( a ); } -BOOST_AUTO_TEST_CASE( KeyManagerKeysFile, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + KeyManagerKeysFile, *boost::unit_test::precondition( dev::test::run_not_express ) ) { KeyManager km; string password = "hardPassword"; BOOST_CHECK( !km.load( password ) ); @@ -86,8 +86,8 @@ BOOST_AUTO_TEST_CASE( KeyManagerKeysFile, km.kill( a ); } -BOOST_AUTO_TEST_CASE( KeyManagerHints, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + KeyManagerHints, *boost::unit_test::precondition( dev::test::run_not_express ) ) { KeyManager km; string password = "hardPassword"; @@ -105,8 +105,8 @@ BOOST_AUTO_TEST_CASE( KeyManagerHints, km.kill( a ); } -BOOST_AUTO_TEST_CASE( KeyManagerAccounts, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + KeyManagerAccounts, *boost::unit_test::precondition( dev::test::run_not_express ) ) { string password = "hardPassword"; TransientDirectory tmpDir; @@ -120,8 +120,8 @@ BOOST_AUTO_TEST_CASE( KeyManagerAccounts, km.kill( a ); } -BOOST_AUTO_TEST_CASE( KeyManagerKill, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + KeyManagerKill, *boost::unit_test::precondition( dev::test::run_not_express ) ) { string password = "hardPassword"; TransientDirectory tmpDir; KeyPair kp = KeyPair::create(); diff --git a/test/unittests/libethereum/Block.cpp b/test/unittests/libethereum/Block.cpp index 895ec7a79..cd851e96c 100644 --- a/test/unittests/libethereum/Block.cpp +++ b/test/unittests/libethereum/Block.cpp @@ -38,7 +38,8 @@ BOOST_FIXTURE_TEST_SUITE( BlockSuite, TestOutputHelperFixture ) BOOST_FIXTURE_TEST_SUITE( GasPricer, TestOutputHelperFixture ) -BOOST_AUTO_TEST_CASE( bNormalTransactionInput, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + bNormalTransactionInput, *boost::unit_test::precondition( dev::test::run_not_express ) ) { TestBlockChain testBlockchain( TestBlockChain::defaultGenesisBlock( 63000 ) ); TestBlock const& genesisBlock = testBlockchain.testGenesis(); State const& genesisState = genesisBlock.state(); @@ -79,7 +80,8 @@ BOOST_AUTO_TEST_CASE( bBlockNotSyncedToBlockchain ) { BOOST_REQUIRE( testBlockT.transactionQueue().topTransactions( 4 ).size() == 2 ); } -BOOST_AUTO_TEST_CASE( bExceedBlockGasLimit, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + bExceedBlockGasLimit, *boost::unit_test::precondition( dev::test::run_not_express ) ) { TestBlockChain testBlockchain( TestBlockChain::defaultGenesisBlock( 63000 ) ); TestBlock const& genesisBlock = testBlockchain.testGenesis(); State const& genesisState = genesisBlock.state(); @@ -139,7 +141,8 @@ BOOST_AUTO_TEST_CASE( bTemporaryNoGasLeft ) { BOOST_REQUIRE( testBlockT.transactionQueue().topTransactions( 4 ).size() == 3 ); } -BOOST_AUTO_TEST_CASE( bInvalidNonceNoncesAhead, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + bInvalidNonceNoncesAhead, *boost::unit_test::precondition( dev::test::run_not_express ) ) { // Add some amount of gas because block limit decreases TestBlockChain testBlockchain( TestBlockChain::defaultGenesisBlock( 63000 + 21000 ) ); TestBlock const& genesisBlock = testBlockchain.testGenesis(); @@ -173,7 +176,8 @@ BOOST_AUTO_TEST_CASE( bInvalidNonceNoncesAhead, *boost::unit_test::precondition( u256( 3 ) ); // nonce starts with 1 } -BOOST_AUTO_TEST_CASE( bInvalidNonceNonceTooLow, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + bInvalidNonceNonceTooLow, *boost::unit_test::precondition( dev::test::run_not_express ) ) { TestBlockChain testBlockchain( TestBlockChain::defaultGenesisBlock( 63000 ) ); TestBlock const& genesisBlock = testBlockchain.testGenesis(); State const& genesisState = genesisBlock.state(); @@ -227,13 +231,13 @@ BOOST_AUTO_TEST_CASE( bConstantinopleBlockReward ) { TestBlock const& topBlock = testBlockchain.topBlock(); - #ifdef FAIR - // default block reward for FAIR is 5 ether - BOOST_REQUIRE_EQUAL( topBlock.state().balance( topBlock.beneficiary() ), 5 * ether ); - #else - // constantinople block reward is 2 ether - BOOST_REQUIRE_EQUAL( topBlock.state().balance( topBlock.beneficiary() ), 2 * ether ); - #endif +#ifdef FAIR + // default block reward for FAIR is 5 ether + BOOST_REQUIRE_EQUAL( topBlock.state().balance( topBlock.beneficiary() ), 5 * ether ); +#else + // constantinople block reward is 2 ether + BOOST_REQUIRE_EQUAL( topBlock.state().balance( topBlock.beneficiary() ), 2 * ether ); +#endif } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/unittests/libethereum/BlockChain.cpp b/test/unittests/libethereum/BlockChain.cpp index 2aab08211..e34ac1f32 100644 --- a/test/unittests/libethereum/BlockChain.cpp +++ b/test/unittests/libethereum/BlockChain.cpp @@ -80,7 +80,7 @@ BOOST_AUTO_TEST_CASE( Mining_1_mineBlockWithTransaction ) { BOOST_AUTO_TEST_CASE( Mining_2_mineUncles ) { TestBlockChain bc( TestBlockChain::defaultGenesisBlock() ); - TestTransaction tr = TestTransaction::defaultTransaction(); // nonce 1 + TestTransaction tr = TestTransaction::defaultTransaction(); // nonce 1 TestBlock block; block.addTransaction( tr ); block.mine( bc ); @@ -92,7 +92,7 @@ BOOST_AUTO_TEST_CASE( Mining_2_mineUncles ) { uncleBlock2.mine( bc ); sleep( 1 ); - TestTransaction tr2 = TestTransaction::defaultTransaction( 2 ); // nonce 2 + TestTransaction tr2 = TestTransaction::defaultTransaction( 2 ); // nonce 2 TestBlock block2; block2.addTransaction( tr2 ); block2.mine( bc ); @@ -297,7 +297,8 @@ BOOST_AUTO_TEST_CASE( updateStats ) { bcRef.garbageCollect( true ); } -BOOST_AUTO_TEST_CASE( invalidJsonThrows, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + invalidJsonThrows, *boost::unit_test::precondition( dev::test::run_not_express ) ) { h256 emptyStateRoot; /* Below, a comma is missing between fields. */ BOOST_CHECK_THROW( diff --git a/test/unittests/libethereum/ClientTest.cpp b/test/unittests/libethereum/ClientTest.cpp index b317202c7..e5abed483 100644 --- a/test/unittests/libethereum/ClientTest.cpp +++ b/test/unittests/libethereum/ClientTest.cpp @@ -108,7 +108,6 @@ struct FixtureCommon { class TestClientFixture : public TestOutputHelperFixture { public: TestClientFixture( const std::string& _config = "" ) try { - std::shared_ptr< ChainParams > chainParams = std::make_shared< ChainParams >(); if ( _config != "" ) { Json::Value ret; @@ -119,8 +118,7 @@ class TestClientFixture : public TestOutputHelperFixture { Json::FastWriter fastWriter; std::string config = fastWriter.write( ret ); chainParams->loadConfig( config ); - } - else { + } else { chainParams->nodeInfo.port = chainParams->nodeInfo.port6 = rand_port; chainParams->sChain.nodes[0].port = chainParams->sChain.nodes[0].port6 = rand_port; } @@ -138,7 +136,7 @@ class TestClientFixture : public TestOutputHelperFixture { auto monitor = make_shared< InstanceMonitor >( "test" ); - setenv("DATA_DIR", m_tmpDir.path().c_str(), 1); + setenv( "DATA_DIR", m_tmpDir.path().c_str(), 1 ); m_ethereum.reset( new eth::ClientTest( chainParams, ( int ) chainParams->getNetworkId(), shared_ptr< GasPricer >(), NULL, monitor, m_tmpDir.path(), WithExisting::Kill ) ); @@ -222,7 +220,8 @@ class TestClientFixture : public TestOutputHelperFixture { ~TestClientFixture() { #ifdef FAIR const auto deadline = chrono::steady_clock::now() + chrono::seconds( 10 ); - while ( m_ethereum->skaleHost()->ignoreNewBlocksEnabled() && chrono::steady_clock::now() < deadline ) { + while ( m_ethereum->skaleHost()->ignoreNewBlocksEnabled() && + chrono::steady_clock::now() < deadline ) { usleep( 10 ); } if ( m_ethereum->skaleHost()->isConsesusUpdateHappened() ) @@ -301,7 +300,7 @@ class TestClientSnapshotsFixture : public TestOutputHelperFixture, public Fixtur auto monitor = make_shared< InstanceMonitor >( "test" ); - setenv("DATA_DIR", m_tmpDir.path().c_str(), 1); + setenv( "DATA_DIR", m_tmpDir.path().c_str(), 1 ); m_ethereum.reset( new eth::ClientTest( chainParams, ( int ) chainParams->getNetworkId(), shared_ptr< GasPricer >(), mgr, monitor, m_tmpDir.path(), WithExisting::Kill ) ); @@ -437,7 +436,8 @@ static std::string const c_genesisInfoSkaleTest = std::string() + "nodeName": "Node1", "nodeID": 1112, "bindIP": "127.0.0.1", - "basePort": )E" + std::to_string( rand_port ) + R"E(, + "basePort": )E" + std::to_string( rand_port ) + + R"E(, "logLevel": "trace", "logLevelProposal": "trace", "testSignatures": true @@ -449,7 +449,9 @@ static std::string const c_genesisInfoSkaleTest = std::string() + "emptyBlockIntervalMs": -1, "correctForkInPowPatchTimestamp": 1, "nodes": [ - { "nodeID": 1112, "ip": "127.0.0.1", "owner": "0x0E7d7F1D34a502bD609542576941C3FCc087c588", "basePort": )E"+std::to_string( rand_port ) + R"E(, "schainIndex" : 1, "publicKey": "0xfa"} + { "nodeID": 1112, "ip": "127.0.0.1", "owner": "0x0E7d7F1D34a502bD609542576941C3FCc087c588", "basePort": )E" + + std::to_string( rand_port ) + + R"E(, "schainIndex" : 1, "publicKey": "0xfa"} ] } }, @@ -472,8 +474,9 @@ static std::string const c_genesisInfoSkaleTest = std::string() + } )E"; #else -static std::string const c_genesisInfoSkaleTest = std::string() + - R"E( +static std::string const c_genesisInfoSkaleTest = + std::string() + + R"E( { "sealEngine": "Ethash", "params": { @@ -513,8 +516,9 @@ static std::string const c_genesisInfoSkaleTest = std::string() + "nodeName": "Node1", "nodeID": 1112, "bindIP": "127.0.0.1", - "basePort": )E" + std::to_string( rand_port ) + - R"E(, + "basePort": )E" + + std::to_string( rand_port ) + + R"E(, "logLevel": "trace", "logLevelProposal": "trace", "testSignatures": true @@ -568,8 +572,8 @@ static std::string const c_genesisInfoSkaleTest = std::string() + "2": { "group": [ { "nodeID": 1112, "owner": "0x0E7d7F1D34a502bD609542576941C3FCc087c588", "ip": "127.0.0.1", "basePort": )E" + - std::to_string( rand_port ) + - R"E(, "ip6": "::1", "basePort6": 1231, "schainIndex" : 1, "publicKey" : "0xfa"} + std::to_string( rand_port ) + + R"E(, "ip6": "::1", "basePort6": 1231, "schainIndex" : 1, "publicKey" : "0xfa"} ] } } @@ -1041,7 +1045,8 @@ BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE( getHistoricNodesData ) #ifndef FAIR -static std::string const c_genesisInfoSkaleIMABLSPublicKeyTest = std::string() + R"E( +static std::string const c_genesisInfoSkaleIMABLSPublicKeyTest = + std::string() + R"E( { "sealEngine": "Ethash", "params": { @@ -1080,7 +1085,8 @@ static std::string const c_genesisInfoSkaleIMABLSPublicKeyTest = std::string() + "nodeName": "Node1", "nodeID": 1112, "bindIP": "127.0.0.1", - "basePort": )E" + std::to_string( rand_port ) + R"E(, + "basePort": )E" + + std::to_string( rand_port ) + R"E(, "logLevel": "trace", "logLevelProposal": "trace", "testSignatures": true @@ -1124,7 +1130,8 @@ static std::string const c_genesisInfoSkaleIMABLSPublicKeyTest = std::string() + } }, "nodes": [ - { "nodeID": 1112, "owner": "0x0E7d7F1D34a502bD609542576941C3FCc087c588", "ip": "127.0.0.1", "basePort": )E"+std::to_string( rand_port ) + R"E(, "schainIndex" : 1, "publicKey": "0xfa"} + { "nodeID": 1112, "owner": "0x0E7d7F1D34a502bD609542576941C3FCc087c588", "ip": "127.0.0.1", "basePort": )E" + + std::to_string( rand_port ) + R"E(, "schainIndex" : 1, "publicKey": "0xfa"} ] } }, @@ -1276,7 +1283,9 @@ BOOST_AUTO_TEST_CASE( initAndUpdateHistoricConfigFields ) { }; BOOST_REQUIRE( testClient->getCurrentBLSPublicKey() == imaBLSPublicKeyOnStartUp ); - BOOST_REQUIRE_EQUAL( testClient->getHistoricNodePublicKey( 0 ) , "0x3a581d62b12232dade30c3710215a271984841657449d1f474295a13737b778266f57e298f123ae80cbab7cc35ead1b62a387556f94b326d5c65d4a7aa2abcba" ); + BOOST_REQUIRE_EQUAL( testClient->getHistoricNodePublicKey( 0 ), + "0x3a581d62b12232dade30c3710215a271984841657449d1f474295a13737b778266f57e298f123ae80cbab7cc" + "35ead1b62a387556f94b326d5c65d4a7aa2abcba" ); BOOST_REQUIRE_EQUAL( testClient->getHistoricNodeId( 0 ), "26" ); BOOST_REQUIRE_EQUAL( testClient->getHistoricNodeIndex( 0 ), "3" ); @@ -1308,7 +1317,9 @@ BOOST_AUTO_TEST_CASE( initAndUpdateHistoricConfigFields ) { sleep( 3 ); BOOST_REQUIRE( testClient->getCurrentBLSPublicKey() == imaBLSPublicKeyAfterBlock ); - BOOST_REQUIRE_EQUAL( testClient->getHistoricNodePublicKey( 0 ), "0x6180cde2cbbcc6b6a17efec4503a7d4316f8612f411ee171587089f770335f484003ad236c534b9afa82befc1f69533723abdb6ec2601e582b72dcfd7919338b" ); + BOOST_REQUIRE_EQUAL( testClient->getHistoricNodePublicKey( 0 ), + "0x6180cde2cbbcc6b6a17efec4503a7d4316f8612f411ee171587089f770335f484003ad236c534b9afa82befc" + "1f69533723abdb6ec2601e582b72dcfd7919338b" ); BOOST_REQUIRE_EQUAL( testClient->getHistoricNodeId( 0 ), "30" ); BOOST_REQUIRE_EQUAL( testClient->getHistoricNodeIndex( 0 ), "0" ); } @@ -1347,7 +1358,8 @@ static std::string const c_skaleConfigString = "nodeName": "TestNode", "nodeID": 1112, "bindIP": "127.0.0.1", - "basePort": )E" + std::to_string( rand_port ) + R"E(, + "basePort": )E" + + std::to_string( rand_port ) + R"E(, "testSignatures": true }, "sChain": { @@ -1356,7 +1368,9 @@ static std::string const c_skaleConfigString = "snapshotIntervalSec": 5, "emptyBlockIntervalMs": 4000, "nodes": [ - { "nodeID": 1112, "owner": "0x0E7d7F1D34a502bD609542576941C3FCc087c588", "ip": "127.0.0.1", "basePort": )E"+std::to_string( rand_port ) + R"E(, "ip6": "::1", "basePort6": 1231, "schainIndex" : 1, "publicKey" : "0xfa"} + { "nodeID": 1112, "owner": "0x0E7d7F1D34a502bD609542576941C3FCc087c588", "ip": "127.0.0.1", "basePort": )E" + + std::to_string( rand_port ) + + R"E(, "ip6": "::1", "basePort6": 1231, "schainIndex" : 1, "publicKey" : "0xfa"} ] } }, @@ -1417,8 +1431,8 @@ static std::string const c_skaleConfigString = "1": { "group": [ { "nodeID": 1112, "owner": "0x0E7d7F1D34a502bD609542576941C3FCc087c588", "ip": "127.0.0.1", "basePort": )E" + - std::to_string( rand_port ) + - R"E(, "ip6": "::1", "basePort6": 1231, "schainIndex" : 1, "publicKey" : "0xfa"} + std::to_string( rand_port ) + + R"E(, "ip6": "::1", "basePort6": 1231, "schainIndex" : 1, "publicKey" : "0xfa"} ] }, "-1": {} diff --git a/test/unittests/libethereum/ExtVMTest.cpp b/test/unittests/libethereum/ExtVMTest.cpp index 548d30033..9ee4cab4c 100644 --- a/test/unittests/libethereum/ExtVMTest.cpp +++ b/test/unittests/libethereum/ExtVMTest.cpp @@ -27,8 +27,7 @@ using namespace dev; using namespace dev::eth; using namespace dev::test; -using skale:: -State; +using skale::State; class ExtVMConstantinopleFixTestFixture : public TestOutputHelperFixture { public: @@ -49,7 +48,7 @@ class ExtVMConstantinopleFixTestFixture : public TestOutputHelperFixture { } EnvInfo createEnvInfo( BlockHeader const& _header ) const { - return {_header, lastBlockHashes, 1, 0, blockchain.chainID()}; + return { _header, lastBlockHashes, 1, 0, blockchain.chainID() }; } NetworkSelector networkSelector; @@ -59,7 +58,7 @@ class ExtVMConstantinopleFixTestFixture : public TestOutputHelperFixture { BlockChain const& blockchain; h256 preExperimentalBlockHash; h256 experimentalBlockHash; - TestLastBlockHashes lastBlockHashes{{}}; + TestLastBlockHashes lastBlockHashes{ {} }; }; BOOST_FIXTURE_TEST_SUITE( ExtVmSuite, ExtVMConstantinopleFixTestFixture ) @@ -72,8 +71,8 @@ BOOST_AUTO_TEST_CASE( BlockhashOutOfBoundsRetunsZero, TestLastBlockHashes lastBlockHashes( {} ); EnvInfo envInfo( createEnvInfo( block.info() ) ); Address addr( "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" ); - ExtVM extVM( block.mutableState(), envInfo, blockchain.sealEngine()->chainParams(), addr, addr, addr, 0, 0, - {}, {}, {}, 0, 0, false, false ); + ExtVM extVM( block.mutableState(), envInfo, blockchain.sealEngine()->chainParams(), addr, addr, + addr, 0, 0, {}, {}, {}, 0, 0, false, false ); BOOST_CHECK_EQUAL( extVM.blockHash( 100 ), h256() ); } @@ -83,12 +82,13 @@ BOOST_AUTO_TEST_CASE( BlockhashBeforeConstantinopleReliesOnLastHashes, Block block = blockchain.genesisBlock( genesisState ); block.sync( blockchain ); - h256s lastHashes{h256( "0xaaabbbccc" ), h256( "0xdddeeefff" )}; + h256s lastHashes{ h256( "0xaaabbbccc" ), h256( "0xdddeeefff" ) }; TestLastBlockHashes lastBlockHashes( lastHashes ); - EnvInfo envInfo( block.info(), lastBlockHashes, block.info().timestamp(), 0, blockchain.chainID() ); + EnvInfo envInfo( + block.info(), lastBlockHashes, block.info().timestamp(), 0, blockchain.chainID() ); Address addr( "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" ); - ExtVM extVM( block.mutableState(), envInfo, blockchain.sealEngine()->chainParams(), addr, addr, addr, 0, 0, - {}, {}, {}, 0, 0, false, false ); + ExtVM extVM( block.mutableState(), envInfo, blockchain.sealEngine()->chainParams(), addr, addr, + addr, 0, 0, {}, {}, {}, 0, 0, false, false ); h256 hash = extVM.blockHash( 1 ); BOOST_REQUIRE_EQUAL( hash, lastHashes[0] ); } diff --git a/test/unittests/libethereum/GasPricer.cpp b/test/unittests/libethereum/GasPricer.cpp index 66dc3b9f6..d7fd73848 100644 --- a/test/unittests/libethereum/GasPricer.cpp +++ b/test/unittests/libethereum/GasPricer.cpp @@ -54,7 +54,8 @@ void executeGasPricerTest( string const& name, double _etherPrice, double _block "ASK Got: " + toString( gp.ask( Block( Block::Null ) ) ) + " Expected: " + toString( _expectedAsk ) ); BOOST_CHECK_MESSAGE( abs( gp.bid( dev::eth::LatestBlock, _txPrio ) - _expectedBid ) < 100000000, - "BID Got: " + toString( gp.bid( dev::eth::LatestBlock, _txPrio ) ) + " Expected: " + toString( _expectedBid ) ); + "BID Got: " + toString( gp.bid( dev::eth::LatestBlock, _txPrio ) ) + + " Expected: " + toString( _expectedBid ) ); } } // namespace test } // namespace dev @@ -72,8 +73,8 @@ BOOST_AUTO_TEST_CASE( trivialGasPricer ) { BOOST_CHECK_EQUAL( gp->bid(), DefaultGasPrice ); } -BOOST_AUTO_TEST_CASE( basicGasPricerNoUpdate, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + basicGasPricerNoUpdate, *boost::unit_test::precondition( dev::test::run_not_express ) ) { BasicGasPricer gp( u256( double( ether / 1000 ) / 30.679 ), u256( 15.0 * 1000 ) ); BOOST_CHECK_EQUAL( gp.ask( Block( Block::Null ) ), 103754996057 ); BOOST_CHECK_EQUAL( gp.bid(), 103754996057 ); diff --git a/test/unittests/libethereum/Genesis.cpp b/test/unittests/libethereum/Genesis.cpp index 33c6cafd4..2a12d03e6 100644 --- a/test/unittests/libethereum/Genesis.cpp +++ b/test/unittests/libethereum/Genesis.cpp @@ -43,8 +43,8 @@ namespace js = json_spirit; BOOST_FIXTURE_TEST_SUITE( BasicTests, TestOutputHelperFixture ) -BOOST_AUTO_TEST_CASE( emptySHA3Types, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + emptySHA3Types, *boost::unit_test::precondition( dev::test::run_not_express ) ) { h256 emptyListSHA3( fromHex( "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" ) ); BOOST_REQUIRE_EQUAL( emptyListSHA3, EmptyListSHA3 ); diff --git a/test/unittests/libethereum/InstanceMonitorTest.cpp b/test/unittests/libethereum/InstanceMonitorTest.cpp index 1f2da0351..bbeb98d4d 100644 --- a/test/unittests/libethereum/InstanceMonitorTest.cpp +++ b/test/unittests/libethereum/InstanceMonitorTest.cpp @@ -13,25 +13,19 @@ using namespace dev::test; namespace fs = boost::filesystem; -class InstanceMonitorMock: public InstanceMonitor { +class InstanceMonitorMock : public InstanceMonitor { public: - explicit InstanceMonitorMock(fs::path const &rotationFlagFilePath, std::shared_ptr statusAndControl) : InstanceMonitor(rotationFlagFilePath, statusAndControl) {}; + explicit InstanceMonitorMock( + fs::path const& rotationFlagFilePath, std::shared_ptr< StatusAndControl > statusAndControl ) + : InstanceMonitor( rotationFlagFilePath, statusAndControl ){}; - fs::path getRotationInfoFilePath() { - return this->rotationInfoFilePath(); - } + fs::path getRotationInfoFilePath() { return this->rotationInfoFilePath(); } - void createFlagFileTest(){ - this->reportExitTimeReached( true ); - } + void createFlagFileTest() { this->reportExitTimeReached( true ); } - void removeFlagFileTest(){ - this->reportExitTimeReached( false ); - } + void removeFlagFileTest() { this->reportExitTimeReached( false ); } - uint64_t getRotationTimestamp() const { - return this->rotationTimestamp(); - } + uint64_t getRotationTimestamp() const { return this->rotationTimestamp(); } }; class InstanceMonitorTestFixture : public TestOutputHelperFixture { @@ -39,29 +33,30 @@ class InstanceMonitorTestFixture : public TestOutputHelperFixture { fs::path rotationFlagDirPath = "test"; InstanceMonitorTestFixture() { - fs::create_directory(rotationFlagDirPath); + fs::create_directory( rotationFlagDirPath ); - statusAndControlFile = std::make_shared(rotationFlagDirPath); - instanceMonitor = std::make_shared< InstanceMonitorMock >(rotationFlagDirPath, statusAndControlFile); + statusAndControlFile = std::make_shared< StatusAndControlFile >( rotationFlagDirPath ); + instanceMonitor = + std::make_shared< InstanceMonitorMock >( rotationFlagDirPath, statusAndControlFile ); rotationFilePath = instanceMonitor->getRotationInfoFilePath(); } - std::shared_ptr statusAndControlFile; + std::shared_ptr< StatusAndControl > statusAndControlFile; std::shared_ptr< InstanceMonitorMock > instanceMonitor; fs::path rotationFilePath; ~InstanceMonitorTestFixture() override { instanceMonitor.reset(); statusAndControlFile.reset(); - if (fs::exists(rotationFilePath)) { - fs::remove(rotationFilePath); + if ( fs::exists( rotationFilePath ) ) { + fs::remove( rotationFilePath ); } - if (fs::exists(rotationFlagDirPath/"skaled.status")) { - fs::remove(rotationFlagDirPath/"skaled.status"); + if ( fs::exists( rotationFlagDirPath / "skaled.status" ) ) { + fs::remove( rotationFlagDirPath / "skaled.status" ); } - if (fs::exists(rotationFlagDirPath)) { - fs::remove(rotationFlagDirPath); + if ( fs::exists( rotationFlagDirPath ) ) { + fs::remove( rotationFlagDirPath ); } }; }; @@ -70,22 +65,22 @@ BOOST_FIXTURE_TEST_SUITE( InstanceMonitorSuite, InstanceMonitorTestFixture ) BOOST_AUTO_TEST_CASE( test_initRotationParams ) { uint64_t ts = 100; - BOOST_REQUIRE( !fs::exists(instanceMonitor->getRotationInfoFilePath() ) ); - instanceMonitor->initRotationParams(ts); - BOOST_CHECK_EQUAL(instanceMonitor->getRotationTimestamp(), ts); + BOOST_REQUIRE( !fs::exists( instanceMonitor->getRotationInfoFilePath() ) ); + instanceMonitor->initRotationParams( ts ); + BOOST_CHECK_EQUAL( instanceMonitor->getRotationTimestamp(), ts ); - BOOST_REQUIRE( fs::exists(instanceMonitor->getRotationInfoFilePath() ) ); + BOOST_REQUIRE( fs::exists( instanceMonitor->getRotationInfoFilePath() ) ); - std::ifstream rotateFile(instanceMonitor->getRotationInfoFilePath().string() ); + std::ifstream rotateFile( instanceMonitor->getRotationInfoFilePath().string() ); auto rotateJson = nlohmann::json::parse( rotateFile ); - BOOST_CHECK_EQUAL(rotateJson["timestamp"].get< uint64_t >(), ts); + BOOST_CHECK_EQUAL( rotateJson["timestamp"].get< uint64_t >(), ts ); } BOOST_AUTO_TEST_CASE( test_isTimeToRotate_invalid_file ) { uint64_t currentTime = 100; - std::ofstream rotationInfoFile(instanceMonitor->getRotationInfoFilePath().string() ); + std::ofstream rotationInfoFile( instanceMonitor->getRotationInfoFilePath().string() ); rotationInfoFile << "Broken file"; BOOST_REQUIRE( !instanceMonitor->isTimeToRotate( currentTime ) ); } @@ -95,7 +90,7 @@ BOOST_AUTO_TEST_CASE( test_isTimeToRotate_false ) { uint64_t currentTime = 100; uint64_t finishTime = 200; BOOST_REQUIRE( !instanceMonitor->isTimeToRotate( currentTime ) ); - instanceMonitor->initRotationParams(finishTime); + instanceMonitor->initRotationParams( finishTime ); BOOST_REQUIRE( !instanceMonitor->isTimeToRotate( currentTime ) ); } @@ -104,10 +99,10 @@ BOOST_AUTO_TEST_CASE( test_isTimeToRotate_true ) { BOOST_REQUIRE( !instanceMonitor->isTimeToRotate( currentTime ) ); - instanceMonitor->initRotationParams(100); + instanceMonitor->initRotationParams( 100 ); BOOST_REQUIRE( instanceMonitor->isTimeToRotate( currentTime ) ); - instanceMonitor->initRotationParams(50); + instanceMonitor->initRotationParams( 50 ); BOOST_REQUIRE( instanceMonitor->isTimeToRotate( currentTime ) ); currentTime = 49; @@ -115,20 +110,20 @@ BOOST_AUTO_TEST_CASE( test_isTimeToRotate_true ) { } BOOST_AUTO_TEST_CASE( test_rotation ) { - instanceMonitor->initRotationParams(0); - instanceMonitor->prepareRotation(); + instanceMonitor->initRotationParams( 0 ); + instanceMonitor->prepareRotation(); - BOOST_REQUIRE( statusAndControlFile->getExitState(StatusAndControl::ExitTimeReached) ); - BOOST_REQUIRE( !( fs::exists(instanceMonitor->getRotationInfoFilePath() ) ) ); + BOOST_REQUIRE( statusAndControlFile->getExitState( StatusAndControl::ExitTimeReached ) ); + BOOST_REQUIRE( !( fs::exists( instanceMonitor->getRotationInfoFilePath() ) ) ); } BOOST_AUTO_TEST_CASE( test_create_remove_flag_file ) { instanceMonitor->createFlagFileTest(); - BOOST_REQUIRE( statusAndControlFile->getExitState(StatusAndControl::ExitTimeReached) ); + BOOST_REQUIRE( statusAndControlFile->getExitState( StatusAndControl::ExitTimeReached ) ); instanceMonitor->removeFlagFileTest(); - BOOST_REQUIRE( !( fs::exists(instanceMonitor->getRotationInfoFilePath() ) ) ); - BOOST_REQUIRE( !statusAndControlFile->getExitState(StatusAndControl::ExitTimeReached) ); + BOOST_REQUIRE( !( fs::exists( instanceMonitor->getRotationInfoFilePath() ) ) ); + BOOST_REQUIRE( !statusAndControlFile->getExitState( StatusAndControl::ExitTimeReached ) ); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/unittests/libethereum/SkaleHost.cpp b/test/unittests/libethereum/SkaleHost.cpp index f96cab1a9..6b897243d 100644 --- a/test/unittests/libethereum/SkaleHost.cpp +++ b/test/unittests/libethereum/SkaleHost.cpp @@ -43,9 +43,9 @@ #include #include -#include #include #include +#include using namespace dev; using namespace dev::eth; @@ -64,7 +64,7 @@ class MockRotationSkaleHost : public SkaleHost { void runCommitteeRotationForConsensus() override { ++rotationCallCount; } - std::atomic< uint32_t > rotationCallCount{0}; + std::atomic< uint32_t > rotationCallCount{ 0 }; }; #endif @@ -170,8 +170,8 @@ class ConsensusTestStubFactory : public ConsensusFactory { // TODO Do not copy&paste from JsonRpcFixture struct SkaleHostFixture : public TestOutputHelperFixture { - SkaleHostFixture( const std::map< std::string, std::string >& params = - std::map< std::string, std::string >(), + SkaleHostFixture( + const std::map< std::string, std::string >& params = std::map< std::string, std::string >(), bool mockCommitteeRotation = false ) { dev::p2p::NetworkPreferences nprefs; libBLS::init(); @@ -235,7 +235,8 @@ struct SkaleHostFixture : public TestOutputHelperFixture { ConsensusTestStubFactory test_stub_factory; #ifdef FAIR if ( mockCommitteeRotation ) { - auto mockHost = std::make_shared< MockRotationSkaleHost >( *client, &test_stub_factory ); + auto mockHost = + std::make_shared< MockRotationSkaleHost >( *client, &test_stub_factory ); skaleHost = mockHost; mockRotationHost = mockHost; } else @@ -1657,7 +1658,7 @@ BOOST_AUTO_TEST_CASE( getBlockRandom ) { dev::h256::random(), dev::ZeroAddress, #endif - true } ); + true } ); u256 blockRandom = skaleHost->getBlockRandom( 0, false ); BOOST_REQUIRE( res.first ); BOOST_REQUIRE( res.second == toBigEndian( static_cast< u256 >( blockRandom ) ) ); @@ -2567,7 +2568,7 @@ BOOST_AUTO_TEST_CASE( biteTransactions ) { #endif #ifdef FAIR -BOOST_AUTO_TEST_CASE(syncNodeGroupsUpdatesEpochIdWithoutRotation) { +BOOST_AUTO_TEST_CASE( syncNodeGroupsUpdatesEpochIdWithoutRotation ) { SkaleHostFixture fixture( {}, true ); auto& client = fixture.client; @@ -2575,40 +2576,29 @@ BOOST_AUTO_TEST_CASE(syncNodeGroupsUpdatesEpochIdWithoutRotation) { uint64_t currentTimestamp = static_cast< uint64_t >( utcTime() ); - fixture.overwriteHistoricNodeGroups( { - { - { - GroupNode{ u256( 0 ), u256( 8 ), - "0xf925c203a30ec6cad5a263db3efab7ed4c1fd74c8688167e10a5a22e15ab5018d8553df0ac54ea" - "10" - "5a3d21845e5660bc3d4e7c82e7af1daa3baad393b1521467", - Address( "0x08151B8F80bfa7dEa760e461412AF24348224edf" ) - } - }, - currentTimestamp, - { - "15959969554621958245201075983340071881770733084910870228938077786643587385029", - "7970122607051572307517094692346020360016825923464107614135327251488152616550", - "3371162264373897025322009434717052197952692496405149486989861571246537813591", - "13678625751515504401110635369790787716744686498431213713911601759809559919693" } - }, - { - { - GroupNode{ u256( 0 ), u256( 8 ), - "0xf925c203a30ec6cad5a263db3efab7ed4c1fd74c8688167e10a5a22e15ab5018d8553df0ac54ea" - "10" - "5a3d21845e5660bc3d4e7c82e7af1daa3baad393b1521467", - Address( "0x08151B8F80bfa7dEa760e461412AF24348224edf" ) - } - }, - std::numeric_limits::max(), { - "3842742177969966091367527274107524613106077736353521259727282251005583743182", - "3497912824016228906558906422247670474553186446469877598411863912329082553081", - "8173996886448941320370434854289578123609627835954133538412363037981850950343", - "20979370720689475348670582375026949105497642726992863932315517524004804784155" - } - } - }); + fixture.overwriteHistoricNodeGroups( + { { { GroupNode{ u256( 0 ), u256( 8 ), + "0xf925c203a30ec6cad5a263db3efab7ed4c1fd74c8688167e10a5a22e15ab5018d8553df0ac54ea" + "10" + "5a3d21845e5660bc3d4e7c82e7af1daa3baad393b1521467", + Address( "0x08151B8F80bfa7dEa760e461412AF24348224edf" ) } }, + currentTimestamp, + { "15959969554621958245201075983340071881770733084910870228938077786643587385029", + "7970122607051572307517094692346020360016825923464107614135327251488152616550", + "3371162264373897025322009434717052197952692496405149486989861571246537813591", + "1367862575151550440111063536979078771674468649843121371391160175980955991969" + "3" } }, + { { GroupNode{ u256( 0 ), u256( 8 ), + "0xf925c203a30ec6cad5a263db3efab7ed4c1fd74c8688167e10a5a22e15ab5018d8553df0ac54ea" + "10" + "5a3d21845e5660bc3d4e7c82e7af1daa3baad393b1521467", + Address( "0x08151B8F80bfa7dEa760e461412AF24348224edf" ) } }, + std::numeric_limits< uint64_t >::max(), + { "3842742177969966091367527274107524613106077736353521259727282251005583743182", + "3497912824016228906558906422247670474553186446469877598411863912329082553081", + "8173996886448941320370434854289578123609627835954133538412363037981850950343", + "2097937072068947534867058237502694910549764272699286393231551752400480478415" + "5" } } } ); BOOST_REQUIRE_EQUAL( client->getCurrentEpochId(), 0 ); @@ -2619,12 +2609,10 @@ BOOST_AUTO_TEST_CASE(syncNodeGroupsUpdatesEpochIdWithoutRotation) { ConsensusExtFace::Transactions{}, #ifdef BITE DecryptedTransactions{ -#ifdef BITE std::make_shared< DecryptedCTXTxsMap >(), -#endif // BITE std::make_shared< DecryptedRegularTxsMap >() }, -#endif +#endif // BITE blockTimestamp, blockId ) ); BOOST_REQUIRE_EQUAL( client->getCurrentEpochId(), 1 ); diff --git a/test/unittests/libethereum/StateUnitTests.cpp b/test/unittests/libethereum/StateUnitTests.cpp index 97ac8594d..d3f2cdc96 100644 --- a/test/unittests/libethereum/StateUnitTests.cpp +++ b/test/unittests/libethereum/StateUnitTests.cpp @@ -25,10 +25,10 @@ #include #include #include -#include -#include #include #include +#include +#include #include @@ -226,9 +226,9 @@ class DbRotationFixture : public TestOutputHelperFixture { TransientDirectory m_tempDirState; State state = State( 0, m_tempDirState.path(), h256{}, BaseState::Empty, 0, #ifndef FAIR - 32, + 32, #endif - 1 ); + 1 ); Address address1{ 1 }, address2{ 2 }; size_t countStateDbPieces() { diff --git a/test/unittests/libethereum/TransactionQueue.cpp b/test/unittests/libethereum/TransactionQueue.cpp index 00ebc94c5..32b0e93f6 100644 --- a/test/unittests/libethereum/TransactionQueue.cpp +++ b/test/unittests/libethereum/TransactionQueue.cpp @@ -126,11 +126,11 @@ BOOST_AUTO_TEST_CASE( tqPriority ) { txq.drop( tx0.sha3() ); // prev BOOST_CHECK( ( Transactions{tx2, tx1, tx3, tx5, tx4} ) == txq.topTransactions( 256 ) ); // now tx4 has nonce increase 1, and goes lower then tx5 and tx3 - BOOST_CHECK( ( Transactions{tx2, tx1, tx4, tx3, tx5} ) == txq.topTransactions( 256 ) ); + BOOST_CHECK( ( Transactions{ tx2, tx1, tx4, tx3, tx5 } ) == txq.topTransactions( 256 ) ); txq.drop( tx1.sha3() ); - BOOST_CHECK( ( Transactions{tx2, tx4, tx3, tx5} ) == txq.topTransactions( 256 ) ); + BOOST_CHECK( ( Transactions{ tx2, tx4, tx3, tx5 } ) == txq.topTransactions( 256 ) ); txq.drop( tx5.sha3() ); - BOOST_CHECK( ( Transactions{tx2, tx4, tx3} ) == txq.topTransactions( 256 ) ); + BOOST_CHECK( ( Transactions{ tx2, tx4, tx3 } ) == txq.topTransactions( 256 ) ); Transaction tx6( 0, gasCostMed, gas, dest, bytes(), 20, sender1 ); importCurrent( txq, tx6 ); @@ -139,7 +139,7 @@ BOOST_AUTO_TEST_CASE( tqPriority ) { Transaction tx7( 0, gasCostHigh, gas, dest, bytes(), 2, sender2 ); importCurrent( txq, tx7 ); // deterministic signature: hash of tx5 and tx7 will be same - BOOST_CHECK( ( Transactions{tx2, tx4, tx3, tx6} ) == txq.topTransactions( 256 ) ); + BOOST_CHECK( ( Transactions{ tx2, tx4, tx3, tx6 } ) == txq.topTransactions( 256 ) ); } BOOST_AUTO_TEST_CASE( tqNonceChange ) { @@ -150,7 +150,6 @@ BOOST_AUTO_TEST_CASE( tqNonceChange ) { Address dest = Address( "0x095e7baea6a6c7c4c2dfeb977efac326af552d87" ); Secret sender1 = Secret( "0x3333333333333333333333333333333333333333333333333333333333333333" ); Secret sender2 = Secret( "0x4444444444444444444444444444444444444444444444444444444444444444" ); - Transaction tx10( 0, gasCost, gas, dest, bytes(), 0, sender1 ); Transaction tx11( 0, gasCost, gas, dest, bytes(), 1, sender1 ); Transaction tx12( 0, gasCost, gas, dest, bytes(), 2, sender1 ); @@ -177,20 +176,18 @@ BOOST_AUTO_TEST_CASE( tqNonceChange ) { // 3 insert tx with height = 3-2=1 importCurrent( txq, tx23 ); // h = 1 => goes with tx11 - Transactions top6 = txq.topTransactions(6); - for(auto tx: top6){ + Transactions top6 = txq.topTransactions( 6 ); + for ( auto tx : top6 ) { std::cout << tx.from() << " " << tx.nonce() << std::endl; } // expected BAD result [tx10], [tx11, tx23], [tx12, tx22], [tx13] !!! - // prev without sort BOOST_REQUIRE( ( Transactions{tx10, tx11, tx22, tx23, tx12, tx13 } ) == top6 ); - // with sort: - BOOST_REQUIRE( ( Transactions{tx10, tx22, tx11, tx23, tx12, tx13 } ) == top6 ); + // prev without sort BOOST_REQUIRE( ( Transactions{tx10, tx11, tx22, tx23, tx12, tx13 } ) == + // top6 ); with sort: + BOOST_REQUIRE( ( Transactions{ tx10, tx22, tx11, tx23, tx12, tx13 } ) == top6 ); } BOOST_AUTO_TEST_CASE( tqFuture ) { dev::eth::TransactionQueue txq; - - // from a94f5374fce5edbc8e2a8697c15331677e6ebf0b const u256 gasCostMed = 20 * szabo; const u256 gas = 25000; Address dest = Address( "0x095e7baea6a6c7c4c2dfeb977efac326af552d87" ); @@ -209,7 +206,7 @@ BOOST_AUTO_TEST_CASE( tqFuture ) { BOOST_CHECK( ( Transactions{tx0, tx1, tx2, tx3, tx4} ) == txq.topTransactions( 256 ) ); txq.setFuture( tx2.sha3() ); - BOOST_CHECK( ( Transactions{tx0, tx1} ) == txq.topTransactions( 256 ) ); + BOOST_CHECK( ( Transactions{ tx0, tx1 } ) == txq.topTransactions( 256 ) ); // TODO disabled it temporarily!! // Transaction tx2_2( 1, gasCostMed, gas, dest, bytes(), 2, sender ); @@ -376,7 +373,7 @@ BOOST_AUTO_TEST_CASE( tqImport ) { ir = importCurrent( tq, testTransaction.transaction().toBytes() ); BOOST_REQUIRE( ir == ImportResult::AlreadyKnown ); - + bytes rlp = testTransaction.transaction().toBytes(); rlp.at( 0 ) = 03; ir = tq.import( rlp, IfDropped::Ignore, false, 0 ); @@ -417,11 +414,11 @@ BOOST_AUTO_TEST_CASE( tqImportFuture ) { TransactionQueue::Status status = tq.status(); BOOST_REQUIRE( status.future == 0 ); - TestTransaction tx1 = TestTransaction::defaultTransaction(4); + TestTransaction tx1 = TestTransaction::defaultTransaction( 4 ); Address sender = tx1.transaction().sender(); - u256 maxNonce = tq.maxNonce(sender); + u256 maxNonce = tq.maxNonce( sender ); BOOST_REQUIRE( maxNonce == 0 ); - u256 waiting = tq.waiting(sender); + u256 waiting = tq.waiting( sender ); BOOST_REQUIRE( waiting == 0 ); ImportResult ir1 = tq.import( tx1.transaction().toBytes(), IfDropped::Ignore, true, 0 ); @@ -430,9 +427,9 @@ BOOST_AUTO_TEST_CASE( tqImportFuture ) { BOOST_REQUIRE( known.size() == 1 ); status = tq.status(); BOOST_REQUIRE( status.future == 1 ); - maxNonce = tq.maxNonce(sender); + maxNonce = tq.maxNonce( sender ); BOOST_REQUIRE( maxNonce == 5 ); - waiting = tq.waiting(sender); + waiting = tq.waiting( sender ); BOOST_REQUIRE( waiting == 1 ); // HACK it's now allowed to repeat future transaction @@ -442,11 +439,11 @@ BOOST_AUTO_TEST_CASE( tqImportFuture ) { BOOST_REQUIRE( known.size() == 1 ); status = tq.status(); BOOST_REQUIRE( status.future == 1 ); - maxNonce = tq.maxNonce(sender); + maxNonce = tq.maxNonce( sender ); BOOST_REQUIRE( maxNonce == 5 ); - waiting = tq.waiting(sender); + waiting = tq.waiting( sender ); BOOST_REQUIRE( waiting == 1 ); - + bytes rlp = tx1.transaction().toBytes(); rlp.at( 0 ) = 03; ir1 = tq.import( rlp, IfDropped::Ignore, true, 0 ); @@ -457,9 +454,9 @@ BOOST_AUTO_TEST_CASE( tqImportFuture ) { BOOST_REQUIRE( ir2 == ImportResult::Success ); known = tq.knownTransactions(); BOOST_REQUIRE( known.size() == 2 ); - maxNonce = tq.maxNonce(sender); + maxNonce = tq.maxNonce( sender ); BOOST_REQUIRE( maxNonce == 5 ); - waiting = tq.waiting(sender); + waiting = tq.waiting( sender ); BOOST_REQUIRE( waiting == 2 ); BOOST_CHECK( ( Transactions{} ) == tq.topTransactions( 256 ) ); @@ -468,9 +465,9 @@ BOOST_AUTO_TEST_CASE( tqImportFuture ) { BOOST_REQUIRE( ir3 == ImportResult::Success ); known = tq.knownTransactions(); BOOST_REQUIRE( known.size() == 3 ); - maxNonce = tq.maxNonce(sender); + maxNonce = tq.maxNonce( sender ); BOOST_REQUIRE( maxNonce == 5 ); - waiting = tq.waiting(sender); + waiting = tq.waiting( sender ); BOOST_REQUIRE( waiting == 3 ); BOOST_CHECK( ( Transactions{} ) == tq.topTransactions( 256 ) ); @@ -479,28 +476,30 @@ BOOST_AUTO_TEST_CASE( tqImportFuture ) { BOOST_REQUIRE( ir4 == ImportResult::Success ); known = tq.knownTransactions(); BOOST_REQUIRE( known.size() == 4 ); - maxNonce = tq.maxNonce(sender); + maxNonce = tq.maxNonce( sender ); BOOST_REQUIRE( maxNonce == 5 ); - waiting = tq.waiting(sender); + waiting = tq.waiting( sender ); BOOST_REQUIRE( waiting == 4 ); status = tq.status(); BOOST_REQUIRE( status.future == 1 ); BOOST_REQUIRE( status.current == 3 ); - BOOST_CHECK( ( Transactions{ tx4.transaction(), tx3.transaction(), tx2.transaction() } ) == tq.topTransactions( 256 ) ); + BOOST_CHECK( ( Transactions{ tx4.transaction(), tx3.transaction(), tx2.transaction() } ) == + tq.topTransactions( 256 ) ); TestTransaction tx5 = TestTransaction::defaultTransaction(3); ImportResult ir5 = importCurrent( tq, tx5.transaction().toBytes() ); BOOST_REQUIRE( ir5 == ImportResult::Success ); known = tq.knownTransactions(); BOOST_REQUIRE( known.size() == 5 ); - maxNonce = tq.maxNonce(sender); + maxNonce = tq.maxNonce( sender ); BOOST_REQUIRE( maxNonce == 5 ); - waiting = tq.waiting(sender); + waiting = tq.waiting( sender ); BOOST_REQUIRE( waiting == 5 ); status = tq.status(); BOOST_REQUIRE( status.future == 0 ); BOOST_REQUIRE( status.current == 5 ); - BOOST_CHECK( ( Transactions{ tx4.transaction(), tx3.transaction(), tx2.transaction(), tx5.transaction(), tx1.transaction() } ) == tq.topTransactions( 256 ) ); + BOOST_CHECK( ( Transactions{ tx4.transaction(), tx3.transaction(), tx2.transaction(), + tx5.transaction(), tx1.transaction() } ) == tq.topTransactions( 256 ) ); const u256 gasCostMed = 20 * szabo; const u256 gas = 25000; @@ -509,7 +508,7 @@ BOOST_AUTO_TEST_CASE( tqImportFuture ) { Transaction tx0( 0, gasCostMed, gas, dest, bytes(), 4, sender2 ); ImportResult ir0 = tq.import( tx0, IfDropped::Ignore, true, 0 ); BOOST_REQUIRE( ir0 == ImportResult::Success ); - waiting = tq.waiting(dev::toAddress(sender2)); + waiting = tq.waiting( dev::toAddress( sender2 ) ); BOOST_REQUIRE( waiting == 1 ); status = tq.status(); BOOST_REQUIRE( status.future == 1 ); @@ -518,7 +517,7 @@ BOOST_AUTO_TEST_CASE( tqImportFuture ) { BOOST_AUTO_TEST_CASE( dropFromFutureToCurrent ) { TransactionQueue tq; - TestTransaction tx1 = TestTransaction::defaultTransaction(1); + TestTransaction tx1 = TestTransaction::defaultTransaction( 1 ); // put transaction to future ImportResult ir1 = tq.import( tx1.transaction().toBytes(), IfDropped::Ignore, true, 0 ); @@ -562,7 +561,7 @@ BOOST_AUTO_TEST_CASE( tqImportFutureLimits ) { TestTransaction tx2 = TestTransaction::defaultTransaction(2); tq.import( tx2.transaction().toBytes(), IfDropped::Ignore, true, 0 ); - auto waiting = tq.waiting(tx1.transaction().sender()); + auto waiting = tq.waiting( tx1.transaction().sender() ); BOOST_REQUIRE( waiting == 2 ); auto known = tq.knownTransactions(); BOOST_REQUIRE( known.size() == 2 ); @@ -571,7 +570,7 @@ BOOST_AUTO_TEST_CASE( tqImportFutureLimits ) { ImportResult ir = tq.import( tx3.transaction().toBytes(), IfDropped::Ignore, true, 0 ); BOOST_REQUIRE( ir == ImportResult::QueueIsFull ); - waiting = tq.waiting(tx1.transaction().sender()); + waiting = tq.waiting( tx1.transaction().sender() ); BOOST_REQUIRE( waiting == 2 ); known = tq.knownTransactions(); BOOST_REQUIRE( known.size() == 2 ); @@ -584,12 +583,12 @@ BOOST_AUTO_TEST_CASE( tqImportFutureLimits2 ) { TestTransaction tx1 = TestTransaction::defaultTransaction(3); tq.import( tx1.transaction().toBytes(), IfDropped::Ignore, true, 0 ); - auto waiting = tq.waiting(tx1.transaction().sender()); + auto waiting = tq.waiting( tx1.transaction().sender() ); BOOST_REQUIRE( waiting == 1 ); auto known = tq.knownTransactions(); BOOST_REQUIRE( known.size() == 1 ); auto status = tq.status(); - BOOST_REQUIRE( status.future == 1 ); + BOOST_REQUIRE( status.future == 1 ); const u256 gasCostMed = 20 * szabo; const u256 gas = 25000; @@ -599,7 +598,7 @@ BOOST_AUTO_TEST_CASE( tqImportFutureLimits2 ) { ImportResult ir0 = tq.import( tx0, IfDropped::Ignore, true, 0 ); BOOST_REQUIRE( ir0 == ImportResult::Success ); - waiting = tq.waiting(tx1.transaction().sender()); + waiting = tq.waiting( tx1.transaction().sender() ); BOOST_REQUIRE( waiting == 1 ); waiting = tq.waiting(toAddress(sender2)); BOOST_REQUIRE( waiting == 1 ); @@ -675,8 +674,9 @@ BOOST_AUTO_TEST_CASE( tqLimit ) { BOOST_AUTO_TEST_CASE( tqLimitBytes ) { TransactionQueue tq( 100, 100, 250, 250 ); - - unsigned maxTxCount = 250 / TestTransaction::defaultTransaction( 1 ).transaction().toBytes().size(); + + unsigned maxTxCount = + 250 / TestTransaction::defaultTransaction( 1 ).transaction().toBytes().size(); TestTransaction testTransaction = TestTransaction::defaultTransaction( 2 ); ImportResult res = tq.import( testTransaction.transaction(), IfDropped::Ignore, true, 0 ); @@ -699,7 +699,7 @@ BOOST_AUTO_TEST_CASE( tqLimitBytes ) { BOOST_REQUIRE( tq.status().future == maxTxCount ); for ( size_t i = 1; i < 10; i++ ) { - if (i == 2 || i == 3) + if ( i == 2 || i == 3 ) continue; testTransaction = TestTransaction::defaultTransaction( i ); res = importCurrent( tq, testTransaction.transaction() ); @@ -713,7 +713,7 @@ BOOST_AUTO_TEST_CASE( tqLimitBytes ) { BOOST_AUTO_TEST_CASE( tqEqueue ) { TransactionQueue tq; TestTransaction testTransaction = TestTransaction::defaultTransaction(); - + bytes payloadToDecode = testTransaction.transaction().toBytes(); RLPStream rlpStream( 2 ); diff --git a/test/unittests/libevm/VMTest.cpp b/test/unittests/libevm/VMTest.cpp index 03369fd3d..fb916bdd2 100644 --- a/test/unittests/libevm/VMTest.cpp +++ b/test/unittests/libevm/VMTest.cpp @@ -17,8 +17,8 @@ along with cpp-ethereum. If not, see . */ -#include #include +#include #include #include #include @@ -51,7 +51,9 @@ BlockHeader initBlockHeader() { class Create2TestFixture : public TestOutputHelperFixture { public: - explicit Create2TestFixture( VMFace* _vm ) : vm{_vm} { state.addBalance( address, 1 * ether ); } + explicit Create2TestFixture( VMFace* _vm ) : vm{ _vm } { + state.addBalance( address, 1 * ether ); + } virtual ~Create2TestFixture() { resetSchainPatchToDefault(); } @@ -85,7 +87,7 @@ class Create2TestFixture : public TestOutputHelperFixture { } void testCreate2doesntChangeContractIfAddressExists() { - state.setCode( expectedAddress, bytes{inputData}, 0 ); + state.setCode( expectedAddress, bytes{ inputData }, 0 ); ExtVM extVm( state, envInfo, se->chainParams(), address, address, address, value, gasPrice, ref( inputData ), ref( code ), sha3( code ), version, depth, isCreate, staticCall ); @@ -264,14 +266,15 @@ class Create2TestFixture : public TestOutputHelperFixture { } - BlockHeader blockHeader{initBlockHeader()}; + BlockHeader blockHeader{ initBlockHeader() }; LastBlockHashes lastBlockHashes; - Address address{KeyPair::create().address()}; + Address address{ KeyPair::create().address() }; // State state{0}; - State state = State(0).createStateCopyAndClearCaches(); + State state = State( 0 ).createStateCopyAndClearCaches(); std::unique_ptr< SealEngineFace > se{ - ChainParams( genesisInfo( Network::ConstantinopleTest ) ).createSealEngine()}; - EnvInfo envInfo{blockHeader, lastBlockHashes, 1, 0, se->chainParams().getChainId()}; + ChainParams( genesisInfo( Network::ConstantinopleTest ) ).createSealEngine() + }; + EnvInfo envInfo{ blockHeader, lastBlockHashes, 1, 0, se->chainParams().getChainId() }; u256 value = 0; u256 gasPrice = 1; @@ -299,20 +302,20 @@ class Create2TestFixture : public TestOutputHelperFixture { class LegacyVMCreate2TestFixture : public Create2TestFixture { public: - LegacyVMCreate2TestFixture() : Create2TestFixture{new LegacyVM} {} + LegacyVMCreate2TestFixture() : Create2TestFixture{ new LegacyVM } {} }; class SkaleInterpreterCreate2TestFixture : public Create2TestFixture { public: SkaleInterpreterCreate2TestFixture() - : Create2TestFixture{new EVMC{evmc_create_interpreter()}} {} + : Create2TestFixture{ new EVMC{ evmc_create_interpreter() } } {} }; class ExtcodehashTestFixture : public TestOutputHelperFixture { public: - explicit ExtcodehashTestFixture( VMFace* _vm ) : vm{_vm} { + explicit ExtcodehashTestFixture( VMFace* _vm ) : vm{ _vm } { state.addBalance( address, 1 * ether ); - state.setCode( extAddress, bytes{extCode}, 0 ); + state.setCode( extAddress, bytes{ extCode }, 0 ); } void testExtcodehashWorksInConstantinople() { @@ -360,7 +363,7 @@ class ExtcodehashTestFixture : public TestOutputHelperFixture { } void testExtCodeHashOfNonContractAccount() { - Address addressWithEmptyCode{KeyPair::create().address()}; + Address addressWithEmptyCode{ KeyPair::create().address() }; state.addBalance( addressWithEmptyCode, 1 * ether ); ExtVM extVm( state, envInfo, se->chainParams(), address, address, address, value, gasPrice, @@ -374,7 +377,7 @@ class ExtcodehashTestFixture : public TestOutputHelperFixture { } void testExtCodeHashOfNonExistentAccount() { - Address addressNonExisting{0x1234}; + Address addressNonExisting{ 0x1234 }; ExtVM extVm( state, envInfo, se->chainParams(), address, address, address, value, gasPrice, addressNonExisting.ref(), ref( code ), sha3( code ), version, depth, isCreate, @@ -386,7 +389,7 @@ class ExtcodehashTestFixture : public TestOutputHelperFixture { } void testExtCodeHashOfPrecomileZeroBalance() { - Address addressPrecompile{0x1}; + Address addressPrecompile{ 0x1 }; ExtVM extVm( state, envInfo, se->chainParams(), address, address, address, value, gasPrice, addressPrecompile.ref(), ref( code ), sha3( code ), version, depth, isCreate, @@ -398,7 +401,7 @@ class ExtcodehashTestFixture : public TestOutputHelperFixture { } void testExtCodeHashOfPrecomileNonZeroBalance() { - Address addressPrecompile{0x1}; + Address addressPrecompile{ 0x1 }; state.addBalance( addressPrecompile, 1 * ether ); ExtVM extVm( state, envInfo, se->chainParams(), address, address, address, value, gasPrice, @@ -420,7 +423,7 @@ class ExtcodehashTestFixture : public TestOutputHelperFixture { code = fromHex( "60206000600037600051803f8060005260206000f35050" ); bytes extAddressPrefixed = - bytes{1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc} + extAddress.ref(); + bytes{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc } + extAddress.ref(); ExtVM extVm( state, envInfo, se->chainParams(), address, address, address, value, gasPrice, ref( extAddressPrefixed ), ref( code ), sha3( code ), version, depth, isCreate, @@ -431,14 +434,15 @@ class ExtcodehashTestFixture : public TestOutputHelperFixture { BOOST_REQUIRE( ret.toBytes() == sha3( extCode ).asBytes() ); } - BlockHeader blockHeader{initBlockHeader()}; + BlockHeader blockHeader{ initBlockHeader() }; LastBlockHashes lastBlockHashes; - Address address{KeyPair::create().address()}; - Address extAddress{KeyPair::create().address()}; - State state{0}; + Address address{ KeyPair::create().address() }; + Address extAddress{ KeyPair::create().address() }; + State state{ 0 }; std::unique_ptr< SealEngineFace > se{ - ChainParams( genesisInfo( Network::ConstantinopleTest ) ).createSealEngine()}; - EnvInfo envInfo{blockHeader, lastBlockHashes, 1, 0, se->chainParams().getChainId()}; + ChainParams( genesisInfo( Network::ConstantinopleTest ) ).createSealEngine() + }; + EnvInfo envInfo{ blockHeader, lastBlockHashes, 1, 0, se->chainParams().getChainId() }; u256 value = 0; u256 gasPrice = 1; @@ -464,24 +468,24 @@ class ExtcodehashTestFixture : public TestOutputHelperFixture { class LegacyVMExtcodehashTestFixture : public ExtcodehashTestFixture { public: - LegacyVMExtcodehashTestFixture() : ExtcodehashTestFixture{new LegacyVM} {} + LegacyVMExtcodehashTestFixture() : ExtcodehashTestFixture{ new LegacyVM } {} }; class SkaleInterpreterExtcodehashTestFixture : public ExtcodehashTestFixture { public: SkaleInterpreterExtcodehashTestFixture() - : ExtcodehashTestFixture{new EVMC{evmc_create_interpreter()}} {} + : ExtcodehashTestFixture{ new EVMC{ evmc_create_interpreter() } } {} }; class SstoreTestFixture : public TestOutputHelperFixture { public: - explicit SstoreTestFixture( VMFace* _vm ) : vm{_vm} { + explicit SstoreTestFixture( VMFace* _vm ) : vm{ _vm } { state.addBalance( from, 1 * ether ); state.addBalance( to, 1 * ether ); } - virtual ~SstoreTestFixture() { } + virtual ~SstoreTestFixture() {} void testEip1283Case1() { #ifdef FAIR @@ -622,14 +626,14 @@ class SstoreTestFixture : public TestOutputHelperFixture { void testGasConsumed( std::string const& _codeStr, u256 const& _originalValue, u256 const& _expectedGasConsumed, u256 const& _expectedRefund ) { #ifndef FAIR - state.setStorageLimit(1000000000); + state.setStorageLimit( 1000000000 ); #endif state.setStorage( to, 0, _originalValue ); state.commit( dev::eth::CommitBehaviour::RemoveEmptyAccounts ); bytes const code = fromHex( _codeStr ); - ExtVM extVm( state, envInfo, se->chainParams(), to, from, from, value, gasPrice, inputData, ref( code ), - sha3( code ), version, depth, isCreate, staticCall ); + ExtVM extVm( state, envInfo, se->chainParams(), to, from, from, value, gasPrice, inputData, + ref( code ), sha3( code ), version, depth, isCreate, staticCall ); u256 gasBefore = gas; owning_bytes_ref ret = vm->exec( gas, extVm, OnOpFunc{} ); @@ -639,14 +643,16 @@ class SstoreTestFixture : public TestOutputHelperFixture { } - BlockHeader blockHeader{initBlockHeader()}; + BlockHeader blockHeader{ initBlockHeader() }; LastBlockHashes lastBlockHashes; - Address from{KeyPair::create().address()}; - Address to{KeyPair::create().address()}; - State state = State( 0, dev::TransientDirectory().path(), dev::h256() ).createStateCopyAndClearCaches(); + Address from{ KeyPair::create().address() }; + Address to{ KeyPair::create().address() }; + State state = + State( 0, dev::TransientDirectory().path(), dev::h256() ).createStateCopyAndClearCaches(); std::unique_ptr< SealEngineFace > se{ - ChainParams( genesisInfo( Network::ConstantinopleTest ) ).createSealEngine()}; - EnvInfo envInfo{blockHeader, lastBlockHashes, 1, 0, se->chainParams().getChainId()}; + ChainParams( genesisInfo( Network::ConstantinopleTest ) ).createSealEngine() + }; + EnvInfo envInfo{ blockHeader, lastBlockHashes, 1, 0, se->chainParams().getChainId() }; u256 value = 0; u256 gasPrice = 1; @@ -662,18 +668,19 @@ class SstoreTestFixture : public TestOutputHelperFixture { class LegacyVMSstoreTestFixture : public SstoreTestFixture { public: - LegacyVMSstoreTestFixture() : SstoreTestFixture{new LegacyVM} {} + LegacyVMSstoreTestFixture() : SstoreTestFixture{ new LegacyVM } {} }; - class ChainIDTestFixture : public TestOutputHelperFixture { public: - explicit ChainIDTestFixture( VMFace* _vm ) : vm{_vm} { state.addBalance( address, 1 * ether ); } + explicit ChainIDTestFixture( VMFace* _vm ) : vm{ _vm } { + state.addBalance( address, 1 * ether ); + } void testChainIDWorksInIstanbul() { - ExtVM extVm( state, envInfo, se->chainParams(), address, address, address, value, gasPrice, {}, - ref( code ), sha3( code ), version, depth, isCreate, staticCall ); + ExtVM extVm( state, envInfo, se->chainParams(), address, address, address, value, gasPrice, + {}, ref( code ), sha3( code ), version, depth, isCreate, staticCall ); owning_bytes_ref ret = vm->exec( gas, extVm, OnOpFunc{} ); @@ -681,8 +688,8 @@ class ChainIDTestFixture : public TestOutputHelperFixture { } void testChainIDHasCorrectCost() { - ExtVM extVm( state, envInfo, se->chainParams(), address, address, address, value, gasPrice, {}, - ref( code ), sha3( code ), version, depth, isCreate, staticCall ); + ExtVM extVm( state, envInfo, se->chainParams(), address, address, address, value, gasPrice, + {}, ref( code ), sha3( code ), version, depth, isCreate, staticCall ); bigint gasBefore; bigint gasAfter; @@ -704,20 +711,21 @@ class ChainIDTestFixture : public TestOutputHelperFixture { se.reset( ChainParams( genesisInfo( Network::ConstantinopleFixTest ) ).createSealEngine() ); version = ConstantinopleFixSchedule.accountVersion; - ExtVM extVm( state, envInfo, se->chainParams(), address, address, address, value, gasPrice, {}, - ref( code ), sha3( code ), version, depth, isCreate, staticCall ); + ExtVM extVm( state, envInfo, se->chainParams(), address, address, address, value, gasPrice, + {}, ref( code ), sha3( code ), version, depth, isCreate, staticCall ); BOOST_REQUIRE_THROW( vm->exec( gas, extVm, OnOpFunc{} ), BadInstruction ); } - BlockHeader blockHeader{initBlockHeader()}; + BlockHeader blockHeader{ initBlockHeader() }; LastBlockHashes lastBlockHashes; - Address address{KeyPair::create().address()}; - State state{0}; + Address address{ KeyPair::create().address() }; + State state{ 0 }; std::unique_ptr< SealEngineFace > se{ - ChainParams( genesisInfo( Network::IstanbulTest ) ).createSealEngine()}; - EnvInfo envInfo{blockHeader, lastBlockHashes, 1, 0, se->chainParams().getChainId()}; + ChainParams( genesisInfo( Network::IstanbulTest ) ).createSealEngine() + }; + EnvInfo envInfo{ blockHeader, lastBlockHashes, 1, 0, se->chainParams().getChainId() }; u256 value = 0; u256 gasPrice = 1; @@ -737,29 +745,31 @@ class ChainIDTestFixture : public TestOutputHelperFixture { class LegacyVMChainIDTestFixture : public ChainIDTestFixture { public: - LegacyVMChainIDTestFixture() : ChainIDTestFixture{new LegacyVM} {} + LegacyVMChainIDTestFixture() : ChainIDTestFixture{ new LegacyVM } {} }; class SkaleInterpreterChainIDTestFixture : public ChainIDTestFixture { public: SkaleInterpreterChainIDTestFixture() - : ChainIDTestFixture{new EVMC{evmc_create_interpreter()}} {} + : ChainIDTestFixture{ new EVMC{ evmc_create_interpreter() } } {} }; class BalanceFixture : public TestOutputHelperFixture { public: - explicit BalanceFixture( VMFace* _vm ) : vm{_vm} { state.addBalance( address, 1 * ether ); } + explicit BalanceFixture( VMFace* _vm ) : vm{ _vm } { state.addBalance( address, 1 * ether ); } void testSelfBalanceWorksInIstanbul() { - ExtVM extVmSelfBalance( state, envInfo, se->chainParams(), address, address, address, value, gasPrice, {}, - ref( codeSelfBalance ), sha3( codeSelfBalance ), version, depth, isCreate, staticCall ); + ExtVM extVmSelfBalance( state, envInfo, se->chainParams(), address, address, address, value, + gasPrice, {}, ref( codeSelfBalance ), sha3( codeSelfBalance ), version, depth, isCreate, + staticCall ); owning_bytes_ref retSelfBalance = vm->exec( gas, extVmSelfBalance, OnOpFunc{} ); BOOST_REQUIRE_EQUAL( fromBigEndian< u256 >( retSelfBalance ), 1 * ether ); - ExtVM extVmBalance( state, envInfo, se->chainParams(), address, address, address, value, gasPrice, {}, - ref( codeBalance ), sha3( codeBalance ), version, depth, isCreate, staticCall ); + ExtVM extVmBalance( state, envInfo, se->chainParams(), address, address, address, value, + gasPrice, {}, ref( codeBalance ), sha3( codeBalance ), version, depth, isCreate, + staticCall ); owning_bytes_ref retBalance = vm->exec( gas, extVmBalance, OnOpFunc{} ); @@ -768,8 +778,9 @@ class BalanceFixture : public TestOutputHelperFixture { } void testSelfBalanceHasCorrectCost() { - ExtVM extVm( state, envInfo, se->chainParams(), address, address, address, value, gasPrice, {}, - ref( codeSelfBalance ), sha3( codeSelfBalance ), version, depth, isCreate, staticCall ); + ExtVM extVm( state, envInfo, se->chainParams(), address, address, address, value, gasPrice, + {}, ref( codeSelfBalance ), sha3( codeSelfBalance ), version, depth, isCreate, + staticCall ); bigint gasBefore; bigint gasAfter; @@ -788,8 +799,8 @@ class BalanceFixture : public TestOutputHelperFixture { } void testBalanceHasCorrectCost() { - ExtVM extVm( state, envInfo, se->chainParams(), address, address, address, value, gasPrice, {}, - ref( codeBalance ), sha3( codeBalance ), version, depth, isCreate, staticCall ); + ExtVM extVm( state, envInfo, se->chainParams(), address, address, address, value, gasPrice, + {}, ref( codeBalance ), sha3( codeBalance ), version, depth, isCreate, staticCall ); bigint gasBefore; bigint gasAfter; @@ -817,20 +828,22 @@ class BalanceFixture : public TestOutputHelperFixture { se.reset( ChainParams( genesisInfo( Network::ConstantinopleFixTest ) ).createSealEngine() ); version = ConstantinopleFixSchedule.accountVersion; - ExtVM extVm( state, envInfo, se->chainParams(), address, address, address, value, gasPrice, {}, - ref( codeSelfBalance ), sha3( codeSelfBalance ), version, depth, isCreate, staticCall ); + ExtVM extVm( state, envInfo, se->chainParams(), address, address, address, value, gasPrice, + {}, ref( codeSelfBalance ), sha3( codeSelfBalance ), version, depth, isCreate, + staticCall ); BOOST_REQUIRE_THROW( vm->exec( gas, extVm, OnOpFunc{} ), BadInstruction ); } - BlockHeader blockHeader{initBlockHeader()}; + BlockHeader blockHeader{ initBlockHeader() }; LastBlockHashes lastBlockHashes; - Address address{KeyPair::create().address()}; - State state{0}; + Address address{ KeyPair::create().address() }; + State state{ 0 }; std::unique_ptr< SealEngineFace > se{ - ChainParams( genesisInfo( Network::IstanbulTest ) ).createSealEngine()}; - EnvInfo envInfo{blockHeader, lastBlockHashes, 1, 0, se->chainParams().getChainId()}; + ChainParams( genesisInfo( Network::IstanbulTest ) ).createSealEngine() + }; + EnvInfo envInfo{ blockHeader, lastBlockHashes, 1, 0, se->chainParams().getChainId() }; u256 value = 0; u256 gasPrice = 1; @@ -856,35 +869,35 @@ class BalanceFixture : public TestOutputHelperFixture { class InstructionTestFixture : public TestOutputHelperFixture { public: - InstructionTestFixture() : vm{new LegacyVM()} { + InstructionTestFixture() : vm{ new LegacyVM() } { ChainParams cp( genesisInfo( Network::IstanbulTest ) ); #ifndef FAIR - cp.sChain._patchTimestamps[static_cast(SchainPatchEnum::PushZeroPatch)] = 1; + cp.sChain._patchTimestamps[static_cast< size_t >( SchainPatchEnum::PushZeroPatch )] = 1; #endif - SchainPatch::init(cp); + SchainPatch::init( cp ); - se.reset(cp.createSealEngine()); - envInfo = std::make_unique ( blockHeader, lastBlockHashes, 1, 0, cp.getChainId() ); + se.reset( cp.createSealEngine() ); + envInfo = + std::make_unique< EnvInfo >( blockHeader, lastBlockHashes, 1, 0, cp.getChainId() ); state.addBalance( address, 1 * ether ); } void testCode( std::string const& _codeStr ) { - bytes const code = fromHex( _codeStr ); - ExtVM extVm( state, *envInfo, se->chainParams(), address, address, address, value, gasPrice, {}, - ref( code ), sha3( code ), version, depth, isCreate, staticCall ); + ExtVM extVm( state, *envInfo, se->chainParams(), address, address, address, value, gasPrice, + {}, ref( code ), sha3( code ), version, depth, isCreate, staticCall ); owning_bytes_ref ret = vm->exec( gas, extVm, OnOpFunc{} ); } - BlockHeader blockHeader{initBlockHeader()}; + BlockHeader blockHeader{ initBlockHeader() }; LastBlockHashes lastBlockHashes; - Address address{KeyPair::create().address()}; - State state{0}; + Address address{ KeyPair::create().address() }; + State state{ 0 }; std::unique_ptr< SealEngineFace > se; - std::unique_ptr envInfo; + std::unique_ptr< EnvInfo > envInfo; u256 value = 0; u256 gasPrice = 1; @@ -899,12 +912,12 @@ class InstructionTestFixture : public TestOutputHelperFixture { class LegacyVMBalanceFixture : public BalanceFixture { public: - LegacyVMBalanceFixture() : BalanceFixture{new LegacyVM} {} + LegacyVMBalanceFixture() : BalanceFixture{ new LegacyVM } {} }; class SkaleInterpreterBalanceFixture : public BalanceFixture { public: - SkaleInterpreterBalanceFixture() : BalanceFixture{new EVMC{evmc_create_interpreter()}} {} + SkaleInterpreterBalanceFixture() : BalanceFixture{ new EVMC{ evmc_create_interpreter() } } {} }; } // namespace @@ -942,7 +955,7 @@ BOOST_AUTO_TEST_CASE( LegacyVMCreate2collisionWithNonEmptyStorage, // Disable this test since SKALE cleans the storage in a different way // There is now need to ALWAYS clean contract storage, // because the only case when a contract is created on non-empty -//storage is create2 -> selfdestruct -> create2_with_the_same_sed +// storage is create2 -> selfdestruct -> create2_with_the_same_sed // Note: the combination above will cease to exist in Shanhai fork because // there will be no selfdestruct BOOST_AUTO_TEST_CASE( LegacyVMCreate2collisionWithNonEmptyStorageEmptyInitCode ) { @@ -1007,23 +1020,28 @@ BOOST_AUTO_TEST_SUITE_END() BOOST_FIXTURE_TEST_SUITE( LegacyVMSstoreSuite, LegacyVMSstoreTestFixture ) -BOOST_AUTO_TEST_CASE( LegacyVMSstoreEip1283Case1, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + LegacyVMSstoreEip1283Case1, *boost::unit_test::precondition( dev::test::run_not_express ) ) { testEip1283Case1(); } -BOOST_AUTO_TEST_CASE( LegacyVMSstoreEip1283Case2, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + LegacyVMSstoreEip1283Case2, *boost::unit_test::precondition( dev::test::run_not_express ) ) { testEip1283Case2(); } -BOOST_AUTO_TEST_CASE( LegacyVMSstoreEip1283Case3, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + LegacyVMSstoreEip1283Case3, *boost::unit_test::precondition( dev::test::run_not_express ) ) { testEip1283Case3(); } -BOOST_AUTO_TEST_CASE( LegacyVMSstoreEip1283Case4, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + LegacyVMSstoreEip1283Case4, *boost::unit_test::precondition( dev::test::run_not_express ) ) { testEip1283Case4(); } -BOOST_AUTO_TEST_CASE( LegacyVMSstoreEip1283Case5, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + LegacyVMSstoreEip1283Case5, *boost::unit_test::precondition( dev::test::run_not_express ) ) { testEip1283Case5(); } @@ -1063,11 +1081,13 @@ BOOST_AUTO_TEST_CASE( LegacyVMSstoreEip1283Case14, *boost::unit_test::disabled() testEip1283Case14(); } -BOOST_AUTO_TEST_CASE( LegacyVMSstoreEip1283Case15, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + LegacyVMSstoreEip1283Case15, *boost::unit_test::precondition( dev::test::run_not_express ) ) { testEip1283Case15(); } -BOOST_AUTO_TEST_CASE( LegacyVMSstoreEip1283Case16, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + LegacyVMSstoreEip1283Case16, *boost::unit_test::precondition( dev::test::run_not_express ) ) { testEip1283Case16(); } @@ -1083,7 +1103,8 @@ BOOST_AUTO_TEST_CASE( LegacyVMChainIDworksInIstanbul, testChainIDWorksInIstanbul(); } -BOOST_AUTO_TEST_CASE( LegacyVMChainIDHasCorrectCost, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + LegacyVMChainIDHasCorrectCost, *boost::unit_test::precondition( dev::test::run_not_express ) ) { testChainIDHasCorrectCost(); } @@ -1118,10 +1139,10 @@ BOOST_FIXTURE_TEST_SUITE( InstructionSuite, InstructionTestFixture ) BOOST_AUTO_TEST_CASE( Push0 ) { string code = "5f"; - BOOST_REQUIRE_NO_THROW( this->testCode(code) ); + BOOST_REQUIRE_NO_THROW( this->testCode( code ) ); u256s stack = vm->stack(); - BOOST_REQUIRE_EQUAL(stack.size(), 1); - BOOST_REQUIRE_EQUAL(stack[0], u256()); + BOOST_REQUIRE_EQUAL( stack.size(), 1 ); + BOOST_REQUIRE_EQUAL( stack[0], u256() ); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/unittests/libskale/HashSnapshot.cpp b/test/unittests/libskale/HashSnapshot.cpp index 5c9b7c70c..b4efa6c40 100644 --- a/test/unittests/libskale/HashSnapshot.cpp +++ b/test/unittests/libskale/HashSnapshot.cpp @@ -60,8 +60,7 @@ class SnapshotHashAgentTest { for ( size_t j = 0; j < _chainParams.sChain.t; ++j ) { blsPrivateKeys_[i] = blsPrivateKeys_[i] + - coeffs[j] * - libBLS::algebra::power( libBLS::algebra::FrScalar( i + 1 ), j ); + coeffs[j] * libBLS::algebra::power( libBLS::algebra::FrScalar( i + 1 ), j ); } } @@ -515,10 +514,9 @@ BOOST_AUTO_TEST_CASE( PositiveTest ) { std::vector< size_t > excpected = { 0, 1, 2 }; BOOST_REQUIRE( res == excpected ); BOOST_REQUIRE( test_agent.getVotedHash().first == hash ); - BOOST_REQUIRE( - test_agent.getVotedHash().second == - libBLS::Bls::Signing( libBLS::algebra::hashToG1( hash.asArray() ), - test_agent.secret_as_is ) ); + BOOST_REQUIRE( test_agent.getVotedHash().second == + libBLS::Bls::Signing( + libBLS::algebra::hashToG1( hash.asArray() ), test_agent.secret_as_is ) ); } BOOST_AUTO_TEST_CASE( WrongHash ) { diff --git a/test/unittests/libskale/SnapshotManager.cpp b/test/unittests/libskale/SnapshotManager.cpp index b8357fef2..dbcf8c825 100644 --- a/test/unittests/libskale/SnapshotManager.cpp +++ b/test/unittests/libskale/SnapshotManager.cpp @@ -113,9 +113,9 @@ struct BtrfsFixture : public FixtureCommon { gainRoot(); rv = system( ( "mount -o user_subvol_rm_allowed " + BTRFS_FILE_PATH + " " + BTRFS_DIR_PATH ) - .c_str() ); + .c_str() ); rv = chown( BTRFS_DIR_PATH.c_str(), sudo_uid, sudo_gid ); - ( void )rv; + ( void ) rv; dropRoot(); // btrfs.subvolume.create( ( BTRFS_DIR_PATH + "/vol1" ).c_str() ); @@ -154,11 +154,11 @@ struct NoBtrfsFixture : public FixtureCommon { } }; -BOOST_AUTO_TEST_SUITE( BtrfsTestSuite, - *boost::unit_test::precondition( dev::test::option_all_tests ) ) +BOOST_AUTO_TEST_SUITE( + BtrfsTestSuite, *boost::unit_test::precondition( dev::test::option_all_tests ) ) BOOST_FIXTURE_TEST_CASE( SimplePositiveTest, BtrfsFixture, - + *boost::unit_test::precondition( dev::test::run_not_express ) ) { std::shared_ptr< dev::eth::ChainParams > chainParams( new dev::eth::ChainParams{} ); SnapshotManager mgr( chainParams, fs::path( BTRFS_DIR_PATH ) ); @@ -174,14 +174,16 @@ BOOST_FIXTURE_TEST_CASE( SimplePositiveTest, BtrfsFixture, #endif auto latest0 = mgr.getLatestSnapshots(); - std::pair< int, int > expected0 { 0, 0 }; + std::pair< int, int > expected0{ 0, 0 }; BOOST_REQUIRE( latest0 == expected0 ); // create snapshot 1 and check its presense mgr.doSnapshot( 1 ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / chainDirName / "d11" ) ); + BOOST_REQUIRE( + fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / chainDirName / "d11" ) ); #ifndef FAIR - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "filestorage" / "d21" ) ); + BOOST_REQUIRE( + fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "filestorage" / "d21" ) ); #endif // add and remove something @@ -194,16 +196,19 @@ BOOST_FIXTURE_TEST_CASE( SimplePositiveTest, BtrfsFixture, #endif auto latest1 = mgr.getLatestSnapshots(); - std::pair< int, int > expected1 { 0, 1 }; + std::pair< int, int > expected1{ 0, 1 }; BOOST_REQUIRE( latest1 == expected1 ); // create snapshot 2 and check files 1 and files 2 mgr.doSnapshot( 2 ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / chainDirName / "d11" ) ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / chainDirName / "d12" ) ); + BOOST_REQUIRE( + fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / chainDirName / "d11" ) ); + BOOST_REQUIRE( + fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / chainDirName / "d12" ) ); #ifndef FAIR - BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / "filestorage" / "d21" ) ); + BOOST_REQUIRE( + !fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / "filestorage" / "d21" ) ); #endif // check that files appear/disappear on restore @@ -223,10 +228,13 @@ BOOST_FIXTURE_TEST_CASE( SimplePositiveTest, BtrfsFixture, BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" ) ); mgr.importDiff( 2 ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / chainDirName / "d11" ) ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / chainDirName / "d12" ) ); + BOOST_REQUIRE( + fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / chainDirName / "d11" ) ); + BOOST_REQUIRE( + fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / chainDirName / "d12" ) ); #ifndef FAIR - BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / "filestorage" / "d21" ) ); + BOOST_REQUIRE( + !fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / "filestorage" / "d21" ) ); #endif mgr.restoreSnapshot( 2 ); @@ -237,12 +245,12 @@ BOOST_FIXTURE_TEST_CASE( SimplePositiveTest, BtrfsFixture, #endif auto latest2 = mgr.getLatestSnapshots(); - std::pair< int, int > expected2 { 1, 2 }; + std::pair< int, int > expected2{ 1, 2 }; BOOST_REQUIRE( latest2 == expected2 ); mgr.doSnapshot( 3 ); auto latest3 = mgr.getLatestSnapshots(); - std::pair< int, int > expected3 { 2, 3 }; + std::pair< int, int > expected3{ 2, 3 }; BOOST_REQUIRE( latest3 == expected3 ); BOOST_REQUIRE_NO_THROW( mgr.removeSnapshot( 1 ) ); @@ -250,15 +258,15 @@ BOOST_FIXTURE_TEST_CASE( SimplePositiveTest, BtrfsFixture, BOOST_REQUIRE_NO_THROW( mgr.removeSnapshot( 3 ) ); } -BOOST_FIXTURE_TEST_CASE( NoBtrfsTest, NoBtrfsFixture, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_FIXTURE_TEST_CASE( + NoBtrfsTest, NoBtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { std::shared_ptr< dev::eth::ChainParams > chainParams( new dev::eth::ChainParams{} ); BOOST_REQUIRE_THROW( SnapshotManager mgr( chainParams, fs::path( BTRFS_DIR_PATH ) ), SnapshotManager::CannotPerformBtrfsOperation ); } -BOOST_FIXTURE_TEST_CASE( BadPathTest, BtrfsFixture, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_FIXTURE_TEST_CASE( + BadPathTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { std::shared_ptr< dev::eth::ChainParams > chainParams( new dev::eth::ChainParams() ); BOOST_REQUIRE_EXCEPTION( SnapshotManager mgr( chainParams, fs::path( BTRFS_DIR_PATH ) / "_invalid" ), @@ -293,24 +301,27 @@ BOOST_FIXTURE_TEST_CASE( InaccessiblePathTest, BtrfsFixture, dropRoot(); std::shared_ptr< dev::eth::ChainParams > chainParams( new dev::eth::ChainParams() ); - BOOST_REQUIRE_EXCEPTION( SnapshotManager mgr( chainParams, fs::path( BTRFS_DIR_PATH ) / "_no_w" ), + BOOST_REQUIRE_EXCEPTION( + SnapshotManager mgr( chainParams, fs::path( BTRFS_DIR_PATH ) / "_no_w" ), SnapshotManager::CannotCreate, [this]( const SnapshotManager::CannotCreate& ex ) -> bool { return ex.path == fs::path( BTRFS_DIR_PATH ) / "_no_w" / "snapshots"; } ); - BOOST_REQUIRE_EXCEPTION( SnapshotManager mgr( chainParams, fs::path( BTRFS_DIR_PATH ) / "_no_x" ), + BOOST_REQUIRE_EXCEPTION( + SnapshotManager mgr( chainParams, fs::path( BTRFS_DIR_PATH ) / "_no_x" ), SnapshotManager::CannotCreate, [this]( const SnapshotManager::CannotCreate& ex ) -> bool { return ex.path == fs::path( BTRFS_DIR_PATH ) / "_no_x" / "snapshots"; } ); - BOOST_REQUIRE_EXCEPTION( SnapshotManager mgr( chainParams, fs::path( BTRFS_DIR_PATH ) / "_no_r" ), + BOOST_REQUIRE_EXCEPTION( + SnapshotManager mgr( chainParams, fs::path( BTRFS_DIR_PATH ) / "_no_r" ), SnapshotManager::CannotCreate, [this]( const SnapshotManager::CannotCreate& ex ) -> bool { return ex.path == fs::path( BTRFS_DIR_PATH ) / "_no_x" / "snapshots"; } ); } -BOOST_FIXTURE_TEST_CASE( SnapshotTest, BtrfsFixture, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_FIXTURE_TEST_CASE( + SnapshotTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { std::shared_ptr< dev::eth::ChainParams > chainParams( new dev::eth::ChainParams{} ); SnapshotManager mgr( chainParams, fs::path( BTRFS_DIR_PATH ) ); @@ -339,8 +350,8 @@ BOOST_FIXTURE_TEST_CASE( SnapshotTest, BtrfsFixture, BOOST_REQUIRE_THROW( mgr.restoreSnapshot( 2 ), SnapshotManager::CannotPerformBtrfsOperation ); } -BOOST_FIXTURE_TEST_CASE( RestoreTest, BtrfsFixture, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_FIXTURE_TEST_CASE( + RestoreTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { std::shared_ptr< dev::eth::ChainParams > chainParams( new dev::eth::ChainParams{} ); SnapshotManager mgr( chainParams, fs::path( BTRFS_DIR_PATH ) ); @@ -351,15 +362,16 @@ BOOST_FIXTURE_TEST_CASE( RestoreTest, BtrfsFixture, BOOST_REQUIRE_NO_THROW( mgr.restoreSnapshot( 2 ) ); BOOST_REQUIRE_EQUAL( - 0, btrfs.subvolume._delete( - ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / dev::eth::BlockChain::getChainDirName( *chainParams ) ).c_str() ) ); + 0, btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / + dev::eth::BlockChain::getChainDirName( *chainParams ) ) + .c_str() ) ); BOOST_REQUIRE_THROW( mgr.restoreSnapshot( 2 ), SnapshotManager::CannotPerformBtrfsOperation ); } #ifndef FAIR -BOOST_FIXTURE_TEST_CASE( DiffTest, BtrfsFixture, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_FIXTURE_TEST_CASE( + DiffTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { std::shared_ptr< dev::eth::ChainParams > chainParams( new dev::eth::ChainParams{} ); SnapshotManager mgr( chainParams, fs::path( BTRFS_DIR_PATH ) ); mgr.doSnapshot( 2 ); @@ -384,7 +396,8 @@ BOOST_FIXTURE_TEST_CASE( DiffTest, BtrfsFixture, BOOST_REQUIRE_GT( fs::file_size( tmp ), 0 ); fs::remove( tmp ); - btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" / "filestorage" ).c_str() ); + btrfs.subvolume._delete( + ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" / "filestorage" ).c_str() ); BOOST_REQUIRE_THROW( tmp = mgr.makeOrGetDiff( 4 ), SnapshotManager::CannotPerformBtrfsOperation ); @@ -393,8 +406,8 @@ BOOST_FIXTURE_TEST_CASE( DiffTest, BtrfsFixture, // TODO Tests to check no files left in /tmp?! -BOOST_FIXTURE_TEST_CASE( ImportTest, BtrfsFixture, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_FIXTURE_TEST_CASE( + ImportTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { std::shared_ptr< dev::eth::ChainParams > chainParams( new dev::eth::ChainParams{} ); SnapshotManager mgr( chainParams, fs::path( BTRFS_DIR_PATH ) ); @@ -411,35 +424,41 @@ BOOST_FIXTURE_TEST_CASE( ImportTest, BtrfsFixture, std::string chainDirName = dev::eth::BlockChain::getChainDirName( dev::eth::ChainParams() ); // delete dest - btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" / chainDirName ).c_str() ); + btrfs.subvolume._delete( + ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" / chainDirName ).c_str() ); #ifndef FAIR - btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" / "filestorage" ).c_str() ); + btrfs.subvolume._delete( + ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" / "filestorage" ).c_str() ); #endif fs::remove_all( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" ); BOOST_REQUIRE_NO_THROW( mgr.importDiff( 4 ) ); // delete dest - btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" / chainDirName ).c_str() ); + btrfs.subvolume._delete( + ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" / chainDirName ).c_str() ); #ifndef FAIR - btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" / "filestorage" ).c_str() ); + btrfs.subvolume._delete( + ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" / "filestorage" ).c_str() ); #endif fs::remove_all( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "4" ); // no source - btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / chainDirName ).c_str() ); + btrfs.subvolume._delete( + ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / chainDirName ).c_str() ); // BOOST_REQUIRE_THROW( mgr.importDiff( 2, 4 ), SnapshotManager::CannotPerformBtrfsOperation ); #ifndef FAIR - btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / "filestorage" ).c_str() ); + btrfs.subvolume._delete( + ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" / "filestorage" ).c_str() ); #endif fs::remove_all( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" ); // BOOST_REQUIRE_THROW( mgr.importDiff( 2, 4 ), SnapshotManager::CannotPerformBtrfsOperation ); } BOOST_FIXTURE_TEST_CASE( SnapshotRotationTest, BtrfsFixture, - + *boost::unit_test::precondition( dev::test::run_not_express ) ) { std::shared_ptr< dev::eth::ChainParams > chainParams( new dev::eth::ChainParams{} ); SnapshotManager mgr( chainParams, fs::path( BTRFS_DIR_PATH ) ); @@ -461,7 +480,7 @@ BOOST_FIXTURE_TEST_CASE( SnapshotRotationTest, BtrfsFixture, } BOOST_FIXTURE_TEST_CASE( DiffRotationTest, BtrfsFixture, - + *boost::unit_test::precondition( dev::test::run_not_express ) ) { std::shared_ptr< dev::eth::ChainParams > chainParams( new dev::eth::ChainParams{} ); SnapshotManager mgr( chainParams, fs::path( BTRFS_DIR_PATH ) ); @@ -492,7 +511,7 @@ BOOST_FIXTURE_TEST_CASE( DiffRotationTest, BtrfsFixture, } BOOST_FIXTURE_TEST_CASE( RemoveSnapshotTest, BtrfsFixture, - + *boost::unit_test::precondition( dev::test::run_not_express ) ) { std::shared_ptr< dev::eth::ChainParams > chainParams( new dev::eth::ChainParams{} ); SnapshotManager mgr( chainParams, fs::path( BTRFS_DIR_PATH ) ); @@ -521,9 +540,9 @@ BOOST_FIXTURE_TEST_CASE( CleanupTest, BtrfsFixture, mgr.cleanup(); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots") ); - BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1") ); - BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2") ); + BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" ) ); + BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" ) ); + BOOST_REQUIRE( !fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "2" ) ); BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "diffs" ) ); @@ -536,8 +555,8 @@ BOOST_FIXTURE_TEST_CASE( CleanupTest, BtrfsFixture, } #ifdef HISTORIC_STATE -BOOST_FIXTURE_TEST_CASE( ArchiveNodeTest, BtrfsFixture, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_FIXTURE_TEST_CASE( + ArchiveNodeTest, BtrfsFixture, *boost::unit_test::precondition( dev::test::run_not_express ) ) { std::shared_ptr< dev::eth::ChainParams > chainParams( new dev::eth::ChainParams() ); chainParams->setArchiveMode(); SnapshotManager mgr( chainParams, fs::path( BTRFS_DIR_PATH ) ); @@ -560,33 +579,45 @@ BOOST_FIXTURE_TEST_CASE( ArchiveNodeTest, BtrfsFixture, // create snapshot 1 and check its presense mgr.doSnapshot( 1 ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / chainDirName / "d11" ) ); + BOOST_REQUIRE( + fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / chainDirName / "d11" ) ); #ifndef FAIR - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "filestorage" / "d21" ) ); + BOOST_REQUIRE( + fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "filestorage" / "d21" ) ); #endif - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "historic_roots" / "d31" ) ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "historic_state" / "d41" ) ); + BOOST_REQUIRE( + fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "historic_roots" / "d31" ) ); + BOOST_REQUIRE( + fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "historic_state" / "d41" ) ); // make diff for archive node BOOST_REQUIRE_NO_THROW( mgr.makeOrGetDiff( 1 ) ); // delete dest - btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / chainDirName ).c_str() ); + btrfs.subvolume._delete( + ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / chainDirName ).c_str() ); #ifndef FAIR - btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "filestorage" ).c_str() ); + btrfs.subvolume._delete( + ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "filestorage" ).c_str() ); #endif - btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "historic_roots" ).c_str() ); - btrfs.subvolume._delete( ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "historic_state" ).c_str() ); + btrfs.subvolume._delete( + ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "historic_roots" ).c_str() ); + btrfs.subvolume._delete( + ( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "historic_state" ).c_str() ); fs::remove_all( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" ); BOOST_REQUIRE_NO_THROW( mgr.importDiff( 1 ) ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / chainDirName / "d11" ) ); + BOOST_REQUIRE( + fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / chainDirName / "d11" ) ); #ifndef FAIR - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "filestorage" / "d21" ) ); + BOOST_REQUIRE( + fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "filestorage" / "d21" ) ); #endif - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "historic_roots" / "d31" ) ); - BOOST_REQUIRE( fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "historic_state" / "d41" ) ); + BOOST_REQUIRE( + fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "historic_roots" / "d31" ) ); + BOOST_REQUIRE( + fs::exists( fs::path( BTRFS_DIR_PATH ) / "snapshots" / "1" / "historic_state" / "d41" ) ); } #endif diff --git a/test/unittests/libskutils/test_skutils_dispatch.cpp b/test/unittests/libskutils/test_skutils_dispatch.cpp index ddb9f5aa2..36dae7518 100644 --- a/test/unittests/libskutils/test_skutils_dispatch.cpp +++ b/test/unittests/libskutils/test_skutils_dispatch.cpp @@ -1,6 +1,6 @@ #include "test_skutils_helper.h" -#include #include +#include static const bool g_bShowDetailedJobLogs = false; // useful for dispatch development only @@ -55,8 +55,7 @@ static std::string thread_prefix_str() { } else strDomain = "~"; // thread / loop / queue / domain - return "TLQD/" + strThreadID + "/" + strLoop + "/" + - strQueue + "/" + strDomain + ": "; + return "TLQD/" + strThreadID + "/" + strLoop + "/" + strQueue + "/" + strDomain + ": "; } BOOST_AUTO_TEST_SUITE( SkUtils ) @@ -68,61 +67,61 @@ BOOST_AUTO_TEST_SUITE( dispatch, *boost::unit_test::precondition( dev::test::opt BOOST_AUTO_TEST_CASE( loop_functionality_alive ) { skutils::test::test_print_header_name( "SkUtils/dispatch/loop_functionality_alive" ); skutils::test::with_test_environment( [&]() { - skutils::test::test_log_e( thread_prefix_str() + "creating loop instance..."); + skutils::test::test_log_e( thread_prefix_str() + "creating loop instance..." ); skutils::dispatch::loop_ptr_t pLoop( new skutils::dispatch::loop ); pLoop->on_job_will_add_ = [&]( const skutils::dispatch::job_id_t& id ) -> bool { - skutils::test::test_log_e( thread_prefix_str() + "will add job " + id); + skutils::test::test_log_e( thread_prefix_str() + "will add job " + id ); return true; }; pLoop->on_job_was_added_ = [&]( const skutils::dispatch::job_id_t& id ) -> void { - skutils::test::test_log_e( thread_prefix_str() + "did added job " + id); + skutils::test::test_log_e( thread_prefix_str() + "did added job " + id ); }; pLoop->on_job_will_remove_ = [&]( const skutils::dispatch::job_id_t& id ) -> bool { - skutils::test::test_log_e( thread_prefix_str() + "will remove job " + id); + skutils::test::test_log_e( thread_prefix_str() + "will remove job " + id ); return true; }; pLoop->on_job_did_removed_ = [&]( const skutils::dispatch::job_id_t& id ) -> void { - skutils::test::test_log_e( thread_prefix_str() + "did removed job " + id); + skutils::test::test_log_e( thread_prefix_str() + "did removed job " + id ); }; pLoop->on_job_will_execute_ = [&]( const skutils::dispatch::job_id_t& id ) -> bool { skutils::test::test_log_e( thread_prefix_str() + "will execute job " + id ); return true; }; pLoop->on_job_did_executed_ = [&]( const skutils::dispatch::job_id_t& id ) -> void { - skutils::test::test_log_e( thread_prefix_str() + "did executed job " + id); + skutils::test::test_log_e( thread_prefix_str() + "did executed job " + id ); }; pLoop->on_job_exception_ = [&]( const skutils::dispatch::job_id_t& id, std::exception* pe ) -> void { - skutils::test::test_log_e( thread_prefix_str() + "exception in job " + id + ", exception info: " + - ( pe ? pe->what() : "unknown exception" )); + skutils::test::test_log_e( + thread_prefix_str() + "exception in job " + id + + ", exception info: " + ( pe ? pe->what() : "unknown exception" ) ); }; // skutils::test::test_log_e( thread_prefix_str() + "starting loop thread..." ); std::thread t( [&]() -> void { - skutils::test::test_log_e( - thread_prefix_str() + "will run loop in thread..." ); + skutils::test::test_log_e( thread_prefix_str() + "will run loop in thread..." ); pLoop->run(); - skutils::test::test_log_e( - thread_prefix_str() + "will exit loop thread..." ); + skutils::test::test_log_e( thread_prefix_str() + "will exit loop thread..." ); } ); - skutils::test::test_log_e( - thread_prefix_str() + "waiting loop to start finished..." ); + skutils::test::test_log_e( thread_prefix_str() + "waiting loop to start finished..." ); pLoop->wait_until_startup(); // static const size_t nSleepSeconds = 3; // size_t nCallCountOnce = 0; const uint64_t nOnceJobTimeout = 500; // milliseconds - pLoop->job_add_once( "once uppon a time", + pLoop->job_add_once( + "once uppon a time", [&]() -> void { ++nCallCountOnce; skutils::test::test_log_e( thread_prefix_str() + "--- once uppon a time job, invocation " + - std::to_string(nCallCountOnce - 1) ); + std::to_string( nCallCountOnce - 1 ) ); }, skutils::dispatch::duration_from_milliseconds( nOnceJobTimeout ) ); // - pLoop->job_add_once( "bad job", + pLoop->job_add_once( + "bad job", [&]() -> void { skutils::test::test_log_e( thread_prefix_str() + "bad job invoked, throwing someting" ); @@ -136,20 +135,20 @@ BOOST_AUTO_TEST_CASE( loop_functionality_alive ) { const uint64_t nPeriodicJobTimeout = 500; // milliseconds const size_t nExpectedCallCountPeriodical = ( nSleepSeconds * 1000 ) / nPeriodicJobTimeout - 1; // -1 for safety) - skutils::test::test_log_e( - thread_prefix_str() + "expecting periodical job to be invoked " + - std::to_string(nExpectedCallCountPeriodical) + " time(s), at least" ); - pLoop->job_add_periodic( "some periodical work", + skutils::test::test_log_e( thread_prefix_str() + "expecting periodical job to be invoked " + + std::to_string( nExpectedCallCountPeriodical ) + + " time(s), at least" ); + pLoop->job_add_periodic( + "some periodical work", [&]() -> void { ++nCallCountPeriodical; - skutils::test::test_log_e( thread_prefix_str() + - "--- periodical job, invocation " + - std::to_string(nCallCountPeriodical - 1)); + skutils::test::test_log_e( thread_prefix_str() + "--- periodical job, invocation " + + std::to_string( nCallCountPeriodical - 1 ) ); }, skutils::dispatch::duration_from_milliseconds( nPeriodicJobTimeout ) ); // skutils::test::test_log_e( thread_prefix_str() + "will sleep " + - std::to_string(nSleepSeconds) + " second(s)..." ); + std::to_string( nSleepSeconds ) + " second(s)..." ); sleep( nSleepSeconds ); // skutils::test::test_log_e( thread_prefix_str() + "will cancel loop..." ); @@ -158,8 +157,7 @@ BOOST_AUTO_TEST_CASE( loop_functionality_alive ) { pLoop->wait(); try { if ( t.joinable() ) { - skutils::test::test_log_e( - thread_prefix_str() + "will wait for loop thread..." ); + skutils::test::test_log_e( thread_prefix_str() + "will wait for loop thread..." ); t.join(); } } catch ( ... ) { @@ -180,15 +178,14 @@ BOOST_AUTO_TEST_CASE( domain_functionality_alive ) { static const size_t nExpectedCallCount = 50; std::atomic_size_t nCallCounter( 0 ); { // block for domain - skutils::test::test_log_e( - thread_prefix_str() + "creating domain instance..." ); + skutils::test::test_log_e( thread_prefix_str() + "creating domain instance..." ); skutils::dispatch::domain_ptr_t pDomain( new skutils::dispatch::domain ); size_t i; std::atomic_bool bInsideCall( false ); - skutils::test::test_log_e( - thread_prefix_str() + "expecting async job to be invoked " + - std::to_string(nExpectedCallCount) + " time(s), at least"); + skutils::test::test_log_e( thread_prefix_str() + "expecting async job to be invoked " + + std::to_string( nExpectedCallCount ) + + " time(s), at least" ); for ( i = 0; i < nExpectedCallCount; ++i ) { skutils::dispatch::queue_ptr_t pQueue( pDomain->queue_get( skutils::dispatch::get_default_queue_id(), true ) ); @@ -197,10 +194,9 @@ BOOST_AUTO_TEST_CASE( domain_functionality_alive ) { bInsideCall = true; ++nCallCounter; if ( g_bShowDetailedJobLogs ) - skutils::test::test_log_e( - thread_prefix_str() + - "--- async job in queue, invocation " + - std::to_string(size_t( nCallCounter ) - 1)); + skutils::test::test_log_e( thread_prefix_str() + + "--- async job in queue, invocation " + + std::to_string( size_t( nCallCounter ) - 1 ) ); BOOST_REQUIRE( bool( bInsideCall ) ); bInsideCall = false; } ); @@ -208,26 +204,26 @@ BOOST_AUTO_TEST_CASE( domain_functionality_alive ) { // // static const size_t nSleepSeconds = 5, nWaitRoundCount = 5; - for( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++ nWaitRound ) { - skutils::test::test_log_e( thread_prefix_str() - + "waiting for test to complete in round " + std::to_string(nWaitRound+1) - + " of " + std::to_string(nWaitRoundCount) - + ", will sleep " + std::to_string(nSleepSeconds) + " second(s)..." ); - sleep( nSleepSeconds ); - skutils::test::test_log_e( thread_prefix_str() + "done sleeping " + - std::to_string(nSleepSeconds) + - " second(s), end of domain life time..." ); - if( size_t( nExpectedCallCount ) == size_t( nCallCounter ) ) - break; - } // for( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++ nWaitRound ) + for ( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++nWaitRound ) { + skutils::test::test_log_e( + thread_prefix_str() + "waiting for test to complete in round " + + std::to_string( nWaitRound + 1 ) + " of " + std::to_string( nWaitRoundCount ) + + ", will sleep " + std::to_string( nSleepSeconds ) + " second(s)..." ); + sleep( nSleepSeconds ); + skutils::test::test_log_e( thread_prefix_str() + "done sleeping " + + std::to_string( nSleepSeconds ) + + " second(s), end of domain life time..." ); + if ( size_t( nExpectedCallCount ) == size_t( nCallCounter ) ) + break; + } // for( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++ nWaitRound ) // // - skutils::test::test_log_e(thread_prefix_str() + "shutting down domain..."); + skutils::test::test_log_e( thread_prefix_str() + "shutting down domain..." ); pDomain->shutdown(); } // block for domain BOOST_REQUIRE( nExpectedCallCount == nCallCounter ); // - skutils::test::test_log_e( thread_prefix_str() + "end of domain alive test"); + skutils::test::test_log_e( thread_prefix_str() + "end of domain alive test" ); } ); } @@ -237,15 +233,16 @@ BOOST_AUTO_TEST_CASE( domain_functionality_alive ) { BOOST_AUTO_TEST_CASE( job_priorities_alive ) { skutils::test::test_print_header_name( "SkUtils/dispatch/job_priorities_alive" ); skutils::test::with_test_environment( [&]() { - size_t g_arrThreadCounts[] = {1, 2, 4 /*, 8, 16, 32, 64*/}; // tests with different count - // of threads + size_t g_arrThreadCounts[] = { 1, 2, 4 /*, 8, 16, 32, 64*/ }; // tests with different count + // of threads for ( const size_t& nThreadCount : g_arrThreadCounts ) { skutils::test::test_log_e( "# " "-----------------------------------------------------------------------" ); - skutils::test::test_log_e( - "# " - "job_priorities_alive with nThreadCount=" + nThreadCount ); + skutils::test::test_log_e( + "# " + "job_priorities_alive with nThreadCount=" + + nThreadCount ); skutils::test::test_log_e( "# " "-----------------------------------------------------------------------" ); @@ -257,24 +254,23 @@ BOOST_AUTO_TEST_CASE( job_priorities_alive ) { const size_t push_count_at_step_; const size_t sleep_milliseconds_; } g_arrTestDataByPriority[] = { - {"-GOD-------", SKUTILS_DISPATCH_PRIORITY_GOD, 0, 0, false, 10, 1}, - {"-BELOW-GOD-", SKUTILS_DISPATCH_PRIORITY_BELOW_GOD, 0, 0, false, 50, 1}, - {"-ABSOLUTE--", SKUTILS_DISPATCH_PRIORITY_ABSOLUTE, 0, 0, false, 800, 1}, - {"-HIGHEST---", SKUTILS_DISPATCH_PRIORITY_HIGHEST, 0, 0, false, 600, 1}, - {"-HIGH------", SKUTILS_DISPATCH_PRIORITY_HIGH, 0, 0, false, 400, 1}, - {"-NORMAL----", SKUTILS_DISPATCH_PRIORITY_NORMAL, 0, 0, false, 250, 1}, - {"-LOW-------", SKUTILS_DISPATCH_PRIORITY_LOW, 0, 0, false, 80, 1}, - {"-LOWEST----", SKUTILS_DISPATCH_PRIORITY_LOWEST, 0, 0, false, 50, 1}, - {"-TOO-LOW---", SKUTILS_DISPATCH_PRIORITY_LOWEST * 10, 0, 0, false, 40, 1}, - {"-EXTRA-LOW-", SKUTILS_DISPATCH_PRIORITY_LOWEST * 100, 0, 0, false, 30, 1}, - {"-HELL-LOW--", SKUTILS_DISPATCH_PRIORITY_LOWEST * 1000, 0, 0, false, 20, 1}, + { "-GOD-------", SKUTILS_DISPATCH_PRIORITY_GOD, 0, 0, false, 10, 1 }, + { "-BELOW-GOD-", SKUTILS_DISPATCH_PRIORITY_BELOW_GOD, 0, 0, false, 50, 1 }, + { "-ABSOLUTE--", SKUTILS_DISPATCH_PRIORITY_ABSOLUTE, 0, 0, false, 800, 1 }, + { "-HIGHEST---", SKUTILS_DISPATCH_PRIORITY_HIGHEST, 0, 0, false, 600, 1 }, + { "-HIGH------", SKUTILS_DISPATCH_PRIORITY_HIGH, 0, 0, false, 400, 1 }, + { "-NORMAL----", SKUTILS_DISPATCH_PRIORITY_NORMAL, 0, 0, false, 250, 1 }, + { "-LOW-------", SKUTILS_DISPATCH_PRIORITY_LOW, 0, 0, false, 80, 1 }, + { "-LOWEST----", SKUTILS_DISPATCH_PRIORITY_LOWEST, 0, 0, false, 50, 1 }, + { "-TOO-LOW---", SKUTILS_DISPATCH_PRIORITY_LOWEST * 10, 0, 0, false, 40, 1 }, + { "-EXTRA-LOW-", SKUTILS_DISPATCH_PRIORITY_LOWEST * 100, 0, 0, false, 30, 1 }, + { "-HELL-LOW--", SKUTILS_DISPATCH_PRIORITY_LOWEST * 1000, 0, 0, false, 20, 1 }, }; static const size_t cntPriorities = sizeof( g_arrTestDataByPriority ) / sizeof( g_arrTestDataByPriority[0] ); size_t idxPriority; { // block for domain - skutils::test::test_log_e( - thread_prefix_str() + "creating domain instance..." ); + skutils::test::test_log_e( thread_prefix_str() + "creating domain instance..." ); skutils::dispatch::domain_ptr_t pDomain( new skutils::dispatch::domain( nThreadCount ) ); // first parameter threads in pool, if not then then number // of CPUs @@ -282,14 +278,13 @@ BOOST_AUTO_TEST_CASE( job_priorities_alive ) { // std::atomic_bool g_bStopSignalFlag( false ), g_bThreadStoppedFlag( false ); std::thread( [&]() { - skutils::test::test_log_e( - thread_prefix_str() + "test thread entered..." ); + skutils::test::test_log_e( thread_prefix_str() + "test thread entered..." ); // init queues with priorities for ( idxPriority = 0; idxPriority < cntPriorities; ++idxPriority ) { skutils::dispatch::priority_t pri = g_arrTestDataByPriority[idxPriority].priority_; skutils::dispatch::queue_id_t strQueueID = - g_arrTestDataByPriority[idxPriority].id_; + g_arrTestDataByPriority[idxPriority].id_; skutils::dispatch::queue_ptr_t pQueue( pDomain->queue_get( strQueueID, true ) ); pQueue->priority( pri ); @@ -303,8 +298,7 @@ BOOST_AUTO_TEST_CASE( job_priorities_alive ) { // skutils::dispatch::priority_t pri = // g_arrTestDataByPriority[idxPriority].priority_; skutils::dispatch::queue_id_t strQueueID = - g_arrTestDataByPriority[idxPriority] - .id_; + g_arrTestDataByPriority[idxPriority].id_; size_t push_count_at_step = g_arrTestDataByPriority[idxPriority].push_count_at_step_; for ( size_t j = 0; j < push_count_at_step; ++j ) { @@ -330,11 +324,9 @@ BOOST_AUTO_TEST_CASE( job_priorities_alive ) { ++nCallCounter; if ( g_bShowDetailedJobLogs ) skutils::test::test_log_e( - thread_prefix_str() + - "--- async job in queue " + - strQueueID + - ", invocation " + - std::to_string(size_t( nCallCounter ) - 1) ); + thread_prefix_str() + "--- async job in queue " + + strQueueID + ", invocation " + + std::to_string( size_t( nCallCounter ) - 1 ) ); BOOST_REQUIRE( bool( bInsideCall ) ); size_t sleep_milliseconds = g_arrTestDataByPriority[idxPriority].sleep_milliseconds_; @@ -361,36 +353,31 @@ BOOST_AUTO_TEST_CASE( job_priorities_alive ) { g_bThreadStoppedFlag = true; skutils::test::test_log_e( thread_prefix_str() + "test thread is about to leave..." ); - } ) - .detach(); + } ).detach(); // // static const size_t nSleepMilliSeconds = 5000; skutils::test::test_log_e( thread_prefix_str() + "will sleep " + - std::to_string(nSleepMilliSeconds) + - " millisecond(s)..."); + std::to_string( nSleepMilliSeconds ) + + " millisecond(s)..." ); std::this_thread::sleep_for( std::chrono::milliseconds( nSleepMilliSeconds ) ); skutils::test::test_log_e( thread_prefix_str() + "done sleeping " + - std::to_string(nSleepMilliSeconds) + - " millisecond(s)"); + std::to_string( nSleepMilliSeconds ) + + " millisecond(s)" ); // - skutils::test::test_log_e( - thread_prefix_str() + "stopping test thread..." ); + skutils::test::test_log_e( thread_prefix_str() + "stopping test thread..." ); g_bStopSignalFlag = true; for ( ; !g_bThreadStoppedFlag; ) std::this_thread::sleep_for( std::chrono::milliseconds( 20 ) ); skutils::test::test_log_e( - thread_prefix_str() + - "test thread was stopped, end of domain life time..."); + thread_prefix_str() + "test thread was stopped, end of domain life time..." ); - skutils::test::test_log_e( - thread_prefix_str() + "shutting down domain..."); + skutils::test::test_log_e( thread_prefix_str() + "shutting down domain..." ); pDomain->shutdown(); } // block for domain skutils::test::test_log_e( thread_prefix_str() + "analyzing results..." ); // for ( idxPriority = 0; idxPriority < cntPriorities; ++idxPriority ) { - skutils::dispatch::queue_id_t strQueueID = g_arrTestDataByPriority[idxPriority].id_; // skutils::tools::format( // "queue_id_%zu", size_t(pri) ); @@ -413,11 +400,10 @@ BOOST_AUTO_TEST_CASE( job_priorities_alive ) { std::string strMiss = skutils::tools::format( "%.1lf", lfPercentMiss ); skutils::test::test_log_e( - thread_prefix_str() + "queue " + strQueueID + - " was submitted " + std::to_string(size_t( nSubmitCounter )) + - " and called " + std::to_string( size_t( nCallCounter ) ) + - " time(s)" + ", hit " + strHit + "%" + - ", miss " + strMiss + "%"); + thread_prefix_str() + "queue " + strQueueID + " was submitted " + + std::to_string( size_t( nSubmitCounter ) ) + " and called " + + std::to_string( size_t( nCallCounter ) ) + " time(s)" + ", hit " + strHit + + "%" + ", miss " + strMiss + "%" ); BOOST_REQUIRE( !bool( bInsideCall ) ); // if( bInsideCall ) { // int xxx = 0; @@ -441,10 +427,9 @@ BOOST_AUTO_TEST_CASE( job_priorities_alive ) { // even safer condition --- --- --- } // for( idxPriority = 1; // idxPriority < cntPriorities; ++ idxPriority ) // - skutils::test::test_log_e( - thread_prefix_str() + - "end of domain priorities test with nThreadCount=" + - std::to_string(nThreadCount) ); + skutils::test::test_log_e( thread_prefix_str() + + "end of domain priorities test with nThreadCount=" + + std::to_string( nThreadCount ) ); } // for( const size_t & nThreadCount : g_arrThreadCounts ) } ); } @@ -474,22 +459,21 @@ BOOST_AUTO_TEST_CASE( domain_timing_functionality_alive ) { nCallCounterSyncExpected = size_t( nCallCounterAsyncExpected ); // { // block for domain - skutils::test::test_log_e( - thread_prefix_str() + "creating domain instance..." ); + skutils::test::test_log_e( thread_prefix_str() + "creating domain instance..." ); skutils::dispatch::domain_ptr_t pDomain( new skutils::dispatch::domain ); // skutils::dispatch::domain_ptr_t pDomain( skutils::dispatch::default_domain() ); skutils::dispatch::queue_ptr_t pQueue( pDomain->queue_get( skutils::dispatch::get_default_queue_id(), true ) ); skutils::dispatch::queue_ptr_t pQueueSync( pDomain->queue_get( sync_queue_id, true ) ); // - skutils::test::test_log_e( thread_prefix_str() + "adding once job to queue"); + skutils::test::test_log_e( thread_prefix_str() + "adding once job to queue" ); pQueue->job_add_once( [&]() { BOOST_REQUIRE( !bool( bInsideCallOnce ) ); bInsideCallOnce = true; ++nCallCounterOnce; - skutils::test::test_log_e( thread_prefix_str() + "--- once job, invocation " + - std::to_string(size_t( nCallCounterOnce ) - 1 ) ); + skutils::test::test_log_e( thread_prefix_str() + "--- once job, invocation " + + std::to_string( size_t( nCallCounterOnce ) - 1 ) ); BOOST_REQUIRE( bool( bInsideCallOnce ) ); bInsideCallOnce = false; }, @@ -501,34 +485,36 @@ BOOST_AUTO_TEST_CASE( domain_timing_functionality_alive ) { BOOST_REQUIRE( !bool( bInsideCallPeriodic ) ); bInsideCallPeriodic = true; ++nCallCounterPeriodic; - skutils::test::test_log_e( thread_prefix_str() + "--- periodic job, invocation " + - std::to_string(size_t( nCallCounterPeriodic ) - 1 ) ); + skutils::test::test_log_e( + thread_prefix_str() + "--- periodic job, invocation " + + std::to_string( size_t( nCallCounterPeriodic ) - 1 ) ); BOOST_REQUIRE( bool( bInsideCallPeriodic ) ); bInsideCallPeriodic = false; }, skutils::dispatch::duration_from_milliseconds( 500 ) // 0.5 seconds ); // - skutils::test::test_log_e( thread_prefix_str() + "adding async job to queue"); + skutils::test::test_log_e( thread_prefix_str() + "adding async job to queue" ); pQueue->job_add( [&]() { BOOST_REQUIRE( !bool( bInsideCallAsync ) ); bInsideCallAsync = true; ++nCallCounterAsync; skutils::test::test_log_e( thread_prefix_str() + "--- async job, invocation " + - std::to_string(size_t( nCallCounterAsync ) - 1 ) ); + std::to_string( size_t( nCallCounterAsync ) - 1 ) ); // - skutils::test::test_log_e( thread_prefix_str() + "will invoke sync job"); + skutils::test::test_log_e( thread_prefix_str() + "will invoke sync job" ); pQueueSync->job_run_sync( [&]() { BOOST_REQUIRE( !bool( bInsideCallSync ) ); bInsideCallSync = true; ++nCallCounterSync; - skutils::test::test_log_e( thread_prefix_str() + "--- sync job, invocation " + - std::to_string(size_t( nCallCounterSync ) - 1 ) ); + skutils::test::test_log_e( + thread_prefix_str() + "--- sync job, invocation " + + std::to_string( size_t( nCallCounterSync ) - 1 ) ); BOOST_REQUIRE( bool( bInsideCallSync ) ); bInsideCallSync = false; } ); - skutils::test::test_log_e(thread_prefix_str() + "did invoked sync job" ); + skutils::test::test_log_e( thread_prefix_str() + "did invoked sync job" ); // BOOST_REQUIRE( bool( bInsideCallAsync ) ); bInsideCallAsync = false; @@ -539,55 +525,48 @@ BOOST_AUTO_TEST_CASE( domain_timing_functionality_alive ) { // // static const size_t nSleepSeconds = 5, nWaitRoundCount = 5; - for( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++ nWaitRound ) { - skutils::test::test_log_e( thread_prefix_str() - + "waiting for test to complete in round " + std::to_string(nWaitRound+1) - + " of " + std::to_string(nWaitRoundCount) - + ", will sleep " + std::to_string(nSleepSeconds) + " second(s)..." ); - sleep( nSleepSeconds ); - skutils::test::test_log_e( thread_prefix_str() + "done sleeping " + - std::to_string(nSleepSeconds) + - " second(s), end of domain life time..." ); - if( size_t( nCallCounterOnce ) >= 1 - && size_t( nCallCounterPeriodic ) >= size_t( nCallCounterPeriodicExpected ) - && size_t( nCallCounterAsync ) >= size_t( nCallCounterAsyncExpected ) - && size_t( nCallCounterSync ) >= size_t( nCallCounterSyncExpected ) - ) - break; - } // for( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++ nWaitRound ) + for ( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++nWaitRound ) { + skutils::test::test_log_e( + thread_prefix_str() + "waiting for test to complete in round " + + std::to_string( nWaitRound + 1 ) + " of " + std::to_string( nWaitRoundCount ) + + ", will sleep " + std::to_string( nSleepSeconds ) + " second(s)..." ); + sleep( nSleepSeconds ); + skutils::test::test_log_e( thread_prefix_str() + "done sleeping " + + std::to_string( nSleepSeconds ) + + " second(s), end of domain life time..." ); + if ( size_t( nCallCounterOnce ) >= 1 && + size_t( nCallCounterPeriodic ) >= size_t( nCallCounterPeriodicExpected ) && + size_t( nCallCounterAsync ) >= size_t( nCallCounterAsyncExpected ) && + size_t( nCallCounterSync ) >= size_t( nCallCounterSyncExpected ) ) + break; + } // for( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++ nWaitRound ) // // - skutils::test::test_log_e( - thread_prefix_str() + "shutting down domain..." ); + skutils::test::test_log_e( thread_prefix_str() + "shutting down domain..." ); pDomain->shutdown(); } // block for domain + skutils::test::test_log_e( "once job expected exactly one call, was called " + + std::to_string( size_t( nCallCounterOnce ) ) + ", " + + ( ( size_t( nCallCounterOnce ) == 1 ) ? "success" : "fail" ) ); skutils::test::test_log_e( - "once job expected exactly one call, was called " + - std::to_string( size_t( nCallCounterOnce ) ) + - ", " + - ( ( size_t( nCallCounterOnce ) == 1 ) ? "success" : - "fail")); - skutils::test::test_log_e( - "periodic job expected call(s) at least " + - std::to_string( size_t( nCallCounterPeriodicExpected ) ) + ", was called " + - std::to_string( size_t( nCallCounterPeriodic ) ) + ", " + + "periodic job expected call(s) at least " + + std::to_string( size_t( nCallCounterPeriodicExpected ) ) + ", was called " + + std::to_string( size_t( nCallCounterPeriodic ) ) + ", " + ( ( size_t( nCallCounterPeriodic ) >= size_t( nCallCounterPeriodicExpected ) ) ? - "success" : - "fail") ); + "success" : + "fail" ) ); skutils::test::test_log_e( "async job expected call(s) at least " + - std::to_string( size_t( nCallCounterAsyncExpected ) ) + ", was called " + - std::to_string( size_t( nCallCounterAsync ) ) + ", " + - ( ( size_t( nCallCounterAsync ) >= size_t( nCallCounterAsyncExpected ) ) ? - "success" : - "fail" ) ); + std::to_string( size_t( nCallCounterAsyncExpected ) ) + ", was called " + + std::to_string( size_t( nCallCounterAsync ) ) + ", " + + ( ( size_t( nCallCounterAsync ) >= size_t( nCallCounterAsyncExpected ) ) ? "success" : + "fail" ) ); skutils::test::test_log_e( - "sync job expected call(s) at least " + - std::to_string( size_t( nCallCounterSyncExpected ) ) + ", was called " + - std::to_string( size_t( nCallCounterSync ) ) + ", " + - ( ( size_t( nCallCounterSync ) >= size_t( nCallCounterSyncExpected ) ) ? - "success" : - "fail" ) ); + "sync job expected call(s) at least " + + std::to_string( size_t( nCallCounterSyncExpected ) ) + ", was called " + + std::to_string( size_t( nCallCounterSync ) ) + ", " + + ( ( size_t( nCallCounterSync ) >= size_t( nCallCounterSyncExpected ) ) ? "success" : + "fail" ) ); BOOST_REQUIRE( size_t( nCallCounterOnce ) == 1 ); BOOST_REQUIRE( size_t( nCallCounterPeriodic ) >= size_t( nCallCounterPeriodicExpected ) ); BOOST_REQUIRE( size_t( nCallCounterAsync ) >= size_t( nCallCounterAsyncExpected ) ); @@ -625,26 +604,28 @@ BOOST_AUTO_TEST_CASE( simple_api ) { // // skutils::dispatch::add( sync_queue_id ); // - skutils::test::test_log_e( thread_prefix_str() + "adding once job to queue" ); - skutils::dispatch::once( skutils::dispatch::get_default_queue_id(), + skutils::test::test_log_e( thread_prefix_str() + "adding once job to queue" ); + skutils::dispatch::once( + skutils::dispatch::get_default_queue_id(), [&]() { BOOST_REQUIRE( !bool( bInsideCallOnce ) ); bInsideCallOnce = true; ++nCallCounterOnce; - skutils::test::test_log_e( thread_prefix_str() + "--- once job, invocation " + + skutils::test::test_log_e( thread_prefix_str() + "--- once job, invocation " + std::to_string( size_t( nCallCounterOnce ) - 1 ) ); BOOST_REQUIRE( bool( bInsideCallOnce ) ); bInsideCallOnce = false; }, skutils::dispatch::duration_from_seconds( 1 ) ); // - skutils::test::test_log_e( thread_prefix_str() + "adding periodic job to queue" ); - skutils::dispatch::repeat( skutils::dispatch::get_default_queue_id(), + skutils::test::test_log_e( thread_prefix_str() + "adding periodic job to queue" ); + skutils::dispatch::repeat( + skutils::dispatch::get_default_queue_id(), [&]() { BOOST_REQUIRE( !bool( bInsideCallPeriodic ) ); bInsideCallPeriodic = true; ++nCallCounterPeriodic; - skutils::test::test_log_e( thread_prefix_str() + "--- periodic job, invocation " + + skutils::test::test_log_e( thread_prefix_str() + "--- periodic job, invocation " + std::to_string( size_t( nCallCounterPeriodic ) - 1 ) ); BOOST_REQUIRE( bool( bInsideCallPeriodic ) ); bInsideCallPeriodic = false; @@ -652,26 +633,27 @@ BOOST_AUTO_TEST_CASE( simple_api ) { skutils::dispatch::duration_from_milliseconds( 500 ) // 0.5 seconds ); // - skutils::test::test_log_e( thread_prefix_str() + "adding async job to queue" ); - skutils::dispatch::async( skutils::dispatch::get_default_queue_id(), + skutils::test::test_log_e( thread_prefix_str() + "adding async job to queue" ); + skutils::dispatch::async( + skutils::dispatch::get_default_queue_id(), [&]() { BOOST_REQUIRE( !bool( bInsideCallAsync ) ); bInsideCallAsync = true; ++nCallCounterAsync; - skutils::test::test_log_e( thread_prefix_str() + "--- async job, invocation " + + skutils::test::test_log_e( thread_prefix_str() + "--- async job, invocation " + std::to_string( size_t( nCallCounterAsync ) - 1 ) ); // - skutils::test::test_log_e( thread_prefix_str() + "will invoke sync job" ); + skutils::test::test_log_e( thread_prefix_str() + "will invoke sync job" ); skutils::dispatch::sync( sync_queue_id, [&]() { BOOST_REQUIRE( !bool( bInsideCallSync ) ); bInsideCallSync = true; ++nCallCounterSync; - skutils::test::test_log_e( thread_prefix_str() + "--- sync job, invocation " + + skutils::test::test_log_e( thread_prefix_str() + "--- sync job, invocation " + std::to_string( size_t( nCallCounterSync ) - 1 ) ); BOOST_REQUIRE( bool( bInsideCallSync ) ); bInsideCallSync = false; } ); - skutils::test::test_log_e( thread_prefix_str() + "did invoked sync job" ); + skutils::test::test_log_e( thread_prefix_str() + "did invoked sync job" ); // BOOST_REQUIRE( bool( bInsideCallAsync ) ); bInsideCallAsync = false; @@ -682,55 +664,49 @@ BOOST_AUTO_TEST_CASE( simple_api ) { // // static const size_t nSleepSeconds = 5, nWaitRoundCount = 5; - for( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++ nWaitRound ) { - skutils::test::test_log_e( thread_prefix_str() - + "waiting for test to complete in round " + std::to_string( nWaitRound+1 ) - + " of " + std::to_string( nWaitRoundCount ) - + ", will sleep " + std::to_string( nSleepSeconds ) + " second(s)..." ); - sleep( nSleepSeconds ); - skutils::test::test_log_e( thread_prefix_str() + "done sleeping " + - std::to_string( nSleepSeconds ) + - " second(s), end of domain life time..." ); - if( size_t( nCallCounterOnce ) == 1 - && size_t( nCallCounterPeriodic ) >= size_t( nCallCounterPeriodicExpected ) - && size_t( nCallCounterAsync ) >= size_t( nCallCounterAsyncExpected ) - && size_t( nCallCounterSync ) >= size_t( nCallCounterSyncExpected ) - ) - break; - } // for( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++ nWaitRound ) + for ( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++nWaitRound ) { + skutils::test::test_log_e( + thread_prefix_str() + "waiting for test to complete in round " + + std::to_string( nWaitRound + 1 ) + " of " + std::to_string( nWaitRoundCount ) + + ", will sleep " + std::to_string( nSleepSeconds ) + " second(s)..." ); + sleep( nSleepSeconds ); + skutils::test::test_log_e( thread_prefix_str() + "done sleeping " + + std::to_string( nSleepSeconds ) + + " second(s), end of domain life time..." ); + if ( size_t( nCallCounterOnce ) == 1 && + size_t( nCallCounterPeriodic ) >= size_t( nCallCounterPeriodicExpected ) && + size_t( nCallCounterAsync ) >= size_t( nCallCounterAsyncExpected ) && + size_t( nCallCounterSync ) >= size_t( nCallCounterSyncExpected ) ) + break; + } // for( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++ nWaitRound ) // // - skutils::test::test_log_e( - thread_prefix_str() + "shutting down default domain..." ); + skutils::test::test_log_e( thread_prefix_str() + "shutting down default domain..." ); skutils::dispatch::shutdown(); // // + skutils::test::test_log_e( "once job expected exactly one call, was called " + + std::to_string( size_t( nCallCounterOnce ) ) + ", " + + ( ( size_t( nCallCounterOnce ) == 1 ) ? "success" : "fail" ) ); skutils::test::test_log_e( - "once job expected exactly one call, was called " + - std::to_string( size_t( nCallCounterOnce ) ) + - ", " + ( ( size_t( nCallCounterOnce ) == 1 ) ? "success" : - "fail" ) ); - skutils::test::test_log_e( - "periodic job expected call(s) at least " + - std::to_string( size_t( nCallCounterPeriodicExpected ) ) + ", was called " + - std::to_string( size_t( nCallCounterPeriodic ) ) + ", " + + "periodic job expected call(s) at least " + + std::to_string( size_t( nCallCounterPeriodicExpected ) ) + ", was called " + + std::to_string( size_t( nCallCounterPeriodic ) ) + ", " + ( ( size_t( nCallCounterPeriodic ) >= size_t( nCallCounterPeriodicExpected ) ) ? - "success" : - "fail" ) ); + "success" : + "fail" ) ); skutils::test::test_log_e( "async job expected call(s) at least " + - std::to_string( size_t( nCallCounterAsyncExpected ) ) + ", was called " + - std::to_string( size_t( nCallCounterAsync ) ) + ", " + - ( ( size_t( nCallCounterAsync ) >= size_t( nCallCounterAsyncExpected ) ) ? - "success" : - "fail" ) ); + std::to_string( size_t( nCallCounterAsyncExpected ) ) + ", was called " + + std::to_string( size_t( nCallCounterAsync ) ) + ", " + + ( ( size_t( nCallCounterAsync ) >= size_t( nCallCounterAsyncExpected ) ) ? "success" : + "fail" ) ); skutils::test::test_log_e( - "sync job expected call(s) at least " + - std::to_string( size_t( nCallCounterSyncExpected ) ) + ", was called " + - std::to_string( size_t( nCallCounterSync ) ) + ", " + - ( ( size_t( nCallCounterSync ) >= size_t( nCallCounterSyncExpected ) ) ? - "success" : - "fail" ) ); + "sync job expected call(s) at least " + + std::to_string( size_t( nCallCounterSyncExpected ) ) + ", was called " + + std::to_string( size_t( nCallCounterSync ) ) + ", " + + ( ( size_t( nCallCounterSync ) >= size_t( nCallCounterSyncExpected ) ) ? "success" : + "fail" ) ); BOOST_REQUIRE( size_t( nCallCounterOnce ) == 1 ); BOOST_REQUIRE( size_t( nCallCounterPeriodic ) >= size_t( nCallCounterPeriodicExpected ) ); BOOST_REQUIRE( size_t( nCallCounterAsync ) >= size_t( nCallCounterAsyncExpected ) ); @@ -758,26 +734,24 @@ BOOST_AUTO_TEST_CASE( auto_queues ) { // // skutils::dispatch::add( sync_queue_id ); // - skutils::test::test_log_e( thread_prefix_str() + "adding async periodical job to auto queue" ); + skutils::test::test_log_e( + thread_prefix_str() + "adding async periodical job to auto queue" ); skutils::dispatch::job_id_t async_job_id0; skutils::dispatch::job_id_t async_job_id1; skutils::dispatch::job_id_t async_job_id2; auto fn = [&]() { ++nCallCounterAsync; - skutils::test::test_log_e( - thread_prefix_str() + "--- async periodical job, invocation " - + std::to_string( size_t( nCallCounterAsync ) - 1 ) ); + skutils::test::test_log_e( thread_prefix_str() + + "--- async periodical job, invocation " + + std::to_string( size_t( nCallCounterAsync ) - 1 ) ); // - skutils::test::test_log_e( - thread_prefix_str() + "will invoke " + "sync job" ); + skutils::test::test_log_e( thread_prefix_str() + "will invoke " + "sync job" ); skutils::dispatch::sync( sync_queue_id, [&]() { ++nCallCounterSync; - skutils::test::test_log_e( - thread_prefix_str() + "--- sync job" + - ", invocation " + std::to_string( size_t( nCallCounterSync ) - 1 ) ); + skutils::test::test_log_e( thread_prefix_str() + "--- sync job" + ", invocation " + + std::to_string( size_t( nCallCounterSync ) - 1 ) ); } ); - skutils::test::test_log_e( - thread_prefix_str() + "did invoked sync job" ); + skutils::test::test_log_e( thread_prefix_str() + "did invoked sync job" ); // }; skutils::dispatch::async( fn, @@ -785,53 +759,54 @@ BOOST_AUTO_TEST_CASE( auto_queues ) { skutils::dispatch::duration_from_milliseconds( 1500 ), // 1.5 seconds &async_job_id0 ); BOOST_REQUIRE( !async_job_id0.empty() ); - skutils::test::test_log_e( thread_prefix_str() + "done, did added async periodical job to auto queue, job id is " + + skutils::test::test_log_e( + thread_prefix_str() + "done, did added async periodical job to auto queue, job id is " + async_job_id0 ); skutils::dispatch::async( fn, skutils::dispatch::duration_from_seconds( 2 ), // 2 seconds skutils::dispatch::duration_from_milliseconds( 1500 ), // 1.5 seconds &async_job_id1 ); BOOST_REQUIRE( !async_job_id1.empty() ); - skutils::test::test_log_e( thread_prefix_str() + "done, did added async periodical job to auto queue, job id is " + - async_job_id1 ); + skutils::test::test_log_e( + thread_prefix_str() + "done, did added async periodical job to auto queue, job id is " + + async_job_id1 ); skutils::dispatch::async( fn, skutils::dispatch::duration_from_seconds( 2 ), // 2 seconds skutils::dispatch::duration_from_milliseconds( 1500 ), // 1.5 seconds &async_job_id2 ); BOOST_REQUIRE( !async_job_id2.empty() ); - skutils::test::test_log_e( thread_prefix_str() + "done, did added async periodical job to auto queue, job id is " + async_job_id2 ); + skutils::test::test_log_e( + thread_prefix_str() + "done, did added async periodical job to auto queue, job id is " + + async_job_id2 ); // // static const size_t nSleepSeconds = 5, nWaitRoundCount = 5; - for( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++ nWaitRound ) { - skutils::test::test_log_e( thread_prefix_str() - + "waiting for test to complete in round " + std::to_string( nWaitRound+1 ) - + " of " + std::to_string( nWaitRoundCount ) - + ", will sleep " + std::to_string( nSleepSeconds ) + " second(s)..." ); - sleep( nSleepSeconds ); - skutils::test::test_log_e( thread_prefix_str() + "done sleeping " + - std::to_string( nSleepSeconds ) + - " second(s), end of domain life time..." ); - if( size_t( nCallCounterAsync ) >= size_t( nCallCounterAsyncExpected ) - && size_t( nCallCounterSync ) >= size_t( nCallCounterSyncExpected ) - && size_t( nCallCounterAsync ) >= size_t( nCallCounterAsyncExpected ) - && size_t( nCallCounterSync ) >= size_t( nCallCounterSyncExpected ) - && size_t( nCallCounterSync ) >= size_t( nCallCounterAsync ) - ) - break; - } // for( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++ nWaitRound ) + for ( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++nWaitRound ) { + skutils::test::test_log_e( + thread_prefix_str() + "waiting for test to complete in round " + + std::to_string( nWaitRound + 1 ) + " of " + std::to_string( nWaitRoundCount ) + + ", will sleep " + std::to_string( nSleepSeconds ) + " second(s)..." ); + sleep( nSleepSeconds ); + skutils::test::test_log_e( thread_prefix_str() + "done sleeping " + + std::to_string( nSleepSeconds ) + + " second(s), end of domain life time..." ); + if ( size_t( nCallCounterAsync ) >= size_t( nCallCounterAsyncExpected ) && + size_t( nCallCounterSync ) >= size_t( nCallCounterSyncExpected ) && + size_t( nCallCounterAsync ) >= size_t( nCallCounterAsyncExpected ) && + size_t( nCallCounterSync ) >= size_t( nCallCounterSyncExpected ) && + size_t( nCallCounterSync ) >= size_t( nCallCounterAsync ) ) + break; + } // for( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++ nWaitRound ) // // - skutils::test::test_log_e( thread_prefix_str() + "stopping async periodical job " + - async_job_id0 + "..."); + skutils::test::test_log_e( + thread_prefix_str() + "stopping async periodical job " + async_job_id0 + "..." ); skutils::dispatch::stop( async_job_id0 ); - skutils::test::test_log_e( thread_prefix_str() + - "stopping async periodical job " + - async_job_id1 + "..." ); + skutils::test::test_log_e( + thread_prefix_str() + "stopping async periodical job " + async_job_id1 + "..." ); skutils::dispatch::stop( async_job_id1 ); - skutils::test::test_log_e( thread_prefix_str() + - "stopping async periodical job " + - async_job_id2 + "..." ); + skutils::test::test_log_e( + thread_prefix_str() + "stopping async periodical job " + async_job_id2 + "..." ); skutils::dispatch::stop( async_job_id2 ); // skutils::dispatch::set_queue_ids_t setQueueIDs; @@ -843,24 +818,21 @@ BOOST_AUTO_TEST_CASE( auto_queues ) { setQueueIDs = skutils::dispatch::get_all_names(); BOOST_REQUIRE( setQueueIDs.size() == 0 ); // - skutils::test::test_log_e( - thread_prefix_str() + "shutting down default domain..." ); + skutils::test::test_log_e( thread_prefix_str() + "shutting down default domain..." ); skutils::dispatch::shutdown(); // skutils::test::test_log_e( "async job expected call(s) at least " + - std::to_string( size_t( nCallCounterAsyncExpected ) ) + ", was called " + - std::to_string( size_t( nCallCounterAsync ) ) + ", " + - ( ( size_t( nCallCounterAsync ) >= size_t( nCallCounterAsyncExpected ) ) ? - "success" : - "fail" ) ); + std::to_string( size_t( nCallCounterAsyncExpected ) ) + ", was called " + + std::to_string( size_t( nCallCounterAsync ) ) + ", " + + ( ( size_t( nCallCounterAsync ) >= size_t( nCallCounterAsyncExpected ) ) ? "success" : + "fail" ) ); skutils::test::test_log_e( - "sync job expected call(s) at least " + - std::to_string( size_t( nCallCounterSyncExpected ) ) + ", was called " + - std::to_string( size_t( nCallCounterSync ) ) + ", " + - ( ( size_t( nCallCounterSync ) >= size_t( nCallCounterSyncExpected ) ) ? - "success" : - "fail" ) ); + "sync job expected call(s) at least " + + std::to_string( size_t( nCallCounterSyncExpected ) ) + ", was called " + + std::to_string( size_t( nCallCounterSync ) ) + ", " + + ( ( size_t( nCallCounterSync ) >= size_t( nCallCounterSyncExpected ) ) ? "success" : + "fail" ) ); BOOST_REQUIRE( size_t( nCallCounterAsync ) >= size_t( nCallCounterAsyncExpected ) ); BOOST_REQUIRE( size_t( nCallCounterSync ) >= size_t( nCallCounterSyncExpected ) ); BOOST_REQUIRE( size_t( nCallCounterSync ) >= size_t( nCallCounterAsync ) ); @@ -892,9 +864,8 @@ BOOST_AUTO_TEST_CASE( cross_jobs ) { skutils::tools::format( "queue_%zu", i ); skutils::dispatch::queue_id_t id_queue_next = skutils::tools::format( "queue_%zu", j ); if ( g_bShowDetailedJobLogs ) - skutils::test::test_log_e( thread_prefix_str() + - "...will add async job to queue " + - id_queue_current + "..." ); + skutils::test::test_log_e( thread_prefix_str() + "...will add async job to queue " + + id_queue_current + "..." ); skutils::dispatch::async( id_queue_current, [&vecInside, &vecCallCount, i, j, id_queue_current, id_queue_next]() { BOOST_REQUIRE( !bool( vecInside[i] ) ); @@ -902,33 +873,28 @@ BOOST_AUTO_TEST_CASE( cross_jobs ) { BOOST_REQUIRE( bool( vecInside[i] ) ); vecCallCount[i]++; if ( i != 0 ) { // condition to avoid chained lock - skutils::test::test_log_e( - thread_prefix_str() + "--> worker " + - id_queue_current + " will invoke " + - id_queue_next ); + skutils::test::test_log_e( thread_prefix_str() + "--> worker " + + id_queue_current + " will invoke " + id_queue_next ); skutils::dispatch::sync( id_queue_next, [&vecInside, &vecCallCount, i, j, id_queue_current, id_queue_next]() { BOOST_REQUIRE( !bool( vecInside[j] ) ); vecInside[j] = true; BOOST_REQUIRE( bool( vecInside[j] ) ); vecCallCount[j]++; - skutils::test::test_log_e( - thread_prefix_str() + "<-- worker " + - id_queue_next + " invoked from " + - id_queue_current ); + skutils::test::test_log_e( thread_prefix_str() + "<-- worker " + + id_queue_next + " invoked from " + + id_queue_current ); BOOST_REQUIRE( bool( vecInside[j] ) ); vecInside[j] = false; BOOST_REQUIRE( !bool( vecInside[j] ) ); } ); } else { - skutils::test::test_log_e( - thread_prefix_str() + "--> worker " + - id_queue_current + " will invoke " + - id_queue_next + "(emulation)" ); - skutils::test::test_log_e( - thread_prefix_str() + "<-- worker " + - id_queue_next + " invoked from " + - id_queue_current + "(emulation)" ); + skutils::test::test_log_e( thread_prefix_str() + "--> worker " + + id_queue_current + " will invoke " + id_queue_next + + "(emulation)" ); + skutils::test::test_log_e( thread_prefix_str() + "<-- worker " + id_queue_next + + " invoked from " + id_queue_current + + "(emulation)" ); vecCallCount[j]++; // invocation emilation } BOOST_REQUIRE( bool( vecInside[i] ) ); @@ -938,75 +904,68 @@ BOOST_AUTO_TEST_CASE( cross_jobs ) { } // // - bool isEverythingOKay = true; // assume good thing + bool isEverythingOKay = true; // assume good thing static const size_t nSleepSeconds = 5, nWaitRoundCount = 5; - for( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++ nWaitRound ) { - skutils::test::test_log_e( thread_prefix_str() - + "waiting for test to complete in round " + std::to_string( nWaitRound+1 ) - + " of " + std::to_string( nWaitRoundCount ) - + ", will sleep " + std::to_string( nSleepSeconds ) + " second(s)..." ); - sleep( nSleepSeconds ); - skutils::test::test_log_e( thread_prefix_str() + "done sleeping " + - std::to_string( nSleepSeconds ) + - " second(s), end of domain life time..." ); - // - // - // pre-liminary attempt to find out everything is OKay - skutils::test::test_log_e( - thread_prefix_str() + "performing preliminary state test..." ); - isEverythingOKay = true; // assume good thing - for ( i = 0; i < nQueueCount; ++i ) { - bool bInside = bool( vecInside[i] ); + for ( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++nWaitRound ) { skutils::test::test_log_e( - thread_prefix_str() + "queue " + std::to_string( i ) + - " is " + - ( ( !bInside ) ? "OKay" : "STILL WORKING - FAIL" ) ); - if ( bInside ) { - isEverythingOKay = false; - break; - } - skutils::dispatch::queue_id_t id_queue_current = - skutils::tools::format( "queue_%zu", i ); - skutils::dispatch::queue_ptr_t pQueue = - skutils::dispatch::get( id_queue_current, false ); - size_t nQueueJobCount = pQueue->async_job_count(); - // BOOST_REQUIRE( nQueueJobCount == 0 ); + thread_prefix_str() + "waiting for test to complete in round " + + std::to_string( nWaitRound + 1 ) + " of " + std::to_string( nWaitRoundCount ) + + ", will sleep " + std::to_string( nSleepSeconds ) + " second(s)..." ); + sleep( nSleepSeconds ); + skutils::test::test_log_e( thread_prefix_str() + "done sleeping " + + std::to_string( nSleepSeconds ) + + " second(s), end of domain life time..." ); + // + // + // pre-liminary attempt to find out everything is OKay skutils::test::test_log_e( - thread_prefix_str() + "worker " + id_queue_current + - " has " + std::to_string( nQueueJobCount ) + - " job(s) unfinished " + - ( ( nQueueJobCount == 0 ) ? "OKay" : - "FAIL, MUST BE ZERO" ) ); - } - skutils::test::test_log_e( - thread_prefix_str() + "done preliminary state test - " + - ( isEverythingOKay ? "PASSED" : "FAILED" ) ); - if( isEverythingOKay ) - break; - } // for( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++ nWaitRound ) + thread_prefix_str() + "performing preliminary state test..." ); + isEverythingOKay = true; // assume good thing + for ( i = 0; i < nQueueCount; ++i ) { + bool bInside = bool( vecInside[i] ); + skutils::test::test_log_e( thread_prefix_str() + "queue " + std::to_string( i ) + + " is " + + ( ( !bInside ) ? "OKay" : "STILL WORKING - FAIL" ) ); + if ( bInside ) { + isEverythingOKay = false; + break; + } + skutils::dispatch::queue_id_t id_queue_current = + skutils::tools::format( "queue_%zu", i ); + skutils::dispatch::queue_ptr_t pQueue = + skutils::dispatch::get( id_queue_current, false ); + size_t nQueueJobCount = pQueue->async_job_count(); + // BOOST_REQUIRE( nQueueJobCount == 0 ); + skutils::test::test_log_e( + thread_prefix_str() + "worker " + id_queue_current + " has " + + std::to_string( nQueueJobCount ) + " job(s) unfinished " + + ( ( nQueueJobCount == 0 ) ? "OKay" : "FAIL, MUST BE ZERO" ) ); + } + skutils::test::test_log_e( thread_prefix_str() + "done preliminary state test - " + + ( isEverythingOKay ? "PASSED" : "FAILED" ) ); + if ( isEverythingOKay ) + break; + } // for( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++ nWaitRound ) // // if ( !isEverythingOKay ) { static const size_t nSleepSecondsExtraAttempt = 10; skutils::test::test_log_e( thread_prefix_str() + "will sleep additional " + std::to_string( nSleepSecondsExtraAttempt ) + - " second(s)..." ); + " second(s)..." ); sleep( nSleepSecondsExtraAttempt ); - skutils::test::test_log_e( thread_prefix_str() + - "done sleeping additional " + + skutils::test::test_log_e( thread_prefix_str() + "done sleeping additional " + std::to_string( nSleepSecondsExtraAttempt ) + - " second(s), end of domain life time..." ); + " second(s), end of domain life time..." ); } // // final test - skutils::test::test_log_e( - thread_prefix_str() + "performing final state test..." ); + skutils::test::test_log_e( thread_prefix_str() + "performing final state test..." ); for ( i = 0; i < nQueueCount; ++i ) { bool bInside = bool( vecInside[i] ); - skutils::test::test_log_e( - thread_prefix_str() + "queue " + std::to_string( i ) + - " is " + - ( ( !bInside ) ? "OKay" : "STILL WORKING - FAIL") ); + skutils::test::test_log_e( thread_prefix_str() + "queue " + std::to_string( i ) + + " is " + + ( ( !bInside ) ? "OKay" : "STILL WORKING - FAIL" ) ); BOOST_REQUIRE( !bInside ); skutils::dispatch::queue_id_t id_queue_current = skutils::tools::format( "queue_%zu", i ); @@ -1015,26 +974,22 @@ BOOST_AUTO_TEST_CASE( cross_jobs ) { size_t nQueueJobCount = pQueue->async_job_count(); // BOOST_REQUIRE( nQueueJobCount == 0 ); skutils::test::test_log_e( - thread_prefix_str() + "worker " + id_queue_current + - " has " + std::to_string( nQueueJobCount ) + - " job(s) unfinished " + - ( ( nQueueJobCount == 0 ) ? "OKay" : - "FAIL, MUST BE ZERO" ) ); + thread_prefix_str() + "worker " + id_queue_current + " has " + + std::to_string( nQueueJobCount ) + " job(s) unfinished " + + ( ( nQueueJobCount == 0 ) ? "OKay" : "FAIL, MUST BE ZERO" ) ); } skutils::test::test_log_e( thread_prefix_str() + "done final state test - PASSED" ); // - skutils::test::test_log_e( - thread_prefix_str() + "shutting down default domain..." ); + skutils::test::test_log_e( thread_prefix_str() + "shutting down default domain..." ); skutils::dispatch::shutdown(); // for ( i = 0; i < nQueueCount; ++i ) { BOOST_REQUIRE( !bool( vecInside[i] ) ); skutils::dispatch::queue_id_t id_queue_current = skutils::tools::format( "queue_%zu", i ); - skutils::test::test_log_e( - thread_prefix_str() + "worker " + id_queue_current + - " was invoked " + std::to_string( vecCallCount[i] ) + - " time(s)" ); + skutils::test::test_log_e( thread_prefix_str() + "worker " + id_queue_current + + " was invoked " + std::to_string( vecCallCount[i] ) + + " time(s)" ); } size_t nCallCountFirst = vecCallCount.front(); BOOST_REQUIRE( nCallCountFirst > 0 ); @@ -1062,12 +1017,12 @@ BOOST_AUTO_TEST_CASE( enqueue_while_busy ) { auto fnLog = [&]( const char* s ) -> void { lock_type lock( mtx ); log_sequence.push_back( s ); - skutils::test::test_log_e( thread_prefix_str() + "--- " + s ); + skutils::test::test_log_e( thread_prefix_str() + "--- " + s ); }; - auto fnLogSequenceSize = [&]( ) -> size_t { - lock_type lock( mtx ); - size_t n = log_sequence.size(); - return n; + auto fnLogSequenceSize = [&]() -> size_t { + lock_type lock( mtx ); + size_t n = log_sequence.size(); + return n; }; const char g_strLogText_LengthyWork_begin[] = "lengthy work begin"; const char g_strLogText_LengthyWork_end[] = "lengthy work end"; @@ -1190,10 +1145,10 @@ BOOST_AUTO_TEST_CASE( enqueue_while_busy ) { BOOST_REQUIRE( !bool( bInside_ShortWork_2 ) ); BOOST_REQUIRE( !bool( bInside_SyncWork ) ); } ); - skutils::test::test_log_e( thread_prefix_str() + "awaiting 500 milliseconds" ); + skutils::test::test_log_e( thread_prefix_str() + "awaiting 500 milliseconds" ); std::this_thread::sleep_for( std::chrono::milliseconds( 500 ) ); skutils::test::test_log_e( - thread_prefix_str() + "done, finished awaiting 500 milliseconds" ); + thread_prefix_str() + "done, finished awaiting 500 milliseconds" ); skutils::dispatch::sync( id_my_queue, [&]() { BOOST_REQUIRE( !bool( bInside_LengthyWork ) ); BOOST_REQUIRE( !bool( bInside_ShortWork_0 ) ); @@ -1224,28 +1179,26 @@ BOOST_AUTO_TEST_CASE( enqueue_while_busy ) { // // static const size_t nSleepSeconds = 5, nWaitRoundCount = 5; - for( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++ nWaitRound ) { - skutils::test::test_log_e( thread_prefix_str() - + "waiting for test to complete in round " + std::to_string( nWaitRound+1 ) - + " of " + std::to_string( nWaitRoundCount ) - + ", will sleep " + std::to_string( nSleepSeconds ) + " second(s)..." ); - sleep( nSleepSeconds ); - skutils::test::test_log_e( thread_prefix_str() + "done sleeping " + - std::to_string( nSleepSeconds ) + - " second(s), end of domain life time..." ); - size_t n = fnLogSequenceSize(); - if( n >= 10 ) - break; - } // for( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++ nWaitRound ) + for ( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++nWaitRound ) { + skutils::test::test_log_e( + thread_prefix_str() + "waiting for test to complete in round " + + std::to_string( nWaitRound + 1 ) + " of " + std::to_string( nWaitRoundCount ) + + ", will sleep " + std::to_string( nSleepSeconds ) + " second(s)..." ); + sleep( nSleepSeconds ); + skutils::test::test_log_e( thread_prefix_str() + "done sleeping " + + std::to_string( nSleepSeconds ) + + " second(s), end of domain life time..." ); + size_t n = fnLogSequenceSize(); + if ( n >= 10 ) + break; + } // for( size_t nWaitRound = 0; nWaitRound < nWaitRoundCount; ++ nWaitRound ) // // - skutils::test::test_log_e( - thread_prefix_str() + "shutting down default domain..." ); + skutils::test::test_log_e( thread_prefix_str() + "shutting down default domain..." ); skutils::dispatch::shutdown(); // // - skutils::test::test_log_e( - thread_prefix_str() + "analyzing expected results..." ); + skutils::test::test_log_e( thread_prefix_str() + "analyzing expected results..." ); BOOST_REQUIRE( log_sequence.size() >= 10 ); BOOST_REQUIRE( log_sequence[0] == g_strLogText_LengthyWork_begin ); BOOST_REQUIRE( log_sequence[1] == g_strLogText_LengthyWork_end ); @@ -1258,8 +1211,7 @@ BOOST_AUTO_TEST_CASE( enqueue_while_busy ) { BOOST_REQUIRE( log_sequence[8] == g_strLogText_ShortWork_2_begin ); BOOST_REQUIRE( log_sequence[9] == g_strLogText_ShortWork_2_end ); // - skutils::test::test_log_e( - thread_prefix_str() + "end of enqueue_while_busy test"); + skutils::test::test_log_e( thread_prefix_str() + "end of enqueue_while_busy test" ); } ); } @@ -1268,7 +1220,7 @@ BOOST_AUTO_TEST_CASE( enqueue_while_busy ) { // temporary disable the test // the functionality it tests is not used -//BOOST_AUTO_TEST_CASE( balance_equality ) { +// BOOST_AUTO_TEST_CASE( balance_equality ) { // skutils::test::test_print_header_name( "SkUtils/dispatch/balance_equality" ); // skutils::test::with_test_environment( [&]() { // typedef std::map< skutils::dispatch::queue_id_t, size_t > map_call_counts_t; @@ -1276,7 +1228,8 @@ BOOST_AUTO_TEST_CASE( enqueue_while_busy ) { // typedef std::mutex mutex_type; // typedef std::lock_guard< mutex_type > lock_type; // mutex_type mtx; -// auto fnLogCall = [&]( const skutils::dispatch::queue_id_t& id, size_t& nCallsOut ) -> void { +// auto fnLogCall = [&]( const skutils::dispatch::queue_id_t& id, size_t& nCallsOut ) -> void +// { // lock_type lock( mtx ); // map_call_counts_t::iterator itFind = mapCallCounts.find( id ), itEnd = // mapCallCounts.end(); @@ -1314,7 +1267,9 @@ BOOST_AUTO_TEST_CASE( enqueue_while_busy ) { // fnLogCall( id_my_queue, nCalls ); // BOOST_REQUIRE( nCalls > 0 ); // // if( g_bShowDetailedJobLogs ) -// // skutils::test::test_log_e( thread_prefix_str() + +// // skutils::test::test_log_e( +// thread_prefix_str() +// + // // cc::debug("--- async job in queue ") + cc::info(id_my_queue) + cc::debug(", // // invocation ") + // // cc::size10(size_t(nCalls)-1) ); @@ -1323,8 +1278,10 @@ BOOST_AUTO_TEST_CASE( enqueue_while_busy ) { // } ); // } // for... // } // for... -// skutils::test::test_log_e( thread_prefix_str() + cc::debug( "done overloading queues, " ) + -// cc::size10( cntExpectedCalls ) + cc::debug( " jobs(s) added" ) ); +// skutils::test::test_log_e( thread_prefix_str() + cc::debug( "done overloading queues, " ) +// + +// cc::size10( cntExpectedCalls ) + cc::debug( " jobs(s) added" ) +// ); // static const size_t nSleepSeconds = 5; // skutils::test::test_log_e( thread_prefix_str() + cc::warn( "will sleep " ) + // cc::size10( nSleepSeconds ) + cc::warn( " second(s)..." ) ); @@ -1376,7 +1333,8 @@ BOOST_AUTO_TEST_CASE( enqueue_while_busy ) { // } // BOOST_REQUIRE( nMax > 0 ); // double lfMin = ( double( nMin ) / double( nMax ) ) * 100.0; -// skutils::test::test_log_e( thread_prefix_str() + cc::debug( "got " ) + cc::size10( nMin ) + +// skutils::test::test_log_e( thread_prefix_str() + cc::debug( "got " ) + cc::size10( nMin ) +// + // cc::debug( " min call(s) and " ) + cc::size10( nMax ) + // cc::debug( " max calls" ) ); // skutils::test::test_log_e( thread_prefix_str() + cc::debug( "got min as " ) + @@ -1387,12 +1345,13 @@ BOOST_AUTO_TEST_CASE( enqueue_while_busy ) { // // // skutils::test::test_log_e( // thread_prefix_str() + cc::debug( "got " ) + cc::size10( nCallsSummary ) + -// cc::debug( " call(s) done, max expected calls is " ) + cc::size10( cntExpectedCalls ) ); +// cc::debug( " call(s) done, max expected calls is " ) + cc::size10( cntExpectedCalls ) +// ); // double lfCallsPercent = ( double( nCallsSummary ) / double( cntExpectedCalls ) ) * 100.0; // skutils::test::test_log_e( thread_prefix_str() + cc::debug( "got real calls as " ) + // cc::note( skutils::tools::format( "%.1lf", lfCallsPercent ) ) + -// cc::debug( "%, if assuming max calls as " ) + cc::size10( 100 ) + -// cc::debug( "%" ) ); +// cc::debug( "%, if assuming max calls as " ) + cc::size10( 100 ) +// + cc::debug( "%" ) ); // // // // // skutils::test::test_log_e( diff --git a/test/unittests/libskutils/test_skutils_helper.h b/test/unittests/libskutils/test_skutils_helper.h index 0a2c220f7..fe24e1858 100644 --- a/test/unittests/libskutils/test_skutils_helper.h +++ b/test/unittests/libskutils/test_skutils_helper.h @@ -10,12 +10,12 @@ #include #include #include +#include #include +#include #include #include #include -#include -#include #include #include @@ -130,7 +130,7 @@ class test_ws_peer : public skutils::ws::peer { skutils::ws::e_ws_log_message_type_t eWSLMT, const std::string& msg ) override; std::string desc( bool isColored = true ) const { - return getShortPeerDescription( isColored, false); + return getShortPeerDescription( isColored, false ); } test_server_ws_base& get_test_server(); const test_server_ws_base& get_test_server() const { @@ -154,7 +154,6 @@ class test_server_ws_base : public test_server, public skutils::ws::server { }; - class test_server_ws : public test_server_ws_base { public: test_server_ws( int nListenPort ); @@ -201,25 +200,21 @@ class test_server_https : public test_server_http_base { class test_server_proxygen : public test_server { skutils::http_pg::wrapped_proxygen_server_handle hProxygenServer_ = nullptr; + public: - test_server_proxygen( const char* strBindAddr4, const char* strBindAddr6, - int nListenPortHTTP4, int nListenPortHTTPS4, int nListenPortHTTP6, int nListenPortHTTPS6, - int32_t threads, int32_t threads_limit - ); + test_server_proxygen( const char* strBindAddr4, const char* strBindAddr6, int nListenPortHTTP4, + int nListenPortHTTPS4, int nListenPortHTTP6, int nListenPortHTTPS6, int32_t threads, + int32_t threads_limit ); virtual ~test_server_proxygen(); void stop() override; void run() override; void run_parallel() override; void check_can_listen() override; virtual bool isSSL() const override; + protected: - skutils::result_of_http_request implHandleHttpRequest( - const nlohmann::json & joIn, - const std::string& strOrigin, - int ipVer, - const std::string& strDstAddress, - int nDstPort - ); + skutils::result_of_http_request implHandleHttpRequest( const nlohmann::json& joIn, + const std::string& strOrigin, int ipVer, const std::string& strDstAddress, int nDstPort ); }; diff --git a/test/unittests/libskutils/test_skutils_http.cpp b/test/unittests/libskutils/test_skutils_http.cpp index 01e503151..240a9b1d6 100644 --- a/test/unittests/libskutils/test_skutils_http.cpp +++ b/test/unittests/libskutils/test_skutils_http.cpp @@ -1,7 +1,6 @@ -#include #include "test_skutils_helper.h" -#include #include +#include BOOST_AUTO_TEST_SUITE( SkUtils ) BOOST_AUTO_TEST_SUITE( http, *boost::unit_test::precondition( dev::test::option_all_tests ) ) @@ -16,7 +15,8 @@ BOOST_AUTO_TEST_CASE( http_server_startup_sync ) { } BOOST_AUTO_TEST_CASE( proxygen_server_startup ) { skutils::test::test_print_header_name( "SkUtils/proxygen/proxygen_server_startup" ); - skutils::test::test_protocol_server_startup( "proxygen", skutils::test::g_nDefaultPortProxygen ); + skutils::test::test_protocol_server_startup( + "proxygen", skutils::test::g_nDefaultPortProxygen ); } BOOST_AUTO_TEST_CASE( http_single_call ) { @@ -68,7 +68,7 @@ BOOST_AUTO_TEST_CASE( http_busy_port ) { skutils::test::test_print_header_name( "SkUtils/http/http_busy_port" ); skutils::test::test_protocol_busy_port( "http", skutils::test::g_nDefaultPort ); } -//BOOST_AUTO_TEST_CASE( proxygen_busy_port ) { +// BOOST_AUTO_TEST_CASE( proxygen_busy_port ) { // skutils::test::test_print_header_name( "SkUtils/proxygen/proxygen_busy_port" ); // skutils::test::test_protocol_busy_port( "proxygen", skutils::test::g_nDefaultPortProxygen ); //} diff --git a/test/unittests/libskutils/test_skutils_rest.cpp b/test/unittests/libskutils/test_skutils_rest.cpp index dda07a4ee..386446899 100644 --- a/test/unittests/libskutils/test_skutils_rest.cpp +++ b/test/unittests/libskutils/test_skutils_rest.cpp @@ -19,9 +19,10 @@ BOOST_AUTO_TEST_CASE( ws ) { skutils::test::test_protocol_rest_call( "ws", skutils::test::g_nDefaultPort, true, false ); } -//BOOST_AUTO_TEST_CASE( wss ) { +// BOOST_AUTO_TEST_CASE( wss ) { // skutils::test::test_print_header_name( "SkUtils/rest/call/wss" ); -// skutils::test::test_protocol_rest_call( "wss", skutils::test::g_nDefaultPort + 123, true, false ); +// skutils::test::test_protocol_rest_call( "wss", skutils::test::g_nDefaultPort + 123, true, +// false ); //} BOOST_AUTO_TEST_SUITE_END() diff --git a/test/unittests/libskutils/test_skutils_unddos.cpp b/test/unittests/libskutils/test_skutils_unddos.cpp index 6e1e5504c..14f70e341 100644 --- a/test/unittests/libskutils/test_skutils_unddos.cpp +++ b/test/unittests/libskutils/test_skutils_unddos.cpp @@ -40,13 +40,13 @@ static std::string get_test_unddos_settings() { } )"; - return test; + return test; } BOOST_AUTO_TEST_CASE( basic_counting ) { skutils::unddos::algorithm unddos; - auto test_settings = get_test_unddos_settings(); - nlohmann::json jsonObj = nlohmann::json::parse(test_settings); + auto test_settings = get_test_unddos_settings(); + nlohmann::json jsonObj = nlohmann::json::parse( test_settings ); unddos.load_settings_from_json( jsonObj ); skutils::unddos::time_tick_mark ttmNow = skutils::unddos::now_tick_mark(); BOOST_REQUIRE( unddos.register_call_from_origin( "11.11.11.11", ttmNow ) == diff --git a/test/unittests/libskutils/test_skutils_ws.cpp b/test/unittests/libskutils/test_skutils_ws.cpp index 9d5f9d51f..a3ce34af2 100644 --- a/test/unittests/libskutils/test_skutils_ws.cpp +++ b/test/unittests/libskutils/test_skutils_ws.cpp @@ -1,7 +1,6 @@ -#include #include "test_skutils_helper.h" -#include #include +#include BOOST_AUTO_TEST_SUITE( SkUtils ) BOOST_AUTO_TEST_SUITE( ws, *boost::unit_test::precondition( dev::test::option_all_tests ) ) diff --git a/test/unittests/libtesteth/testHelperTest.cpp b/test/unittests/libtesteth/testHelperTest.cpp index 2ed17b314..2307d1337 100644 --- a/test/unittests/libtesteth/testHelperTest.cpp +++ b/test/unittests/libtesteth/testHelperTest.cpp @@ -29,25 +29,25 @@ using namespace dev::test; BOOST_FIXTURE_TEST_SUITE( TestHelperSuite, TestOutputHelperFixture ) BOOST_AUTO_TEST_SUITE( TranslateNetworks ) -BOOST_AUTO_TEST_CASE( translateNetworks_gteIstanbul, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { - set< string > networks = {">=Istanbul"}; +BOOST_AUTO_TEST_CASE( + translateNetworks_gteIstanbul, *boost::unit_test::precondition( dev::test::run_not_express ) ) { + set< string > networks = { ">=Istanbul" }; networks = test::translateNetworks( networks ); BOOST_CHECK( contains( networks, "Istanbul" ) ); } BOOST_AUTO_TEST_CASE( translateNetworks_gtConstantinople, - + *boost::unit_test::precondition( dev::test::run_not_express ) ) { - set< string > networks = {">Constantinople"}; + set< string > networks = { ">Constantinople" }; networks = test::translateNetworks( networks ); BOOST_CHECK( !contains( networks, "Constantinople" ) ); BOOST_CHECK( contains( networks, "ConstantinopleFix" ) ); } -BOOST_AUTO_TEST_CASE( translateNetworks_gtHomestead, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { - set< string > networks = {"Frontier", ">Homestead"}; +BOOST_AUTO_TEST_CASE( + translateNetworks_gtHomestead, *boost::unit_test::precondition( dev::test::run_not_express ) ) { + set< string > networks = { "Frontier", ">Homestead" }; networks = test::translateNetworks( networks ); BOOST_REQUIRE( networks.count( "Frontier" ) > 0 ); BOOST_REQUIRE( networks.count( "Homestead" ) == 0 ); @@ -57,17 +57,17 @@ BOOST_AUTO_TEST_CASE( translateNetworks_gtHomestead, } } -BOOST_AUTO_TEST_CASE( translateNetworks_geHomestead, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { - set< string > networks = {"Frontier", ">=Homestead"}; +BOOST_AUTO_TEST_CASE( + translateNetworks_geHomestead, *boost::unit_test::precondition( dev::test::run_not_express ) ) { + set< string > networks = { "Frontier", ">=Homestead" }; networks = test::translateNetworks( networks ); for ( auto const& net : test::getNetworks() ) BOOST_REQUIRE( networks.count( test::netIdToString( net ) ) > 0 ); } -BOOST_AUTO_TEST_CASE( translateNetworks_ltHomestead, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { - set< string > networks = {" networks = { " 0 ); for ( auto const& net : test::getNetworks() ) { @@ -76,9 +76,9 @@ BOOST_AUTO_TEST_CASE( translateNetworks_ltHomestead, } } -BOOST_AUTO_TEST_CASE( translateNetworks_ltTest, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { - set< string > networks = {"<=EIP150", " networks = { "<=EIP150", " 0 ); BOOST_REQUIRE( networks.count( "Homestead" ) > 0 ); @@ -87,9 +87,9 @@ BOOST_AUTO_TEST_CASE( translateNetworks_ltTest, BOOST_REQUIRE( networks.count( "Byzantium" ) == 0 ); } -BOOST_AUTO_TEST_CASE( translateNetworks_leHomestead, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { - set< string > networks = {"<=Homestead"}; +BOOST_AUTO_TEST_CASE( + translateNetworks_leHomestead, *boost::unit_test::precondition( dev::test::run_not_express ) ) { + set< string > networks = { "<=Homestead" }; networks = test::translateNetworks( networks ); BOOST_REQUIRE( networks.count( "Frontier" ) > 0 ); BOOST_REQUIRE( networks.count( "Homestead" ) > 0 ); @@ -99,9 +99,9 @@ BOOST_AUTO_TEST_CASE( translateNetworks_leHomestead, } } -BOOST_AUTO_TEST_CASE( translateNetworks_leFrontier, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { - set< string > networks = {"<=Frontier"}; +BOOST_AUTO_TEST_CASE( + translateNetworks_leFrontier, *boost::unit_test::precondition( dev::test::run_not_express ) ) { + set< string > networks = { "<=Frontier" }; networks = test::translateNetworks( networks ); BOOST_REQUIRE( networks.count( "Frontier" ) > 0 ); for ( auto const& net : test::getNetworks() ) { @@ -112,90 +112,90 @@ BOOST_AUTO_TEST_CASE( translateNetworks_leFrontier, BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE( TestHelper ) -BOOST_AUTO_TEST_CASE( levenshteinDistance_similar, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + levenshteinDistance_similar, *boost::unit_test::precondition( dev::test::run_not_express ) ) { char const* word1 = "someword"; char const* word2 = "soemword"; size_t distance = test::levenshteinDistance( word1, strlen( word1 ), word2, strlen( word2 ) ); BOOST_CHECK_EQUAL( distance, 2 ); } -BOOST_AUTO_TEST_CASE( levenshteinDistance_similar2, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + levenshteinDistance_similar2, *boost::unit_test::precondition( dev::test::run_not_express ) ) { char const* word1 = "sOmeWord"; char const* word2 = "someword"; size_t distance = test::levenshteinDistance( word1, strlen( word1 ), word2, strlen( word2 ) ); BOOST_CHECK_EQUAL( distance, 2 ); } -BOOST_AUTO_TEST_CASE( levenshteinDistance_similar3, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + levenshteinDistance_similar3, *boost::unit_test::precondition( dev::test::run_not_express ) ) { char const* word1 = "sOmeWoRd"; char const* word2 = "someword"; size_t distance = test::levenshteinDistance( word1, strlen( word1 ), word2, strlen( word2 ) ); BOOST_CHECK_EQUAL( distance, 3 ); } -BOOST_AUTO_TEST_CASE( levenshteinDistance_similar4, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + levenshteinDistance_similar4, *boost::unit_test::precondition( dev::test::run_not_express ) ) { char const* word1 = "sOmeWoRd"; char const* word2 = "soemword"; size_t distance = test::levenshteinDistance( word1, strlen( word1 ), word2, strlen( word2 ) ); BOOST_CHECK_EQUAL( distance, 5 ); } -BOOST_AUTO_TEST_CASE( levenshteinDistance_AgtB, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + levenshteinDistance_AgtB, *boost::unit_test::precondition( dev::test::run_not_express ) ) { char const* word1 = "someword"; char const* word2 = "other"; size_t distance = test::levenshteinDistance( word1, strlen( word1 ), word2, strlen( word2 ) ); BOOST_CHECK_EQUAL( distance, 4 ); } -BOOST_AUTO_TEST_CASE( levenshteinDistance_AgtB2, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + levenshteinDistance_AgtB2, *boost::unit_test::precondition( dev::test::run_not_express ) ) { char const* word1 = "some long sentence here"; char const* word2 = "other shorter phrase"; size_t distance = test::levenshteinDistance( word1, strlen( word1 ), word2, strlen( word2 ) ); BOOST_CHECK_EQUAL( distance, 14 ); } -BOOST_AUTO_TEST_CASE( levenshteinDistance_BgtA, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + levenshteinDistance_BgtA, *boost::unit_test::precondition( dev::test::run_not_express ) ) { char const* word1 = "other"; char const* word2 = "someword"; size_t distance = test::levenshteinDistance( word1, strlen( word1 ), word2, strlen( word2 ) ); BOOST_CHECK_EQUAL( distance, 4 ); } -BOOST_AUTO_TEST_CASE( levenshteinDistance_BgtA2, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + levenshteinDistance_BgtA2, *boost::unit_test::precondition( dev::test::run_not_express ) ) { char const* word1 = "other shorter phrase"; char const* word2 = "some long sentence here"; size_t distance = test::levenshteinDistance( word1, strlen( word1 ), word2, strlen( word2 ) ); BOOST_CHECK_EQUAL( distance, 14 ); } -BOOST_AUTO_TEST_CASE( levenshteinDistance_different, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + levenshteinDistance_different, *boost::unit_test::precondition( dev::test::run_not_express ) ) { char const* word1 = "abdefg"; char const* word2 = "hijklmn"; size_t distance = test::levenshteinDistance( word1, strlen( word1 ), word2, strlen( word2 ) ); BOOST_CHECK_EQUAL( distance, 6 ); } -BOOST_AUTO_TEST_CASE( getTestSuggestions, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { - vector< string > const testList = { - "test1", "test2", "BlockSuite", "BlockSuite/TestCase", "GeneralBlockchainTests"}; +BOOST_AUTO_TEST_CASE( + getTestSuggestions, *boost::unit_test::precondition( dev::test::run_not_express ) ) { + vector< string > const testList = { "test1", "test2", "BlockSuite", "BlockSuite/TestCase", + "GeneralBlockchainTests" }; auto list = test::testSuggestions( testList, "blocksuit" ); BOOST_CHECK( test::inArray( list, string( "BlockSuite" ) ) ); } -BOOST_AUTO_TEST_CASE( getTestSuggestions2, - *boost::unit_test::precondition( dev::test::run_not_express ) ) { - vector< string > const testList = {"test1", "test2", "BlockSuite", "BlockSuite/TestCase", - "GeneralBlockchainTests", "GeneralStateTests/stExample", "BCGeneralStateTests/stExample"}; +BOOST_AUTO_TEST_CASE( + getTestSuggestions2, *boost::unit_test::precondition( dev::test::run_not_express ) ) { + vector< string > const testList = { "test1", "test2", "BlockSuite", "BlockSuite/TestCase", + "GeneralBlockchainTests", "GeneralStateTests/stExample", "BCGeneralStateTests/stExample" }; auto list = test::testSuggestions( testList, "GeneralStateTests/stExample2" ); BOOST_CHECK( test::inArray( list, string( "GeneralStateTests/stExample" ) ) ); diff --git a/test/unittests/libweb3core/LevelDBHash.cpp b/test/unittests/libweb3core/LevelDBHash.cpp index afe960599..91fa8b6e1 100644 --- a/test/unittests/libweb3core/LevelDBHash.cpp +++ b/test/unittests/libweb3core/LevelDBHash.cpp @@ -9,7 +9,7 @@ BOOST_AUTO_TEST_SUITE( LevelDBHashBase ) BOOST_AUTO_TEST_CASE( hash ) { dev::TransientDirectory td; - std::vector< std::pair< std::string, std::string > > randomKeysValues(123); + std::vector< std::pair< std::string, std::string > > randomKeysValues( 123 ); dev::h256 hash; { @@ -22,7 +22,7 @@ BOOST_AUTO_TEST_CASE( hash ) { for ( size_t i = 0; i < 123; ++i ) { std::string key = dev::h256::random().hex(); std::string value = dev::h256::random().hex(); - db->insert( dev::db::Slice(key), dev::db::Slice(value) ); + db->insert( dev::db::Slice( key ), dev::db::Slice( value ) ); randomKeysValues[i] = { key, value }; } @@ -41,7 +41,7 @@ BOOST_AUTO_TEST_CASE( hash ) { for ( size_t i = 0; i < 123; ++i ) { std::string key = randomKeysValues[i].first; std::string value = randomKeysValues[i].second; - db_copy->insert( dev::db::Slice(key), dev::db::Slice(value) ); + db_copy->insert( dev::db::Slice( key ), dev::db::Slice( value ) ); } db_copy->insert( dev::db::Slice( "PieceUsageBytes" ), dev::db::Slice( "123456789" ) ); db_copy->insert( dev::db::Slice( "ppieceUsageBytes" ), dev::db::Slice( "123456789" ) ); @@ -63,7 +63,7 @@ BOOST_AUTO_TEST_CASE( hash ) { for ( size_t i = 0; i < 123; ++i ) { std::string key = randomKeysValues[i].first; std::string value = randomKeysValues[i].second; - db_copy->insert( dev::db::Slice(key), dev::db::Slice(value) ); + db_copy->insert( dev::db::Slice( key ), dev::db::Slice( value ) ); } db_copy->insert( dev::db::Slice( "PieceUsageBytes" ), dev::db::Slice( "123456789" ) ); @@ -82,7 +82,7 @@ BOOST_AUTO_TEST_CASE( hash ) { dev::db::LevelDB::defaultSnapshotDBOptions() }; - std::unique_ptr< dev::db::LevelDB > m_db( new dev::db::LevelDB( td.path(), options) ); + std::unique_ptr< dev::db::LevelDB > m_db( new dev::db::LevelDB( td.path(), options ) ); isContinue = m_db->hashBasePartially( &dbCtx, lastHashedKey ); } @@ -103,7 +103,7 @@ BOOST_AUTO_TEST_CASE( hash ) { for ( size_t i = 0; i < 123; ++i ) { std::string key = dev::h256::random().hex(); std::string value = dev::h256::random().hex(); - db_diff->insert( dev::db::Slice(key), dev::db::Slice(value) ); + db_diff->insert( dev::db::Slice( key ), dev::db::Slice( value ) ); } hash_diff = db_diff->hashBase(); diff --git a/test/unittests/libweb3jsonrpc/AccountHolder.cpp b/test/unittests/libweb3jsonrpc/AccountHolder.cpp index bdc547071..70aac620b 100644 --- a/test/unittests/libweb3jsonrpc/AccountHolder.cpp +++ b/test/unittests/libweb3jsonrpc/AccountHolder.cpp @@ -34,7 +34,8 @@ namespace test { BOOST_FIXTURE_TEST_SUITE( AccountHolderTest, TestOutputHelperFixture ) -BOOST_AUTO_TEST_CASE( ProxyAccountUseCase, *boost::unit_test::precondition( dev::test::run_not_express ) ) { +BOOST_AUTO_TEST_CASE( + ProxyAccountUseCase, *boost::unit_test::precondition( dev::test::run_not_express ) ) { FixedAccountHolder h = FixedAccountHolder( function< Interface*() >(), vector< KeyPair >() ); BOOST_CHECK( h.allAccounts().empty() ); diff --git a/test/unittests/libweb3jsonrpc/Client.cpp b/test/unittests/libweb3jsonrpc/Client.cpp index f84d5a2ee..f53792af3 100644 --- a/test/unittests/libweb3jsonrpc/Client.cpp +++ b/test/unittests/libweb3jsonrpc/Client.cpp @@ -72,11 +72,11 @@ BOOST_AUTO_TEST_CASE( Personal ) { // dev::WebThreeDirect web3( WebThreeDirect::composeClientVersion( "eth" ), getDataDir(), // string(), // chainParams, WithExisting::Kill, set< string >{"eth"} ); - auto monitor = make_shared< InstanceMonitor >("test"); + auto monitor = make_shared< InstanceMonitor >( "test" ); - setenv("DATA_DIR", getDataDir().c_str(), 1); - Client client( chainParams, ( int ) chainParams->getNetworkId(), shared_ptr< GasPricer >(), NULL, monitor, - getDataDir(), WithExisting::Kill, TransactionQueue::Limits{100000, 1024} ); + setenv( "DATA_DIR", getDataDir().c_str(), 1 ); + Client client( chainParams, ( int ) chainParams->getNetworkId(), shared_ptr< GasPricer >(), + NULL, monitor, getDataDir(), WithExisting::Kill, TransactionQueue::Limits{ 100000, 1024 } ); client.injectSkaleHost(); #ifdef BITE @@ -99,7 +99,7 @@ BOOST_AUTO_TEST_CASE( Personal ) { return false; // user input goes here } ); rpc::Personal personal( keyManager, accountHolder, client ); - rpc::Eth eth( std::string(""), client, accountHolder ); + rpc::Eth eth( std::string( "" ), client, accountHolder ); // Create account diff --git a/test/unittests/libweb3jsonrpc/SkaledFixture.cpp b/test/unittests/libweb3jsonrpc/SkaledFixture.cpp index cb3e03064..e715ac359 100644 --- a/test/unittests/libweb3jsonrpc/SkaledFixture.cpp +++ b/test/unittests/libweb3jsonrpc/SkaledFixture.cpp @@ -104,27 +104,27 @@ Json::Value CurlClient::doRequestResponse() { // Accessing JSON data if ( root.isMember( "result" ) ) { return root["result"]; - } else if (root.isMember( "error" )) { + } else if ( root.isMember( "error" ) ) { CHECK( root["error"].isObject() ); auto errorDescription = root["error"]; string description = "JSON-RPC error:"; - if (errorDescription.isMember( "code" )) { + if ( errorDescription.isMember( "code" ) ) { description += errorDescription["code"].asString() + ":"; } - if (errorDescription.isMember( "message" )) { + if ( errorDescription.isMember( "message" ) ) { description += errorDescription["message"].asString() + ":"; }; - throw std::runtime_error( description); + throw std::runtime_error( description ); } else { throw std::runtime_error( "No result or error in response" ); Json::StreamWriterBuilder writer; - writer["indentation"] = " "; // Set indentation level (2 spaces here) + writer["indentation"] = " "; // Set indentation level (2 spaces here) // Convert the Json::Value to a string - std::string output = Json::writeString(writer, root); - throw std::runtime_error( "No result or error in response:" + output); + std::string output = Json::writeString( writer, root ); + throw std::runtime_error( "No result or error in response:" + output ); } } else { // Output error message if parsing fails @@ -181,10 +181,9 @@ void CurlClient::doRequestResponseAndCheckForError( } - - string CurlClient::eth_getLatestBlock() { - std::string jsonPayload = R"({"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest", false],"id":1})"; + std::string jsonPayload = + R"({"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest", false],"id":1})"; Json::Value response; doRequestResponseAndCheckForError( jsonPayload, response ); @@ -237,7 +236,7 @@ string CurlClient::eth_hashrate() { doRequestResponseAndCheckForError( jsonPayload, response ); CHECK( response.isMember( "result" ) ); - CHECK(response["result"].asString() == "0x0"); + CHECK( response["result"].asString() == "0x0" ); return response["result"].toStyledString(); } @@ -247,7 +246,7 @@ string CurlClient::eth_mining() { doRequestResponseAndCheckForError( jsonPayload, response ); CHECK( response.isMember( "result" ) ); - CHECK(response["result"].asBool() == false); + CHECK( response["result"].asBool() == false ); return response["result"].toStyledString(); } @@ -262,7 +261,8 @@ string CurlClient::eth_syncing() { string CurlClient::web3_clientVersion() { - std::string jsonPayload = R"({"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":1})"; + std::string jsonPayload = + R"({"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":1})"; Json::Value response; doRequestResponseAndCheckForError( jsonPayload, response ); @@ -544,23 +544,23 @@ void SkaledFixture::doOneTinyTransfersIteration( TransferType _transferType ) { } - cout << 1000.0 * testAccounts.size() * mtmBatchSize / ( getCurrentTimeMs() - begin ) << - " submission tps" << endl; + cout << 1000.0 * testAccounts.size() * mtmBatchSize / ( getCurrentTimeMs() - begin ) + << " submission tps" << endl; for ( auto&& account : testAccounts ) { - waitForTransactionOrBatch(account.second, mtmBatchSize ); + waitForTransactionOrBatch( account.second, mtmBatchSize ); }; - cout << 1000.0 * testAccounts.size() * mtmBatchSize / ( getCurrentTimeMs() - begin ) - << " total tps" << endl; + cout << 1000.0 * testAccounts.size() * mtmBatchSize / ( getCurrentTimeMs() - begin ) + << " total tps" << endl; for ( auto&& account : testAccountsVector ) { checkReceiptStatusAndGetGasUsed( account->getLastTxHash() ); } } -void SkaledFixture::doOneReadCallIteration(CallType _transferType, string _callName ) { +void SkaledFixture::doOneReadCallIteration( CallType _transferType, string _callName ) { CHECK( threadsCountForTestTransactions <= testAccounts.size() ); auto transactionsPerThread = testAccounts.size() / threadsCountForTestTransactions; @@ -582,14 +582,14 @@ void SkaledFixture::doOneReadCallIteration(CallType _transferType, string _callN for ( uint64_t j = 0; j < transactionsPerThread; j++ ) { auto account = testAccountsVector.at( threadNumber * transactionsPerThread + j ); - doCall( account, gasPrice, _transferType); + doCall( account, gasPrice, _transferType ); } } ); threads.push_back( t ); } } else { auto oldAccount = testAccountsVector.at( accountNum ); - doCall(oldAccount, gasPrice, _transferType); + doCall( oldAccount, gasPrice, _transferType ); } } @@ -602,7 +602,8 @@ void SkaledFixture::doOneReadCallIteration(CallType _transferType, string _callN } - cout << _callName << " call tps:" << 1000.0 * testAccounts.size() / ( getCurrentTimeMs() - begin ) << endl; + cout << _callName + << " call tps:" << 1000.0 * testAccounts.size() / ( getCurrentTimeMs() - begin ) << endl; } @@ -681,7 +682,6 @@ void SkaledFixture::sendTinyTransfersForAllAccounts( void SkaledFixture::sendCallsForAllAccounts( uint64_t _iterations, CallType _callType, string _callName ) { - for ( uint64_t iteration = 0; iteration < _iterations; iteration++ ) { doOneReadCallIteration( _callType, _callName ); } @@ -815,10 +815,10 @@ string SkaledFixture::getTxPayload( Transaction& transaction ) { // this call sends ether a single transfer, or multiple copies of same transfer. // the latter is used in MTM mode testing. For a single transder _batchSize = 1 void SkaledFixture::sendSingleTransferOrBatch( u256 _amount, std::shared_ptr< SkaledAccount > _from, - const string& _to, const u256& _gasPrice, uint64_t _batchSize, TransferType _transferType, + const string& _to, const u256& _gasPrice, uint64_t _batchSize, TransferType _transferType, TransactionWait _wait ) { auto from = _from->getAddressAsString(); - auto accountNonce = _from->computeNonceForNextTransactionOrBatch(_batchSize); + auto accountNonce = _from->computeNonceForNextTransactionOrBatch( _batchSize ); u256 dstBalanceBefore; @@ -857,9 +857,9 @@ void SkaledFixture::sendSingleTransferOrBatch( u256 _amount, std::shared_ptr< Sk ts.gas = 90000; ts.gasPrice = _gasPrice; - vector txHashes; + vector< string > txHashes; - for (uint64_t i = 0; i < _batchSize; i++) { + for ( uint64_t i = 0; i < _batchSize; i++ ) { Transaction transaction( ts ); transaction.forceChainId( chainId ); transaction.forceType( this->transactionType ); @@ -868,8 +868,8 @@ void SkaledFixture::sendSingleTransferOrBatch( u256 _amount, std::shared_ptr< Sk } #ifndef FAIR - if (usePow) { - calculateAndSetPowGas(transaction); + if ( usePow ) { + calculateAndSetPowGas( transaction ); } #endif @@ -882,8 +882,8 @@ void SkaledFixture::sendSingleTransferOrBatch( u256 _amount, std::shared_ptr< Sk auto txHash = getThreadLocalCurlClient()->eth_sendRawTransaction( payload ); txHashes.push_back( txHash ); } catch ( std::exception& e ) { - cerr << "Exception in eth_sendRawTransaction from: " << transaction.from() << - ": nonce: " << transaction.nonce() << endl; + cerr << "Exception in eth_sendRawTransaction from: " << transaction.from() + << ": nonce: " << transaction.nonce() << endl; cerr << e.what() << endl; throw e; } @@ -899,7 +899,7 @@ void SkaledFixture::sendSingleTransferOrBatch( u256 _amount, std::shared_ptr< Sk ++ts.nonce; } - _from->setLastTxHash( txHashes.back()); + _from->setLastTxHash( txHashes.back() ); } @@ -982,8 +982,8 @@ string SkaledFixture::sendSingleDeployOrSolidityCall( u256 _amount, } -void SkaledFixture::waitForTransactionOrBatch( std::shared_ptr< SkaledAccount > _account, - uint64_t _batchSize) { +void SkaledFixture::waitForTransactionOrBatch( + std::shared_ptr< SkaledAccount > _account, uint64_t _batchSize ) { u256 transactionCount; auto lastSentNonce = _account->getLastSentNonce(); @@ -992,8 +992,7 @@ void SkaledFixture::waitForTransactionOrBatch( std::shared_ptr< SkaledAccount > while ( ( transactionCount = getThreadLocalCurlClient()->eth_getTransactionCount( - _account->getAddressAsString() ) ) < lastSentNonce + 1) { - + _account->getAddressAsString() ) ) < lastSentNonce + 1 ) { if ( this->verifyTransactions ) { CHECK( getTransactionCount( _account->getAddressAsString() ) == transactionCount ) } @@ -1007,9 +1006,9 @@ void SkaledFixture::waitForTransactionOrBatch( std::shared_ptr< SkaledAccount > } // the count should now be one more than the last transaction nonce - CHECK( transactionCount == lastSentNonce + 1); + CHECK( transactionCount == lastSentNonce + 1 ); - _account->notifyLastTransactionOrBatchCompleted( _batchSize); + _account->notifyLastTransactionOrBatchCompleted( _batchSize ); } void SkaledFixture::splitAccountInHalves( std::shared_ptr< SkaledAccount > _from, @@ -1039,43 +1038,41 @@ void SkaledFixture::sendTinyTransfer( std::shared_ptr< SkaledAccount > _from, co CHECK( fee <= getBalance( _from->getAddressAsString() ) ) } - sendSingleTransferOrBatch( 1, _from, _from->getAddressAsString(), _gasPrice, - this->mtmBatchSize, _transferType, _wait ); + sendSingleTransferOrBatch( 1, _from, _from->getAddressAsString(), _gasPrice, this->mtmBatchSize, + _transferType, _wait ); } - -void SkaledFixture::doCall( std::shared_ptr< SkaledAccount > _from, const u256& _gasPrice, - CallType _transferType ) { +void SkaledFixture::doCall( + std::shared_ptr< SkaledAccount > _from, const u256& _gasPrice, CallType _transferType ) { auto c = getThreadLocalCurlClient(); auto address = _from->getAddressAsString(); - if (_transferType == CallType::TRANSACTION_COUNT) { - c->eth_getTransactionCount( address); - } else if (_transferType == CallType::BALANCE) { - c->eth_getBalance( address); - } else if (_transferType == CallType::BLOCK_BY_NUMBER) { + if ( _transferType == CallType::TRANSACTION_COUNT ) { + c->eth_getTransactionCount( address ); + } else if ( _transferType == CallType::BALANCE ) { + c->eth_getBalance( address ); + } else if ( _transferType == CallType::BLOCK_BY_NUMBER ) { c->eth_getLatestBlock(); - } else if (_transferType == CallType::BLOCK_NUMBER) { + } else if ( _transferType == CallType::BLOCK_NUMBER ) { c->eth_blockNumber(); - } else if (_transferType == CallType::CHAIN_ID) { + } else if ( _transferType == CallType::CHAIN_ID ) { c->eth_chainId(); - } else if (_transferType == CallType::NET_VERSION) { - c-> net_version(); - } else if (_transferType == CallType::GAS_PRICE) { + } else if ( _transferType == CallType::NET_VERSION ) { + c->net_version(); + } else if ( _transferType == CallType::GAS_PRICE ) { c->eth_gasPrice(); - } else if (_transferType == CallType::HASH_RATE) { + } else if ( _transferType == CallType::HASH_RATE ) { c->eth_hashrate(); - } else if (_transferType == CallType::MINING) { + } else if ( _transferType == CallType::MINING ) { c->eth_mining(); - } else if (_transferType == CallType::SYNCING) { + } else if ( _transferType == CallType::SYNCING ) { c->eth_syncing(); - } else if (_transferType == CallType::WEB3_CLIENT_VERSION) { + } else if ( _transferType == CallType::WEB3_CLIENT_VERSION ) { c->web3_clientVersion(); } } - unique_ptr< WebThreeStubClient > SkaledFixture::rpcClient() const { auto httpClient = new jsonrpc::HttpClient( skaledEndpoint ); httpClient->SetTimeout( 10000 ); @@ -1085,12 +1082,11 @@ unique_ptr< WebThreeStubClient > SkaledFixture::rpcClient() const { #ifndef FAIR void SkaledFixture::calculateAndSetPowGas( Transaction& _t ) const { - for ( u256 i = 1;; i++ ) { _t.forceGasPrice( i ); - h256 hash = dev::sha3( _t.sender().ref() ) ^ - dev::sha3( _t.nonce() ) ^ dev::sha3( _t.gasPrice() ); + h256 hash = + dev::sha3( _t.sender().ref() ) ^ dev::sha3( _t.nonce() ) ^ dev::sha3( _t.gasPrice() ); u256 externalGas = ~u256( 0 ) / u256( hash ) / powDiffuculty; diff --git a/test/unittests/libweb3jsonrpc/SkaledFixture.h b/test/unittests/libweb3jsonrpc/SkaledFixture.h index d144cd3a2..24f502941 100644 --- a/test/unittests/libweb3jsonrpc/SkaledFixture.h +++ b/test/unittests/libweb3jsonrpc/SkaledFixture.h @@ -48,8 +48,17 @@ enum class TransactionWait { WAIT_FOR_COMPLETION, DONT_WAIT_FOR_COMPLETION }; enum class TransferType { NATIVE, ERC20 }; enum class CallType { - TRANSACTION_COUNT, BALANCE, BLOCK_BY_NUMBER, BLOCK_NUMBER, CHAIN_ID, NET_VERSION, GAS_PRICE, - HASH_RATE, MINING, SYNCING, WEB3_CLIENT_VERSION + TRANSACTION_COUNT, + BALANCE, + BLOCK_BY_NUMBER, + BLOCK_NUMBER, + CHAIN_ID, + NET_VERSION, + GAS_PRICE, + HASH_RATE, + MINING, + SYNCING, + WEB3_CLIENT_VERSION }; class SkaledAccount { @@ -101,9 +110,7 @@ class SkaledAccount { } - string getAddressAsString() const { - return addressAsString; - } + string getAddressAsString() const { return addressAsString; } const Secret& getKey() const; @@ -197,7 +204,6 @@ class CurlClient { void doRequestResponseAndCheckForError( std::string jsonPayload, Json::Value& response ); - string eth_getLatestBlock(); string eth_blockNumber(); @@ -246,7 +252,7 @@ class SkaledFixture : public TestOutputHelperFixture { void doOneTinyTransfersIteration( TransferType _transferType ); - void doOneReadCallIteration( CallType _transferType, string _callName ); + void doOneReadCallIteration( CallType _transferType, string _callName ); void mintAllKeysWithERC20(); diff --git a/test/unittests/libweb3jsonrpc/WebThreeStubClient.cpp b/test/unittests/libweb3jsonrpc/WebThreeStubClient.cpp index 21ef48ff7..28dd9add8 100644 --- a/test/unittests/libweb3jsonrpc/WebThreeStubClient.cpp +++ b/test/unittests/libweb3jsonrpc/WebThreeStubClient.cpp @@ -1456,7 +1456,6 @@ Json::Value WebThreeStubClient::bite_getDecryptedTransactionData( const std::str jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString() ); } -#ifdef BITE Json::Value WebThreeStubClient::bite_getCraftedCtxs( const std::string& param1 ) { Json::Value p; p.append( param1 ); @@ -1479,7 +1478,6 @@ std::string WebThreeStubClient::bite_getCtxOrigin( const std::string& param1 ) { jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString() ); } #endif // BITE -#endif // BITE #ifdef FAIR Json::Value WebThreeStubClient::skale_getBLSPublicKey() { diff --git a/test/unittests/libweb3jsonrpc/WebThreeStubClient.h b/test/unittests/libweb3jsonrpc/WebThreeStubClient.h index c2b85bb68..e67d1b2a1 100644 --- a/test/unittests/libweb3jsonrpc/WebThreeStubClient.h +++ b/test/unittests/libweb3jsonrpc/WebThreeStubClient.h @@ -180,11 +180,9 @@ class WebThreeStubClient : public jsonrpc::Client { #ifdef BITE Json::Value bite_getCommitteesInfo() noexcept( false ); Json::Value bite_getDecryptedTransactionData( const std::string& param1 ) noexcept( false ); -#ifdef BITE Json::Value bite_getCraftedCtxs( const std::string& request ) noexcept( false ); std::string bite_getCtxOrigin( const std::string& request ) noexcept( false ); #endif // BITE -#endif // BITE #ifdef FAIR Json::Value skale_getBLSPublicKey() noexcept( false ); diff --git a/test/unittests/libweb3jsonrpc/jsonrpc.cpp b/test/unittests/libweb3jsonrpc/jsonrpc.cpp index 2520c1f3b..612601ffd 100644 --- a/test/unittests/libweb3jsonrpc/jsonrpc.cpp +++ b/test/unittests/libweb3jsonrpc/jsonrpc.cpp @@ -1,8771 +1,8901 @@ -/* - Modifications Copyright (C) 2018-2019 SKALE Labs - - 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 . -*/ - -#pragma GCC diagnostic ignored "-Wdeprecated" - -#include - -#include "WebThreeStubClient.h" - - -#include "SkaledFixture.h" -#include "genesisGeneration2Config.h" -#include "libweb3jsonrpc/SkaleFace.h" -#include -#include -#include -#include -#include -#ifndef FAIR -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "SkaledFixture.h" -#include -#include - -#ifndef FAIR -#include -#endif - -#include "genesisGeneration2Config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#ifdef BITE -#include -#include -#endif - -#ifdef BITE -#include -#include -#endif - -#ifdef FAIR -#include -#endif - -// This is defined by some weird windows header - workaround for now. -#undef GetMessage - - -using namespace std; -using namespace dev; -using namespace dev::eth; -using namespace dev::test; - -static size_t rand_port = ( srand( time( nullptr ) ), 1024 + rand() % 64000 ); - -#ifndef FAIR -static std::string const c_genesisConfigString = R"( -{ - "sealEngine": "NoProof", - "params": { - "accountStartNonce": "0x00", - "maximumExtraDataSize": "0x1000000", - "blockReward": "0x4563918244F40000", - "allowFutureBlocks": true, - "homesteadForkBlock": "0x00", - "EIP150ForkBlock": "0x00", - "EIP158ForkBlock": "0x00", - "byzantiumForkBlock": "0x00", - "constantinopleForkBlock": "0x00", - "istanbulForkBlock": "0x00", - "skaleDisableChainIdCheck": true, - "externalGasDifficulty": "0x1" - }, - "genesis": { - "author" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", - "difficulty" : "0x20000", - "gasLimit" : "0x0f4240", - "nonce" : "0x00", - "extraData" : "0x00", - "timestamp" : "0x00", - "mixHash" : "0x00", - "stateRoot": "0x01" - }, - "skaleConfig": { - "nodeInfo": { - "nodeName": "Node1", - "nodeID": 1112, - "bindIP": "127.0.0.1", - "basePort": )" + - std::to_string( rand_port ) + R"(, - "logLevel": "trace", - "logLevelProposal": "trace", - "testSignatures": true - }, - "sChain": { - "schainName": "TestChain", - "schainID": 1, - "emptyBlockIntervalMs": -1, - "nodeGroups": {}, - "nodes": [ - { "nodeID": 1112, "owner": "0x0E7d7F1D34a502bD609542576941C3FCc087c588", "ip": "127.0.0.1", "basePort": )" + - std::to_string( rand_port ) + - R"(, "schainIndex" : 1, "publicKey": "0xfa"} - ] - } - }, - "accounts": { - "0000000000000000000000000000000000000001": { "precompiled": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, - "0000000000000000000000000000000000000002": { "precompiled": { "name": "sha256", "linear": { "base": 60, "word": 12 } } }, - "0000000000000000000000000000000000000003": { "precompiled": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } }, - "0000000000000000000000000000000000000004": { "precompiled": { "name": "identity", "linear": { "base": 15, "word": 3 } } },)" + - R"( "0000000000000000000000000000000000000005": { - "precompiled": { - "name": "createFile", - "linear": { - "base": 15, - "word": 0 - }, - "restrictAccess": ["00000000000000000000000000000000000000AA", "692a70d2e424a56d2c6c27aa97d1a86395877b3a"] - } - },)" + - - /* -pragma solidity ^0.4.25; -contract Caller { -function call() public { -bool status; -string memory fileName = "test"; -address sender = 0x000000000000000000000000000000AA; -assembly{ -let ptr := mload(0x40) -mstore(ptr, sender) -mstore(add(ptr, 0x20), 4) -mstore(add(ptr, 0x40), mload(add(fileName, 0x20))) -mstore(add(ptr, 0x60), 1) -status := call(not(0), 0x05, 0, ptr, 0x80, ptr, 32) -} -} - -function revertCall() public { -call(); -revert(); -} -} -*/ - R"("0000000000000000000000000000000000000006": { - "precompiled": { - "name": "addBalance", - "linear": { - "base": 15, - "word": 0 - }, - "restrictAccess": ["5c4e11842e8be09264dc1976943571d7af6d00f9"] - } - }, - "0000000000000000000000000000000000000007": { - "precompiled": { - "name": "getIMABLSPublicKey", - "linear": { - "base": 15, - "word": 0 - } - } - }, - "0000000000000000000000000000000000000008": { "precompiled": { "name": "getBlockRandom", "linear": { "base": 15, "word": 0 } } }, - "0x5c4e11842e8be09264dc1976943571d7af6d00f9" : { - "balance" : "1000000000000000000000000000000" - }, - "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a" : { - "balance" : "0x00", - "code" : "0x6080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806328b5e32b14604e578063f38fb65b146062575b600080fd5b348015605957600080fd5b5060606076565b005b348015606d57600080fd5b50607460ec565b005b6000606060006040805190810160405280600481526020017f7465737400000000000000000000000000000000000000000000000000000000815250915060aa905060405181815260046020820152602083015160408201526001606082015260208160808360006005600019f1935050505050565b60f26076565b600080fd00a165627a7a72305820262a5822c4fe6c154b2ef3198c7827d35fc6da59da2cea2c4f2fad9d4a5ccd5e0029", - "nonce" : "0x00", - "storage" : { - } - }, - "0x095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "0x0de0b6b3a7640000", - "code" : "0x6001600101600055", - "nonce" : "0x00", - "storage" : { - } - }, - "0xC2002000000000000000000000000000000000C2": { - "balance": "0", - "code": "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80639b063104146037578063cd16ecbf146062575b600080fd5b606060048036036020811015604b57600080fd5b8101908080359060200190929190505050608d565b005b608b60048036036020811015607657600080fd5b81019080803590602001909291905050506097565b005b8060018190555050565b806000819055505056fea265627a7a7231582029df540a7555533ef4b3f66bc4f9abe138b00117d1496efbfd9d035a48cd595e64736f6c634300050d0032", - "storage": { - "0x0": "0x01" - }, - "nonce": "0" - }, - "0xD2002000000000000000000000000000000000D2": { - "balance": "0", - "code": "0x608060405234801561001057600080fd5b50600436106100455760003560e01c806313f44d101461005557806338eada1c146100af5780634ba79dfe146100f357610046565b5b6002801461005357600080fd5b005b6100976004803603602081101561006b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610137565b60405180821515815260200191505060405180910390f35b6100f1600480360360208110156100c557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101f4565b005b6101356004803603602081101561010957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061030f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16148061019957506101988261042b565b5b806101ed5750600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b9050919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f43616c6c6572206973206e6f7420746865206f776e657200000000000000000081525060200191505060405180910390fd5b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f43616c6c6572206973206e6f7420746865206f776e657200000000000000000081525060200191505060405180910390fd5b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600080823b90506000811191505091905056fea26469706673582212202aca1f7abb7d02061b58de9b559eabe1607c880fda3932bbdb2b74fa553e537c64736f6c634300060c0033", - "storage": { - }, - "nonce": "0" - }, - "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "0x0de0b6b3a7640000", - "code" : "0x", - "nonce" : "0x00", - "storage" : { - } - }, - "0xD2001300000000000000000000000000000000D4": { - "balance": "0", - "nonce": "0", - "storage": {}, - "code":"0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80632098776714610051578063b8bd717f1461007f578063d37165fa146100ad578063fdde8d66146100db575b600080fd5b61007d6004803603602081101561006757600080fd5b8101908080359060200190929190505050610109565b005b6100ab6004803603602081101561009557600080fd5b8101908080359060200190929190505050610136565b005b6100d9600480360360208110156100c357600080fd5b8101908080359060200190929190505050610170565b005b610107600480360360208110156100f157600080fd5b8101908080359060200190929190505050610191565b005b60005a90505b815a8203101561011e5761010f565b600080fd5b815a8203101561013257610123565b5050565b60005a90505b815a8203101561014b5761013c565b600060011461015957600080fd5b5a90505b815a8203101561016c5761015d565b5050565b60005a9050600081830390505b805a8303101561018c5761017d565b505050565b60005a90505b815a820310156101a657610197565b60016101b157600080fd5b5a90505b815a820310156101c4576101b5565b505056fea264697066735822122089b72532621e7d1849e444ee6efaad4fb8771258e6f79755083dce434e5ac94c64736f6c63430006000033" - } - } -} -)"; -#else -static std::string const c_genesisConfigString = - R"( -{ - "sealEngine": "NoProof", - "params": { - "accountStartNonce": "0x00", - "maximumExtraDataSize": "0x1000000", - "blockReward": "0x4563918244F40000", - "allowFutureBlocks": true, - "homesteadForkBlock": "0x00", - "EIP150ForkBlock": "0x00", - "EIP158ForkBlock": "0x00", - "byzantiumForkBlock": "0x00", - "constantinopleForkBlock": "0x00", - "istanbulForkBlock": "0x00", - "skaleDisableChainIdCheck": true - }, - "genesis": { - "author" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", - "difficulty" : "0x20000", - "gasLimit" : "0x0f4240", - "nonce" : "0x00", - "extraData" : "0x00", - "timestamp" : "0x00", - "mixHash" : "0x00", - "stateRoot": "0x01" - }, - "skaleConfig": { - "nodeInfo": { - "nodeName": "Node1", - "nodeID": 1112, - "bindIP": "127.0.0.1", - "basePort": )" + - std::to_string( rand_port ) + R"(, - "logLevel": "trace", - "logLevelProposal": "trace", - "testSignatures": true - }, - "sChain": { - "schainName": "TestChain", - "schainID": 1, - "emptyBlockIntervalMs": -1, - "nodeGroups": {}, - "nodes": { - "1": { - "stakingContractAddress": "0x5C60C315985977b7a408eBF4256984Acdf949549", - "group": [ - { "nodeID": 1112, "owner": "0x0E7d7F1D34a502bD609542576941C3FCc087c588", "ip": "127.0.0.1", "basePort": )" + - std::to_string( rand_port ) + - R"(, "ip6": "::1", "basePort6": 1231, "schainIndex" : 1, "publicKey" : "0xfa"} - ] - }, - "-1": {} - } - } - }, - "accounts": { - "0000000000000000000000000000000000000001": { "precompiled": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, - "0000000000000000000000000000000000000002": { "precompiled": { "name": "sha256", "linear": { "base": 60, "word": 12 } } }, - "0000000000000000000000000000000000000003": { "precompiled": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } }, - "0000000000000000000000000000000000000004": { "precompiled": { "name": "identity", "linear": { "base": 15, "word": 3 } } }, - "0000000000000000000000000000000000000008": { "precompiled": { "name": "getBlockRandom", "linear": { "base": 15, "word": 0 } } }, - )" - /* -pragma solidity ^0.4.25; -contract Caller { -function call() public { -bool status; -string memory fileName = "test"; -address sender = 0x000000000000000000000000000000AA; -assembly{ -let ptr := mload(0x40) -mstore(ptr, sender) -mstore(add(ptr, 0x20), 4) -mstore(add(ptr, 0x40), mload(add(fileName, 0x20))) -mstore(add(ptr, 0x60), 1) -status := call(not(0), 0x05, 0, ptr, 0x80, ptr, 32) -} -} - -function revertCall() public { -call(); -revert(); -} -} -*/ - R"("0000000000000000000000000000000000000006": { - "precompiled": { - "name": "addBalance", - "linear": { - "base": 15, - "word": 0 - } - } - }, - "0x5c4e11842e8be09264dc1976943571d7af6d00f9" : { - "balance" : "1000000000000000000000000000000" - }, - "0x5339Ef05428d1b87f4e2F2db64E782c68E9cDA56": { - "balance" : "1000000000000000000000000000000" - }, - "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a" : { - "balance" : "0x00", - "code" : "0x6080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806328b5e32b14604e578063f38fb65b146062575b600080fd5b348015605957600080fd5b5060606076565b005b348015606d57600080fd5b50607460ec565b005b6000606060006040805190810160405280600481526020017f7465737400000000000000000000000000000000000000000000000000000000815250915060aa905060405181815260046020820152602083015160408201526001606082015260208160808360006005600019f1935050505050565b60f26076565b600080fd00a165627a7a72305820262a5822c4fe6c154b2ef3198c7827d35fc6da59da2cea2c4f2fad9d4a5ccd5e0029", - "nonce" : "0x00", - "storage" : { - } - }, - "0x095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "0x0de0b6b3a7640000", - "code" : "0x6001600101600055", - "nonce" : "0x00", - "storage" : { - } - }, - "0xC2002000000000000000000000000000000000C2": { - "balance": "0", - "code": "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80639b063104146037578063cd16ecbf146062575b600080fd5b606060048036036020811015604b57600080fd5b8101908080359060200190929190505050608d565b005b608b60048036036020811015607657600080fd5b81019080803590602001909291905050506097565b005b8060018190555050565b806000819055505056fea265627a7a7231582029df540a7555533ef4b3f66bc4f9abe138b00117d1496efbfd9d035a48cd595e64736f6c634300050d0032", - "storage": { - "0x0": "0x01" - }, - "nonce": "0" - }, - "0xD2002000000000000000000000000000000000D2": { - "balance": "0", - "code": "0x608060405234801561001057600080fd5b50600436106100455760003560e01c806313f44d101461005557806338eada1c146100af5780634ba79dfe146100f357610046565b5b6002801461005357600080fd5b005b6100976004803603602081101561006b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610137565b60405180821515815260200191505060405180910390f35b6100f1600480360360208110156100c557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101f4565b005b6101356004803603602081101561010957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061030f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16148061019957506101988261042b565b5b806101ed5750600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b9050919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f43616c6c6572206973206e6f7420746865206f776e657200000000000000000081525060200191505060405180910390fd5b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f43616c6c6572206973206e6f7420746865206f776e657200000000000000000081525060200191505060405180910390fd5b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600080823b90506000811191505091905056fea26469706673582212202aca1f7abb7d02061b58de9b559eabe1607c880fda3932bbdb2b74fa553e537c64736f6c634300060c0033", - "storage": { - }, - "nonce": "0" - }, - "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "0x0de0b6b3a7640000", - "code" : "0x", - "nonce" : "0x00", - "storage" : { - } - }, - "0xD2001300000000000000000000000000000000D4": { - "balance": "0", - "nonce": "0", - "storage": {}, - "code":"0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80632098776714610051578063b8bd717f1461007f578063d37165fa146100ad578063fdde8d66146100db575b600080fd5b61007d6004803603602081101561006757600080fd5b8101908080359060200190929190505050610109565b005b6100ab6004803603602081101561009557600080fd5b8101908080359060200190929190505050610136565b005b6100d9600480360360208110156100c357600080fd5b8101908080359060200190929190505050610170565b005b610107600480360360208110156100f157600080fd5b8101908080359060200190929190505050610191565b005b60005a90505b815a8203101561011e5761010f565b600080fd5b815a8203101561013257610123565b5050565b60005a90505b815a8203101561014b5761013c565b600060011461015957600080fd5b5a90505b815a8203101561016c5761015d565b5050565b60005a9050600081830390505b805a8303101561018c5761017d565b505050565b60005a90505b815a820310156101a657610197565b60016101b157600080fd5b5a90505b815a820310156101c4576101b5565b505056fea264697066735822122089b72532621e7d1849e444ee6efaad4fb8771258e6f79755083dce434e5ac94c64736f6c63430006000033" - } - } -} -)"; -#endif - -namespace { -class TestIpcServer : public jsonrpc::AbstractServerConnector { -public: - bool StartListening() override { return true; } - - bool StopListening() override { return true; } - - bool SendResponse( std::string const& _response, void* _addInfo = nullptr ) /*override*/ { - *static_cast< std::string* >( _addInfo ) = _response; - return true; - } -}; - -class TestIpcClient : public jsonrpc::IClientConnector { -public: - explicit TestIpcClient( TestIpcServer& _server ) : m_server{ _server } {} - - void SendRPCMessage( const std::string& _message, std::string& _result ) override { - m_server.ProcessRequest( _message, _result ); - } - -private: - TestIpcServer& m_server; -}; - -struct JsonRpcFixture : public TestOutputHelperFixture { - // chain params needs to be a field of JsonRPCFixture - // since references to it are passed to the server - std::shared_ptr< ChainParams > chainParams = std::make_shared< ChainParams >(); - - - JsonRpcFixture( const std::string& _config = "", bool _owner = true, - bool _deploymentControl = true, bool _generation2 = false, bool _mtmEnabled = false, - bool _isSyncNode = false, int _emptyBlockIntervalMs = -1, - const std::map< std::string, std::string >& params = - std::map< std::string, std::string >() ) { - - // this fixture is used in all tests to load config. So also init bls library as well - libBLS::init(); - - if ( _config != "" ) { - if ( !_generation2 ) { - Json::Value ret; - Json::Reader().parse( _config, ret ); - if ( _owner ) { - ret["skaleConfig"]["sChain"]["schainOwner"] = toJS( coinbase.address() ); - if ( _deploymentControl ) - ret["accounts"]["0xD2002000000000000000000000000000000000D2"]["storage"] - ["0x0"] = toJS( coinbase.address() ); - } else { - ret["skaleConfig"]["sChain"]["schainOwner"] = toJS( account2.address() ); - if ( _deploymentControl ) - ret["accounts"]["0xD2002000000000000000000000000000000000D2"]["storage"] - ["0x0"] = toJS( account2.address() ); - } -#ifndef FAIR - ret["skaleConfig"]["sChain"]["contractStorageLimit"] = 128; -#endif - if ( params.count( "contractStorageLimit" ) ) - ret["skaleConfig"]["sChain"]["contractStorageLimit"] = std::stoi( params.at( "contractStorageLimit" ) ); -#ifdef BITE - if ( params.count( "BITE2PatchTimestamp" ) ) - ret["skaleConfig"]["sChain"]["Bite2PatchTimestamp"] = std::stoi( params.at( "BITE2PatchTimestamp" ) ); -#endif - Json::FastWriter fastWriter; - std::string output = fastWriter.write( ret ); - chainParams->loadConfig( output ); - } else { - Json::Value ret; - Json::FastWriter fastWriter; - Json::Reader().parse( _config, ret ); -#ifndef FAIR - ret["skaleConfig"]["sChain"]["contractStorageLimit"] = 106874910; - ret["skaleConfig"]["sChain"]["contractStoragePatchTimestamp"] = 1000; -#endif - std::string output = fastWriter.write( ret ); - chainParams->loadConfig( output ); - - // insecure schain owner(originator) private key - // address is 0x5C4e11842E8be09264dc1976943571d7Af6d00F9 - coinbase = dev::KeyPair( dev::Secret( - "0x1c2cd4b70c2b8c6cd7144bbbfbd1e5c6eacb4a5efd9c86d0e29cbbec4e8483b9" ) ); - // address is 0x7aa5e36aa15e93d10f4f26357c30f052dacdde5f - account3 = dev::KeyPair( dev::Secret( - "0x23ABDBD3C61B5330AF61EBE8BEF582F4E5CC08E554053A718BDCE7813B9DC1FC" ) ); - } - } else { - chainParams->sealEngineName = NoProof::name(); - chainParams->allowFutureBlocks = true; - chainParams->difficulty = chainParams->getMinimumDifficulty(); - chainParams->gasLimit = chainParams->getMaxGasLimit(); - chainParams->byzantiumForkBlock = 0; - chainParams->EIP158ForkBlock = 0; - chainParams->constantinopleForkBlock = 0; - chainParams->istanbulForkBlock = 0; -#ifndef FAIR - chainParams->externalGasDifficulty = 1; - chainParams->sChain.contractStorageLimit = 128; -#endif - // 615 + 1430 is experimentally-derived block size + average extras size - chainParams->sChain.dbStorageLimit = 320.5 * ( 615 + 1430 ); -#ifdef FAIR - chainParams->sChain.nodeGroups = - { - { { GroupNode{ u256( 0 ), u256( 8 ), - "0xf925c203a30ec6cad5a263db3efab7ed4c1fd74c8688167e10a5a22e15ab5018d8553df0ac54ea", - Address( "0x08151B8F80bfa7dEa760e461412AF24348224edf" ) - } }, - uint64_t( -1 ), - { "3842742177969966091367527274107524613106077736353521259727282251005583743182", - "3497912824016228906558906422247670474553186446469877598411863912329082553081", - "8173996886448941320370434854289578123609627835954133538412363037981850950343", - "20979370720689475348670582375026949105497642726992863932315517524004804784155" } - } - }; - chainParams->sChain.nodes[0].owner = jsToAddress( "0x0E7d7F1D34a502bD609542576941C3FCc087c588" ); -#endif -#ifndef FAIR - chainParams->sChain - ._patchTimestamps[static_cast< size_t >( SchainPatchEnum::ContractStoragePatch )] = - 1; - chainParams->sChain._patchTimestamps[static_cast< size_t >( - SchainPatchEnum::StorageDestructionPatch )] = 1; - powPatchActivationTimestamp = time( nullptr ) + 60; - chainParams->sChain - ._patchTimestamps[static_cast< size_t >( SchainPatchEnum::CorrectForkInPowPatch )] = - powPatchActivationTimestamp; - push0PatchActivationTimestamp = time( nullptr ) + 10; - chainParams->sChain - ._patchTimestamps[static_cast< size_t >( SchainPatchEnum::PushZeroPatch )] = - push0PatchActivationTimestamp; -#endif - chainParams->sChain.emptyBlockIntervalMs = _emptyBlockIntervalMs; - // add random extra data to randomize genesis hash and get random DB path, - // so that tests can be run in parallel - // TODO: better make it use ethemeral in-memory databases - chainParams->extraData = h256::random().asBytes(); - chainParams->nodeInfo.port = chainParams->nodeInfo.port6 = rand_port; - chainParams->sChain.nodes[0].port = chainParams->sChain.nodes[0].port6 = rand_port; - chainParams->skaleDisableChainIdCheck = true; - - if ( params.count( "getLogsBlocksLimit" ) && stoi( params.at( "getLogsBlocksLimit" ) ) ) - chainParams->logsBlocksLimit = stoi( params.at( "getLogsBlocksLimit" ) ); - if ( params.count( "getResponseLogCountLimit" ) && stoi( params.at( "getResponseLogCountLimit" ) ) ) - chainParams->responseLogCountLimit = stoi( params.at( "getResponseLogCountLimit" ) ); - } - chainParams->sChain.multiTransactionMode = _mtmEnabled; - chainParams->nodeInfo.syncNode = _isSyncNode; - - auto monitor = make_shared< InstanceMonitor >( "test" ); - - - setenv( "DATA_DIR", tempDir.path().c_str(), 1 ); - client.reset( new eth::ClientTest( chainParams, ( int ) chainParams->getNetworkId(), - shared_ptr< GasPricer >(), NULL, monitor, tempDir.path(), WithExisting::Kill ) ); - - if ( !_generation2 ) - client->setAuthor( coinbase.address() ); - else - client->setAuthor( chainParams->getBlockAuthor() ); - - // wait for 1st block - because it's always empty - std::promise< void > blockPromise; - auto importHandler = client->setOnBlockImport( - [&blockPromise]( BlockHeader const& ) { blockPromise.set_value(); } ); - - client->injectSkaleHost(); - dev::eth::g_skaleHost = client->skaleHost(); - client->startWorking(); - - if ( !_isSyncNode ) - blockPromise.get_future().wait(); - - using FullServer = ModularServer< rpc::EthFace, rpc::SkaleFace, rpc::NetFace, rpc::Web3Face, - rpc::AdminEthFace /*, rpc::AdminNetFace*/, rpc::DebugFace, rpc::TestFace >; - - accountHolder.reset( new FixedAccountHolder( [&]() { return client.get(); }, {} ) ); - accountHolder->setAccounts( { coinbase, account2, account3 } ); - - sessionManager.reset( new rpc::SessionManager() ); - adminSession = - sessionManager->newSession( rpc::SessionPermissions{ { rpc::Privilege::Admin } } ); - - auto ethFace = new rpc::Eth( - _config.empty() ? std::string( "" ) : _config, *client, *accountHolder.get() ); - - dev::rpc::Skale* skaleFace = nullptr; -#ifdef BITE - skaleFace = new rpc::Skale( *client ); -#endif - - gasPricer = make_shared< eth::TrivialGasPricer >( 0, DefaultGasPrice ); - - rpcServer.reset( new FullServer( ethFace, skaleFace, new rpc::Net( chainParams ), - new rpc::Web3(), // TODO Add version parameter here? - new rpc::AdminEth( *client, *gasPricer, keyManager, *sessionManager ), - new rpc::Debug( *client, nullptr, "" ), new rpc::Test( *client ) ) ); - - - // - SkaleServerOverride::opts_t serverOpts; - - inject_rapidjson_handlers( serverOpts, ethFace ); - - serverOpts.netOpts_.bindOptsStandard_.cntServers_ = 1; - serverOpts.netOpts_.bindOptsStandard_.strAddrHTTP4_ = chainParams->getSelfNodeIp(); - // random port - // +3 because rand() seems to be called effectively simultaneously here and in "static" - // section - thus giving same port for consensus - serverOpts.netOpts_.bindOptsStandard_.nBasePortHTTP4_ = std::rand() % 64000 + 1025 + 3; - skale_server_connector = new SkaleServerOverride( chainParams, client.get(), serverOpts ); - rpcServer->addConnector( skale_server_connector ); - skale_server_connector->StartListening(); - - sleep( 1 ); - - httpClient = new jsonrpc::HttpClient( - "http://" + chainParams->getSelfNodeIp() + ":" + - std::to_string( serverOpts.netOpts_.bindOptsStandard_.nBasePortHTTP4_ ) ); - httpClient->SetTimeout( 1000000000 ); - - rpcClient = unique_ptr< WebThreeStubClient >( new WebThreeStubClient( *httpClient ) ); - - BOOST_TEST_MESSAGE( "Constructed JsonRpcFixture" ); - } - - ~JsonRpcFixture() { -#ifdef FAIR - // Make sure safe consensus is properly updated before exit (epoch id in particular). - // Only related to FAIR - const auto deadline = chrono::steady_clock::now() + chrono::seconds( 10 ); - while ( client->skaleHost()->ignoreNewBlocksEnabled() && chrono::steady_clock::now() < deadline ) { - usleep( 10 ); - } - if ( client->skaleHost()->isConsesusUpdateHappened() ) - client->skaleHost()->handleConsensusUpdate(); -#endif - - if ( skale_server_connector ) - skale_server_connector->StopListening(); - - if ( httpClient ) - delete httpClient; - - if ( g_skaleHost ) - g_skaleHost.reset(); - - BOOST_TEST_MESSAGE( "Destructed JsonRpcFixture" ); - } - - string sendingRawShouldFail( string const& _t ) { - try { - rpcClient->eth_sendRawTransaction( _t ); - BOOST_FAIL( "Exception expected." ); - } catch ( jsonrpc::JsonRpcException const& _e ) { - return _e.GetMessage(); - } - return string(); - } - - string estimateGasShouldFail( Json::Value const& _t ) { - try { - rpcClient->eth_estimateGas( _t ); - BOOST_FAIL( "Exception expected." ); - } catch ( jsonrpc::JsonRpcException const& _e ) { - return _e.GetMessage(); - } - return string(); - } - - TransientDirectory tempDir; // ! should exist before client! - unique_ptr< Client > client; - - dev::KeyPair coinbase{ KeyPair::create() }; - dev::KeyPair account2{ KeyPair::create() }; - dev::KeyPair account3{ KeyPair::create() }; - unique_ptr< FixedAccountHolder > accountHolder; - unique_ptr< rpc::SessionManager > sessionManager; - std::shared_ptr< eth::TrivialGasPricer > gasPricer; - KeyManager keyManager{ KeyManager::defaultPath(), SecretStore::defaultPath() }; - unique_ptr< ModularServer<> > rpcServer; - unique_ptr< WebThreeStubClient > rpcClient; - std::string adminSession; - SkaleServerOverride* skale_server_connector; - jsonrpc::HttpClient* httpClient; - time_t powPatchActivationTimestamp; - time_t push0PatchActivationTimestamp; -}; - -#ifndef FAIR -struct RestrictedAddressFixture : public JsonRpcFixture { - RestrictedAddressFixture( - const std::string& _config = c_genesisConfigString, bool _mtmEnabled = false ) - : JsonRpcFixture( _config, true, true, false, _mtmEnabled ) { - setenv( "HOME", tempDir.path().c_str(), 1 ); // getDataDir() now points to the different - // directories for different tests - ownerAddress = Address( "00000000000000000000000000000000000000AA" ); - std::string fileName = "test"; - path = dev::getDataDir() / "filestorage" / Address( ownerAddress ).hex() / fileName; - data = - ( "0x" - "00000000000000000000000000000000000000000000000000000000000000AA" - "0000000000000000000000000000000000000000000000000000000000000004" - "7465737400000000000000000000000000000000000000000000000000000000" // test - "0000000000000000000000000000000000000000000000000000000000000004" ); - } - - ~RestrictedAddressFixture() override { remove( path.c_str() ); } - - Address ownerAddress; - std::string data; - boost::filesystem::path path; -}; -#endif - -string fromAscii( string _s ) { - bytes b = asBytes( _s ); - return toHexPrefixed( b ); -} -} // namespace - -#ifdef BITE -/// Helper functions - -dev::bytes formEncryptedMessageMockup( const dev::bytes& message, const dev::Address& toAddress ) { - RLPStream biteDataRlp( 2 ); - - biteDataRlp << message; - biteDataRlp << ( dev::Address::Arith ) toAddress; - - auto messageToEncrypt = biteDataRlp.out(); - auto encryptedMessage = libBLS::ThresholdEncryption::mockupEncrypt( messageToEncrypt ); - - u256 epochId = 0; - - RLPStream bitePayloadRlp( 2 ); - - bitePayloadRlp << epochId; - bitePayloadRlp << encryptedMessage; - - auto rlpBytes = bitePayloadRlp.out(); - return dev::bytes( rlpBytes.begin(), rlpBytes.end() ); -} - -std::string formTransactionRlp( const JsonRpcFixture& fixture, const std::string& senderAddress, - const std::string& data, size_t& nonce, - const std::string& toAddress = "0x5EdF1e852fdD1B0Bc47C0307EF755C76f4B9c251" ) { - Json::Value txEncryptedData; - txEncryptedData["to"] = toAddress; - txEncryptedData["from"] = senderAddress; - txEncryptedData["gas"] = "100000"; - txEncryptedData["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txEncryptedData["data"] = data; - txEncryptedData["nonce"] = nonce++; - - TransactionSkeleton ts = toTransactionSkeleton( txEncryptedData ); - ts = fixture.client->populateTransactionWithDefaults( ts ); - pair< bool, Secret > ar = fixture.accountHolder->authenticate( ts ); - Transaction tx( ts, ar.second ); - - return dev::toHexPrefixed( tx.toBytes() ); -} - -std::string formBITEPayloadRlp( u256 _epochId, const dev::bytes& _encryptedBITEData ) { - RLPStream bitePayloadRlp( 2 ); - - bitePayloadRlp << _epochId; - bitePayloadRlp << _encryptedBITEData; - - auto rlpBytes = bitePayloadRlp.out(); - return dev::toHexPrefixed( rlpBytes ); -} - -#endif // BITE - -BOOST_AUTO_TEST_SUITE( JsonRpcSuite ) - - -BOOST_AUTO_TEST_CASE( jsonrpc_gasPrice ) { - JsonRpcFixture fixture; - string gasPrice = fixture.rpcClient->eth_gasPrice(); - BOOST_CHECK_EQUAL( gasPrice, toJS( 20 * dev::eth::shannon ) ); -} - - -BOOST_AUTO_TEST_CASE( - jsonrpc_accounts, *boost::unit_test::precondition( dev::test::run_not_express ) ) { - JsonRpcFixture fixture; - std::vector< dev::KeyPair > keys = { KeyPair::create(), KeyPair::create() }; - fixture.accountHolder->setAccounts( keys ); - Json::Value k = fixture.rpcClient->eth_accounts(); - fixture.accountHolder->setAccounts( {} ); - BOOST_CHECK_EQUAL( k.isArray(), true ); - BOOST_CHECK_EQUAL( k.size(), keys.size() ); - for ( auto& i : k ) { - auto it = std::find_if( keys.begin(), keys.end(), [i]( dev::KeyPair const& keyPair ) { - return jsToAddress( i.asString() ) == keyPair.address(); - } ); - - BOOST_CHECK_EQUAL( it != keys.end(), true ); - } -} - -BOOST_AUTO_TEST_CASE( jsonrpc_number ) { - JsonRpcFixture fixture; - auto number = jsToU256( fixture.rpcClient->eth_blockNumber() ); - BOOST_CHECK_EQUAL( number, fixture.client->number() ); - dev::eth::mine( *( fixture.client ), 1 ); - auto numberAfter = jsToU256( fixture.rpcClient->eth_blockNumber() ); - BOOST_CHECK_GE( numberAfter, number + 1 ); - BOOST_CHECK_EQUAL( numberAfter, fixture.client->number() ); -} - - -BOOST_AUTO_TEST_CASE( jsonrpc_netVersion ) { - std::string _config = c_genesisConfigString; - Json::Value ret; - Json::Reader().parse( _config, ret ); - - // Set chainID = 65535 - ret["params"]["chainID"] = "0xffff"; - - Json::FastWriter fastWriter; - std::string config = fastWriter.write( ret ); - JsonRpcFixture fixture( config ); - - auto version = fixture.rpcClient->net_version(); - BOOST_CHECK_EQUAL( version, "65535" ); -} - -BOOST_AUTO_TEST_CASE( jsonrpc_setMining ) { - JsonRpcFixture fixture; - fixture.rpcClient->admin_eth_setMining( true, fixture.adminSession ); - BOOST_CHECK_EQUAL( fixture.client->wouldSeal(), true ); - - fixture.rpcClient->admin_eth_setMining( false, fixture.adminSession ); - BOOST_CHECK_EQUAL( fixture.client->wouldSeal(), false ); -} - -BOOST_AUTO_TEST_CASE( jsonrpc_stateAt ) { - JsonRpcFixture fixture; - dev::KeyPair key = KeyPair::create(); - auto address = key.address(); - string stateAt = fixture.rpcClient->eth_getStorageAt( toJS( address ), "0", "latest" ); - BOOST_CHECK_EQUAL( fixture.client->stateAt( address, 0 ), jsToU256( stateAt ) ); -} - -BOOST_AUTO_TEST_CASE( - eth_coinbase, *boost::unit_test::precondition( dev::test::run_not_express ) ) { - JsonRpcFixture fixture; - string coinbase = fixture.rpcClient->eth_coinbase(); - BOOST_REQUIRE_EQUAL( jsToAddress( coinbase ), fixture.client->author() ); -} - -BOOST_AUTO_TEST_CASE( eth_sendTransaction ) { - JsonRpcFixture fixture; - auto address = fixture.coinbase.address(); - u256 countAt = - jsToU256( fixture.rpcClient->eth_getTransactionCount( toJS( address ), "latest" ) ); - - BOOST_CHECK_EQUAL( countAt, fixture.client->countAt( address ) ); - BOOST_CHECK_EQUAL( countAt, 0 ); - u256 balance = fixture.client->balanceAt( address ); - string balanceString = fixture.rpcClient->eth_getBalance( toJS( address ), "latest" ); - BOOST_CHECK_EQUAL( toJS( balance ), balanceString ); - BOOST_CHECK_EQUAL( jsToDecimal( balanceString ), "0" ); - - dev::eth::simulateMining( *( fixture.client ), 1 ); - balance = fixture.client->balanceAt( address ); - balanceString = fixture.rpcClient->eth_getBalance( toJS( address ), "latest" ); - - BOOST_REQUIRE_GT( balance, 0 ); - BOOST_CHECK_EQUAL( toJS( balance ), balanceString ); - - - auto txAmount = balance / 2u; - auto gasPrice = 10 * dev::eth::szabo; - auto gas = EVMSchedule().txGas; - - auto receiver = KeyPair::create(); - - Json::Value t; - t["from"] = toJS( address ); - t["value"] = jsToDecimal( toJS( txAmount ) ); - t["to"] = toJS( receiver.address() ); - t["data"] = toJS( bytes() ); - t["gas"] = toJS( gas ); - t["gasPrice"] = toJS( gasPrice ); - - std::string txHash = fixture.rpcClient->eth_sendTransaction( t ); - BOOST_REQUIRE( !txHash.empty() ); - - fixture.accountHolder->setAccounts( {} ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - countAt = jsToU256( fixture.rpcClient->eth_getTransactionCount( toJS( address ), "latest" ) ); - u256 balance2 = fixture.client->balanceAt( receiver.address() ); - string balanceString2 = - fixture.rpcClient->eth_getBalance( toJS( receiver.address() ), "latest" ); - - BOOST_CHECK_EQUAL( countAt, fixture.client->countAt( address ) ); - BOOST_CHECK_EQUAL( countAt, 1 ); - BOOST_CHECK_EQUAL( toJS( balance2 ), balanceString2 ); - BOOST_CHECK_EQUAL( jsToU256( balanceString2 ), txAmount ); - BOOST_CHECK_EQUAL( txAmount, balance2 ); -} - -BOOST_AUTO_TEST_CASE( eth_sendRawTransaction_validTransaction, - - *boost::unit_test::precondition( dev::test::run_not_express ) ) { - JsonRpcFixture fixture; - auto senderAddress = fixture.coinbase.address(); - auto receiver = KeyPair::create(); - - Json::Value t; - t["from"] = toJS( senderAddress ); - t["to"] = toJS( receiver.address() ); - t["value"] = jsToDecimal( toJS( 10000 * dev::eth::szabo ) ); - - // Mine to generate a non-zero account balance - const int blocksToMine = 1; -#ifdef FAIR - const u256 blockReward = fixture.client->chainParams().blockReward( - fixture.client->blockChain().info().timestamp(), - fixture.client->blockChain().info().number() ); -#else - const u256 blockReward = 2 * dev::eth::ether; -#endif - dev::eth::simulateMining( *( fixture.client ), blocksToMine ); - BOOST_CHECK_EQUAL( blockReward, fixture.client->balanceAt( senderAddress ) ); - - auto signedTx = fixture.rpcClient->eth_signTransaction( t ); - BOOST_REQUIRE( !signedTx["raw"].empty() ); - - auto txHash = fixture.rpcClient->eth_sendRawTransaction( signedTx["raw"].asString() ); - BOOST_REQUIRE( !txHash.empty() ); -} - -BOOST_AUTO_TEST_CASE( eth_sendRawTransaction_errorZeroBalance ) { - JsonRpcFixture fixture; - auto senderAddress = fixture.coinbase.address(); - auto receiver = KeyPair::create(); - - BOOST_CHECK_EQUAL( 0, fixture.client->balanceAt( senderAddress ) ); - - Json::Value t; - t["from"] = toJS( senderAddress ); - t["to"] = toJS( receiver.address() ); - t["value"] = jsToDecimal( toJS( 10000 * dev::eth::szabo ) ); - - auto signedTx = fixture.rpcClient->eth_signTransaction( t ); - BOOST_REQUIRE( signedTx["raw"] ); - - BOOST_CHECK_EQUAL( fixture.sendingRawShouldFail( signedTx["raw"].asString() ), - "Account balance is too low (balance < value + gas * gas price)." ); -} - -BOOST_AUTO_TEST_CASE( eth_sendRawTransaction_errorInvalidNonce, - - *boost::unit_test::precondition( dev::test::run_not_express ) ) { - JsonRpcFixture fixture; - auto senderAddress = fixture.coinbase.address(); - auto receiver = KeyPair::create(); - - // Mine to generate a non-zero account balance - const size_t blocksToMine = 1; -#ifdef FAIR - const u256 blockReward = fixture.client->chainParams().blockReward( - fixture.client->blockChain().info().timestamp(), - fixture.client->blockChain().info().number() ); -#else - const u256 blockReward = 2 * dev::eth::ether; -#endif - dev::eth::simulateMining( *( fixture.client ), blocksToMine ); - BOOST_CHECK_EQUAL( blockReward, fixture.client->balanceAt( senderAddress ) ); - - Json::Value t; - t["from"] = toJS( senderAddress ); - t["to"] = toJS( receiver.address() ); - t["value"] = jsToDecimal( toJS( 10000 * dev::eth::szabo ) ); - - auto signedTx = fixture.rpcClient->eth_signTransaction( t ); - BOOST_REQUIRE( !signedTx["raw"].empty() ); - - auto txHash = fixture.rpcClient->eth_sendRawTransaction( signedTx["raw"].asString() ); - BOOST_REQUIRE( !txHash.empty() ); - - mineTransaction( *fixture.client, 1 ); - - auto invalidNonce = - jsToU256( fixture.rpcClient->eth_getTransactionCount( toJS( senderAddress ), "latest" ) ) - - 1; - t["nonce"] = jsToDecimal( toJS( invalidNonce ) ); - - signedTx = fixture.rpcClient->eth_signTransaction( t ); - BOOST_REQUIRE( !signedTx["raw"].empty() ); - - BOOST_CHECK_EQUAL( - fixture.sendingRawShouldFail( signedTx["raw"].asString() ), "Invalid transaction nonce." ); -} - -BOOST_AUTO_TEST_CASE( eth_sendRawTransaction_errorInsufficientGas ) { - JsonRpcFixture fixture; - auto senderAddress = fixture.coinbase.address(); - auto receiver = KeyPair::create(); - - // Mine to generate a non-zero account balance - const int blocksToMine = 1; -#ifdef FAIR - const u256 blockReward = fixture.client->chainParams().blockReward( - fixture.client->blockChain().info().timestamp(), - fixture.client->blockChain().info().number() ); -#else - const u256 blockReward = 2 * dev::eth::ether; -#endif - dev::eth::simulateMining( *( fixture.client ), blocksToMine ); - BOOST_CHECK_EQUAL( blockReward, fixture.client->balanceAt( senderAddress ) ); - - Json::Value t; - t["from"] = toJS( senderAddress ); - t["to"] = toJS( receiver.address() ); - t["value"] = jsToDecimal( toJS( 10000 * dev::eth::szabo ) ); - - const int minGasForValueTransferTx = 21000; - t["gas"] = jsToDecimal( toJS( minGasForValueTransferTx - 1 ) ); - - auto signedTx = fixture.rpcClient->eth_signTransaction( t ); - BOOST_REQUIRE( !signedTx["raw"].empty() ); - - BOOST_CHECK_EQUAL( fixture.sendingRawShouldFail( signedTx["raw"].asString() ), - "Transaction gas amount is less than the intrinsic gas amount for this transaction type." ); -} - -BOOST_AUTO_TEST_CASE( eth_sendRawTransaction_errorDuplicateTransaction ) { - JsonRpcFixture fixture; - auto senderAddress = fixture.coinbase.address(); - auto receiver = KeyPair::create(); - - // Mine to generate a non-zero account balance - const int blocksToMine = 1; -#ifdef FAIR - const u256 blockReward = fixture.client->chainParams().blockReward( - fixture.client->blockChain().info().timestamp(), - fixture.client->blockChain().info().number() ); -#else - const u256 blockReward = 2 * dev::eth::ether; -#endif - dev::eth::simulateMining( *( fixture.client ), blocksToMine ); - BOOST_CHECK_EQUAL( blockReward, fixture.client->balanceAt( senderAddress ) ); - - Json::Value t; - t["from"] = toJS( senderAddress ); - t["to"] = toJS( receiver.address() ); - t["value"] = jsToDecimal( toJS( 10000 * dev::eth::szabo ) ); - - auto signedTx = fixture.rpcClient->eth_signTransaction( t ); - BOOST_REQUIRE( !signedTx["raw"].empty() ); - - auto txHash = fixture.rpcClient->eth_sendRawTransaction( signedTx["raw"].asString() ); - BOOST_REQUIRE( !txHash.empty() ); - - auto txNonce = - jsToU256( fixture.rpcClient->eth_getTransactionCount( toJS( senderAddress ), "latest" ) ); - t["nonce"] = jsToDecimal( toJS( txNonce ) ); - - signedTx = fixture.rpcClient->eth_signTransaction( t ); - BOOST_REQUIRE( !signedTx["raw"].empty() ); - - BOOST_CHECK_EQUAL( fixture.sendingRawShouldFail( signedTx["raw"].asString() ), - "Same transaction already exists in the pending transaction queue." ); -} - -#ifdef FAIR - -/** - * Auxiliar function to mine a block to gather balance, - * and build a signed legacy pre-EIP155 transaction. - * Used to test acceptance vs. rejection of pre-EIP155 transactions - */ -Json::Value buildSignedTransaction( JsonRpcFixture& fixture ) { - auto receiver = KeyPair::create(); - auto senderAddress = fixture.coinbase.address(); - - // Mine to generate a non-zero account balance - const size_t blocksToMine = 1; - const u256 blockReward = fixture.client->chainParams().blockReward( - fixture.client->blockChain().info().timestamp(), - fixture.client->blockChain().info().number() ); - dev::eth::simulateMining( *( fixture.client ), blocksToMine ); - BOOST_CHECK_EQUAL( blockReward, fixture.client->balanceAt( senderAddress ) ); - - Json::Value sampleTx; - sampleTx["to"] = toJS( receiver.address() ); - sampleTx["from"] = toJS( senderAddress ); - sampleTx["gas"] = "100000"; - sampleTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - sampleTx["value"] = jsToDecimal( toJS( 10000 * dev::eth::szabo ) ); - sampleTx["data"] = "0x0"; - sampleTx["nonce"] = 0; - - return fixture.rpcClient->eth_signTransaction( sampleTx ); -}; - -BOOST_AUTO_TEST_CASE( eth_sendRawTransaction_acceptPreEIP155Txns_configOmitted ) { - std::string _config = c_genesisConfigString; - Json::Value ret; - Json::Reader().parse( _config, ret ); - Json::FastWriter fastWriter; - - // 'allowPreEIP155Txns' field is not set -> should be allowed by default - std::string config = fastWriter.write( ret ); - JsonRpcFixture fixture( config ); - auto signedTx = buildSignedTransaction( fixture ); - std::string txHash = fixture.rpcClient->eth_sendRawTransaction( signedTx["raw"].asString() ); - BOOST_REQUIRE( !txHash.empty() ); -} - -BOOST_AUTO_TEST_CASE( eth_sendRawTransaction_acceptPreEIP155Txns_configTrue ) { - std::string _config = c_genesisConfigString; - Json::Value ret; - Json::Reader().parse( _config, ret ); - Json::FastWriter fastWriter; - - // 'allowPreEIP155Txns' field is set to true -> should be allowed - ret["params"]["allowPreEIP155Txns"] = true; - std::string config = fastWriter.write( ret ); - JsonRpcFixture fixture( config ); - auto signedTx = buildSignedTransaction( fixture ); - std::string txHash = fixture.rpcClient->eth_sendRawTransaction( signedTx["raw"].asString() ); - BOOST_REQUIRE( !txHash.empty() ); -} - -BOOST_AUTO_TEST_CASE( eth_sendRawTransaction_rejectPreEIP155Txns_configFalse ) { - std::string _config = c_genesisConfigString; - Json::Value ret; - Json::Reader().parse( _config, ret ); - Json::FastWriter fastWriter; - - // 'allowPreEIP155Txns' field is set to false -> should be rejected - ret["params"]["allowPreEIP155Txns"] = false; - std::string config = fastWriter.write( ret ); - JsonRpcFixture fixture( config ); - auto signedTx = buildSignedTransaction( fixture ); - - std::cout << "Raw transaction: " << signedTx["raw"].asString() << std::endl; - BOOST_REQUIRE_THROW( - fixture.rpcClient->eth_sendRawTransaction( signedTx["raw"].asString() ), - jsonrpc::JsonRpcException - ); -} - -#endif - - - - -BOOST_AUTO_TEST_CASE( send_raw_tx_sync ) { - // Enable sync mode - JsonRpcFixture fixture( c_genesisConfigString, true, true, true, false, true ); - Address senderAddress = fixture.coinbase.address(); - fixture.client->setAuthor( senderAddress ); - - // contract test { - // function f(uint a) returns(uint d) { return a * 7; } - // } - - string compiled = - "6080604052341561000f57600080fd5b60b98061001d6000396000f300" - "608060405260043610603f576000357c01000000000000000000000000" - "00000000000000000000000000000000900463ffffffff168063b3de64" - "8b146044575b600080fd5b3415604e57600080fd5b606a600480360381" - "019080803590602001909291905050506080565b604051808281526020" - "0191505060405180910390f35b60006007820290509190505600a16562" - "7a7a72305820f294e834212334e2978c6dd090355312a3f0f9476b8eb9" - "8fb480406fc2728a960029"; - - Json::Value create; - create["code"] = compiled; - create["gas"] = "180000"; - - BOOST_REQUIRE( fixture.client->transactionQueueStatus().current == 0 ); - - // Sending tx to sync node - string txHash = fixture.rpcClient->eth_sendTransaction( create ); - - auto pendingTransactions = fixture.client->pending(); - BOOST_REQUIRE( pendingTransactions.size() == 1 ); - auto txHashFromQueue = "0x" + pendingTransactions[0].sha3().hex(); - BOOST_REQUIRE( txHashFromQueue == txHash ); -} - -BOOST_AUTO_TEST_CASE( eth_signTransaction ) { - JsonRpcFixture fixture; - auto address = fixture.coinbase.address(); - auto countAtBeforeSign = - jsToU256( fixture.rpcClient->eth_getTransactionCount( toJS( address ), "latest" ) ); - auto receiver = KeyPair::create(); - - Json::Value t; - t["from"] = toJS( address ); - t["value"] = jsToDecimal( toJS( 1 ) ); - t["to"] = toJS( receiver.address() ); - - Json::Value res = fixture.rpcClient->eth_signTransaction( t ); - BOOST_REQUIRE( res["raw"] ); - BOOST_REQUIRE( res["tx"] ); - - fixture.accountHolder->setAccounts( {} ); - dev::eth::mine( *( fixture.client ), 1 ); - - auto countAtAfterSign = - jsToU256( fixture.rpcClient->eth_getTransactionCount( toJS( address ), "latest" ) ); - - BOOST_CHECK_EQUAL( countAtBeforeSign, countAtAfterSign ); -} - - -const string skaledConfigFileName = "../../test/historicstate/configs/basic_config.json"; - - -BOOST_AUTO_TEST_CASE( simple_contract ) { - JsonRpcFixture fixture; - dev::eth::simulateMining( *( fixture.client ), 1 ); - - // pragma solidity 0.8.4; - // contract test { - // uint value; - // function f(uint a) public pure returns(uint d) { - // return a * 7; - // } - // function setValue(uint _value) external { - // value = _value; - // } - // } - - string compiled = - "608060405234801561001057600080fd5b506101ef8061002060003" - "96000f3fe608060405234801561001057600080fd5b506004361061" - "00365760003560e01c8063552410771461003b578063b3de648b146" - "10057575b600080fd5b610055600480360381019061005091906100" - "bc565b610087565b005b610071600480360381019061006c9190610" - "0bc565b610091565b60405161007e91906100f4565b604051809103" - "90f35b8060008190555050565b60006007826100a0919061010f565" - "b9050919050565b6000813590506100b6816101a2565b9291505056" - "5b6000602082840312156100ce57600080fd5b60006100dc8482850" - "16100a7565b91505092915050565b6100ee81610169565b82525050" - "565b600060208201905061010960008301846100e5565b929150505" - "65b600061011a82610169565b915061012583610169565b9250817f" - "fffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "fffffffff048311821515161561015e5761015d610173565b5b8282" - "02905092915050565b6000819050919050565b7f4e487b710000000" - "0000000000000000000000000000000000000000000000000600052" - "601160045260246000fd5b6101ab81610169565b81146101b657600" - "080fd5b5056fea26469706673582212200be8156151b5ef7c250fa7" - "b8c8ed4e2a1c32cd526f9c868223f6838fa1193c9e64736f6c63430" - "008040033"; - - Json::Value create; - create["code"] = compiled; - create["gas"] = "180000"; // TODO or change global default of 90000? - - BOOST_CHECK_EQUAL( jsToU256( fixture.rpcClient->eth_blockNumber() ), 1 ); - BOOST_CHECK_EQUAL( jsToU256( fixture.rpcClient->eth_getTransactionCount( - toJS( fixture.coinbase.address() ), "latest" ) ), - 0 ); - - string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( !receipt["contractAddress"].isNull() ); - string contractAddress = receipt["contractAddress"].asString(); - BOOST_REQUIRE( contractAddress != "null" ); - - Json::Value call; - call["to"] = contractAddress; - call["data"] = "0xb3de648b0000000000000000000000000000000000000000000000000000000000000001"; - call["gas"] = "1000000"; - call["gasPrice"] = "0"; - string result = fixture.rpcClient->eth_call( call, "latest" ); - BOOST_CHECK_EQUAL( - result, "0x0000000000000000000000000000000000000000000000000000000000000007" ); - - Json::Value inputCall; - inputCall["to"] = contractAddress; - inputCall["input"] = - "0xb3de648b0000000000000000000000000000000000000000000000000000000000000001"; - inputCall["gas"] = "1000000"; - inputCall["gasPrice"] = "0"; - result = fixture.rpcClient->eth_call( inputCall, "latest" ); - BOOST_CHECK_EQUAL( - result, "0x0000000000000000000000000000000000000000000000000000000000000007" ); - - Json::Value transact; - transact["to"] = contractAddress; - transact["data"] = "0x552410770000000000000000000000000000000000000000000000000000000000000001"; - txHash = fixture.rpcClient->eth_sendTransaction( transact ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - auto res = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE_EQUAL( res["status"], string( "0x1" ) ); - - Json::Value inputTx; - inputTx["to"] = contractAddress; - inputTx["input"] = "0x552410770000000000000000000000000000000000000000000000000000000000000002"; - txHash = fixture.rpcClient->eth_sendTransaction( inputTx ); - - dev::eth::mineTransaction( *( fixture.client ), 1 ); - res = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE_EQUAL( res["status"], string( "0x1" ) ); -} - -BOOST_AUTO_TEST_CASE( deploy_contract_from_owner ) { - JsonRpcFixture fixture( c_genesisConfigString ); - Address senderAddress = fixture.coinbase.address(); - - fixture.client->setAuthor( senderAddress ); - dev::eth::simulateMining( *( fixture.client ), 1 ); - - // contract test { - // function f(uint a) returns(uint d) { return a * 7; } - // } - - string compiled = - "6080604052341561000f57600080fd5b60b98061001d6000396000f300" - "608060405260043610603f576000357c01000000000000000000000000" - "00000000000000000000000000000000900463ffffffff168063b3de64" - "8b146044575b600080fd5b3415604e57600080fd5b606a600480360381" - "019080803590602001909291905050506080565b604051808281526020" - "0191505060405180910390f35b60006007820290509190505600a16562" - "7a7a72305820f294e834212334e2978c6dd090355312a3f0f9476b8eb9" - "8fb480406fc2728a960029"; - - Json::Value create; - - create["from"] = toJS( senderAddress ); - create["code"] = compiled; - create["gas"] = "1000000"; - - string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - - BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x1" ) ); - BOOST_REQUIRE( !receipt["contractAddress"].isNull() ); - Json::Value code = - fixture.rpcClient->eth_getCode( receipt["contractAddress"].asString(), "latest" ); - BOOST_REQUIRE( code.asString().substr( 2 ) == compiled.substr( 58 ) ); -} - -BOOST_AUTO_TEST_CASE( deploy_contract_not_from_owner ) { - JsonRpcFixture fixture( c_genesisConfigString, false ); - auto senderAddress = fixture.coinbase.address(); - - fixture.client->setAuthor( senderAddress ); - dev::eth::simulateMining( *( fixture.client ), 1 ); - - // contract test { - // function f(uint a) returns(uint d) { return a * 7; } - // } - - string compiled = - "6080604052341561000f57600080fd5b60b98061001d6000396000f300" - "608060405260043610603f576000357c01000000000000000000000000" - "00000000000000000000000000000000900463ffffffff168063b3de64" - "8b146044575b600080fd5b3415604e57600080fd5b606a600480360381" - "019080803590602001909291905050506080565b604051808281526020" - "0191505060405180910390f35b60006007820290509190505600a16562" - "7a7a72305820f294e834212334e2978c6dd090355312a3f0f9476b8eb9" - "8fb480406fc2728a960029"; - - Json::Value create; - - create["from"] = toJS( senderAddress ); - create["code"] = compiled; - create["gas"] = "1000000"; - - string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); -#ifdef FAIR - BOOST_CHECK_EQUAL( receipt["status"], string( "0x1" ) ); - Json::Value code = - fixture.rpcClient->eth_getCode( receipt["contractAddress"].asString(), "latest" ); - BOOST_REQUIRE( code.asString() == "0x608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063b3de648b146044575b600080fd5b3415604e57600080fd5b606a600480360381019080803590602001909291905050506080565b6040518082815260200191505060405180910390f35b60006007820290509190505600a165627a7a72305820f294e834212334e2978c6dd090355312a3f0f9476b8eb98fb480406fc2728a960029" ); -#else - BOOST_CHECK_EQUAL( receipt["status"], string( "0x0" ) ); - Json::Value code = - fixture.rpcClient->eth_getCode( receipt["contractAddress"].asString(), "latest" ); - BOOST_REQUIRE( code.asString() == "0x" ); -#endif -} - -BOOST_AUTO_TEST_CASE( deploy_contract_without_controller ) { - std::string _config = c_genesisConfigString; - Json::Value ret; - Json::Reader().parse( _config, ret ); - ret["accounts"].removeMember( "0xD2002000000000000000000000000000000000D2" ); - Json::FastWriter fastWriter; - std::string config = fastWriter.write( ret ); - JsonRpcFixture fixture( config, false, false ); - auto senderAddress = fixture.coinbase.address(); - - fixture.client->setAuthor( senderAddress ); - dev::eth::simulateMining( *( fixture.client ), 1 ); - - // contract test { - // function f(uint a) returns(uint d) { return a * 7; } - // } - - string compiled = - "6080604052341561000f57600080fd5b60b98061001d6000396000f300" - "608060405260043610603f576000357c01000000000000000000000000" - "00000000000000000000000000000000900463ffffffff168063b3de64" - "8b146044575b600080fd5b3415604e57600080fd5b606a600480360381" - "019080803590602001909291905050506080565b604051808281526020" - "0191505060405180910390f35b60006007820290509190505600a16562" - "7a7a72305820f294e834212334e2978c6dd090355312a3f0f9476b8eb9" - "8fb480406fc2728a960029"; - - Json::Value create; - - create["from"] = toJS( senderAddress ); - create["code"] = compiled; - create["gas"] = "1000000"; - - string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x1" ) ); - BOOST_REQUIRE( !receipt["contractAddress"].isNull() ); - Json::Value code = - fixture.rpcClient->eth_getCode( receipt["contractAddress"].asString(), "latest" ); - BOOST_REQUIRE( code.asString().substr( 2 ) == compiled.substr( 58 ) ); -} - -#ifndef FAIR -BOOST_AUTO_TEST_CASE( deploy_contract_with_controller ) { - JsonRpcFixture fixture( c_genesisConfigString, false ); - auto senderAddress = fixture.coinbase.address(); - - fixture.client->setAuthor( senderAddress ); - dev::eth::simulateMining( *( fixture.client ), 1 ); - - // contract test { - // function f(uint a) returns(uint d) { return a * 7; } - // } - - string compiled = - "6080604052341561000f57600080fd5b60b98061001d6000396000f300" - "608060405260043610603f576000357c01000000000000000000000000" - "00000000000000000000000000000000900463ffffffff168063b3de64" - "8b146044575b600080fd5b3415604e57600080fd5b606a600480360381" - "019080803590602001909291905050506080565b604051808281526020" - "0191505060405180910390f35b60006007820290509190505600a16562" - "7a7a72305820f294e834212334e2978c6dd090355312a3f0f9476b8eb9" - "8fb480406fc2728a960029"; - - Json::Value create; - - create["from"] = toJS( senderAddress ); - create["code"] = compiled; - create["gas"] = "1000000"; - - string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_CHECK_EQUAL( receipt["status"], string( "0x0" ) ); - Json::Value code = - fixture.rpcClient->eth_getCode( receipt["contractAddress"].asString(), "latest" ); - BOOST_REQUIRE( code.asString() == "0x" ); -} -#endif - - -BOOST_AUTO_TEST_CASE( create_opcode ) { - JsonRpcFixture fixture( c_genesisConfigString ); - auto senderAddress = fixture.coinbase.address(); - - fixture.client->setAuthor( senderAddress ); - dev::eth::simulateMining( *( fixture.client ), 1 ); - - /* - pragma solidity ^0.4.25; - - contract test { - address public a; - - function f() public { - address _address; - assembly { - let ptr := mload(0x40) - _address := create(0x00,ptr,0x20) - } - a = _address; - } - } -*/ - - string compiled = - "608060405234801561001057600080fd5b50610161806100206000396000f30060806040526004361061004c57" - "6000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630dbe" - "671f1461005157806326121ff0146100a8575b600080fd5b34801561005d57600080fd5b506100666100bf565b" - "604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffff" - "ffffff16815260200191505060405180910390f35b3480156100b457600080fd5b506100bd6100e4565b005b60" - "00809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060405160208160" - "00f0915050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffff" - "ffffffffffffffffffffffffffffffffffff160217905550505600a165627a7a72305820fc6f465560bc93346a" - "25f87ff189a58c26f5bf6f2e46570058fd79c1a3c3063a0029"; - - Json::Value create; - - create["from"] = toJS( senderAddress ); - create["code"] = compiled; - create["gas"] = "1000000"; - - string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - string contractAddress = receipt["contractAddress"].asString(); - - fixture.client->setAuthor( fixture.account2.address() ); - dev::eth::simulateMining( *( fixture.client ), 1 ); - - Json::Value transactionCallObject; - - transactionCallObject["from"] = toJS( fixture.account2.address() ); - transactionCallObject["to"] = contractAddress; - transactionCallObject["data"] = "0x26121ff0"; - - fixture.rpcClient->eth_sendTransaction( transactionCallObject ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value checkAddress; - checkAddress["to"] = contractAddress; - checkAddress["data"] = "0x0dbe671f"; - string response1 = fixture.rpcClient->eth_call( checkAddress, "latest" ); - BOOST_CHECK( - response1 != "0x0000000000000000000000000000000000000000000000000000000000000000" ); - - fixture.client->setAuthor( senderAddress ); - transactionCallObject["from"] = toJS( senderAddress ); - fixture.rpcClient->eth_sendTransaction( transactionCallObject ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - string response2 = fixture.rpcClient->eth_call( checkAddress, "latest" ); - BOOST_CHECK( - response2 != "0x0000000000000000000000000000000000000000000000000000000000000000" ); - BOOST_CHECK( response2 != response1 ); -} - -BOOST_AUTO_TEST_CASE( push0_patch_activation ) { - JsonRpcFixture fixture; - auto senderAddress = fixture.coinbase.address(); - - fixture.client->setAuthor( senderAddress ); - dev::eth::simulateMining( *( fixture.client ), 1 ); - - fixture.client->setAuthor( fixture.account2.address() ); - dev::eth::simulateMining( *( fixture.client ), 1 ); - - /* - // SPDX-License-Identifier: GPL-3.0 - - pragma solidity >=0.8.2; - - contract Push0Test { - fallback() external payable { - assembly { - let t := add(9, 10) - } - } - } - - then convert to yul: --ir p0test.sol` >p0test.yul - - then change code: - { - let r := add(88,99) - let tmp := verbatim_0i_1o(hex"5f") - } - - then compile! - - */ - string compiled = - "608060405234156100135761001261003b565b5b61001b610040565b610023610031565b6101b7610043823961" - "01b781f35b6000604051905090565b600080fd5b56fe608060405261000f36600061015b565b805160208201f3" - "5b60006060905090565b6000604051905090565b6000601f19601f8301169050919050565b7f4e487b71000000" - "00000000000000000000000000000000000000000000000000600052604160045260246000fd5b610073826100" - "2a565b810181811067ffffffffffffffff821117156100925761009161003b565b5b80604052505050565b6000" - "6100a5610020565b90506100b1828261006a565b919050565b600067ffffffffffffffff8211156100d1576100" - "d061003b565b5b6100da8261002a565b9050602081019050919050565b60006100f2826100b6565b6100fb8161" - "009b565b915082825250919050565b7f7375636365737300000000000000000000000000000000000000000000" - "000000600082015250565b600061013b60076100e7565b905061014960208201610106565b90565b6000610156" - "61012f565b905090565b6000610165610017565b809150600a6009015f505061017861014c565b915050929150" - "5056fea2646970667358221220b3871ed09fbcbb1dac74c3cd48dafa5d097bea7c808b5ff2c16a996cf108d3c6" - "64736f6c63430008190033"; - // "60806040523415601057600f6031565b5b60166036565b601c6027565b604c60398239604c81f35b6000604051905090565b600080fd5b56fe6080604052600a600c565b005b60636058015f505056fea2646970667358221220ee9861b869ceda6de64f2ec7ccbebf2babce54b35502a866a4193e05ae595e1f64736f6c63430008130033"; - - Json::Value create; - - create["from"] = toJS( senderAddress ); - create["code"] = compiled; - create["gas"] = "1000000"; - - string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x1" ) ); // deploy should succeed - string contractAddress = receipt["contractAddress"].asString(); - - Json::Value callObject; - - callObject["from"] = toJS( fixture.account2.address() ); - callObject["to"] = contractAddress; - -#ifndef FAIR - // first try without PushZeroPatch - - txHash = fixture.rpcClient->eth_sendTransaction( callObject ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x0" ) ); // exec should fail - - string callResult = fixture.rpcClient->eth_call( callObject, "latest" ); - BOOST_REQUIRE_EQUAL( callResult, string( "0x" ) ); // call too - - // wait for block after timestamp - BOOST_REQUIRE_LT( fixture.client->blockInfo( LatestBlock ).timestamp(), - fixture.push0PatchActivationTimestamp ); - while ( time( nullptr ) < fixture.push0PatchActivationTimestamp ) - sleep( 1 ); - - // 1st timestamp-crossing block - txHash = fixture.rpcClient->eth_sendTransaction( callObject ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - BOOST_REQUIRE_GE( fixture.client->blockInfo( LatestBlock ).timestamp(), - fixture.push0PatchActivationTimestamp ); -#endif - -#ifdef HISTORIC_STATE - uint64_t crossingBlockNumber = fixture.client->number(); -#endif - -#ifndef FAIR - // in the "crossing" block tx still should fail - receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x0" ) ); -#endif - - // in 1st block with patch call should succeed - auto callResult1 = fixture.rpcClient->eth_call( callObject, "latest" ); - BOOST_REQUIRE_NE( callResult1, string( "0x" ) ); - - // tx should succeed too - txHash = fixture.rpcClient->eth_sendTransaction( callObject ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x1" ) ); - -#ifdef HISTORIC_STATE -#ifndef FAIR - // historic call should fail before activation and succees after it - callResult1 = fixture.rpcClient->eth_call( callObject, toJS( crossingBlockNumber - 1 ) ); - BOOST_REQUIRE_EQUAL( callResult1, string( "0x" ) ); -#endif // FAIR - - callResult1 = fixture.rpcClient->eth_call( callObject, toJS( crossingBlockNumber ) ); - BOOST_REQUIRE_NE( callResult1, string( "0x" ) ); -#endif // HISTORIC_STATE -} - -BOOST_AUTO_TEST_CASE( eth_estimateGas ) { - JsonRpcFixture fixture( c_genesisConfigString ); - - // This contract is predeployed on SKALE test network - // on address 0xD2001300000000000000000000000000000000D4 - - // pragma solidity 0.6.0; - // contract Test { - // ... - // function testRequire(uint gasConsumed) public { - // uint initialGas = gasleft(); - // while (initialGas - gasleft() < gasConsumed) {} - // require(1 == 0); - // initialGas = gasleft(); - // while (initialGas - gasleft() < gasConsumed) {} - // } - // - // function testRevert(uint gasConsumed) public { - // uint initialGas = gasleft(); - // while (initialGas - gasleft() < gasConsumed) {} - // revert(); - // initialGas = gasleft(); - // while (initialGas - gasleft() < gasConsumed) {} - // } - // - // function testRequireOff(uint gasConsumed) public { - // uint initialGas = gasleft(); - // while (initialGas - gasleft() < gasConsumed) {} - // require(true); - // initialGas = gasleft(); - // while (initialGas - gasleft() < gasConsumed) {} - // } - // } - - // data to call method testRevert(50000) - - Json::Value testRevert; - testRevert["to"] = "0xD2001300000000000000000000000000000000D4"; - testRevert["data"] = - "0x20987767000000000000000000000000000000000000000000000000000000000000c350"; - string response = fixture.estimateGasShouldFail( testRevert ); - BOOST_CHECK( - response.find( "EVM revert instruction without description message" ) != string::npos ); - - Json::Value testPositive; - testPositive["to"] = "0xD2001300000000000000000000000000000000D4"; - testPositive["data"] = - "0xfdde8d66000000000000000000000000000000000000000000000000000000000000c350"; - response = fixture.rpcClient->eth_estimateGas( testPositive ); - string response2 = fixture.rpcClient->eth_estimateGas( testPositive, "latest" ); - string response3 = fixture.rpcClient->eth_estimateGas( testPositive, "1" ); - BOOST_CHECK_EQUAL( response, "0x1db20" ); - BOOST_CHECK_EQUAL( response2, "0x1db20" ); - BOOST_CHECK_EQUAL( response3, "0x1db20" ); -} - -BOOST_AUTO_TEST_CASE( eth_estimateGas_chainId ) { - std::string _config = c_genesisConfigString; - Json::Value ret; - Json::Reader().parse( _config, ret ); - - // Set chainID = 65535 - ret["params"]["chainID"] = "0xffff"; - - Json::FastWriter fastWriter; - std::string config = fastWriter.write( ret ); - JsonRpcFixture fixture( config ); - - // pragma solidity ^0.8.13; - - // contract Counter { - // error BlockNumber(uint256 blockNumber); - - // constructor() { - // revert BlockNumber(block.chainid); - // } - // } - - Json::Value testRevert; - testRevert["data"] = - "0x6080604052348015600f57600080fd5b50604051633013bad360e21b81524660048201526024016040518091" - "0390fdfe"; - - try { - fixture.rpcClient->eth_estimateGas( testRevert, "latest" ); - } catch ( jsonrpc::JsonRpcException& ex ) { - BOOST_CHECK_EQUAL( ex.GetCode(), 3 ); - BOOST_CHECK_EQUAL( ex.GetData().asString(), - "0xc04eeb4c000000000000000000000000000000000000000000000000000000000000ffff" ); - BOOST_CHECK_EQUAL( ex.GetMessage(), "EVM revert instruction without description message" ); - } -} - -BOOST_AUTO_TEST_CASE( eth_sendRawTransaction_gasLimitExceeded ) { - JsonRpcFixture fixture; - auto senderAddress = fixture.coinbase.address(); - dev::eth::simulateMining( *( fixture.client ), 1 ); - - // We change author because coinbase.address() is author address by default - // and will take all transaction fee after execution so we can't check money spent - // for senderAddress correctly. - fixture.client->setAuthor( Address( 5 ) ); - - // contract test { - // function f(uint a) returns(uint d) { return a * 7; } - // } - - string compiled = - "6080604052341561000f57600080fd5b60b98061001d6000396000f300" - "608060405260043610603f576000357c01000000000000000000000000" - "00000000000000000000000000000000900463ffffffff168063b3de64" - "8b146044575b600080fd5b3415604e57600080fd5b606a600480360381" - "019080803590602001909291905050506080565b604051808281526020" - "0191505060405180910390f35b60006007820290509190505600a16562" - "7a7a72305820f294e834212334e2978c6dd090355312a3f0f9476b8eb9" - "8fb480406fc2728a960029"; - - Json::Value create; - int gas = 82000; // not enough but will pass size check - string gasPrice = "100000000000"; // 100b - create["from"] = toJS( senderAddress ); - create["code"] = compiled; - create["gas"] = gas; - create["gasPrice"] = gasPrice; - - BOOST_CHECK_EQUAL( jsToU256( fixture.rpcClient->eth_blockNumber() ), 1 ); - BOOST_CHECK_EQUAL( jsToU256( fixture.rpcClient->eth_getTransactionCount( - toJS( fixture.coinbase.address() ), "latest" ) ), - 0 ); - - u256 balanceBefore = jsToU256( - fixture.rpcClient->eth_getBalance( toJS( fixture.coinbase.address() ), "latest" ) ); - - BOOST_REQUIRE_EQUAL( jsToU256( fixture.rpcClient->eth_getTransactionCount( - toJS( fixture.coinbase.address() ), "latest" ) ), - 0 ); - - string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - u256 balanceAfter = jsToU256( - fixture.rpcClient->eth_getBalance( toJS( fixture.coinbase.address() ), "latest" ) ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - - BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x0" ) ); - BOOST_REQUIRE_EQUAL( balanceBefore - balanceAfter, u256( gas ) * u256( gasPrice ) ); -} - -BOOST_AUTO_TEST_CASE( contract_storage ) { - JsonRpcFixture fixture; - dev::eth::simulateMining( *( fixture.client ), 1 ); - - - // pragma solidity ^0.4.22; - - // contract test - // { - // uint hello; - // function writeHello(uint value) returns(bool d) - // { - // hello = value; - // return true; - // } - // } - - - string compiled = - "6080604052341561000f57600080fd5b60c28061001d6000396000f3006" - "08060405260043610603f576000357c0100000000000000000000000000" - "000000000000000000000000000000900463ffffffff16806315b2eec31" - "46044575b600080fd5b3415604e57600080fd5b606a6004803603810190" - "80803590602001909291905050506084565b60405180821515151581526" - "0200191505060405180910390f35b600081600081905550600190509190" - "505600a165627a7a72305820d8407d9cdaaf82966f3fa7a3e665b8cf4e6" - "5ee8909b83094a3f856b9051274500029"; - - Json::Value create; - create["code"] = compiled; - create["gas"] = "180000"; // TODO or change global default of 90000? - string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( !receipt["contractAddress"].isNull() ); - string contractAddress = receipt["contractAddress"].asString(); - BOOST_REQUIRE( contractAddress != "null" ); - - Json::Value transact; - transact["to"] = contractAddress; - transact["data"] = "0x15b2eec30000000000000000000000000000000000000000000000000000000000000003"; - string txHash2 = fixture.rpcClient->eth_sendTransaction( transact ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - string storage = fixture.rpcClient->eth_getStorageAt( contractAddress, "0", "latest" ); - BOOST_CHECK_EQUAL( - storage, "0x0000000000000000000000000000000000000000000000000000000000000003" ); - - Json::Value receipt2 = fixture.rpcClient->eth_getTransactionReceipt( txHash2 ); - string contractAddress2 = receipt2["contractAddress"].asString(); - BOOST_REQUIRE( receipt2["contractAddress"].isNull() ); -} - -BOOST_AUTO_TEST_CASE( web3_sha3, *boost::unit_test::precondition( dev::test::run_not_express ) ) { - JsonRpcFixture fixture; - string testString = "multiply(uint256)"; - h256 expected = dev::sha3( testString ); - - auto hexValue = fromAscii( testString ); - string result = fixture.rpcClient->web3_sha3( hexValue ); - BOOST_CHECK_EQUAL( toJS( expected ), result ); - BOOST_CHECK_EQUAL( - "0xc6888fa159d67f77c2f3d7a402e199802766bd7e8d4d1ecd2274fc920265d56a", result ); -} - -BOOST_AUTO_TEST_CASE( test_importRawBlock ) { - JsonRpcFixture fixture( c_genesisConfigString ); - string blockHash = fixture.rpcClient->test_importRawBlock( - "0xf90279f9020ea0" - // "c92211c9cd49036c37568feedb8e518a24a77e9f6ca959931a19dcf186a8e1e6" - // TODO this is our genesis (with stateRoot=1!) hash - just generated from code; need to - // check it by hands - "b449751a1ccedfcdae41640170e1712e8100d45061e6945f8fc7f556034d61ea" - "a01dcc4de8" - "dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2" - "697ff9baa0328f16ca7b0259d7617b3ddf711c107efe6d5785cbeb11a8ed1614b484a6bc3aa093ca2a18d52e7c" - "1846f7b104e2fc1e5fdc71ebe38187248f9437d39e74f43aaba0f5a4cad211681b78d25e6fde8dea45961dd1d2" - "22a43e4d75e3b7733e50889203b901000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "00008304000001830f460f82a0348203e897d68094312e342e302b2b62383163726c696e7578676e75a08e2042" - "e00086a18e2f095bc997dc11d1c93fcf34d0540a428ee95869a4a62264883f8fd3f43a3567c3f865f863800183" - "061a8094095e7baea6a6c7c4c2dfeb977efac326af552d87830186a0801ca0e94818d1f3b0c69eb37720145a5e" - "ad7fbf6f8d80139dd53953b4a782301050a3a01fcf46908c01576715411be0857e30027d6be3250a3653f049b3" - "ff8d74d2540cc0" ); - - // blockHash, "0xedef94eddd6002ae14803b91aa5138932f948026310144fc615d52d7d5ff29c7" ); - // TODO again, this was computed just in code - no trust to it - std::cout << blockHash << std::endl; - BOOST_CHECK_EQUAL( - blockHash, "0x7683f686a7ecf6949d29cab2075b8aa45f061e27338e61ea3c37a7a0bd80f17b" ); -} - -BOOST_AUTO_TEST_CASE( call_from_parameter ) { - JsonRpcFixture fixture; - dev::eth::simulateMining( *( fixture.client ), 1 ); - - - // pragma solidity ^0.5.1; - - // contract Test - // { - - // function whoAmI() public view returns (address) { - // return msg.sender; - // } - // } - - - string compiled = - "608060405234801561001057600080fd5b5060c68061001f6000396000f" - "3fe6080604052600436106039576000357c010000000000000000000000" - "000000000000000000000000000000000090048063da91254c14603e575" - "b600080fd5b348015604957600080fd5b5060506092565b604051808273" - "ffffffffffffffffffffffffffffffffffffffff1673fffffffffffffff" - "fffffffffffffffffffffffff16815260200191505060405180910390f3" - "5b60003390509056fea165627a7a72305820abfa953fead48d8f657bca6" - "57713501650734d40342585cafcf156a3fe1f41d20029"; - - auto senderAddress = fixture.coinbase.address(); - - Json::Value create; - create["from"] = toJS( senderAddress ); - create["code"] = compiled; - create["gas"] = "180000"; // TODO or change global default of 90000? - string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - std::cout << cc::now2string() << " eth_getTransactionReceipt" << std::endl; - Json::Value receipt; - try { - receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - } catch ( ... ) { - std::cout << cc::now2string() << " /eth_getTransactionReceipt" << std::endl; - throw; - } - std::cout << cc::now2string() << " /eth_getTransactionReceipt" << std::endl; - string contractAddress = receipt["contractAddress"].asString(); - - Json::Value transactionCallObject; - transactionCallObject["to"] = contractAddress; - transactionCallObject["data"] = "0xda91254c"; - - fixture.accountHolder->setAccounts( vector< dev::KeyPair >() ); - - string responseString = fixture.rpcClient->eth_call( transactionCallObject, "latest" ); - BOOST_CHECK_EQUAL( - responseString, "0x0000000000000000000000000000000000000000000000000000000000000000" ); - - transactionCallObject["from"] = "0x112233445566778899aabbccddeeff0011223344"; - - responseString = fixture.rpcClient->eth_call( transactionCallObject, "latest" ); - BOOST_CHECK_EQUAL( - responseString, "0x000000000000000000000000112233445566778899aabbccddeeff0011223344" ); -} - - -BOOST_AUTO_TEST_CASE( call_with_error ) { - JsonRpcFixture fixture; - dev::eth::simulateMining( *( fixture.client ), 1 ); - - // pragma solidity ^0.8.0; - // contract BasicCustomErrorContract { - // // Define custom errors - // error InsufficientBalance(); - // error Unauthorized(); - // address public owner; - // // Function only callable by the owner - // function ownerOnlyFunction() external { - // revert Unauthorized(); - // } - // } - - string compiled = - "608060405234801561001057600080fd5b50610168806100206000396000f3fe608060" - "405234801561001057600080fd5b5060043610610053576000357c0100000000000000" - "000000000000000000000000000000000000000000900480638da5cb5b146100585780" - "63e021c20614610076575b600080fd5b610060610080565b60405161006d9190610117" - "565b60405180910390f35b61007e6100a4565b005b60008054906101000a900473ffff" - "ffffffffffffffffffffffffffffffffffff1681565b6040517f82b429000000000000" - "0000000000000000000000000000000000000000000000815260040160405180910390" - "fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60" - "00610101826100d6565b9050919050565b610111816100f6565b82525050565b600060" - "208201905061012c6000830184610108565b9291505056fea264697066735822122013" - "2ca0f4158a0540a7e67f304c94305f81bbe52de2314e2b9cee92a2c74e103a64736f6c" - "63430008120033"; - - auto senderAddress = fixture.coinbase.address(); - - Json::Value create; - create["from"] = toJS( senderAddress ); - create["code"] = compiled; - create["gas"] = "180000"; - string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - string contractAddress = receipt["contractAddress"].asString(); - - Json::Value transactionCallObject; - transactionCallObject["to"] = contractAddress; - transactionCallObject["data"] = "0xe021c206"; - - try { - fixture.rpcClient->eth_call( transactionCallObject, "latest" ); - } catch ( jsonrpc::JsonRpcException& ex ) { - BOOST_CHECK_EQUAL( ex.GetCode(), 3 ); - BOOST_CHECK_EQUAL( ex.GetData().asString(), "0x82b42900" ); - BOOST_CHECK_EQUAL( ex.GetMessage(), "EVM revert instruction without description message" ); - } -} - -BOOST_AUTO_TEST_CASE( eth_call_create ) { - JsonRpcFixture fixture; - dev::eth::simulateMining( *( fixture.client ), 1 ); - - auto senderAddress = fixture.coinbase.address(); - - // contract test { - // function f(uint a) returns(uint d) { return a * 7; } - // } - string compiled = - "6080604052348015600f57600080fd5b5060b98061001d6000396000f300" - "608060405260043610603f576000357c01000000000000000000000000" - "00000000000000000000000000000000900463ffffffff168063b3de64" - "8b146044575b600080fd5b3415604e57600080fd5b606a600480360381" - "019080803590602001909291905050506080565b604051808281526020" - "0191505060405180910390f35b60006007820290509190505600a16562" - "7a7a72305820f294e834212334e2978c6dd090355312a3f0f9476b8eb9" - "8fb480406fc2728a960029"; - - // eth_call with no "to" field triggers creation transaction - Json::Value callObject; - callObject["from"] = toJS( senderAddress ); - callObject["data"] = "0x" + compiled; - callObject["gas"] = "1000000"; - callObject["gasPrice"] = "0"; - - string callResult = fixture.rpcClient->eth_call( callObject, "latest" ); - // creation via eth_call should return the runtime bytecode - BOOST_REQUIRE( callResult.size() > 2 ); - BOOST_REQUIRE( callResult != "0x" ); - - // verify state was not modified by eth_call (nonce unchanged) - u256 nonceAfterCall = jsToU256( - fixture.rpcClient->eth_getTransactionCount( toJS( senderAddress ), "latest" ) ); - BOOST_REQUIRE_EQUAL( nonceAfterCall, 0 ); - - // now actually deploy via eth_sendTransaction and verify we get the same runtime bytecode - Json::Value deployTx; - deployTx["from"] = toJS( senderAddress ); - deployTx["code"] = compiled; - deployTx["gas"] = "1000000"; - string txHash = fixture.rpcClient->eth_sendTransaction( deployTx ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x1" ) ); - BOOST_REQUIRE( !receipt["contractAddress"].isNull() ); - - string contractAddress = receipt["contractAddress"].asString(); - string deployedCode = fixture.rpcClient->eth_getCode( contractAddress, "latest" ); - - // the runtime bytecode from eth_call should match the actually deployed code - BOOST_REQUIRE_EQUAL( callResult, deployedCode ); -} - -BOOST_AUTO_TEST_CASE( estimate_gas_with_error ) { - JsonRpcFixture fixture; - dev::eth::simulateMining( *( fixture.client ), 1 ); - - // pragma solidity ^0.8.0; - // contract BasicCustomErrorContract { - // // Define custom errors - // error InsufficientBalance(); - // error Unauthorized(); - // address public owner; - // // Function only callable by the owner - // function ownerOnlyFunction() external { - // revert Unauthorized(); - // } - // } - - string compiled = - "608060405234801561001057600080fd5b50610168806100206000396000f3fe608060" - "405234801561001057600080fd5b5060043610610053576000357c0100000000000000" - "000000000000000000000000000000000000000000900480638da5cb5b146100585780" - "63e021c20614610076575b600080fd5b610060610080565b60405161006d9190610117" - "565b60405180910390f35b61007e6100a4565b005b60008054906101000a900473ffff" - "ffffffffffffffffffffffffffffffffffff1681565b6040517f82b429000000000000" - "0000000000000000000000000000000000000000000000815260040160405180910390" - "fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60" - "00610101826100d6565b9050919050565b610111816100f6565b82525050565b600060" - "208201905061012c6000830184610108565b9291505056fea264697066735822122013" - "2ca0f4158a0540a7e67f304c94305f81bbe52de2314e2b9cee92a2c74e103a64736f6c" - "63430008120033"; - - auto senderAddress = fixture.coinbase.address(); - - Json::Value create; - create["from"] = toJS( senderAddress ); - create["code"] = compiled; - create["gas"] = "180000"; - string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - string contractAddress = receipt["contractAddress"].asString(); - - Json::Value transactionCallObject; - transactionCallObject["to"] = contractAddress; - transactionCallObject["data"] = "0xe021c206"; - - try { - fixture.rpcClient->eth_estimateGas( transactionCallObject, "latest" ); - } catch ( jsonrpc::JsonRpcException& ex ) { - BOOST_CHECK_EQUAL( ex.GetCode(), 3 ); - BOOST_CHECK_EQUAL( ex.GetData().asString(), "0x82b42900" ); - BOOST_CHECK_EQUAL( ex.GetMessage(), "EVM revert instruction without description message" ); - } -} - -#ifndef FAIR -BOOST_AUTO_TEST_CASE( simplePoWTransaction ) { - u256 ESTIMATE_AFTER_PATCH = u256( 21000 + 1024 * 16 ); - u256 ESTIMATE_BEFORE_PATCH = u256( 21000 + 1024 * 68 ); - - // 1s empty block interval - JsonRpcFixture fixture( "", true, true, false, false, false, 1000 ); - dev::eth::simulateMining( *( fixture.client ), 1 ); - - auto senderAddress = fixture.coinbase.address(); - - Json::Value transact; - transact["from"] = toJS( senderAddress ); - transact["to"] = toJS( senderAddress ); - // 1k - ostringstream ss( "0x" ); - for ( int i = 0; i < 1024 / 16; ++i ) - ss << "112233445566778899aabbccddeeff11"; - transact["data"] = ss.str(); - - string gasEstimateStr = fixture.rpcClient->eth_estimateGas( transact ); - u256 gasEstimate = jsToU256( gasEstimateStr ); - - // old estimate before patch - BOOST_REQUIRE_EQUAL( gasEstimate, ESTIMATE_BEFORE_PATCH ); - - u256 powGasPrice = 0; - - - do { - // mine enough POW to tun transaction after PATCH but not before patch - const u256 GAS_PER_HASH = 1; - u256 candidate = h256::random(); - h256 hash = dev::sha3( senderAddress ) ^ dev::sha3( u256( 0 ) ) ^ dev::sha3( candidate ); - u256 externalGas = ~u256( 0 ) / u256( hash ) / GAS_PER_HASH; - if ( externalGas >= ESTIMATE_AFTER_PATCH && - externalGas < ESTIMATE_AFTER_PATCH + ESTIMATE_AFTER_PATCH / 10 ) { - powGasPrice = candidate; - } - } while ( !powGasPrice ); - // Account balance is too low will mean that PoW didn't work out - transact["gasPrice"] = toJS( powGasPrice ); - - // we may've been calculating pow for too long and patch is active already - // need to know the block number at this point - auto latestBlockNumber = - fixture.client->blockInfo( fixture.client->hashFromNumber( LatestBlock ) ).number(); - - // wait for patch turning on and see how it happens - string txHash; - BlockHeader badInfo, goodInfo; - uint64_t blockCounter = 2; - for ( ;; ) { - gasEstimateStr = fixture.rpcClient->eth_estimateGas( transact ); - gasEstimate = jsToU256( gasEstimateStr ); - // old - if ( gasEstimate == ESTIMATE_BEFORE_PATCH ) { - // we are before patch. Sending show fail since we do not have enough PoW gas - try { - fixture.rpcClient->eth_sendTransaction( transact ); - BOOST_REQUIRE( false ); - } catch ( const std::exception& ex ) { - assert( string( ex.what() ).find( "balance is too low" ) != string::npos ); - badInfo = - fixture.client->blockInfo( fixture.client->hashFromNumber( LatestBlock ) ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); // empty block - fixture.client->state().getOriginalDb()->createBlockSnap( blockCounter ); - blockCounter++; - } - } else { // now we are after patch - BOOST_REQUIRE_EQUAL( gasEstimate, ESTIMATE_AFTER_PATCH ); - txHash = fixture.rpcClient->eth_sendTransaction( transact ); - goodInfo = fixture.client->blockInfo( fixture.client->hashFromNumber( LatestBlock ) ); - break; - } - } - - BOOST_REQUIRE_LT( badInfo.timestamp(), fixture.powPatchActivationTimestamp ); - BOOST_REQUIRE_GE( goodInfo.timestamp(), fixture.powPatchActivationTimestamp ); - BOOST_REQUIRE_EQUAL( std::max( badInfo.number() + 1, latestBlockNumber ), goodInfo.number() ); - - dev::eth::mineTransaction( *( fixture.client ), 1 ); - fixture.client->state().getOriginalDb()->createBlockSnap( blockCounter ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE_EQUAL( receipt["status"], "0x1" ); -} -#endif - -#ifndef FAIR -BOOST_AUTO_TEST_CASE( clearPartialReceipts ) { - // Prepare fixture - std::string _config = c_genesisConfigString; - Json::Value ret; - Json::Reader().parse( _config, ret ); - - std::string chainID = "0x97"; // 151 - ret["params"]["chainID"] = chainID; - time_t clearPartialReceiptsActivationTs = time( nullptr ) + 10; - ret["skaleConfig"]["sChain"]["clearPartialReceiptsPatchTimestamp"] = - clearPartialReceiptsActivationTs; - ret["skaleConfig"]["sChain"]["singleStateCommitPerBlockPatchTimestamp"] = - std::numeric_limits< time_t >::max(); - - Json::FastWriter fastWriter; - std::string config = fastWriter.write( ret ); - JsonRpcFixture fixture( config ); - - // To fill coinbase wallet - dev::eth::simulateMining( *( fixture.client ), 20 ); - - string senderAddress = toJS( fixture.coinbase.address() ); - - Json::Value transactionCallObject; - transactionCallObject["from"] = toJS( senderAddress ); - transactionCallObject["to"] = "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a"; - transactionCallObject["data"] = "0x28b5e32b"; - - int64_t blocksToCheck = 6, timestampTransitionBlock = 4, expectedNoLegacyReceiptsBlock = 5; - - for ( int64_t block = 2; block < blocksToCheck; ++block ) { - if ( block == timestampTransitionBlock ) { - sleep( 12 ); - } - - TransactionSkeleton ts = toTransactionSkeleton( transactionCallObject ); - ts = fixture.client->populateTransactionWithDefaults( ts ); - pair< bool, Secret > ar = fixture.accountHolder->authenticate( ts ); - Transaction tx( ts, ar.second ); - auto txHash = fixture.rpcClient->eth_sendRawTransaction( toJS( tx.toBytes() ) ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - auto receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - dev::eth::BlockNumber blockNumber = jsToInt( receipt["blockNumber"].asString() ); - skale::State state( fixture.client->state() ); - BOOST_REQUIRE_EQUAL( blockNumber, block ); - BOOST_REQUIRE_EQUAL( state.safePartialTransactionReceipts( blockNumber ).size(), 0 ); - int64_t expectedSize = block == expectedNoLegacyReceiptsBlock ? 0 : 1; - BOOST_REQUIRE_EQUAL( state.safeLegacyPartialTransactionReceipts().size(), expectedSize ); - } -} - -BOOST_AUTO_TEST_CASE( single_state_commit_per_block_patch_transition ) { - Json::Value configJson; - Json::Reader().parse( c_genesisConfigString, configJson ); - time_t activationTimestamp = time( nullptr ) + 5; - configJson["skaleConfig"]["sChain"]["SingleStateCommitPerBlockPatchTimestamp"] = - static_cast< Json::Int64 >( activationTimestamp ); - - Json::FastWriter fastWriter; - JsonRpcFixture fixture( fastWriter.write( configJson ), true, true, false, true ); - dev::eth::simulateMining( *( fixture.client ), 1 ); - - struct DbCommitCounterGuard { - DbCommitCounterGuard() { skale::state_commit_counter::enable( true ); } - ~DbCommitCounterGuard() { skale::state_commit_counter::enable( false ); } - } guard; - - u256 nextNonce; - - auto sendPayment = [&]() { - Json::Value tx; - tx["from"] = fixture.coinbase.address().hex(); - tx["to"] = fixture.account2.address().hex(); - tx["value"] = toJS( 1 ); - tx["gas"] = toJS( 21000 ); - tx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - tx["nonce"] = toJS( nextNonce ); - nextNonce++; - std::string hash = fixture.rpcClient->eth_sendTransaction( tx ); - BOOST_REQUIRE( !hash.empty() ); - }; - - auto produceBlockWithTransaction = [&]() { - nextNonce = jsToU256( fixture.rpcClient->eth_getTransactionCount( - fixture.coinbase.address().hex(), "latest" ) ); - sendPayment(); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - }; - - skale::state_commit_counter::reset(); - produceBlockWithTransaction(); - // Before activation: 2 commits (1 for tx execution, 1 for block state) - BOOST_REQUIRE_EQUAL( skale::state_commit_counter::count(), 2 ); - - // Receipts should not be saved before activation - auto progressLog = fixture.client->state().getProgressLog(); - BOOST_REQUIRE( progressLog ); - auto receiptsBefore = progressLog->loadProgressData(); - BOOST_CHECK( !receiptsBefore ); - - sleep( 6 ); - - // Produce a block after the activation timestamp so subsequent blocks observe - // commit-per-block semantics. - produceBlockWithTransaction(); - - skale::state_commit_counter::reset(); - produceBlockWithTransaction(); - // After activation: 1 commit (single commit per block) - BOOST_REQUIRE_EQUAL( skale::state_commit_counter::count(), 1 ); - - // Receipts should be saved after activation - auto receiptsAfter = progressLog->loadProgressData(); - BOOST_REQUIRE( receiptsAfter ); - BOOST_CHECK_EQUAL( receiptsAfter->receipts.size(), 1 ); -} - -BOOST_AUTO_TEST_CASE( state_progress_log_skip_already_committed ) { - Json::Value configJson; - Json::Reader().parse( c_genesisConfigString, configJson ); - configJson["skaleConfig"]["sChain"]["singleStateCommitPerBlockPatchTimestamp"] = - static_cast< Json::Int64 >( 1 ); - - Json::FastWriter fastWriter; - JsonRpcFixture fixture( fastWriter.write( configJson ), true, true, false, true ); - dev::eth::simulateMining( *( fixture.client ), 1 ); - - struct DbCommitCounterGuard { - DbCommitCounterGuard() { skale::state_commit_counter::enable( true ); } - ~DbCommitCounterGuard() { skale::state_commit_counter::enable( false ); } - } guard; - - u256 nextNonce; - - auto sendPayment = [&]() { - Json::Value tx; - tx["from"] = fixture.coinbase.address().hex(); - tx["to"] = fixture.account2.address().hex(); - tx["value"] = toJS( 1 ); - tx["gas"] = toJS( 21000 ); - tx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - tx["nonce"] = toJS( nextNonce ); - nextNonce++; - std::string hash = fixture.rpcClient->eth_sendTransaction( tx ); - BOOST_REQUIRE( !hash.empty() ); - }; - - auto produceBlockWithTransaction = [&]() { - nextNonce = jsToU256( fixture.rpcClient->eth_getTransactionCount( - fixture.coinbase.address().hex(), "latest" ) ); - sendPayment(); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - }; - - produceBlockWithTransaction(); - - skale::state_commit_counter::reset(); - produceBlockWithTransaction(); - BOOST_REQUIRE_EQUAL( skale::state_commit_counter::count(), 1 ); - - auto progressLog = fixture.client->state().getProgressLog(); - BOOST_REQUIRE( progressLog ); - BOOST_CHECK( progressLog->isBlockCommitCompleted( fixture.client->number() ) ); -} - -BOOST_AUTO_TEST_CASE( state_progress_log_crash_recovery ) { - Json::Value configJson; - Json::Reader().parse( c_genesisConfigString, configJson ); - configJson["skaleConfig"]["sChain"]["singleStateCommitPerBlockPatchTimestamp"] = - static_cast< Json::Int64 >( 1 ); - - Json::FastWriter fastWriter; - JsonRpcFixture fixture( fastWriter.write( configJson ), true, true, false, true ); - dev::eth::simulateMining( *( fixture.client ), 1 ); - - struct DbCommitCounterGuard { - DbCommitCounterGuard() { skale::state_commit_counter::enable( true ); } - ~DbCommitCounterGuard() { skale::state_commit_counter::enable( false ); } - } guard; - - u256 nextNonce; - - auto sendPayment = [&]() { - Json::Value tx; - tx["from"] = fixture.coinbase.address().hex(); - tx["to"] = fixture.account2.address().hex(); - tx["value"] = toJS( 1 ); - tx["gas"] = toJS( 21000 ); - tx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - tx["nonce"] = toJS( nextNonce ); - nextNonce++; - std::string hash = fixture.rpcClient->eth_sendTransaction( tx ); - BOOST_REQUIRE( !hash.empty() ); - }; - - auto produceBlockWithTransaction = [&]() { - nextNonce = jsToU256( fixture.rpcClient->eth_getTransactionCount( - fixture.coinbase.address().hex(), "latest" ) ); - sendPayment(); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - }; - - produceBlockWithTransaction(); - - auto progressLog = fixture.client->state().getProgressLog(); - BOOST_REQUIRE( progressLog ); - - uint64_t completedBlock = fixture.client->number(); - BOOST_CHECK( progressLog->isBlockCommitCompleted( completedBlock ) ); - - progressLog->markBlockCommitStarted( completedBlock + 1 ); - BOOST_CHECK( !progressLog->isBlockCommitCompleted( completedBlock + 1 ) ); - - skale::state_commit_counter::reset(); - produceBlockWithTransaction(); - BOOST_REQUIRE_EQUAL( skale::state_commit_counter::count(), 1 ); - - BOOST_CHECK( progressLog->isBlockCommitCompleted( fixture.client->number() ) ); -} - -namespace { -template < typename PatchType > -void waitForPatchActivation( int timeoutSeconds = 10 ) { - auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds( timeoutSeconds ); - while ( !PatchType::isEnabledWhen( time( nullptr ) ) ) { - BOOST_REQUIRE( std::chrono::steady_clock::now() < deadline ); - std::this_thread::sleep_for( std::chrono::milliseconds( 50 ) ); - } -} -} // namespace - -#ifndef FAIR -// Test fs commits before SingleStateCommitPerBlockPatch is active -BOOST_AUTO_TEST_CASE( single_fs_commit_per_block_patch_before ) { - Json::Value configJson; - Json::Reader().parse( c_genesisConfigString, configJson ); - // Patch disabled (far future timestamp) - configJson["skaleConfig"]["sChain"]["singleStateCommitPerBlockPatchTimestamp"] = - static_cast< Json::Int64 >( 0 ); - configJson["skaleConfig"]["sChain"]["revertableFSPatchTimestamp"] = - static_cast< Json::Int64 >( 1 ); - - Json::FastWriter fastWriter; - RestrictedAddressFixture fixture( fastWriter.write( configJson ), true ); - dev::eth::simulateMining( *( fixture.client ), 1 ); - - struct FsCommitCounterGuard { - FsCommitCounterGuard() { skale::fs_commit_counter::enable( true ); } - ~FsCommitCounterGuard() { skale::fs_commit_counter::enable( false ); } - } guard; - - auto senderAddress = fixture.coinbase.address(); - fixture.client->setAuthor( senderAddress ); - - u256 nextNonce; - - auto executeFilestorageOperation = [&]() { - Json::Value tx; - tx["from"] = toJS( senderAddress ); - tx["to"] = "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a"; - tx["data"] = "0xf38fb65b"; - tx["nonce"] = toJS( nextNonce ); - nextNonce++; - TransactionSkeleton ts = toTransactionSkeleton( tx ); - ts = fixture.client->populateTransactionWithDefaults( ts ); - pair< bool, Secret > ar = fixture.accountHolder->authenticate( ts ); - Transaction transaction( ts, ar.second ); - fixture.rpcClient->eth_sendRawTransaction( toJS( transaction.toBytes() ) ); - }; - - auto produceBlockWithFilestorageOperations = [&]() { - nextNonce = jsToU256( fixture.rpcClient->eth_getTransactionCount( - toJS( senderAddress ), "latest" ) ); - executeFilestorageOperation(); - executeFilestorageOperation(); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - fixture.client->state().getOriginalDb()->createBlockSnap( fixture.client->number() ); - }; - - // Without patch: expect 2 commits (one per transaction) - skale::fs_commit_counter::reset(); - produceBlockWithFilestorageOperations(); - BOOST_REQUIRE_EQUAL( skale::fs_commit_counter::count(), 2 ); -} - -// Test fs commits after SingleStateCommitPerBlockPatch is active -BOOST_AUTO_TEST_CASE( single_fs_commit_per_block_patch_after ) { - Json::Value configJson; - Json::Reader().parse( c_genesisConfigString, configJson ); - // Patch enabled from genesis - configJson["skaleConfig"]["sChain"]["singleStateCommitPerBlockPatchTimestamp"] = - static_cast< Json::Int64 >( 1 ); - configJson["skaleConfig"]["sChain"]["revertableFSPatchTimestamp"] = - static_cast< Json::Int64 >( 1 ); - - Json::FastWriter fastWriter; - RestrictedAddressFixture fixture( fastWriter.write( configJson ), true ); - dev::eth::simulateMining( *( fixture.client ), 1 ); - - struct FsCommitCounterGuard { - FsCommitCounterGuard() { skale::fs_commit_counter::enable( true ); } - ~FsCommitCounterGuard() { skale::fs_commit_counter::enable( false ); } - } guard; - - auto senderAddress = fixture.coinbase.address(); - fixture.client->setAuthor( senderAddress ); - - u256 nextNonce; - - auto executeFilestorageOperation = [&]() { - Json::Value tx; - tx["from"] = toJS( senderAddress ); - tx["to"] = "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a"; - tx["data"] = "0xf38fb65b"; - tx["nonce"] = toJS( nextNonce ); - nextNonce++; - TransactionSkeleton ts = toTransactionSkeleton( tx ); - ts = fixture.client->populateTransactionWithDefaults( ts ); - pair< bool, Secret > ar = fixture.accountHolder->authenticate( ts ); - Transaction transaction( ts, ar.second ); - fixture.rpcClient->eth_sendRawTransaction( toJS( transaction.toBytes() ) ); - }; - - auto produceBlockWithFilestorageOperations = [&]() { - nextNonce = jsToU256( fixture.rpcClient->eth_getTransactionCount( - toJS( senderAddress ), "latest" ) ); - executeFilestorageOperation(); - executeFilestorageOperation(); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - fixture.client->state().getOriginalDb()->createBlockSnap( fixture.client->number() ); - }; - - // With patch: expect 1 commit (one per block) - skale::fs_commit_counter::reset(); - produceBlockWithFilestorageOperations(); - BOOST_REQUIRE_EQUAL( skale::fs_commit_counter::count(), 1 ); -} -#endif - -BOOST_AUTO_TEST_CASE( recalculateExternalGas ) { - std::string _config = c_genesisConfigString; - Json::Value ret; - Json::Reader().parse( _config, ret ); - - std::string chainID = "0x15"; - ret["params"]["chainID"] = chainID; - - // remove deployment control - auto accounts = ret["accounts"]; - accounts.removeMember( "0xD2002000000000000000000000000000000000D2" ); - ret["accounts"] = accounts; - - // setup patch - time_t externalGasPatchActivationTimestamp = time( nullptr ) + 10; - ret["skaleConfig"]["sChain"]["ExternalGasPatchTimestamp"] = externalGasPatchActivationTimestamp; - - Json::FastWriter fastWriter; - std::string config = fastWriter.write( ret ); - JsonRpcFixture fixture( config, true, false ); - dev::eth::simulateMining( *( fixture.client ), 20 ); - - auto senderAddress = fixture.coinbase.address().hex(); - - // // SPDX-License-Identifier: GPL-3.0 - - // pragma solidity >=0.8.2 <0.9.0; - - // /** - // * @title Storage - // * @dev Store & retrieve value in a variable - // * @custom:dev-run-script ./scripts/deploy_with_ethers.ts - // */ - // contract Storage { - - // uint256 number; - // uint256 number1; - // uint256 number2; - - // /** - // * @dev Store value in variable - // * @param num value to store - // */ - // function store(uint256 num) public { - // number = num; - // number1 = num; - // number2 = num; - // } - - // /** - // * @dev Return value - // * @return value of 'number' - // */ - // function retrieve() public view returns (uint256){ - // return number; - // } - // } - std::string bytecode = - "608060405234801561001057600080fd5b5061015e806100206000396000f3fe60806040523480156100105760" - "0080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080" - "fd5b610043610075565b60405161005091906100e7565b60405180910390f35b61007360048036038101906100" - "6e91906100ab565b61007e565b005b60008054905090565b806000819055508060018190555080600281905550" - "50565b6000813590506100a581610111565b92915050565b6000602082840312156100c1576100c061010c565b" - "5b60006100cf84828501610096565b91505092915050565b6100e181610102565b82525050565b600060208201" - "90506100fc60008301846100d8565b92915050565b6000819050919050565b600080fd5b61011a81610102565b" - "811461012557600080fd5b5056fea2646970667358221220780703bb6ac2eec922a510d57edcae39b852b578e7" - "f63a263ddb936758dc9c4264736f6c63430008070033"; - - // deploy contact - Json::Value create; - create["from"] = senderAddress; - create["code"] = bytecode; - create["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - create["gas"] = 140000; - create["nonce"] = 0; - - std::string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - fixture.client->state().getOriginalDb()->createBlockSnap( 2 ); - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( receipt["status"].asString() == "0x1" ); - std::string contractAddress = receipt["contractAddress"].asString(); - - // send txn to a contract from the suspicious account - // store( 4 ) - Json::Value txn; - txn["from"] = "0x40797bb29d12FC0dFD04277D16a3Dd4FAc3a6e5B"; - txn["data"] = "0x6057361d0000000000000000000000000000000000000000000000000000000000000004"; - txn["gasPrice"] = "0xdffe55527a88d3775c23ecd3ae38ff1e90caf12b5beb4f7ea3ad998a990a895c"; - txn["gas"] = 140000; - txn["chainId"] = "0x15"; - txn["nonce"] = 0; - txn["to"] = contractAddress; - - auto ts = toTransactionSkeleton( txn ); - auto t = dev::eth::Transaction( - ts, dev::Secret( "7be24de049f2d0d4ecaeaa81564aecf647fa7a4c86264243d77e01da25d859a0" ) ); - - txHash = fixture.rpcClient->eth_sendRawTransaction( dev::toHex( t.toBytes() ) ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - fixture.client->state().getOriginalDb()->createBlockSnap( 3 ); - receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - - - BOOST_REQUIRE( receipt["status"].asString() == "0x0" ); - BOOST_REQUIRE( receipt["gasUsed"].asString() == "0x61cb" ); - - - sleep( 10 ); - - // push new block to update timestamp - Json::Value refill; - refill["from"] = senderAddress; - refill["to"] = dev::Address::random().hex(); - refill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - refill["value"] = 100; - refill["nonce"] = 1; - - txHash = fixture.rpcClient->eth_sendTransaction( refill ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - fixture.client->state().getOriginalDb()->createBlockSnap( 4 ); - - // send txn to a contract from another suspicious account - // store( 4 ) - txn["from"] = "0x5cdb7527ec85022991D4e27F254C438E8337ad7E"; - txn["data"] = "0x6057361d0000000000000000000000000000000000000000000000000000000000000004"; - txn["gasPrice"] = "0x974749a06d5cd0dba6a4e1f3d14d5f480db716dcbc9a34ec5496b8d86e99f898"; - txn["gas"] = 140000; - txn["chainId"] = "0x15"; - txn["nonce"] = 0; - txn["to"] = contractAddress; - - ts = toTransactionSkeleton( txn ); - t = dev::eth::Transaction( - ts, dev::Secret( "8df08814fcfc169aad0015654114be06c28b27bdcdef286cf4dbd5e2950a3ffc" ) ); - - txHash = fixture.rpcClient->eth_sendRawTransaction( dev::toHex( t.toBytes() ) ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - fixture.client->state().getOriginalDb()->createBlockSnap( 5 ); - receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - - BOOST_REQUIRE( receipt["status"].asString() == "0x1" ); - BOOST_REQUIRE( receipt["gasUsed"].asString() == "0x13ef4" ); -} -#endif - -BOOST_AUTO_TEST_CASE( skipTransactionExecution ) { - std::string _config = c_genesisConfigString; - Json::Value ret; - Json::Reader().parse( _config, ret ); - - // Set chainID = 21 - std::string chainID = "0x15"; - ret["params"]["chainID"] = chainID; - - Json::FastWriter fastWriter; - std::string config = fastWriter.write( ret ); - JsonRpcFixture fixture( config ); - dev::eth::simulateMining( *( fixture.client ), 20 ); - - auto senderAddress = fixture.coinbase.address().hex(); - - Json::Value refill; - refill["from"] = senderAddress; - refill["to"] = "0x5EdF1e852fdD1B0Bc47C0307EF755C76f4B9c251"; - refill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - refill["value"] = 1000000000000000; - refill["nonce"] = 0; - - std::string txHash = fixture.rpcClient->eth_sendTransaction( refill ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - // send txn and verify that gas used is correct - // gas used value is hardcoded in State::txnsToSkipExecution - Json::Value txn; - txn["from"] = "0x5EdF1e852fdD1B0Bc47C0307EF755C76f4B9c251"; - txn["gasPrice"] = "0x4a817c800"; - txn["gas"] = 40000; - txn["chainId"] = "0x15"; - txn["nonce"] = 0; - txn["value"] = 1; - txn["to"] = "0x5cdb7527ec85022991D4e27F254C438E8337ad7E"; - - auto ts = toTransactionSkeleton( txn ); - auto t = dev::eth::Transaction( - ts, dev::Secret( "08cee1f4bc8c37f88124bb3fc64566ccd35dbeeac84c62300f6b8809cab9ea2f" ) ); - - txHash = fixture.rpcClient->eth_sendRawTransaction( dev::toHex( t.toBytes() ) ); - BOOST_REQUIRE( txHash == "0x95fb5557db8cc6de0aff3a64c18a6d9378b0d312b24f5d77e8dbf5cc0612d74f" ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( receipt["gasUsed"].asString() == "0x5ac0" ); -} - -#ifndef FAIR -BOOST_AUTO_TEST_CASE( transactionWithoutFunds ) { - JsonRpcFixture fixture; - dev::eth::simulateMining( *( fixture.client ), 1 ); - - // pragma solidity ^0.4.22; - - // contract test - // { - // uint hello; - // function writeHello(uint value) returns(bool d) - // { - // hello = value; - // return true; - // } - // } - - - string compiled = - "6080604052341561000f57600080fd5b60c28061001d6000396000f3006" - "08060405260043610603f576000357c0100000000000000000000000000" - "000000000000000000000000000000900463ffffffff16806315b2eec31" - "46044575b600080fd5b3415604e57600080fd5b606a6004803603810190" - "80803590602001909291905050506084565b60405180821515151581526" - "0200191505060405180910390f35b600081600081905550600190509190" - "505600a165627a7a72305820d8407d9cdaaf82966f3fa7a3e665b8cf4e6" - "5ee8909b83094a3f856b9051274500029"; - - auto senderAddress = fixture.coinbase.address(); - - Json::Value create; - create["from"] = toJS( senderAddress ); - create["code"] = compiled; - create["gas"] = "180000"; // TODO or change global default of 90000? - string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - string contractAddress = receipt["contractAddress"].asString(); - - Address address2 = fixture.account2.address(); - string balanceString = fixture.rpcClient->eth_getBalance( toJS( address2 ), "latest" ); - BOOST_REQUIRE_EQUAL( toJS( 0 ), balanceString ); - - Json::Value transact; - transact["from"] = toJS( address2 ); - transact["to"] = contractAddress; - transact["data"] = "0x15b2eec30000000000000000000000000000000000000000000000000000000000000003"; - - string gasEstimateStr = fixture.rpcClient->eth_estimateGas( transact ); - u256 gasEstimate = jsToU256( gasEstimateStr ); - - u256 powGasPrice = 0; - do { - const u256 GAS_PER_HASH = 1; - u256 candidate = h256::random(); - h256 hash = dev::sha3( address2 ) ^ dev::sha3( u256( 0 ) ) ^ dev::sha3( candidate ); - u256 externalGas = ~u256( 0 ) / u256( hash ) * GAS_PER_HASH; - if ( externalGas >= gasEstimate && externalGas < gasEstimate + gasEstimate / 10 ) { - powGasPrice = candidate; - } - } while ( !powGasPrice ); - transact["gasPrice"] = toJS( powGasPrice ); - - fixture.rpcClient->eth_sendTransaction( transact ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - string storage = fixture.rpcClient->eth_getStorageAt( contractAddress, "0", "latest" ); - BOOST_CHECK_EQUAL( - storage, "0x0000000000000000000000000000000000000000000000000000000000000003" ); - - balanceString = fixture.rpcClient->eth_getBalance( toJS( address2 ), "latest" ); - BOOST_REQUIRE_EQUAL( toJS( 0 ), balanceString ); -} -#endif - -BOOST_AUTO_TEST_CASE( eth_sendRawTransaction_gasPriceTooLow ) { - JsonRpcFixture fixture; - auto senderAddress = fixture.coinbase.address(); - auto receiver = KeyPair::create(); - - // Mine to generate a non-zero account balance - const int blocksToMine = 1; -#ifdef FAIR - const u256 blockReward = fixture.client->chainParams().blockReward( - fixture.client->blockChain().info().timestamp(), - fixture.client->blockChain().info().number() ); -#else - const u256 blockReward = 2 * dev::eth::ether; -#endif - dev::eth::simulateMining( *( fixture.client ), blocksToMine ); - BOOST_CHECK_EQUAL( blockReward, fixture.client->balanceAt( senderAddress ) ); - - u256 initial_gasPrice = fixture.client->gasBidPrice(); - - Json::Value t; - t["from"] = toJS( senderAddress ); - t["to"] = toJS( receiver.address() ); - t["value"] = jsToDecimal( toJS( 10000 * dev::eth::szabo ) ); - t["gasPrice"] = jsToDecimal( toJS( initial_gasPrice ) ); - - auto signedTx = fixture.rpcClient->eth_signTransaction( t ); - BOOST_REQUIRE( !signedTx["raw"].empty() ); - - auto txHash = fixture.rpcClient->eth_sendRawTransaction( signedTx["raw"].asString() ); - BOOST_REQUIRE( !txHash.empty() ); - - mineTransaction( *fixture.client, 1 ); - BOOST_REQUIRE_EQUAL( - fixture.rpcClient->eth_getTransactionCount( toJS( senderAddress ), "latest" ), "0x1" ); - - - ///////////////////////// - - t["nonce"] = "1"; - t["gasPrice"] = jsToDecimal( toJS( initial_gasPrice - 1 ) ); - auto signedTx2 = fixture.rpcClient->eth_signTransaction( t ); - BOOST_CHECK_EQUAL( fixture.sendingRawShouldFail( signedTx2["raw"].asString() ), - "Transaction gas price lower than current eth_gasPrice." ); -} - -// different ways to ask for topic(s) -BOOST_AUTO_TEST_CASE( logs ) { - JsonRpcFixture fixture; - dev::eth::simulateMining( *( fixture.client ), 1 ); - - // will generate topics [0xxxx, 0, 0], [0xxx, 0, 1] etc - /* - pragma solidity >=0.4.10 <0.7.0; - - contract Logger{ - - uint256 i; - uint256 j; - - fallback() external payable { - log3(bytes32(block.number), bytes32(block.number), bytes32(i), bytes32(j)); - j++; - if(j==10){ - j = 0; - i++; - }// j overflow - } - }*/ - - string bytecode = - "6080604052348015600f57600080fd5b50609b8061001e6000396000f3fe608060405260015460001b60005460" - "001b4360001b4360001b6040518082815260200191505060405180910390a36001600081548092919060010191" - "90505550600a6001541415606357600060018190555060008081548092919060010191905055505b00fea26469" - "70667358221220fdf2f98961b803b6b32dfc9be766990cbdb17559d9a03724d12fc672e33804b164736f6c6343" - "00060c0033"; - - Json::Value create; - create["code"] = bytecode; - create["gas"] = "180000"; // TODO or change global default of 90000? - - string deployHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value deployReceipt = fixture.rpcClient->eth_getTransactionReceipt( deployHash ); - string contractAddress = deployReceipt["contractAddress"].asString(); - - for ( int i = 0; i <= 23; ++i ) { - Json::Value t; - t["from"] = toJS( fixture.coinbase.address() ); - t["value"] = jsToDecimal( "0" ); - t["to"] = contractAddress; - t["gas"] = "99000"; - -#ifdef FAIR - std::string txHash; - if (i%2) { - txHash = fixture.rpcClient->eth_sendTransaction( t ); - } - else { - std::string addrWithout0x = contractAddress.substr( 2 ); - dev::bytes encryptedData = formEncryptedMessageMockup( dev::bytes(), dev::Address( addrWithout0x ) ); - // account for the nonce 0 used for contract deployment - size_t nonce = static_cast(i + 1); - std::string rlp = formTransactionRlp( fixture, t["from"].asString(), - dev::toHex( encryptedData ), nonce, addrWithout0x); - txHash = fixture.rpcClient->eth_sendRawTransaction( rlp ); - } -#else - std::string txHash = fixture.rpcClient->eth_sendTransaction( t ); -#endif - BOOST_REQUIRE( !txHash.empty() ); - - dev::eth::mineTransaction( *( fixture.client ), 1 ); - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - } - BOOST_REQUIRE_EQUAL( fixture.client->number(), 26 ); // block 1 - bootstrapAll, block 2 - - // deploy - - // ask for logs - Json::Value t; - t["fromBlock"] = 3; - t["toBlock"] = 26; - t["address"] = contractAddress; - t["topics"] = Json::Value( Json::arrayValue ); - - // 1 topics = [] - Json::Value logs = fixture.rpcClient->eth_getLogs( t ); - - BOOST_REQUIRE( logs.isArray() ); - BOOST_REQUIRE_EQUAL( logs.size(), 24 ); - u256 t1 = dev::jsToU256( logs[12]["topics"][1].asString() ); - BOOST_REQUIRE_EQUAL( t1, 1 ); - u256 t2 = dev::jsToU256( logs[12]["topics"][2].asString() ); - BOOST_REQUIRE_EQUAL( t2, 2 ); - - // 2 topics = [a] - t["topics"] = Json::Value( Json::arrayValue ); - t["topics"][1] = u256_to_js( dev::u256( 2 ) ); - - logs = fixture.rpcClient->eth_getLogs( t ); - - BOOST_REQUIRE( logs.isArray() ); - BOOST_REQUIRE_EQUAL( logs.size(), 4 ); - t1 = dev::jsToU256( logs[0]["topics"][1].asString() ); - BOOST_REQUIRE_EQUAL( t1, 2 ); - t2 = dev::jsToU256( logs[0]["topics"][2].asString() ); - BOOST_REQUIRE_EQUAL( t2, 0 ); - - // 3 topics = [null, a] - t["topics"] = Json::Value( Json::arrayValue ); - t["topics"][2] = u256_to_js( dev::u256( 1 ) ); // 01,11,21 but not 1x - - logs = fixture.rpcClient->eth_getLogs( t ); - - BOOST_REQUIRE( logs.isArray() ); - BOOST_REQUIRE_EQUAL( logs.size(), 3 ); - - // 4 topics = [a,b] - t["topics"] = Json::Value( Json::arrayValue ); - t["topics"][1] = u256_to_js( dev::u256( 1 ) ); - t["topics"][2] = u256_to_js( dev::u256( 2 ) ); - - logs = fixture.rpcClient->eth_getLogs( t ); - - BOOST_REQUIRE( logs.isArray() ); - BOOST_REQUIRE_EQUAL( logs.size(), 1 ); - - // 5 topics = [[a,b]] - t["topics"] = Json::Value( Json::arrayValue ); - t["topics"][1] = Json::Value( Json::arrayValue ); - t["topics"][1][0] = u256_to_js( dev::u256( 1 ) ); - t["topics"][1][1] = u256_to_js( dev::u256( 2 ) ); - - logs = fixture.rpcClient->eth_getLogs( t ); - - BOOST_REQUIRE( logs.isArray() ); - BOOST_REQUIRE_EQUAL( logs.size(), 10 + 4 ); - - // 6 topics = [a,a] - t["topics"] = Json::Value( Json::arrayValue ); - t["topics"][1] = u256_to_js( dev::u256( 1 ) ); - t["topics"][2] = u256_to_js( dev::u256( 1 ) ); - - logs = fixture.rpcClient->eth_getLogs( t ); - - BOOST_REQUIRE( logs.isArray() ); - BOOST_REQUIRE_EQUAL( logs.size(), 1 ); - - // 7 topics = [[a,b], c] - t["topics"] = Json::Value( Json::arrayValue ); - t["topics"][1] = Json::Value( Json::arrayValue ); - t["topics"][1][0] = u256_to_js( dev::u256( 1 ) ); - t["topics"][1][1] = u256_to_js( dev::u256( 2 ) ); - t["topics"][2] = u256_to_js( dev::u256( 1 ) ); // 11, 21 - - logs = fixture.rpcClient->eth_getLogs( t ); - - BOOST_REQUIRE( logs.isArray() ); - BOOST_REQUIRE_EQUAL( logs.size(), 2 ); - t1 = dev::jsToU256( logs[0]["topics"][1].asString() ); - BOOST_REQUIRE_EQUAL( t1, 1 ); - t2 = dev::jsToU256( logs[0]["topics"][2].asString() ); - BOOST_REQUIRE_EQUAL( t2, 1 ); - t1 = dev::jsToU256( logs[1]["topics"][1].asString() ); - BOOST_REQUIRE_EQUAL( t1, 2 ); - t2 = dev::jsToU256( logs[1]["topics"][2].asString() ); - BOOST_REQUIRE_EQUAL( t2, 1 ); - - // 8 repeat #7 without address - auto logs7 = logs; - t["address"] = Json::Value( Json::arrayValue ); - logs = fixture.rpcClient->eth_getLogs( t ); - BOOST_REQUIRE_EQUAL( logs7, logs ); - - // 9 repeat #7 with 2 addresses - t["address"] = Json::Value( Json::arrayValue ); - t["address"][0] = contractAddress; - t["address"][1] = "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"; // dummy - logs = fixture.rpcClient->eth_getLogs( t ); - BOOST_REQUIRE_EQUAL( logs7, logs ); - - // 10 request address only - t["topics"] = Json::Value( Json::arrayValue ); - logs = fixture.rpcClient->eth_getLogs( t ); - BOOST_REQUIRE( logs.isArray() ); - BOOST_REQUIRE_EQUAL( logs.size(), 24 ); - - Json::Value filterReq; - filterReq["fromBlock"] = 3; - filterReq["toBlock"] = 26; - filterReq["address"] = contractAddress; - filterReq["topics"] = Json::Value( Json::arrayValue ); - std::string filterId = fixture.rpcClient->eth_newFilter( filterReq ); - Json::Value filterLogs = fixture.rpcClient->eth_getFilterLogs( filterId ); - BOOST_REQUIRE( filterLogs.isArray() ); - BOOST_REQUIRE_EQUAL( filterLogs.size(), logs.size() ); -} - -// limit on getLogs output -BOOST_AUTO_TEST_CASE( getLogs_limit ) { - JsonRpcFixture fixture( - "", true, true, false, false, false, -1, { { "getLogsBlocksLimit", "10" } } ); - - dev::eth::simulateMining( *( fixture.client ), 100 ); - - // push0Patch is enabled by default for FAIR -#ifndef FAIR - // wait for push0Patch to be activated - sleep(10); - - // update block timestamp to activate patch - Json::Value txRefill; - txRefill["to"] = "0xc868AF52a6549c773082A334E5AE232e0Ea3B513"; - txRefill["from"] = toJS( fixture.coinbase.address() ); - txRefill["gas"] = "100000"; - txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txRefill["value"] = 100000000000000000; - string txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#endif - -/* -// SPDX-License-Identifier: None -pragma solidity ^0.8; -contract Logger{ -event DummyEvent(uint256, uint256); -fallback() external payable { - for(uint i=0; i<100; ++i) - emit DummyEvent(block.number, i); -} -} -*/ - - string bytecode = - "6080604052348015600e575f80fd5b5060c080601a5f395ff3fe60806040525f5b6064811015604f577f907787" - "67414a5c844b9d35a8745f67697ee3b8c2c3f4feafe5d9a3e234a5a3654382604051603d9291906067565b6040" - "5180910390a18060010190506006565b005b5f819050919050565b6061816051565b82525050565b5f60408201" - "905060785f830185605a565b60836020830184605a565b939250505056fea264697066735822122040208e35f2" - "706dd92c17579466ab671c308efec51f558a755ea2cf81105ab22964736f6c63430008190033"; - - Json::Value create; - create["code"] = bytecode; - create["gas"] = "180000"; // TODO or change global default of 90000? - - string deployHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value deployReceipt = fixture.rpcClient->eth_getTransactionReceipt( deployHash ); - string contractAddress = deployReceipt["contractAddress"].asString(); - - // generate 10 blocks 10 logs each - - Json::Value t; - t["from"] = toJS( fixture.coinbase.address() ); - t["value"] = jsToDecimal( "0" ); - t["to"] = contractAddress; - t["gas"] = "999000"; - - for ( int i = 0; i < 11; ++i ) { - std::string txHash = fixture.rpcClient->eth_sendTransaction( t ); - BOOST_REQUIRE( !txHash.empty() ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE_EQUAL( receipt["status"], "0x1" ); - } - - // ask for logs - Json::Value req; - req["fromBlock"] = 1; - req["toBlock"] = 11; - req["topics"] = Json::Value( Json::arrayValue ); - - // 1 10 blocks - BOOST_REQUIRE_NO_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs( req ) ); - - // 2 with topics - req["address"] = contractAddress; - BOOST_REQUIRE_NO_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs( req ) ); - - // 3 11 blocks - req["toBlock"] = 12; - BOOST_CHECK_EXCEPTION( - ( fixture.rpcClient->eth_getLogs( req ) ), - jsonrpc::JsonRpcException, - []( const jsonrpc::JsonRpcException& ex ) { - return ex.GetCode() == -32005 && std::string( ex.GetMessage() ).find( "Block range limit exceeded" ) != - std::string::npos; - } ); - - // 4 filter - string filterId = fixture.rpcClient->eth_newFilter( req ); - - BOOST_REQUIRE_NO_THROW( Json::Value res = fixture.rpcClient->eth_getFilterChanges( filterId ) ); - - req["toBlock"] = 2; - filterId = fixture.rpcClient->eth_newFilter( req ); - BOOST_REQUIRE_NO_THROW( Json::Value res = fixture.rpcClient->eth_getFilterLogs( filterId ) ); - BOOST_REQUIRE_NO_THROW( - Json::Value res2 = fixture.rpcClient->eth_getFilterChanges( filterId ) ); - - req["toBlock"] = 50; - filterId = fixture.rpcClient->eth_newFilter( req ); - BOOST_CHECK_EXCEPTION( - ( fixture.rpcClient->eth_getFilterLogs( filterId ) ), - jsonrpc::JsonRpcException, - []( const jsonrpc::JsonRpcException& ex ) { - std::cout << ex.GetCode() << " " << ex.GetMessage() << std::endl; - return ex.GetCode() == -32005 && std::string( ex.GetMessage() ).find( "Block range limit exceeded" ) != - std::string::npos; - } ); -} - -BOOST_AUTO_TEST_CASE( getResponseLogCountLimit ) { - JsonRpcFixture fixture( - "", true, true, false, false, false, -1, { { "getResponseLogCountLimit", "201" } } ); - - dev::eth::simulateMining( *( fixture.client ), 1 ); - -#ifndef FAIR - sleep( 10 ); - Json::Value txRefill; - txRefill["to"] = "0xc868AF52a6549c773082A334E5AE232e0Ea3B513"; - txRefill["from"] = toJS( fixture.coinbase.address() ); - txRefill["gas"] = "100000"; - txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txRefill["value"] = 100000000000000000; - string txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#endif - - string bytecode = - "6080604052348015600e575f80fd5b5060c080601a5f395ff3fe60806040525f5b6064811015604f577f907787" - "67414a5c844b9d35a8745f67697ee3b8c2c3f4feafe5d9a3e234a5a3654382604051603d9291906067565b6040" - "5180910390a18060010190506006565b005b5f819050919050565b6061816051565b82525050565b5f60408201" - "905060785f830185605a565b60836020830184605a565b939250505056fea264697066735822122040208e35f2" - "706dd92c17579466ab671c308efec51f558a755ea2cf81105ab22964736f6c63430008190033"; - - Json::Value create; - create["code"] = bytecode; - create["gas"] = "180000"; - string deployHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - Json::Value deployReceipt = fixture.rpcClient->eth_getTransactionReceipt( deployHash ); - string contractAddress = deployReceipt["contractAddress"].asString(); - - Json::Value callTx; - callTx["from"] = toJS( fixture.coinbase.address() ); - callTx["to"] = contractAddress; - callTx["gas"] = "999000"; - - for ( int i = 0; i < 5; ++i ) { - string h = fixture.rpcClient->eth_sendTransaction( callTx ); - BOOST_REQUIRE( !h.empty() ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - } - - Json::Value req; - req["fromBlock"] = 1; - req["topics"] = Json::Value( Json::arrayValue ); - req["address"] = contractAddress; - - req["toBlock"] = 4; - BOOST_REQUIRE_NO_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs( req ) ); - - string overHash = fixture.rpcClient->eth_sendTransaction( callTx ); - BOOST_REQUIRE( !overHash.empty() ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - req["toBlock"] = fixture.client->number(); - BOOST_CHECK_EXCEPTION( - ( fixture.rpcClient->eth_getLogs( req ) ), - jsonrpc::JsonRpcException, - []( const jsonrpc::JsonRpcException& ex ) { - return ex.GetCode() == -32005 && std::string( ex.GetMessage() ).find( "Response log count limit exceeded" ) != - std::string::npos; - } ); -} - -// test blockHash parameter -BOOST_AUTO_TEST_CASE( getLogs_blockHash ) { - JsonRpcFixture fixture; - dev::eth::simulateMining( *( fixture.client ), 1 ); - - string latestHash = - fixture.rpcClient->eth_getBlockByNumber( "latest", false )["hash"].asString(); - - Json::Value req; - req["blockHash"] = "xyz"; - BOOST_REQUIRE_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs( req ), std::exception ); - - req["blockHash"] = Json::Value( Json::arrayValue ); - BOOST_REQUIRE_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs( req ), std::exception ); - - req["fromBlock"] = 1; - req["toBlock"] = 1; - BOOST_REQUIRE_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs( req ), std::exception ); - - req["blockHash"] = latestHash; - BOOST_REQUIRE_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs( req ), std::exception ); - - req.removeMember( "fromBlock" ); - req.removeMember( "toBlock" ); - BOOST_REQUIRE_NO_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs( req ) ); - - req["blockHash"] = "0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b"; - BOOST_REQUIRE_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs( req ), std::exception ); - - req["blockHash"] = ""; - BOOST_REQUIRE_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs( req ), std::exception ); -} - -BOOST_AUTO_TEST_CASE( estimate_gas_low_gas_txn ) { - JsonRpcFixture fixture; - dev::eth::simulateMining( *( fixture.client ), 10 ); - - auto senderAddress = fixture.coinbase.address(); - - /* - // SPDX-License-Identifier: None - pragma solidity ^0.6.0; - - contract TestEstimateGas { - uint256[256] number; - uint256 counter = 0; - - function store(uint256 x) public { - number[counter] = x; - counter += 1; - } - - function clear(uint256 pos) public { - number[pos] = 0; - } - } - */ - - string bytecode = - "608060405260006101005534801561001657600080fd5b50610104806100266000396000f3fe60806040523480" - "15600f57600080fd5b506004361060325760003560e01c80636057361d146037578063c0fe1af8146062575b60" - "0080fd5b606060048036036020811015604b57600080fd5b8101908080359060200190929190505050608d565b" - "005b608b60048036036020811015607657600080fd5b810190808035906020019092919050505060b8565b005b" - "806000610100546101008110609e57fe5b018190555060016101006000828254019250508190555050565b6000" - "8082610100811060c657fe5b01819055505056fea26469706673582212206c8da972693a5b8c9bf59c197c4a0c" - "554e9f51abd20047572c9c19125b533d2964736f6c634300060c0033"; - - Json::Value create; - create["code"] = bytecode; - create["gas"] = "180000"; // TODO or change global default of 90000? - - string deployHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value deployReceipt = fixture.rpcClient->eth_getTransactionReceipt( deployHash ); - string contractAddress = deployReceipt["contractAddress"].asString(); - - Json::Value txStore1; // call store(1) - txStore1["to"] = contractAddress; - txStore1["data"] = "0x6057361d0000000000000000000000000000000000000000000000000000000000000001"; - txStore1["from"] = toJS( senderAddress ); - txStore1["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - fixture.rpcClient->eth_sendTransaction( txStore1 ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value estimateGasCall; // call clear(0) - estimateGasCall["to"] = contractAddress; - estimateGasCall["data"] = - "0xc0fe1af80000000000000000000000000000000000000000000000000000000000000000"; - estimateGasCall["from"] = toJS( senderAddress ); - estimateGasCall["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - string estimatedGas = fixture.rpcClient->eth_estimateGas( estimateGasCall ); - - dev::bytes data = dev::jsToBytes( estimateGasCall["data"].asString() ); - BOOST_REQUIRE( - dev::jsToU256( estimatedGas ) > - dev::eth::TransactionBase::baseGasRequired( false, &data, - fixture.client->chainParams().makeEvmSchedule( - fixture.client->latestBlock().info().timestamp(), fixture.client->number() ) ) ); - - // try to send with this gas - estimateGasCall["gas"] = toJS( jsToInt( estimatedGas ) ); - string clearHash = fixture.rpcClient->eth_sendTransaction( estimateGasCall ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - Json::Value clearReceipt = fixture.rpcClient->eth_getTransactionReceipt( clearHash ); - BOOST_REQUIRE_EQUAL( clearReceipt["status"], "0x1" ); - BOOST_REQUIRE_LT( jsToInt( clearReceipt["gasUsed"].asString() ), 21000 ); - - // try to lower gas - estimateGasCall["gas"] = toJS( jsToInt( estimatedGas ) - 1 ); - clearHash = fixture.rpcClient->eth_sendTransaction( estimateGasCall ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - clearReceipt = fixture.rpcClient->eth_getTransactionReceipt( clearHash ); - BOOST_REQUIRE_EQUAL( clearReceipt["status"], "0x0" ); - BOOST_REQUIRE_GT( jsToInt( clearReceipt["gasUsed"].asString() ), 21000 ); -} - -BOOST_AUTO_TEST_CASE( storage_limit_contract ) { - JsonRpcFixture fixture; - dev::eth::simulateMining( *( fixture.client ), 10 ); - - // pragma solidity 0.4.25; - - // contract TestStorageLimit { - - // uint[] public storageArray; - - // function store(uint256 num) public { - // storageArray.push( num ); - // } - - // function erase(uint256 index) public { - // delete storageArray[index]; - // } - - // function foo() public view { - // uint len = storageArray.length; - // storageArray.push(1); - // } - - // function storeAndCall(uint256 num) public { - // storageArray.push( num ); - // foo(); - // } - - // function zero(uint256 index) public { - // storageArray[index] = 0; - // } - - // function strangeFunction(uint256 index) public { - // storageArray[index] = 1; - // storageArray[index] = 0; - // storageArray[index] = 2; - // } - // } - - std::string bytecode = - "0x608060405234801561001057600080fd5b5061034f806100206000396000f300608060405260043610610083" - "576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630e" - "031ab1146100885780631007f753146100c95780636057361d146100f6578063c298557814610123578063c67c" - "d8841461013a578063d269ad4e14610167578063e0353e5914610194575b600080fd5b34801561009457600080" - "fd5b506100b3600480360381019080803590602001909291905050506101c1565b604051808281526020019150" - "5060405180910390f35b3480156100d557600080fd5b506100f460048036038101908080359060200190929190" - "5050506101e4565b005b34801561010257600080fd5b5061012160048036038101908080359060200190929190" - "505050610204565b005b34801561012f57600080fd5b50610138610233565b005b34801561014657600080fd5b" - "506101656004803603810190808035906020019092919050505061026c565b005b34801561017357600080fd5b" - "50610192600480360381019080803590602001909291905050506102a3565b005b3480156101a057600080fd5b" - "506101bf60048036038101908080359060200190929190505050610302565b005b6000818154811015156101d0" - "57fe5b906000526020600020016000915090505481565b6000818154811015156101f357fe5b90600052602060" - "0020016000905550565b6000819080600181540180825580915050906001820390600052602060002001600090" - "91929091909150555050565b600080805490509050600060019080600181540180825580915050906001820390" - "60005260206000200160009091929091909150555050565b600081908060018154018082558091505090600182" - "03906000526020600020016000909192909190915055506102a0610233565b50565b6001600082815481101515" - "6102b457fe5b9060005260206000200181905550600080828154811015156102d257fe5b906000526020600020" - "018190555060026000828154811015156102f157fe5b906000526020600020018190555050565b600080828154" - "8110151561031257fe5b9060005260206000200181905550505600a165627a7a723058201ed095336772c55688" - "864a6b45ca6ab89311c5533f8d38cdf931f1ce38be78080029"; - - auto senderAddress = fixture.coinbase.address(); - - Json::Value create; - create["from"] = toJS( senderAddress ); - create["data"] = bytecode; - create["gas"] = "1800000"; // TODO or change global default of 90000? - string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - string contractAddress = receipt["contractAddress"].asString(); -#ifndef FAIR - dev::Address contract = dev::Address( contractAddress ); -#endif - - Json::Value txCall; // call foo() - txCall["to"] = contractAddress; - txCall["data"] = "0xc2985578"; - txCall["from"] = toJS( senderAddress ); - txCall["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - auto callResult = fixture.rpcClient->eth_call( txCall, "latest" ); -#ifndef FAIR - BOOST_REQUIRE( - fixture.client->state().createReadOnlySnapBasedCopy().storageUsed( contract ) == 0 ); -#endif - BOOST_REQUIRE_EQUAL( callResult, std::string( "0x" ) ); - - Json::Value txPushValueAndCall; // call storeAndCall(1) - txPushValueAndCall["to"] = contractAddress; - txPushValueAndCall["data"] = - "0xc67cd8840000000000000000000000000000000000000000000000000000000000000001"; - txPushValueAndCall["from"] = toJS( senderAddress ); - txPushValueAndCall["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txPushValueAndCall["gas"] = "200000"; - txHash = fixture.rpcClient->eth_sendTransaction( txPushValueAndCall ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#ifndef FAIR - BOOST_REQUIRE( - fixture.client->state().createReadOnlySnapBasedCopy().storageUsed( contract ) == 96 ); -#endif - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); - - Json::Value txPushValue; // call store(2) - txPushValue["to"] = contractAddress; - txPushValue["data"] = - "0x6057361d0000000000000000000000000000000000000000000000000000000000000002"; - txPushValue["from"] = toJS( senderAddress ); - txPushValue["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txPushValue["gas"] = "200000"; - txHash = fixture.rpcClient->eth_sendTransaction( txPushValue ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#ifndef FAIR - BOOST_REQUIRE( - fixture.client->state().createReadOnlySnapBasedCopy().storageUsed( contract ) == 128 ); -#endif - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); - - Json::Value txThrow; // trying to call store(3) - txThrow["to"] = contractAddress; - txThrow["data"] = "0x6057361d0000000000000000000000000000000000000000000000000000000000000003"; - txThrow["from"] = toJS( senderAddress ); - txThrow["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txThrow["gas"] = "200000"; - txHash = fixture.rpcClient->eth_sendTransaction( txThrow ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#ifndef FAIR - BOOST_REQUIRE( - fixture.client->state().createReadOnlySnapBasedCopy().storageUsed( contract ) == 128 ); - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x0" ); -#else - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); -#endif - - Json::Value txEraseValue; // call erase(2) - txEraseValue["to"] = contractAddress; - txEraseValue["data"] = - "0x1007f7530000000000000000000000000000000000000000000000000000000000000002"; - txEraseValue["from"] = toJS( senderAddress ); - txEraseValue["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txEraseValue["gas"] = "200000"; - txHash = fixture.rpcClient->eth_sendTransaction( txEraseValue ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#ifndef FAIR - BOOST_REQUIRE( - fixture.client->state().createReadOnlySnapBasedCopy().storageUsed( contract ) == 96 ); -#endif - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); - - - Json::Value txZeroValue; // call zero(1) - txZeroValue["to"] = contractAddress; - txZeroValue["data"] = - "0xe0353e590000000000000000000000000000000000000000000000000000000000000001"; - txZeroValue["from"] = toJS( senderAddress ); - txZeroValue["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txZeroValue["gas"] = "200000"; - txHash = fixture.rpcClient->eth_sendTransaction( txZeroValue ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#ifndef FAIR - BOOST_REQUIRE( - fixture.client->state().createReadOnlySnapBasedCopy().storageUsed( contract ) == 64 ); -#endif - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); - - Json::Value txZeroValue1; // call zero(1) - txZeroValue1["to"] = contractAddress; - txZeroValue1["data"] = - "0xe0353e590000000000000000000000000000000000000000000000000000000000000001"; - txZeroValue1["from"] = toJS( senderAddress ); - txZeroValue1["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txZeroValue1["gas"] = "200000"; - txHash = fixture.rpcClient->eth_sendTransaction( txZeroValue1 ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#ifndef FAIR - BOOST_REQUIRE( - fixture.client->state().createReadOnlySnapBasedCopy().storageUsed( contract ) == 64 ); -#endif - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); - - Json::Value txValueChanged; // call strangeFunction(1) - txValueChanged["to"] = contractAddress; - txValueChanged["data"] = - "0xd269ad4e0000000000000000000000000000000000000000000000000000000000000001"; - txValueChanged["from"] = toJS( senderAddress ); - txValueChanged["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txValueChanged["gas"] = "200000"; - txHash = fixture.rpcClient->eth_sendTransaction( txValueChanged ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#ifndef FAIR - BOOST_REQUIRE( - fixture.client->state().createReadOnlySnapBasedCopy().storageUsed( contract ) == 96 ); -#endif - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); - - Json::Value txValueChanged1; // call strangeFunction(0) - txValueChanged1["to"] = contractAddress; - txValueChanged1["data"] = - "0xd269ad4e0000000000000000000000000000000000000000000000000000000000000000"; - txValueChanged1["from"] = toJS( senderAddress ); - txValueChanged1["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txValueChanged1["gas"] = "200000"; - txHash = fixture.rpcClient->eth_sendTransaction( txValueChanged1 ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#ifndef FAIR - BOOST_REQUIRE( - fixture.client->state().createReadOnlySnapBasedCopy().storageUsed( contract ) == 96 ); -#endif - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); - - Json::Value txValueChanged2; // call strangeFunction(2) - txValueChanged2["to"] = contractAddress; - txValueChanged2["data"] = - "0xd269ad4e0000000000000000000000000000000000000000000000000000000000000002"; - txValueChanged2["from"] = toJS( senderAddress ); - txValueChanged2["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txValueChanged2["gas"] = "200000"; - txHash = fixture.rpcClient->eth_sendTransaction( txValueChanged2 ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#ifndef FAIR - BOOST_REQUIRE( - fixture.client->state().createReadOnlySnapBasedCopy().storageUsed( contract ) == 128 ); -#endif - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); - - Json::Value txValueChanged3; // try call strangeFunction(3) - txValueChanged3["to"] = contractAddress; - txValueChanged3["data"] = - "0xd269ad4e0000000000000000000000000000000000000000000000000000000000000003"; - txValueChanged3["from"] = toJS( senderAddress ); - txValueChanged3["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txValueChanged3["gas"] = "200000"; - txHash = fixture.rpcClient->eth_sendTransaction( txValueChanged3 ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#ifndef FAIR - BOOST_REQUIRE( - fixture.client->state().createReadOnlySnapBasedCopy().storageUsed( contract ) == 128 ); - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x0" ); -#else - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); -#endif -} - -BOOST_AUTO_TEST_CASE( storage_limit_chain ) { - JsonRpcFixture fixture; - dev::eth::simulateMining( *( fixture.client ), 20 ); - // pragma solidity >=0.4.22 <0.7.0; - - // contract TestStorage1 { - - // uint[] array; - - // function store(uint256 num) public { - // array.push( num + 2 ); - // } - - // function erase(uint idx) public { - // delete array[idx]; - // } - // } - std::string bytecode1 = - "608060405234801561001057600080fd5b5061012c806100206000396000f3fe6080604052348015600f576000" - "80fd5b5060043610604f576000357c010000000000000000000000000000000000000000000000000000000090" - "0480631007f7531460545780636057361d14607f575b600080fd5b607d60048036036020811015606857600080" - "fd5b810190808035906020019092919050505060aa565b005b60a860048036036020811015609357600080fd5b" - "810190808035906020019092919050505060c7565b005b6000818154811060b657fe5b90600052602060002001" - "6000905550565b6000600282019080600181540180825580915050600190039060005260206000200160009091" - "9091909150555056fea264697066735822122055c65b9e093cdb44864dac3fb79ec15a542db86c2f897b938043" - "d8e15468ca4464736f6c63430006060033"; - - auto senderAddress = fixture.coinbase.address(); - - Json::Value create1; - create1["from"] = toJS( senderAddress ); - create1["data"] = bytecode1; - create1["gas"] = "1800000"; - string txHash = fixture.rpcClient->eth_sendTransaction( create1 ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt1 = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - string contractAddress1 = receipt1["contractAddress"].asString(); - - // pragma solidity >=0.4.22 <0.7.0; - - // contract TestStorage2 { - - // uint[] array; - - // function store(uint256 num) public { - // array.push( num ); - // } - - // function erase(uint idx) public { - // delete array[idx]; - // } - // } - Json::Value txStore; // call store(1) - txStore["to"] = contractAddress1; - txStore["data"] = "0x6057361d0000000000000000000000000000000000000000000000000000000000000001"; - txStore["from"] = toJS( senderAddress ); - txStore["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txHash = fixture.rpcClient->eth_sendTransaction( txStore ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#ifndef FAIR - BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == 64 ); -#endif - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); - - // call store(2) - txStore["to"] = contractAddress1; - txStore["data"] = "0x6057361d0000000000000000000000000000000000000000000000000000000000000002"; - txStore["from"] = toJS( senderAddress ); - txStore["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txHash = fixture.rpcClient->eth_sendTransaction( txStore ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#ifndef FAIR - BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == 96 ); -#endif - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); - - Json::Value txErase; // call erase(1) - txErase["to"] = contractAddress1; - txErase["data"] = "0x1007f7530000000000000000000000000000000000000000000000000000000000000001"; - txErase["from"] = toJS( senderAddress ); - txErase["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txHash = fixture.rpcClient->eth_sendTransaction( txErase ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#ifndef FAIR - BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == 64 ); -#endif - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); - - // pragma solidity >=0.4.22 <0.7.0; - - // contract TestStorage2 { - - // uint[] array; - - // function store(uint256 num) public { - // array.push( num ); - // } - - // function erase(uint idx) public { - // delete array[idx]; - // } - // } - std::string bytecode2 = - "608060405234801561001057600080fd5b50610129806100206000396000f3fe6080604052348015600f576000" - "80fd5b5060043610604f576000357c010000000000000000000000000000000000000000000000000000000090" - "0480631007f7531460545780636057361d14607f575b600080fd5b607d60048036036020811015606857600080" - "fd5b810190808035906020019092919050505060aa565b005b60a860048036036020811015609357600080fd5b" - "810190808035906020019092919050505060c7565b005b6000818154811060b657fe5b90600052602060002001" - "6000905550565b6000819080600181540180825580915050600190039060005260206000200160009091909190" - "9150555056fea26469706673582212202bfb5f6fb63ae4f1c9a362ed3f7de7aa5514029db925efa368e711e35d" - "9ebc0a64736f6c63430006060033"; - - Json::Value create2; - create2["from"] = toJS( senderAddress ); - create2["data"] = bytecode2; - create2["gas"] = "1800000"; - txHash = fixture.rpcClient->eth_sendTransaction( create2 ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt2 = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - string contractAddress2 = receipt2["contractAddress"].asString(); - - Json::Value txStoreSecondContract; // call store(1) - txStoreSecondContract["to"] = contractAddress2; - txStoreSecondContract["data"] = - "0x6057361d0000000000000000000000000000000000000000000000000000000000000001"; - txStoreSecondContract["from"] = toJS( senderAddress ); - txStoreSecondContract["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txHash = fixture.rpcClient->eth_sendTransaction( txStoreSecondContract ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#ifndef FAIR - BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == 128 ); -#endif - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); - - // try call store(2) to second contract - txStoreSecondContract["to"] = contractAddress2; - txStoreSecondContract["data"] = - "0x6057361d0000000000000000000000000000000000000000000000000000000000000002"; - txStoreSecondContract["from"] = toJS( senderAddress ); - txStoreSecondContract["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txHash = fixture.rpcClient->eth_sendTransaction( txStoreSecondContract ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#ifndef FAIR - BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == 128 ); - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x0" ); -#else - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); -#endif - - // try call store(3) to first contract - txStore["to"] = contractAddress1; - txStore["data"] = "0x6057361d0000000000000000000000000000000000000000000000000000000000000001"; - txStore["from"] = toJS( senderAddress ); - txStore["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txHash = fixture.rpcClient->eth_sendTransaction( txStore ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#ifndef FAIR - BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == 128 ); - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x0" ); -#else - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); -#endif - - Json::Value txZeroValue; // call zero(1) - txZeroValue["to"] = contractAddress1; - txZeroValue["data"] = - "0x1007f7530000000000000000000000000000000000000000000000000000000000000000"; - txZeroValue["from"] = toJS( senderAddress ); - txZeroValue["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txHash = fixture.rpcClient->eth_sendTransaction( txZeroValue ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#ifndef FAIR - BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == 96 ); -#endif - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); -} - -BOOST_AUTO_TEST_CASE( storage_limit_predeployed ) { - JsonRpcFixture fixture( c_genesisConfigString ); - dev::eth::simulateMining( *( fixture.client ), 20 ); -#ifndef FAIR - BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == 64 ); -#endif - - string contractAddress = "0xC2002000000000000000000000000000000000C2"; - string senderAddress = toJS( fixture.coinbase.address() ); - - Json::Value txChangeInt; - txChangeInt["to"] = contractAddress; - txChangeInt["data"] = - "0xcd16ecbf0000000000000000000000000000000000000000000000000000000000000002"; - txChangeInt["from"] = senderAddress; - txChangeInt["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - string txHash = fixture.rpcClient->eth_sendTransaction( txChangeInt ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#ifndef FAIR - BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == 64 ); -#endif - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); - - Json::Value txZeroValue; - txZeroValue["to"] = contractAddress; - txZeroValue["data"] = - "0xcd16ecbf0000000000000000000000000000000000000000000000000000000000000000"; - txZeroValue["from"] = senderAddress; - txZeroValue["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txHash = fixture.rpcClient->eth_sendTransaction( txZeroValue ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#ifndef FAIR - BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == 32 ); -#endif - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); - - Json::Value txChangeInt1; - txChangeInt["to"] = contractAddress; - txChangeInt["data"] = - "0x9b0631040000000000000000000000000000000000000000000000000000000000000001"; - txChangeInt["from"] = senderAddress; - txChangeInt["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txHash = fixture.rpcClient->eth_sendTransaction( txChangeInt ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#ifndef FAIR - BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == 64 ); -#endif - BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); -} - -BOOST_AUTO_TEST_CASE( storage_limit_reverted ) { - JsonRpcFixture fixture; - dev::eth::simulateMining( *( fixture.client ), 1000 ); - // pragma solidity >=0.7.0 <0.9.0; - - // contract Storage { - - // uint256[10] number; - - // /** - // * @dev Store value in variable - // * @param num value to store - // */ - // function store(uint256 num, uint256 pos) public { - // number[pos] = num; - // } - // } - std::string bytecode1 = - "0x608060405234801561001057600080fd5b50610134806100206000396000f3fe6080604052348015600f5760" - "0080fd5b506004361060285760003560e01c80636ed28ed014602d575b600080fd5b6043600480360381019060" - "3f91906096565b6045565b005b81600082600a8110605757605660cf565b5b01819055505050565b600080fd5b" - "6000819050919050565b6076816065565b8114608057600080fd5b50565b600081359050609081606f565b9291" - "5050565b6000806040838503121560aa5760a96060565b5b600060b6858286016083565b925050602060c58582" - "86016083565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000" - "00000000600052603260045260246000fdfea2646970667358221220ec8739ad7fc74a76053c683510b3c836d0" - "1c7eda3687d89e65380260a97e741b64736f6c63430008120033"; - auto senderAddress = fixture.coinbase.address(); - - Json::Value create1; - create1["from"] = toJS( senderAddress ); - create1["data"] = bytecode1; - create1["gas"] = "1800000"; - string txHash = fixture.rpcClient->eth_sendTransaction( create1 ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt1 = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( receipt1["status"] == string( "0x1" ) ); - string contractAddress1 = receipt1["contractAddress"].asString(); - - // contract CallTry { - - // bool success; - // uint256 count; - // address storageAddress; - - // event Message(string mes); - - // constructor(address newAddress) { - // storageAddress = newAddress; - // } - - // function storeTry() public { - // count = 1; - // success = true; - // try Storage(storageAddress).store(10, 10) { - // emit Message("true"); - // } catch Error(string memory reason) { - // emit Message(reason); - // } catch Panic(uint errorCode) { - // emit Message(string(abi.encodePacked(errorCode))); - // } catch (bytes memory revertData) { - // emit Message(string(revertData)); - // }contractAddress1 - // count = 0; - // success = false; - // } - // } - - std::string bytecode2 = - "608060405234801561001057600080fd5b506040516106f93803806106f9833981810160405281019061003291" - "906100dc565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373" - "ffffffffffffffffffffffffffffffffffffffff16021790555050610109565b600080fd5b600073ffffffffff" - "ffffffffffffffffffffffffffffff82169050919050565b60006100a98261007e565b9050919050565b6100b9" - "8161009e565b81146100c457600080fd5b50565b6000815190506100d6816100b0565b92915050565b60006020" - "82840312156100f2576100f1610079565b5b6000610100848285016100c7565b91505092915050565b6105e180" - "6101186000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c1" - "8829ca14610030575b600080fd5b61003861003a565b005b6001808190555060016000806101000a81548160ff" - "021916908315150217905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffff" - "ff1673ffffffffffffffffffffffffffffffffffffffff16636ed28ed0600a806040518363ffffffff1660e01b" - "81526004016100b99291906102de565b600060405180830381600087803b1580156100d357600080fd5b505af1" - "9250505080156100e4575060015b610235576100f0610314565b806308c379a00361014c57506101046103b156" - "5b8061010f57506101c5565b7f51a7f65c6325882f237d4aeb43228179cfad48b868511d508e24b4437a819137" - "8160405161013e91906104c0565b60405180910390a150610230565b634e487b71036101c55761015e6104e256" - "5b9061016957506101c5565b7f51a7f65c6325882f237d4aeb43228179cfad48b868511d508e24b4437a819137" - "8160405160200161019b9190610524565b6040516020818303038152906040526040516101b791906104c0565b" - "60405180910390a150610230565b3d80600081146101f1576040519150601f19603f3d011682016040523d8252" - "3d6000602084013e6101f6565b606091505b507f51a7f65c6325882f237d4aeb43228179cfad48b868511d508e" - "24b4437a8191378160405161022691906104c0565b60405180910390a1505b61026b565b7f51a7f65c6325882f" - "237d4aeb43228179cfad48b868511d508e24b4437a8191376040516102629061058b565b60405180910390a15b" - "600060018190555060008060006101000a81548160ff021916908315150217905550565b600081905091905056" - "5b6000819050919050565b6000819050919050565b60006102c86102c36102be8461028f565b6102a3565b6102" - "99565b9050919050565b6102d8816102ad565b82525050565b60006040820190506102f360008301856102cf56" - "5b61030060208301846102cf565b9392505050565b60008160e01c9050919050565b600060033d111561033357" - "60046000803e610330600051610307565b90505b90565b6000604051905090565b6000601f19601f8301169050" - "919050565b7f4e487b710000000000000000000000000000000000000000000000000000000060005260416004" - "5260246000fd5b61038982610340565b810181811067ffffffffffffffff821117156103a8576103a761035156" - "5b5b80604052505050565b600060443d1061043e576103c3610336565b60043d036004823e80513d6024820111" - "67ffffffffffffffff821117156103eb57505061043e565b808201805167ffffffffffffffff81111561040957" - "5050505061043e565b80602083010160043d03850181111561042657505050505061043e565b61043582602001" - "850186610380565b82955050505050505b90565b600081519050919050565b6000828252602082019050929150" - "50565b60005b8381101561047b578082015181840152602081019050610460565b60008484015250505050565b" - "600061049282610441565b61049c818561044c565b93506104ac81856020860161045d565b6104b58161034056" - "5b840191505092915050565b600060208201905081810360008301526104da8184610487565b90509291505056" - "5b60008060233d11156104ff576020600460003e6001915060005190505b9091565b6000819050919050565b61" - "051e61051982610299565b610503565b82525050565b6000610530828461050d565b6020820191508190509291" - "5050565b7f7472756500000000000000000000000000000000000000000000000000000000600082015250565b" - "600061057560048361044c565b91506105808261053f565b602082019050919050565b60006020820190508181" - "0360008301526105a481610568565b905091905056fea26469706673582212201a522ad11a321603efd182e33e" - "10b59f65b8c9a8b84c8ec3d832ff1d0b726cc564736f6c63430008120033" + - std::string( "000000000000000000000000" ) + contractAddress1.substr( 2 ); - Json::Value create2; - create2["from"] = toJS( senderAddress ); - create2["data"] = bytecode2; - create2["gas"] = "1800000"; - txHash = fixture.rpcClient->eth_sendTransaction( create2 ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt2 = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( receipt2["status"] == string( "0x1" ) ); - string contractAddress2 = receipt2["contractAddress"].asString(); - -#ifndef FAIR - auto storageUsed = fixture.client->state().storageUsedTotal(); -#endif - - Json::Value txStoreTry; - txStoreTry["to"] = contractAddress2; - txStoreTry["data"] = "0xc18829ca"; - txStoreTry["from"] = senderAddress.hex(); - txStoreTry["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txHash = fixture.rpcClient->eth_sendTransaction( txStoreTry ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); -#ifndef FAIR - BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == storageUsed ); -#endif - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( receipt["gasUsed"] != "0x0" ); - BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); -} - -BOOST_AUTO_TEST_CASE( setSchainExitTime ) { - JsonRpcFixture fixture; - Json::Value requestJson; - requestJson["finishTime"] = 100; - BOOST_REQUIRE_THROW( - fixture.rpcClient->setSchainExitTime( requestJson ), jsonrpc::JsonRpcException ); -} - -#ifndef FAIR -/* -BOOST_AUTO_TEST_CASE( oracle, *boost::unit_test::disabled() ) { - - JsonRpcFixture fixture; - std::string receipt; - std::string result; - std::time_t current = std::time(nullptr); - std::string request; - for (int i = 0; i < 1000000; ++i) { - request = -skutils::tools::format("{\"cid\":1,\"uri\":\"http://worldtimeapi.org/api/timezone/Europe/Kiev\",\"jsps\":[\"/unixtime\",\"/day_of_year\",\"/xxx\"],\"trims\":[1,1,1],\"time\":%zu000,\"pow\":%zu}", -current, i); auto os = make_shared(request); if ( os->verifyPow() ) { break; - } - } - uint64_t status = fixture.client->submitOracleRequest(request, receipt); - - BOOST_REQUIRE_EQUAL(status, 0); - BOOST_CHECK(receipt != ""); - - sleep(5); - - uint64_t resultStatus = fixture.client->checkOracleResult(receipt, result); - BOOST_REQUIRE_EQUAL(resultStatus, 0); - BOOST_CHECK(result != ""); - - - -}*/ -#endif - -BOOST_AUTO_TEST_CASE( doDbCompactionDebugCall ) { - JsonRpcFixture fixture; - - fixture.rpcClient->debug_doStateDbCompaction(); - - fixture.rpcClient->debug_doBlocksDbCompaction(); -} - -BOOST_AUTO_TEST_CASE( debugGetPatchTimestamps ) { - Json::Value configJson; - Json::Reader().parse( c_genesisConfigString, configJson ); - - // indexed by enum int value - std::vector< size_t > patchTimestamps; - - // Set custom config file & create timestamps for each patch - size_t numPatches = static_cast< size_t >( SchainPatchEnum::PatchesCount ); - for ( size_t patch = 0; patch < numPatches; patch++ ) { - SchainPatchEnum patchEnum = static_cast< SchainPatchEnum >( patch ); - size_t ts = patch + 1000; // just to offset from the default values (0, 1) - patchTimestamps.push_back( ts ); - - std::string patchName = getPatchNameForEnum( patchEnum ) + "Timestamp"; - patchName[0] = tolower( patchName[0] ); - configJson["skaleConfig"]["sChain"][patchName] = ts; - } - - Json::FastWriter fastWriter; - std::string customConfigFile = fastWriter.write( configJson ); - - JsonRpcFixture fixture( customConfigFile, false, false, false, false ); - Json::Value returnedPatchTimestamps = fixture.rpcClient->debug_getPatchTimestamps(); - - // compare returned timestamps to actual timestamps - for ( size_t patchIdx = 0; patchIdx < numPatches; patchIdx++ ) { - SchainPatchEnum patchEnum = static_cast< SchainPatchEnum >( patchIdx ); - - std::string patchName = getPatchNameForEnum( patchEnum ) + "Timestamp"; - patchName[0] = tolower( patchName[0] ); - size_t returnedTimestamp = - static_cast< size_t >( returnedPatchTimestamps[patchName].asInt() ); - - BOOST_REQUIRE_EQUAL( returnedTimestamp, patchTimestamps[patchIdx] ); - } -} - -#ifndef FAIR -BOOST_AUTO_TEST_CASE( powTxnGasLimit ) { - Json::Value configJson; - Json::Reader().parse( c_genesisConfigString, configJson ); - configJson["skaleConfig"]["sChain"]["powCheckPatchTimestamp"] = 1; - Json::FastWriter fastWriter; - std::string customConfigFile = fastWriter.write( configJson ); - JsonRpcFixture fixture( customConfigFile, false, false, true, false ); - - // mine blocks without transactions - dev::eth::simulateMining( *( fixture.client ), 2000000 ); - - string senderAddress = toJS( fixture.coinbase.address() ); - - Json::Value txPOW1; - txPOW1["to"] = "0x0000000000000000000000000000000000000033"; - txPOW1["from"] = senderAddress; - txPOW1["gas"] = "100000"; - txPOW1["gasPrice"] = - "0xa449dcaf2bca14e6bd0ac650eed9555008363002b2fc3a4c8422b7a9525a8135"; // gas 200k - txPOW1["value"] = 1; - string txHash = fixture.rpcClient->eth_sendTransaction( txPOW1 ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt1 = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( receipt1["status"] == string( "0x1" ) ); - - Json::Value txPOW2; - txPOW2["to"] = "0x0000000000000000000000000000000000000033"; - txPOW2["from"] = senderAddress; - txPOW2["gas"] = "100000"; - txPOW2["gasPrice"] = - "0xc5002ab03e1e7e196b3d0ffa9801e783fcd48d4c6d972f1389ab63f4e2d0bef0"; // gas 1m - txPOW2["value"] = 100; - - BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendTransaction( txPOW2 ), - jsonrpc::JsonRpcException ); // block gas limit reached -} -#endif - -BOOST_AUTO_TEST_CASE( EIP1898Calls ) { - JsonRpcFixture fixture; - - Json::Value eip1898WellFormed; - eip1898WellFormed["blockHash"] = dev::h256::random().hex(); - eip1898WellFormed["requireCanonical"] = true; - - Json::Value eip1898WellFormed1; - eip1898WellFormed1["blockHash"] = dev::h256::random().hex(); - - Json::Value eip1898WellFormed2; - eip1898WellFormed2["blockHash"] = dev::h256::random().hex(); - eip1898WellFormed2["requireCanonical"] = false; - - Json::Value eip1898WellFormed3; - eip1898WellFormed3["blockNumber"] = dev::h256::random().hex(); - - Json::Value eip1898BadFormed; - eip1898BadFormed["blockHashxxx"] = dev::h256::random().hex(); - eip1898BadFormed["requireCanonical"] = false; - - Json::Value eip1898BadFormed1; - eip1898BadFormed1["blockHash"] = dev::h256::random().hex(); - eip1898BadFormed1["requireCanonical"] = false; - eip1898BadFormed1["smth"] = 1; - - Json::Value eip1898BadFormed2; - eip1898BadFormed2["blockHash"] = 228; - - Json::Value eip1898BadFormed3; - eip1898BadFormed3["blockHash"] = dev::h256::random().hex(); - eip1898BadFormed3["requireCanonical"] = 228; - - Json::Value eip1898BadFormed4; - eip1898BadFormed4["blockNumber"] = dev::h256::random().hex(); - eip1898BadFormed4["requireCanonical"] = true; - - Json::Value eip1898BadFormed5; - eip1898BadFormed5["blockNumber"] = dev::h256::random().hex(); - eip1898BadFormed5["requireCanonical"] = 228; - - - std::array< Json::Value, 4 > wellFormedCalls = { eip1898WellFormed, eip1898WellFormed1, - eip1898WellFormed2, eip1898WellFormed3 }; - std::array< Json::Value, 6 > badFormedCalls = { eip1898BadFormed, eip1898BadFormed1, - eip1898BadFormed2, eip1898BadFormed3, eip1898BadFormed4, eip1898BadFormed5 }; - - - auto address = fixture.coinbase.address(); - - std::string response; - for ( const auto& call : wellFormedCalls ) { - BOOST_REQUIRE_NO_THROW( fixture.rpcClient->eth_getBalanceEIP1898( toJS( address ), call ) ); - } - - for ( const auto& call : badFormedCalls ) { - BOOST_REQUIRE_THROW( fixture.rpcClient->eth_getBalanceEIP1898( toJS( address ), call ), - jsonrpc::JsonRpcException ); - } - - - for ( const auto& call : wellFormedCalls ) { - Json::Value transactionCallObject; - transactionCallObject["to"] = "0x0000000000000000000000000000000000000005"; - transactionCallObject["data"] = "0x0000000000000000000000000000000000000005"; - BOOST_REQUIRE_NO_THROW( fixture.rpcClient->eth_callEIP1898( transactionCallObject, call ) ); - } - - for ( const auto& call : badFormedCalls ) { - Json::Value transactionCallObject; - transactionCallObject["to"] = "0x0000000000000000000000000000000000000005"; - transactionCallObject["data"] = "0x0000000000000000000000000000000000000005"; - BOOST_REQUIRE_THROW( fixture.rpcClient->eth_callEIP1898( transactionCallObject, call ), - jsonrpc::JsonRpcException ); - } - - for ( const auto& call : wellFormedCalls ) { - BOOST_REQUIRE_NO_THROW( fixture.rpcClient->eth_getCodeEIP1898( toJS( address ), call ) ); - } - - for ( const auto& call : badFormedCalls ) { - BOOST_REQUIRE_THROW( fixture.rpcClient->eth_getCodeEIP1898( toJS( address ), call ), - jsonrpc::JsonRpcException ); - } - - for ( const auto& call : wellFormedCalls ) { - BOOST_REQUIRE_NO_THROW( - fixture.rpcClient->eth_getStorageAtEIP1898( toJS( address ), toJS( address ), call ) ); - } - - for ( const auto& call : badFormedCalls ) { - BOOST_REQUIRE_THROW( - fixture.rpcClient->eth_getStorageAtEIP1898( toJS( address ), toJS( address ), call ), - jsonrpc::JsonRpcException ); - } - - for ( const auto& call : wellFormedCalls ) { - BOOST_REQUIRE_NO_THROW( - fixture.rpcClient->eth_getTransactionCountEIP1898( toJS( address ), call ) ); - } - - for ( const auto& call : badFormedCalls ) { - BOOST_REQUIRE_THROW( - fixture.rpcClient->eth_getTransactionCountEIP1898( toJS( address ), call ), - jsonrpc::JsonRpcException ); - } -} - -BOOST_AUTO_TEST_CASE( eip2930Transactions ) { - std::string _config = c_genesisConfigString; - Json::Value ret; - Json::Reader().parse( _config, ret ); - - // Set chainID = 151 - std::string chainID = "0x97"; - ret["params"]["chainID"] = chainID; - time_t eip1559PatchActivationTimestamp = time( nullptr ) + 10; - ret["skaleConfig"]["sChain"]["EIP1559TransactionsPatchTimestamp"] = - eip1559PatchActivationTimestamp; - - - Json::FastWriter fastWriter; - std::string config = fastWriter.write( ret ); - JsonRpcFixture fixture( config ); - - dev::eth::simulateMining( *( fixture.client ), 20 ); - string senderAddress = toJS( fixture.coinbase.address() ); - - Json::Value txRefill; - txRefill["to"] = "0xc868AF52a6549c773082A334E5AE232e0Ea3B513"; - txRefill["from"] = senderAddress; - txRefill["gas"] = "100000"; - txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txRefill["value"] = 100000000000000000; - string txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); - BOOST_REQUIRE( receipt["type"] == "0x0" ); - - auto result = fixture.rpcClient->eth_getTransactionByHash( txHash ); - BOOST_REQUIRE( result["type"] == "0x0" ); - BOOST_REQUIRE( !result.isMember( "yParity" ) ); - BOOST_REQUIRE( !result.isMember( "accessList" ) ); - - BOOST_REQUIRE( fixture.rpcClient->eth_getBalance( "0xc868AF52a6549c773082A334E5AE232e0Ea3B513", - "latest" ) == "0x16345785d8a0000" ); - -#ifndef FAIR - // try sending type1 txn before patchTimestmap - BOOST_REQUIRE_THROW( - fixture.rpcClient->eth_sendRawTransaction( - "0x01f8678197808504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b0180c001a01e" - "bdc546c8b85511b7ba831f47c4981069d7af972d10b7dce2c57225cb5df6a7a055ae1e84fea41d37589eb7" - "40a0a93017a5cd0e9f10ee50f165bf4b1b4c78ddae" ), - jsonrpc::JsonRpcException ); // INVALID_PARAMS - sleep( 10 ); -#endif - - // force 1 block to update timestamp - txRefill["to"] = "0xc868AF52a6549c773082A334E5AE232e0Ea3B513"; - txRefill["from"] = senderAddress; - txRefill["gas"] = "100000"; - txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txRefill["value"] = 0; - txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); - BOOST_REQUIRE( receipt["type"] == "0x0" ); - - // send 1 WEI from 0xc868AF52a6549c773082A334E5AE232e0Ea3B513 to - // 0x7D36aF85A184E220A656525fcBb9A63B9ab3C12b encoded type 1 txn - txHash = fixture.rpcClient->eth_sendRawTransaction( - "0x01f8678197808504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b0180c001a01ebdc5" - "46c8b85511b7ba831f47c4981069d7af972d10b7dce2c57225cb5df6a7a055ae1e84fea41d37589eb740a0a930" - "17a5cd0e9f10ee50f165bf4b1b4c78ddae" ); - auto pendingTransactions = fixture.rpcClient->eth_pendingTransactions(); - BOOST_REQUIRE( pendingTransactions.isArray() && pendingTransactions.size() == 1 ); - BOOST_REQUIRE( pendingTransactions[0]["type"] == "0x1" ); - BOOST_REQUIRE( pendingTransactions[0].isMember( "yParity" ) && - pendingTransactions[0].isMember( "accessList" ) ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - // compare with txn hash from geth - BOOST_REQUIRE( txHash == "0xc843560015a655b8f81f65a458be9019bdb5cd8e416b6329ca18f36de0b8244d" ); - - BOOST_REQUIRE( dev::toHexPrefixed( fixture.client->transactions( 4 )[0].toBytes() ) == - "0x01f8678197808504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b0180c" - "001a01ebdc546c8b85511b7ba831f47c4981069d7af972d10b7dce2c57225cb5df6a7a055ae1e84" - "fea41d37589eb740a0a93017a5cd0e9f10ee50f165bf4b1b4c78ddae" ); - - BOOST_REQUIRE( fixture.rpcClient->eth_getBalance( - "0x7D36aF85A184E220A656525fcBb9A63B9ab3C12b", "latest" ) == "0x1" ); - - auto block = fixture.rpcClient->eth_getBlockByNumber( "4", false ); - BOOST_REQUIRE( block["transactions"].size() == 1 ); - BOOST_REQUIRE( block["transactions"][0].asString() == txHash ); - - block = fixture.rpcClient->eth_getBlockByNumber( "4", true ); - BOOST_REQUIRE( block["transactions"].size() == 1 ); - BOOST_REQUIRE( block["transactions"][0]["hash"].asString() == txHash ); - BOOST_REQUIRE( block["transactions"][0]["type"] == "0x1" ); - - BOOST_REQUIRE( block["transactions"][0]["yParity"].asString() == - block["transactions"][0]["v"].asString() ); - - BOOST_REQUIRE( block["transactions"][0]["accessList"].isArray() ); - BOOST_REQUIRE( block["transactions"][0]["accessList"].size() == 0 ); - BOOST_REQUIRE( block["transactions"][0].isMember( "chainId" ) ); - BOOST_REQUIRE( block["transactions"][0]["chainId"].asString() == chainID ); - - std::string blockHash = block["hash"].asString(); - BOOST_REQUIRE( - fixture.client->transactionHashes( dev::h256( blockHash ) )[0] == - dev::h256( "0xc843560015a655b8f81f65a458be9019bdb5cd8e416b6329ca18f36de0b8244d" ) ); - - receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); - BOOST_REQUIRE( receipt["type"] == "0x1" ); - BOOST_REQUIRE( receipt["effectiveGasPrice"] == "0x4a817c800" ); - - result = fixture.rpcClient->eth_getTransactionByHash( txHash ); - BOOST_REQUIRE( result["hash"].asString() == txHash ); - BOOST_REQUIRE( result["type"] == "0x1" ); - - BOOST_REQUIRE( result["yParity"].asString() == result["v"].asString() ); - - BOOST_REQUIRE( result["accessList"].isArray() ); - BOOST_REQUIRE( result["accessList"].size() == 0 ); - - result = fixture.rpcClient->eth_getTransactionByBlockHashAndIndex( blockHash, "0x0" ); - BOOST_REQUIRE( result["hash"].asString() == txHash ); - BOOST_REQUIRE( result["type"] == "0x1" ); - BOOST_REQUIRE( result["yParity"].asString() == result["v"].asString() ); - BOOST_REQUIRE( result["accessList"].isArray() ); - - result = fixture.rpcClient->eth_getTransactionByBlockNumberAndIndex( "0x4", "0x0" ); - BOOST_REQUIRE( result["hash"].asString() == txHash ); - BOOST_REQUIRE( result["type"] == "0x1" ); - - BOOST_REQUIRE( result["yParity"].asString() == result["v"].asString() ); - - BOOST_REQUIRE( result["accessList"].isArray() ); - BOOST_REQUIRE( result["accessList"].size() == 0 ); - - // now the same txn with accessList and increased nonce - // [ { 'address': HexBytes( "0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae" ), 'storageKeys': ( - // "0x0000000000000000000000000000000000000000000000000000000000000003", - // "0x0000000000000000000000000000000000000000000000000000000000000007" ) } ] - txHash = fixture.rpcClient->eth_sendRawTransaction( - "0x01f8c38197018504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b0180f85bf85994de" - "0b295669a9fd93d5f28d9ec85e40f4cb697baef842a00000000000000000000000000000000000000000000000" - "000000000000000003a0000000000000000000000000000000000000000000000000000000000000000780a0b0" - "3eaf481958e22fc39bd1d526eb9255be1e6625614f02ca939e51c3d7e64bcaa05f675640c04bb050d27bd1f39c" - "07b6ff742311b04dab760bb3bc206054332879" ); - pendingTransactions = fixture.rpcClient->eth_pendingTransactions(); - BOOST_REQUIRE( pendingTransactions.isArray() && pendingTransactions.size() == 1 ); - BOOST_REQUIRE( pendingTransactions[0]["type"] == "0x1" ); - BOOST_REQUIRE( pendingTransactions[0].isMember( "yParity" ) && - pendingTransactions[0].isMember( "accessList" ) ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - // compare with txn hash from geth - BOOST_REQUIRE( txHash == "0xa6d3541e06dff71fb8344a4db2a4ad4e0b45024eb23a8f568982b70a5f50f94d" ); - BOOST_REQUIRE( - dev::toHexPrefixed( fixture.client->transactions( 5 )[0].toBytes() ) == - "0x01f8c38197018504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b0180f85bf85994de" - "0b295669a9fd93d5f28d9ec85e40f4cb697baef842a00000000000000000000000000000000000000000000000" - "000000000000000003a0000000000000000000000000000000000000000000000000000000000000000780a0b0" - "3eaf481958e22fc39bd1d526eb9255be1e6625614f02ca939e51c3d7e64bcaa05f675640c04bb050d27bd1f39c" - "07b6ff742311b04dab760bb3bc206054332879" ); - - result = fixture.rpcClient->eth_getTransactionByHash( txHash ); - BOOST_REQUIRE( result["type"] == "0x1" ); - BOOST_REQUIRE( result["accessList"].isArray() ); - BOOST_REQUIRE( result["accessList"].size() == 1 ); - BOOST_REQUIRE( result["accessList"][0].isObject() && - result["accessList"][0].getMemberNames().size() == 2 ); - BOOST_REQUIRE( result["accessList"][0].isMember( "address" ) && - result["accessList"][0].isMember( "storageKeys" ) ); - BOOST_REQUIRE( result["accessList"][0]["address"].asString() == - "0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae" ); - BOOST_REQUIRE( result["accessList"][0]["storageKeys"].isArray() && - result["accessList"][0]["storageKeys"].size() == 2 ); - BOOST_REQUIRE( result["accessList"][0]["storageKeys"][0].asString() == - "0x0000000000000000000000000000000000000000000000000000000000000003" ); - BOOST_REQUIRE( result["accessList"][0]["storageKeys"][1].asString() == - "0x0000000000000000000000000000000000000000000000000000000000000007" ); - - block = fixture.rpcClient->eth_getBlockByNumber( "5", true ); - result = block["transactions"][0]; - BOOST_REQUIRE( result["type"] == "0x1" ); - BOOST_REQUIRE( result["accessList"].isArray() ); - BOOST_REQUIRE( result["accessList"].size() == 1 ); - BOOST_REQUIRE( result["accessList"][0].isObject() && - result["accessList"][0].getMemberNames().size() == 2 ); - BOOST_REQUIRE( result["accessList"][0].isMember( "address" ) && - result["accessList"][0].isMember( "storageKeys" ) ); - BOOST_REQUIRE( result["accessList"][0]["address"].asString() == - "0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae" ); - BOOST_REQUIRE( result["accessList"][0]["storageKeys"].isArray() && - result["accessList"][0]["storageKeys"].size() == 2 ); - BOOST_REQUIRE( result["accessList"][0]["storageKeys"][0].asString() == - "0x0000000000000000000000000000000000000000000000000000000000000003" ); - BOOST_REQUIRE( result["accessList"][0]["storageKeys"][1].asString() == - "0x0000000000000000000000000000000000000000000000000000000000000007" ); -} - -BOOST_AUTO_TEST_CASE( eip1559Transactions ) { - std::string _config = c_genesisConfigString; - Json::Value ret; - Json::Reader().parse( _config, ret ); - - // Set chainID = 151 - std::string chainID = "0x97"; - ret["params"]["chainID"] = chainID; - time_t eip1559PatchActivationTimestamp = time( nullptr ) + 10; - ret["skaleConfig"]["sChain"]["EIP1559TransactionsPatchTimestamp"] = - eip1559PatchActivationTimestamp; - - Json::FastWriter fastWriter; - std::string config = fastWriter.write( ret ); - JsonRpcFixture fixture( config ); - - dev::eth::simulateMining( *( fixture.client ), 20 ); - fixture.client->state().getOriginalDb()->createBlockSnap( 2 ); - string senderAddress = toJS( fixture.coinbase.address() ); - - Json::Value txRefill; - txRefill["to"] = "0x5EdF1e852fdD1B0Bc47C0307EF755C76f4B9c251"; - txRefill["from"] = senderAddress; - txRefill["gas"] = "100000"; - txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txRefill["value"] = 100000000000000000; - string txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - fixture.client->state().getOriginalDb()->createBlockSnap( 3 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); - BOOST_REQUIRE( receipt["type"] == "0x0" ); - - auto result = fixture.rpcClient->eth_getTransactionByHash( txHash ); - BOOST_REQUIRE( result["type"] == "0x0" ); - BOOST_REQUIRE( !result.isMember( "yParity" ) ); - BOOST_REQUIRE( !result.isMember( "accessList" ) ); - - BOOST_REQUIRE( fixture.rpcClient->eth_getBalance( "0x5EdF1e852fdD1B0Bc47C0307EF755C76f4B9c251", - "latest" ) == "0x16345785d8a0000" ); - -#ifndef FAIR - // try sending type2 txn before patchTimestmap - BOOST_REQUIRE_THROW( - fixture.rpcClient->eth_sendRawTransaction( - "0x02f8c98197808504a817c8018504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b" - "0180f85bf85994de0b295669a9fd93d5f28d9ec85e40f4cb697baef842a000000000000000000000000000" - "00000000000000000000000000000000000003a00000000000000000000000000000000000000000000000" - "00000000000000000701a005bd1eedc509a8e94cfcfc84d0b5fd53a0888a475274cbeee321047da5d139f8" - "a00e7f0dd8b5277766d447ea51b7d8f571dc8bb57ff95c068c58f5b6fe9089dde8" ), - jsonrpc::JsonRpcException ); // INVALID_PARAMS - sleep( 10 ); -#endif - - // force 1 block to update timestamp - txRefill["to"] = "0xc868AF52a6549c773082A334E5AE232e0Ea3B513"; - txRefill["from"] = senderAddress; - txRefill["gas"] = "100000"; - txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txRefill["value"] = 0; - txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - fixture.client->state().getOriginalDb()->createBlockSnap( 4 ); - receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); - BOOST_REQUIRE( receipt["type"] == "0x0" ); - BOOST_REQUIRE( receipt["effectiveGasPrice"] == "0x4a817c800" ); - - - // send 1 WEI from 0x5EdF1e852fdD1B0Bc47C0307EF755C76f4B9c251 to - // 0x7D36aF85A184E220A656525fcBb9A63B9ab3C12b encoded type 2 txn - txHash = fixture.rpcClient->eth_sendRawTransaction( - "0x02f8c98197808504a817c8008504a817c801827530947d36af85a184e220a656525fcbb9a63b9ab3c12b018" - "0f85bf85994de0b295669a9fd93d5f28d9ec85e40f4cb697baef842a000000000000000000000000000000000" - "00000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000" - "00000000780a0f000a16aeee9ac96602e8b179d39caca61f347a296e78ec9c57ec06c6e378422a02462cfad48" - "32a32ed8c55fddf8a033d4a73f62fed993de3687ba14902eaea2d4" ); - - auto pendingTransactions = fixture.rpcClient->eth_pendingTransactions(); - BOOST_REQUIRE( pendingTransactions.isArray() && pendingTransactions.size() == 1 ); - BOOST_REQUIRE( pendingTransactions[0]["type"] == "0x2" ); - BOOST_REQUIRE( pendingTransactions[0].isMember( "yParity" ) && - pendingTransactions[0].isMember( "accessList" ) ); - BOOST_REQUIRE( pendingTransactions[0].isMember( "maxFeePerGas" ) && - pendingTransactions[0].isMember( "maxPriorityFeePerGas" ) ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - // compare with txn hash from geth - BOOST_REQUIRE( txHash == "0xd9463624627c7add3b3ac18a228569b3a9075cc05bec64db060ea8904f3c4288" ); - BOOST_REQUIRE( - dev::toHexPrefixed( fixture.client->transactions( 4 )[0].toBytes() ) == - "0x02f8c98197808504a817c8008504a817c801827530947d36af85a184e220a656525fcbb9a63b9ab3c12b018" - "0f85bf85994de0b295669a9fd93d5f28d9ec85e40f4cb697baef842a000000000000000000000000000000000" - "00000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000" - "00000000780a0f000a16aeee9ac96602e8b179d39caca61f347a296e78ec9c57ec06c6e378422a02462cfad48" - "32a32ed8c55fddf8a033d4a73f62fed993de3687ba14902eaea2d4" ); - - BOOST_REQUIRE( fixture.rpcClient->eth_getBalance( - "0x7D36aF85A184E220A656525fcBb9A63B9ab3C12b", "latest" ) == "0x1" ); - - auto block = fixture.rpcClient->eth_getBlockByNumber( "4", false ); - BOOST_REQUIRE( block["transactions"].size() == 1 ); - BOOST_REQUIRE( block["transactions"][0].asString() == txHash ); - - block = fixture.rpcClient->eth_getBlockByNumber( "4", true ); - BOOST_REQUIRE( !block["baseFeePerGas"].asString().empty() ); - BOOST_REQUIRE( block["transactions"].size() == 1 ); - BOOST_REQUIRE( block["transactions"][0]["hash"].asString() == txHash ); - BOOST_REQUIRE( block["transactions"][0]["type"] == "0x2" ); - - BOOST_REQUIRE( block["transactions"][0]["yParity"].asString() == - block["transactions"][0]["v"].asString() ); - - BOOST_REQUIRE( block["transactions"][0]["accessList"].isArray() ); - BOOST_REQUIRE( block["transactions"][0].isMember( "chainId" ) ); - BOOST_REQUIRE( block["transactions"][0]["chainId"].asString() == chainID ); - - std::string blockHash = block["hash"].asString(); - - receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); - BOOST_REQUIRE( receipt["type"] == "0x2" ); - BOOST_REQUIRE( receipt["effectiveGasPrice"] == "0x4a817c801" ); - - result = fixture.rpcClient->eth_getTransactionByHash( txHash ); - BOOST_REQUIRE( result["hash"].asString() == txHash ); - BOOST_REQUIRE( result["type"] == "0x2" ); - - BOOST_REQUIRE( result["yParity"].asString() == result["v"].asString() ); - - BOOST_REQUIRE( result["accessList"].isArray() ); - BOOST_REQUIRE( - result.isMember( "maxPriorityFeePerGas" ) && result["maxPriorityFeePerGas"].isString() ); - BOOST_REQUIRE( result.isMember( "maxFeePerGas" ) && result["maxFeePerGas"].isString() ); - BOOST_REQUIRE( result["maxPriorityFeePerGas"] == "0x4a817c800" ); - BOOST_REQUIRE( result["maxFeePerGas"] == "0x4a817c801" ); - - result = fixture.rpcClient->eth_getTransactionByBlockHashAndIndex( blockHash, "0x0" ); - BOOST_REQUIRE( result["hash"].asString() == txHash ); - BOOST_REQUIRE( result["type"] == "0x2" ); - - BOOST_REQUIRE( result["yParity"].asString() == result["v"].asString() ); - - BOOST_REQUIRE( result["accessList"].isArray() ); - BOOST_REQUIRE( result["maxPriorityFeePerGas"] == "0x4a817c800" ); - BOOST_REQUIRE( result["maxFeePerGas"] == "0x4a817c801" ); - - result = fixture.rpcClient->eth_getTransactionByBlockNumberAndIndex( "0x4", "0x0" ); - BOOST_REQUIRE( result["hash"].asString() == txHash ); - BOOST_REQUIRE( result["type"] == "0x2" ); - - BOOST_REQUIRE( result["yParity"].asString() == result["v"].asString() ); - - BOOST_REQUIRE( result["accessList"].isArray() ); - BOOST_REQUIRE( result["maxPriorityFeePerGas"] == "0x4a817c800" ); - BOOST_REQUIRE( result["maxFeePerGas"] == "0x4a817c801" ); - - BOOST_REQUIRE_NO_THROW( fixture.rpcClient->eth_getBlockByNumber( "0x0", false ) ); -} - -BOOST_AUTO_TEST_CASE( eip2930RpcMethods ) { - std::string _config = c_genesisConfigString; - Json::Value ret; - Json::Reader().parse( _config, ret ); - - // Set chainID = 151 - ret["params"]["chainID"] = "0x97"; - - Json::FastWriter fastWriter; - std::string config = fastWriter.write( ret ); - JsonRpcFixture fixture( config ); - - dev::eth::simulateMining( *( fixture.client ), 20 ); - string senderAddress = toJS( fixture.coinbase.address() ); - - Json::Value txRefill; - txRefill["to"] = "0x5EdF1e852fdD1B0Bc47C0307EF755C76f4B9c251"; - txRefill["from"] = senderAddress; - txRefill["gas"] = "100000"; - txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txRefill["value"] = 1000000; - string txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); - BOOST_REQUIRE( receipt["type"] == "0x0" ); - - auto accessList = fixture.rpcClient->eth_createAccessList( txRefill, "latest" ); - BOOST_REQUIRE( accessList.isMember( "accessList" ) && accessList.isMember( "gasUsed" ) ); - BOOST_REQUIRE( accessList["accessList"].isArray() && accessList["accessList"].size() == 0 ); - BOOST_REQUIRE( accessList["gasUsed"].isString() ); -} - -BOOST_AUTO_TEST_CASE( eip1559RpcMethods ) { - std::string _config = c_genesisConfigString; - Json::Value ret; - Json::Reader().parse( _config, ret ); - - // Set chainID = 151 - ret["params"]["chainID"] = "0x97"; - time_t eip1559PatchActivationTimestamp = time( nullptr ) + 5; - ret["skaleConfig"]["sChain"]["EIP1559TransactionsPatchTimestamp"] = - eip1559PatchActivationTimestamp; - - Json::FastWriter fastWriter; - std::string config = fastWriter.write( ret ); - JsonRpcFixture fixture( config ); - - dev::eth::simulateMining( *( fixture.client ), 20 ); - string senderAddress = toJS( fixture.coinbase.address() ); - - Json::Value txRefill; - txRefill["to"] = "0x5EdF1e852fdD1B0Bc47C0307EF755C76f4B9c251"; - txRefill["from"] = senderAddress; - txRefill["gas"] = "100000"; - txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txRefill["value"] = 100000000000000000; - for ( size_t i = 0; i < 10; ++i ) { - // mine 10 blocks - string txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - } - - BOOST_REQUIRE( fixture.rpcClient->eth_maxPriorityFeePerGas() == "0x0" ); - - auto bn = fixture.client->number(); - - Json::Value percentiles = Json::Value( Json::arrayValue ); - percentiles.resize( 2 ); - percentiles[0] = 20; - percentiles[1] = 80; - - size_t blockCnt = 9; - auto feeHistory = fixture.rpcClient->eth_feeHistory( toJS( blockCnt ), "latest", percentiles ); - - BOOST_REQUIRE( feeHistory["oldestBlock"] == toJS( bn - blockCnt + 1 ) ); - - BOOST_REQUIRE( feeHistory.isMember( "baseFeePerGas" ) ); - BOOST_REQUIRE( feeHistory["baseFeePerGas"].isArray() ); - - for ( Json::Value::ArrayIndex i = 0; i < blockCnt; ++i ) { - BOOST_REQUIRE( feeHistory["baseFeePerGas"][i].isString() ); - std::string estimatedBaseFeePerGas = - EIP1559TransactionsPatch::isEnabledWhen( - fixture.client->blockInfo( bn - i - 1 ).timestamp() ) ? - toJS( fixture.client->gasBidPrice( bn - i - 1 ) ) : - toJS( 0 ); - BOOST_REQUIRE( feeHistory["baseFeePerGas"][i].asString() == estimatedBaseFeePerGas ); - BOOST_REQUIRE_GT( feeHistory["gasUsedRatio"][i].asDouble(), 0 ); - BOOST_REQUIRE_GT( 1, feeHistory["gasUsedRatio"][i].asDouble() ); - for ( Json::Value::ArrayIndex j = 0; j < percentiles.size(); ++j ) { - BOOST_REQUIRE_EQUAL( feeHistory["reward"][i][j].asString(), toJS( 0 ) ); - } - } - - Json::Value floatPercentiles = Json::Value( Json::arrayValue ); - floatPercentiles.resize( 2 ); - floatPercentiles[0] = 20.5; - floatPercentiles[1] = 80.0; - - auto feeHistoryWithFloatPercentiles = - fixture.rpcClient->eth_feeHistory( toJS( blockCnt ), "latest", floatPercentiles ); - BOOST_REQUIRE( feeHistoryWithFloatPercentiles.isMember( "reward" ) ); - BOOST_REQUIRE( feeHistoryWithFloatPercentiles["reward"].isArray() ); - for ( Json::Value::ArrayIndex i = 0; i < blockCnt; ++i ) { - BOOST_REQUIRE( feeHistoryWithFloatPercentiles["reward"][i].isArray() ); - BOOST_REQUIRE_EQUAL( - feeHistoryWithFloatPercentiles["reward"][i].size(), floatPercentiles.size() ); - } - - BOOST_REQUIRE_NO_THROW( fixture.rpcClient->eth_feeHistory( blockCnt, "latest", percentiles ) ); -} - -BOOST_AUTO_TEST_CASE( vInTxnSignature ) { - std::string _config = c_genesisConfigString; - Json::Value ret; - Json::Reader().parse( _config, ret ); - - // Set chainID = 151 - ret["params"]["chainID"] = "0x97"; - time_t eip1559PatchActivationTimestamp = time( nullptr ); - ret["skaleConfig"]["sChain"]["EIP1559TransactionsPatchTimestamp"] = - eip1559PatchActivationTimestamp; - - Json::FastWriter fastWriter; - std::string config = fastWriter.write( ret ); - JsonRpcFixture fixture( config ); - - dev::eth::simulateMining( *( fixture.client ), 20 ); - string senderAddress = toJS( fixture.coinbase.address() ); - - Json::Value txRefill; - txRefill["to"] = "0x5EdF1e852fdD1B0Bc47C0307EF755C76f4B9c251"; - txRefill["from"] = senderAddress; - txRefill["gas"] = "100000"; - txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txRefill["value"] = 100000000000000000; - string txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - // send non replay protected txn - txHash = fixture.rpcClient->eth_sendRawTransaction( - "0xf864808504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b01801ba0171c7f31feaa0f" - "d7825a5a28d7b535d0b0ee200b27792f66eb7796e7a6a555d7a0081790244f21cefa563b55a7a68ee78f846673" - "8b5827be19faaeff0586fd71be" ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value txn = fixture.rpcClient->eth_getTransactionByHash( txHash ); - dev::u256 v = dev::jsToU256( txn["v"].asString() ); - BOOST_REQUIRE( v < 29 && v > 26 ); - - // send replay protected legacy txn - txHash = fixture.rpcClient->eth_sendRawTransaction( - "0xf866018504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b0180820151a018b400fc56" - "bc3568e4f23f6f93d538745a5b18054252d6030791c294c9aea9d4a00930492125784fad0a8b38b915e8621f54" - "c53f0878a77f21920c751ec5fd220a" ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - txn = fixture.rpcClient->eth_getTransactionByHash( txHash ); - v = dev::jsToU256( txn["v"].asString() ); - BOOST_REQUIRE( v < 339 && v > 336 ); // 2 * 151 + 35 - - // send type1 txn - txHash = fixture.rpcClient->eth_sendRawTransaction( - "0x01f8c38197028504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b0180f85bf85994de" - "0b295669a9fd93d5f28d9ec85e40f4cb697baef842a00000000000000000000000000000000000000000000000" - "000000000000000003a0000000000000000000000000000000000000000000000000000000000000000701a0ee" - "608b7c5df843b4a1988a3e9c24d53019fa674e06a6b2ae0c347a00601c1a84a06ed451f9cc0f4334a180458605" - "ecaa212e58f8436e1a4318e75ae417c72eba2b" ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - txn = fixture.rpcClient->eth_getTransactionByHash( txHash ); - v = dev::jsToU256( txn["v"].asString() ); - BOOST_REQUIRE( v < 2 && v >= 0 ); - - // send type2 txn - txHash = fixture.rpcClient->eth_sendRawTransaction( - "0x02f86d8197038504a817c8008504a817c801827530947d36af85a184e220a656525fcbb9a63b9ab3c12b808" - "0c001a0f399bf6ecf7f7d464d18a36a05475c6464760a111a2039b9be76eadbe185e4b4a0234c828163103039" - "446653ebc8031631ab984e59169be57a759345fe4a1bf127" ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - txn = fixture.rpcClient->eth_getTransactionByHash( txHash ); - v = dev::jsToU256( txn["v"].asString() ); - BOOST_REQUIRE( v < 2 && v >= 0 ); -} - -BOOST_AUTO_TEST_CASE( InvalidTransactionFormatPatch ) { - std::string _config = c_genesisConfigString; - Json::Value ret; - Json::Reader().parse( _config, ret ); - - // Set chainID = 151 - std::string chainID = "0x97"; - ret["params"]["chainID"] = chainID; - time_t eip1559PatchActivationTimestamp = time( nullptr ) - 1; - time_t InvalidTransactionFormatPatchActivationTimestamp = time( nullptr ) + 10; - ret["skaleConfig"]["sChain"]["InvalidTransactionFormatPatchTimestamp"] = - InvalidTransactionFormatPatchActivationTimestamp; - ret["skaleConfig"]["sChain"]["EIP1559TransactionsPatchTimestamp"] = - eip1559PatchActivationTimestamp; - - Json::FastWriter fastWriter; - std::string config = fastWriter.write( ret ); - JsonRpcFixture fixture( config ); - - dev::eth::simulateMining( *( fixture.client ), 20 ); - string senderAddress = toJS( fixture.coinbase.address() ); - - Json::Value txRefill; - txRefill["to"] = "0x5EdF1e852fdD1B0Bc47C0307EF755C76f4B9c251"; - txRefill["from"] = senderAddress; - txRefill["gas"] = "100000"; - txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txRefill["value"] = 1000000000000000000; - string txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); - - -#ifndef FAIR - // send a txn with maxPriorityFeePerGas > maxFeePerGas before InvalidTransactionFormatPatchTimestamp - txHash = fixture.rpcClient->eth_sendRawTransaction( - "0x02f86d8197808504a817c8018504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b8080" - "c001a0db2fe04a66fa54bfe9c6e0166d85a31b34cbff10dbde0e0584081aec6bb33c30a06b956a49c52f1460da" - "9f93fc495eaa863ae5a8c91ee9230c2f3976f5e74d4f47" ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); - - Json::Value tx = fixture.rpcClient->eth_getTransactionByHash( txHash ); - BOOST_REQUIRE( dev::jsToU256( tx["maxFeePerGas"].asString() ) < - dev::jsToU256( tx["maxPriorityFeePerGas"].asString() ) ); - - dev::eth::Transaction t = fixture.client->transaction( dev::h256( txHash ) ); - BOOST_REQUIRE( t.maxFeePerGas() < t.maxPriorityFeePerGas() ); -#endif - - sleep( 10 ); - - // force 1 block to update timestamp - txRefill["to"] = "0xc868AF52a6549c773082A334E5AE232e0Ea3B513"; - txRefill["from"] = senderAddress; - txRefill["gas"] = "100000"; - txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txRefill["value"] = 0; - txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - sleep( 1 ); - - // send a txn with maxPriorityFeePerGas > maxFeePerGas after - // InvalidTransactionFormatPatchTimestamp, it should fail - BOOST_REQUIRE_THROW( - fixture.rpcClient->eth_sendRawTransaction( - "0x02f86d8197018504a817c8018504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b" - "8080c080a0aea5ff86373cbbbb33c9f3e9a25ceb9a694ee71beff452a4d29903d73fd30ca9a00458d4f7d5" - "4be178b42d230cc5a4740540d55b8ca0f9c74c79c1d49f6686b1e6" ), - jsonrpc::JsonRpcException ); // INVALID_PARAMS -} - -BOOST_AUTO_TEST_CASE( jsonrpcVersionInResponseHeader ) { - JsonRpcFixture fixture; - - dev::eth::simulateMining( *( fixture.client ), 20 ); - // pragma solidity >=0.8.2 <0.9.0; - - // /** - // * @title Storage - // * @dev Store & retrieve value in a variable - // * @custom:dev-run-script ./scripts/deploy_with_ethers.ts - // */ - // contract Storage { - - // uint256 number; - // uint256 number1; - // uint256 number2; - - // /** - // * @dev Store value in variable - // * @param num value to store - // */ - // function store(uint256 num) public { - // number = num; - // number1 = num; - // number2 = num; - // } - - // /** - // * @dev Return value - // * @return value of 'number' - // */ - // function retrieve() public view returns (uint256){ - // return number; - // } - // } - std::string bytecode = - "6080604052348015600f57600080fd5b5061015e8061001f6000396000f3fe6080604052348015610010576000" - "80fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd" - "5b610043610075565b60405161005091906100af565b60405180910390f35b610073600480360381019061006e" - "91906100fb565b61007e565b005b60008054905090565b80600081905550806001819055508060028190555050" - "565b6000819050919050565b6100a981610096565b82525050565b60006020820190506100c460008301846100" - "a0565b92915050565b600080fd5b6100d881610096565b81146100e357600080fd5b50565b6000813590506100" - "f5816100cf565b92915050565b600060208284031215610111576101106100ca565b5b600061011f8482850161" - "00e6565b9150509291505056fea264697066735822122081840c9060f8fb10a0bdf054a92c6bd15ea462286507" - "fad9a9fe26e653e2f2e264736f6c634300081a0033"; - auto senderAddress = fixture.coinbase.address(); - - Json::Value create1; - create1["from"] = toJS( senderAddress ); - create1["data"] = bytecode; - create1["gas"] = "1800000"; - string txHash = fixture.rpcClient->eth_sendTransaction( create1 ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); - string contractAddress = receipt["contractAddress"].asString(); - - skutils::rest::client cli( skutils::rest::g_nClientConnectionTimeoutMS ); - std::string url = - std::string( "http://" ) + - fixture.skale_server_connector->opts_.netOpts_.bindOptsStandard_.strAddrHTTP4_ + - std::string( ":" ) + - std::to_string( - fixture.skale_server_connector->opts_.netOpts_.bindOptsStandard_.nBasePortHTTP4_ ); - BOOST_REQUIRE( cli.open( url ) ); - - // try to send bad call to trigger EVM reverted w/o description error - nlohmann::json joIn = nlohmann::json::object(); - joIn["jsonrpc"] = "2.0"; - joIn["method"] = "eth_call"; - nlohmann::json params = nlohmann::json::array(); - nlohmann::json callDetails = nlohmann::json::object(); - callDetails["data"] = - "0x01ffc9a7d9b67a2600000000000000000000000000000000000000000000000000000000"; - callDetails["to"] = contractAddress; - params.push_back( callDetails ); - params.push_back( "latest" ); - joIn["params"] = params; - skutils::rest::data_t d = cli.call( joIn ); - - nlohmann::json joAnswer = nlohmann::json::parse( d.s_ ); - BOOST_REQUIRE( joAnswer.count( "jsonrpc" ) > 0 ); - BOOST_REQUIRE( joAnswer["jsonrpc"] == "2.0" ); - - // try to send legit eth_call as well - joIn = nlohmann::json::object(); - joIn["jsonrpc"] = "2.0"; - joIn["method"] = "eth_call"; - params = nlohmann::json::array(); - callDetails = nlohmann::json::object(); - callDetails["data"] = "0x2e64cec1"; - callDetails["to"] = contractAddress; - callDetails["from"] = senderAddress.hex(); - callDetails["value"] = "0x0"; - params.push_back( callDetails ); - params.push_back( "latest" ); - joIn["params"] = params; - d = cli.call( joIn ); - - joAnswer = nlohmann::json::parse( d.s_ ); - BOOST_REQUIRE( joAnswer.count( "jsonrpc" ) > 0 ); - BOOST_REQUIRE( joAnswer["jsonrpc"] == "2.0" ); -} - -BOOST_AUTO_TEST_CASE( getZeroBlock ) { - JsonRpcFixture fixture; - Json::Value block = fixture.rpcClient->eth_getBlockByNumber( "0", "false" ); - BOOST_REQUIRE( block["number"] == string( "0x0" ) ); - - string blockHash = block["hash"].asString(); - Json::Value blockByHash = fixture.rpcClient->eth_getBlockByHash( blockHash, "false" ); - BOOST_REQUIRE( blockByHash["number"] == string( "0x0" ) ); - BOOST_REQUIRE( blockByHash["hash"] == blockHash ); -} - -BOOST_AUTO_TEST_CASE( getBlockRandom ) { - std::string _config = c_genesisConfigString; - Json::Value ret; - Json::Reader().parse( _config, ret ); - - time_t currentBlockRandomPatchActivationTimestamp = time( nullptr ) + 10; - ret["skaleConfig"]["sChain"]["currentBlockRandomPatchTimestamp"] = - currentBlockRandomPatchActivationTimestamp; - - Json::FastWriter fastWriter; - std::string config = fastWriter.write( ret ); - - JsonRpcFixture fixture( config ); - - dev::eth::simulateMining( *( fixture.client ), 20 ); - string senderAddress = toJS( fixture.coinbase.address() ); - - // create block and save block random for it - Json::Value txRefill; - txRefill["to"] = "0xc868AF52a6549c773082A334E5AE232e0Ea3B513"; - txRefill["from"] = toJS( senderAddress ); - txRefill["gas"] = "100000"; - txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txRefill["value"] = 1; - fixture.rpcClient->eth_sendTransaction( txRefill ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - PrecompiledExecutor blockRandomExecutor = PrecompiledRegistrar::executor( "getBlockRandom" ); - auto blockNumberEarly = fixture.client->number(); - dev::eth::PrecompiledCallContext ctx( blockNumberEarly, - 0, -#ifdef BITE - 0, - dev::h256::random(), - dev::ZeroAddress, -#endif - true ); - auto blockRandomEarly = blockRandomExecutor( dev::bytesConstRef(), ctx ); - - // wait till patch is activated - sleep( 10 ); - fixture.rpcClient->eth_sendTransaction( txRefill ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - -// pragma solidity ^0.8.13; - -// contract GetBlockRandomPrecompiled { -// address public constant PRECOMPILE_0X08 = address(0x08); -// bytes32 lastBlockRandom; - -// function getBlockRandom() public returns (bytes32) { -// (bool success, bytes memory result) = PRECOMPILE_0X08.staticcall(""); -// require(success, "Call to precompile 0x06 failed"); -// require(result.length >= 20, "Invalid result length"); -// lastBlockRandom = bytes32(result); - -// return lastBlockRandom; -// } - -// function getLastBlockRandom() public view returns (bytes32) { -// return lastBlockRandom; -// } -// } - std::string bytecode = "6080604052348015600f57600080fd5b506104548061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80633ec4b2de146100465780635e2e884d14610064578063dc031dfe14610082575b600080fd5b61004e6100a0565b60405161005b91906101fc565b60405180910390f35b61006c6100a5565b6040516100799190610230565b60405180910390f35b61008a6100ae565b6040516100979190610230565b60405180910390f35b600881565b60008054905090565b6000806000600873ffffffffffffffffffffffffffffffffffffffff166040516100d79061027c565b600060405180830381855afa9150503d8060008114610112576040519150601f19603f3d011682016040523d82523d6000602084013e610117565b606091505b50915091508161015c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610153906102ee565b60405180910390fd5b6014815110156101a1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101989061035a565b60405180910390fd5b806101ab906103b7565b6000819055506000549250505090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101e6826101bb565b9050919050565b6101f6816101db565b82525050565b600060208201905061021160008301846101ed565b92915050565b6000819050919050565b61022a81610217565b82525050565b60006020820190506102456000830184610221565b92915050565b600081905092915050565b50565b600061026660008361024b565b915061027182610256565b600082019050919050565b600061028782610259565b9150819050919050565b600082825260208201905092915050565b7f43616c6c20746f20707265636f6d70696c652030783036206661696c65640000600082015250565b60006102d8601e83610291565b91506102e3826102a2565b602082019050919050565b60006020820190508181036000830152610307816102cb565b9050919050565b7f496e76616c696420726573756c74206c656e6774680000000000000000000000600082015250565b6000610344601583610291565b915061034f8261030e565b602082019050919050565b6000602082019050818103600083015261037381610337565b9050919050565b600081519050919050565b6000819050602082019050919050565b60006103a18251610217565b80915050919050565b600082821b905092915050565b60006103c28261037a565b826103cc84610385565b90506103d781610395565b92506020821015610417576104127fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff836020036008026103aa565b831692505b505091905056fea26469706673582212200547f4a1b7b525d8f531c7e991887fdca3437350b86fc09b06a1acaa83b5c3ad64736f6c634300081e0033"; - - // deploy contract - Json::Value create; - create["from"] = toJS( senderAddress ); - create["code"] = bytecode; - create["gas"] = "900000"; - string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - auto txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - std::string contractAddress = txReceipt["contractAddress"].asString(); - - // submit getBlockRandom transaction - Json::Value txGenerate; - txGenerate["to"] = contractAddress; - txGenerate["data"] = "0xdc031dfe"; - txGenerate["from"] = toJS( senderAddress ); - fixture.rpcClient->eth_sendTransaction( txGenerate ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - // read data from contract - Json::Value callGetLast; - callGetLast["to"] = contractAddress; - callGetLast["data"] = "0x5e2e884d"; - callGetLast["from"] = toJS( senderAddress ); - dev::bytes blockRandomFromContract = dev::fromHex( fixture.rpcClient->eth_call( callGetLast, "latest" ) ); - - ctx = PrecompiledCallContext( fixture.client->number(), - 0, -#ifdef BITE - 0, - dev::h256::random(), - dev::ZeroAddress, -#endif - true ); - auto executionResult = blockRandomExecutor( dev::bytesConstRef(), ctx ); - - BOOST_REQUIRE( executionResult.first ); - BOOST_REQUIRE( executionResult.second == blockRandomFromContract ); - -#ifdef HISTORIC_STATE - // produce more blocks, execute historic call and compare results - fixture.rpcClient->eth_sendTransaction( txRefill ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - dev::bytes blockRandomFromHistoricCall = dev::fromHex( fixture.rpcClient->eth_call( callGetLast, toJS( fixture.client->number() - 1 ) ) ); - BOOST_REQUIRE( blockRandomFromHistoricCall == blockRandomFromContract ); - - // ask for blockRandom for early block - ctx = PrecompiledCallContext( blockNumberEarly, - 0, -#ifdef BITE - 0, - dev::h256::random(), - dev::ZeroAddress, -#endif - true ); - auto blockRandomEarlyHistoric = blockRandomExecutor(dev::bytesConstRef(), ctx ); - BOOST_REQUIRE( blockRandomEarlyHistoric.first ); - BOOST_REQUIRE( blockRandomEarlyHistoric.second == blockRandomEarly.second ); -#endif -} - -#ifdef BITE - -#ifndef FAIR -static std::string const c_BITEConfigString = - R"( -{ - "sealEngine": "NoProof", - "params": { - "accountStartNonce": "0x00", - "maximumExtraDataSize": "0x1000000", - "blockReward": "0x4563918244F40000", - "allowFutureBlocks": true, - "homesteadForkBlock": "0x00", - "EIP150ForkBlock": "0x00", - "EIP158ForkBlock": "0x00", - "byzantiumForkBlock": "0x00", - "constantinopleForkBlock": "0x00", - "istanbulForkBlock": "0x00", - "skaleDisableChainIdCheck": true, - "externalGasDifficulty": "0x1", - "minGasLimit": "0xFFFFFFF", - "maxGasLimit": "7fffffffffffffff" - }, - "genesis": { - "author" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", - "difficulty" : "0x20000", - "gasLimit": "0xFFFFFFF", - "nonce" : "0x00", - "extraData" : "0x00", - "timestamp" : "0x00", - "mixHash" : "0x00", - "stateRoot": "0x01" - }, - "skaleConfig": { - "nodeInfo": { - "nodeID": 8, - "nodeName": "test_node", - "bindIP": "0.0.0.0", - "logLevel": "info", - "logLevelConfig": "info", - "imaMessageProxySChain": "0xd2AAa00100000000000000000000000000000000", - "imaMessageProxyMainNet": "0x337591F78cbf2b113A57D9709511a1b6E524DdaE", - "rotateAfterBlock": 10240, - "basePort": )" + - std::to_string( rand_port ) + R"(, - "logLevel": "trace", - "logLevelProposal": "trace", - "ecdsaKeyName": "NEK:d391a1af1cd9663335e0f970e59402bf16fcfe0cc421c535bf60ba618a456d68", - "wallets": { - "ima": { - "keyShareName": "BLS_KEY:SCHAIN_ID:1:NODE_ID:0:DKG_ID:0", - "t": 1, - "n": 1, - "certFile": "/skale-data/node_data/sgx_certs/sgx.crt", - "keyFile": "/skale-data/node_data/sgx_certs/sgx.key", - "commonBLSPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", - "commonBLSPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", - "commonBLSPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", - "commonBLSPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693", - "BLSPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", - "BLSPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", - "BLSPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", - "BLSPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693" - } - } - }, - "sChain": { - "schainName": "TestChain", - "schainID": 1, - "contractStorageLimit": 128, - "emptyBlockIntervalMs": -1, - "ContractCreationReadOnlyPatchTimestamp": 1, - "SingleStateCommitPerBlockPatchTimestamp": 1,)" -#ifdef BITE - R"( "Bite2PatchTimestamp": 1, - "currentBlockRandomPatchTimestamp": 1,)" -#endif - R"( "nodeGroups": { - "0": { - "nodes": { - "8": [ - 1, - 8, - "0xf925c203a30ec6cad5a263db3efab7ed4c1fd74c8688167e10a5a22e15ab5018d8553df0ac54ea105a3d21845e5660bc3d4e7c82e7af1daa3baad393b1521467" - ] - }, - "finish_ts": null, - "bls_public_key": { - "blsPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", - "blsPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", - "blsPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", - "blsPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693" - } - } - }, - "nodes": [ - { - "nodeID": 8, - "nodeName": "test_node", - "basePort": )" + std::to_string( rand_port ) + R"(, - "httpRpcPort": 9568, - "httpsRpcPort": 9573, - "wsRpcPort": 9567, - "wssRpcPort": 9572, - "blsPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", - "blsPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", - "blsPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", - "blsPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693", - "publicKey": "0xf925c203a30ec6cad5a263db3efab7ed4c1fd74c8688167e10a5a22e15ab5018d8553df0ac54ea105a3d21845e5660bc3d4e7c82e7af1daa3baad393b1521467", - "owner": "0x5112ce768917e907191557d7e9521c2590cdd3a0", - "schainIndex": 1, - "ip": "186.14.217.13", - "publicIP": "4.127.224.50" - } - ] - } - }, - "accounts": { - "0000000000000000000000000000000000000001": { "precompiled": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, - "0000000000000000000000000000000000000002": { "precompiled": { "name": "sha256", "linear": { "base": 60, "word": 12 } } }, - "0000000000000000000000000000000000000003": { "precompiled": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } }, - "0000000000000000000000000000000000000004": { "precompiled": { "name": "identity", "linear": { "base": 15, "word": 3 } } }, - "0000000000000000000000000000000000000005": { "precompiled": { "name": "getBlockRandom", "linear": { "base": 15, "word": 0 } } },)" -#ifdef BITE - R"( - "000000000000000000000000000000000000001A": { "precompiled": { "name": "getRandomWalletAndSignatureForCTX", "linear": { "base": 15, "word": 0 } } }, - "000000000000000000000000000000000000001B": { "precompiled": { "name": "submitCTX", "linear": { "base": 15, "word": 0 } } },)" -#endif - /* -pragma solidity ^0.4.25; -contract Caller { -function call() public { -bool status; -string memory fileName = "test"; -address sender = 0x000000000000000000000000000000AA; -assembly{ -let ptr := mload(0x40) -mstore(ptr, sender) -mstore(add(ptr, 0x20), 4) -mstore(add(ptr, 0x40), mload(add(fileName, 0x20))) -mstore(add(ptr, 0x60), 1) -status := call(not(0), 0x05, 0, ptr, 0x80, ptr, 32) -} -} - -function revertCall() public { -call(); -revert(); -} -} -*/ - R"("0x5c4e11842e8be09264dc1976943571d7af6d00f9" : { - "balance" : "1000000000000000000000000000000" - }, - "0x7aa5E36AA15E93D10F4F26357C30F052DacDde5F": { - "balance": "1000000000000000000000000000000" - }, - "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a" : { - "balance" : "0x00", - "code" : "0x6080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806328b5e32b14604e578063f38fb65b146062575b600080fd5b348015605957600080fd5b5060606076565b005b348015606d57600080fd5b50607460ec565b005b6000606060006040805190810160405280600481526020017f7465737400000000000000000000000000000000000000000000000000000000815250915060aa905060405181815260046020820152602083015160408201526001606082015260208160808360006005600019f1935050505050565b60f26076565b600080fd00a165627a7a72305820262a5822c4fe6c154b2ef3198c7827d35fc6da59da2cea2c4f2fad9d4a5ccd5e0029", - "nonce" : "0x00", - "storage" : { - } - }, - "0x095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "0x0de0b6b3a7640000", - "code" : "0x6001600101600055", - "nonce" : "0x00", - "storage" : { - } - }, - "0xC2002000000000000000000000000000000000C2": { - "balance": "0", - "code": "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80639b063104146037578063cd16ecbf146062575b600080fd5b606060048036036020811015604b57600080fd5b8101908080359060200190929190505050608d565b005b608b60048036036020811015607657600080fd5b81019080803590602001909291905050506097565b005b8060018190555050565b806000819055505056fea265627a7a7231582029df540a7555533ef4b3f66bc4f9abe138b00117d1496efbfd9d035a48cd595e64736f6c634300050d0032", - "storage": { - "0x0": "0x01" - }, - "nonce": "0" - }, - "0xD2002000000000000000000000000000000000D2": { - "balance": "0", - "code": "0x608060405234801561001057600080fd5b50600436106100455760003560e01c806313f44d101461005557806338eada1c146100af5780634ba79dfe146100f357610046565b5b6002801461005357600080fd5b005b6100976004803603602081101561006b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610137565b60405180821515815260200191505060405180910390f35b6100f1600480360360208110156100c557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101f4565b005b6101356004803603602081101561010957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061030f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16148061019957506101988261042b565b5b806101ed5750600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b9050919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f43616c6c6572206973206e6f7420746865206f776e657200000000000000000081525060200191505060405180910390fd5b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f43616c6c6572206973206e6f7420746865206f776e657200000000000000000081525060200191505060405180910390fd5b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600080823b90506000811191505091905056fea26469706673582212202aca1f7abb7d02061b58de9b559eabe1607c880fda3932bbdb2b74fa553e537c64736f6c634300060c0033", - "storage": { - "0x0": "0x5C4e11842E8be09264dc1976943571d7Af6d00F9" - }, - "nonce": "0" - }, - "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "0x0de0b6b3a7640000", - "code" : "0x", - "nonce" : "0x00", - "storage" : { - } - }, - "0xD2001300000000000000000000000000000000D4": { - "balance": "0", - "nonce": "0", - "storage": {}, - "code":"0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80632098776714610051578063b8bd717f1461007f578063d37165fa146100ad578063fdde8d66146100db575b600080fd5b61007d6004803603602081101561006757600080fd5b8101908080359060200190929190505050610109565b005b6100ab6004803603602081101561009557600080fd5b8101908080359060200190929190505050610136565b005b6100d9600480360360208110156100c357600080fd5b8101908080359060200190929190505050610170565b005b610107600480360360208110156100f157600080fd5b8101908080359060200190929190505050610191565b005b60005a90505b815a8203101561011e5761010f565b600080fd5b815a8203101561013257610123565b5050565b60005a90505b815a8203101561014b5761013c565b600060011461015957600080fd5b5a90505b815a8203101561016c5761015d565b5050565b60005a9050600081830390505b805a8303101561018c5761017d565b505050565b60005a90505b815a820310156101a657610197565b60016101b157600080fd5b5a90505b815a820310156101c4576101b5565b505056fea264697066735822122089b72532621e7d1849e444ee6efaad4fb8771258e6f79755083dce434e5ac94c64736f6c63430006000033" - } - } -} -)"; -#else -static std::string const c_BITEConfigString = - R"( -{ - "sealEngine": "NoProof", - "params": { - "accountStartNonce": "0x00", - "maximumExtraDataSize": "0x1000000", - "blockReward": "0x4563918244F40000", - "allowFutureBlocks": true, - "homesteadForkBlock": "0x00", - "EIP150ForkBlock": "0x00", - "EIP158ForkBlock": "0x00", - "byzantiumForkBlock": "0x00", - "constantinopleForkBlock": "0x00", - "istanbulForkBlock": "0x00", - "skaleDisableChainIdCheck": true, - "minGasLimit": "0xFFFFFFF", - "maxGasLimit": "7fffffffffffffff" - }, - "genesis": { - "author" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", - "difficulty" : "0x20000", - "gasLimit": "0xFFFFFFF", - "nonce" : "0x00", - "extraData" : "0x00", - "timestamp" : "0x00", - "mixHash" : "0x00", - "stateRoot": "0x01" - }, - "skaleConfig": { - "nodeInfo": { - "nodeID": 8, - "nodeName": "test_node", - "bindIP": "0.0.0.0", - "logLevel": "info", - "logLevelConfig": "info", - "rotateAfterBlock": 10240, - "basePort": )" + - std::to_string( rand_port ) + R"(, - "logLevel": "trace", - "logLevelProposal": "trace", - "ecdsaKeyName": "NEK:d391a1af1cd9663335e0f970e59402bf16fcfe0cc421c535bf60ba618a456d68" - }, - "sChain": { - "schainName": "TestChain", - "schainID": 1, - "emptyBlockIntervalMs": -1, - "ContractCreationReadOnlyPatchTimestamp": 1, - "SingleStateCommitPerBlockPatchTimestamp": 1,)" -#ifdef BITE - R"( "Bite2PatchTimestamp": 1, - "currentBlockRandomPatchTimestamp": 1,)" -#endif - R"( "nodeGroups": { - "0": { - "nodes": { - "8": [ - 1, - 8, - "0xf925c203a30ec6cad5a263db3efab7ed4c1fd74c8688167e10a5a22e15ab5018d8553df0ac54ea105a3d21845e5660bc3d4e7c82e7af1daa3baad393b1521467" - ] - }, - "finish_ts": null, - "bls_public_key": { - "blsPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", - "blsPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", - "blsPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", - "blsPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693" - } - } - }, - "nodes": { - "1": { - "blsKey": { - "keyShareName": "BLS_KEY:SCHAIN_ID:1:NODE_ID:0:DKG_ID:0", - "t": 1, - "n": 1, - "certFile": "/skale-data/node_data/sgx_certs/sgx.crt", - "keyFile": "/skale-data/node_data/sgx_certs/sgx.key", - "commonBLSPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", - "commonBLSPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", - "commonBLSPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", - "commonBLSPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693", - "BLSPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", - "BLSPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", - "BLSPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", - "BLSPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693" - }, - "group": [ - { - "nodeID": 8, - "nodeName": "test_node", - "basePort": )" + std::to_string( rand_port ) + R"(, - "httpRpcPort": 9568, - "httpsRpcPort": 9573, - "wsRpcPort": 9567, - "wssRpcPort": 9572, - "blsPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", - "blsPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", - "blsPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", - "blsPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693", - "publicKey": "0xf925c203a30ec6cad5a263db3efab7ed4c1fd74c8688167e10a5a22e15ab5018d8553df0ac54ea105a3d21845e5660bc3d4e7c82e7af1daa3baad393b1521467", - "owner": "0x5112ce768917e907191557d7e9521c2590cdd3a0", - "schainIndex": 1, - "ip": "186.14.217.13", - "publicIP": "4.127.224.50" - } - ] - }, - "-1": {} - } - } - }, - "accounts": { - "0000000000000000000000000000000000000001": { "precompiled": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, - "0000000000000000000000000000000000000002": { "precompiled": { "name": "sha256", "linear": { "base": 60, "word": 12 } } }, - "0000000000000000000000000000000000000003": { "precompiled": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } }, - "0000000000000000000000000000000000000004": { "precompiled": { "name": "identity", "linear": { "base": 15, "word": 3 } } }, - "0000000000000000000000000000000000000005": { "precompiled": { "name": "getBlockRandom", "linear": { "base": 15, "word": 0 } } },)" -#ifdef BITE - R"( - "0x000000000000000000000000000000000000001A": { "precompiled": { "name": "getRandomWalletAndSignatureForCTX", "linear": { "base": 15, "word": 0 } } }, - "0x000000000000000000000000000000000000001B": { "precompiled": { "name": "submitCTX", "linear": { "base": 15, "word": 0 } } },)" -#endif - /* -pragma solidity ^0.4.25; -contract Caller { -function call() public { -bool status; -string memory fileName = "test"; -address sender = 0x000000000000000000000000000000AA; -assembly{ -let ptr := mload(0x40) -mstore(ptr, sender) -mstore(add(ptr, 0x20), 4) -mstore(add(ptr, 0x40), mload(add(fileName, 0x20))) -mstore(add(ptr, 0x60), 1) -status := call(not(0), 0x05, 0, ptr, 0x80, ptr, 32) -} -} - -function revertCall() public { -call(); -revert(); -} -} -*/ - R"("0x5c4e11842e8be09264dc1976943571d7af6d00f9" : { - "balance" : "1000000000000000000000000000000" - }, - "0x7aa5E36AA15E93D10F4F26357C30F052DacDde5F": { - "balance": "1000000000000000000000000000000" - }, - "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a" : { - "balance" : "0x00", - "code" : "0x6080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806328b5e32b14604e578063f38fb65b146062575b600080fd5b348015605957600080fd5b5060606076565b005b348015606d57600080fd5b50607460ec565b005b6000606060006040805190810160405280600481526020017f7465737400000000000000000000000000000000000000000000000000000000815250915060aa905060405181815260046020820152602083015160408201526001606082015260208160808360006005600019f1935050505050565b60f26076565b600080fd00a165627a7a72305820262a5822c4fe6c154b2ef3198c7827d35fc6da59da2cea2c4f2fad9d4a5ccd5e0029", - "nonce" : "0x00", - "storage" : { - } - }, - "0x095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "0x0de0b6b3a7640000", - "code" : "0x6001600101600055", - "nonce" : "0x00", - "storage" : { - } - }, - "0xC2002000000000000000000000000000000000C2": { - "balance": "0", - "code": "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80639b063104146037578063cd16ecbf146062575b600080fd5b606060048036036020811015604b57600080fd5b8101908080359060200190929190505050608d565b005b608b60048036036020811015607657600080fd5b81019080803590602001909291905050506097565b005b8060018190555050565b806000819055505056fea265627a7a7231582029df540a7555533ef4b3f66bc4f9abe138b00117d1496efbfd9d035a48cd595e64736f6c634300050d0032", - "storage": { - "0x0": "0x01" - }, - "nonce": "0" - }, - "0xD2002000000000000000000000000000000000D2": { - "balance": "0", - "code": "0x608060405234801561001057600080fd5b50600436106100455760003560e01c806313f44d101461005557806338eada1c146100af5780634ba79dfe146100f357610046565b5b6002801461005357600080fd5b005b6100976004803603602081101561006b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610137565b60405180821515815260200191505060405180910390f35b6100f1600480360360208110156100c557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101f4565b005b6101356004803603602081101561010957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061030f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16148061019957506101988261042b565b5b806101ed5750600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b9050919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f43616c6c6572206973206e6f7420746865206f776e657200000000000000000081525060200191505060405180910390fd5b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f43616c6c6572206973206e6f7420746865206f776e657200000000000000000081525060200191505060405180910390fd5b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600080823b90506000811191505091905056fea26469706673582212202aca1f7abb7d02061b58de9b559eabe1607c880fda3932bbdb2b74fa553e537c64736f6c634300060c0033", - "storage": { - }, - "nonce": "0" - }, - "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "0x0de0b6b3a7640000", - "code" : "0x", - "nonce" : "0x00", - "storage" : { - } - }, - "0xD2001300000000000000000000000000000000D4": { - "balance": "0", - "nonce": "0", - "storage": {}, - "code":"0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80632098776714610051578063b8bd717f1461007f578063d37165fa146100ad578063fdde8d66146100db575b600080fd5b61007d6004803603602081101561006757600080fd5b8101908080359060200190929190505050610109565b005b6100ab6004803603602081101561009557600080fd5b8101908080359060200190929190505050610136565b005b6100d9600480360360208110156100c357600080fd5b8101908080359060200190929190505050610170565b005b610107600480360360208110156100f157600080fd5b8101908080359060200190929190505050610191565b005b60005a90505b815a8203101561011e5761010f565b600080fd5b815a8203101561013257610123565b5050565b60005a90505b815a8203101561014b5761013c565b600060011461015957600080fd5b5a90505b815a8203101561016c5761015d565b5050565b60005a9050600081830390505b805a8303101561018c5761017d565b505050565b60005a90505b815a820310156101a657610197565b60016101b157600080fd5b5a90505b815a820310156101c4576101b5565b505056fea264697066735822122089b72532621e7d1849e444ee6efaad4fb8771258e6f79755083dce434e5ac94c64736f6c63430006000033" - } - } -} -)"; - -static std::string const c_BITECommitteeRotationConfigString = - R"( -{ - "sealEngine": "NoProof", - "params": { - "accountStartNonce": "0x00", - "maximumExtraDataSize": "0x1000000", - "blockReward": "0x4563918244F40000", - "allowFutureBlocks": true, - "homesteadForkBlock": "0x00", - "EIP150ForkBlock": "0x00", - "EIP158ForkBlock": "0x00", - "byzantiumForkBlock": "0x00", - "constantinopleForkBlock": "0x00", - "istanbulForkBlock": "0x00", - "skaleDisableChainIdCheck": true, - "externalGasDifficulty": "0x1" - }, - "genesis": { - "author" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", - "difficulty" : "0x20000", - "gasLimit" : "0x0f4240", - "nonce" : "0x00", - "extraData" : "0x00", - "timestamp" : "0x00", - "mixHash" : "0x00", - "stateRoot": "0x01" - }, - "skaleConfig": { - "nodeInfo": { - "nodeID": 8, - "nodeName": "test_node", - "bindIP": "0.0.0.0", - "logLevel": "info", - "logLevelConfig": "info", - "imaMessageProxySChain": "0xd2AAa00100000000000000000000000000000000", - "imaMessageProxyMainNet": "0x337591F78cbf2b113A57D9709511a1b6E524DdaE", - "rotateAfterBlock": 10240, - "basePort": )" + - std::to_string( rand_port ) + R"(, - "logLevel": "trace", - "logLevelProposal": "trace", - "ecdsaKeyName": "NEK:d391a1af1cd9663335e0f970e59402bf16fcfe0cc421c535bf60ba618a456d68" - }, - "sChain": { - "schainName": "TestChain", - "schainID": 1, - "emptyBlockIntervalMs": -1, - "nodeGroups": { - "0": { - "nodes": { - "8": [ - 0, - 8, - "0xf925c203a30ec6cad5a263db3efab7ed4c1fd74c8688167e10a5a22e15ab5018d8553df0ac54ea105a3d21845e5660bc3d4e7c82e7af1daa3baad393b1521467", - "0x08151B8F80bfa7dEa760e461412AF24348224edf" - ] - }, - "finish_ts": 1, - "bls_public_key": { - "blsPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", - "blsPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", - "blsPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", - "blsPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693" - } - }, - "1": { - "nodes": { - "8": [ - 0, - 8, - "0xf925c203a30ec6cad5a263db3efab7ed4c1fd74c8688167e10a5a22e15ab5018d8553df0ac54ea105a3d21845e5660bc3d4e7c82e7af1daa3baad393b1521467", - "0x405c96D388cDFBa4f17493c875CCE9c680225276" - ] - }, - "finish_ts": null, - "bls_public_key": { - "blsPublicKey0": "3842742177969966091367527274107524613106077736353521259727282251005583743182", - "blsPublicKey1": "3497912824016228906558906422247670474553186446469877598411863912329082553081", - "blsPublicKey2": "8173996886448941320370434854289578123609627835954133538412363037981850950343", - "blsPublicKey3": "20979370720689475348670582375026949105497642726992863932315517524004804784155" - } - } - }, - "nodes": { - "1": { - "blsKey": { - "keyShareName": "BLS_KEY:SCHAIN_ID:1:NODE_ID:0:DKG_ID:0", - "t": 1, - "n": 1, - "certFile": "/skale-data/node_data/sgx_certs/sgx.crt", - "keyFile": "/skale-data/node_data/sgx_certs/sgx.key", - "commonBLSPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", - "commonBLSPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", - "commonBLSPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", - "commonBLSPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693", - "BLSPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", - "BLSPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", - "BLSPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", - "BLSPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693" - }, - "stakingContractAddress": "0x5C60C315985977b7a408eBF4256984Acdf949549", - "group": [ - { - "nodeID": 8, - "nodeName": "test_node", - "basePort": )" + std::to_string( rand_port ) + R"(, - "httpRpcPort": 9568, - "httpsRpcPort": 9573, - "wsRpcPort": 9567, - "wssRpcPort": 9572, - "blsPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", - "blsPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", - "blsPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", - "blsPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693", - "publicKey": "0xf925c203a30ec6cad5a263db3efab7ed4c1fd74c8688167e10a5a22e15ab5018d8553df0ac54ea105a3d21845e5660bc3d4e7c82e7af1daa3baad393b1521467", - "owner": "0x5112ce768917e907191557d7e9521c2590cdd3a0", - "schainIndex": 1, - "ip": "186.14.217.13", - "publicIP": "4.127.224.50" - } - ] - }, - "-1": { - "blsKey": { - "keyShareName": "BLS_KEY:SCHAIN_ID:1:NODE_ID:0:DKG_ID:0", - "t": 1, - "n": 1, - "certFile": "/skale-data/node_data/sgx_certs/sgx.crt", - "keyFile": "/skale-data/node_data/sgx_certs/sgx.key", - "commonBLSPublicKey0": "3842742177969966091367527274107524613106077736353521259727282251005583743182", - "commonBLSPublicKey1": "3497912824016228906558906422247670474553186446469877598411863912329082553081", - "commonBLSPublicKey2": "8173996886448941320370434854289578123609627835954133538412363037981850950343", - "commonBLSPublicKey3": "20979370720689475348670582375026949105497642726992863932315517524004804784155", - "BLSPublicKey0": "3842742177969966091367527274107524613106077736353521259727282251005583743182", - "BLSPublicKey1": "3497912824016228906558906422247670474553186446469877598411863912329082553081", - "BLSPublicKey2": "8173996886448941320370434854289578123609627835954133538412363037981850950343", - "BLSPublicKey3": "20979370720689475348670582375026949105497642726992863932315517524004804784155" - }, - "group": [ - { - "nodeID": 8, - "nodeName": "test_node", - "basePort": )" + std::to_string( rand_port ) + R"(, - "httpRpcPort": 9568, - "httpsRpcPort": 9573, - "wsRpcPort": 9567, - "wssRpcPort": 9572, - "blsPublicKey0": "3842742177969966091367527274107524613106077736353521259727282251005583743182", - "blsPublicKey1": "3497912824016228906558906422247670474553186446469877598411863912329082553081", - "blsPublicKey2": "8173996886448941320370434854289578123609627835954133538412363037981850950343", - "blsPublicKey3": "20979370720689475348670582375026949105497642726992863932315517524004804784155", - "publicKey": "0xf925c203a30ec6cad5a263db3efab7ed4c1fd74c8688167e10a5a22e15ab5018d8553df0ac54ea105a3d21845e5660bc3d4e7c82e7af1daa3baad393b1521467", - "owner": "0x5112ce768917e907191557d7e9521c2590cdd3a0", - "schainIndex": 1, - "ip": "186.14.217.13", - "publicIP": "4.127.224.50" - } - ] - } - } - } - }, - "accounts": { - "0000000000000000000000000000000000000001": { "precompiled": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, - "0000000000000000000000000000000000000002": { "precompiled": { "name": "sha256", "linear": { "base": 60, "word": 12 } } }, - "0000000000000000000000000000000000000003": { "precompiled": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } }, - "0000000000000000000000000000000000000004": { "precompiled": { "name": "identity", "linear": { "base": 15, "word": 3 } } },)" - /* -pragma solidity ^0.4.25; -contract Caller { -function call() public { -bool status; -string memory fileName = "test"; -address sender = 0x000000000000000000000000000000AA; -assembly{ -let ptr := mload(0x40) -mstore(ptr, sender) -mstore(add(ptr, 0x20), 4) -mstore(add(ptr, 0x40), mload(add(fileName, 0x20))) -mstore(add(ptr, 0x60), 1) -status := call(not(0), 0x05, 0, ptr, 0x80, ptr, 32) -} -} - -function revertCall() public { -call(); -revert(); -} -} -*/ - R"("0x5c4e11842e8be09264dc1976943571d7af6d00f9" : { - "balance" : "1000000000000000000000000000000" - }, - "0x7aa5E36AA15E93D10F4F26357C30F052DacDde5F": { - "balance": "1000000000000000000000000000000" - }, - "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a" : { - "balance" : "0x00", - "code" : "0x6080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806328b5e32b14604e578063f38fb65b146062575b600080fd5b348015605957600080fd5b5060606076565b005b348015606d57600080fd5b50607460ec565b005b6000606060006040805190810160405280600481526020017f7465737400000000000000000000000000000000000000000000000000000000815250915060aa905060405181815260046020820152602083015160408201526001606082015260208160808360006005600019f1935050505050565b60f26076565b600080fd00a165627a7a72305820262a5822c4fe6c154b2ef3198c7827d35fc6da59da2cea2c4f2fad9d4a5ccd5e0029", - "nonce" : "0x00", - "storage" : { - } - }, - "0x095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "0x0de0b6b3a7640000", - "code" : "0x6001600101600055", - "nonce" : "0x00", - "storage" : { - } - }, - "0xC2002000000000000000000000000000000000C2": { - "balance": "0", - "code": "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80639b063104146037578063cd16ecbf146062575b600080fd5b606060048036036020811015604b57600080fd5b8101908080359060200190929190505050608d565b005b608b60048036036020811015607657600080fd5b81019080803590602001909291905050506097565b005b8060018190555050565b806000819055505056fea265627a7a7231582029df540a7555533ef4b3f66bc4f9abe138b00117d1496efbfd9d035a48cd595e64736f6c634300050d0032", - "storage": { - "0x0": "0x01" - }, - "nonce": "0" - }, - "0xD2002000000000000000000000000000000000D2": { - "balance": "0", - "code": "0x608060405234801561001057600080fd5b50600436106100455760003560e01c806313f44d101461005557806338eada1c146100af5780634ba79dfe146100f357610046565b5b6002801461005357600080fd5b005b6100976004803603602081101561006b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610137565b60405180821515815260200191505060405180910390f35b6100f1600480360360208110156100c557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101f4565b005b6101356004803603602081101561010957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061030f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16148061019957506101988261042b565b5b806101ed5750600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b9050919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f43616c6c6572206973206e6f7420746865206f776e657200000000000000000081525060200191505060405180910390fd5b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f43616c6c6572206973206e6f7420746865206f776e657200000000000000000081525060200191505060405180910390fd5b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600080823b90506000811191505091905056fea26469706673582212202aca1f7abb7d02061b58de9b559eabe1607c880fda3932bbdb2b74fa553e537c64736f6c634300060c0033", - "storage": { - }, - "nonce": "0" - }, - "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "0x0de0b6b3a7640000", - "code" : "0x", - "nonce" : "0x00", - "storage" : { - } - }, - "0xD2001300000000000000000000000000000000D4": { - "balance": "0", - "nonce": "0", - "storage": {}, - "code":"0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80632098776714610051578063b8bd717f1461007f578063d37165fa146100ad578063fdde8d66146100db575b600080fd5b61007d6004803603602081101561006757600080fd5b8101908080359060200190929190505050610109565b005b6100ab6004803603602081101561009557600080fd5b8101908080359060200190929190505050610136565b005b6100d9600480360360208110156100c357600080fd5b8101908080359060200190929190505050610170565b005b610107600480360360208110156100f157600080fd5b8101908080359060200190929190505050610191565b005b60005a90505b815a8203101561011e5761010f565b600080fd5b815a8203101561013257610123565b5050565b60005a90505b815a8203101561014b5761013c565b600060011461015957600080fd5b5a90505b815a8203101561016c5761015d565b5050565b60005a9050600081830390505b805a8303101561018c5761017d565b505050565b60005a90505b815a820310156101a657610197565b60016101b157600080fd5b5a90505b815a820310156101c4576101b5565b505056fea264697066735822122089b72532621e7d1849e444ee6efaad4fb8771258e6f79755083dce434e5ac94c64736f6c63430006000033" - } - } -} -)"; -#endif // #ifndef FAIR - - -BOOST_AUTO_TEST_CASE( getCommonPublicKey ) { - JsonRpcFixture fixture( c_BITEConfigString, false, false, true ); - - Json::Value biteInfo = fixture.rpcClient->bite_getCommitteesInfo(); - - BOOST_REQUIRE( biteInfo.isArray() ); - std::string blsPublicKey = biteInfo[0]["commonBLSPublicKey"].asString(); - uint64_t epochId = biteInfo[0]["epochId"].asUInt64(); - - auto commonPublicKeyFromConfig = fixture.client->chainParams().getCommonBlsPublicKey(); - libBLS::algebra::G2Point commonPublicKey = libBLS::algebra::G2Point::fromString( commonPublicKeyFromConfig, libBLS::Base::DEC ); - - BOOST_REQUIRE_EQUAL( blsPublicKey.size(), 256 ); - BOOST_REQUIRE_EQUAL( libBLS::TEPublicKey( blsPublicKey, libBLS::Base::HEXA ).getPublicKeyRaw(), commonPublicKey ); - BOOST_REQUIRE_EQUAL( epochId, fixture.client->getCurrentEpochId() ); -} - -#ifdef BITE - -// Helper function to build abi.encode(bytes[] args1, bytes[] args2) -dev::bytes buildAbiEncodedArrays( const std::vector& args1Elements, const std::vector& args2Elements ) { - // Validate that all args1 elements meet minimum length requirement - for ( size_t i = 0; i < args1Elements.size(); ++i ) { - if ( args1Elements[i].size() < BITE_CIPHERTEXT_MIN_LEN ) { - throw std::runtime_error( "buildAbiEncodedArrays: args1 element " + std::to_string(i) + - " is too short (" + std::to_string(args1Elements[i].size()) + " bytes), must be at least " + - std::to_string(BITE_CIPHERTEXT_MIN_LEN) + " bytes" ); - } - } - - dev::bytes result; - - // Calculate total size for args1 array data - size_t args1DataSize = 32; // length field - args1DataSize += 32 * args1Elements.size(); // offsets for each element - for ( const auto& elem : args1Elements ) { - args1DataSize += 32; // length field for element - args1DataSize += (elem.size() + 31) / 32 * 32; // padded element data - } - - // Write offsets to both arrays - dev::bytes args1Offset = dev::toBigEndian( dev::u256( 64 ) ); - dev::bytes args2Offset = dev::toBigEndian( dev::u256( 64 + args1DataSize ) ); - result.insert( result.end(), args1Offset.begin(), args1Offset.end() ); - result.insert( result.end(), args2Offset.begin(), args2Offset.end() ); - - // Encode args1 array - dev::bytes args1Length = dev::toBigEndian( dev::u256( args1Elements.size() ) ); - result.insert( result.end(), args1Length.begin(), args1Length.end() ); - - // Calculate and write element offsets for args1 - size_t currentOffset = 32 * args1Elements.size(); // After all offset fields - for ( const auto& elem : args1Elements ) { - dev::bytes elemOffset = dev::toBigEndian( dev::u256( currentOffset ) ); - result.insert( result.end(), elemOffset.begin(), elemOffset.end() ); - currentOffset += 32 + (elem.size() + 31) / 32 * 32; // length + padded data - } - - // Write args1 element data - for ( const auto& elem : args1Elements ) { - dev::bytes elemLength = dev::toBigEndian( dev::u256( elem.size() ) ); - result.insert( result.end(), elemLength.begin(), elemLength.end() ); - result.insert( result.end(), elem.begin(), elem.end() ); - while( result.size() % 32 != 0 ) result.push_back(0); - } - - // Encode args2 array (same structure as args1) - dev::bytes args2Length = dev::toBigEndian( dev::u256( args2Elements.size() ) ); - result.insert( result.end(), args2Length.begin(), args2Length.end() ); - - // Calculate and write element offsets for args2 - currentOffset = 32 * args2Elements.size(); - for ( const auto& elem : args2Elements ) { - dev::bytes elemOffset = dev::toBigEndian( dev::u256( currentOffset ) ); - result.insert( result.end(), elemOffset.begin(), elemOffset.end() ); - currentOffset += 32 + (elem.size() + 31) / 32 * 32; - } - - // Write args2 element data - for ( const auto& elem : args2Elements ) { - dev::bytes elemLength = dev::toBigEndian( dev::u256( elem.size() ) ); - result.insert( result.end(), elemLength.begin(), elemLength.end() ); - result.insert( result.end(), elem.begin(), elem.end() ); - while( result.size() % 32 != 0 ) result.push_back(0); - } - - return result; -} - -BOOST_AUTO_TEST_CASE( rejectExplicitCTXSubmission ) { - JsonRpcFixture fixture( c_BITEConfigString, true, true, true, true, false, -1, { { "contractStorageLimit", "100000" } } ); - string senderAddress = toJS( fixture.coinbase.address() ); - size_t nonce = 0; - std::string onDecryptSelector = dev::toHexPrefixed( dev::bite::ON_DECRYPT_FUNCTION_SELECTOR ); - Transaction t( dev::jsToBytes( formTransactionRlp( fixture, senderAddress, onDecryptSelector, nonce, dev::Address::random().hex() ) ), CheckTransaction::Everything, - false, false, false, true, true - ); - BOOST_REQUIRE_THROW( fixture.client->importTransaction( t ), IllegalCTXSubmission ); - BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendRawTransaction( dev::toHexPrefixed( t.toBytes() ) ), jsonrpc::JsonRpcException ); -} - -BOOST_AUTO_TEST_CASE( submitCTX ) { - JsonRpcFixture fixture( c_BITEConfigString, true, true, true, true, false, -1, {{ "contractStorageLimit", "100000" }} ); - - string senderAddress = toJS( fixture.coinbase.address() ); - - std::vector< dev::bytes > pregeneratedDecryptedValues{ dev::fromHex( "5b221ee6b5c5751ff5808beddbc0644dc4fdda6b5efb13dbb49d698cb0e3f172" ), - dev::fromHex( "006aa7d63edcfb03635a2ecf5064a9eec076c2466fb2a6c35d59b5f1039f2535" ) }; - std::vector< dev::bytes > pregeneratedPlaintextValues{ dev::asBytes( "plaintext1" ), dev::asBytes( "plaintext2" ) }; -// pragma solidity ^0.8.13; - -// contract Precompile0x1BCaller { -// bytes[] decrypted = new bytes[](1); -// bytes[] plaintext = new bytes[](1); -// constructor() payable {} - -// function submitCTX() public { -// uint256 randomNumber = uint256(keccak256(abi.encodePacked(block.timestamp, block.number))) % 2500000 + 1000000; -// bytes[] memory args1 = new bytes[](2); -// // Use pre-generated args1 values instead of generating them dynamically -// args1[0] = hex"f9015880b9015401cc5504bac92b5ccafa0c3202372d7bb0b8cb6861795deddafae0ed7be924ff170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006360e4a05b2e03056b2d61c7ad2deb47b0be0084ffab44bf506bfff07b951fb0bf37c171584f74d80c96306e124152458183a7a2c570a136099f7c4ffc9dde340cbed4f87133200fc4e425946925eaac958209aba78e190feeb5c9f31182ec8d458260279adb3976c158471b932bbee5bb320c"; -// args1[1] = hex"f9015880b9015401154918854780593f1c6bf620684b29ab3d4c4a4f5996dcbd1c1d0b48c06d56b40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000751884c80374b7b5d6d0ef740dacbea91b3d53ee5243eeacf94a970f131185c69dfd44e868e370602c72484bc2f34e9466255ef50ca817d34d61a46bff368318b6fff300eb566dac8d1c569a270c6d9c1f99664643582cafcb276fea83d5564cd38f4b1be0e8ee6c06e10f10f10dc39120884"; - -// bytes[] memory args2 = new bytes[](2); -// args2[0] = abi.encodePacked("plaintext1"); -// args2[1] = abi.encodePacked("plaintext2"); - -// bytes memory randomBytes = abi.encode(args1, args2); -// bytes memory input = abi.encode(randomNumber, randomBytes); - -// (bool success, bytes memory result) = address(0x1B).staticcall(input); -// require(success, "0x1B call failed"); - -// // Extract address from first 20 bytes of result and transfer -// address walletAddress = address(bytes20(result)); -// payable(walletAddress).transfer(400000000000); -// } - -// function submitCTXWithInput(bytes calldata input) public { -// (bool success, bytes memory result) = address(0x1B).staticcall(input); -// require(success, "0x1B call failed"); - -// // Extract address from first 20 bytes of result and transfer -// address walletAddress = address(bytes20(result)); -// payable(walletAddress).transfer(400000000000 ); -// } - -// function onDecrypt(bytes[] calldata decryptedArguments, bytes[] calldata plaintextArguments) public { -// delete decrypted; -// decrypted = new bytes[](decryptedArguments.length); -// for (uint i = 0; i < decryptedArguments.length; ++i) { -// decrypted[i] = decryptedArguments[i]; -// } -// delete plaintext; -// plaintext = new bytes[](plaintextArguments.length); -// for (uint i = 0; i < plaintextArguments.length; ++i) { -// plaintext[i] = plaintextArguments[i]; -// } -// return; -// } - -// function getDecrypted() public view returns (bytes[] memory) { -// return decrypted; -// } - -// function getPlaintext() public view returns (bytes[] memory) { -// return plaintext; -// } -// } - std::string bytecode = "6080604052600167ffffffffffffffff81111561001f5761001e6101ad565b5b60405190808252806020026020018201604052801561005257816020015b606081526020019060019003908161003d5790505b50600090805190602001906100689291906100d3565b50600167ffffffffffffffff811115610084576100836101ad565b5b6040519080825280602002602001820160405280156100b757816020015b60608152602001906001900390816100a25790505b50600190805190602001906100cd9291906100d3565b506104cf565b82805482825590600052602060002090810192821561011b579160200282015b8281111561011a57825182908161010a91906103fd565b50916020019190600101906100f3565b5b509050610128919061012c565b5090565b5b8082111561014c57600081816101439190610150565b5060010161012d565b5090565b50805461015c90610216565b6000825580601f1061016e575061018d565b601f01602090049060005260206000209081019061018c9190610190565b5b50565b5b808211156101a9576000816000905550600101610191565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061022e57607f821691505b602082108103610241576102406101e7565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026102a97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261026c565b6102b3868361026c565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006102fa6102f56102f0846102cb565b6102d5565b6102cb565b9050919050565b6000819050919050565b610314836102df565b61032861032082610301565b848454610279565b825550505050565b600090565b61033d610330565b61034881848461030b565b505050565b5b8181101561036c57610361600082610335565b60018101905061034e565b5050565b601f8211156103b15761038281610247565b61038b8461025c565b8101602085101561039a578190505b6103ae6103a68561025c565b83018261034d565b50505b505050565b600082821c905092915050565b60006103d4600019846008026103b6565b1980831691505092915050565b60006103ed83836103c3565b9150826002028217905092915050565b610406826101dc565b67ffffffffffffffff81111561041f5761041e6101ad565b5b6104298254610216565b610434828285610370565b600060209050601f8311600181146104675760008415610455578287015190505b61045f85826103e1565b8655506104c7565b601f19841661047586610247565b60005b8281101561049d57848901518255600182019150602085019450602081019050610478565b868310156104ba57848901516104b6601f8916826103c3565b8355505b6001600288020188555050505b505050505050565b6118b5806104de6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c806338d5a3121461005c57806357983ac81461007a5780636040c1fb146100965780637372aa26146100b2578063cc159120146100bc575b600080fd5b6100646100da565b6040516100719190610af5565b60405180910390f35b610094600480360381019061008f9190610b86565b6101b3565b005b6100b060048036038101906100ab9190610c5d565b610378565b005b6100ba61048c565b005b6100c46107cf565b6040516100d19190610af5565b60405180910390f35b60606000805480602002602001604051908101604052809291908181526020016000905b828210156101aa57838290600052602060002001805461011d90610cd9565b80601f016020809104026020016040519081016040528092919081815260200182805461014990610cd9565b80156101965780601f1061016b57610100808354040283529160200191610196565b820191906000526020600020905b81548152906001019060200180831161017957829003601f168201915b5050505050815260200190600101906100fe565b50505050905090565b6000806101c091906108a8565b8383905067ffffffffffffffff8111156101dd576101dc610d0a565b5b60405190808252806020026020018201604052801561021057816020015b60608152602001906001900390816101fb5790505b50600090805190602001906102269291906108c9565b5060005b848490508110156102915784848281811061024857610247610d39565b5b905060200281019061025a9190610d77565b6000838154811061026e5761026d610d39565b5b906000526020600020019182610285929190610f9b565b5080600101905061022a565b50600160006102a091906108a8565b8181905067ffffffffffffffff8111156102bd576102bc610d0a565b5b6040519080825280602002602001820160405280156102f057816020015b60608152602001906001900390816102db5790505b50600190805190602001906103069291906108c9565b5060005b828290508110156103715782828281811061032857610327610d39565b5b905060200281019061033a9190610d77565b6001838154811061034e5761034d610d39565b5b906000526020600020019182610365929190610f9b565b5080600101905061030a565b5050505050565b600080601b73ffffffffffffffffffffffffffffffffffffffff1684846040516103a39291906110aa565b600060405180830381855afa9150503d80600081146103de576040519150601f19603f3d011682016040523d82523d6000602084013e6103e3565b606091505b509150915081610428576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041f90611120565b60405180910390fd5b60008161043490611191565b60601c90508073ffffffffffffffffffffffffffffffffffffffff166108fc645d21dba0009081150290604051600060405180830381858888f19350505050158015610484573d6000803e3d6000fd5b505050505050565b6000620f4240622625a042436040516020016104a9929190611219565b6040516020818303038152906040528051906020012060001c6104cc9190611274565b6104d691906112d4565b90506000600267ffffffffffffffff8111156104f5576104f4610d0a565b5b60405190808252806020026020018201604052801561052857816020015b60608152602001906001900390816105135790505b50905060405180610180016040528061015b81526020016115b061015b91398160008151811061055b5761055a610d39565b5b602002602001018190525060405180610180016040528061015b815260200161170b61015b91398160018151811061059657610595610d39565b5b60200260200101819052506000600267ffffffffffffffff8111156105be576105bd610d0a565b5b6040519080825280602002602001820160405280156105f157816020015b60608152602001906001900390816105dc5790505b5090506040516020016106039061135f565b6040516020818303038152906040528160008151811061062657610625610d39565b5b6020026020010181905250604051602001610640906113c0565b6040516020818303038152906040528160018151811061066357610662610d39565b5b6020026020010181905250600082826040516020016106839291906113d5565b6040516020818303038152906040529050600084826040516020016106a9929190611465565b6040516020818303038152906040529050600080601b73ffffffffffffffffffffffffffffffffffffffff16836040516106e391906114c6565b600060405180830381855afa9150503d806000811461071e576040519150601f19603f3d011682016040523d82523d6000602084013e610723565b606091505b509150915081610768576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075f90611120565b60405180910390fd5b60008161077490611191565b60601c90508073ffffffffffffffffffffffffffffffffffffffff166108fc645d21dba0009081150290604051600060405180830381858888f193505050501580156107c4573d6000803e3d6000fd5b505050505050505050565b60606001805480602002602001604051908101604052809291908181526020016000905b8282101561089f57838290600052602060002001805461081290610cd9565b80601f016020809104026020016040519081016040528092919081815260200182805461083e90610cd9565b801561088b5780601f106108605761010080835404028352916020019161088b565b820191906000526020600020905b81548152906001019060200180831161086e57829003601f168201915b5050505050815260200190600101906107f3565b50505050905090565b50805460008255906000526020600020908101906108c69190610922565b50565b828054828255906000526020600020908101928215610911579160200282015b8281111561091057825182908161090091906114dd565b50916020019190600101906108e9565b5b50905061091e9190610922565b5090565b5b8082111561094257600081816109399190610946565b50600101610923565b5090565b50805461095290610cd9565b6000825580601f106109645750610983565b601f0160209004906000526020600020908101906109829190610986565b5b50565b5b8082111561099f576000816000905550600101610987565b5090565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610a095780820151818401526020810190506109ee565b60008484015250505050565b6000601f19601f8301169050919050565b6000610a31826109cf565b610a3b81856109da565b9350610a4b8185602086016109eb565b610a5481610a15565b840191505092915050565b6000610a6b8383610a26565b905092915050565b6000602082019050919050565b6000610a8b826109a3565b610a9581856109ae565b935083602082028501610aa7856109bf565b8060005b85811015610ae35784840389528151610ac48582610a5f565b9450610acf83610a73565b925060208a01995050600181019050610aab565b50829750879550505050505092915050565b60006020820190508181036000830152610b0f8184610a80565b905092915050565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f840112610b4657610b45610b21565b5b8235905067ffffffffffffffff811115610b6357610b62610b26565b5b602083019150836020820283011115610b7f57610b7e610b2b565b5b9250929050565b60008060008060408587031215610ba057610b9f610b17565b5b600085013567ffffffffffffffff811115610bbe57610bbd610b1c565b5b610bca87828801610b30565b9450945050602085013567ffffffffffffffff811115610bed57610bec610b1c565b5b610bf987828801610b30565b925092505092959194509250565b60008083601f840112610c1d57610c1c610b21565b5b8235905067ffffffffffffffff811115610c3a57610c39610b26565b5b602083019150836001820283011115610c5657610c55610b2b565b5b9250929050565b60008060208385031215610c7457610c73610b17565b5b600083013567ffffffffffffffff811115610c9257610c91610b1c565b5b610c9e85828601610c07565b92509250509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680610cf157607f821691505b602082108103610d0457610d03610caa565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112610d9457610d93610d68565b5b80840192508235915067ffffffffffffffff821115610db657610db5610d6d565b5b602083019250600182023603831315610dd257610dd1610d72565b5b509250929050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302610e477fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610e0a565b610e518683610e0a565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000610e98610e93610e8e84610e69565b610e73565b610e69565b9050919050565b6000819050919050565b610eb283610e7d565b610ec6610ebe82610e9f565b848454610e17565b825550505050565b600090565b610edb610ece565b610ee6818484610ea9565b505050565b5b81811015610f0a57610eff600082610ed3565b600181019050610eec565b5050565b601f821115610f4f57610f2081610de5565b610f2984610dfa565b81016020851015610f38578190505b610f4c610f4485610dfa565b830182610eeb565b50505b505050565b600082821c905092915050565b6000610f7260001984600802610f54565b1980831691505092915050565b6000610f8b8383610f61565b9150826002028217905092915050565b610fa58383610dda565b67ffffffffffffffff811115610fbe57610fbd610d0a565b5b610fc88254610cd9565b610fd3828285610f0e565b6000601f8311600181146110025760008415610ff0578287013590505b610ffa8582610f7f565b865550611062565b601f19841661101086610de5565b60005b8281101561103857848901358255600182019150602085019450602081019050611013565b868310156110555784890135611051601f891682610f61565b8355505b6001600288020188555050505b50505050505050565b600081905092915050565b82818337600083830152505050565b6000611091838561106b565b935061109e838584611076565b82840190509392505050565b60006110b7828486611085565b91508190509392505050565b600082825260208201905092915050565b7f307831422063616c6c206661696c656400000000000000000000000000000000600082015250565b600061110a6010836110c3565b9150611115826110d4565b602082019050919050565b60006020820190508181036000830152611139816110fd565b9050919050565b6000819050602082019050919050565b60007fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b60006111888251611150565b80915050919050565b600061119c826109cf565b826111a684611140565b90506111b18161117c565b925060148210156111f1576111ec7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083601403600802610e0a565b831692505b5050919050565b6000819050919050565b61121361120e82610e69565b6111f8565b82525050565b60006112258285611202565b6020820191506112358284611202565b6020820191508190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061127f82610e69565b915061128a83610e69565b92508261129a57611299611245565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006112df82610e69565b91506112ea83610e69565b9250828201905080821115611302576113016112a5565b5b92915050565b600081905092915050565b7f706c61696e746578743100000000000000000000000000000000000000000000600082015250565b6000611349600a83611308565b915061135482611313565b600a82019050919050565b600061136a8261133c565b9150819050919050565b7f706c61696e746578743200000000000000000000000000000000000000000000600082015250565b60006113aa600a83611308565b91506113b582611374565b600a82019050919050565b60006113cb8261139d565b9150819050919050565b600060408201905081810360008301526113ef8185610a80565b905081810360208301526114038184610a80565b90509392505050565b61141581610e69565b82525050565b600082825260208201905092915050565b6000611437826109cf565b611441818561141b565b93506114518185602086016109eb565b61145a81610a15565b840191505092915050565b600060408201905061147a600083018561140c565b818103602083015261148c818461142c565b90509392505050565b60006114a0826109cf565b6114aa818561106b565b93506114ba8185602086016109eb565b80840191505092915050565b60006114d28284611495565b915081905092915050565b6114e6826109cf565b67ffffffffffffffff8111156114ff576114fe610d0a565b5b6115098254610cd9565b611514828285610f0e565b600060209050601f8311600181146115475760008415611535578287015190505b61153f8582610f7f565b8655506115a7565b601f19841661155586610de5565b60005b8281101561157d57848901518255600182019150602085019450602081019050611558565b8683101561159a5784890151611596601f891682610f61565b8355505b6001600288020188555050505b50505050505056fef9015880b9015401cc5504bac92b5ccafa0c3202372d7bb0b8cb6861795deddafae0ed7be924ff170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006360e4a05b2e03056b2d61c7ad2deb47b0be0084ffab44bf506bfff07b951fb0bf37c171584f74d80c96306e124152458183a7a2c570a136099f7c4ffc9dde340cbed4f87133200fc4e425946925eaac958209aba78e190feeb5c9f31182ec8d458260279adb3976c158471b932bbee5bb320cf9015880b9015401154918854780593f1c6bf620684b29ab3d4c4a4f5996dcbd1c1d0b48c06d56b40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000751884c80374b7b5d6d0ef740dacbea91b3d53ee5243eeacf94a970f131185c69dfd44e868e370602c72484bc2f34e9466255ef50ca817d34d61a46bff368318b6fff300eb566dac8d1c569a270c6d9c1f99664643582cafcb276fea83d5564cd38f4b1be0e8ee6c06e10f10f10dc39120884a26469706673582212209f594371591c2c5cc2a967353f54d26d3d236ad0e4c36a1598ff39cef70eae1664736f6c63781c302e382e33312d7072652e312b636f6d6d69742e6235393536366636004d"; - - // deploy contract - Json::Value create; - create["from"] = toJS( senderAddress ); - create["code"] = bytecode; - create["gas"] = "1800000"; - create["value"] = "10000000000000000000"; - create["nonce"] = 0; - string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - auto txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - std::string contractAddress = txReceipt["contractAddress"].asString(); - BOOST_REQUIRE( txReceipt["status"] == "0x1" ); - - // send a transaction -> BITE2 txn queue should become non-empty - Json::Value txGenerate; - txGenerate["to"] = contractAddress; - txGenerate["gas"] = "1000000"; - txGenerate["data"] = "0x7372aa26"; - txGenerate["from"] = toJS( senderAddress ); - txGenerate["nonce"] = 1; - - txHash = fixture.rpcClient->eth_sendTransaction( txGenerate ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( txReceipt["status"] == "0x1" ); - - BOOST_REQUIRE( fixture.client->debugGetTransactionQueue()->pendingBITE2Transactions()->size() == 1 ); - auto bite2Txn = fixture.client->debugGetTransactionQueue()->pendingBITE2Transactions()->front(); - BOOST_REQUIRE( !bite2Txn.isInvalid() ); - BOOST_REQUIRE_NE( bite2Txn.sender(), dev::ZeroAddress ); - auto to = bite2Txn.to(); - BOOST_REQUIRE_EQUAL( to, dev::Address( contractAddress ) ); - - Json::Value craftedCTXs = fixture.rpcClient->bite_getCraftedCtxs( txHash ); - BOOST_REQUIRE_EQUAL( craftedCTXs.size(), 1 ); - BOOST_REQUIRE_EQUAL( craftedCTXs[0].asString(), bite2Txn.sha3().hex() ); - - dev::u256 randomGasLimit = dev::h256::Arith( dev::h256::random() ) % 2500000 + 1000000; - dev::bytes randomGasLimitBytes = dev::toBigEndian( randomGasLimit ); - - std::vector< dev::bytes > originalValues{ dev::h256::random().asBytes(), dev::h256::random().asBytes() }; - - dev::bytes encryptedArg1 = formEncryptedMessageMockup( originalValues[0], dev::Address( contractAddress ) ); - dev::bytes encryptedArg2 = formEncryptedMessageMockup( originalValues[1], dev::Address( contractAddress ) ); - - // Build abi.encode(bytes[] args1, bytes[] args2) with 2 elements each - // args1 elements must be at least BITE_CIPHERTEXT_MIN_LEN bytes (encrypted data) - std::vector args1 = { - encryptedArg1, encryptedArg2 - }; - std::vector args2 = { - dev::fromHex("706c61696e746578743122"), // "plaintext1" - dev::fromHex("706c61696e746578743222") // "plaintext2" - }; - - dev::bytes randomData = buildAbiEncodedArrays( args1, args2 ); - - // Build ABI-encoded input: abi.encode(address, uint256, bytes) - // Format: gasLimit(32) + offset_to_bytes(32) + bytes_length(32) + bytes_data - dev::bytes resultData; - // gasLimit value (32 bytes) - resultData.insert( resultData.end(), randomGasLimitBytes.begin(), randomGasLimitBytes.end() ); - - // offset to bytes data (points to position 64 = 2 * 32) - dev::bytes dataOffset = dev::toBigEndian( dev::u256( 64 ) ); - resultData.insert( resultData.end(), dataOffset.begin(), dataOffset.end() ); - // bytes data (length + content) - dev::bytes dataLength = dev::toBigEndian( dev::u256( randomData.size() ) ); - resultData.insert( resultData.end(), dataLength.begin(), dataLength.end() ); - resultData.insert( resultData.end(), randomData.begin(), randomData.end() ); - - txGenerate["to"] = contractAddress; - txGenerate["data"] = "0x6040c1fb" + dev::toHex( dev::u256( 32 ) ) + dev::toHex( dev::u256( resultData.size() ) ) + dev::toHex( resultData ); - txGenerate["from"] = toJS( senderAddress ); - txGenerate["nonce"] = 2; - std::string txGenerateHash = fixture.rpcClient->eth_sendTransaction( txGenerate ); - BOOST_REQUIRE_EQUAL( fixture.client->debugGetTransactionQueue()->pendingBITE2Transactions()->size(), 1 ); - BOOST_REQUIRE_EQUAL( fixture.client->pending().size(), 1 ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - PrecompiledExecutor submitCTXExecutor = PrecompiledRegistrar::executor( "submitCTX" ); - dev::eth::PrecompiledCallContext ctx( fixture.client->number(), 1, 1, dev::h256::random(), - dev::Address( contractAddress ), true ); - - dev::bytesConstRef input( resultData.data(), resultData.size() ); - auto res = submitCTXExecutor( input, ctx ); - BOOST_REQUIRE( res.first ); - - dev::Address addressFromPrecompiled( dev::bytes( res.second.begin(), res.second.begin() + dev::Address::size ) ); - - PrecompiledExecutor blockRandomExecutor = PrecompiledRegistrar::executor( "getBlockRandom" ); - auto vrs = dev::makeSignature( blockRandomExecutor( bytesConstRef(), ctx ).second, ctx.currentTxnIndex ); - dev::u256 gasPrice = g_skaleHost->getGasPrice( ctx.blockNumber.convert_to< unsigned >() ); - - // Build expected RLP-encoded data: RLP(RLP(args1[0], args1[1]), RLP(args2[0], args2[1])) - RLPStream args1Stream; - args1Stream.appendList( args1.size() ); - for ( const auto& elem : args1 ) { - args1Stream << elem; - } - - RLPStream args2Stream; - args2Stream.appendList( args2.size() ); - for ( const auto& elem : args2 ) { - args2Stream << elem; - } - - RLPStream finalStream; - finalStream.appendList( 2 ); - finalStream.appendRaw( args1Stream.out() ); - finalStream.appendRaw( args2Stream.out() ); - - dev::bytes rlpEncodedData = finalStream.out(); - - rlpEncodedData.insert( rlpEncodedData.begin(), - dev::bite::ON_DECRYPT_FUNCTION_SELECTOR.begin(), - dev::bite::ON_DECRYPT_FUNCTION_SELECTOR.end() ); - - // Create expected transaction for signature verification using RLP-encoded data - Transaction expectedTransaction( 0, gasPrice, randomGasLimit, dev::Address( contractAddress ), rlpEncodedData, 0 ); - dev::h256 expectedTxnHash = expectedTransaction.sha3( dev::eth::WithoutSignature ); - dev::Public expectedPublicKey = recover( vrs, expectedTxnHash ); - dev::Address expectedWalletAddress = dev::toAddress( expectedPublicKey ); - - auto bn = fixture.client->number(); - BOOST_REQUIRE_EQUAL( fixture.client->transactions( bn ).size(), 2 ); - BOOST_REQUIRE( fixture.client->transactions( bn )[0].isCTX() ); - - // call getDecrypted() - Json::Value callDecrypted; - callDecrypted["to"] = contractAddress; - callDecrypted["data"] = "0x38d5a312"; - dev::bytes result = dev::fromHex( fixture.rpcClient->eth_call( callDecrypted, "latest" ) ); - auto [rlpStreamDecrypted, decryptedLength] = dev::bite::parseAbiEncodedBytesArray( dev::bytesConstRef( result.data(), result.size() ), 32, "" ); - BOOST_REQUIRE_EQUAL( decryptedLength, pregeneratedDecryptedValues.size() ); - dev::RLP rlpDecrypted( rlpStreamDecrypted.out() ); - for (size_t i = 0; i < decryptedLength; ++i) { - dev::RLP decryptedPayload( rlpDecrypted[i].payload() ); - BOOST_REQUIRE( decryptedPayload[0].toBytes() == pregeneratedDecryptedValues[i] ); - BOOST_REQUIRE_EQUAL( dev::toHexPrefixed( decryptedPayload[1].toBytes() ), contractAddress ); - } - - // call getPlaintext() - Json::Value callPlaintext; - callPlaintext["to"] = contractAddress; - callPlaintext["data"] = "0xcc159120"; - result = dev::fromHex( fixture.rpcClient->eth_call( callPlaintext, "latest" ) ); - auto [rlpStreamPlaintext, plaintextLength] = dev::bite::parseAbiEncodedBytesArray( dev::bytesConstRef( result.data(), result.size() ), 32, "" ); - BOOST_REQUIRE_EQUAL( plaintextLength, pregeneratedPlaintextValues.size() ); - dev::RLP rlpPlaintext( rlpStreamPlaintext.out() ); - for (size_t i = 0; i < plaintextLength; ++i) { - BOOST_REQUIRE_EQUAL( dev::toHex( rlpPlaintext[i].toBytes() ), dev::toHex( pregeneratedPlaintextValues[i] ) ); - } - - BOOST_REQUIRE_EQUAL( fixture.client->debugGetTransactionQueue()->pendingBITE2Transactions()->size(), 1 ); - - auto pendingCTXs = fixture.client->blockChain().pendingCTXsList(); - BOOST_REQUIRE_EQUAL( pendingCTXs.size(), 1 ); - auto pendingCTX = pendingCTXs[0]; - BOOST_REQUIRE( pendingCTX.isCTX() ); - BOOST_REQUIRE_EQUAL( pendingCTX.to(), dev::Address( contractAddress ) ); - BOOST_REQUIRE_EQUAL( pendingCTX.gas(), randomGasLimit ); - BOOST_REQUIRE_EQUAL( pendingCTX.sender(), expectedWalletAddress ); - BOOST_REQUIRE_EQUAL( "0x" + pendingCTX.getCTXOrigin().hex(), txGenerateHash ); - - dev::eth::mineTransaction( *( fixture.client ), 1 ); - bn = fixture.client->number(); - BOOST_REQUIRE_EQUAL( fixture.client->transactions( bn ).size(), 1 ); - Transaction ctxFromBlockchain = fixture.client->transaction( fixture.client->blockInfo( bn ).hash(), unsigned( 0 ) ); - - BOOST_REQUIRE( ctxFromBlockchain.isCTX() ); - BOOST_REQUIRE_EQUAL( ctxFromBlockchain.to(), dev::Address( contractAddress ) ); - BOOST_REQUIRE_EQUAL( ctxFromBlockchain.gas(), randomGasLimit ); - BOOST_REQUIRE( ctxFromBlockchain.data() == rlpEncodedData ); - BOOST_REQUIRE( ctxFromBlockchain.signature() == vrs ); - BOOST_REQUIRE_EQUAL( ctxFromBlockchain.sender(), expectedWalletAddress ); - - auto ctxOrigin = fixture.rpcClient->bite_getCtxOrigin( "0x" + ctxFromBlockchain.sha3().hex() ); - BOOST_REQUIRE_EQUAL( "0x" + ctxOrigin, txGenerateHash ); - - // call getDecrypted() - result = dev::fromHex( fixture.rpcClient->eth_call( callDecrypted, "latest" ) ); - auto [rlpStreamDecrypted1, decryptedLength1] = dev::bite::parseAbiEncodedBytesArray( dev::bytesConstRef( result.data(), result.size() ), 32, "" ); - BOOST_REQUIRE_EQUAL( decryptedLength1, pregeneratedDecryptedValues.size() ); - dev::RLP rlpDecrypted1( rlpStreamDecrypted1.out() ); - for (size_t i = 0; i < decryptedLength1; ++i) { - dev::RLP decryptedPayload( rlpDecrypted1[i].payload() ); - BOOST_REQUIRE( decryptedPayload[0].toBytes() == originalValues[i] ); - BOOST_REQUIRE_EQUAL( dev::toHexPrefixed( decryptedPayload[1].toBytes() ), contractAddress ); - } - - // call getPlaintext() - result = dev::fromHex( fixture.rpcClient->eth_call( callPlaintext, "latest" ) ); - auto [rlpStreamPlaintext1, plaintextLength1] = dev::bite::parseAbiEncodedBytesArray( dev::bytesConstRef( result.data(), result.size() ), 32, "" ); - BOOST_REQUIRE_EQUAL( plaintextLength1, pregeneratedPlaintextValues.size() ); - dev::RLP rlpPlaintext1( rlpStreamPlaintext1.out() ); - for (size_t i = 0; i < plaintextLength1; ++i) { - BOOST_REQUIRE_EQUAL( dev::toHex( rlpPlaintext1[i].toBytes() ), dev::toHex( args2[i] ) ); - } - - // test submitCTXWithInput with randomGasLimit >> lastBlockGasLimit - dev::u256 lastBlockGasLimit = fixture.client->blockInfo( fixture.client->number() ).gasLimit(); - dev::u256 randomGasLimit2 = lastBlockGasLimit * 10; - dev::bytes randomGasLimitBytes2 = dev::toBigEndian( randomGasLimit2 ); - - std::vector< dev::bytes > originalValues2{ dev::h256::random().asBytes(), dev::h256::random().asBytes() }; - - dev::bytes encryptedArg1_2 = formEncryptedMessageMockup( originalValues2[0], dev::Address( contractAddress ) ); - dev::bytes encryptedArg2_2 = formEncryptedMessageMockup( originalValues2[1], dev::Address( contractAddress ) ); - - std::vector args1_2 = { - encryptedArg1_2, encryptedArg2_2 - }; - std::vector args2_2 = { - dev::fromHex("706c61696e746578743122"), // "plaintext1" - dev::fromHex("706c61696e746578743222") // "plaintext2" - }; - - dev::bytes randomData2 = buildAbiEncodedArrays( args1_2, args2_2 ); - - dev::bytes resultData2; - // gasLimit value (32 bytes) - much greater than block gas limit - resultData2.insert( resultData2.end(), randomGasLimitBytes2.begin(), randomGasLimitBytes2.end() ); - - // offset to bytes data (points to position 64 = 2 * 32) - dev::bytes dataOffset2 = dev::toBigEndian( dev::u256( 64 ) ); - resultData2.insert( resultData2.end(), dataOffset2.begin(), dataOffset2.end() ); - // bytes data (length + content) - dev::bytes dataLength2 = dev::toBigEndian( dev::u256( randomData2.size() ) ); - resultData2.insert( resultData2.end(), dataLength2.begin(), dataLength2.end() ); - resultData2.insert( resultData2.end(), randomData2.begin(), randomData2.end() ); - - txGenerate["to"] = contractAddress; - txGenerate["data"] = "0x6040c1fb" + dev::toHex( dev::u256( 32 ) ) + dev::toHex( dev::u256( resultData2.size() ) ) + dev::toHex( resultData2 ); - txGenerate["from"] = toJS( senderAddress ); - txGenerate["nonce"] = 3; - std::string txGenerateHash2 = fixture.rpcClient->eth_sendTransaction( txGenerate ); - BOOST_REQUIRE_EQUAL( fixture.client->pending().size(), 1 ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txGenerateHash2 ); - BOOST_REQUIRE( txReceipt["status"] == "0x0" ); - - auto bn2 = fixture.client->number(); - BOOST_REQUIRE_EQUAL( fixture.client->transactions( bn2 ).size(), 1 ); - - BOOST_REQUIRE_EQUAL( fixture.client->debugGetTransactionQueue()->pendingBITE2Transactions()->size(), 0 ); -} - -BOOST_AUTO_TEST_CASE( submitCTXInContractConstructor ) { - JsonRpcFixture fixture( c_BITEConfigString, true, true, true, true, false, -1, {{ "contractStorageLimit", "100000"}} ); - - string senderAddress = toJS( fixture.coinbase.address() ); - - std::vector< dev::bytes > pregeneratedDecryptedValues{ dev::fromHex( "5b221ee6b5c5751ff5808beddbc0644dc4fdda6b5efb13dbb49d698cb0e3f172" ), - dev::fromHex( "006aa7d63edcfb03635a2ecf5064a9eec076c2466fb2a6c35d59b5f1039f2535" ) }; - std::vector< dev::bytes > pregeneratedPlaintextValues{ dev::asBytes( "plaintext1" ), dev::asBytes( "plaintext2" ) }; -// pragma solidity ^0.8.13; - -// contract submitCTX { -// bytes[] decrypted = new bytes[](1); -// bytes[] plaintext = new bytes[](1); -// constructor() payable { -// uint256 randomNumber = uint256(keccak256(abi.encodePacked(block.timestamp, block.number))) % 2500000 + 1000000; -// bytes[] memory args1 = new bytes[](2); -// // Use pre-generated args1 values instead of generating them dynamically -// args1[0] = hex"f9015880b9015401cc5504bac92b5ccafa0c3202372d7bb0b8cb6861795deddafae0ed7be924ff170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006360e4a05b2e03056b2d61c7ad2deb47b0be0084ffab44bf506bfff07b951fb0bf37c171584f74d80c96306e124152458183a7a2c570a136099f7c4ffc9dde340cbed4f87133200fc4e425946925eaac958209aba78e190feeb5c9f31182ec8d458260279adb3976c158471b932bbee5bb320c"; -// args1[1] = hex"f9015880b9015401154918854780593f1c6bf620684b29ab3d4c4a4f5996dcbd1c1d0b48c06d56b40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000751884c80374b7b5d6d0ef740dacbea91b3d53ee5243eeacf94a970f131185c69dfd44e868e370602c72484bc2f34e9466255ef50ca817d34d61a46bff368318b6fff300eb566dac8d1c569a270c6d9c1f99664643582cafcb276fea83d5564cd38f4b1be0e8ee6c06e10f10f10dc39120884"; - -// bytes[] memory args2 = new bytes[](2); -// args2[0] = abi.encodePacked("plaintext1"); -// args2[1] = abi.encodePacked("plaintext2"); - -// bytes memory randomBytes = abi.encode(args1, args2); -// bytes memory input = abi.encode(randomNumber, randomBytes); - -// (bool success, bytes memory result) = address(0x1B).staticcall(input); -// require(success, "0x1B call failed"); - -// // Extract address from first 20 bytes of result and transfer -// address walletAddress = address(bytes20(result)); -// payable(walletAddress).transfer(400000000000); -// } -// } - std::string bytecode = "6080604052600167ffffffffffffffff81111561001f5761001e6104ee565b5b60405190808252806020026020018201604052801561005257816020015b606081526020019060019003908161003d5790505b5060009080519060200190610068929190610414565b50600167ffffffffffffffff811115610084576100836104ee565b5b6040519080825280602002602001820160405280156100b757816020015b60608152602001906001900390816100a25790505b50600190805190602001906100cd929190610414565b506000620f4240622625a042436040516020016100eb929190610548565b6040516020818303038152906040528051906020012060001c61010e91906105a3565b6101189190610603565b90506000600267ffffffffffffffff811115610137576101366104ee565b5b60405190808252806020026020018201604052801561016a57816020015b60608152602001906001900390816101555790505b50905060405180610180016040528061015b8152602001610df861015b91398160008151811061019d5761019c610637565b5b602002602001018190525060405180610180016040528061015b8152602001610f5361015b9139816001815181106101d8576101d7610637565b5b60200260200101819052506000600267ffffffffffffffff811115610200576101ff6104ee565b5b60405190808252806020026020018201604052801561023357816020015b606081526020019060019003908161021e5790505b509050604051602001610245906106bd565b6040516020818303038152906040528160008151811061026857610267610637565b5b60200260200101819052506040516020016102829061071e565b604051602081830303815290604052816001815181106102a5576102a4610637565b5b6020026020010181905250600082826040516020016102c5929190610885565b6040516020818303038152906040529050600084826040516020016102eb929190610915565b6040516020818303038152906040529050600080601b73ffffffffffffffffffffffffffffffffffffffff16836040516103259190610981565b600060405180830381855afa9150503d8060008114610360576040519150601f19603f3d011682016040523d82523d6000602084013e610365565b606091505b5091509150816103aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a1906109f5565b60405180910390fd5b6000816103b690610a73565b60601c90508073ffffffffffffffffffffffffffffffffffffffff166108fc645d21dba0009081150290604051600060405180830381858888f19350505050158015610406573d6000803e3d6000fd5b505050505050505050610dab565b82805482825590600052602060002090810192821561045c579160200282015b8281111561045b57825182908161044b9190610cd9565b5091602001919060010190610434565b5b509050610469919061046d565b5090565b5b8082111561048d57600081816104849190610491565b5060010161046e565b5090565b50805461049d90610b09565b6000825580601f106104af57506104ce565b601f0160209004906000526020600020908101906104cd91906104d1565b5b50565b5b808211156104ea5760008160009055506001016104d2565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000819050919050565b6000819050919050565b61054261053d8261051d565b610527565b82525050565b60006105548285610531565b6020820191506105648284610531565b6020820191508190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006105ae8261051d565b91506105b98361051d565b9250826105c9576105c8610574565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061060e8261051d565b91506106198361051d565b9250828201905080821115610631576106306105d4565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081905092915050565b7f706c61696e746578743100000000000000000000000000000000000000000000600082015250565b60006106a7600a83610666565b91506106b282610671565b600a82019050919050565b60006106c88261069a565b9150819050919050565b7f706c61696e746578743200000000000000000000000000000000000000000000600082015250565b6000610708600a83610666565b9150610713826106d2565b600a82019050919050565b6000610729826106fb565b9150819050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561079957808201518184015260208101905061077e565b60008484015250505050565b6000601f19601f8301169050919050565b60006107c18261075f565b6107cb818561076a565b93506107db81856020860161077b565b6107e4816107a5565b840191505092915050565b60006107fb83836107b6565b905092915050565b6000602082019050919050565b600061081b82610733565b610825818561073e565b9350836020820285016108378561074f565b8060005b85811015610873578484038952815161085485826107ef565b945061085f83610803565b925060208a0199505060018101905061083b565b50829750879550505050505092915050565b6000604082019050818103600083015261089f8185610810565b905081810360208301526108b38184610810565b90509392505050565b6108c58161051d565b82525050565b600082825260208201905092915050565b60006108e78261075f565b6108f181856108cb565b935061090181856020860161077b565b61090a816107a5565b840191505092915050565b600060408201905061092a60008301856108bc565b818103602083015261093c81846108dc565b90509392505050565b600081905092915050565b600061095b8261075f565b6109658185610945565b935061097581856020860161077b565b80840191505092915050565b600061098d8284610950565b915081905092915050565b600082825260208201905092915050565b7f307831422063616c6c206661696c656400000000000000000000000000000000600082015250565b60006109df601083610998565b91506109ea826109a9565b602082019050919050565b60006020820190508181036000830152610a0e816109d2565b9050919050565b6000819050602082019050919050565b60007fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b6000610a5d8251610a25565b80915050919050565b600082821b905092915050565b6000610a7e8261075f565b82610a8884610a15565b9050610a9381610a51565b92506014821015610ad357610ace7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083601403600802610a66565b831692505b5050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680610b2157607f821691505b602082108103610b3457610b33610ada565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600060088302610b8f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610a66565b610b998683610a66565b95508019841693508086168417925050509392505050565b6000819050919050565b6000610bd6610bd1610bcc8461051d565b610bb1565b61051d565b9050919050565b6000819050919050565b610bf083610bbb565b610c04610bfc82610bdd565b848454610b5f565b825550505050565b600090565b610c19610c0c565b610c24818484610be7565b505050565b5b81811015610c4857610c3d600082610c11565b600181019050610c2a565b5050565b601f821115610c8d57610c5e81610b3a565b610c6784610b4f565b81016020851015610c76578190505b610c8a610c8285610b4f565b830182610c29565b50505b505050565b600082821c905092915050565b6000610cb060001984600802610c92565b1980831691505092915050565b6000610cc98383610c9f565b9150826002028217905092915050565b610ce28261075f565b67ffffffffffffffff811115610cfb57610cfa6104ee565b5b610d058254610b09565b610d10828285610c4c565b600060209050601f831160018114610d435760008415610d31578287015190505b610d3b8582610cbd565b865550610da3565b601f198416610d5186610b3a565b60005b82811015610d7957848901518255600182019150602085019450602081019050610d54565b86831015610d965784890151610d92601f891682610c9f565b8355505b6001600288020188555050505b505050505050565b603f80610db96000396000f3fe6080604052600080fdfea26469706673582212207f8d440a8b67a3a94ec70a43d822504c120782b181a52230ee20ee672f58781364736f6c634300081f0033f9015880b9015401cc5504bac92b5ccafa0c3202372d7bb0b8cb6861795deddafae0ed7be924ff170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006360e4a05b2e03056b2d61c7ad2deb47b0be0084ffab44bf506bfff07b951fb0bf37c171584f74d80c96306e124152458183a7a2c570a136099f7c4ffc9dde340cbed4f87133200fc4e425946925eaac958209aba78e190feeb5c9f31182ec8d458260279adb3976c158471b932bbee5bb320cf9015880b9015401154918854780593f1c6bf620684b29ab3d4c4a4f5996dcbd1c1d0b48c06d56b40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000751884c80374b7b5d6d0ef740dacbea91b3d53ee5243eeacf94a970f131185c69dfd44e868e370602c72484bc2f34e9466255ef50ca817d34d61a46bff368318b6fff300eb566dac8d1c569a270c6d9c1f99664643582cafcb276fea83d5564cd38f4b1be0e8ee6c06e10f10f10dc39120884"; - - // deploy contract - Json::Value create; - create["from"] = toJS( senderAddress ); - create["code"] = bytecode; - create["gas"] = "1800000"; - create["value"] = "10000000000000000000"; - create["nonce"] = 0; - string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - auto txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - std::string contractAddress = txReceipt["contractAddress"].asString(); - BOOST_REQUIRE( txReceipt["status"] == "0x1" ); - - // BITE2 txn queue should become non-empty - BOOST_REQUIRE( fixture.client->debugGetTransactionQueue()->pendingBITE2Transactions()->size() == 1 ); - auto bite2Txn = fixture.client->debugGetTransactionQueue()->pendingBITE2Transactions()->front(); - BOOST_REQUIRE( !bite2Txn.isInvalid() ); - BOOST_REQUIRE_NE( bite2Txn.sender(), dev::ZeroAddress ); - auto to = bite2Txn.to(); - BOOST_REQUIRE_EQUAL( to, dev::Address( contractAddress ) ); -} - -BOOST_AUTO_TEST_CASE( CTXTransactionAfterRevert ) { - JsonRpcFixture fixture( c_BITEConfigString, true, true, true, true, false, -1, {{ "contractStorageLimit", "100000" }} ); - - string senderAddress = toJS( fixture.coinbase.address() ); - -// pragma solidity ^0.8.13; - -// contract submitCTXCaller { -// bytes[] decrypted = new bytes[](1); -// bytes[] plaintext = new bytes[](1); -// constructor() payable {} - -// function submitCTX() public { -// uint256 randomNumber = uint256(keccak256(abi.encodePacked(block.timestamp, block.number))) % 2500000 + 1000000; -// bytes[] memory args1 = new bytes[](2); -// // Use pre-generated args1 values instead of generating them dynamically -// args1[0] = hex"f9015880b9015401cc5504bac92b5ccafa0c3202372d7bb0b8cb6861795deddafae0ed7be924ff170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006360e4a05b2e03056b2d61c7ad2deb47b0be0084ffab44bf506bfff07b951fb0bf37c171584f74d80c96306e124152458183a7a2c570a136099f7c4ffc9dde340cbed4f87133200fc4e425946925eaac958209aba78e190feeb5c9f31182ec8d458260279adb3976c158471b932bbee5bb320c"; -// args1[1] = hex"f9015880b9015401154918854780593f1c6bf620684b29ab3d4c4a4f5996dcbd1c1d0b48c06d56b40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000751884c80374b7b5d6d0ef740dacbea91b3d53ee5243eeacf94a970f131185c69dfd44e868e370602c72484bc2f34e9466255ef50ca817d34d61a46bff368318b6fff300eb566dac8d1c569a270c6d9c1f99664643582cafcb276fea83d5564cd38f4b1be0e8ee6c06e10f10f10dc39120884"; - -// bytes[] memory args2 = new bytes[](2); -// args2[0] = abi.encodePacked("plaintext1"); -// args2[1] = abi.encodePacked("plaintext2"); - -// bytes memory randomBytes = abi.encode(args1, args2); -// bytes memory input = abi.encode(randomNumber, randomBytes); - -// (bool success, bytes memory result) = address(0x1B).call(input); -// require(success, "0x1B call failed"); - -// // Extract address from first 20 bytes of result and transfer -// address walletAddress = address(bytes20(result)); -// payable(walletAddress).transfer(400000000000); -// } - -// function submitCTXWithRevert() public { -// uint256 randomNumber = uint256(keccak256(abi.encodePacked(block.timestamp, block.number))) % 2500000 + 1000000; -// bytes[] memory args1 = new bytes[](2); -// // Use pre-generated args1 values instead of generating them dynamically -// args1[0] = hex"f9015880b9015401cc5504bac92b5ccafa0c3202372d7bb0b8cb6861795deddafae0ed7be924ff170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006360e4a05b2e03056b2d61c7ad2deb47b0be0084ffab44bf506bfff07b951fb0bf37c171584f74d80c96306e124152458183a7a2c570a136099f7c4ffc9dde340cbed4f87133200fc4e425946925eaac958209aba78e190feeb5c9f31182ec8d458260279adb3976c158471b932bbee5bb320c"; -// args1[1] = hex"f9015880b9015401154918854780593f1c6bf620684b29ab3d4c4a4f5996dcbd1c1d0b48c06d56b40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000751884c80374b7b5d6d0ef740dacbea91b3d53ee5243eeacf94a970f131185c69dfd44e868e370602c72484bc2f34e9466255ef50ca817d34d61a46bff368318b6fff300eb566dac8d1c569a270c6d9c1f99664643582cafcb276fea83d5564cd38f4b1be0e8ee6c06e10f10f10dc39120884"; - -// bytes[] memory args2 = new bytes[](2); -// args2[0] = abi.encodePacked("plaintext1"); -// args2[1] = abi.encodePacked("plaintext2"); - -// bytes memory randomBytes = abi.encode(args1, args2); -// bytes memory input = abi.encode(randomNumber, randomBytes); - -// (bool success, bytes memory result) = address(0x1B).staticcall(input); -// require(success, "0x1B call failed"); - -// // Extract address from first 20 bytes of result and transfer -// address walletAddress = address(bytes20(result)); -// payable(walletAddress).transfer(400000000000); -// require(false); -// } - -// function onDecrypt(bytes[] calldata decryptedArguments, bytes[] calldata plaintextArguments) public { -// delete decrypted; -// decrypted = new bytes[](decryptedArguments.length); -// for (uint i = 0; i < decryptedArguments.length; ++i) { -// decrypted[i] = decryptedArguments[i]; -// } -// delete plaintext; -// plaintext = new bytes[](plaintextArguments.length); -// for (uint i = 0; i < plaintextArguments.length; ++i) { -// plaintext[i] = plaintextArguments[i]; -// } -// return; -// } - -// function getDecrypted() public view returns (bytes[] memory) { -// return decrypted; -// } - -// function getPlaintext() public view returns (bytes[] memory) { -// return plaintext; -// } -// } - std::string bytecode = "6080604052600167ffffffffffffffff81111561001f5761001e6101ad565b5b60405190808252806020026020018201604052801561005257816020015b606081526020019060019003908161003d5790505b50600090805190602001906100689291906100d3565b50600167ffffffffffffffff811115610084576100836101ad565b5b6040519080825280602002602001820160405280156100b757816020015b60608152602001906001900390816100a25790505b50600190805190602001906100cd9291906100d3565b506104cf565b82805482825590600052602060002090810192821561011b579160200282015b8281111561011a57825182908161010a91906103fd565b50916020019190600101906100f3565b5b509050610128919061012c565b5090565b5b8082111561014c57600081816101439190610150565b5060010161012d565b5090565b50805461015c90610216565b6000825580601f1061016e575061018d565b601f01602090049060005260206000209081019061018c9190610190565b5b50565b5b808211156101a9576000816000905550600101610191565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061022e57607f821691505b602082108103610241576102406101e7565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026102a97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261026c565b6102b3868361026c565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006102fa6102f56102f0846102cb565b6102d5565b6102cb565b9050919050565b6000819050919050565b610314836102df565b61032861032082610301565b848454610279565b825550505050565b600090565b61033d610330565b61034881848461030b565b505050565b5b8181101561036c57610361600082610335565b60018101905061034e565b5050565b601f8211156103b15761038281610247565b61038b8461025c565b8101602085101561039a578190505b6103ae6103a68561025c565b83018261034d565b50505b505050565b600082821c905092915050565b60006103d4600019846008026103b6565b1980831691505092915050565b60006103ed83836103c3565b9150826002028217905092915050565b610406826101dc565b67ffffffffffffffff81111561041f5761041e6101ad565b5b6104298254610216565b610434828285610370565b600060209050601f8311600181146104675760008415610455578287015190505b61045f85826103e1565b8655506104c7565b601f19841661047586610247565b60005b8281101561049d57848901518255600182019150602085019450602081019050610478565b868310156104ba57848901516104b6601f8916826103c3565b8355505b6001600288020188555050505b505050505050565b6119ef806104de6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c806338d5a3121461005c57806357983ac81461007a5780637372aa2614610096578063a2934a8c146100a0578063cc159120146100aa575b600080fd5b6100646100c8565b6040516100719190610d1f565b60405180910390f35b610094600480360381019061008f9190610db0565b6101a1565b005b61009e610366565b005b6100a86106ab565b005b6100b26109f9565b6040516100bf9190610d1f565b60405180910390f35b60606000805480602002602001604051908101604052809291908181526020016000905b8282101561019857838290600052602060002001805461010b90610e60565b80601f016020809104026020016040519081016040528092919081815260200182805461013790610e60565b80156101845780601f1061015957610100808354040283529160200191610184565b820191906000526020600020905b81548152906001019060200180831161016757829003601f168201915b5050505050815260200190600101906100ec565b50505050905090565b6000806101ae9190610ad2565b8383905067ffffffffffffffff8111156101cb576101ca610e91565b5b6040519080825280602002602001820160405280156101fe57816020015b60608152602001906001900390816101e95790505b5060009080519060200190610214929190610af3565b5060005b8484905081101561027f5784848281811061023657610235610ec0565b5b90506020028101906102489190610efe565b6000838154811061025c5761025b610ec0565b5b906000526020600020019182610273929190611122565b50806001019050610218565b506001600061028e9190610ad2565b8181905067ffffffffffffffff8111156102ab576102aa610e91565b5b6040519080825280602002602001820160405280156102de57816020015b60608152602001906001900390816102c95790505b50600190805190602001906102f4929190610af3565b5060005b8282905081101561035f5782828281811061031657610315610ec0565b5b90506020028101906103289190610efe565b6001838154811061033c5761033b610ec0565b5b906000526020600020019182610353929190611122565b508060010190506102f8565b5050505050565b6000620f4240622625a04243604051602001610383929190611213565b6040516020818303038152906040528051906020012060001c6103a6919061126e565b6103b091906112ce565b90506000600267ffffffffffffffff8111156103cf576103ce610e91565b5b60405190808252806020026020018201604052801561040257816020015b60608152602001906001900390816103ed5790505b50905060405180610180016040528061015b81526020016116ea61015b91398160008151811061043557610434610ec0565b5b602002602001018190525060405180610180016040528061015b815260200161184561015b9139816001815181106104705761046f610ec0565b5b60200260200101819052506000600267ffffffffffffffff81111561049857610497610e91565b5b6040519080825280602002602001820160405280156104cb57816020015b60608152602001906001900390816104b65790505b5090506040516020016104dd90611359565b60405160208183030381529060405281600081518110610500576104ff610ec0565b5b602002602001018190525060405160200161051a906113ba565b6040516020818303038152906040528160018151811061053d5761053c610ec0565b5b60200260200101819052506000828260405160200161055d9291906113cf565b60405160208183030381529060405290506000848260405160200161058392919061145f565b6040516020818303038152906040529050600080601b73ffffffffffffffffffffffffffffffffffffffff16836040516105bd91906114cb565b6000604051808303816000865af19150503d80600081146105fa576040519150601f19603f3d011682016040523d82523d6000602084013e6105ff565b606091505b509150915081610644576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161063b9061153f565b60405180910390fd5b600081610650906115b0565b60601c90508073ffffffffffffffffffffffffffffffffffffffff166108fc645d21dba0009081150290604051600060405180830381858888f193505050501580156106a0573d6000803e3d6000fd5b505050505050505050565b6000620f4240622625a042436040516020016106c8929190611213565b6040516020818303038152906040528051906020012060001c6106eb919061126e565b6106f591906112ce565b90506000600267ffffffffffffffff81111561071457610713610e91565b5b60405190808252806020026020018201604052801561074757816020015b60608152602001906001900390816107325790505b50905060405180610180016040528061015b81526020016116ea61015b91398160008151811061077a57610779610ec0565b5b602002602001018190525060405180610180016040528061015b815260200161184561015b9139816001815181106107b5576107b4610ec0565b5b60200260200101819052506000600267ffffffffffffffff8111156107dd576107dc610e91565b5b60405190808252806020026020018201604052801561081057816020015b60608152602001906001900390816107fb5790505b50905060405160200161082290611359565b6040516020818303038152906040528160008151811061084557610844610ec0565b5b602002602001018190525060405160200161085f906113ba565b6040516020818303038152906040528160018151811061088257610881610ec0565b5b6020026020010181905250600082826040516020016108a29291906113cf565b6040516020818303038152906040529050600084826040516020016108c892919061145f565b6040516020818303038152906040529050600080601b73ffffffffffffffffffffffffffffffffffffffff168360405161090291906114cb565b600060405180830381855afa9150503d806000811461093d576040519150601f19603f3d011682016040523d82523d6000602084013e610942565b606091505b509150915081610987576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097e9061153f565b60405180910390fd5b600081610993906115b0565b60601c90508073ffffffffffffffffffffffffffffffffffffffff166108fc645d21dba0009081150290604051600060405180830381858888f193505050501580156109e3573d6000803e3d6000fd5b5060006109ef57600080fd5b5050505050505050565b60606001805480602002602001604051908101604052809291908181526020016000905b82821015610ac9578382906000526020600020018054610a3c90610e60565b80601f0160208091040260200160405190810160405280929190818152602001828054610a6890610e60565b8015610ab55780601f10610a8a57610100808354040283529160200191610ab5565b820191906000526020600020905b815481529060010190602001808311610a9857829003601f168201915b505050505081526020019060010190610a1d565b50505050905090565b5080546000825590600052602060002090810190610af09190610b4c565b50565b828054828255906000526020600020908101928215610b3b579160200282015b82811115610b3a578251829081610b2a9190611617565b5091602001919060010190610b13565b5b509050610b489190610b4c565b5090565b5b80821115610b6c5760008181610b639190610b70565b50600101610b4d565b5090565b508054610b7c90610e60565b6000825580601f10610b8e5750610bad565b601f016020900490600052602060002090810190610bac9190610bb0565b5b50565b5b80821115610bc9576000816000905550600101610bb1565b5090565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610c33578082015181840152602081019050610c18565b60008484015250505050565b6000601f19601f8301169050919050565b6000610c5b82610bf9565b610c658185610c04565b9350610c75818560208601610c15565b610c7e81610c3f565b840191505092915050565b6000610c958383610c50565b905092915050565b6000602082019050919050565b6000610cb582610bcd565b610cbf8185610bd8565b935083602082028501610cd185610be9565b8060005b85811015610d0d5784840389528151610cee8582610c89565b9450610cf983610c9d565b925060208a01995050600181019050610cd5565b50829750879550505050505092915050565b60006020820190508181036000830152610d398184610caa565b905092915050565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f840112610d7057610d6f610d4b565b5b8235905067ffffffffffffffff811115610d8d57610d8c610d50565b5b602083019150836020820283011115610da957610da8610d55565b5b9250929050565b60008060008060408587031215610dca57610dc9610d41565b5b600085013567ffffffffffffffff811115610de857610de7610d46565b5b610df487828801610d5a565b9450945050602085013567ffffffffffffffff811115610e1757610e16610d46565b5b610e2387828801610d5a565b925092505092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680610e7857607f821691505b602082108103610e8b57610e8a610e31565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112610f1b57610f1a610eef565b5b80840192508235915067ffffffffffffffff821115610f3d57610f3c610ef4565b5b602083019250600182023603831315610f5957610f58610ef9565b5b509250929050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302610fce7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610f91565b610fd88683610f91565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b600061101f61101a61101584610ff0565b610ffa565b610ff0565b9050919050565b6000819050919050565b61103983611004565b61104d61104582611026565b848454610f9e565b825550505050565b600090565b611062611055565b61106d818484611030565b505050565b5b818110156110915761108660008261105a565b600181019050611073565b5050565b601f8211156110d6576110a781610f6c565b6110b084610f81565b810160208510156110bf578190505b6110d36110cb85610f81565b830182611072565b50505b505050565b600082821c905092915050565b60006110f9600019846008026110db565b1980831691505092915050565b600061111283836110e8565b9150826002028217905092915050565b61112c8383610f61565b67ffffffffffffffff81111561114557611144610e91565b5b61114f8254610e60565b61115a828285611095565b6000601f8311600181146111895760008415611177578287013590505b6111818582611106565b8655506111e9565b601f19841661119786610f6c565b60005b828110156111bf5784890135825560018201915060208501945060208101905061119a565b868310156111dc57848901356111d8601f8916826110e8565b8355505b6001600288020188555050505b50505050505050565b6000819050919050565b61120d61120882610ff0565b6111f2565b82525050565b600061121f82856111fc565b60208201915061122f82846111fc565b6020820191508190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061127982610ff0565b915061128483610ff0565b9250826112945761129361123f565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006112d982610ff0565b91506112e483610ff0565b92508282019050808211156112fc576112fb61129f565b5b92915050565b600081905092915050565b7f706c61696e746578743100000000000000000000000000000000000000000000600082015250565b6000611343600a83611302565b915061134e8261130d565b600a82019050919050565b600061136482611336565b9150819050919050565b7f706c61696e746578743200000000000000000000000000000000000000000000600082015250565b60006113a4600a83611302565b91506113af8261136e565b600a82019050919050565b60006113c582611397565b9150819050919050565b600060408201905081810360008301526113e98185610caa565b905081810360208301526113fd8184610caa565b90509392505050565b61140f81610ff0565b82525050565b600082825260208201905092915050565b600061143182610bf9565b61143b8185611415565b935061144b818560208601610c15565b61145481610c3f565b840191505092915050565b60006040820190506114746000830185611406565b81810360208301526114868184611426565b90509392505050565b600081905092915050565b60006114a582610bf9565b6114af818561148f565b93506114bf818560208601610c15565b80840191505092915050565b60006114d7828461149a565b915081905092915050565b600082825260208201905092915050565b7f307831422063616c6c206661696c656400000000000000000000000000000000600082015250565b60006115296010836114e2565b9150611534826114f3565b602082019050919050565b600060208201905081810360008301526115588161151c565b9050919050565b6000819050602082019050919050565b60007fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b60006115a7825161156f565b80915050919050565b60006115bb82610bf9565b826115c58461155f565b90506115d08161159b565b925060148210156116105761160b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083601403600802610f91565b831692505b5050919050565b61162082610bf9565b67ffffffffffffffff81111561163957611638610e91565b5b6116438254610e60565b61164e828285611095565b600060209050601f831160018114611681576000841561166f578287015190505b6116798582611106565b8655506116e1565b601f19841661168f86610f6c565b60005b828110156116b757848901518255600182019150602085019450602081019050611692565b868310156116d457848901516116d0601f8916826110e8565b8355505b6001600288020188555050505b50505050505056fef9015880b9015401cc5504bac92b5ccafa0c3202372d7bb0b8cb6861795deddafae0ed7be924ff170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006360e4a05b2e03056b2d61c7ad2deb47b0be0084ffab44bf506bfff07b951fb0bf37c171584f74d80c96306e124152458183a7a2c570a136099f7c4ffc9dde340cbed4f87133200fc4e425946925eaac958209aba78e190feeb5c9f31182ec8d458260279adb3976c158471b932bbee5bb320cf9015880b9015401154918854780593f1c6bf620684b29ab3d4c4a4f5996dcbd1c1d0b48c06d56b40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000751884c80374b7b5d6d0ef740dacbea91b3d53ee5243eeacf94a970f131185c69dfd44e868e370602c72484bc2f34e9466255ef50ca817d34d61a46bff368318b6fff300eb566dac8d1c569a270c6d9c1f99664643582cafcb276fea83d5564cd38f4b1be0e8ee6c06e10f10f10dc39120884a2646970667358221220fc4b359f946612f95cce9c035d3fb72316657813aa43c0d7e630b942efcc079e64736f6c63781c302e382e33312d7072652e312b636f6d6d69742e6235393536366636004d"; - - // deploy contract - Json::Value create; - create["from"] = toJS( senderAddress ); - create["code"] = bytecode; - create["gas"] = "1800000"; - create["value"] = "10000000000000000000"; - create["nonce"] = 0; - string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - auto txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - std::string contractAddress = txReceipt["contractAddress"].asString(); - BOOST_REQUIRE( txReceipt["status"] == "0x1" ); - - // call submitCTX() - // BITE2 queue should become non-empty - Json::Value txGenerate; - txGenerate["to"] = contractAddress; - txGenerate["gas"] = "1000000"; - txGenerate["data"] = "0x7372aa26"; - txGenerate["from"] = toJS( senderAddress ); - txGenerate["nonce"] = 1; - txHash = fixture.rpcClient->eth_sendTransaction( txGenerate ); - - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( txReceipt["status"] == "0x1" ); - BOOST_REQUIRE_EQUAL( fixture.client->debugGetTransactionQueue()->pendingBITE2Transactions()->size(), 1 ); - - - // call submitCTXWithRevert() - // BITE2 queue size should remain empty - Json::Value txFailGenerate; - txFailGenerate["to"] = contractAddress; - txFailGenerate["gas"] = "1000000"; - txFailGenerate["data"] = "0xa2934a8c"; - txFailGenerate["from"] = toJS( senderAddress ); - txFailGenerate["nonce"] = 2; - txHash = fixture.rpcClient->eth_sendTransaction( txFailGenerate ); - - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( txReceipt["status"] == "0x0" ); - - BOOST_REQUIRE_EQUAL( fixture.client->debugGetTransactionQueue()->pendingBITE2Transactions()->size(), 0 ); -} - -BOOST_AUTO_TEST_CASE( CTXOutOfBlockGasLimit ) { - JsonRpcFixture fixture( c_BITEConfigString, true, true, true, true, false, -1, {{ "contractStorageLimit", "100000" }} ); - - dev::eth::g_skaleHost = fixture.client->skaleHost(); - - string senderAddress = toJS( fixture.coinbase.address() ); - - // pragma solidity ^0.8.13; - - // contract Precompile0x07Caller { - // bytes[] decrypted = new bytes[](1); - // bytes[] plaintext = new bytes[](1); - // constructor() payable {} - - // function submitCTX(uint256 gasAmount) public { - // uint256 randomNumber = gasAmount + 100000; - // bytes[] memory args1 = new bytes[](2); - // // Use pre-generated args1 values instead of generating them dynamically - // args1[0] = hex"f9015880b9015401cc5504bac92b5ccafa0c3202372d7bb0b8cb6861795deddafae0ed7be924ff170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006360e4a05b2e03056b2d61c7ad2deb47b0be0084ffab44bf506bfff07b951fb0bf37c171584f74d80c96306e124152458183a7a2c570a136099f7c4ffc9dde340cbed4f87133200fc4e425946925eaac958209aba78e190feeb5c9f31182ec8d458260279adb3976c158471b932bbee5bb320c"; - // args1[1] = hex"f9015880b9015401154918854780593f1c6bf620684b29ab3d4c4a4f5996dcbd1c1d0b48c06d56b40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000751884c80374b7b5d6d0ef740dacbea91b3d53ee5243eeacf94a970f131185c69dfd44e868e370602c72484bc2f34e9466255ef50ca817d34d61a46bff368318b6fff300eb566dac8d1c569a270c6d9c1f99664643582cafcb276fea83d5564cd38f4b1be0e8ee6c06e10f10f10dc39120884"; - - // bytes[] memory args2 = new bytes[](1); - // args2[0] = abi.encode(gasAmount); - - // bytes memory randomBytes = abi.encode(args1, args2); - // bytes memory input = abi.encode(randomNumber, randomBytes); - - // (bool success, bytes memory result) = address(0x1B).staticcall(input); - // require(success, "0x1B call failed"); - - // // Extract address from first 20 bytes of result and transfer - // address walletAddress = address(bytes20(result)); - // payable(walletAddress).transfer(25169190900000); - // } - - // function onDecrypt(bytes[] calldata decryptedArguments, bytes[] calldata plaintextArguments) public { - // delete decrypted; - // decrypted = new bytes[](decryptedArguments.length); - // for (uint i = 0; i < decryptedArguments.length; ++i) { - // decrypted[i] = decryptedArguments[i]; - // } - // delete plaintext; - // plaintext = new bytes[](plaintextArguments.length); - // for (uint i = 0; i < plaintextArguments.length; ++i) { - // plaintext[i] = plaintextArguments[i]; - // } - // uint256 gasAmount = abi.decode(plaintext[0], (uint256)); - // uint256 startGas = gasleft(); - // while (startGas - gasleft() < gasAmount && gasleft() > 50000) { - // plaintext.push(abi.encode(gasleft())); - // } - // return; - // } - - // function getDecrypted() public view returns (bytes[] memory) { - // return decrypted; - // } - - // function getPlaintext() public view returns (bytes[] memory) { - // return plaintext; - // } - // } - - std::string bytecode = "6080604052600167ffffffffffffffff81111561001f5761001e6101ad565b5b60405190808252806020026020018201604052801561005257816020015b606081526020019060019003908161003d5790505b50600090805190602001906100689291906100d3565b50600167ffffffffffffffff811115610084576100836101ad565b5b6040519080825280602002602001820160405280156100b757816020015b60608152602001906001900390816100a25790505b50600190805190602001906100cd9291906100d3565b506104cf565b82805482825590600052602060002090810192821561011b579160200282015b8281111561011a57825182908161010a91906103fd565b50916020019190600101906100f3565b5b509050610128919061012c565b5090565b5b8082111561014c57600081816101439190610150565b5060010161012d565b5090565b50805461015c90610216565b6000825580601f1061016e575061018d565b601f01602090049060005260206000209081019061018c9190610190565b5b50565b5b808211156101a9576000816000905550600101610191565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061022e57607f821691505b602082108103610241576102406101e7565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026102a97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261026c565b6102b3868361026c565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006102fa6102f56102f0846102cb565b6102d5565b6102cb565b9050919050565b6000819050919050565b610314836102df565b61032861032082610301565b848454610279565b825550505050565b600090565b61033d610330565b61034881848461030b565b505050565b5b8181101561036c57610361600082610335565b60018101905061034e565b5050565b601f8211156103b15761038281610247565b61038b8461025c565b8101602085101561039a578190505b6103ae6103a68561025c565b83018261034d565b50505b505050565b600082821c905092915050565b60006103d4600019846008026103b6565b1980831691505092915050565b60006103ed83836103c3565b9150826002028217905092915050565b610406826101dc565b67ffffffffffffffff81111561041f5761041e6101ad565b5b6104298254610216565b610434828285610370565b600060209050601f8311600181146104675760008415610455578287015190505b61045f85826103e1565b8655506104c7565b601f19841661047586610247565b60005b8281101561049d57848901518255600182019150602085019450602081019050610478565b868310156104ba57848901516104b6601f8916826103c3565b8355505b6001600288020188555050505b505050505050565b6116da806104de6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806338d5a312146100515780634c6f6c221461006f57806357983ac81461008b578063cc159120146100a7575b600080fd5b6100596100c5565b6040516100669190610a9a565b60405180910390f35b61008960048036038101906100849190610afc565b61019e565b005b6100a560048036038101906100a09190610b8e565b61046f565b005b6100af610774565b6040516100bc9190610a9a565b60405180910390f35b60606000805480602002602001604051908101604052809291908181526020016000905b8282101561019557838290600052602060002001805461010890610c3e565b80601f016020809104026020016040519081016040528092919081815260200182805461013490610c3e565b80156101815780601f1061015657610100808354040283529160200191610181565b820191906000526020600020905b81548152906001019060200180831161016457829003601f168201915b5050505050815260200190600101906100e9565b50505050905090565b6000620186a0826101af9190610c9e565b90506000600267ffffffffffffffff8111156101ce576101cd610cd2565b5b60405190808252806020026020018201604052801561020157816020015b60608152602001906001900390816101ec5790505b50905060405180610180016040528061015b81526020016113d561015b91398160008151811061023457610233610d01565b5b602002602001018190525060405180610180016040528061015b815260200161153061015b91398160018151811061026f5761026e610d01565b5b60200260200101819052506000600167ffffffffffffffff81111561029757610296610cd2565b5b6040519080825280602002602001820160405280156102ca57816020015b60608152602001906001900390816102b55790505b509050836040516020016102de9190610d3f565b6040516020818303038152906040528160008151811061030157610300610d01565b5b602002602001018190525060008282604051602001610321929190610d5a565b604051602081830303815290604052905060008482604051602001610347929190610ddb565b6040516020818303038152906040529050600080601b73ffffffffffffffffffffffffffffffffffffffff16836040516103819190610e47565b600060405180830381855afa9150503d80600081146103bc576040519150601f19603f3d011682016040523d82523d6000602084013e6103c1565b606091505b509150915081610406576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103fd90610ebb565b60405180910390fd5b60008161041290610f39565b60601c90508073ffffffffffffffffffffffffffffffffffffffff166108fc6516e428aed1209081150290604051600060405180830381858888f19350505050158015610463573d6000803e3d6000fd5b50505050505050505050565b60008061047c919061084d565b8383905067ffffffffffffffff81111561049957610498610cd2565b5b6040519080825280602002602001820160405280156104cc57816020015b60608152602001906001900390816104b75790505b50600090805190602001906104e292919061086e565b5060005b8484905081101561054d5784848281811061050457610503610d01565b5b90506020028101906105169190610faf565b6000838154811061052a57610529610d01565b5b9060005260206000200191826105419291906111bc565b508060010190506104e6565b506001600061055c919061084d565b8181905067ffffffffffffffff81111561057957610578610cd2565b5b6040519080825280602002602001820160405280156105ac57816020015b60608152602001906001900390816105975790505b50600190805190602001906105c292919061086e565b5060005b8282905081101561062d578282828181106105e4576105e3610d01565b5b90506020028101906105f69190610faf565b6001838154811061060a57610609610d01565b5b9060005260206000200191826106219291906111bc565b508060010190506105c6565b506000600160008154811061064557610644610d01565b5b90600052602060002001805461065a90610c3e565b80601f016020809104026020016040519081016040528092919081815260200182805461068690610c3e565b80156106d35780601f106106a8576101008083540402835291602001916106d3565b820191906000526020600020905b8154815290600101906020018083116106b657829003601f168201915b50505050508060200190518101906106eb91906112a1565b905060005a90505b815a8261070091906112ce565b10801561070e575061c3505a115b1561076c5760015a6040516020016107269190610d3f565b6040516020818303038152906040529080600181540180825580915050600190039060005260206000200160009091909190915090816107669190611302565b506106f3565b505050505050565b60606001805480602002602001604051908101604052809291908181526020016000905b828210156108445783829060005260206000200180546107b790610c3e565b80601f01602080910402602001604051908101604052809291908181526020018280546107e390610c3e565b80156108305780601f1061080557610100808354040283529160200191610830565b820191906000526020600020905b81548152906001019060200180831161081357829003601f168201915b505050505081526020019060010190610798565b50505050905090565b508054600082559060005260206000209081019061086b91906108c7565b50565b8280548282559060005260206000209081019282156108b6579160200282015b828111156108b55782518290816108a59190611302565b509160200191906001019061088e565b5b5090506108c391906108c7565b5090565b5b808211156108e757600081816108de91906108eb565b506001016108c8565b5090565b5080546108f790610c3e565b6000825580601f106109095750610928565b601f016020900490600052602060002090810190610927919061092b565b5b50565b5b8082111561094457600081600090555060010161092c565b5090565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60005b838110156109ae578082015181840152602081019050610993565b60008484015250505050565b6000601f19601f8301169050919050565b60006109d682610974565b6109e0818561097f565b93506109f0818560208601610990565b6109f9816109ba565b840191505092915050565b6000610a1083836109cb565b905092915050565b6000602082019050919050565b6000610a3082610948565b610a3a8185610953565b935083602082028501610a4c85610964565b8060005b85811015610a885784840389528151610a698582610a04565b9450610a7483610a18565b925060208a01995050600181019050610a50565b50829750879550505050505092915050565b60006020820190508181036000830152610ab48184610a25565b905092915050565b600080fd5b600080fd5b6000819050919050565b610ad981610ac6565b8114610ae457600080fd5b50565b600081359050610af681610ad0565b92915050565b600060208284031215610b1257610b11610abc565b5b6000610b2084828501610ae7565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f840112610b4e57610b4d610b29565b5b8235905067ffffffffffffffff811115610b6b57610b6a610b2e565b5b602083019150836020820283011115610b8757610b86610b33565b5b9250929050565b60008060008060408587031215610ba857610ba7610abc565b5b600085013567ffffffffffffffff811115610bc657610bc5610ac1565b5b610bd287828801610b38565b9450945050602085013567ffffffffffffffff811115610bf557610bf4610ac1565b5b610c0187828801610b38565b925092505092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680610c5657607f821691505b602082108103610c6957610c68610c0f565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610ca982610ac6565b9150610cb483610ac6565b9250828201905080821115610ccc57610ccb610c6f565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b610d3981610ac6565b82525050565b6000602082019050610d546000830184610d30565b92915050565b60006040820190508181036000830152610d748185610a25565b90508181036020830152610d888184610a25565b90509392505050565b600082825260208201905092915050565b6000610dad82610974565b610db78185610d91565b9350610dc7818560208601610990565b610dd0816109ba565b840191505092915050565b6000604082019050610df06000830185610d30565b8181036020830152610e028184610da2565b90509392505050565b600081905092915050565b6000610e2182610974565b610e2b8185610e0b565b9350610e3b818560208601610990565b80840191505092915050565b6000610e538284610e16565b915081905092915050565b600082825260208201905092915050565b7f307831422063616c6c206661696c656400000000000000000000000000000000600082015250565b6000610ea5601083610e5e565b9150610eb082610e6f565b602082019050919050565b60006020820190508181036000830152610ed481610e98565b9050919050565b6000819050602082019050919050565b60007fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b6000610f238251610eeb565b80915050919050565b600082821b905092915050565b6000610f4482610974565b82610f4e84610edb565b9050610f5981610f17565b92506014821015610f9957610f947fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083601403600802610f2c565b831692505b5050919050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112610fcc57610fcb610fa0565b5b80840192508235915067ffffffffffffffff821115610fee57610fed610fa5565b5b60208301925060018202360383131561100a57611009610faa565b5b509250929050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b6000600883026110727fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610f2c565b61107c8683610f2c565b95508019841693508086168417925050509392505050565b6000819050919050565b60006110b96110b46110af84610ac6565b611094565b610ac6565b9050919050565b6000819050919050565b6110d38361109e565b6110e76110df826110c0565b848454611042565b825550505050565b600090565b6110fc6110ef565b6111078184846110ca565b505050565b5b8181101561112b576111206000826110f4565b60018101905061110d565b5050565b601f821115611170576111418161101d565b61114a84611032565b81016020851015611159578190505b61116d61116585611032565b83018261110c565b50505b505050565b600082821c905092915050565b600061119360001984600802611175565b1980831691505092915050565b60006111ac8383611182565b9150826002028217905092915050565b6111c68383611012565b67ffffffffffffffff8111156111df576111de610cd2565b5b6111e98254610c3e565b6111f482828561112f565b6000601f8311600181146112235760008415611211578287013590505b61121b85826111a0565b865550611283565b601f1984166112318661101d565b60005b8281101561125957848901358255600182019150602085019450602081019050611234565b868310156112765784890135611272601f891682611182565b8355505b6001600288020188555050505b50505050505050565b60008151905061129b81610ad0565b92915050565b6000602082840312156112b7576112b6610abc565b5b60006112c58482850161128c565b91505092915050565b60006112d982610ac6565b91506112e483610ac6565b92508282039050818111156112fc576112fb610c6f565b5b92915050565b61130b82610974565b67ffffffffffffffff81111561132457611323610cd2565b5b61132e8254610c3e565b61133982828561112f565b600060209050601f83116001811461136c576000841561135a578287015190505b61136485826111a0565b8655506113cc565b601f19841661137a8661101d565b60005b828110156113a25784890151825560018201915060208501945060208101905061137d565b868310156113bf57848901516113bb601f891682611182565b8355505b6001600288020188555050505b50505050505056fef9015880b9015401cc5504bac92b5ccafa0c3202372d7bb0b8cb6861795deddafae0ed7be924ff170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006360e4a05b2e03056b2d61c7ad2deb47b0be0084ffab44bf506bfff07b951fb0bf37c171584f74d80c96306e124152458183a7a2c570a136099f7c4ffc9dde340cbed4f87133200fc4e425946925eaac958209aba78e190feeb5c9f31182ec8d458260279adb3976c158471b932bbee5bb320cf9015880b9015401154918854780593f1c6bf620684b29ab3d4c4a4f5996dcbd1c1d0b48c06d56b40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000751884c80374b7b5d6d0ef740dacbea91b3d53ee5243eeacf94a970f131185c69dfd44e868e370602c72484bc2f34e9466255ef50ca817d34d61a46bff368318b6fff300eb566dac8d1c569a270c6d9c1f99664643582cafcb276fea83d5564cd38f4b1be0e8ee6c06e10f10f10dc39120884a26469706673582212207709b91a00629c07db20a39f6c7636d35cc5abbd73e615e9843332b487d0f11664736f6c63781c302e382e33312d7072652e312b636f6d6d69742e6235393536366636004d"; - - // deploy contract - Json::Value create; - create["from"] = toJS( senderAddress ); - create["code"] = bytecode; - create["gas"] = "1800000"; - create["value"] = "10000000000000000000"; - create["nonce"] = 0; - string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - auto txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - std::string contractAddress = txReceipt["contractAddress"].asString(); - BOOST_REQUIRE( txReceipt["status"] == "0x1" ); - - fixture.rpcClient->debug_pauseConsensus( true ); - - // get block gas limit - dev::u256 blockGasLimit = fixture.client->blockInfo( fixture.client->number() ).gasLimit(); - - // send 2 submitCTXWithInput transactions in one block - // total gasLimit specified in the payload of these transactions should extend block gas limit - // gasUsed of these transactions corresponds to their gasLimit - // regular txns should not be processed until CTX queue is not empty - dev::u256 highGasLimit = (blockGasLimit * 90) / 100; - dev::bytes highGasLimitBytes = dev::toBigEndian( highGasLimit ); - - dev::u256 gasAmountForTx = highGasLimit; - - std::string calldata = "0x4c6f6c22" + dev::toHex( gasAmountForTx ); - - auto startBlockNumber = fixture.client->number(); - - // send a transaction -> BITE2 txn queue should become non-empty - Json::Value txGenerate; - txGenerate["to"] = contractAddress; - txGenerate["gas"] = "1000000"; - txGenerate["data"] = calldata; - txGenerate["from"] = toJS( senderAddress ); - txGenerate["nonce"] = 1; - fixture.rpcClient->eth_sendTransaction( txGenerate ); - - txGenerate["from"] = toJS( senderAddress ); - txGenerate["nonce"] = 2; - fixture.rpcClient->eth_sendTransaction( txGenerate ); - - fixture.rpcClient->debug_pauseConsensus( false ); - - // sleep 50 ms - enough for pendingTransactions() to complete - usleep( 50000 ); - - // stop again to freeze the following pending queue state: 2 CTXs + 1 regular txn - fixture.rpcClient->debug_pauseConsensus( true ); - - while ( fixture.client->number() != startBlockNumber + 1 ) - usleep( 10000 ); - - // sample regular txn - Json::Value txRefill; - txRefill["from"] = toJS( senderAddress ); - txRefill["to"] = "0xc868AF52a6549c773082A334E5AE232e0Ea3B513"; - txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txRefill["gas"] = 30000; - txRefill["nonce"] = 3; - fixture.rpcClient->eth_sendTransaction( txRefill ); - - fixture.rpcClient->debug_pauseConsensus( false ); - - // call mineTransaction to create a block - dev::eth::mineTransaction( *( fixture.client ), 2 ); - - // wait for 3 blocks to appear - auto endBlockNumber = fixture.client->number(); - BOOST_REQUIRE_EQUAL( endBlockNumber, startBlockNumber + 3 ); - - // check two last block - each should contain 1 CTX - // last block also contains a regular txn - auto beforeLastBlock = fixture.client->blockInfo( endBlockNumber - 1 ); - auto lastBlock = fixture.client->blockInfo( endBlockNumber ); - BOOST_REQUIRE_LT( lastBlock.gasUsed(), blockGasLimit ); - BOOST_REQUIRE_LT( beforeLastBlock.gasUsed(), blockGasLimit ); - - auto beforeLastBlockTxns = fixture.client->transactions( endBlockNumber - 1 ); - auto lastBlockTxns = fixture.client->transactions( endBlockNumber ); - BOOST_REQUIRE_EQUAL( beforeLastBlockTxns.size(), 1 ); - BOOST_REQUIRE( beforeLastBlockTxns[0].isCTX() ); - BOOST_REQUIRE_EQUAL( lastBlockTxns.size(), 2 ); - BOOST_REQUIRE( lastBlockTxns[0].isCTX() ); - BOOST_REQUIRE( !lastBlockTxns[1].isCTX() ); - - // check transactions status - auto txnHashes = fixture.client->transactionHashes( endBlockNumber - 1 ); - auto receipt = fixture.rpcClient->eth_getTransactionReceipt( "0x" + txnHashes[0].hex() ); - BOOST_REQUIRE( receipt["status"] == "0x1" ); - - txnHashes = fixture.client->transactionHashes( endBlockNumber ); - BOOST_REQUIRE_EQUAL( txnHashes.size(), 2 ); - for ( const auto& hash: txnHashes ) { - auto receipt = fixture.rpcClient->eth_getTransactionReceipt( "0x" + hash.hex() ); - BOOST_REQUIRE( receipt["status"] == "0x1" ); - } -} - -#endif // BITE - -#ifdef FAIR -BOOST_AUTO_TEST_CASE( getBLSPublicKey ) { - JsonRpcFixture fixture( c_BITEConfigString, false, false, true ); - - Json::Value blsPublicKey = fixture.rpcClient->skale_getBLSPublicKey(); - - BOOST_REQUIRE_EQUAL( blsPublicKey["BLSPublicKey0"], "15959969554621958245201075983340071881770733084910870228938077786643587385029" ); - BOOST_REQUIRE_EQUAL( blsPublicKey["BLSPublicKey1"], "7970122607051572307517094692346020360016825923464107614135327251488152616550" ); - BOOST_REQUIRE_EQUAL( blsPublicKey["BLSPublicKey2"], "3371162264373897025322009434717052197952692496405149486989861571246537813591" ); - BOOST_REQUIRE_EQUAL( blsPublicKey["BLSPublicKey3"], "13678625751515504401110635369790787716744686498431213713911601759809559919693" ); -} - -BOOST_AUTO_TEST_CASE( dencunOpcodesInConstructor ) { - JsonRpcFixture fixture( c_BITEConfigString, false, false, true ); - - // contract TLoadInConstructor { - - // constructor(uint256 _input) { - // assembly { - // let val := tload(0x0) - // sstore(0x0, val) - // } - // } - // } - - string compiled = "6080604052348015600e575f5ffd5b505f5c805f555060ac8060205f395ff3fe6080604052348015600e575f5ffd5b50600436106026575f3560e01c80636d619daa14602a575b5f5ffd5b60306044565b604051603b9190605f565b60405180910390f35b5f5481565b5f819050919050565b6059816049565b82525050565b5f60208201905060705f8301846052565b9291505056fea26469706673582212201a73df3522b78621c03ab2198ced2428e80055f4b32dc9b71881cb75acf3788e64736f6c634300081e0033"; - auto senderAddress = fixture.coinbase.address(); - - Json::Value create; - create["from"] = toJS( senderAddress ); - create["code"] = compiled; - create["gas"] = "900000"; - string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - try { - fixture.rpcClient->eth_estimateGas( create, "latest" ); - } catch ( jsonrpc::JsonRpcException& ex ) { - BOOST_CHECK_EQUAL( ex.GetCode(), 3 ); - BOOST_CHECK_EQUAL( ex.GetMessage(), "Contract uses unsupported Dencun opcode. Please ensure it is compiled for EVM <= Shanghai" ); - } - - auto txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE_EQUAL( txReceipt["status"].asString(), std::string( "0x0" ) ); - BOOST_REQUIRE_EQUAL( txReceipt["revertReason"].asString(), std::string( "Contract uses unsupported Dencun opcode. Please ensure it is compiled for EVM <= Shanghai" ) ); -} - -BOOST_AUTO_TEST_CASE( dencunOpcodesInTransaction ) { - JsonRpcFixture fixture( c_BITEConfigString, false, false, true ); - - // contract DencunContract { - // uint256 public storedValue; - - // function test(uint256 _input) external { - // assembly { - // tstore(0x0, _input) - - // let val := tload(0x0) - - // sstore(0x0, val) - // } - // } - - // function mcopyTest() public pure returns (uint256) { - // uint256[] memory source = new uint256[](3); - // source[0] = 10; - // source[1] = 20; - // source[2] = 30; - - // uint256[] memory destination = new uint256[](3); - - // assembly { - // let length := mul(3, 32) // 3 elements * 32 bytes each - - // mcopy(destination, add(source, 32), length) - // } - - // return destination[0]; - // } - // } - - string compiled = "6080604052348015600e575f5ffd5b506102f58061001c5f395ff3fe608060405234801561000f575f5ffd5b506004361061003f575f3560e01c806325c696111461004357806329e99f07146100615780636d619daa1461007d575b5f5ffd5b61004b61009b565b60405161005891906101f3565b60405180910390f35b61007b6004803603810190610076919061023a565b6101ca565b005b6100856101d6565b60405161009291906101f3565b60405180910390f35b5f5f600367ffffffffffffffff8111156100b8576100b7610265565b5b6040519080825280602002602001820160405280156100e65781602001602082028036833780820191505090505b509050600a815f815181106100fe576100fd610292565b5b6020026020010181815250506014816001815181106101205761011f610292565b5b602002602001018181525050601e8160028151811061014257610141610292565b5b6020026020010181815250505f600367ffffffffffffffff81111561016a57610169610265565b5b6040519080825280602002602001820160405280156101985781602001602082028036833780820191505090505b50905060206003028060208401835e50805f815181106101bb576101ba610292565b5b60200260200101519250505090565b805f5d5f5c805f555050565b5f5481565b5f819050919050565b6101ed816101db565b82525050565b5f6020820190506102065f8301846101e4565b92915050565b5f5ffd5b610219816101db565b8114610223575f5ffd5b50565b5f8135905061023481610210565b92915050565b5f6020828403121561024f5761024e61020c565b5b5f61025c84828501610226565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffdfea2646970667358221220879e6b5abbaea0d21b84075bdae00106284ac238ab5826f8e7e6519d744550b464736f6c634300081e0033"; - auto senderAddress = fixture.coinbase.address(); - - Json::Value create; - create["from"] = toJS( senderAddress ); - create["code"] = compiled; - create["gas"] = "900000"; - string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - auto txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - std::string contractAddress = txReceipt["contractAddress"].asString(); - - // Call DencunContract.test(111) - Json::Value sampleTx; - sampleTx["data"] = "0x29e99f07000000000000000000000000000000000000000000000000000000000000006f"; - sampleTx["to"] = contractAddress; - - try { - fixture.rpcClient->eth_estimateGas( sampleTx, "latest" ); - } catch ( jsonrpc::JsonRpcException& ex ) { - BOOST_CHECK_EQUAL( ex.GetCode(), 3 ); - BOOST_CHECK_EQUAL( ex.GetMessage(), "Contract uses unsupported Dencun opcode. Please ensure it is compiled for EVM <= Shanghai" ); - } - - try { - fixture.rpcClient->eth_call( sampleTx, "latest" ); - } catch ( jsonrpc::JsonRpcException& ex ) { - BOOST_CHECK_EQUAL( ex.GetCode(), 3 ); - BOOST_CHECK_EQUAL( ex.GetMessage(), "Contract uses unsupported Dencun opcode. Please ensure it is compiled for EVM <= Shanghai" ); - } - - txHash = fixture.rpcClient->eth_sendTransaction( sampleTx ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE_EQUAL( txReceipt["status"].asString(), std::string( "0x0" ) ); - BOOST_REQUIRE_EQUAL( txReceipt["revertReason"].asString(), std::string( "Contract uses unsupported Dencun opcode. Please ensure it is compiled for EVM <= Shanghai" ) ); - - // Call DencunContract.mcopyTest() - sampleTx["data"] = "0x25c69611"; - txHash = fixture.rpcClient->eth_sendTransaction( sampleTx ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE_EQUAL( txReceipt["status"].asString(), std::string( "0x0" ) ); - BOOST_REQUIRE_EQUAL( txReceipt["revertReason"].asString(), std::string( "Contract uses unsupported Dencun opcode. Please ensure it is compiled for EVM <= Shanghai" ) ); -} - -#endif // FAIR - -BOOST_AUTO_TEST_CASE( importInvalidBITETransaction ) { - JsonRpcFixture fixture( c_BITEConfigString, false, false, true, true ); - - dev::bite::isCiphertextValidationEnabled = true; - - string senderAddress = toJS( fixture.coinbase.address() ); - size_t nonce = 0; - std::string biteAddress = "0x" + std::string( BITE_ADDRESS_AS_STRING ); - - /// Normal valid BITE transaction -> should not throw - std::string message = - h256::random().hex() + std::string( "5EdF1e852fdD1B0Bc47C0307EF755C76f4B9c251" ); - auto messageBytes = libBLS::ThresholdUtils::hexCStringToBytes( message.c_str() ); - - auto biteInfo = fixture.rpcClient->bite_getCommitteesInfo(); - auto blsPublicKey = biteInfo[0]["commonBLSPublicKey"].asString(); - u256 epochId = biteInfo[0]["epochId"].asUInt64(); - - auto encryptedMessage = - libBLS::ThresholdEncryption::encrypt( messageBytes, libBLS::TEPublicKey( blsPublicKey, libBLS::Base::HEXA ) ); - auto encryptedBytes = encryptedMessage.toBytes(); - - auto dataField = formBITEPayloadRlp( epochId, encryptedBytes ); - - auto validBITETransactionRlp = - formTransactionRlp( fixture, senderAddress, dataField, nonce, biteAddress ); - BOOST_REQUIRE_NO_THROW( fixture.rpcClient->eth_sendRawTransaction( validBITETransactionRlp ) ); - - /// Spoiling the BITE address -> should not throw any excpetion because txn is not - /// BITE-formatted - auto spoiledBiteAddress = - libBLS::ThresholdUtils::hexCStringToBytes( std::string( BITE_ADDRESS_AS_STRING ).c_str() ); - size_t idxToSpoil = rand() % 20; - spoiledBiteAddress[idxToSpoil]++; - std::string spoiledBiteAddressHex = - libBLS::ThresholdUtils::bytesToHexString( spoiledBiteAddress ); - - auto validNonBITETransactionRlp = - formTransactionRlp( fixture, senderAddress, dataField, nonce, spoiledBiteAddressHex ); - BOOST_REQUIRE_NO_THROW( - fixture.rpcClient->eth_sendRawTransaction( validNonBITETransactionRlp ) ); - - /// Provide wrong epochId -> txn is not validated - should throw an exception - auto dataFieldWrongEpochId = formBITEPayloadRlp( epochId + 1, encryptedBytes ); - auto invalidBITETransactionRlp = - formTransactionRlp( fixture, senderAddress, dataFieldWrongEpochId, nonce, biteAddress ); - BOOST_REQUIRE_THROW( - fixture.client->importTransaction( Transaction( - dev::jsToBytes( invalidBITETransactionRlp ), CheckTransaction::None, false ) ), - dev::eth::InvalidBITETransaction ); - BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendRawTransaction( invalidBITETransactionRlp ), - jsonrpc::JsonRpcException ); - - /// No data in the data field -> data is bad formatted - should throw an exception - invalidBITETransactionRlp = - formTransactionRlp( fixture, senderAddress, "", nonce, biteAddress ); - BOOST_REQUIRE_THROW( - fixture.client->importTransaction( Transaction( - dev::jsToBytes( invalidBITETransactionRlp ), CheckTransaction::None, false ) ), - dev::eth::InvalidBITETransaction ); - BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendRawTransaction( invalidBITETransactionRlp ), - jsonrpc::JsonRpcException ); - - RLPStream tooShortRlp; - - /// Only epoch in data field -> data is too short - should throw an exception - tooShortRlp.appendList( 1 ); - tooShortRlp << epochId; - dev::bytes invalidTooShortBITETxnData = tooShortRlp.out(); - invalidBITETransactionRlp = - formTransactionRlp( fixture, senderAddress, - dev::toHexPrefixed( invalidTooShortBITETxnData ), nonce, biteAddress ); - BOOST_REQUIRE_THROW( - fixture.client->importTransaction( Transaction( - dev::jsToBytes( invalidBITETransactionRlp ), CheckTransaction::None, false ) ), - dev::eth::InvalidBITETransaction ); - BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendRawTransaction( invalidBITETransactionRlp ), - jsonrpc::JsonRpcException ); - tooShortRlp.clear(); - - /// Only epoch + key -> no data - should throw an exception - encryptedMessage.data = std::make_shared< dev::bytes >(); - tooShortRlp.appendList( 2 ); - tooShortRlp << epochId; - tooShortRlp << encryptedMessage.toBytes(); - invalidTooShortBITETxnData = tooShortRlp.out(); - invalidBITETransactionRlp = - formTransactionRlp( fixture, senderAddress, - dev::toHexPrefixed( invalidTooShortBITETxnData ), nonce, biteAddress ); - BOOST_REQUIRE_THROW( - fixture.client->importTransaction( Transaction( - dev::jsToBytes( invalidBITETransactionRlp ), CheckTransaction::None, false ) ), - dev::eth::BITETransactionTooShort ); - BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendRawTransaction( invalidBITETransactionRlp ), - jsonrpc::JsonRpcException ); - - /// Spoiling key part of ciphertext - auto randomEncryptedKeyObj = libBLS::CipheredKey::random(); - randomEncryptedKeyObj.V = encryptedMessage.keys[0].V; - auto randomEncryptedKeyByteArray = randomEncryptedKeyObj.toBytes(); - auto spoiledMessageBytes = encryptedBytes; - // overwrite key part - std::copy( randomEncryptedKeyByteArray.begin(), randomEncryptedKeyByteArray.end(), - spoiledMessageBytes.begin() ); - - RLPStream spoiledBITEDataRlp; - spoiledBITEDataRlp.appendList( 2 ); - spoiledBITEDataRlp << epochId; - spoiledBITEDataRlp << spoiledMessageBytes; - dev::bytes invalidBITETxnData = spoiledBITEDataRlp.out(); - - invalidBITETransactionRlp = - formTransactionRlp( fixture, senderAddress, - dev::toHexPrefixed( invalidBITETxnData ), nonce, biteAddress ); - BOOST_REQUIRE_THROW( - fixture.client->importTransaction( Transaction( - dev::jsToBytes( invalidBITETransactionRlp ), CheckTransaction::None, false ) ), - dev::eth::InvalidBITETransaction ); - BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendRawTransaction( invalidBITETransactionRlp ), - jsonrpc::JsonRpcException ); - spoiledBITEDataRlp.clear(); - - /// Encrypted key is not well formed -> should throw exception - randomEncryptedKeyObj.U.setXC0( libBLS::algebra::FqElement::random() ); - randomEncryptedKeyObj.W.setY( libBLS::algebra::FqElement::random() ); - randomEncryptedKeyByteArray = randomEncryptedKeyObj.toBytes(); - std::copy( randomEncryptedKeyByteArray.begin(), randomEncryptedKeyByteArray.end(), - spoiledMessageBytes.begin() ); - - spoiledBITEDataRlp.appendList( 2 ); - spoiledBITEDataRlp << epochId; - spoiledBITEDataRlp << spoiledMessageBytes; - invalidBITETxnData = spoiledBITEDataRlp.out(); - - invalidBITETransactionRlp = - formTransactionRlp( fixture, senderAddress, - dev::toHexPrefixed( invalidBITETxnData ), nonce, biteAddress ); - BOOST_REQUIRE_THROW( - fixture.client->importTransaction( Transaction( - dev::jsToBytes( invalidBITETransactionRlp ), CheckTransaction::None, false ) ), - dev::eth::InvalidBITETransaction ); - BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendRawTransaction( invalidBITETransactionRlp ), - jsonrpc::JsonRpcException ); - - // now send BITE txn with multiple epochIds / encryptedAESKeys - libBLS::TEPublicKey publicKey2 = libBLS::TEPublicKey::random(); - u256 epochId2 = epochId + 5; - - encryptedMessage = libBLS::ThresholdEncryption::encrypt( messageBytes, { libBLS::TEPublicKey( blsPublicKey, libBLS::Base::HEXA ), publicKey2 } ); - auto encryptedBITEDataBytes = encryptedMessage.toBytes(); - - // Create payload with 2 encrypted AES keys - RLPStream bitePayload; - bitePayload.appendList( 2 ); - bitePayload << epochId; - bitePayload << encryptedBITEDataBytes; - - auto rlpBytes = bitePayload.out(); - dev::bytes twoPayloadBITETxnData = dev::bytes( rlpBytes.begin(), rlpBytes.end() ); - - validBITETransactionRlp = - formTransactionRlp( fixture, senderAddress, - dev::toHexPrefixed( twoPayloadBITETxnData ), nonce, biteAddress ); - BOOST_REQUIRE_NO_THROW( fixture.rpcClient->eth_sendRawTransaction( validBITETransactionRlp ) ); - - // 3 elements in payload is not allowed - - RLPStream threeElementsPayload; - threeElementsPayload.appendList( 3 ); - threeElementsPayload << epochId; - threeElementsPayload << epochId2; - threeElementsPayload << encryptedBITEDataBytes; - - auto threeElementsRlpBytes = threeElementsPayload.out(); - dev::bytes threeElementsBITETxnData = dev::bytes( threeElementsRlpBytes.begin(), - threeElementsRlpBytes.end() ); - - std::string threeElementsBITETxnRlp = - formTransactionRlp( fixture, senderAddress, - dev::toHexPrefixed( threeElementsBITETxnData ), nonce, biteAddress ); - BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendRawTransaction( threeElementsBITETxnRlp ), - jsonrpc::JsonRpcException ); - - // epochId doesn't match and only 1 encrypted AES keys - libBLS::TEPublicKey publicKey3 = libBLS::TEPublicKey::random(); - - auto encryptedMessage1Key = libBLS::ThresholdEncryption::encrypt( messageBytes, publicKey3 ); - auto encryptedBITEDataBytes1Key = encryptedMessage1Key.toBytes(); - - RLPStream mismatchPayload; - mismatchPayload.appendList( 2 ); - mismatchPayload << epochId2; - mismatchPayload << encryptedBITEDataBytes1Key; - - auto mismatchRlpBytes = mismatchPayload.out(); - dev::bytes mismatchBITETxnData = dev::bytes( mismatchRlpBytes.begin(), mismatchRlpBytes.end() ); - - std::string mismatchBITETxnRlp = - formTransactionRlp( fixture, senderAddress, - dev::toHexPrefixed( mismatchBITETxnData ), nonce, biteAddress ); - BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendRawTransaction( mismatchBITETxnRlp ), - jsonrpc::JsonRpcException ); - - // 2 encrypted AES keys submitted, but one key is corrupt - auto corruptEncryptedMessage = libBLS::ThresholdEncryption::encrypt( messageBytes, { libBLS::TEPublicKey( blsPublicKey, libBLS::Base::HEXA ), publicKey2 } ); - - // Corrupt the first key by replacing it with a random one - corruptEncryptedMessage.keys[0] = libBLS::CipheredKey( - libBLS::algebra::G2Point::random(), - corruptEncryptedMessage.keys[0].V, - libBLS::algebra::G1Point::random() - ); - - auto corruptEncryptedBITEDataBytes = corruptEncryptedMessage.toBytes(); - - RLPStream corruptPayload; - corruptPayload.appendList( 2 ); - corruptPayload << epochId; - corruptPayload << corruptEncryptedBITEDataBytes; - - auto corruptRlpBytes = corruptPayload.out(); - dev::bytes corruptBITETxnData = dev::bytes( corruptRlpBytes.begin(), corruptRlpBytes.end() ); - - std::string corruptBITETxnRlp = - formTransactionRlp( fixture, senderAddress, - dev::toHexPrefixed( corruptBITETxnData ), nonce, biteAddress ); - BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendRawTransaction( corruptBITETxnRlp ), - jsonrpc::JsonRpcException ); -} - -BOOST_AUTO_TEST_CASE( BITETransactionCouldNotBeDecrypted ) { - JsonRpcFixture fixture( c_BITEConfigString, false, false, true, true ); - - string senderAddress = toJS( fixture.coinbase.address() ); - - // address 0x7aa5e36aa15e93d10f4f26357c30f052dacdde5f is preset in config - auto balanceBefore = - fixture.rpcClient->eth_getBalance( "0x7aa5e36aa15e93d10f4f26357c30f052dacdde5f", "latest" ); - auto balanceBeforeU256 = dev::jsToU256( balanceBefore ); - BOOST_REQUIRE( - balanceBeforeU256 == dev::u256( dev::bigint( "1000000000000000000000000000000" ) ) ); - - // data must have the destination address and the original message - RLPStream biteDataRlp( 2 ); - biteDataRlp << ( dev::h256::Arith ) h256::random(); - biteDataRlp << ( dev::Address::Arith ) dev::Address( "0x7aa5e36aa15e93d10f4f26357c30f052dacdde5f" ); - - auto messageBytes = biteDataRlp.out(); - - auto biteInfo = fixture.rpcClient->bite_getCommitteesInfo(); - auto blsPublicKey = biteInfo[0]["commonBLSPublicKey"].asString(); - u256 epochId = biteInfo[0]["epochId"].asUInt64(); - - auto ciphertext = - libBLS::ThresholdEncryption::encrypt( messageBytes, libBLS::TEPublicKey( blsPublicKey, libBLS::Base::HEXA ) ); - auto ciphertextBytes = ciphertext.toBytes(); - - // spoil random element in decryptedData - // only tamper the data part - // | -- Number of keys --| | --- KEY ---- | | --- Data - tamper this part ----| - size_t idxToSpoil = - 1 + libBLS::CipheredKey::CIPHERED_KEY_SIZE_BYTES + - rand() % ( ciphertextBytes.size() - libBLS::CipheredKey::CIPHERED_KEY_SIZE_BYTES ); - ciphertextBytes[idxToSpoil]++; - - auto invalidEncryptedData = libBLS::ThresholdUtils::bytesToHexString( ciphertextBytes ); - - size_t nonce = 0; - - RLPStream bitePayloadRlp( 2 ); - - bitePayloadRlp << epochId; - bitePayloadRlp << ciphertextBytes; - - auto rlpBytes = bitePayloadRlp.out(); - std::string biteAddress = "0x" + std::string( BITE_ADDRESS_AS_STRING ); - std::string txnRlp = formTransactionRlp( - fixture, "0x7aa5e36aa15e93d10f4f26357c30f052dacdde5f", dev::toHexPrefixed( rlpBytes ), - nonce, biteAddress ); - - Transaction t( dev::fromHex( txnRlp ), dev::eth::CheckTransaction::None ); - auto minGasRequired = t.baseGasRequired( fixture.client->evmSchedule() ); - - auto gasPrice = fixture.rpcClient->eth_gasPrice(); - auto invalidTxnHash = fixture.rpcClient->eth_sendRawTransaction( txnRlp ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - auto balanceAfter = - fixture.rpcClient->eth_getBalance( "0x7aa5e36aa15e93d10f4f26357c30f052dacdde5f", "latest" ); - BOOST_REQUIRE_EQUAL( balanceAfter, - dev::toJS( balanceBeforeU256 - minGasRequired * dev::jsToU256( gasPrice ) ) ); - - try { - fixture.rpcClient->bite_getDecryptedTransactionData( invalidTxnHash ); - } catch ( const jsonrpc::JsonRpcException& ex ) { - std::string errorMessage = - "Transaction with provided hash does not have any decrypted data associated with it."; - BOOST_REQUIRE( ex.what() == errorMessage ); - } - - auto receipt = fixture.rpcClient->eth_getTransactionReceipt( invalidTxnHash ); - BOOST_REQUIRE( - receipt["revertReason"] == std::string( "Could not decrypt BITE transaction." ) ); -} - - -BOOST_AUTO_TEST_CASE( getDecryptedTransactionData ) { - std::string _config = c_genesisConfigString; - Json::Value ret; - Json::Reader().parse( _config, ret ); - // enable type1 & type2 txs - ret["skaleConfig"]["sChain"]["EIP1559TransactionsPatchTimestamp"] = 1; - // Set chainID = 151 - std::string chainID = "0x97"; - ret["params"]["chainID"] = chainID; -#ifndef FAIR - // set contractStorageLimit - ret["skaleConfig"]["sChain"]["contractStorageLimit"] = 1000000; -#endif - - Json::FastWriter fastWriter; - std::string config = fastWriter.write( ret ); - JsonRpcFixture fixture( config, true, true, false, false, false, -1, {{ "contractStorageLimit", "1000000" }} ); - - dev::eth::simulateMining( *( fixture.client ), 20 ); - string senderAddress = toJS( fixture.coinbase.address() ); - - int nonce = 0; - - // ---- Legacy ----- - Json::Value legacyTx; - - dev::Address originalToAddress( "0x5edf1e852fdd1b0bc47c0307ef755c76f4b9c251" ); - std::string plaintext = - "0x6057361d0000000000000000000000000000000000000000000000000000000000000001"; - std::string encryptedDataPlusToAddressLegacy = dev::toHexPrefixed( - formEncryptedMessageMockup( dev::fromHex( plaintext ), originalToAddress ) ); - - // signal BITE tx - legacyTx["to"] = toJS( "0x" + std::string( BITE_ADDRESS_AS_STRING ) ); - legacyTx["from"] = senderAddress; - legacyTx["gas"] = "100000"; - legacyTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - legacyTx["value"] = "20000000000000000000"; // send all fixture.coinbase.address() balance to - // cover for next calls - legacyTx["data"] = encryptedDataPlusToAddressLegacy; - legacyTx["nonce"] = nonce++; - - TransactionSkeleton legacyTs = toTransactionSkeleton( legacyTx ); - legacyTs = fixture.client->populateTransactionWithDefaults( legacyTs ); - pair< bool, Secret > legacyAr = fixture.accountHolder->authenticate( legacyTs ); - Transaction legacyTransaction( legacyTs, legacyAr.second ); - - std::string legacyRLP = dev::toHexPrefixed( legacyTransaction.toBytes() ); - std::string legacyHash = fixture.rpcClient->eth_sendRawTransaction( legacyRLP ); - - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - auto legacyTxReceipt = fixture.rpcClient->eth_getTransactionReceipt( legacyHash ); - BOOST_REQUIRE( legacyTxReceipt["status"].asString() == std::string( "0x1" ) ); - BOOST_REQUIRE( - legacyTxReceipt["blockNumber"].asString() == fixture.rpcClient->eth_blockNumber() ); - BOOST_REQUIRE( legacyTxReceipt["to"].asString() == "0x" + originalToAddress.hex() ); - - auto legacyEncryptedResponse = fixture.rpcClient->eth_getTransactionByHash( legacyHash ); - BOOST_REQUIRE( - legacyEncryptedResponse["input"].asString() == encryptedDataPlusToAddressLegacy ); - - auto legacyDecryptedResponse = - fixture.rpcClient->bite_getDecryptedTransactionData( legacyHash ); - BOOST_REQUIRE( legacyDecryptedResponse["data"] == plaintext ); - BOOST_REQUIRE( legacyDecryptedResponse["to"] == "0x" + originalToAddress.hex() ); - - // ---- Type1 tx ----- - /* - transaction1['nonce'] = 0 - transaction1['gasPrice'] = 20000000000 - transaction1['gas'] = 80000 - transaction1['to'] = 0xc868af52a6549c773082a334e5ae232e0ea3b513 - transaction1['value'] = 0 - transaction1['chainId'] = 151 - transaction1['type'] = 1 - transaction1['data'] = call to SC - */ - std::string originalToAddressType1 = "c868af52a6549c773082a334e5ae232e0ea3b513"; - // data ciphered from a single run of formEncryptedMessageMockup( plaintext, originalToAddress ) - // since it differs each run, and the RLP-encoded tx was built outside this test case (via an - // external script), we need to set this manually Note that the encryptedData includes the 'To' - // address already - std::string encryptedDataPlusToAddressType1 = "0xf9015d80b901590192084354e0f043e108c255d159de7360e5a972bacdbaf3257420f66478d79b930000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005b87049973afc70916c3588f2e5bcdd65acdc73f544d201979b4ce8307815fda7281e032402b0e1d82ccc830046e5de0c7a2e8f9fd4ea6dcd9e85230a5f278373f5c873b1ed1bae995c74899927c92b8e2b41af3adfba46def6b857a4e74b7595e2bb9c84773ba4a1167fc73bd17ca65334d12eaf9401897"; - std::string type1Tx = "0x01f901ca8197808504a817c800830138809442495445204d452049274d20454e43525950544480b90160f9015d80b901590192084354e0f043e108c255d159de7360e5a972bacdbaf3257420f66478d79b930000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005b87049973afc70916c3588f2e5bcdd65acdc73f544d201979b4ce8307815fda7281e032402b0e1d82ccc830046e5de0c7a2e8f9fd4ea6dcd9e85230a5f278373f5c873b1ed1bae995c74899927c92b8e2b41af3adfba46def6b857a4e74b7595e2bb9c84773ba4a1167fc73bd17ca65334d12eaf9401897c001a05b144ba5643c7ff31cfefdeaf4043e222c0c32f5c849c21598f89e82abdea07fa048762844d57807403777d655dec566230266759e173c187e4cecebfa4579ea66"; - - std::string type1Hash = fixture.rpcClient->eth_sendRawTransaction( type1Tx ); - - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - auto type1TxReceipt = fixture.rpcClient->eth_getTransactionReceipt( type1Hash ); - BOOST_REQUIRE( type1TxReceipt["status"].asString() == std::string( "0x1" ) ); - BOOST_REQUIRE( - type1TxReceipt["blockNumber"].asString() == fixture.rpcClient->eth_blockNumber() ); - BOOST_REQUIRE( type1TxReceipt["to"].asString() == "0x" + originalToAddressType1 ); - - auto type1EncryptedResponse = fixture.rpcClient->eth_getTransactionByHash( type1Hash ); - BOOST_REQUIRE( type1EncryptedResponse["input"].asString() == encryptedDataPlusToAddressType1 ); - - auto type1DecryptedResponse = fixture.rpcClient->bite_getDecryptedTransactionData( type1Hash ); - BOOST_REQUIRE( type1DecryptedResponse["data"] == plaintext ); - BOOST_REQUIRE( type1DecryptedResponse["to"] == "0x" + originalToAddressType1 ); - - // ---- Type2 tx ----- - /* - transaction1['nonce'] = 1 - transaction1['gas'] = 80000 - transaction1['maxFeePerGas'] = 20000000000 - transaction1['maxPriorityFeePerGas'] = 20000000000 - 1 - transaction1['to'] = 0xc868AF52a6549c773082A334E5AE232e0Ea3B513 - transaction1['value'] = 0 - transaction1['chainId'] = 151 - transaction1['type'] = 2 - transaction1['data'] = encryptedData - */ - - std::string originalToAddressType2 = originalToAddressType1; - std::string encryptedDataPlusToAddressType2 = encryptedDataPlusToAddressType1; - std::string type2Tx = "0x02f901d08197018504a817c7ff8504a817c800830138809442495445204d452049274d20454e43525950544480b90160f9015d80b901590192084354e0f043e108c255d159de7360e5a972bacdbaf3257420f66478d79b930000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005b87049973afc70916c3588f2e5bcdd65acdc73f544d201979b4ce8307815fda7281e032402b0e1d82ccc830046e5de0c7a2e8f9fd4ea6dcd9e85230a5f278373f5c873b1ed1bae995c74899927c92b8e2b41af3adfba46def6b857a4e74b7595e2bb9c84773ba4a1167fc73bd17ca65334d12eaf9401897c080a0c8512955420b554abcde1ea13d67bef9a38bf541938a8b915c514722821481f2a03f3ca19e2513078f058462c622bd07ea0b6f15b5bc28998bcc79c59c3c0400db"; - std::string type2Hash = fixture.rpcClient->eth_sendRawTransaction( type2Tx ); - - - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - auto type2TxReceipt = fixture.rpcClient->eth_getTransactionReceipt( type2Hash ); - BOOST_REQUIRE( type2TxReceipt["status"].asString() == std::string( "0x1" ) ); - BOOST_REQUIRE( - type2TxReceipt["blockNumber"].asString() == fixture.rpcClient->eth_blockNumber() ); - BOOST_REQUIRE( type2TxReceipt["to"].asString() == "0x" + originalToAddressType2 ); - - auto type2EncryptedResponse = fixture.rpcClient->eth_getTransactionByHash( type2Hash ); - BOOST_REQUIRE( type2EncryptedResponse["input"].asString() == encryptedDataPlusToAddressType2 ); - - auto type2DecryptedResponse = fixture.rpcClient->bite_getDecryptedTransactionData( type2Hash ); - BOOST_REQUIRE( type2DecryptedResponse["data"] == plaintext ); - BOOST_REQUIRE( type2DecryptedResponse["to"] == "0x" + originalToAddressType2 ); - - - // pragma solidity >=0.8.2 <0.9.0; - - // /** - // * @title Storage - // * @dev Store & retrieve value in a variable - // * @custom:dev-run-script ./scripts/deploy_with_ethers.ts - // */ - // contract Storage { - - // uint256 number; - // uint256 number1; - // uint256 number2; - - // /** - // * @dev Store value in variable - // * @param num value to store - // */ - // function store(uint256 num) public { - // number = num; - // number1 = num; - // number2 = num; - // } - - // /** - // * @dev Return value - // * @return value of 'number' - // */ - // function retrieve() public view returns (uint256){ - // return number; - // } - // } - string bytecode = - "608060405234801561001057600080fd5b50610155806100206000396000f3fe60806040523" - "4801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b57" - "80636057361d14610059575b600080fd5b610043610075565b60405161005091906100e3565" - "b60405180910390f35b610073600480360381019061006e91906100ab565b61007e565b005b" - "60008054905090565b80600081905550806001819055508060028190555050565b600081359" - "0506100a581610108565b92915050565b6000602082840312156100bd57600080fd5b600061" - "00cb84828501610096565b91505092915050565b6100dd816100fe565b82525050565b60006" - "020820190506100f860008301846100d4565b92915050565b6000819050919050565b610111" - "816100fe565b811461011c57600080fd5b5056fea2646970667358221220edbb1123b5e4538" - "463747d4497720f4c0b79ff718b7bf245e6ba81dc37dc1a0364736f6c63430008040033"; - - Json::Value create; - create["from"] = toJS( senderAddress ); - create["data"] = bytecode; // SC creation goes in plaintext - create["gas"] = "180000"; - std::string txHash = fixture.rpcClient->eth_sendTransaction( create ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); - - std::string contractAddress = receipt["contractAddress"].asString(); - std::string contractAddressWithout0x = contractAddress.substr( 2 ); - - // verify state is empty - Json::Value call; - call["to"] = contractAddress; - call["data"] = "0x2e64cec1"; - call["from"] = toJS( senderAddress ); - BOOST_REQUIRE( u256( 0 ) == dev::jsToU256( fixture.rpcClient->eth_call( call, "latest" ) ) ); - - string dataStore1 = "6057361d0000000000000000000000000000000000000000000000000000000000000001"; - string dataStoreInvalid = - "6057361e0000000000000000000000000000000000000000000000000000000000000001"; - - // send txn to change state - Json::Value store1; - store1["to"] = toJS( "0x" + std::string( BITE_ADDRESS_AS_STRING ) ); - store1["data"] = dev::toHexPrefixed( formEncryptedMessageMockup( dev::fromHex( dataStore1 ), dev::Address( contractAddressWithout0x ) ) ); - store1["from"] = toJS( senderAddress ); - store1["gasPrice"] = fixture.rpcClient->eth_gasPrice(); -#ifdef FAIR - store1["gas"] = "200000"; // EIP-2929: need more gas for cold access costs -#else - store1["gas"] = "111000"; -#endif - txHash = fixture.rpcClient->eth_sendTransaction( store1 ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( receipt["status"] == std::string( "0x1" ) ); - - // check that previous txn changed the state - call["to"] = contractAddress; - call["data"] = "0x2e64cec1"; - call["from"] = toJS( senderAddress ); - BOOST_REQUIRE( u256( 1 ) == dev::jsToU256( fixture.rpcClient->eth_call( call, "latest" ) ) ); - - // send invalid call to the contract - txn should fail - Json::Value txInvalidContractCall; - txInvalidContractCall["to"] = toJS( "0x" + std::string( BITE_ADDRESS_AS_STRING ) ); - txInvalidContractCall["data"] = dev::toHexPrefixed( formEncryptedMessageMockup( dev::fromHex( dataStoreInvalid ), dev::Address( contractAddressWithout0x ) ) ); - txInvalidContractCall["from"] = toJS( senderAddress ); - txInvalidContractCall["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txHash = fixture.rpcClient->eth_sendTransaction( txInvalidContractCall ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( receipt["status"] == std::string( "0x0" ) ); -} - -#ifdef FAIR -BOOST_AUTO_TEST_CASE( committeeRotation ) { - std::string _config = c_BITECommitteeRotationConfigString; - Json::Value ret; - Json::Reader().parse( _config, ret ); - - auto firstGroupObject = ret["skaleConfig"]["sChain"]["nodes"]["1"]; - auto secondGroupObject = ret["skaleConfig"]["sChain"]["nodes"]["-1"]; - - std::array< std::string, 4 > firstGroupCommonPublicKey; - firstGroupCommonPublicKey[0] = firstGroupObject["blsKey"]["commonBLSPublicKey0"].asString(); - firstGroupCommonPublicKey[1] = firstGroupObject["blsKey"]["commonBLSPublicKey1"].asString(); - firstGroupCommonPublicKey[2] = firstGroupObject["blsKey"]["commonBLSPublicKey2"].asString(); - firstGroupCommonPublicKey[3] = firstGroupObject["blsKey"]["commonBLSPublicKey3"].asString(); - - std::array< std::string, 4 > secondGroupCommonPublicKey; - secondGroupCommonPublicKey[0] = secondGroupObject["blsKey"]["commonBLSPublicKey0"].asString(); - secondGroupCommonPublicKey[1] = secondGroupObject["blsKey"]["commonBLSPublicKey1"].asString(); - secondGroupCommonPublicKey[2] = secondGroupObject["blsKey"]["commonBLSPublicKey2"].asString(); - secondGroupCommonPublicKey[3] = secondGroupObject["blsKey"]["commonBLSPublicKey3"].asString(); - - BOOST_REQUIRE( firstGroupCommonPublicKey != secondGroupCommonPublicKey ); - - ret["skaleConfig"]["sChain"]["nodes"].clear(); - - auto currentTime = time( nullptr ); - auto firstGroupTs = currentTime; - auto secondGroupTs = firstGroupTs + 10; - - ret["skaleConfig"]["sChain"]["nodes"][std::to_string( firstGroupTs )] = firstGroupObject; - ret["skaleConfig"]["sChain"]["nodes"][std::to_string( secondGroupTs )] = secondGroupObject; - - ret["skaleConfig"]["sChain"]["nodeGroups"]["0"]["finish_ts"] = secondGroupTs; - - auto blsPublicKeyStringToStringArray = [](const std::string& publicKeyStr) { - libBLS::TEPublicKey publicKey( publicKeyStr, libBLS::Base::HEXA ); - auto rawPublicKey = publicKey.getPublicKeyRaw(); - return rawPublicKey.toStringArray( libBLS::Base::DEC ); - }; - - Json::FastWriter fastWriter; - std::string config = fastWriter.write( ret ); - JsonRpcFixture fixture( config, false, false, true ); - - Json::Value txRefill; - txRefill["to"] = "0xc868AF52a6549c773082A334E5AE232e0Ea3B513"; - txRefill["from"] = toJS( fixture.coinbase.address() ); - txRefill["gas"] = "100000"; - txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - txRefill["value"] = 100000000000000000; - string txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - auto receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( receipt["status"] == std::string( "0x1" ) ); - - auto latestBlockTs = fixture.client->blockChain().info().timestamp(); - BOOST_REQUIRE( latestBlockTs < secondGroupTs && latestBlockTs > firstGroupTs ); - BOOST_REQUIRE( fixture.client->chainParams().getCommonBlsPublicKey() == firstGroupCommonPublicKey ); - BOOST_REQUIRE( fixture.client->isCommitteeRotationSoon() ); - - auto biteInfo = fixture.rpcClient->bite_getCommitteesInfo(); - BOOST_REQUIRE( biteInfo.isArray() ); - BOOST_REQUIRE_EQUAL( biteInfo.size(), 2 ); - BOOST_REQUIRE( blsPublicKeyStringToStringArray( biteInfo[0]["commonBLSPublicKey"].asString() ) == firstGroupCommonPublicKey ); - BOOST_REQUIRE_EQUAL( biteInfo[0]["epochId"].asUInt64(), 0 ); - BOOST_REQUIRE( blsPublicKeyStringToStringArray( biteInfo[1]["commonBLSPublicKey"].asString() ) == secondGroupCommonPublicKey ); - BOOST_REQUIRE_EQUAL( biteInfo[1]["epochId"].asUInt64(), 1 ); - - while ( latestBlockTs++ < secondGroupTs ) - sleep( 1 ); - - txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( receipt["status"] == std::string( "0x1" ) ); - - BOOST_REQUIRE( latestBlockTs >= secondGroupTs ); - BOOST_REQUIRE( fixture.client->chainParams().getCommonBlsPublicKey() == secondGroupCommonPublicKey ); - - biteInfo = fixture.rpcClient->bite_getCommitteesInfo(); - BOOST_REQUIRE_EQUAL( biteInfo.size(), 1 ); - BOOST_REQUIRE( blsPublicKeyStringToStringArray( biteInfo[0]["commonBLSPublicKey"].asString() ) == secondGroupCommonPublicKey ); - BOOST_REQUIRE_EQUAL( biteInfo[0]["epochId"].asUInt64(), 1 ); - BOOST_REQUIRE( !fixture.client->isCommitteeRotationSoon() ); - - // HACK: currently on committee rotation skaled calls exitGracefully in consensus - // it interferes with exit procedure - // put sleep here to avoid collisions - sleep( 10 ); - - txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE( receipt["status"] == std::string( "0x1" ) ); -} - - -BOOST_AUTO_TEST_CASE( fetchingBlockRewardBeneficiary ) { - std::string config = c_BITECommitteeRotationConfigString; - Json::Value ret; - Json::Reader().parse( config, ret ); - - Json::FastWriter fastWriter; - config = fastWriter.write( ret ); - JsonRpcFixture fixture( config, false, false, true ); - - Address rewardWalletAddress = fixture.client->chainParams().getNodeBeneficiaryInHistoricGroup( 0, 1 ); - BOOST_REQUIRE( rewardWalletAddress == Address( "0x08151B8F80bfa7dEa760e461412AF24348224edf" ) ); - rewardWalletAddress = fixture.client->chainParams().getNodeBeneficiaryInHistoricGroup( 1, 1 ); - BOOST_REQUIRE( rewardWalletAddress == Address( "0x405c96D388cDFBa4f17493c875CCE9c680225276" ) ); -} - -BOOST_AUTO_TEST_CASE( block_author_balance ) { - // when rewardWalletAddress is not defined - - // for testBlockRewardsActivationPatchAddress - setenv( "TEST_BLOCK_REWARDS_ACTIVATION", "1", 1 ); - - std::string _config = c_genesisConfigString; - Json::Value ret; - Json::Reader().parse( _config, ret ); - // Set FAIR chainID - std::string chainID = "0x3a6"; - ret["params"]["chainID"] = chainID; - // disable block rewards at startup - ret["params"]["blockReward"] = "0x00"; - - Json::FastWriter fastWriter; - std::string config = fastWriter.write( ret ); - JsonRpcFixture fixture( config, false, false, true ); - - string etherbase = fixture.rpcClient->eth_coinbase(); - - BOOST_REQUIRE( !BlockRewardsActivationPatch::isEnabled( fixture.client->chainId() ) ); - - // checksumed address: 0x0E7d7F1D34a502bD609542576941C3FCc087c588 - auto node_owner = "0x0e7d7f1d34a502bd609542576941c3fcc087c588"; - - auto etherbase_address = jsToAddress( etherbase ); - - u256 etherbaseBalance = fixture.client->balanceAt( etherbase_address ); - BOOST_REQUIRE_EQUAL( etherbaseBalance, 0 ); - - dev::Address stakingContractAddress = fixture.client->chainParams().getStakingContractAddress(); - BOOST_REQUIRE_EQUAL( fixture.client->balanceAt( stakingContractAddress ), 0 ); - - // mine transaction not from testBlockRewardsActivationPatchAddress - block rewards should stay disabled - Json::Value silentTx; - silentTx["value"] = 1; - // address has preset balance in config - // silentTx["from"] = dev::Address( "0x5C4e11842E8be09264dc1976943571d7Af6d00F9" ).hex(); - silentTx["to"] = BlockRewardsActivationPatch::getMagicAddress().hex(); - silentTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - silentTx["gas"] = 30000; - silentTx["nonce"] = 0; - - auto silentTs = toTransactionSkeleton( silentTx ); - auto silentT = dev::eth::Transaction( - silentTs, dev::Secret( "1c2cd4b70c2b8c6cd7144bbbfbd1e5c6eacb4a5efd9c86d0e29cbbec4e8483b9" ) ); - - std::string txHash = fixture.rpcClient->eth_sendRawTransaction( dev::toHex( silentT.toBytes() ) ); - BOOST_REQUIRE( !txHash.empty() ); - - dev::eth::mineTransaction( *( fixture.client ), 1 ); - BOOST_REQUIRE( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"] == "0x1" ); - BOOST_REQUIRE( !BlockRewardsActivationPatch::isEnabled( fixture.client->chainId() ) ); - // staking contract balance only gets changed when block rewards are activated - BOOST_REQUIRE_EQUAL( fixture.client->balanceAt( stakingContractAddress ), 0 ); - etherbaseBalance = fixture.client->balanceAt( etherbase_address ); - BOOST_REQUIRE_EQUAL( etherbaseBalance, 0 ); - - // mine transaction from testBlockRewardsActivationPatchAddress - block rewards should enable - Json::Value activationTx; - // activationTx["from"] = "0x5339Ef05428d1b87f4e2F2db64E782c68E9cDA56"; - activationTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - activationTx["gas"] = 30000; - activationTx["chainId"] = "0x3a9"; - activationTx["nonce"] = 0; - activationTx["to"] = dev::Address::random().hex(); - - auto ts = toTransactionSkeleton( activationTx ); - auto t = dev::eth::Transaction( - ts, dev::Secret( "0e394ff21db60660a27a6383aedf8c75070648965acbef7c369c1bae2141a485" ) ); - - txHash = fixture.rpcClient->eth_sendRawTransaction( dev::toHex( t.toBytes() ) ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - BOOST_REQUIRE( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"] == "0x1" ); - BOOST_REQUIRE( BlockRewardsActivationPatch::isEnabled( fixture.client->chainId() ) ); - etherbaseBalance = fixture.client->balanceAt( etherbase_address ); - BOOST_REQUIRE_EQUAL( etherbaseBalance, 0 ); - BOOST_REQUIRE_EQUAL( fixture.client->balanceAt( stakingContractAddress ), 0 ); - - etherbaseBalance = fixture.client->balanceAt( jsToAddress( etherbase ) ); - - auto authorInitialBalance = fixture.client->balanceAt( jsToAddress( "0x0E7d7F1D34a502bD609542576941C3FCc087c588" ) ); - auto stakingContractInitialBalance = fixture.client->balanceAt( stakingContractAddress ); - - auto initialBlockNumber = jsToU256( fixture.rpcClient->eth_blockNumber() ); - - // push random transaction, check balance difference - Json::Value sampleTx; - sampleTx["value"] = 1000000; - sampleTx["data"] = toJS( bytes() ); - sampleTx["from"] = fixture.coinbase.address().hex(); - sampleTx["to"] = fixture.account2.address().hex(); - sampleTx["gasPrice"] = 1000000000000; - txHash = fixture.rpcClient->eth_sendTransaction( sampleTx ); - BOOST_REQUIRE( !txHash.empty() ); - - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - fixture.client->state().getOriginalDb()->createBlockSnap( 2 ); - BOOST_REQUIRE_EQUAL( fixture.client->balanceAt( fixture.account2.address() ), u256( 1000000 ) ); - - auto txData = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - - auto blockNumAsString = fixture.rpcClient->eth_blockNumber(); - - auto author = fixture.rpcClient->eth_getBlockByNumber( blockNumAsString, false )["author"]; - auto blockNumber = jsToU256( blockNumAsString ); - - BOOST_REQUIRE( author == node_owner ); - - auto totalReward = fixture.client->chainParams().blockReward( - fixture.client->latestBlock().info().timestamp(), fixture.client->number() ); - auto blockAuthorReward = dev::calculateShareWithPrecision( totalReward, fixture.client->evmSchedule().shareOfBlockRewardToBlockAuthorPromille ); - auto stakingContractReward = totalReward - blockAuthorReward; - - auto feeForTx = - jsToU256( sampleTx["gasPrice"].asString() ) * jsToU256( txData["gasUsed"].asString() ); - feeForTx = dev::calculateShareWithPrecision( feeForTx, fixture.client->evmSchedule().shareOfTransactionFeeToRewardPromille ); - - auto expectedAuthorBalanceChange = ( blockNumber - initialBlockNumber ) * blockAuthorReward + feeForTx; - auto expectedContractBalanceChange = ( blockNumber - initialBlockNumber ) * stakingContractReward; - - BOOST_REQUIRE_EQUAL( - fixture.client->balanceAt( jsToAddress( author.asString() ) ) - authorInitialBalance, - expectedAuthorBalanceChange ); - BOOST_REQUIRE_EQUAL( - fixture.client->balanceAt( stakingContractAddress ) - stakingContractInitialBalance, - expectedContractBalanceChange ); -} - -BOOST_AUTO_TEST_CASE( block_author_balance_reward_wallet ) { - // when rewardWalletAddress is defined - - // checksumed address: 0xfa3fe33E351a7c60039E59D923e417A6362D1C3E - auto node_reward_wallet = "0xfa3fe33e351a7c60039e59d923e417a6362d1c3e"; - auto node_reward_wallet_address = jsToAddress( node_reward_wallet ); - - nlohmann::json configJson = nlohmann::json::parse( c_BITECommitteeRotationConfigString ); - // configJson["skaleConfig"]["sChain"]["nodeGroups"]["0"]["nodes"]["8"][3] = node_reward_wallet; - configJson["skaleConfig"]["sChain"]["nodeGroups"]["1"]["nodes"]["8"][3] = node_reward_wallet; - // configJson["skaleConfig"]["sChain"]["node"]["1"]["group"][0]["rewardWalletAddress"] = node_reward_wallet; - - auto noRewardWalletAddressConfig = configJson.dump(); - JsonRpcFixture fixture( noRewardWalletAddressConfig, false, false, true ); - - auto authorInitialBalance = fixture.client->balanceAt( node_reward_wallet_address ); - - auto initialBlockNumber = jsToU256( fixture.rpcClient->eth_blockNumber() ); - - // mine block without transactions - dev::eth::simulateMining( *( fixture.client ), 1 ); - sleep( 3 ); - - // mine transaction - Json::Value sampleTx; - sampleTx["value"] = 1000000; - sampleTx["data"] = toJS( bytes() ); - sampleTx["from"] = fixture.coinbase.address().hex(); - sampleTx["to"] = fixture.account2.address().hex(); - sampleTx["gasPrice"] = 1000000000000; - std::string txHash = fixture.rpcClient->eth_sendTransaction( sampleTx ); - BOOST_REQUIRE( !txHash.empty() ); - - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - fixture.client->state().getOriginalDb()->createBlockSnap( 2 ); - BOOST_REQUIRE_EQUAL( fixture.client->balanceAt( fixture.account2.address() ), u256( 1000000 ) ); - - auto txData = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - - auto blockNumAsString = fixture.rpcClient->eth_blockNumber(); - - auto author = fixture.rpcClient->eth_getBlockByNumber( blockNumAsString, false )["author"]; - auto blockNumber = jsToU256( blockNumAsString ); - BOOST_REQUIRE( author == node_reward_wallet ); - - auto totalReward = fixture.client->chainParams().blockReward( - fixture.client->latestBlock().info().timestamp(), fixture.client->number() ); - auto blockAuthorReward = - dev::calculateShareWithPrecision( totalReward, - fixture.client->evmSchedule().shareOfBlockRewardToBlockAuthorPromille ); - - auto feeForTx = jsToU256( sampleTx["gasPrice"].asString() ) * jsToU256( txData["gasUsed"].asString() ); - feeForTx = dev::calculateShareWithPrecision( feeForTx, fixture.client->evmSchedule().shareOfTransactionFeeToRewardPromille ); - auto expectedBalanceChange = ( blockNumber - initialBlockNumber ) * blockAuthorReward + feeForTx; - - BOOST_REQUIRE_EQUAL( - fixture.client->balanceAt( jsToAddress( author.asString() ) ) - authorInitialBalance, - expectedBalanceChange ); -} -#endif // FAIR - -#endif // #ifdef BITE - -#ifndef FAIR -BOOST_AUTO_TEST_CASE( etherbase_generation2 ) { - JsonRpcFixture fixture( c_genesisGeneration2ConfigString, false, false, true ); - string etherbase = fixture.rpcClient->eth_coinbase(); - - u256 etherbaseBalance = fixture.client->balanceAt( jsToAddress( etherbase ) ); - - // mine block without transactions - dev::eth::simulateMining( *( fixture.client ), 1 ); - sleep( 3 ); - etherbaseBalance = fixture.client->balanceAt( jsToAddress( etherbase ) ); - BOOST_REQUIRE_GT( etherbaseBalance, 0 ); - - // mine transaction - Json::Value sampleTx; - sampleTx["value"] = 1000000; - sampleTx["data"] = toJS( bytes() ); - sampleTx["from"] = fixture.coinbase.address().hex(); - sampleTx["to"] = fixture.account2.address().hex(); - sampleTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - std::string txHash = fixture.rpcClient->eth_sendTransaction( sampleTx ); - BOOST_REQUIRE( !txHash.empty() ); - dev::eth::mineTransaction( *( fixture.client ), 2 ); - fixture.client->state().getOriginalDb()->createBlockSnap( 2 ); - BOOST_REQUIRE_EQUAL( fixture.client->balanceAt( fixture.account2.address() ), u256( 1000000 ) ); - - // partially retrieve 1000000 - etherbaseBalance = fixture.client->balanceAt( jsToAddress( etherbase ) ); - u256 balance = - fixture.client->balanceAt( jsToAddress( "0x7aa5E36AA15E93D10F4F26357C30F052DacDde5F" ) ); - - Json::Value partiallyRetrieveTx; - partiallyRetrieveTx["data"] = - "0xc6427474000000000000000000000000d2c0deface0000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000006000000000000000000000000000000000000000000000000000000000000000e4b61d" - "27f6000000000000000000000000d2ba3e00000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "00000000000000600000000000000000000000000000000000000000000000000000000000000044204a3e9300" - "00000000000000000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f0000000000000000000000000000" - "0000000000000000000000000000000f4240000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000"; - partiallyRetrieveTx["from"] = "0x5C4e11842E8be09264dc1976943571d7Af6d00F9"; - partiallyRetrieveTx["to"] = "0xD244519000000000000000000000000000000000"; - partiallyRetrieveTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - partiallyRetrieveTx["gas"] = toJS( "1000000" ); - txHash = fixture.rpcClient->eth_sendTransaction( partiallyRetrieveTx ); - BOOST_REQUIRE( !txHash.empty() ); - dev::eth::mineTransaction( *( fixture.client ), 2 ); - - fixture.client->state().getOriginalDb()->createBlockSnap( 3 ); - auto t = fixture.rpcClient->eth_getTransactionReceipt( txHash ); -#ifdef FAIR - // reward goes to the node owner, not etherbase - BOOST_REQUIRE_EQUAL( fixture.client->balanceAt( jsToAddress( etherbase ) ), etherbaseBalance - u256( 1000000 ) ); -#else - BOOST_REQUIRE_EQUAL( fixture.client->balanceAt( jsToAddress( etherbase ) ), - etherbaseBalance + - jsToU256( t["gasUsed"].asString() ) * - jsToU256( partiallyRetrieveTx["gasPrice"].asString() ) - - u256( 1000000 ) ); -#endif - BOOST_REQUIRE_EQUAL( - fixture.client->balanceAt( jsToAddress( "0x7aa5E36AA15E93D10F4F26357C30F052DacDde5F" ) ), - balance + u256( 1000000 ) ); - - // retrieve all - u256 oldEtherbaseBalance = fixture.client->balanceAt( jsToAddress( etherbase ) ); - balance = - fixture.client->balanceAt( jsToAddress( "0x7aa5E36AA15E93D10F4F26357C30F052DacDde5F" ) ); - - Json::Value retrieveTx; - retrieveTx["data"] = - "0xc6427474000000000000000000000000d2c0deface0000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000006000000000000000000000000000000000000000000000000000000000000000c4b61d" - "27f6000000000000000000000000d2ba3e00000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000006000000000000000000000000000000000000000000000000000000000000000240a79309b00" - "00000000000000000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f0000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; - retrieveTx["from"] = "0x5C4e11842E8be09264dc1976943571d7Af6d00F9"; - retrieveTx["to"] = "0xD244519000000000000000000000000000000000"; - retrieveTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - retrieveTx["gas"] = toJS( "1000000" ); - txHash = fixture.rpcClient->eth_sendTransaction( retrieveTx ); - BOOST_REQUIRE( !txHash.empty() ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - fixture.client->state().getOriginalDb()->createBlockSnap( 4 ); - t = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - etherbaseBalance = fixture.client->balanceAt( jsToAddress( etherbase ) ); -#ifdef FAIR -// reward goes to the node owner, not etherbase - BOOST_REQUIRE_EQUAL( etherbaseBalance, 0 ); -#else - BOOST_REQUIRE_EQUAL( etherbaseBalance, - jsToU256( t["gasUsed"].asString() ) * - jsToU256( partiallyRetrieveTx["gasPrice"].asString() )); -#endif - BOOST_REQUIRE_EQUAL( - fixture.client->balanceAt( jsToAddress( "0x7aa5E36AA15E93D10F4F26357C30F052DacDde5F" ) ), - balance + oldEtherbaseBalance ); -} - -BOOST_AUTO_TEST_CASE( deploy_controller_generation2 ) { - JsonRpcFixture fixture( c_genesisGeneration2ConfigString, false, false, true ); - - Json::Value hasRoleBeforeGrantingCall; - hasRoleBeforeGrantingCall["data"] = - "0x91d14854fc425f2263d0df187444b70e47283d622c70181c5baebb1306a01edba1ce184c0000000000000000" - "000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f"; - hasRoleBeforeGrantingCall["to"] = "0xD2002000000000000000000000000000000000d2"; - BOOST_REQUIRE( - jsToInt( fixture.rpcClient->eth_call( hasRoleBeforeGrantingCall, "latest" ) ) == 0 ); - - string compiled = - "6080604052341561000f57600080fd5b60b98061001d6000396000f300" - "608060405260043610603f576000357c01000000000000000000000000" - "00000000000000000000000000000000900463ffffffff168063b3de64" - "8b146044575b600080fd5b3415604e57600080fd5b606a600480360381" - "019080803590602001909291905050506080565b604051808281526020" - "0191505060405180910390f35b60006007820290509190505600a16562" - "7a7a72305820f294e834212334e2978c6dd090355312a3f0f9476b8eb9" - "8fb480406fc2728a960029"; - - Json::Value deployContractWithoutRoleTx; - deployContractWithoutRoleTx["from"] = "0x7aa5e36aa15e93d10f4f26357c30f052dacdde5f"; - deployContractWithoutRoleTx["code"] = compiled; - deployContractWithoutRoleTx["gas"] = "1000000"; - deployContractWithoutRoleTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - - string txHash = fixture.rpcClient->eth_sendTransaction( deployContractWithoutRoleTx ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x0" ) ); - Json::Value code = - fixture.rpcClient->eth_getCode( receipt["contractAddress"].asString(), "latest" ); - BOOST_REQUIRE( code.asString() == "0x" ); - - // grant deployer role to 0x7aa5e36aa15e93d10f4f26357c30f052dacdde5f - Json::Value grantDeployerRoleTx; - grantDeployerRoleTx["data"] = - "0xc6427474000000000000000000000000d2c0deface0000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000006000000000000000000000000000000000000000000000000000000000000000c4b61d" - "27f6000000000000000000000000d2002000000000000000000000000000000000d20000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "00000000000000600000000000000000000000000000000000000000000000000000000000000024e43252d700" - "00000000000000000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f0000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; - grantDeployerRoleTx["from"] = "0x5C4e11842E8be09264dc1976943571d7Af6d00F9"; - grantDeployerRoleTx["to"] = "0xD244519000000000000000000000000000000000"; - grantDeployerRoleTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - grantDeployerRoleTx["gas"] = toJS( "1000000" ); - txHash = fixture.rpcClient->eth_sendTransaction( grantDeployerRoleTx ); - BOOST_REQUIRE( !txHash.empty() ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value hasRoleCall; - hasRoleCall["data"] = - "0x91d14854fc425f2263d0df187444b70e47283d622c70181c5baebb1306a01edba1ce184c0000000000000000" - "000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f"; - hasRoleCall["to"] = "0xD2002000000000000000000000000000000000d2"; - BOOST_REQUIRE( jsToInt( fixture.rpcClient->eth_call( hasRoleCall, "latest" ) ) == 1 ); - - // contract test { - // function f(uint a) returns(uint d) { return a * 7; } - // } - - Json::Value deployContractTx; - deployContractTx["from"] = "0x7aa5e36aa15e93d10f4f26357c30f052dacdde5f"; - deployContractTx["code"] = compiled; - deployContractTx["gas"] = "1000000"; - deployContractTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - - txHash = fixture.rpcClient->eth_sendTransaction( deployContractTx ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x1" ) ); - BOOST_REQUIRE( !receipt["contractAddress"].isNull() ); - code = fixture.rpcClient->eth_getCode( receipt["contractAddress"].asString(), "latest" ); - BOOST_REQUIRE( code.asString().substr( 2 ) == compiled.substr( 58 ) ); -} - -BOOST_AUTO_TEST_CASE( deployment_control_v2 ) { - // Inserting ConfigController mockup into config and enabling flexibleDeploymentPatch. - // ConfigController mockup contract: - - // pragma solidity ^0.8.9; - // contract ConfigController { - // bool public freeContractDeployment = false; - // function isAddressWhitelisted(address addr) external view returns (bool) { - // return false; - // } - // function isDeploymentAllowed(address origin, address sender) - // external view returns (bool) { - // return freeContractDeployment; - // } - // function setFreeContractDeployment() external { - // freeContractDeployment = true; - // } - // } - - string configControllerV2 = - "0x608060405234801561001057600080fd5b506004361061004c576000" - "3560e01c806313f44d1014610051578063a2306c4f14610081578063d0" - "f557f41461009f578063f7e2a91b146100cf575b600080fd5b61006b60" - "048036038101906100669190610189565b6100d9565b60405161007891" - "906101d1565b60405180910390f35b6100896100e0565b604051610096" - "91906101d1565b60405180910390f35b6100b960048036038101906100" - "b491906101ec565b6100f1565b6040516100c691906101d1565b604051" - "80910390f35b6100d761010a565b005b6000919050565b600080549061" - "01000a900460ff1681565b60008060009054906101000a900460ff1690" - "5092915050565b60016000806101000a81548160ff0219169083151502" - "17905550565b600080fd5b600073ffffffffffffffffffffffffffffff" - "ffffffffff82169050919050565b60006101568261012b565b90509190" - "50565b6101668161014b565b811461017157600080fd5b50565b600081" - "3590506101838161015d565b92915050565b6000602082840312156101" - "9f5761019e610126565b5b60006101ad84828501610174565b91505092" - "915050565b60008115159050919050565b6101cb816101b6565b825250" - "50565b60006020820190506101e660008301846101c2565b9291505056" - "5b6000806040838503121561020357610202610126565b5b6000610211" - "85828601610174565b925050602061022285828601610174565b915050" - "925092905056fea2646970667358221220b5f971b16f7bbba22272b220" - "7e02f10abf1682c17fe636c7bf6406c5cae5716064736f6c63430008090033"; - - - std::string _config = c_genesisGeneration2ConfigString; - Json::Value ret; - Json::Reader().parse( _config, ret ); - ret["accounts"]["0xD2002000000000000000000000000000000000d2"]["code"] = configControllerV2; - ret["skaleConfig"]["sChain"]["flexibleDeploymentPatchTimestamp"] = 1; - Json::FastWriter fastWriter; - std::string config = fastWriter.write( ret ); - - JsonRpcFixture fixture( config, false, false, true ); - Address senderAddress = fixture.coinbase.address(); - fixture.client->setAuthor( senderAddress ); - - // contract test { - // function f(uint a) returns(uint d) { return a * 7; } - // } - - string compiled = - "6080604052341561000f57600080fd5b60b98061001d6000396000f300" - "608060405260043610603f576000357c01000000000000000000000000" - "00000000000000000000000000000000900463ffffffff168063b3de64" - "8b146044575b600080fd5b3415604e57600080fd5b606a600480360381" - "019080803590602001909291905050506080565b604051808281526020" - "0191505060405180910390f35b60006007820290509190505600a16562" - "7a7a72305820f294e834212334e2978c6dd090355312a3f0f9476b8eb9" - "8fb480406fc2728a960029"; - - - // Trying to deploy contract without permission - Json::Value deployContractWithoutRoleTx; - deployContractWithoutRoleTx["from"] = senderAddress.hex(); - deployContractWithoutRoleTx["code"] = compiled; - deployContractWithoutRoleTx["gas"] = "1000000"; - deployContractWithoutRoleTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - - string txHash = fixture.rpcClient->eth_sendTransaction( deployContractWithoutRoleTx ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x0" ) ); - - Json::Value code = - fixture.rpcClient->eth_getCode( receipt["contractAddress"].asString(), "latest" ); - BOOST_REQUIRE( code.asString() == "0x" ); - - // Allow to deploy by calling setFreeContractDeployment() - Json::Value grantDeployerRoleTx; - grantDeployerRoleTx["data"] = "0xf7e2a91b"; - grantDeployerRoleTx["from"] = senderAddress.hex(); - grantDeployerRoleTx["to"] = "0xD2002000000000000000000000000000000000D2"; - grantDeployerRoleTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - grantDeployerRoleTx["gas"] = toJS( "1000000" ); - txHash = fixture.rpcClient->eth_sendTransaction( grantDeployerRoleTx ); - BOOST_REQUIRE( !txHash.empty() ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - // Deploying with permission - Json::Value deployContractTx; - deployContractTx["from"] = senderAddress.hex(); - deployContractTx["code"] = compiled; - deployContractTx["gas"] = "1000000"; - deployContractTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - - txHash = fixture.rpcClient->eth_sendTransaction( deployContractTx ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x1" ) ); - BOOST_REQUIRE( !receipt["contractAddress"].isNull() ); - code = fixture.rpcClient->eth_getCode( receipt["contractAddress"].asString(), "latest" ); - BOOST_REQUIRE( code.asString().substr( 2 ) == compiled.substr( 58 ) ); -} - -BOOST_AUTO_TEST_CASE( filestorage_generation2 ) { - JsonRpcFixture fixture( c_genesisGeneration2ConfigString, false, false, true ); - - Json::Value hasRoleBeforeGrantingCall; - hasRoleBeforeGrantingCall["data"] = - "0x91d1485468bf109b95a5c15fb2bb99041323c27d15f8675e11bf7420a1cd6ad64c394f460000000000000000" - "000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f"; - hasRoleBeforeGrantingCall["to"] = "0xD3002000000000000000000000000000000000d3"; - BOOST_REQUIRE( - jsToInt( fixture.rpcClient->eth_call( hasRoleBeforeGrantingCall, "latest" ) ) == 0 ); - - Json::Value reserveSpaceBeforeGrantRoleTx; - reserveSpaceBeforeGrantRoleTx["data"] = - "0x1cfe4e3b0000000000000000000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f0000000000000000" - "000000000000000000000000000000000000000000000064"; - reserveSpaceBeforeGrantRoleTx["from"] = "0x7aa5e36aa15e93d10f4f26357c30f052dacdde5f"; - reserveSpaceBeforeGrantRoleTx["to"] = "0xD3002000000000000000000000000000000000d3"; - reserveSpaceBeforeGrantRoleTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - reserveSpaceBeforeGrantRoleTx["gas"] = toJS( "1000000" ); - std::string txHash = fixture.rpcClient->eth_sendTransaction( reserveSpaceBeforeGrantRoleTx ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x0" ) ); - - Json::Value grantRoleTx; - grantRoleTx["data"] = - "0xc6427474000000000000000000000000d2c0deface0000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000006000000000000000000000000000000000000000000000000000000000000000e4b61d" - "27f6000000000000000000000000d3002000000000000000000000000000000000d30000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000006000000000000000000000000000000000000000000000000000000000000000442f2ff15d68" - "bf109b95a5c15fb2bb99041323c27d15f8675e11bf7420a1cd6ad64c394f460000000000000000000000007aa5" - "e36aa15e93d10f4f26357c30f052dacdde5f000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000"; - grantRoleTx["from"] = "0x5C4e11842E8be09264dc1976943571d7Af6d00F9"; - grantRoleTx["to"] = "0xD244519000000000000000000000000000000000"; - grantRoleTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - grantRoleTx["gas"] = toJS( "1000000" ); - txHash = fixture.rpcClient->eth_sendTransaction( grantRoleTx ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x1" ) ); - - Json::Value hasRoleCall; - hasRoleCall["data"] = - "0x91d1485468bf109b95a5c15fb2bb99041323c27d15f8675e11bf7420a1cd6ad64c394f460000000000000000" - "000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f"; - hasRoleCall["to"] = "0xD3002000000000000000000000000000000000d3"; - BOOST_REQUIRE( jsToInt( fixture.rpcClient->eth_call( hasRoleCall, "latest" ) ) == 1 ); - - Json::Value reserveSpaceTx; - reserveSpaceTx["data"] = - "0x1cfe4e3b0000000000000000000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f0000000000000000" - "000000000000000000000000000000000000000000000064"; - reserveSpaceTx["from"] = "0x7aa5e36aa15e93d10f4f26357c30f052dacdde5f"; - reserveSpaceTx["to"] = "0xD3002000000000000000000000000000000000d3"; - reserveSpaceTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - reserveSpaceTx["gas"] = toJS( "1000000" ); - txHash = fixture.rpcClient->eth_sendTransaction( reserveSpaceTx ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x1" ) ); - - Json::Value getReservedSpaceCall; - hasRoleCall["data"] = - "0xbb559d160000000000000000000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f"; - hasRoleCall["to"] = "0xD3002000000000000000000000000000000000d3"; - BOOST_REQUIRE( jsToInt( fixture.rpcClient->eth_call( hasRoleCall, "latest" ) ) == 100 ); -} -#endif - -BOOST_AUTO_TEST_CASE( PrecompiledPrintFakeEth, - *boost::unit_test::precondition( []( unsigned long ) -> bool { return false; } ) ) { - JsonRpcFixture fixture( c_genesisConfigString, false, false ); - dev::eth::simulateMining( *( fixture.client ), 20 ); - - fixture.accountHolder->setAccounts( { fixture.coinbase, fixture.account2, - dev::KeyPair( dev::Secret( - "0x1c2cd4b70c2b8c6cd7144bbbfbd1e5c6eacb4a5efd9c86d0e29cbbec4e8483b9" ) ) } ); - - u256 balance = - fixture.client->balanceAt( jsToAddress( "0x5C4e11842E8Be09264DC1976943571D7AF6d00f8" ) ); - BOOST_REQUIRE_EQUAL( balance, 0 ); - - Json::Value printFakeEthFromDisallowedAddressTx; - printFakeEthFromDisallowedAddressTx["data"] = - "0x5C4e11842E8Be09264DC1976943571D7AF6d00f8000000000000000000000000000000000000000000000000" - "0000000000000010"; - printFakeEthFromDisallowedAddressTx["from"] = fixture.coinbase.address().hex(); - printFakeEthFromDisallowedAddressTx["to"] = "0000000000000000000000000000000000000006"; - printFakeEthFromDisallowedAddressTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - fixture.rpcClient->eth_sendTransaction( printFakeEthFromDisallowedAddressTx ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - balance = - fixture.client->balanceAt( jsToAddress( "0x5C4e11842E8Be09264DC1976943571D7AF6d00f8" ) ); - BOOST_REQUIRE_EQUAL( balance, 0 ); - - Json::Value printFakeEthTx; - printFakeEthTx["data"] = - "0x5C4e11842E8Be09264DC1976943571D7AF6d00f8000000000000000000000000000000000000000000000000" - "0000000000000010"; - printFakeEthTx["from"] = "0x5C4e11842E8be09264dc1976943571d7Af6d00F9"; - printFakeEthTx["to"] = "0000000000000000000000000000000000000006"; - printFakeEthTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - fixture.rpcClient->eth_sendTransaction( printFakeEthTx ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - balance = - fixture.client->balanceAt( jsToAddress( "0x5C4e11842E8Be09264DC1976943571D7AF6d00f8" ) ); - BOOST_REQUIRE_EQUAL( balance, 16 ); - - Json::Value printFakeEthCall; - - printFakeEthCall["data"] = - "0x5C4e11842E8Be09264DC1976943571D7AF6d00f8000000000000000000000000000000000000000000000000" - "0000000000000010"; - - printFakeEthCall["from"] = "0x5C4e11842E8be09264dc1976943571d7Af6d00F9"; - printFakeEthCall["to"] = "0000000000000000000000000000000000000006"; - printFakeEthCall["gasPrice"] = fixture.rpcClient->eth_gasPrice(); - fixture.rpcClient->eth_call( printFakeEthCall, "latest" ); - - balance = - fixture.client->balanceAt( jsToAddress( "0x5C4e11842E8Be09264DC1976943571D7AF6d00f8" ) ); - BOOST_REQUIRE_EQUAL( balance, 16 ); - - // pragma solidity ^0.4.25; - - // contract Caller { - // function call() public view { - // bool status; - // uint amount = 16; - // address to = 0x5C4e11842E8Be09264DC1976943571D7AF6d00f8; - // assembly{ - // let ptr := mload(0x40) - // mstore(ptr, to) - // mstore(add(ptr, 0x20), amount) - // status := delegatecall(not(0), 0x06, ptr, 0x40, ptr, 32) - // } - // } - // } - - string compiled = - "0x6080604052348015600f57600080fd5b5060a78061001e6000396000f3006080604052600436106022576000" - "3560e01c63ffffffff16806328b5e32b146027575b600080fd5b348015603257600080fd5b506039603b565b00" - "5b600080600060109150735c4e11842e8be09264dc1976943571d7af6d00f89050604051818152826020820152" - "6020816040836006600019f49350505050505600a165627a7a72305820c99b5f7e9e41fb0fee1724d382ca0f2c" - "003087f66b3b46037ca6c7d452b076f20029"; - - Json::Value create; - create["from"] = fixture.coinbase.address().hex(); - create["code"] = compiled; - create["gas"] = "1000000"; - - TransactionSkeleton ts = toTransactionSkeleton( create ); - ts = fixture.client->populateTransactionWithDefaults( ts ); - pair< bool, Secret > ar = fixture.accountHolder->authenticate( ts ); - Transaction tx( ts, ar.second ); - - auto txHash = fixture.rpcClient->eth_sendRawTransaction( toJS( tx.toBytes() ) ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); - string contractAddress = receipt["contractAddress"].asString(); - - Json::Value transactionCallObject; - transactionCallObject["to"] = contractAddress; - transactionCallObject["data"] = "0x28b5e32b"; - - fixture.rpcClient->eth_call( transactionCallObject, "latest" ); - balance = - fixture.client->balanceAt( jsToAddress( "0x5C4e11842E8Be09264DC1976943571D7AF6d00f8" ) ); - BOOST_REQUIRE_EQUAL( balance, 16 ); -} - -BOOST_AUTO_TEST_CASE( mtm_import_sequential_txs ) { - JsonRpcFixture fixture( c_genesisConfigString, true, true, false, true ); - dev::eth::simulateMining( *( fixture.client ), 1 ); - - Json::Value txJson; - txJson["from"] = fixture.coinbase.address().hex(); - txJson["gas"] = "100000"; - - txJson["nonce"] = "0"; - TransactionSkeleton ts1 = toTransactionSkeleton( txJson ); - ts1 = fixture.client->populateTransactionWithDefaults( ts1 ); - pair< bool, Secret > ar1 = fixture.accountHolder->authenticate( ts1 ); - Transaction tx1( ts1, ar1.second ); - - txJson["nonce"] = "1"; - TransactionSkeleton ts2 = toTransactionSkeleton( txJson ); - ts2 = fixture.client->populateTransactionWithDefaults( ts2 ); - pair< bool, Secret > ar2 = fixture.accountHolder->authenticate( ts2 ); - Transaction tx2( ts2, ar2.second ); - - txJson["nonce"] = "2"; - TransactionSkeleton ts3 = toTransactionSkeleton( txJson ); - ts3 = fixture.client->populateTransactionWithDefaults( ts3 ); - pair< bool, Secret > ar3 = fixture.accountHolder->authenticate( ts3 ); - Transaction tx3( ts3, ar3.second ); - - h256 h1 = fixture.client->importTransaction( tx1, TransactionBroadcast::DontBroadcast ); - h256 h2 = fixture.client->importTransaction( tx2, TransactionBroadcast::DontBroadcast ); - h256 h3 = fixture.client->importTransaction( tx3, TransactionBroadcast::DontBroadcast ); - BOOST_REQUIRE( h1 ); - BOOST_REQUIRE( h2 ); - BOOST_REQUIRE( h3 ); - BOOST_REQUIRE( fixture.client->transactionQueueStatus().current == 3 ); -} - -BOOST_AUTO_TEST_CASE( mtm_import_future_txs ) { - JsonRpcFixture fixture( c_genesisConfigString, true, true, false, true ); - dev::eth::simulateMining( *( fixture.client ), 1 ); - auto tq = fixture.client->debugGetTransactionQueue(); - fixture.client->skaleHost()->pauseConsensus( true ); - - Json::Value txJson; - txJson["from"] = fixture.coinbase.address().hex(); - txJson["gas"] = "100000"; - - txJson["nonce"] = "0"; - TransactionSkeleton ts1 = toTransactionSkeleton( txJson ); - ts1 = fixture.client->populateTransactionWithDefaults( ts1 ); - pair< bool, Secret > ar1 = fixture.accountHolder->authenticate( ts1 ); - Transaction tx1( ts1, ar1.second ); - - txJson["nonce"] = "1"; - TransactionSkeleton ts2 = toTransactionSkeleton( txJson ); - ts2 = fixture.client->populateTransactionWithDefaults( ts2 ); - pair< bool, Secret > ar2 = fixture.accountHolder->authenticate( ts2 ); - Transaction tx2( ts2, ar2.second ); - - txJson["nonce"] = "2"; - TransactionSkeleton ts3 = toTransactionSkeleton( txJson ); - ts3 = fixture.client->populateTransactionWithDefaults( ts3 ); - pair< bool, Secret > ar3 = fixture.accountHolder->authenticate( ts3 ); - Transaction tx3( ts3, ar3.second ); - - txJson["nonce"] = "3"; - TransactionSkeleton ts4 = toTransactionSkeleton( txJson ); - ts4 = fixture.client->populateTransactionWithDefaults( ts4 ); - pair< bool, Secret > ar4 = fixture.accountHolder->authenticate( ts4 ); - Transaction tx4( ts4, ar4.second ); - - txJson["nonce"] = "4"; - TransactionSkeleton ts5 = toTransactionSkeleton( txJson ); - ts5 = fixture.client->populateTransactionWithDefaults( ts5 ); - pair< bool, Secret > ar5 = fixture.accountHolder->authenticate( ts5 ); - Transaction tx5( ts5, ar5.second ); - - h256 h1 = fixture.client->importTransaction( tx5 ); - BOOST_REQUIRE( h1 ); - BOOST_REQUIRE_EQUAL( tq->futureSize(), 1 ); - - Json::Value call = fixture.rpcClient->debug_getFutureTransactions(); - BOOST_REQUIRE_EQUAL( call.size(), 1 ); - - h256 h2 = fixture.client->importTransaction( tx3 ); - BOOST_REQUIRE( h2 ); - BOOST_REQUIRE_EQUAL( tq->futureSize(), 2 ); - - call = fixture.rpcClient->debug_getFutureTransactions(); - BOOST_REQUIRE_EQUAL( call.size(), 2 ); - BOOST_REQUIRE_EQUAL( call[0]["from"], string( "0x" ) + txJson["from"].asString() ); - - h256 h3 = fixture.client->importTransaction( tx2 ); - BOOST_REQUIRE( h3 ); - BOOST_REQUIRE_EQUAL( tq->futureSize(), 3 ); - - call = fixture.rpcClient->debug_getFutureTransactions(); - BOOST_REQUIRE_EQUAL( call.size(), 3 ); - - h256 h4 = fixture.client->importTransaction( tx1 ); - BOOST_REQUIRE( h4 ); - BOOST_REQUIRE_EQUAL( tq->futureSize(), 1 ); - BOOST_REQUIRE_EQUAL( tq->status().current, 3 ); - - call = fixture.rpcClient->debug_getFutureTransactions(); - BOOST_REQUIRE_EQUAL( call.size(), 1 ); - - h256 h5 = fixture.client->importTransaction( tx4 ); - BOOST_REQUIRE( h5 ); - BOOST_REQUIRE_EQUAL( tq->futureSize(), 0 ); - BOOST_REQUIRE_EQUAL( tq->status().current, 5 ); - - call = fixture.rpcClient->debug_getFutureTransactions(); - BOOST_REQUIRE_EQUAL( call.size(), 0 ); - - fixture.client->skaleHost()->pauseConsensus( false ); -} - -// TODO: Enable for multitransaction mode checking - - -// historic node shall ignore invalid transactions in block -BOOST_AUTO_TEST_CASE( skip_invalid_transactions ) { - sleep( 1 ); - JsonRpcFixture fixture( c_genesisConfigString, true, true, false, true ); - dev::eth::simulateMining( *( fixture.client ), 1 ); // 2 Ether - - cout << " Balance: " - << fixture.rpcClient->eth_getBalance( - fixture.accountHolder->allAccounts()[0].hex(), "latest" ) - << endl; - - // 1 import 1 transaction to increase block number - // also send some eth to account2 - // TODO repair mineMoney function! (it asserts) - Json::Value txJson; - txJson["from"] = fixture.coinbase.address().hex(); - txJson["gas"] = "200000"; - txJson["gasPrice"] = "5000000000000"; - txJson["to"] = fixture.account2.address().hex(); -#ifdef FAIR - txJson["value"] = "3500000000000000000"; -#else - txJson["value"] = "1000000000000000000"; -#endif - - txJson["nonce"] = "0"; - TransactionSkeleton ts1 = toTransactionSkeleton( txJson ); - ts1 = fixture.client->populateTransactionWithDefaults( ts1 ); - pair< bool, Secret > ar1 = fixture.accountHolder->authenticate( ts1 ); - Transaction tx1( ts1, ar1.second ); - fixture.client->importTransaction( tx1 ); - - // 1 eth left (returned to author) - dev::eth::mineTransaction( *( fixture.client ), 1 ); - cout << fixture.accountHolder->allAccounts()[0].hex() << " Balance2: " - << fixture.rpcClient->eth_getBalance( - fixture.accountHolder->allAccounts()[0].hex(), "latest" ) - << endl; - - // 2 import 4 transactions with money for 1st, 2nd, and 3rd - // require full 1 Ether for gas+value - txJson["gas"] = "100000"; - txJson["nonce"] = "1"; - txJson["value"] = "500000000000000000"; // take 0.5 eth out - ts1 = toTransactionSkeleton( txJson ); - ts1 = fixture.client->populateTransactionWithDefaults( ts1 ); - ar1 = fixture.accountHolder->authenticate( ts1 ); - tx1 = Transaction( ts1, ar1.second ); - - txJson["nonce"] = "2"; - TransactionSkeleton ts2 = toTransactionSkeleton( txJson ); - ts2 = fixture.client->populateTransactionWithDefaults( ts2 ); - pair< bool, Secret > ar2 = fixture.accountHolder->authenticate( ts2 ); - Transaction tx2( ts2, ar2.second ); - - txJson["from"] = fixture.account2.address().hex(); - txJson["nonce"] = "0"; - txJson["value"] = "0"; - txJson["gasPrice"] = "20000000000"; - txJson["gas"] = "53000"; - TransactionSkeleton ts3 = toTransactionSkeleton( txJson ); - ts3 = fixture.client->populateTransactionWithDefaults( ts3 ); - pair< bool, Secret > ar3 = fixture.accountHolder->authenticate( ts3 ); - Transaction tx3( ts3, ar3.second ); - - txJson["nonce"] = "1"; - TransactionSkeleton ts4 = toTransactionSkeleton( txJson ); - ts3 = fixture.client->populateTransactionWithDefaults( ts4 ); - pair< bool, Secret > ar4 = fixture.accountHolder->authenticate( ts4 ); - Transaction tx4( ts3, ar3.second ); - - // pause consensus to make sure all txs are imported at once, and - // will all be placed in the same block - fixture.client->skaleHost()->pauseConsensus( true ); - - h256 h4 = fixture.client->importTransaction( tx4 ); // ok - h256 h2 = fixture.client->importTransaction( tx2 ); // invalid - h256 h3 = fixture.client->importTransaction( tx3 ); // ok - h256 h1 = fixture.client->importTransaction( tx1 ); // ok - - fixture.client->skaleHost()->pauseConsensus( false ); - - dev::eth::mineTransaction( *( fixture.client ), 1 ); - cout << "Balance3: " - << fixture.rpcClient->eth_getBalance( - fixture.accountHolder->allAccounts()[0].hex(), "latest" ) - << endl; - - ( void ) h1; - ( void ) h2; - ( void ) h3; - ( void ) h4; - -#ifdef HISTORIC_STATE - // 3 check that historic node sees only 3 txns - - string explicitNumberStr = to_string( fixture.client->number() ); - - // 1 Block - Json::Value block = fixture.rpcClient->eth_getBlockByNumber( "latest", "false" ); - - string bh = block["hash"].asString(); - - // 2 transaction count - Json::Value cnt = fixture.rpcClient->eth_getBlockTransactionCountByNumber( "latest" ); - BOOST_REQUIRE_EQUAL( cnt.asString(), "0x3" ); - cnt = fixture.rpcClient->eth_getBlockTransactionCountByNumber( explicitNumberStr ); - BOOST_REQUIRE_EQUAL( cnt.asString(), "0x3" ); - cnt = fixture.rpcClient->eth_getBlockTransactionCountByHash( bh ); - BOOST_REQUIRE_EQUAL( cnt.asString(), "0x3" ); - - - BOOST_REQUIRE_EQUAL( block["transactions"].size(), 3 ); - BOOST_REQUIRE_EQUAL( block["transactions"][0]["transactionIndex"], "0x0" ); - BOOST_REQUIRE_EQUAL( block["transactions"][1]["transactionIndex"], "0x1" ); - BOOST_REQUIRE_EQUAL( block["transactions"][2]["transactionIndex"], "0x2" ); - - // same with explicit number - block = fixture.rpcClient->eth_getBlockByNumber( explicitNumberStr, "false" ); - - BOOST_REQUIRE_EQUAL( block["transactions"].size(), 3 ); - BOOST_REQUIRE_EQUAL( block["transactions"][0]["transactionIndex"], "0x0" ); - BOOST_REQUIRE_EQUAL( block["transactions"][1]["transactionIndex"], "0x1" ); - BOOST_REQUIRE_EQUAL( block["transactions"][2]["transactionIndex"], "0x2" ); - - // 3 receipts - Json::Value r1, r3, r4; - BOOST_REQUIRE_NO_THROW( r1 = fixture.rpcClient->eth_getTransactionReceipt( toJS( h1 ) ) ); - BOOST_REQUIRE_THROW( - fixture.rpcClient->eth_getTransactionReceipt( toJS( h2 ) ), jsonrpc::JsonRpcException ); - BOOST_REQUIRE_NO_THROW( r3 = fixture.rpcClient->eth_getTransactionReceipt( toJS( h3 ) ) ); - BOOST_REQUIRE_NO_THROW( r4 = fixture.rpcClient->eth_getTransactionReceipt( toJS( h4 ) ) ); - - BOOST_REQUIRE_EQUAL( r1["transactionIndex"], "0x0" ); - BOOST_REQUIRE_EQUAL( r3["transactionIndex"], "0x1" ); - BOOST_REQUIRE_EQUAL( r4["transactionIndex"], "0x2" ); - - // 4 transaction by index - Json::Value t0 = fixture.rpcClient->eth_getTransactionByBlockNumberAndIndex( "latest", "0" ); - Json::Value t1 = fixture.rpcClient->eth_getTransactionByBlockNumberAndIndex( "latest", "1" ); - Json::Value t2 = fixture.rpcClient->eth_getTransactionByBlockNumberAndIndex( "latest", "2" ); - BOOST_REQUIRE_EQUAL( jsToFixed< 32 >( t0["hash"].asString() ), h1 ); - BOOST_REQUIRE_EQUAL( jsToFixed< 32 >( t1["hash"].asString() ), h3 ); - BOOST_REQUIRE_EQUAL( jsToFixed< 32 >( t2["hash"].asString() ), h4 ); - - // same with explicit block number - - t0 = fixture.rpcClient->eth_getTransactionByBlockNumberAndIndex( explicitNumberStr, "0" ); - t1 = fixture.rpcClient->eth_getTransactionByBlockNumberAndIndex( explicitNumberStr, "1" ); - t2 = fixture.rpcClient->eth_getTransactionByBlockNumberAndIndex( explicitNumberStr, "2" ); - BOOST_REQUIRE_EQUAL( jsToFixed< 32 >( t0["hash"].asString() ), h1 ); - BOOST_REQUIRE_EQUAL( jsToFixed< 32 >( t1["hash"].asString() ), h3 ); - BOOST_REQUIRE_EQUAL( jsToFixed< 32 >( t2["hash"].asString() ), h4 ); - - BOOST_REQUIRE_EQUAL( bh, r1["blockHash"].asString() ); - - t0 = fixture.rpcClient->eth_getTransactionByBlockHashAndIndex( bh, "0" ); - t1 = fixture.rpcClient->eth_getTransactionByBlockHashAndIndex( bh, "1" ); - t2 = fixture.rpcClient->eth_getTransactionByBlockHashAndIndex( bh, "2" ); - - BOOST_REQUIRE_EQUAL( jsToFixed< 32 >( t0["hash"].asString() ), h1 ); - BOOST_REQUIRE_EQUAL( jsToFixed< 32 >( t1["hash"].asString() ), h3 ); - BOOST_REQUIRE_EQUAL( jsToFixed< 32 >( t2["hash"].asString() ), h4 ); - - // 5 transaction by hash - BOOST_REQUIRE_THROW( - fixture.rpcClient->eth_getTransactionByHash( toJS( h2 ) ), jsonrpc::JsonRpcException ); - - // send it successfully - - // make money - dev::eth::simulateMining( *fixture.client, 1 ); - - h2 = fixture.client->importTransaction( tx2 ); // invalid - - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - // checks: - Json::Value r2; - BOOST_REQUIRE_NO_THROW( r2 = fixture.rpcClient->eth_getTransactionReceipt( toJS( h2 ) ) ); - BOOST_REQUIRE_EQUAL( r2["blockNumber"], toJS( fixture.client->number() ) ); -#endif -} - -BOOST_AUTO_TEST_CASE( eth_signAndSendRawTransaction, - *boost::unit_test::precondition( dev::test::manuallyRunningTest ) ) { - SkaledFixture fixture( skaledConfigFileName ); - fixture.setupFirstKey(); - auto firstAccount = fixture.testAccounts.begin()->second; - auto gasPrice = fixture.getCurrentGasPrice(); - for ( uint64_t i = 0; i < 3; i++ ) { - auto dst = SkaledAccount::generate(); - fixture.splitAccountInHalves( - firstAccount, dst, gasPrice, TransactionWait::WAIT_FOR_COMPLETION ); - } -} - -BOOST_AUTO_TEST_CASE( perf_sendManyParalelEthTransfers, - *boost::unit_test::precondition( dev::test::manuallyRunningTest ) ) { - SkaledFixture fixture( skaledConfigFileName ); - vector< Secret > accountPieces; - - fixture.verifyTransactions = false; - fixture.threadsCountForTestTransactions = 8; - fixture.mtmBatchSize = 1; - - fixture.setupFirstKey(); - fixture.deployERC20(); - - fixture.setupTwoToTheNKeys( 12 ); - - fixture.sendTinyTransfersForAllAccounts( 10, TransferType::NATIVE ); -} - - -BOOST_AUTO_TEST_CASE( - perf_calls, *boost::unit_test::precondition( dev::test::manuallyRunningTest ) ) { - SkaledFixture fixture( skaledConfigFileName ); - vector< Secret > accountPieces; - - fixture.threadsCountForTestTransactions = 8; - - - fixture.setupFirstKey(); - fixture.deployERC20(); - - fixture.setupTwoToTheNKeys( 12 ); - - fixture.sendCallsForAllAccounts( 1, CallType::BLOCK_BY_NUMBER, "eth_getBlockByNumber" ); - fixture.sendCallsForAllAccounts( 1, CallType::TRANSACTION_COUNT, "eth_transactionCount" ); - fixture.sendCallsForAllAccounts( 1, CallType::BALANCE, "eth_getBalance" ); - fixture.sendCallsForAllAccounts( 1, CallType::BLOCK_NUMBER, "eth_blockNumber" ); - fixture.sendCallsForAllAccounts( 1, CallType::CHAIN_ID, "eth_chainId" ); - fixture.sendCallsForAllAccounts( 1, CallType::NET_VERSION, "net_version" ); - fixture.sendCallsForAllAccounts( 1, CallType::GAS_PRICE, "eth_gasPrice" ); - fixture.sendCallsForAllAccounts( 1, CallType::HASH_RATE, "eth_hashrate" ); - fixture.sendCallsForAllAccounts( 1, CallType::MINING, "eth_mining" ); - fixture.sendCallsForAllAccounts( 1, CallType::SYNCING, "eth_syncing" ); - fixture.sendCallsForAllAccounts( 1, CallType::WEB3_CLIENT_VERSION, "web3_clientVersion" ); -} - - -BOOST_AUTO_TEST_CASE( perf_sendManyParalelEthMTMTransfers, - *boost::unit_test::precondition( dev::test::manuallyRunningTest ) ) { - SkaledFixture fixture( skaledConfigFileName ); - vector< Secret > accountPieces; - - fixture.verifyTransactions = false; - fixture.threadsCountForTestTransactions = 8; - fixture.mtmBatchSize = 5; - - fixture.setupFirstKey(); - fixture.setupTwoToTheNKeys( 8 ); - - fixture.sendTinyTransfersForAllAccounts( 10, TransferType::NATIVE ); -} - -BOOST_AUTO_TEST_CASE( perf_sendManyParalelEthType1Transfers, - *boost::unit_test::precondition( dev::test::manuallyRunningTest ) ) { - SkaledFixture fixture( skaledConfigFileName ); - vector< Secret > accountPieces; - - fixture.verifyTransactions = false; - fixture.threadsCountForTestTransactions = 8; - fixture.transactionType = TransactionType::Type1; - - fixture.setupFirstKey(); - fixture.deployERC20(); - - fixture.setupTwoToTheNKeys( 12 ); - - fixture.sendTinyTransfersForAllAccounts( 1000, TransferType::NATIVE ); -} - -BOOST_AUTO_TEST_CASE( perf_sendManyParalelEthType2Transfers, - *boost::unit_test::precondition( dev::test::manuallyRunningTest ) ) { - SkaledFixture fixture( skaledConfigFileName ); - vector< Secret > accountPieces; - - fixture.verifyTransactions = false; - fixture.threadsCountForTestTransactions = 8; - fixture.transactionType = TransactionType::Type2; - - fixture.setupFirstKey(); - fixture.deployERC20(); - - fixture.setupTwoToTheNKeys( 12 ); - - fixture.sendTinyTransfersForAllAccounts( 1000, TransferType::NATIVE ); -} - -BOOST_AUTO_TEST_CASE( perf_sendManyParalelEthPowTransfers, - *boost::unit_test::precondition( dev::test::manuallyRunningTest ) ) { - SkaledFixture fixture( skaledConfigFileName ); - vector< Secret > accountPieces; - - fixture.verifyTransactions = false; - fixture.threadsCountForTestTransactions = 8; -#ifndef FAIR - fixture.usePow = true; -#endif - - fixture.setupFirstKey(); - fixture.deployERC20(); - - fixture.setupTwoToTheNKeys( 4 ); - - fixture.sendTinyTransfersForAllAccounts( 1000, TransferType::NATIVE ); -} - -BOOST_AUTO_TEST_CASE( perf_sendManyParalelERC20Transfers, - *boost::unit_test::precondition( dev::test::manuallyRunningTest ) ) { - SkaledFixture fixture( skaledConfigFileName ); - vector< Secret > accountPieces; - - fixture.verifyTransactions = false; - fixture.threadsCountForTestTransactions = 8; - - fixture.setupFirstKey(); - - fixture.deployERC20(); - - fixture.setupTwoToTheNKeys( 12 ); - fixture.mintAllKeysWithERC20(); - - fixture.sendTinyTransfersForAllAccounts( 10, TransferType::ERC20 ); -} - - -#ifndef FAIR -BOOST_FIXTURE_TEST_SUITE( RestrictedAddressSuite, RestrictedAddressFixture ) - -BOOST_AUTO_TEST_CASE( direct_call ) { - Json::Value transactionCallObject; - transactionCallObject["to"] = "0x0000000000000000000000000000000000000005"; - transactionCallObject["data"] = data; - - rpcClient->eth_call( transactionCallObject, "latest" ); - BOOST_REQUIRE( !boost::filesystem::exists( path ) ); - - transactionCallObject["from"] = "0xdeadbeef01234567896c27aa97d1a86395877b3a"; - rpcClient->eth_call( transactionCallObject, "latest" ); - BOOST_REQUIRE( !boost::filesystem::exists( path ) ); - - transactionCallObject["from"] = "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a"; - rpcClient->eth_call( transactionCallObject, "latest" ); - BOOST_REQUIRE( !boost::filesystem::exists( path ) ); -} - -BOOST_AUTO_TEST_CASE( transaction_from_restricted_address ) { - auto senderAddress = coinbase.address(); - client->setAuthor( senderAddress ); - dev::eth::simulateMining( *( client ), 1000 ); - - Json::Value transactionCallObject; - transactionCallObject["from"] = toJS( senderAddress ); - transactionCallObject["to"] = "0x0000000000000000000000000000000000000005"; - transactionCallObject["data"] = data; - - TransactionSkeleton ts = toTransactionSkeleton( transactionCallObject ); - ts = client->populateTransactionWithDefaults( ts ); - pair< bool, Secret > ar = accountHolder->authenticate( ts ); - Transaction tx( ts, ar.second ); - - auto txHash = rpcClient->eth_sendRawTransaction( toJS( tx.toBytes() ) ); - dev::eth::mineTransaction( *( client ), 1 ); - - BOOST_REQUIRE( !boost::filesystem::exists( path ) ); -} - -BOOST_AUTO_TEST_CASE( transaction_from_allowed_address ) { - auto senderAddress = coinbase.address(); - client->setAuthor( senderAddress ); - dev::eth::simulateMining( *( client ), 1000 ); - - Json::Value transactionCallObject; - transactionCallObject["from"] = toJS( senderAddress ); - transactionCallObject["to"] = "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a"; - transactionCallObject["data"] = "0x28b5e32b"; - - TransactionSkeleton ts = toTransactionSkeleton( transactionCallObject ); - ts = client->populateTransactionWithDefaults( ts ); - pair< bool, Secret > ar = accountHolder->authenticate( ts ); - Transaction tx( ts, ar.second ); - - auto txHash = rpcClient->eth_sendRawTransaction( toJS( tx.toBytes() ) ); - dev::eth::mineTransaction( *( client ), 1 ); - - BOOST_REQUIRE( boost::filesystem::exists( path ) ); -} - -BOOST_AUTO_TEST_CASE( delegate_call ) { - auto senderAddress = coinbase.address(); - client->setAuthor( senderAddress ); - dev::eth::simulateMining( *( client ), 1000 ); - - // pragma solidity ^0.4.25; - // - // contract Caller { - // function call() public view { - // bool status; - // string memory fileName = "test"; - // address sender = 0x000000000000000000000000000000AA; - // assembly{ - // let ptr := mload(0x40) - // mstore(ptr, sender) - // mstore(add(ptr, 0x20), 4) - // mstore(add(ptr, 0x40), mload(add(fileName, 0x20))) - // mstore(add(ptr, 0x60), 1) - // status := delegatecall(not(0), 0x05, ptr, 0x80, ptr, 32) - // } - // } - // } - - string compiled = - "6080604052348015600f57600080fd5b5060f88061001e6000396000f300608060405260043610603f57600035" - "7c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806328b5e32b14" - "6044575b600080fd5b348015604f57600080fd5b5060566058565b005b60006060600060408051908101604052" - "80600481526020017f746573740000000000000000000000000000000000000000000000000000000081525091" - "5060aa905060405181815260046020820152602083015160408201526001606082015260208160808360056000" - "19f49350505050505600a165627a7a72305820172a27e3e21f45218a47c53133bb33150ee9feac9e9d5d13294b" - "48b03773099a0029"; - - Json::Value create; - - create["from"] = toJS( senderAddress ); - create["code"] = compiled; - create["gas"] = "1000000"; - - TransactionSkeleton ts = toTransactionSkeleton( create ); - ts = client->populateTransactionWithDefaults( ts ); - pair< bool, Secret > ar = accountHolder->authenticate( ts ); - Transaction tx( ts, ar.second ); - - auto txHash = rpcClient->eth_sendRawTransaction( toJS( tx.toBytes() ) ); - dev::eth::mineTransaction( *( client ), 1 ); - - Json::Value receipt = rpcClient->eth_getTransactionReceipt( txHash ); - string contractAddress = receipt["contractAddress"].asString(); - - Json::Value transactionCallObject; - transactionCallObject["to"] = contractAddress; - transactionCallObject["data"] = "0x28b5e32b"; - - rpcClient->eth_call( transactionCallObject, "latest" ); - BOOST_REQUIRE( !boost::filesystem::exists( path ) ); - - transactionCallObject["from"] = ownerAddress.hex(); - rpcClient->eth_call( transactionCallObject, "latest" ); - BOOST_REQUIRE( !boost::filesystem::exists( path ) ); - - transactionCallObject["to"] = "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a"; - rpcClient->eth_call( transactionCallObject, "latest" ); - BOOST_REQUIRE( !boost::filesystem::exists( path ) ); -} - -BOOST_AUTO_TEST_SUITE_END() - -BOOST_AUTO_TEST_SUITE( FilestorageCacheSuite ) - -BOOST_AUTO_TEST_CASE( cached_filestorage ) { - auto _config = c_genesisConfigString; - Json::Value ret; - Json::Reader().parse( _config, ret ); - ret["skaleConfig"]["sChain"]["revertableFSPatchTimestamp"] = 1; - Json::FastWriter fastWriter; - std::string config = fastWriter.write( ret ); - RestrictedAddressFixture fixture( config ); - - auto senderAddress = fixture.coinbase.address(); - fixture.client->setAuthor( senderAddress ); - dev::eth::simulateMining( *( fixture.client ), 1000 ); - - Json::Value transactionCallObject; - transactionCallObject["from"] = toJS( senderAddress ); - transactionCallObject["to"] = "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a"; - transactionCallObject["data"] = "0xf38fb65b"; - - TransactionSkeleton ts = toTransactionSkeleton( transactionCallObject ); - ts = fixture.client->populateTransactionWithDefaults( ts ); - pair< bool, Secret > ar = fixture.accountHolder->authenticate( ts ); - Transaction tx( ts, ar.second ); - - auto txHash = fixture.rpcClient->eth_sendRawTransaction( toJS( tx.toBytes() ) ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - BOOST_REQUIRE( !boost::filesystem::exists( fixture.path ) ); -} - -BOOST_AUTO_TEST_CASE( uncached_filestorage ) { - auto _config = c_genesisConfigString; - Json::Value ret; - Json::Reader().parse( _config, ret ); - ret["skaleConfig"]["sChain"]["revertableFSPatchTimestamp"] = 9999999999999; - Json::FastWriter fastWriter; - std::string config = fastWriter.write( ret ); - RestrictedAddressFixture fixture( config ); - - auto senderAddress = fixture.coinbase.address(); - fixture.client->setAuthor( senderAddress ); - dev::eth::simulateMining( *( fixture.client ), 1000 ); - - Json::Value transactionCallObject; - transactionCallObject["from"] = toJS( senderAddress ); - transactionCallObject["to"] = "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a"; - transactionCallObject["data"] = "0xf38fb65b"; - - TransactionSkeleton ts = toTransactionSkeleton( transactionCallObject ); - ts = fixture.client->populateTransactionWithDefaults( ts ); - pair< bool, Secret > ar = fixture.accountHolder->authenticate( ts ); - Transaction tx( ts, ar.second ); - - auto txHash = fixture.rpcClient->eth_sendRawTransaction( toJS( tx.toBytes() ) ); - dev::eth::mineTransaction( *( fixture.client ), 1 ); - - BOOST_REQUIRE( boost::filesystem::exists( fixture.path ) ); -} - -BOOST_AUTO_TEST_SUITE_END() -#endif - -BOOST_FIXTURE_TEST_SUITE( GappedCacheSuite, JsonRpcFixture ) - -#ifdef HISTORIC_STATE - -BOOST_AUTO_TEST_CASE( test_blocks ) { - dev::rpc::_detail::GappedTransactionIndexCache cache( 10, *client ); - BOOST_REQUIRE_EQUAL( cache.realBlockTransactionCount( LatestBlock ), 0 ); - BOOST_REQUIRE_EQUAL( cache.realBlockTransactionCount( PendingBlock ), 0 ); - BOOST_REQUIRE_EQUAL( cache.realBlockTransactionCount( 999999999 ), 0 ); -} - -BOOST_AUTO_TEST_CASE( test_transactions ) { - simulateMining( *client, 1, Address( "0xf6c2a4ba2350e58a45916a03d0faa70dcc5dcfbf" ) ); - - // give it some time since testing fixture is not reliable - // to do - move to real skaled testing - sleep( 3 ); - - dev::rpc::_detail::GappedTransactionIndexCache cache( 10, *client ); - - Transaction invalid( fromHex( "0x00112233445566778899001122334455667788990011223344556677889900" - "11223344556677889900112233" - "4455667788990011223344556677889900112233445566778899001122334455" - "66778899001122334455667788" - "990011223344556677889900112233445566778899" ), - CheckTransaction::None, true ); - - Transaction valid( - fromHex( "0xf86c808504a817c80083015f90943d7112ee86223baf0a506b9d2a77595cbbba51d1872386f26fc" - "10000801ca0655757fd0650a65a373c48a4dc0f3d6ac5c3831aa0cc2cb863a5909dc6c25f72a07188" - "2ee8633466a243c0ea64dadb3120c1ca7a5cc7433c6c0b1c861a85322265" ), - CheckTransaction::None ); -#ifndef FAIR - valid.ignoreExternalGas(); -#endif - - // give it some time since testing fixture is not reliable - // to do - move to real skaled testing - sleep( 3 ); - - client->importTransactionsAsBlock( Transactions{ invalid, valid }, -#ifdef BITE - DecryptedTransactions{ -#ifdef BITE - std::make_shared< DecryptedCTXTxsMap >(), -#endif // BITE - std::make_shared< DecryptedRegularTxsMap >() - }, -#endif - -#ifdef FAIR - 1, -#endif - 1 ); - -#ifndef FAIR - BOOST_REQUIRE_EQUAL( cache.realBlockTransactionCount( LatestBlock ), 2 ); - BOOST_REQUIRE_EQUAL( cache.realIndexFromGapped( LatestBlock, 0 ), 1 ); - BOOST_REQUIRE_EQUAL( cache.gappedIndexFromReal( LatestBlock, 1 ), 0 ); - BOOST_REQUIRE_THROW( cache.gappedIndexFromReal( LatestBlock, 0 ), std::out_of_range ); - BOOST_REQUIRE_EQUAL( cache.transactionPresent( LatestBlock, 0 ), false ); - BOOST_REQUIRE_EQUAL( cache.transactionPresent( LatestBlock, 1 ), true ); -#else - BOOST_REQUIRE_EQUAL( cache.realBlockTransactionCount( LatestBlock ), 1 ); - BOOST_REQUIRE_EQUAL( cache.gappedBlockTransactionCount( LatestBlock ), 1 ); - BOOST_REQUIRE_EQUAL( cache.realIndexFromGapped( LatestBlock, 0 ), 0 ); - BOOST_REQUIRE_NO_THROW( cache.gappedIndexFromReal( LatestBlock, 0 ) ); - BOOST_REQUIRE_EQUAL( cache.transactionPresent( LatestBlock, 0 ), true ); - BOOST_REQUIRE_THROW( cache.transactionPresent( LatestBlock, 1 ), std::out_of_range ); -#endif -} - -BOOST_AUTO_TEST_CASE( test_exceptions ) { - simulateMining( *client, 1, Address( "0xf6c2a4ba2350e58a45916a03d0faa70dcc5dcfbf" ) ); - - dev::rpc::_detail::GappedTransactionIndexCache cache( 10, *client ); - - Transaction invalid( fromHex( "0x00112233445566778899001122334455667788990011223344556677889900" - "11223344556677889900112233" - "4455667788990011223344556677889900112233445566778899001122334455" - "66778899001122334455667788" - "990011223344556677889900112233445566778899" ), - CheckTransaction::None, true ); - - Transaction valid( - fromHex( "0xf86c808504a817c80083015f90943d7112ee86223baf0a506b9d2a77595cbbba51d1872386f26fc" - "10000801ca0655757fd0650a65a373c48a4dc0f3d6ac5c3831aa0cc2cb863a5909dc6c25f72a07188" - "2ee8633466a243c0ea64dadb3120c1ca7a5cc7433c6c0b1c861a85322265" ), - CheckTransaction::None ); - -#ifndef FAIR - valid.ignoreExternalGas(); -#endif - - client->importTransactionsAsBlock( Transactions{ invalid, valid }, -#ifdef BITE - DecryptedTransactions{ -#ifdef BITE - std::make_shared< DecryptedCTXTxsMap >(), -#endif // BITE - std::make_shared< DecryptedRegularTxsMap >() - }, -#endif - -#ifdef FAIR - 1, -#endif - 1 ); - BOOST_REQUIRE_THROW( cache.realIndexFromGapped( LatestBlock, 1 ), std::out_of_range ); - BOOST_REQUIRE_THROW( cache.realIndexFromGapped( LatestBlock, 2 ), std::out_of_range ); - BOOST_REQUIRE_THROW( cache.gappedIndexFromReal( LatestBlock, 2 ), std::out_of_range ); -#ifndef FAIR - BOOST_REQUIRE_THROW( cache.gappedIndexFromReal( LatestBlock, 0 ), std::out_of_range ); -#endif - BOOST_REQUIRE_THROW( cache.transactionPresent( LatestBlock, 2 ), std::out_of_range ); -} - -#endif - -BOOST_AUTO_TEST_SUITE_END() - -BOOST_AUTO_TEST_SUITE_END() +/* + Modifications Copyright (C) 2018-2019 SKALE Labs + + 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 . +*/ + +#pragma GCC diagnostic ignored "-Wdeprecated" + +#include + +#include "WebThreeStubClient.h" + + +#include "SkaledFixture.h" +#include "genesisGeneration2Config.h" +#include "libweb3jsonrpc/SkaleFace.h" +#include +#include +#include +#include +#include +#ifndef FAIR +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "SkaledFixture.h" +#include +#include +#include + +#ifndef FAIR +#include +#endif + +#include "genesisGeneration2Config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef BITE +#include +#include +#endif + +#ifdef BITE +#include +#include +#endif + +#ifdef FAIR +#include +#endif + +// This is defined by some weird windows header - workaround for now. +#undef GetMessage + + +using namespace std; +using namespace dev; +using namespace dev::eth; +using namespace dev::test; + +static size_t rand_port = ( srand( time( nullptr ) ), 1024 + rand() % 64000 ); + +#ifndef FAIR +static std::string const c_genesisConfigString = R"( +{ + "sealEngine": "NoProof", + "params": { + "accountStartNonce": "0x00", + "maximumExtraDataSize": "0x1000000", + "blockReward": "0x4563918244F40000", + "allowFutureBlocks": true, + "homesteadForkBlock": "0x00", + "EIP150ForkBlock": "0x00", + "EIP158ForkBlock": "0x00", + "byzantiumForkBlock": "0x00", + "constantinopleForkBlock": "0x00", + "istanbulForkBlock": "0x00", + "skaleDisableChainIdCheck": true, + "externalGasDifficulty": "0x1" + }, + "genesis": { + "author" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "difficulty" : "0x20000", + "gasLimit" : "0x0f4240", + "nonce" : "0x00", + "extraData" : "0x00", + "timestamp" : "0x00", + "mixHash" : "0x00", + "stateRoot": "0x01" + }, + "skaleConfig": { + "nodeInfo": { + "nodeName": "Node1", + "nodeID": 1112, + "bindIP": "127.0.0.1", + "basePort": )" + std::to_string( rand_port ) + + R"(, + "logLevel": "trace", + "logLevelProposal": "trace", + "testSignatures": true + }, + "sChain": { + "schainName": "TestChain", + "schainID": 1, + "emptyBlockIntervalMs": -1, + "nodeGroups": {}, + "nodes": [ + { "nodeID": 1112, "owner": "0x0E7d7F1D34a502bD609542576941C3FCc087c588", "ip": "127.0.0.1", "basePort": )" + + std::to_string( rand_port ) + + R"(, "schainIndex" : 1, "publicKey": "0xfa"} + ] + } + }, + "accounts": { + "0000000000000000000000000000000000000001": { "precompiled": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, + "0000000000000000000000000000000000000002": { "precompiled": { "name": "sha256", "linear": { "base": 60, "word": 12 } } }, + "0000000000000000000000000000000000000003": { "precompiled": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } }, + "0000000000000000000000000000000000000004": { "precompiled": { "name": "identity", "linear": { "base": 15, "word": 3 } } },)" + + R"( "0000000000000000000000000000000000000005": { + "precompiled": { + "name": "createFile", + "linear": { + "base": 15, + "word": 0 + }, + "restrictAccess": ["00000000000000000000000000000000000000AA", "692a70d2e424a56d2c6c27aa97d1a86395877b3a"] + } + },)" + + + /* + pragma solidity ^0.4.25; + contract Caller { + function call() public { + bool status; + string memory fileName = "test"; + address sender = 0x000000000000000000000000000000AA; + assembly{ + let ptr := mload(0x40) + mstore(ptr, sender) + mstore(add(ptr, 0x20), 4) + mstore(add(ptr, 0x40), mload(add(fileName, 0x20))) + mstore(add(ptr, 0x60), 1) + status := call(not(0), 0x05, 0, ptr, 0x80, ptr, 32) + } + } + + function revertCall() public { + call(); + revert(); + } + } + */ + R"("0000000000000000000000000000000000000006": { + "precompiled": { + "name": "addBalance", + "linear": { + "base": 15, + "word": 0 + }, + "restrictAccess": ["5c4e11842e8be09264dc1976943571d7af6d00f9"] + } + }, + "0000000000000000000000000000000000000007": { + "precompiled": { + "name": "getIMABLSPublicKey", + "linear": { + "base": 15, + "word": 0 + } + } + }, + "0000000000000000000000000000000000000008": { "precompiled": { "name": "getBlockRandom", "linear": { "base": 15, "word": 0 } } }, + "0x5c4e11842e8be09264dc1976943571d7af6d00f9" : { + "balance" : "1000000000000000000000000000000" + }, + "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a" : { + "balance" : "0x00", + "code" : "0x6080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806328b5e32b14604e578063f38fb65b146062575b600080fd5b348015605957600080fd5b5060606076565b005b348015606d57600080fd5b50607460ec565b005b6000606060006040805190810160405280600481526020017f7465737400000000000000000000000000000000000000000000000000000000815250915060aa905060405181815260046020820152602083015160408201526001606082015260208160808360006005600019f1935050505050565b60f26076565b600080fd00a165627a7a72305820262a5822c4fe6c154b2ef3198c7827d35fc6da59da2cea2c4f2fad9d4a5ccd5e0029", + "nonce" : "0x00", + "storage" : { + } + }, + "0x095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x6001600101600055", + "nonce" : "0x00", + "storage" : { + } + }, + "0xC2002000000000000000000000000000000000C2": { + "balance": "0", + "code": "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80639b063104146037578063cd16ecbf146062575b600080fd5b606060048036036020811015604b57600080fd5b8101908080359060200190929190505050608d565b005b608b60048036036020811015607657600080fd5b81019080803590602001909291905050506097565b005b8060018190555050565b806000819055505056fea265627a7a7231582029df540a7555533ef4b3f66bc4f9abe138b00117d1496efbfd9d035a48cd595e64736f6c634300050d0032", + "storage": { + "0x0": "0x01" + }, + "nonce": "0" + }, + "0xD2002000000000000000000000000000000000D2": { + "balance": "0", + "code": "0x608060405234801561001057600080fd5b50600436106100455760003560e01c806313f44d101461005557806338eada1c146100af5780634ba79dfe146100f357610046565b5b6002801461005357600080fd5b005b6100976004803603602081101561006b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610137565b60405180821515815260200191505060405180910390f35b6100f1600480360360208110156100c557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101f4565b005b6101356004803603602081101561010957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061030f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16148061019957506101988261042b565b5b806101ed5750600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b9050919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f43616c6c6572206973206e6f7420746865206f776e657200000000000000000081525060200191505060405180910390fd5b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f43616c6c6572206973206e6f7420746865206f776e657200000000000000000081525060200191505060405180910390fd5b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600080823b90506000811191505091905056fea26469706673582212202aca1f7abb7d02061b58de9b559eabe1607c880fda3932bbdb2b74fa553e537c64736f6c634300060c0033", + "storage": { + }, + "nonce": "0" + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0xD2001300000000000000000000000000000000D4": { + "balance": "0", + "nonce": "0", + "storage": {}, + "code":"0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80632098776714610051578063b8bd717f1461007f578063d37165fa146100ad578063fdde8d66146100db575b600080fd5b61007d6004803603602081101561006757600080fd5b8101908080359060200190929190505050610109565b005b6100ab6004803603602081101561009557600080fd5b8101908080359060200190929190505050610136565b005b6100d9600480360360208110156100c357600080fd5b8101908080359060200190929190505050610170565b005b610107600480360360208110156100f157600080fd5b8101908080359060200190929190505050610191565b005b60005a90505b815a8203101561011e5761010f565b600080fd5b815a8203101561013257610123565b5050565b60005a90505b815a8203101561014b5761013c565b600060011461015957600080fd5b5a90505b815a8203101561016c5761015d565b5050565b60005a9050600081830390505b805a8303101561018c5761017d565b505050565b60005a90505b815a820310156101a657610197565b60016101b157600080fd5b5a90505b815a820310156101c4576101b5565b505056fea264697066735822122089b72532621e7d1849e444ee6efaad4fb8771258e6f79755083dce434e5ac94c64736f6c63430006000033" + } + } +} +)"; +#else +static std::string const c_genesisConfigString = + R"( +{ + "sealEngine": "NoProof", + "params": { + "accountStartNonce": "0x00", + "maximumExtraDataSize": "0x1000000", + "blockReward": "0x4563918244F40000", + "allowFutureBlocks": true, + "homesteadForkBlock": "0x00", + "EIP150ForkBlock": "0x00", + "EIP158ForkBlock": "0x00", + "byzantiumForkBlock": "0x00", + "constantinopleForkBlock": "0x00", + "istanbulForkBlock": "0x00", + "skaleDisableChainIdCheck": true + }, + "genesis": { + "author" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "difficulty" : "0x20000", + "gasLimit" : "0x0f4240", + "nonce" : "0x00", + "extraData" : "0x00", + "timestamp" : "0x00", + "mixHash" : "0x00", + "stateRoot": "0x01" + }, + "skaleConfig": { + "nodeInfo": { + "nodeName": "Node1", + "nodeID": 1112, + "bindIP": "127.0.0.1", + "basePort": )" + + std::to_string( rand_port ) + R"(, + "logLevel": "trace", + "logLevelProposal": "trace", + "testSignatures": true + }, + "sChain": { + "schainName": "TestChain", + "schainID": 1, + "emptyBlockIntervalMs": -1, + "nodeGroups": {}, + "nodes": { + "1": { + "stakingContractAddress": "0x5C60C315985977b7a408eBF4256984Acdf949549", + "group": [ + { "nodeID": 1112, "owner": "0x0E7d7F1D34a502bD609542576941C3FCc087c588", "ip": "127.0.0.1", "basePort": )" + + std::to_string( rand_port ) + + R"(, "ip6": "::1", "basePort6": 1231, "schainIndex" : 1, "publicKey" : "0xfa"} + ] + }, + "-1": {} + } + } + }, + "accounts": { + "0000000000000000000000000000000000000001": { "precompiled": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, + "0000000000000000000000000000000000000002": { "precompiled": { "name": "sha256", "linear": { "base": 60, "word": 12 } } }, + "0000000000000000000000000000000000000003": { "precompiled": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } }, + "0000000000000000000000000000000000000004": { "precompiled": { "name": "identity", "linear": { "base": 15, "word": 3 } } }, + "0000000000000000000000000000000000000008": { "precompiled": { "name": "getBlockRandom", "linear": { "base": 15, "word": 0 } } }, + )" + /* +pragma solidity ^0.4.25; +contract Caller { +function call() public { +bool status; +string memory fileName = "test"; +address sender = 0x000000000000000000000000000000AA; +assembly{ +let ptr := mload(0x40) +mstore(ptr, sender) +mstore(add(ptr, 0x20), 4) +mstore(add(ptr, 0x40), mload(add(fileName, 0x20))) +mstore(add(ptr, 0x60), 1) +status := call(not(0), 0x05, 0, ptr, 0x80, ptr, 32) +} +} + +function revertCall() public { +call(); +revert(); +} +} +*/ + R"("0000000000000000000000000000000000000006": { + "precompiled": { + "name": "addBalance", + "linear": { + "base": 15, + "word": 0 + } + } + }, + "0x5c4e11842e8be09264dc1976943571d7af6d00f9" : { + "balance" : "1000000000000000000000000000000" + }, + "0x5339Ef05428d1b87f4e2F2db64E782c68E9cDA56": { + "balance" : "1000000000000000000000000000000" + }, + "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a" : { + "balance" : "0x00", + "code" : "0x6080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806328b5e32b14604e578063f38fb65b146062575b600080fd5b348015605957600080fd5b5060606076565b005b348015606d57600080fd5b50607460ec565b005b6000606060006040805190810160405280600481526020017f7465737400000000000000000000000000000000000000000000000000000000815250915060aa905060405181815260046020820152602083015160408201526001606082015260208160808360006005600019f1935050505050565b60f26076565b600080fd00a165627a7a72305820262a5822c4fe6c154b2ef3198c7827d35fc6da59da2cea2c4f2fad9d4a5ccd5e0029", + "nonce" : "0x00", + "storage" : { + } + }, + "0x095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x6001600101600055", + "nonce" : "0x00", + "storage" : { + } + }, + "0xC2002000000000000000000000000000000000C2": { + "balance": "0", + "code": "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80639b063104146037578063cd16ecbf146062575b600080fd5b606060048036036020811015604b57600080fd5b8101908080359060200190929190505050608d565b005b608b60048036036020811015607657600080fd5b81019080803590602001909291905050506097565b005b8060018190555050565b806000819055505056fea265627a7a7231582029df540a7555533ef4b3f66bc4f9abe138b00117d1496efbfd9d035a48cd595e64736f6c634300050d0032", + "storage": { + "0x0": "0x01" + }, + "nonce": "0" + }, + "0xD2002000000000000000000000000000000000D2": { + "balance": "0", + "code": "0x608060405234801561001057600080fd5b50600436106100455760003560e01c806313f44d101461005557806338eada1c146100af5780634ba79dfe146100f357610046565b5b6002801461005357600080fd5b005b6100976004803603602081101561006b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610137565b60405180821515815260200191505060405180910390f35b6100f1600480360360208110156100c557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101f4565b005b6101356004803603602081101561010957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061030f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16148061019957506101988261042b565b5b806101ed5750600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b9050919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f43616c6c6572206973206e6f7420746865206f776e657200000000000000000081525060200191505060405180910390fd5b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f43616c6c6572206973206e6f7420746865206f776e657200000000000000000081525060200191505060405180910390fd5b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600080823b90506000811191505091905056fea26469706673582212202aca1f7abb7d02061b58de9b559eabe1607c880fda3932bbdb2b74fa553e537c64736f6c634300060c0033", + "storage": { + }, + "nonce": "0" + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0xD2001300000000000000000000000000000000D4": { + "balance": "0", + "nonce": "0", + "storage": {}, + "code":"0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80632098776714610051578063b8bd717f1461007f578063d37165fa146100ad578063fdde8d66146100db575b600080fd5b61007d6004803603602081101561006757600080fd5b8101908080359060200190929190505050610109565b005b6100ab6004803603602081101561009557600080fd5b8101908080359060200190929190505050610136565b005b6100d9600480360360208110156100c357600080fd5b8101908080359060200190929190505050610170565b005b610107600480360360208110156100f157600080fd5b8101908080359060200190929190505050610191565b005b60005a90505b815a8203101561011e5761010f565b600080fd5b815a8203101561013257610123565b5050565b60005a90505b815a8203101561014b5761013c565b600060011461015957600080fd5b5a90505b815a8203101561016c5761015d565b5050565b60005a9050600081830390505b805a8303101561018c5761017d565b505050565b60005a90505b815a820310156101a657610197565b60016101b157600080fd5b5a90505b815a820310156101c4576101b5565b505056fea264697066735822122089b72532621e7d1849e444ee6efaad4fb8771258e6f79755083dce434e5ac94c64736f6c63430006000033" + } + } +} +)"; +#endif + +namespace { +class TestIpcServer : public jsonrpc::AbstractServerConnector { +public: + bool StartListening() override { return true; } + + bool StopListening() override { return true; } + + bool SendResponse( std::string const& _response, void* _addInfo = nullptr ) /*override*/ { + *static_cast< std::string* >( _addInfo ) = _response; + return true; + } +}; + +class TestIpcClient : public jsonrpc::IClientConnector { +public: + explicit TestIpcClient( TestIpcServer& _server ) : m_server{ _server } {} + + void SendRPCMessage( const std::string& _message, std::string& _result ) override { + m_server.ProcessRequest( _message, _result ); + } + +private: + TestIpcServer& m_server; +}; + +struct JsonRpcFixture : public TestOutputHelperFixture { + // chain params needs to be a field of JsonRPCFixture + // since references to it are passed to the server + std::shared_ptr< ChainParams > chainParams = std::make_shared< ChainParams >(); + + + JsonRpcFixture( const std::string& _config = "", bool _owner = true, + bool _deploymentControl = true, bool _generation2 = false, bool _mtmEnabled = false, + bool _isSyncNode = false, int _emptyBlockIntervalMs = -1, + const std::map< std::string, std::string >& params = + std::map< std::string, std::string >() ) { + + // this fixture is used in all tests to load config. So also init bls library as well + libBLS::init(); + + if ( _config != "" ) { + if ( !_generation2 ) { + Json::Value ret; + Json::Reader().parse( _config, ret ); + if ( _owner ) { + ret["skaleConfig"]["sChain"]["schainOwner"] = toJS( coinbase.address() ); + if ( _deploymentControl ) + ret["accounts"]["0xD2002000000000000000000000000000000000D2"]["storage"] + ["0x0"] = toJS( coinbase.address() ); + } else { + ret["skaleConfig"]["sChain"]["schainOwner"] = toJS( account2.address() ); + if ( _deploymentControl ) + ret["accounts"]["0xD2002000000000000000000000000000000000D2"]["storage"] + ["0x0"] = toJS( account2.address() ); + } +#ifndef FAIR + ret["skaleConfig"]["sChain"]["contractStorageLimit"] = 128; +#endif + if ( params.count( "contractStorageLimit" ) ) + ret["skaleConfig"]["sChain"]["contractStorageLimit"] = std::stoi( params.at( "contractStorageLimit" ) ); +#ifdef BITE + if ( params.count( "BITE2PatchTimestamp" ) ) + ret["skaleConfig"]["sChain"]["Bite2PatchTimestamp"] = std::stoi( params.at( "BITE2PatchTimestamp" ) ); +#endif + Json::FastWriter fastWriter; + std::string output = fastWriter.write( ret ); + chainParams->loadConfig( output ); + } else { + Json::Value ret; + Json::FastWriter fastWriter; + Json::Reader().parse( _config, ret ); +#ifndef FAIR + ret["skaleConfig"]["sChain"]["contractStorageLimit"] = 106874910; + ret["skaleConfig"]["sChain"]["contractStoragePatchTimestamp"] = 1000; +#endif + std::string output = fastWriter.write( ret ); + chainParams->loadConfig( output ); + + // insecure schain owner(originator) private key + // address is 0x5C4e11842E8be09264dc1976943571d7Af6d00F9 + coinbase = dev::KeyPair( dev::Secret( + "0x1c2cd4b70c2b8c6cd7144bbbfbd1e5c6eacb4a5efd9c86d0e29cbbec4e8483b9" ) ); + // address is 0x7aa5e36aa15e93d10f4f26357c30f052dacdde5f + account3 = dev::KeyPair( dev::Secret( + "0x23ABDBD3C61B5330AF61EBE8BEF582F4E5CC08E554053A718BDCE7813B9DC1FC" ) ); + } + } else { + chainParams->sealEngineName = NoProof::name(); + chainParams->allowFutureBlocks = true; + chainParams->difficulty = chainParams->getMinimumDifficulty(); + chainParams->gasLimit = chainParams->getMaxGasLimit(); + chainParams->byzantiumForkBlock = 0; + chainParams->EIP158ForkBlock = 0; + chainParams->constantinopleForkBlock = 0; + chainParams->istanbulForkBlock = 0; +#ifndef FAIR + chainParams->externalGasDifficulty = 1; + chainParams->sChain.contractStorageLimit = 128; +#endif + // 615 + 1430 is experimentally-derived block size + average extras size + chainParams->sChain.dbStorageLimit = 320.5 * ( 615 + 1430 ); +#ifdef FAIR + chainParams->sChain.nodeGroups = { { + { GroupNode { + u256( 0 ), + u256( 8 ), + "0xf925c203a30ec6cad5a263db3efab7ed4c1fd74c8688167e10a5a22e15ab5018d8553df0ac54" + "ea", + Address( "0x08151B8F80bfa7dEa760e461412AF24348224edf" ) + } }, + uint64_t( -1 ), + { "3842742177969966091367527274107524613106077736353521259727282251005583743182", + "3497912824016228906558906422247670474553186446469877598411863912329082553081", + "8173996886448941320370434854289578123609627835954133538412363037981850950343", + "20979370720689475348670582375026949105497642726992863932315517524004804784155" + } + } }; + chainParams->sChain.nodes[0].owner = + jsToAddress( "0x0E7d7F1D34a502bD609542576941C3FCc087c588" ); +#endif +#ifndef FAIR + chainParams->sChain + ._patchTimestamps[static_cast< size_t >( SchainPatchEnum::ContractStoragePatch )] = + 1; + chainParams->sChain._patchTimestamps[static_cast< size_t >( + SchainPatchEnum::StorageDestructionPatch )] = 1; + powPatchActivationTimestamp = time( nullptr ) + 60; + chainParams->sChain + ._patchTimestamps[static_cast< size_t >( SchainPatchEnum::CorrectForkInPowPatch )] = + powPatchActivationTimestamp; + push0PatchActivationTimestamp = time( nullptr ) + 10; + chainParams->sChain + ._patchTimestamps[static_cast< size_t >( SchainPatchEnum::PushZeroPatch )] = + push0PatchActivationTimestamp; +#endif + chainParams->sChain.emptyBlockIntervalMs = _emptyBlockIntervalMs; + // add random extra data to randomize genesis hash and get random DB path, + // so that tests can be run in parallel + // TODO: better make it use ethemeral in-memory databases + chainParams->extraData = h256::random().asBytes(); + chainParams->nodeInfo.port = chainParams->nodeInfo.port6 = rand_port; + chainParams->sChain.nodes[0].port = chainParams->sChain.nodes[0].port6 = rand_port; + chainParams->skaleDisableChainIdCheck = true; + + if ( params.count( "getLogsBlocksLimit" ) && stoi( params.at( "getLogsBlocksLimit" ) ) ) + chainParams->logsBlocksLimit = stoi( params.at( "getLogsBlocksLimit" ) ); + if ( params.count( "getResponseLogCountLimit" ) && + stoi( params.at( "getResponseLogCountLimit" ) ) ) + chainParams->responseLogCountLimit = + stoi( params.at( "getResponseLogCountLimit" ) ); + } + chainParams->sChain.multiTransactionMode = _mtmEnabled; + chainParams->nodeInfo.syncNode = _isSyncNode; + + auto monitor = make_shared< InstanceMonitor >( "test" ); + + + setenv( "DATA_DIR", tempDir.path().c_str(), 1 ); + client.reset( new eth::ClientTest( chainParams, ( int ) chainParams->getNetworkId(), + shared_ptr< GasPricer >(), NULL, monitor, tempDir.path(), WithExisting::Kill ) ); + + if ( !_generation2 ) + client->setAuthor( coinbase.address() ); + else + client->setAuthor( chainParams->getBlockAuthor() ); + + // wait for 1st block - because it's always empty + std::promise< void > blockPromise; + auto importHandler = client->setOnBlockImport( + [&blockPromise]( BlockHeader const& ) { blockPromise.set_value(); } ); + + client->injectSkaleHost(); + dev::eth::g_skaleHost = client->skaleHost(); + client->startWorking(); + + if ( !_isSyncNode ) + blockPromise.get_future().wait(); + + using FullServer = ModularServer< rpc::EthFace, rpc::SkaleFace, rpc::NetFace, rpc::Web3Face, + rpc::AdminEthFace /*, rpc::AdminNetFace*/, rpc::DebugFace, rpc::TestFace >; + + accountHolder.reset( new FixedAccountHolder( [&]() { return client.get(); }, {} ) ); + accountHolder->setAccounts( { coinbase, account2, account3 } ); + + sessionManager.reset( new rpc::SessionManager() ); + adminSession = + sessionManager->newSession( rpc::SessionPermissions{ { rpc::Privilege::Admin } } ); + + auto ethFace = new rpc::Eth( + _config.empty() ? std::string( "" ) : _config, *client, *accountHolder.get() ); + + dev::rpc::Skale* skaleFace = nullptr; +#ifdef BITE + skaleFace = new rpc::Skale( *client ); +#endif + + gasPricer = make_shared< eth::TrivialGasPricer >( 0, DefaultGasPrice ); + + rpcServer.reset( new FullServer( ethFace, skaleFace, new rpc::Net( chainParams ), + new rpc::Web3(), // TODO Add version parameter here? + new rpc::AdminEth( *client, *gasPricer, keyManager, *sessionManager ), + new rpc::Debug( *client, nullptr, "" ), new rpc::Test( *client ) ) ); + + + // + SkaleServerOverride::opts_t serverOpts; + + inject_rapidjson_handlers( serverOpts, ethFace ); + + serverOpts.netOpts_.bindOptsStandard_.cntServers_ = 1; + serverOpts.netOpts_.bindOptsStandard_.strAddrHTTP4_ = chainParams->getSelfNodeIp(); + // random port + // +3 because rand() seems to be called effectively simultaneously here and in "static" + // section - thus giving same port for consensus + serverOpts.netOpts_.bindOptsStandard_.nBasePortHTTP4_ = std::rand() % 64000 + 1025 + 3; + skale_server_connector = new SkaleServerOverride( chainParams, client.get(), serverOpts ); + rpcServer->addConnector( skale_server_connector ); + skale_server_connector->StartListening(); + + sleep( 1 ); + + httpClient = new jsonrpc::HttpClient( + "http://" + chainParams->getSelfNodeIp() + ":" + + std::to_string( serverOpts.netOpts_.bindOptsStandard_.nBasePortHTTP4_ ) ); + httpClient->SetTimeout( 1000000000 ); + + rpcClient = unique_ptr< WebThreeStubClient >( new WebThreeStubClient( *httpClient ) ); + + BOOST_TEST_MESSAGE( "Constructed JsonRpcFixture" ); + } + + ~JsonRpcFixture() { +#ifdef FAIR + // Make sure safe consensus is properly updated before exit (epoch id in particular). + // Only related to FAIR + const auto deadline = chrono::steady_clock::now() + chrono::seconds( 10 ); + while ( client->skaleHost()->ignoreNewBlocksEnabled() && + chrono::steady_clock::now() < deadline ) { + usleep( 10 ); + } + if ( client->skaleHost()->isConsesusUpdateHappened() ) + client->skaleHost()->handleConsensusUpdate(); +#endif + + if ( skale_server_connector ) + skale_server_connector->StopListening(); + + if ( httpClient ) + delete httpClient; + + if ( g_skaleHost ) + g_skaleHost.reset(); + + BOOST_TEST_MESSAGE( "Destructed JsonRpcFixture" ); + } + + string sendingRawShouldFail( string const& _t ) { + try { + rpcClient->eth_sendRawTransaction( _t ); + BOOST_FAIL( "Exception expected." ); + } catch ( jsonrpc::JsonRpcException const& _e ) { + return _e.GetMessage(); + } + return string(); + } + + string estimateGasShouldFail( Json::Value const& _t ) { + try { + rpcClient->eth_estimateGas( _t ); + BOOST_FAIL( "Exception expected." ); + } catch ( jsonrpc::JsonRpcException const& _e ) { + return _e.GetMessage(); + } + return string(); + } + + TransientDirectory tempDir; // ! should exist before client! + unique_ptr< Client > client; + + dev::KeyPair coinbase{ KeyPair::create() }; + dev::KeyPair account2{ KeyPair::create() }; + dev::KeyPair account3{ KeyPair::create() }; + unique_ptr< FixedAccountHolder > accountHolder; + unique_ptr< rpc::SessionManager > sessionManager; + std::shared_ptr< eth::TrivialGasPricer > gasPricer; + KeyManager keyManager{ KeyManager::defaultPath(), SecretStore::defaultPath() }; + unique_ptr< ModularServer<> > rpcServer; + unique_ptr< WebThreeStubClient > rpcClient; + std::string adminSession; + SkaleServerOverride* skale_server_connector; + jsonrpc::HttpClient* httpClient; + time_t powPatchActivationTimestamp; + time_t push0PatchActivationTimestamp; +}; + +#ifndef FAIR +struct RestrictedAddressFixture : public JsonRpcFixture { + RestrictedAddressFixture( + const std::string& _config = c_genesisConfigString, bool _mtmEnabled = false ) + : JsonRpcFixture( _config, true, true, false, _mtmEnabled ) { + setenv( "HOME", tempDir.path().c_str(), 1 ); // getDataDir() now points to the different + // directories for different tests + ownerAddress = Address( "00000000000000000000000000000000000000AA" ); + std::string fileName = "test"; + path = dev::getDataDir() / "filestorage" / Address( ownerAddress ).hex() / fileName; + data = + ( "0x" + "00000000000000000000000000000000000000000000000000000000000000AA" + "0000000000000000000000000000000000000000000000000000000000000004" + "7465737400000000000000000000000000000000000000000000000000000000" // test + "0000000000000000000000000000000000000000000000000000000000000004" ); + } + + ~RestrictedAddressFixture() override { remove( path.c_str() ); } + + Address ownerAddress; + std::string data; + boost::filesystem::path path; +}; +#endif + +string fromAscii( string _s ) { + bytes b = asBytes( _s ); + return toHexPrefixed( b ); +} +} // namespace + +#ifdef BITE +/// Helper functions + +dev::bytes formEncryptedMessageMockup( const dev::bytes& message, const dev::Address& toAddress ) { + RLPStream biteDataRlp( 2 ); + + biteDataRlp << message; + biteDataRlp << ( dev::Address::Arith ) toAddress; + + auto messageToEncrypt = biteDataRlp.out(); + auto encryptedMessage = libBLS::ThresholdEncryption::mockupEncrypt( messageToEncrypt ); + + u256 epochId = 0; + + RLPStream bitePayloadRlp( 2 ); + + bitePayloadRlp << epochId; + bitePayloadRlp << encryptedMessage; + + auto rlpBytes = bitePayloadRlp.out(); + return dev::bytes( rlpBytes.begin(), rlpBytes.end() ); +} + +std::string formTransactionRlp( const JsonRpcFixture& fixture, const std::string& senderAddress, + const std::string& data, size_t& nonce, + const std::string& toAddress = "0x5EdF1e852fdD1B0Bc47C0307EF755C76f4B9c251" ) { + Json::Value txEncryptedData; + txEncryptedData["to"] = toAddress; + txEncryptedData["from"] = senderAddress; + txEncryptedData["gas"] = "100000"; + txEncryptedData["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txEncryptedData["data"] = data; + txEncryptedData["nonce"] = nonce++; + + TransactionSkeleton ts = toTransactionSkeleton( txEncryptedData ); + ts = fixture.client->populateTransactionWithDefaults( ts ); + pair< bool, Secret > ar = fixture.accountHolder->authenticate( ts ); + Transaction tx( ts, ar.second ); + + return dev::toHexPrefixed( tx.toBytes() ); +} + +std::string formBITEPayloadRlp( u256 _epochId, const dev::bytes& _encryptedBITEData ) { + RLPStream bitePayloadRlp( 2 ); + + bitePayloadRlp << _epochId; + bitePayloadRlp << _encryptedBITEData; + + auto rlpBytes = bitePayloadRlp.out(); + return dev::toHexPrefixed( rlpBytes ); +} + +#endif // BITE + +BOOST_AUTO_TEST_SUITE( JsonRpcSuite ) + + +BOOST_AUTO_TEST_CASE( jsonrpc_gasPrice ) { + JsonRpcFixture fixture; + string gasPrice = fixture.rpcClient->eth_gasPrice(); + BOOST_CHECK_EQUAL( gasPrice, toJS( 20 * dev::eth::shannon ) ); +} + + +BOOST_AUTO_TEST_CASE( + jsonrpc_accounts, *boost::unit_test::precondition( dev::test::run_not_express ) ) { + JsonRpcFixture fixture; + std::vector< dev::KeyPair > keys = { KeyPair::create(), KeyPair::create() }; + fixture.accountHolder->setAccounts( keys ); + Json::Value k = fixture.rpcClient->eth_accounts(); + fixture.accountHolder->setAccounts( {} ); + BOOST_CHECK_EQUAL( k.isArray(), true ); + BOOST_CHECK_EQUAL( k.size(), keys.size() ); + for ( auto& i : k ) { + auto it = std::find_if( keys.begin(), keys.end(), [i]( dev::KeyPair const& keyPair ) { + return jsToAddress( i.asString() ) == keyPair.address(); + } ); + + BOOST_CHECK_EQUAL( it != keys.end(), true ); + } +} + +BOOST_AUTO_TEST_CASE( jsonrpc_number ) { + JsonRpcFixture fixture; + auto number = jsToU256( fixture.rpcClient->eth_blockNumber() ); + BOOST_CHECK_EQUAL( number, fixture.client->number() ); + dev::eth::mine( *( fixture.client ), 1 ); + auto numberAfter = jsToU256( fixture.rpcClient->eth_blockNumber() ); + BOOST_CHECK_GE( numberAfter, number + 1 ); + BOOST_CHECK_EQUAL( numberAfter, fixture.client->number() ); +} + + +BOOST_AUTO_TEST_CASE( jsonrpc_netVersion ) { + std::string _config = c_genesisConfigString; + Json::Value ret; + Json::Reader().parse( _config, ret ); + + // Set chainID = 65535 + ret["params"]["chainID"] = "0xffff"; + + Json::FastWriter fastWriter; + std::string config = fastWriter.write( ret ); + JsonRpcFixture fixture( config ); + + auto version = fixture.rpcClient->net_version(); + BOOST_CHECK_EQUAL( version, "65535" ); +} + +BOOST_AUTO_TEST_CASE( jsonrpc_setMining ) { + JsonRpcFixture fixture; + fixture.rpcClient->admin_eth_setMining( true, fixture.adminSession ); + BOOST_CHECK_EQUAL( fixture.client->wouldSeal(), true ); + + fixture.rpcClient->admin_eth_setMining( false, fixture.adminSession ); + BOOST_CHECK_EQUAL( fixture.client->wouldSeal(), false ); +} + +BOOST_AUTO_TEST_CASE( jsonrpc_stateAt ) { + JsonRpcFixture fixture; + dev::KeyPair key = KeyPair::create(); + auto address = key.address(); + string stateAt = fixture.rpcClient->eth_getStorageAt( toJS( address ), "0", "latest" ); + BOOST_CHECK_EQUAL( fixture.client->stateAt( address, 0 ), jsToU256( stateAt ) ); +} + +BOOST_AUTO_TEST_CASE( + eth_coinbase, *boost::unit_test::precondition( dev::test::run_not_express ) ) { + JsonRpcFixture fixture; + string coinbase = fixture.rpcClient->eth_coinbase(); + BOOST_REQUIRE_EQUAL( jsToAddress( coinbase ), fixture.client->author() ); +} + +BOOST_AUTO_TEST_CASE( eth_sendTransaction ) { + JsonRpcFixture fixture; + auto address = fixture.coinbase.address(); + u256 countAt = + jsToU256( fixture.rpcClient->eth_getTransactionCount( toJS( address ), "latest" ) ); + + BOOST_CHECK_EQUAL( countAt, fixture.client->countAt( address ) ); + BOOST_CHECK_EQUAL( countAt, 0 ); + u256 balance = fixture.client->balanceAt( address ); + string balanceString = fixture.rpcClient->eth_getBalance( toJS( address ), "latest" ); + BOOST_CHECK_EQUAL( toJS( balance ), balanceString ); + BOOST_CHECK_EQUAL( jsToDecimal( balanceString ), "0" ); + + dev::eth::simulateMining( *( fixture.client ), 1 ); + balance = fixture.client->balanceAt( address ); + balanceString = fixture.rpcClient->eth_getBalance( toJS( address ), "latest" ); + + BOOST_REQUIRE_GT( balance, 0 ); + BOOST_CHECK_EQUAL( toJS( balance ), balanceString ); + + + auto txAmount = balance / 2u; + auto gasPrice = 10 * dev::eth::szabo; + auto gas = EVMSchedule().txGas; + + auto receiver = KeyPair::create(); + + Json::Value t; + t["from"] = toJS( address ); + t["value"] = jsToDecimal( toJS( txAmount ) ); + t["to"] = toJS( receiver.address() ); + t["data"] = toJS( bytes() ); + t["gas"] = toJS( gas ); + t["gasPrice"] = toJS( gasPrice ); + + std::string txHash = fixture.rpcClient->eth_sendTransaction( t ); + BOOST_REQUIRE( !txHash.empty() ); + + fixture.accountHolder->setAccounts( {} ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + countAt = jsToU256( fixture.rpcClient->eth_getTransactionCount( toJS( address ), "latest" ) ); + u256 balance2 = fixture.client->balanceAt( receiver.address() ); + string balanceString2 = + fixture.rpcClient->eth_getBalance( toJS( receiver.address() ), "latest" ); + + BOOST_CHECK_EQUAL( countAt, fixture.client->countAt( address ) ); + BOOST_CHECK_EQUAL( countAt, 1 ); + BOOST_CHECK_EQUAL( toJS( balance2 ), balanceString2 ); + BOOST_CHECK_EQUAL( jsToU256( balanceString2 ), txAmount ); + BOOST_CHECK_EQUAL( txAmount, balance2 ); +} + +BOOST_AUTO_TEST_CASE( eth_sendRawTransaction_validTransaction, + + *boost::unit_test::precondition( dev::test::run_not_express ) ) { + JsonRpcFixture fixture; + auto senderAddress = fixture.coinbase.address(); + auto receiver = KeyPair::create(); + + Json::Value t; + t["from"] = toJS( senderAddress ); + t["to"] = toJS( receiver.address() ); + t["value"] = jsToDecimal( toJS( 10000 * dev::eth::szabo ) ); + + // Mine to generate a non-zero account balance + const int blocksToMine = 1; +#ifdef FAIR + const u256 blockReward = + fixture.client->chainParams().blockReward( fixture.client->blockChain().info().timestamp(), + fixture.client->blockChain().info().number() ); +#else + const u256 blockReward = 2 * dev::eth::ether; +#endif + dev::eth::simulateMining( *( fixture.client ), blocksToMine ); + BOOST_CHECK_EQUAL( blockReward, fixture.client->balanceAt( senderAddress ) ); + + auto signedTx = fixture.rpcClient->eth_signTransaction( t ); + BOOST_REQUIRE( !signedTx["raw"].empty() ); + + auto txHash = fixture.rpcClient->eth_sendRawTransaction( signedTx["raw"].asString() ); + BOOST_REQUIRE( !txHash.empty() ); +} + +BOOST_AUTO_TEST_CASE( eth_sendRawTransaction_errorZeroBalance ) { + JsonRpcFixture fixture; + auto senderAddress = fixture.coinbase.address(); + auto receiver = KeyPair::create(); + + BOOST_CHECK_EQUAL( 0, fixture.client->balanceAt( senderAddress ) ); + + Json::Value t; + t["from"] = toJS( senderAddress ); + t["to"] = toJS( receiver.address() ); + t["value"] = jsToDecimal( toJS( 10000 * dev::eth::szabo ) ); + + auto signedTx = fixture.rpcClient->eth_signTransaction( t ); + BOOST_REQUIRE( signedTx["raw"] ); + + BOOST_CHECK_EQUAL( fixture.sendingRawShouldFail( signedTx["raw"].asString() ), + "Account balance is too low (balance < value + gas * gas price)." ); +} + +BOOST_AUTO_TEST_CASE( eth_sendRawTransaction_errorInvalidNonce, + + *boost::unit_test::precondition( dev::test::run_not_express ) ) { + JsonRpcFixture fixture; + auto senderAddress = fixture.coinbase.address(); + auto receiver = KeyPair::create(); + + // Mine to generate a non-zero account balance + const size_t blocksToMine = 1; +#ifdef FAIR + const u256 blockReward = + fixture.client->chainParams().blockReward( fixture.client->blockChain().info().timestamp(), + fixture.client->blockChain().info().number() ); +#else + const u256 blockReward = 2 * dev::eth::ether; +#endif + dev::eth::simulateMining( *( fixture.client ), blocksToMine ); + BOOST_CHECK_EQUAL( blockReward, fixture.client->balanceAt( senderAddress ) ); + + Json::Value t; + t["from"] = toJS( senderAddress ); + t["to"] = toJS( receiver.address() ); + t["value"] = jsToDecimal( toJS( 10000 * dev::eth::szabo ) ); + + auto signedTx = fixture.rpcClient->eth_signTransaction( t ); + BOOST_REQUIRE( !signedTx["raw"].empty() ); + + auto txHash = fixture.rpcClient->eth_sendRawTransaction( signedTx["raw"].asString() ); + BOOST_REQUIRE( !txHash.empty() ); + + mineTransaction( *fixture.client, 1 ); + + auto invalidNonce = + jsToU256( fixture.rpcClient->eth_getTransactionCount( toJS( senderAddress ), "latest" ) ) - + 1; + t["nonce"] = jsToDecimal( toJS( invalidNonce ) ); + + signedTx = fixture.rpcClient->eth_signTransaction( t ); + BOOST_REQUIRE( !signedTx["raw"].empty() ); + + BOOST_CHECK_EQUAL( + fixture.sendingRawShouldFail( signedTx["raw"].asString() ), "Invalid transaction nonce." ); +} + +BOOST_AUTO_TEST_CASE( eth_sendRawTransaction_errorInsufficientGas ) { + JsonRpcFixture fixture; + auto senderAddress = fixture.coinbase.address(); + auto receiver = KeyPair::create(); + + // Mine to generate a non-zero account balance + const int blocksToMine = 1; +#ifdef FAIR + const u256 blockReward = + fixture.client->chainParams().blockReward( fixture.client->blockChain().info().timestamp(), + fixture.client->blockChain().info().number() ); +#else + const u256 blockReward = 2 * dev::eth::ether; +#endif + dev::eth::simulateMining( *( fixture.client ), blocksToMine ); + BOOST_CHECK_EQUAL( blockReward, fixture.client->balanceAt( senderAddress ) ); + + Json::Value t; + t["from"] = toJS( senderAddress ); + t["to"] = toJS( receiver.address() ); + t["value"] = jsToDecimal( toJS( 10000 * dev::eth::szabo ) ); + + const int minGasForValueTransferTx = 21000; + t["gas"] = jsToDecimal( toJS( minGasForValueTransferTx - 1 ) ); + + auto signedTx = fixture.rpcClient->eth_signTransaction( t ); + BOOST_REQUIRE( !signedTx["raw"].empty() ); + + BOOST_CHECK_EQUAL( fixture.sendingRawShouldFail( signedTx["raw"].asString() ), + "Transaction gas amount is less than the intrinsic gas amount for this transaction type." ); +} + +BOOST_AUTO_TEST_CASE( eth_sendRawTransaction_errorDuplicateTransaction ) { + JsonRpcFixture fixture; + auto senderAddress = fixture.coinbase.address(); + auto receiver = KeyPair::create(); + + // Mine to generate a non-zero account balance + const int blocksToMine = 1; +#ifdef FAIR + const u256 blockReward = + fixture.client->chainParams().blockReward( fixture.client->blockChain().info().timestamp(), + fixture.client->blockChain().info().number() ); +#else + const u256 blockReward = 2 * dev::eth::ether; +#endif + dev::eth::simulateMining( *( fixture.client ), blocksToMine ); + BOOST_CHECK_EQUAL( blockReward, fixture.client->balanceAt( senderAddress ) ); + + Json::Value t; + t["from"] = toJS( senderAddress ); + t["to"] = toJS( receiver.address() ); + t["value"] = jsToDecimal( toJS( 10000 * dev::eth::szabo ) ); + + auto signedTx = fixture.rpcClient->eth_signTransaction( t ); + BOOST_REQUIRE( !signedTx["raw"].empty() ); + + auto txHash = fixture.rpcClient->eth_sendRawTransaction( signedTx["raw"].asString() ); + BOOST_REQUIRE( !txHash.empty() ); + + auto txNonce = + jsToU256( fixture.rpcClient->eth_getTransactionCount( toJS( senderAddress ), "latest" ) ); + t["nonce"] = jsToDecimal( toJS( txNonce ) ); + + signedTx = fixture.rpcClient->eth_signTransaction( t ); + BOOST_REQUIRE( !signedTx["raw"].empty() ); + + BOOST_CHECK_EQUAL( fixture.sendingRawShouldFail( signedTx["raw"].asString() ), + "Same transaction already exists in the pending transaction queue." ); +} + +#ifdef FAIR + +/** + * Auxiliar function to mine a block to gather balance, + * and build a signed legacy pre-EIP155 transaction. + * Used to test acceptance vs. rejection of pre-EIP155 transactions + */ +Json::Value buildSignedTransaction( JsonRpcFixture& fixture ) { + auto receiver = KeyPair::create(); + auto senderAddress = fixture.coinbase.address(); + + // Mine to generate a non-zero account balance + const size_t blocksToMine = 1; + const u256 blockReward = + fixture.client->chainParams().blockReward( fixture.client->blockChain().info().timestamp(), + fixture.client->blockChain().info().number() ); + dev::eth::simulateMining( *( fixture.client ), blocksToMine ); + BOOST_CHECK_EQUAL( blockReward, fixture.client->balanceAt( senderAddress ) ); + + Json::Value sampleTx; + sampleTx["to"] = toJS( receiver.address() ); + sampleTx["from"] = toJS( senderAddress ); + sampleTx["gas"] = "100000"; + sampleTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + sampleTx["value"] = jsToDecimal( toJS( 10000 * dev::eth::szabo ) ); + sampleTx["data"] = "0x0"; + sampleTx["nonce"] = 0; + + return fixture.rpcClient->eth_signTransaction( sampleTx ); +}; + +BOOST_AUTO_TEST_CASE( eth_sendRawTransaction_acceptPreEIP155Txns_configOmitted ) { + std::string _config = c_genesisConfigString; + Json::Value ret; + Json::Reader().parse( _config, ret ); + Json::FastWriter fastWriter; + + // 'allowPreEIP155Txns' field is not set -> should be allowed by default + std::string config = fastWriter.write( ret ); + JsonRpcFixture fixture( config ); + auto signedTx = buildSignedTransaction( fixture ); + std::string txHash = fixture.rpcClient->eth_sendRawTransaction( signedTx["raw"].asString() ); + BOOST_REQUIRE( !txHash.empty() ); +} + +BOOST_AUTO_TEST_CASE( eth_sendRawTransaction_acceptPreEIP155Txns_configTrue ) { + std::string _config = c_genesisConfigString; + Json::Value ret; + Json::Reader().parse( _config, ret ); + Json::FastWriter fastWriter; + + // 'allowPreEIP155Txns' field is set to true -> should be allowed + ret["params"]["allowPreEIP155Txns"] = true; + std::string config = fastWriter.write( ret ); + JsonRpcFixture fixture( config ); + auto signedTx = buildSignedTransaction( fixture ); + std::string txHash = fixture.rpcClient->eth_sendRawTransaction( signedTx["raw"].asString() ); + BOOST_REQUIRE( !txHash.empty() ); +} + +BOOST_AUTO_TEST_CASE( eth_sendRawTransaction_rejectPreEIP155Txns_configFalse ) { + std::string _config = c_genesisConfigString; + Json::Value ret; + Json::Reader().parse( _config, ret ); + Json::FastWriter fastWriter; + + // 'allowPreEIP155Txns' field is set to false -> should be rejected + ret["params"]["allowPreEIP155Txns"] = false; + std::string config = fastWriter.write( ret ); + JsonRpcFixture fixture( config ); + auto signedTx = buildSignedTransaction( fixture ); + + std::cout << "Raw transaction: " << signedTx["raw"].asString() << std::endl; + BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendRawTransaction( signedTx["raw"].asString() ), + jsonrpc::JsonRpcException ); +} + +#endif + + +BOOST_AUTO_TEST_CASE( send_raw_tx_sync ) { + // Enable sync mode + JsonRpcFixture fixture( c_genesisConfigString, true, true, true, false, true ); + Address senderAddress = fixture.coinbase.address(); + fixture.client->setAuthor( senderAddress ); + + // contract test { + // function f(uint a) returns(uint d) { return a * 7; } + // } + + string compiled = + "6080604052341561000f57600080fd5b60b98061001d6000396000f300" + "608060405260043610603f576000357c01000000000000000000000000" + "00000000000000000000000000000000900463ffffffff168063b3de64" + "8b146044575b600080fd5b3415604e57600080fd5b606a600480360381" + "019080803590602001909291905050506080565b604051808281526020" + "0191505060405180910390f35b60006007820290509190505600a16562" + "7a7a72305820f294e834212334e2978c6dd090355312a3f0f9476b8eb9" + "8fb480406fc2728a960029"; + + Json::Value create; + create["code"] = compiled; + create["gas"] = "180000"; + + BOOST_REQUIRE( fixture.client->transactionQueueStatus().current == 0 ); + + // Sending tx to sync node + string txHash = fixture.rpcClient->eth_sendTransaction( create ); + + auto pendingTransactions = fixture.client->pending(); + BOOST_REQUIRE( pendingTransactions.size() == 1 ); + auto txHashFromQueue = "0x" + pendingTransactions[0].sha3().hex(); + BOOST_REQUIRE( txHashFromQueue == txHash ); +} + +BOOST_AUTO_TEST_CASE( eth_signTransaction ) { + JsonRpcFixture fixture; + auto address = fixture.coinbase.address(); + auto countAtBeforeSign = + jsToU256( fixture.rpcClient->eth_getTransactionCount( toJS( address ), "latest" ) ); + auto receiver = KeyPair::create(); + + Json::Value t; + t["from"] = toJS( address ); + t["value"] = jsToDecimal( toJS( 1 ) ); + t["to"] = toJS( receiver.address() ); + + Json::Value res = fixture.rpcClient->eth_signTransaction( t ); + BOOST_REQUIRE( res["raw"] ); + BOOST_REQUIRE( res["tx"] ); + + fixture.accountHolder->setAccounts( {} ); + dev::eth::mine( *( fixture.client ), 1 ); + + auto countAtAfterSign = + jsToU256( fixture.rpcClient->eth_getTransactionCount( toJS( address ), "latest" ) ); + + BOOST_CHECK_EQUAL( countAtBeforeSign, countAtAfterSign ); +} + + +const string skaledConfigFileName = "../../test/historicstate/configs/basic_config.json"; + + +BOOST_AUTO_TEST_CASE( simple_contract ) { + JsonRpcFixture fixture; + dev::eth::simulateMining( *( fixture.client ), 1 ); + + // pragma solidity 0.8.4; + // contract test { + // uint value; + // function f(uint a) public pure returns(uint d) { + // return a * 7; + // } + // function setValue(uint _value) external { + // value = _value; + // } + // } + + string compiled = + "608060405234801561001057600080fd5b506101ef8061002060003" + "96000f3fe608060405234801561001057600080fd5b506004361061" + "00365760003560e01c8063552410771461003b578063b3de648b146" + "10057575b600080fd5b610055600480360381019061005091906100" + "bc565b610087565b005b610071600480360381019061006c9190610" + "0bc565b610091565b60405161007e91906100f4565b604051809103" + "90f35b8060008190555050565b60006007826100a0919061010f565" + "b9050919050565b6000813590506100b6816101a2565b9291505056" + "5b6000602082840312156100ce57600080fd5b60006100dc8482850" + "16100a7565b91505092915050565b6100ee81610169565b82525050" + "565b600060208201905061010960008301846100e5565b929150505" + "65b600061011a82610169565b915061012583610169565b9250817f" + "fffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "fffffffff048311821515161561015e5761015d610173565b5b8282" + "02905092915050565b6000819050919050565b7f4e487b710000000" + "0000000000000000000000000000000000000000000000000600052" + "601160045260246000fd5b6101ab81610169565b81146101b657600" + "080fd5b5056fea26469706673582212200be8156151b5ef7c250fa7" + "b8c8ed4e2a1c32cd526f9c868223f6838fa1193c9e64736f6c63430" + "008040033"; + + Json::Value create; + create["code"] = compiled; + create["gas"] = "180000"; // TODO or change global default of 90000? + + BOOST_CHECK_EQUAL( jsToU256( fixture.rpcClient->eth_blockNumber() ), 1 ); + BOOST_CHECK_EQUAL( jsToU256( fixture.rpcClient->eth_getTransactionCount( + toJS( fixture.coinbase.address() ), "latest" ) ), + 0 ); + + string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( !receipt["contractAddress"].isNull() ); + string contractAddress = receipt["contractAddress"].asString(); + BOOST_REQUIRE( contractAddress != "null" ); + + Json::Value call; + call["to"] = contractAddress; + call["data"] = "0xb3de648b0000000000000000000000000000000000000000000000000000000000000001"; + call["gas"] = "1000000"; + call["gasPrice"] = "0"; + string result = fixture.rpcClient->eth_call( call, "latest" ); + BOOST_CHECK_EQUAL( + result, "0x0000000000000000000000000000000000000000000000000000000000000007" ); + + Json::Value inputCall; + inputCall["to"] = contractAddress; + inputCall["input"] = + "0xb3de648b0000000000000000000000000000000000000000000000000000000000000001"; + inputCall["gas"] = "1000000"; + inputCall["gasPrice"] = "0"; + result = fixture.rpcClient->eth_call( inputCall, "latest" ); + BOOST_CHECK_EQUAL( + result, "0x0000000000000000000000000000000000000000000000000000000000000007" ); + + Json::Value transact; + transact["to"] = contractAddress; + transact["data"] = "0x552410770000000000000000000000000000000000000000000000000000000000000001"; + txHash = fixture.rpcClient->eth_sendTransaction( transact ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + auto res = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE_EQUAL( res["status"], string( "0x1" ) ); + + Json::Value inputTx; + inputTx["to"] = contractAddress; + inputTx["input"] = "0x552410770000000000000000000000000000000000000000000000000000000000000002"; + txHash = fixture.rpcClient->eth_sendTransaction( inputTx ); + + dev::eth::mineTransaction( *( fixture.client ), 1 ); + res = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE_EQUAL( res["status"], string( "0x1" ) ); +} + +BOOST_AUTO_TEST_CASE( deploy_contract_from_owner ) { + JsonRpcFixture fixture( c_genesisConfigString ); + Address senderAddress = fixture.coinbase.address(); + + fixture.client->setAuthor( senderAddress ); + dev::eth::simulateMining( *( fixture.client ), 1 ); + + // contract test { + // function f(uint a) returns(uint d) { return a * 7; } + // } + + string compiled = + "6080604052341561000f57600080fd5b60b98061001d6000396000f300" + "608060405260043610603f576000357c01000000000000000000000000" + "00000000000000000000000000000000900463ffffffff168063b3de64" + "8b146044575b600080fd5b3415604e57600080fd5b606a600480360381" + "019080803590602001909291905050506080565b604051808281526020" + "0191505060405180910390f35b60006007820290509190505600a16562" + "7a7a72305820f294e834212334e2978c6dd090355312a3f0f9476b8eb9" + "8fb480406fc2728a960029"; + + Json::Value create; + + create["from"] = toJS( senderAddress ); + create["code"] = compiled; + create["gas"] = "1000000"; + + string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + + BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x1" ) ); + BOOST_REQUIRE( !receipt["contractAddress"].isNull() ); + Json::Value code = + fixture.rpcClient->eth_getCode( receipt["contractAddress"].asString(), "latest" ); + BOOST_REQUIRE( code.asString().substr( 2 ) == compiled.substr( 58 ) ); +} + +BOOST_AUTO_TEST_CASE( deploy_contract_not_from_owner ) { + JsonRpcFixture fixture( c_genesisConfigString, false ); + auto senderAddress = fixture.coinbase.address(); + + fixture.client->setAuthor( senderAddress ); + dev::eth::simulateMining( *( fixture.client ), 1 ); + + // contract test { + // function f(uint a) returns(uint d) { return a * 7; } + // } + + string compiled = + "6080604052341561000f57600080fd5b60b98061001d6000396000f300" + "608060405260043610603f576000357c01000000000000000000000000" + "00000000000000000000000000000000900463ffffffff168063b3de64" + "8b146044575b600080fd5b3415604e57600080fd5b606a600480360381" + "019080803590602001909291905050506080565b604051808281526020" + "0191505060405180910390f35b60006007820290509190505600a16562" + "7a7a72305820f294e834212334e2978c6dd090355312a3f0f9476b8eb9" + "8fb480406fc2728a960029"; + + Json::Value create; + + create["from"] = toJS( senderAddress ); + create["code"] = compiled; + create["gas"] = "1000000"; + + string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); +#ifdef FAIR + BOOST_CHECK_EQUAL( receipt["status"], string( "0x1" ) ); + Json::Value code = + fixture.rpcClient->eth_getCode( receipt["contractAddress"].asString(), "latest" ); + BOOST_REQUIRE( code.asString() == + "0x608060405260043610603f576000357c010000000000000000000000000000000000000000000" + "0000000000000900463ffffffff168063b3de648b146044575b600080fd5b3415604e57600080fd" + "5b606a600480360381019080803590602001909291905050506080565b604051808281526020019" + "1505060405180910390f35b60006007820290509190505600a165627a7a72305820f294e8342123" + "34e2978c6dd090355312a3f0f9476b8eb98fb480406fc2728a960029" ); +#else + BOOST_CHECK_EQUAL( receipt["status"], string( "0x0" ) ); + Json::Value code = + fixture.rpcClient->eth_getCode( receipt["contractAddress"].asString(), "latest" ); + BOOST_REQUIRE( code.asString() == "0x" ); +#endif +} + +BOOST_AUTO_TEST_CASE( deploy_contract_without_controller ) { + std::string _config = c_genesisConfigString; + Json::Value ret; + Json::Reader().parse( _config, ret ); + ret["accounts"].removeMember( "0xD2002000000000000000000000000000000000D2" ); + Json::FastWriter fastWriter; + std::string config = fastWriter.write( ret ); + JsonRpcFixture fixture( config, false, false ); + auto senderAddress = fixture.coinbase.address(); + + fixture.client->setAuthor( senderAddress ); + dev::eth::simulateMining( *( fixture.client ), 1 ); + + // contract test { + // function f(uint a) returns(uint d) { return a * 7; } + // } + + string compiled = + "6080604052341561000f57600080fd5b60b98061001d6000396000f300" + "608060405260043610603f576000357c01000000000000000000000000" + "00000000000000000000000000000000900463ffffffff168063b3de64" + "8b146044575b600080fd5b3415604e57600080fd5b606a600480360381" + "019080803590602001909291905050506080565b604051808281526020" + "0191505060405180910390f35b60006007820290509190505600a16562" + "7a7a72305820f294e834212334e2978c6dd090355312a3f0f9476b8eb9" + "8fb480406fc2728a960029"; + + Json::Value create; + + create["from"] = toJS( senderAddress ); + create["code"] = compiled; + create["gas"] = "1000000"; + + string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x1" ) ); + BOOST_REQUIRE( !receipt["contractAddress"].isNull() ); + Json::Value code = + fixture.rpcClient->eth_getCode( receipt["contractAddress"].asString(), "latest" ); + BOOST_REQUIRE( code.asString().substr( 2 ) == compiled.substr( 58 ) ); +} + +#ifndef FAIR +BOOST_AUTO_TEST_CASE( deploy_contract_with_controller ) { + JsonRpcFixture fixture( c_genesisConfigString, false ); + auto senderAddress = fixture.coinbase.address(); + + fixture.client->setAuthor( senderAddress ); + dev::eth::simulateMining( *( fixture.client ), 1 ); + + // contract test { + // function f(uint a) returns(uint d) { return a * 7; } + // } + + string compiled = + "6080604052341561000f57600080fd5b60b98061001d6000396000f300" + "608060405260043610603f576000357c01000000000000000000000000" + "00000000000000000000000000000000900463ffffffff168063b3de64" + "8b146044575b600080fd5b3415604e57600080fd5b606a600480360381" + "019080803590602001909291905050506080565b604051808281526020" + "0191505060405180910390f35b60006007820290509190505600a16562" + "7a7a72305820f294e834212334e2978c6dd090355312a3f0f9476b8eb9" + "8fb480406fc2728a960029"; + + Json::Value create; + + create["from"] = toJS( senderAddress ); + create["code"] = compiled; + create["gas"] = "1000000"; + + string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_CHECK_EQUAL( receipt["status"], string( "0x0" ) ); + Json::Value code = + fixture.rpcClient->eth_getCode( receipt["contractAddress"].asString(), "latest" ); + BOOST_REQUIRE( code.asString() == "0x" ); +} +#endif + + +BOOST_AUTO_TEST_CASE( create_opcode ) { + JsonRpcFixture fixture( c_genesisConfigString ); + auto senderAddress = fixture.coinbase.address(); + + fixture.client->setAuthor( senderAddress ); + dev::eth::simulateMining( *( fixture.client ), 1 ); + + /* + pragma solidity ^0.4.25; + + contract test { + address public a; + + function f() public { + address _address; + assembly { + let ptr := mload(0x40) + _address := create(0x00,ptr,0x20) + } + a = _address; + } + } +*/ + + string compiled = + "608060405234801561001057600080fd5b50610161806100206000396000f30060806040526004361061004c57" + "6000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630dbe" + "671f1461005157806326121ff0146100a8575b600080fd5b34801561005d57600080fd5b506100666100bf565b" + "604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffff" + "ffffff16815260200191505060405180910390f35b3480156100b457600080fd5b506100bd6100e4565b005b60" + "00809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060405160208160" + "00f0915050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffff" + "ffffffffffffffffffffffffffffffffffff160217905550505600a165627a7a72305820fc6f465560bc93346a" + "25f87ff189a58c26f5bf6f2e46570058fd79c1a3c3063a0029"; + + Json::Value create; + + create["from"] = toJS( senderAddress ); + create["code"] = compiled; + create["gas"] = "1000000"; + + string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + string contractAddress = receipt["contractAddress"].asString(); + + fixture.client->setAuthor( fixture.account2.address() ); + dev::eth::simulateMining( *( fixture.client ), 1 ); + + Json::Value transactionCallObject; + + transactionCallObject["from"] = toJS( fixture.account2.address() ); + transactionCallObject["to"] = contractAddress; + transactionCallObject["data"] = "0x26121ff0"; + + fixture.rpcClient->eth_sendTransaction( transactionCallObject ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value checkAddress; + checkAddress["to"] = contractAddress; + checkAddress["data"] = "0x0dbe671f"; + string response1 = fixture.rpcClient->eth_call( checkAddress, "latest" ); + BOOST_CHECK( + response1 != "0x0000000000000000000000000000000000000000000000000000000000000000" ); + + fixture.client->setAuthor( senderAddress ); + transactionCallObject["from"] = toJS( senderAddress ); + fixture.rpcClient->eth_sendTransaction( transactionCallObject ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + string response2 = fixture.rpcClient->eth_call( checkAddress, "latest" ); + BOOST_CHECK( + response2 != "0x0000000000000000000000000000000000000000000000000000000000000000" ); + BOOST_CHECK( response2 != response1 ); +} + +BOOST_AUTO_TEST_CASE( push0_patch_activation ) { + JsonRpcFixture fixture; + auto senderAddress = fixture.coinbase.address(); + + fixture.client->setAuthor( senderAddress ); + dev::eth::simulateMining( *( fixture.client ), 1 ); + + fixture.client->setAuthor( fixture.account2.address() ); + dev::eth::simulateMining( *( fixture.client ), 1 ); + + /* + // SPDX-License-Identifier: GPL-3.0 + + pragma solidity >=0.8.2; + + contract Push0Test { + fallback() external payable { + assembly { + let t := add(9, 10) + } + } + } + + then convert to yul: --ir p0test.sol` >p0test.yul + + then change code: + { + let r := add(88,99) + let tmp := verbatim_0i_1o(hex"5f") + } + + then compile! + + */ + string compiled = + "608060405234156100135761001261003b565b5b61001b610040565b610023610031565b6101b7610043823961" + "01b781f35b6000604051905090565b600080fd5b56fe608060405261000f36600061015b565b805160208201f3" + "5b60006060905090565b6000604051905090565b6000601f19601f8301169050919050565b7f4e487b71000000" + "00000000000000000000000000000000000000000000000000600052604160045260246000fd5b610073826100" + "2a565b810181811067ffffffffffffffff821117156100925761009161003b565b5b80604052505050565b6000" + "6100a5610020565b90506100b1828261006a565b919050565b600067ffffffffffffffff8211156100d1576100" + "d061003b565b5b6100da8261002a565b9050602081019050919050565b60006100f2826100b6565b6100fb8161" + "009b565b915082825250919050565b7f7375636365737300000000000000000000000000000000000000000000" + "000000600082015250565b600061013b60076100e7565b905061014960208201610106565b90565b6000610156" + "61012f565b905090565b6000610165610017565b809150600a6009015f505061017861014c565b915050929150" + "5056fea2646970667358221220b3871ed09fbcbb1dac74c3cd48dafa5d097bea7c808b5ff2c16a996cf108d3c6" + "64736f6c63430008190033"; + // "60806040523415601057600f6031565b5b60166036565b601c6027565b604c60398239604c81f35b6000604051905090565b600080fd5b56fe6080604052600a600c565b005b60636058015f505056fea2646970667358221220ee9861b869ceda6de64f2ec7ccbebf2babce54b35502a866a4193e05ae595e1f64736f6c63430008130033"; + + Json::Value create; + + create["from"] = toJS( senderAddress ); + create["code"] = compiled; + create["gas"] = "1000000"; + + string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x1" ) ); // deploy should succeed + string contractAddress = receipt["contractAddress"].asString(); + + Json::Value callObject; + + callObject["from"] = toJS( fixture.account2.address() ); + callObject["to"] = contractAddress; + +#ifndef FAIR + // first try without PushZeroPatch + + txHash = fixture.rpcClient->eth_sendTransaction( callObject ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x0" ) ); // exec should fail + + string callResult = fixture.rpcClient->eth_call( callObject, "latest" ); + BOOST_REQUIRE_EQUAL( callResult, string( "0x" ) ); // call too + + // wait for block after timestamp + BOOST_REQUIRE_LT( fixture.client->blockInfo( LatestBlock ).timestamp(), + fixture.push0PatchActivationTimestamp ); + while ( time( nullptr ) < fixture.push0PatchActivationTimestamp ) + sleep( 1 ); + + // 1st timestamp-crossing block + txHash = fixture.rpcClient->eth_sendTransaction( callObject ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + BOOST_REQUIRE_GE( fixture.client->blockInfo( LatestBlock ).timestamp(), + fixture.push0PatchActivationTimestamp ); +#endif + +#ifdef HISTORIC_STATE + uint64_t crossingBlockNumber = fixture.client->number(); +#endif + +#ifndef FAIR + // in the "crossing" block tx still should fail + receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x0" ) ); +#endif + + // in 1st block with patch call should succeed + auto callResult1 = fixture.rpcClient->eth_call( callObject, "latest" ); + BOOST_REQUIRE_NE( callResult1, string( "0x" ) ); + + // tx should succeed too + txHash = fixture.rpcClient->eth_sendTransaction( callObject ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x1" ) ); + +#ifdef HISTORIC_STATE +#ifndef FAIR + // historic call should fail before activation and succees after it + callResult1 = fixture.rpcClient->eth_call( callObject, toJS( crossingBlockNumber - 1 ) ); + BOOST_REQUIRE_EQUAL( callResult1, string( "0x" ) ); +#endif // FAIR + + callResult1 = fixture.rpcClient->eth_call( callObject, toJS( crossingBlockNumber ) ); + BOOST_REQUIRE_NE( callResult1, string( "0x" ) ); +#endif // HISTORIC_STATE +} + +BOOST_AUTO_TEST_CASE( eth_estimateGas ) { + JsonRpcFixture fixture( c_genesisConfigString ); + + // This contract is predeployed on SKALE test network + // on address 0xD2001300000000000000000000000000000000D4 + + // pragma solidity 0.6.0; + // contract Test { + // ... + // function testRequire(uint gasConsumed) public { + // uint initialGas = gasleft(); + // while (initialGas - gasleft() < gasConsumed) {} + // require(1 == 0); + // initialGas = gasleft(); + // while (initialGas - gasleft() < gasConsumed) {} + // } + // + // function testRevert(uint gasConsumed) public { + // uint initialGas = gasleft(); + // while (initialGas - gasleft() < gasConsumed) {} + // revert(); + // initialGas = gasleft(); + // while (initialGas - gasleft() < gasConsumed) {} + // } + // + // function testRequireOff(uint gasConsumed) public { + // uint initialGas = gasleft(); + // while (initialGas - gasleft() < gasConsumed) {} + // require(true); + // initialGas = gasleft(); + // while (initialGas - gasleft() < gasConsumed) {} + // } + // } + + // data to call method testRevert(50000) + + Json::Value testRevert; + testRevert["to"] = "0xD2001300000000000000000000000000000000D4"; + testRevert["data"] = + "0x20987767000000000000000000000000000000000000000000000000000000000000c350"; + string response = fixture.estimateGasShouldFail( testRevert ); + BOOST_CHECK( + response.find( "EVM revert instruction without description message" ) != string::npos ); + + Json::Value testPositive; + testPositive["to"] = "0xD2001300000000000000000000000000000000D4"; + testPositive["data"] = + "0xfdde8d66000000000000000000000000000000000000000000000000000000000000c350"; + response = fixture.rpcClient->eth_estimateGas( testPositive ); + string response2 = fixture.rpcClient->eth_estimateGas( testPositive, "latest" ); + string response3 = fixture.rpcClient->eth_estimateGas( testPositive, "1" ); + BOOST_CHECK_EQUAL( response, "0x1db20" ); + BOOST_CHECK_EQUAL( response2, "0x1db20" ); + BOOST_CHECK_EQUAL( response3, "0x1db20" ); +} + +BOOST_AUTO_TEST_CASE( eth_estimateGas_chainId ) { + std::string _config = c_genesisConfigString; + Json::Value ret; + Json::Reader().parse( _config, ret ); + + // Set chainID = 65535 + ret["params"]["chainID"] = "0xffff"; + + Json::FastWriter fastWriter; + std::string config = fastWriter.write( ret ); + JsonRpcFixture fixture( config ); + + // pragma solidity ^0.8.13; + + // contract Counter { + // error BlockNumber(uint256 blockNumber); + + // constructor() { + // revert BlockNumber(block.chainid); + // } + // } + + Json::Value testRevert; + testRevert["data"] = + "0x6080604052348015600f57600080fd5b50604051633013bad360e21b81524660048201526024016040518091" + "0390fdfe"; + + try { + fixture.rpcClient->eth_estimateGas( testRevert, "latest" ); + } catch ( jsonrpc::JsonRpcException& ex ) { + BOOST_CHECK_EQUAL( ex.GetCode(), 3 ); + BOOST_CHECK_EQUAL( ex.GetData().asString(), + "0xc04eeb4c000000000000000000000000000000000000000000000000000000000000ffff" ); + BOOST_CHECK_EQUAL( ex.GetMessage(), "EVM revert instruction without description message" ); + } +} + +BOOST_AUTO_TEST_CASE( eth_sendRawTransaction_gasLimitExceeded ) { + JsonRpcFixture fixture; + auto senderAddress = fixture.coinbase.address(); + dev::eth::simulateMining( *( fixture.client ), 1 ); + + // We change author because coinbase.address() is author address by default + // and will take all transaction fee after execution so we can't check money spent + // for senderAddress correctly. + fixture.client->setAuthor( Address( 5 ) ); + + // contract test { + // function f(uint a) returns(uint d) { return a * 7; } + // } + + string compiled = + "6080604052341561000f57600080fd5b60b98061001d6000396000f300" + "608060405260043610603f576000357c01000000000000000000000000" + "00000000000000000000000000000000900463ffffffff168063b3de64" + "8b146044575b600080fd5b3415604e57600080fd5b606a600480360381" + "019080803590602001909291905050506080565b604051808281526020" + "0191505060405180910390f35b60006007820290509190505600a16562" + "7a7a72305820f294e834212334e2978c6dd090355312a3f0f9476b8eb9" + "8fb480406fc2728a960029"; + + Json::Value create; + int gas = 82000; // not enough but will pass size check + string gasPrice = "100000000000"; // 100b + create["from"] = toJS( senderAddress ); + create["code"] = compiled; + create["gas"] = gas; + create["gasPrice"] = gasPrice; + + BOOST_CHECK_EQUAL( jsToU256( fixture.rpcClient->eth_blockNumber() ), 1 ); + BOOST_CHECK_EQUAL( jsToU256( fixture.rpcClient->eth_getTransactionCount( + toJS( fixture.coinbase.address() ), "latest" ) ), + 0 ); + + u256 balanceBefore = jsToU256( + fixture.rpcClient->eth_getBalance( toJS( fixture.coinbase.address() ), "latest" ) ); + + BOOST_REQUIRE_EQUAL( jsToU256( fixture.rpcClient->eth_getTransactionCount( + toJS( fixture.coinbase.address() ), "latest" ) ), + 0 ); + + string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + u256 balanceAfter = jsToU256( + fixture.rpcClient->eth_getBalance( toJS( fixture.coinbase.address() ), "latest" ) ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + + BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x0" ) ); + BOOST_REQUIRE_EQUAL( balanceBefore - balanceAfter, u256( gas ) * u256( gasPrice ) ); +} + +BOOST_AUTO_TEST_CASE( contract_storage ) { + JsonRpcFixture fixture; + dev::eth::simulateMining( *( fixture.client ), 1 ); + + + // pragma solidity ^0.4.22; + + // contract test + // { + // uint hello; + // function writeHello(uint value) returns(bool d) + // { + // hello = value; + // return true; + // } + // } + + + string compiled = + "6080604052341561000f57600080fd5b60c28061001d6000396000f3006" + "08060405260043610603f576000357c0100000000000000000000000000" + "000000000000000000000000000000900463ffffffff16806315b2eec31" + "46044575b600080fd5b3415604e57600080fd5b606a6004803603810190" + "80803590602001909291905050506084565b60405180821515151581526" + "0200191505060405180910390f35b600081600081905550600190509190" + "505600a165627a7a72305820d8407d9cdaaf82966f3fa7a3e665b8cf4e6" + "5ee8909b83094a3f856b9051274500029"; + + Json::Value create; + create["code"] = compiled; + create["gas"] = "180000"; // TODO or change global default of 90000? + string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( !receipt["contractAddress"].isNull() ); + string contractAddress = receipt["contractAddress"].asString(); + BOOST_REQUIRE( contractAddress != "null" ); + + Json::Value transact; + transact["to"] = contractAddress; + transact["data"] = "0x15b2eec30000000000000000000000000000000000000000000000000000000000000003"; + string txHash2 = fixture.rpcClient->eth_sendTransaction( transact ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + string storage = fixture.rpcClient->eth_getStorageAt( contractAddress, "0", "latest" ); + BOOST_CHECK_EQUAL( + storage, "0x0000000000000000000000000000000000000000000000000000000000000003" ); + + Json::Value receipt2 = fixture.rpcClient->eth_getTransactionReceipt( txHash2 ); + string contractAddress2 = receipt2["contractAddress"].asString(); + BOOST_REQUIRE( receipt2["contractAddress"].isNull() ); +} + +BOOST_AUTO_TEST_CASE( web3_sha3, *boost::unit_test::precondition( dev::test::run_not_express ) ) { + JsonRpcFixture fixture; + string testString = "multiply(uint256)"; + h256 expected = dev::sha3( testString ); + + auto hexValue = fromAscii( testString ); + string result = fixture.rpcClient->web3_sha3( hexValue ); + BOOST_CHECK_EQUAL( toJS( expected ), result ); + BOOST_CHECK_EQUAL( + "0xc6888fa159d67f77c2f3d7a402e199802766bd7e8d4d1ecd2274fc920265d56a", result ); +} + +BOOST_AUTO_TEST_CASE( test_importRawBlock ) { + JsonRpcFixture fixture( c_genesisConfigString ); + string blockHash = fixture.rpcClient->test_importRawBlock( + "0xf90279f9020ea0" + // "c92211c9cd49036c37568feedb8e518a24a77e9f6ca959931a19dcf186a8e1e6" + // TODO this is our genesis (with stateRoot=1!) hash - just generated from code; need to + // check it by hands + "b449751a1ccedfcdae41640170e1712e8100d45061e6945f8fc7f556034d61ea" + "a01dcc4de8" + "dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347942adc25665018aa1fe0e6bc666dac8fc2" + "697ff9baa0328f16ca7b0259d7617b3ddf711c107efe6d5785cbeb11a8ed1614b484a6bc3aa093ca2a18d52e7c" + "1846f7b104e2fc1e5fdc71ebe38187248f9437d39e74f43aaba0f5a4cad211681b78d25e6fde8dea45961dd1d2" + "22a43e4d75e3b7733e50889203b901000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "00008304000001830f460f82a0348203e897d68094312e342e302b2b62383163726c696e7578676e75a08e2042" + "e00086a18e2f095bc997dc11d1c93fcf34d0540a428ee95869a4a62264883f8fd3f43a3567c3f865f863800183" + "061a8094095e7baea6a6c7c4c2dfeb977efac326af552d87830186a0801ca0e94818d1f3b0c69eb37720145a5e" + "ad7fbf6f8d80139dd53953b4a782301050a3a01fcf46908c01576715411be0857e30027d6be3250a3653f049b3" + "ff8d74d2540cc0" ); + + // blockHash, "0xedef94eddd6002ae14803b91aa5138932f948026310144fc615d52d7d5ff29c7" ); + // TODO again, this was computed just in code - no trust to it + std::cout << blockHash << std::endl; + BOOST_CHECK_EQUAL( + blockHash, "0x7683f686a7ecf6949d29cab2075b8aa45f061e27338e61ea3c37a7a0bd80f17b" ); +} + +BOOST_AUTO_TEST_CASE( call_from_parameter ) { + JsonRpcFixture fixture; + dev::eth::simulateMining( *( fixture.client ), 1 ); + + + // pragma solidity ^0.5.1; + + // contract Test + // { + + // function whoAmI() public view returns (address) { + // return msg.sender; + // } + // } + + + string compiled = + "608060405234801561001057600080fd5b5060c68061001f6000396000f" + "3fe6080604052600436106039576000357c010000000000000000000000" + "000000000000000000000000000000000090048063da91254c14603e575" + "b600080fd5b348015604957600080fd5b5060506092565b604051808273" + "ffffffffffffffffffffffffffffffffffffffff1673fffffffffffffff" + "fffffffffffffffffffffffff16815260200191505060405180910390f3" + "5b60003390509056fea165627a7a72305820abfa953fead48d8f657bca6" + "57713501650734d40342585cafcf156a3fe1f41d20029"; + + auto senderAddress = fixture.coinbase.address(); + + Json::Value create; + create["from"] = toJS( senderAddress ); + create["code"] = compiled; + create["gas"] = "180000"; // TODO or change global default of 90000? + string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + std::cout << cc::now2string() << " eth_getTransactionReceipt" << std::endl; + Json::Value receipt; + try { + receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + } catch ( ... ) { + std::cout << cc::now2string() << " /eth_getTransactionReceipt" << std::endl; + throw; + } + std::cout << cc::now2string() << " /eth_getTransactionReceipt" << std::endl; + string contractAddress = receipt["contractAddress"].asString(); + + Json::Value transactionCallObject; + transactionCallObject["to"] = contractAddress; + transactionCallObject["data"] = "0xda91254c"; + + fixture.accountHolder->setAccounts( vector< dev::KeyPair >() ); + + string responseString = fixture.rpcClient->eth_call( transactionCallObject, "latest" ); + BOOST_CHECK_EQUAL( + responseString, "0x0000000000000000000000000000000000000000000000000000000000000000" ); + + transactionCallObject["from"] = "0x112233445566778899aabbccddeeff0011223344"; + + responseString = fixture.rpcClient->eth_call( transactionCallObject, "latest" ); + BOOST_CHECK_EQUAL( + responseString, "0x000000000000000000000000112233445566778899aabbccddeeff0011223344" ); +} + + +BOOST_AUTO_TEST_CASE( call_with_error ) { + JsonRpcFixture fixture; + dev::eth::simulateMining( *( fixture.client ), 1 ); + + // pragma solidity ^0.8.0; + // contract BasicCustomErrorContract { + // // Define custom errors + // error InsufficientBalance(); + // error Unauthorized(); + // address public owner; + // // Function only callable by the owner + // function ownerOnlyFunction() external { + // revert Unauthorized(); + // } + // } + + string compiled = + "608060405234801561001057600080fd5b50610168806100206000396000f3fe608060" + "405234801561001057600080fd5b5060043610610053576000357c0100000000000000" + "000000000000000000000000000000000000000000900480638da5cb5b146100585780" + "63e021c20614610076575b600080fd5b610060610080565b60405161006d9190610117" + "565b60405180910390f35b61007e6100a4565b005b60008054906101000a900473ffff" + "ffffffffffffffffffffffffffffffffffff1681565b6040517f82b429000000000000" + "0000000000000000000000000000000000000000000000815260040160405180910390" + "fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60" + "00610101826100d6565b9050919050565b610111816100f6565b82525050565b600060" + "208201905061012c6000830184610108565b9291505056fea264697066735822122013" + "2ca0f4158a0540a7e67f304c94305f81bbe52de2314e2b9cee92a2c74e103a64736f6c" + "63430008120033"; + + auto senderAddress = fixture.coinbase.address(); + + Json::Value create; + create["from"] = toJS( senderAddress ); + create["code"] = compiled; + create["gas"] = "180000"; + string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + string contractAddress = receipt["contractAddress"].asString(); + + Json::Value transactionCallObject; + transactionCallObject["to"] = contractAddress; + transactionCallObject["data"] = "0xe021c206"; + + try { + fixture.rpcClient->eth_call( transactionCallObject, "latest" ); + } catch ( jsonrpc::JsonRpcException& ex ) { + BOOST_CHECK_EQUAL( ex.GetCode(), 3 ); + BOOST_CHECK_EQUAL( ex.GetData().asString(), "0x82b42900" ); + BOOST_CHECK_EQUAL( ex.GetMessage(), "EVM revert instruction without description message" ); + } +} + +BOOST_AUTO_TEST_CASE( eth_call_create ) { + JsonRpcFixture fixture; + dev::eth::simulateMining( *( fixture.client ), 1 ); + + auto senderAddress = fixture.coinbase.address(); + + // contract test { + // function f(uint a) returns(uint d) { return a * 7; } + // } + string compiled = + "6080604052348015600f57600080fd5b5060b98061001d6000396000f300" + "608060405260043610603f576000357c01000000000000000000000000" + "00000000000000000000000000000000900463ffffffff168063b3de64" + "8b146044575b600080fd5b3415604e57600080fd5b606a600480360381" + "019080803590602001909291905050506080565b604051808281526020" + "0191505060405180910390f35b60006007820290509190505600a16562" + "7a7a72305820f294e834212334e2978c6dd090355312a3f0f9476b8eb9" + "8fb480406fc2728a960029"; + + // eth_call with no "to" field triggers creation transaction + Json::Value callObject; + callObject["from"] = toJS( senderAddress ); + callObject["data"] = "0x" + compiled; + callObject["gas"] = "1000000"; + callObject["gasPrice"] = "0"; + + string callResult = fixture.rpcClient->eth_call( callObject, "latest" ); + // creation via eth_call should return the runtime bytecode + BOOST_REQUIRE( callResult.size() > 2 ); + BOOST_REQUIRE( callResult != "0x" ); + + // verify state was not modified by eth_call (nonce unchanged) + u256 nonceAfterCall = + jsToU256( fixture.rpcClient->eth_getTransactionCount( toJS( senderAddress ), "latest" ) ); + BOOST_REQUIRE_EQUAL( nonceAfterCall, 0 ); + + // now actually deploy via eth_sendTransaction and verify we get the same runtime bytecode + Json::Value deployTx; + deployTx["from"] = toJS( senderAddress ); + deployTx["code"] = compiled; + deployTx["gas"] = "1000000"; + string txHash = fixture.rpcClient->eth_sendTransaction( deployTx ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x1" ) ); + BOOST_REQUIRE( !receipt["contractAddress"].isNull() ); + + string contractAddress = receipt["contractAddress"].asString(); + string deployedCode = fixture.rpcClient->eth_getCode( contractAddress, "latest" ); + + // the runtime bytecode from eth_call should match the actually deployed code + BOOST_REQUIRE_EQUAL( callResult, deployedCode ); +} + +BOOST_AUTO_TEST_CASE( estimate_gas_with_error ) { + JsonRpcFixture fixture; + dev::eth::simulateMining( *( fixture.client ), 1 ); + + // pragma solidity ^0.8.0; + // contract BasicCustomErrorContract { + // // Define custom errors + // error InsufficientBalance(); + // error Unauthorized(); + // address public owner; + // // Function only callable by the owner + // function ownerOnlyFunction() external { + // revert Unauthorized(); + // } + // } + + string compiled = + "608060405234801561001057600080fd5b50610168806100206000396000f3fe608060" + "405234801561001057600080fd5b5060043610610053576000357c0100000000000000" + "000000000000000000000000000000000000000000900480638da5cb5b146100585780" + "63e021c20614610076575b600080fd5b610060610080565b60405161006d9190610117" + "565b60405180910390f35b61007e6100a4565b005b60008054906101000a900473ffff" + "ffffffffffffffffffffffffffffffffffff1681565b6040517f82b429000000000000" + "0000000000000000000000000000000000000000000000815260040160405180910390" + "fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60" + "00610101826100d6565b9050919050565b610111816100f6565b82525050565b600060" + "208201905061012c6000830184610108565b9291505056fea264697066735822122013" + "2ca0f4158a0540a7e67f304c94305f81bbe52de2314e2b9cee92a2c74e103a64736f6c" + "63430008120033"; + + auto senderAddress = fixture.coinbase.address(); + + Json::Value create; + create["from"] = toJS( senderAddress ); + create["code"] = compiled; + create["gas"] = "180000"; + string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + string contractAddress = receipt["contractAddress"].asString(); + + Json::Value transactionCallObject; + transactionCallObject["to"] = contractAddress; + transactionCallObject["data"] = "0xe021c206"; + + try { + fixture.rpcClient->eth_estimateGas( transactionCallObject, "latest" ); + } catch ( jsonrpc::JsonRpcException& ex ) { + BOOST_CHECK_EQUAL( ex.GetCode(), 3 ); + BOOST_CHECK_EQUAL( ex.GetData().asString(), "0x82b42900" ); + BOOST_CHECK_EQUAL( ex.GetMessage(), "EVM revert instruction without description message" ); + } +} + +#ifndef FAIR +BOOST_AUTO_TEST_CASE( simplePoWTransaction ) { + u256 ESTIMATE_AFTER_PATCH = u256( 21000 + 1024 * 16 ); + u256 ESTIMATE_BEFORE_PATCH = u256( 21000 + 1024 * 68 ); + + // 1s empty block interval + JsonRpcFixture fixture( "", true, true, false, false, false, 1000 ); + dev::eth::simulateMining( *( fixture.client ), 1 ); + + auto senderAddress = fixture.coinbase.address(); + + Json::Value transact; + transact["from"] = toJS( senderAddress ); + transact["to"] = toJS( senderAddress ); + // 1k + ostringstream ss( "0x" ); + for ( int i = 0; i < 1024 / 16; ++i ) + ss << "112233445566778899aabbccddeeff11"; + transact["data"] = ss.str(); + + string gasEstimateStr = fixture.rpcClient->eth_estimateGas( transact ); + u256 gasEstimate = jsToU256( gasEstimateStr ); + + // old estimate before patch + BOOST_REQUIRE_EQUAL( gasEstimate, ESTIMATE_BEFORE_PATCH ); + + u256 powGasPrice = 0; + + + do { + // mine enough POW to tun transaction after PATCH but not before patch + const u256 GAS_PER_HASH = 1; + u256 candidate = h256::random(); + h256 hash = dev::sha3( senderAddress ) ^ dev::sha3( u256( 0 ) ) ^ dev::sha3( candidate ); + u256 externalGas = ~u256( 0 ) / u256( hash ) / GAS_PER_HASH; + if ( externalGas >= ESTIMATE_AFTER_PATCH && + externalGas < ESTIMATE_AFTER_PATCH + ESTIMATE_AFTER_PATCH / 10 ) { + powGasPrice = candidate; + } + } while ( !powGasPrice ); + // Account balance is too low will mean that PoW didn't work out + transact["gasPrice"] = toJS( powGasPrice ); + + // we may've been calculating pow for too long and patch is active already + // need to know the block number at this point + auto latestBlockNumber = + fixture.client->blockInfo( fixture.client->hashFromNumber( LatestBlock ) ).number(); + + // wait for patch turning on and see how it happens + string txHash; + BlockHeader badInfo, goodInfo; + uint64_t blockCounter = 2; + for ( ;; ) { + gasEstimateStr = fixture.rpcClient->eth_estimateGas( transact ); + gasEstimate = jsToU256( gasEstimateStr ); + // old + if ( gasEstimate == ESTIMATE_BEFORE_PATCH ) { + // we are before patch. Sending show fail since we do not have enough PoW gas + try { + fixture.rpcClient->eth_sendTransaction( transact ); + BOOST_REQUIRE( false ); + } catch ( const std::exception& ex ) { + assert( string( ex.what() ).find( "balance is too low" ) != string::npos ); + badInfo = + fixture.client->blockInfo( fixture.client->hashFromNumber( LatestBlock ) ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); // empty block + fixture.client->state().getOriginalDb()->createBlockSnap( blockCounter ); + blockCounter++; + } + } else { // now we are after patch + BOOST_REQUIRE_EQUAL( gasEstimate, ESTIMATE_AFTER_PATCH ); + txHash = fixture.rpcClient->eth_sendTransaction( transact ); + goodInfo = fixture.client->blockInfo( fixture.client->hashFromNumber( LatestBlock ) ); + break; + } + } + + BOOST_REQUIRE_LT( badInfo.timestamp(), fixture.powPatchActivationTimestamp ); + BOOST_REQUIRE_GE( goodInfo.timestamp(), fixture.powPatchActivationTimestamp ); + BOOST_REQUIRE_EQUAL( std::max( badInfo.number() + 1, latestBlockNumber ), goodInfo.number() ); + + dev::eth::mineTransaction( *( fixture.client ), 1 ); + fixture.client->state().getOriginalDb()->createBlockSnap( blockCounter ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE_EQUAL( receipt["status"], "0x1" ); +} +#endif + +#ifndef FAIR +BOOST_AUTO_TEST_CASE( clearPartialReceipts ) { + // Prepare fixture + std::string _config = c_genesisConfigString; + Json::Value ret; + Json::Reader().parse( _config, ret ); + + std::string chainID = "0x97"; // 151 + ret["params"]["chainID"] = chainID; + time_t clearPartialReceiptsActivationTs = time( nullptr ) + 10; + ret["skaleConfig"]["sChain"]["clearPartialReceiptsPatchTimestamp"] = + clearPartialReceiptsActivationTs; + ret["skaleConfig"]["sChain"]["singleStateCommitPerBlockPatchTimestamp"] = + std::numeric_limits< time_t >::max(); + + Json::FastWriter fastWriter; + std::string config = fastWriter.write( ret ); + JsonRpcFixture fixture( config ); + + // To fill coinbase wallet + dev::eth::simulateMining( *( fixture.client ), 20 ); + + string senderAddress = toJS( fixture.coinbase.address() ); + + Json::Value transactionCallObject; + transactionCallObject["from"] = toJS( senderAddress ); + transactionCallObject["to"] = "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a"; + transactionCallObject["data"] = "0x28b5e32b"; + + int64_t blocksToCheck = 6, timestampTransitionBlock = 4, expectedNoLegacyReceiptsBlock = 5; + + for ( int64_t block = 2; block < blocksToCheck; ++block ) { + if ( block == timestampTransitionBlock ) { + sleep( 12 ); + } + + TransactionSkeleton ts = toTransactionSkeleton( transactionCallObject ); + ts = fixture.client->populateTransactionWithDefaults( ts ); + pair< bool, Secret > ar = fixture.accountHolder->authenticate( ts ); + Transaction tx( ts, ar.second ); + auto txHash = fixture.rpcClient->eth_sendRawTransaction( toJS( tx.toBytes() ) ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + auto receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + dev::eth::BlockNumber blockNumber = jsToInt( receipt["blockNumber"].asString() ); + skale::State state( fixture.client->state() ); + BOOST_REQUIRE_EQUAL( blockNumber, block ); + BOOST_REQUIRE_EQUAL( state.safePartialTransactionReceipts( blockNumber ).size(), 0 ); + int64_t expectedSize = block == expectedNoLegacyReceiptsBlock ? 0 : 1; + BOOST_REQUIRE_EQUAL( state.safeLegacyPartialTransactionReceipts().size(), expectedSize ); + } +} + +BOOST_AUTO_TEST_CASE( single_state_commit_per_block_patch_transition ) { + Json::Value configJson; + Json::Reader().parse( c_genesisConfigString, configJson ); + time_t activationTimestamp = time( nullptr ) + 5; + configJson["skaleConfig"]["sChain"]["SingleStateCommitPerBlockPatchTimestamp"] = + static_cast< Json::Int64 >( activationTimestamp ); + + Json::FastWriter fastWriter; + JsonRpcFixture fixture( fastWriter.write( configJson ), true, true, false, true ); + dev::eth::simulateMining( *( fixture.client ), 1 ); + + struct DbCommitCounterGuard { + DbCommitCounterGuard() { skale::state_commit_counter::enable( true ); } + ~DbCommitCounterGuard() { skale::state_commit_counter::enable( false ); } + } guard; + + u256 nextNonce; + + auto sendPayment = [&]() { + Json::Value tx; + tx["from"] = fixture.coinbase.address().hex(); + tx["to"] = fixture.account2.address().hex(); + tx["value"] = toJS( 1 ); + tx["gas"] = toJS( 21000 ); + tx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + tx["nonce"] = toJS( nextNonce ); + nextNonce++; + std::string hash = fixture.rpcClient->eth_sendTransaction( tx ); + BOOST_REQUIRE( !hash.empty() ); + }; + + auto produceBlockWithTransaction = [&]() { + nextNonce = jsToU256( fixture.rpcClient->eth_getTransactionCount( + fixture.coinbase.address().hex(), "latest" ) ); + sendPayment(); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + }; + + skale::state_commit_counter::reset(); + produceBlockWithTransaction(); + // Before activation: 2 commits (1 for tx execution, 1 for block state) + BOOST_REQUIRE_EQUAL( skale::state_commit_counter::count(), 2 ); + + // Receipts should not be saved before activation + auto progressLog = fixture.client->state().getProgressLog(); + BOOST_REQUIRE( progressLog ); + auto receiptsBefore = progressLog->loadProgressData(); + BOOST_CHECK( !receiptsBefore ); + + sleep( 6 ); + + // Produce a block after the activation timestamp so subsequent blocks observe + // commit-per-block semantics. + produceBlockWithTransaction(); + + skale::state_commit_counter::reset(); + produceBlockWithTransaction(); + // After activation: 1 commit (single commit per block) + BOOST_REQUIRE_EQUAL( skale::state_commit_counter::count(), 1 ); + + // Receipts should be saved after activation + auto receiptsAfter = progressLog->loadProgressData(); + BOOST_REQUIRE( receiptsAfter ); + BOOST_CHECK_EQUAL( receiptsAfter->receipts.size(), 1 ); +} + +BOOST_AUTO_TEST_CASE( state_progress_log_skip_already_committed ) { + Json::Value configJson; + Json::Reader().parse( c_genesisConfigString, configJson ); + configJson["skaleConfig"]["sChain"]["singleStateCommitPerBlockPatchTimestamp"] = + static_cast< Json::Int64 >( 1 ); + + Json::FastWriter fastWriter; + JsonRpcFixture fixture( fastWriter.write( configJson ), true, true, false, true ); + dev::eth::simulateMining( *( fixture.client ), 1 ); + + struct DbCommitCounterGuard { + DbCommitCounterGuard() { skale::state_commit_counter::enable( true ); } + ~DbCommitCounterGuard() { skale::state_commit_counter::enable( false ); } + } guard; + + u256 nextNonce; + + auto sendPayment = [&]() { + Json::Value tx; + tx["from"] = fixture.coinbase.address().hex(); + tx["to"] = fixture.account2.address().hex(); + tx["value"] = toJS( 1 ); + tx["gas"] = toJS( 21000 ); + tx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + tx["nonce"] = toJS( nextNonce ); + nextNonce++; + std::string hash = fixture.rpcClient->eth_sendTransaction( tx ); + BOOST_REQUIRE( !hash.empty() ); + }; + + auto produceBlockWithTransaction = [&]() { + nextNonce = jsToU256( fixture.rpcClient->eth_getTransactionCount( + fixture.coinbase.address().hex(), "latest" ) ); + sendPayment(); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + }; + + produceBlockWithTransaction(); + + skale::state_commit_counter::reset(); + produceBlockWithTransaction(); + BOOST_REQUIRE_EQUAL( skale::state_commit_counter::count(), 1 ); + + auto progressLog = fixture.client->state().getProgressLog(); + BOOST_REQUIRE( progressLog ); + BOOST_CHECK( progressLog->isBlockCommitCompleted( fixture.client->number() ) ); +} + +BOOST_AUTO_TEST_CASE( state_progress_log_crash_recovery ) { + Json::Value configJson; + Json::Reader().parse( c_genesisConfigString, configJson ); + configJson["skaleConfig"]["sChain"]["singleStateCommitPerBlockPatchTimestamp"] = + static_cast< Json::Int64 >( 1 ); + + Json::FastWriter fastWriter; + JsonRpcFixture fixture( fastWriter.write( configJson ), true, true, false, true ); + dev::eth::simulateMining( *( fixture.client ), 1 ); + + struct DbCommitCounterGuard { + DbCommitCounterGuard() { skale::state_commit_counter::enable( true ); } + ~DbCommitCounterGuard() { skale::state_commit_counter::enable( false ); } + } guard; + + u256 nextNonce; + + auto sendPayment = [&]() { + Json::Value tx; + tx["from"] = fixture.coinbase.address().hex(); + tx["to"] = fixture.account2.address().hex(); + tx["value"] = toJS( 1 ); + tx["gas"] = toJS( 21000 ); + tx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + tx["nonce"] = toJS( nextNonce ); + nextNonce++; + std::string hash = fixture.rpcClient->eth_sendTransaction( tx ); + BOOST_REQUIRE( !hash.empty() ); + }; + + auto produceBlockWithTransaction = [&]() { + nextNonce = jsToU256( fixture.rpcClient->eth_getTransactionCount( + fixture.coinbase.address().hex(), "latest" ) ); + sendPayment(); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + }; + + produceBlockWithTransaction(); + + auto progressLog = fixture.client->state().getProgressLog(); + BOOST_REQUIRE( progressLog ); + + uint64_t completedBlock = fixture.client->number(); + BOOST_CHECK( progressLog->isBlockCommitCompleted( completedBlock ) ); + + progressLog->markBlockCommitStarted( completedBlock + 1 ); + BOOST_CHECK( !progressLog->isBlockCommitCompleted( completedBlock + 1 ) ); + + skale::state_commit_counter::reset(); + produceBlockWithTransaction(); + BOOST_REQUIRE_EQUAL( skale::state_commit_counter::count(), 1 ); + + BOOST_CHECK( progressLog->isBlockCommitCompleted( fixture.client->number() ) ); +} + +namespace { +template < typename PatchType > +void waitForPatchActivation( int timeoutSeconds = 10 ) { + auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds( timeoutSeconds ); + while ( !PatchType::isEnabledWhen( time( nullptr ) ) ) { + BOOST_REQUIRE( std::chrono::steady_clock::now() < deadline ); + std::this_thread::sleep_for( std::chrono::milliseconds( 50 ) ); + } +} +} // namespace + +#ifndef FAIR +// Test fs commits before SingleStateCommitPerBlockPatch is active +BOOST_AUTO_TEST_CASE( single_fs_commit_per_block_patch_before ) { + Json::Value configJson; + Json::Reader().parse( c_genesisConfigString, configJson ); + // Patch disabled (far future timestamp) + configJson["skaleConfig"]["sChain"]["singleStateCommitPerBlockPatchTimestamp"] = + static_cast< Json::Int64 >( 0 ); + configJson["skaleConfig"]["sChain"]["revertableFSPatchTimestamp"] = + static_cast< Json::Int64 >( 1 ); + + Json::FastWriter fastWriter; + RestrictedAddressFixture fixture( fastWriter.write( configJson ), true ); + dev::eth::simulateMining( *( fixture.client ), 1 ); + + struct FsCommitCounterGuard { + FsCommitCounterGuard() { skale::fs_commit_counter::enable( true ); } + ~FsCommitCounterGuard() { skale::fs_commit_counter::enable( false ); } + } guard; + + auto senderAddress = fixture.coinbase.address(); + fixture.client->setAuthor( senderAddress ); + + u256 nextNonce; + + auto executeFilestorageOperation = [&]() { + Json::Value tx; + tx["from"] = toJS( senderAddress ); + tx["to"] = "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a"; + tx["data"] = "0xf38fb65b"; + tx["nonce"] = toJS( nextNonce ); + nextNonce++; + TransactionSkeleton ts = toTransactionSkeleton( tx ); + ts = fixture.client->populateTransactionWithDefaults( ts ); + pair< bool, Secret > ar = fixture.accountHolder->authenticate( ts ); + Transaction transaction( ts, ar.second ); + fixture.rpcClient->eth_sendRawTransaction( toJS( transaction.toBytes() ) ); + }; + + auto produceBlockWithFilestorageOperations = [&]() { + nextNonce = jsToU256( + fixture.rpcClient->eth_getTransactionCount( toJS( senderAddress ), "latest" ) ); + executeFilestorageOperation(); + executeFilestorageOperation(); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + fixture.client->state().getOriginalDb()->createBlockSnap( fixture.client->number() ); + }; + + // Without patch: expect 2 commits (one per transaction) + skale::fs_commit_counter::reset(); + produceBlockWithFilestorageOperations(); + BOOST_REQUIRE_EQUAL( skale::fs_commit_counter::count(), 2 ); +} + +// Test fs commits after SingleStateCommitPerBlockPatch is active +BOOST_AUTO_TEST_CASE( single_fs_commit_per_block_patch_after ) { + Json::Value configJson; + Json::Reader().parse( c_genesisConfigString, configJson ); + // Patch enabled from genesis + configJson["skaleConfig"]["sChain"]["singleStateCommitPerBlockPatchTimestamp"] = + static_cast< Json::Int64 >( 1 ); + configJson["skaleConfig"]["sChain"]["revertableFSPatchTimestamp"] = + static_cast< Json::Int64 >( 1 ); + + Json::FastWriter fastWriter; + RestrictedAddressFixture fixture( fastWriter.write( configJson ), true ); + dev::eth::simulateMining( *( fixture.client ), 1 ); + + struct FsCommitCounterGuard { + FsCommitCounterGuard() { skale::fs_commit_counter::enable( true ); } + ~FsCommitCounterGuard() { skale::fs_commit_counter::enable( false ); } + } guard; + + auto senderAddress = fixture.coinbase.address(); + fixture.client->setAuthor( senderAddress ); + + u256 nextNonce; + + auto executeFilestorageOperation = [&]() { + Json::Value tx; + tx["from"] = toJS( senderAddress ); + tx["to"] = "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a"; + tx["data"] = "0xf38fb65b"; + tx["nonce"] = toJS( nextNonce ); + nextNonce++; + TransactionSkeleton ts = toTransactionSkeleton( tx ); + ts = fixture.client->populateTransactionWithDefaults( ts ); + pair< bool, Secret > ar = fixture.accountHolder->authenticate( ts ); + Transaction transaction( ts, ar.second ); + fixture.rpcClient->eth_sendRawTransaction( toJS( transaction.toBytes() ) ); + }; + + auto produceBlockWithFilestorageOperations = [&]() { + nextNonce = jsToU256( + fixture.rpcClient->eth_getTransactionCount( toJS( senderAddress ), "latest" ) ); + executeFilestorageOperation(); + executeFilestorageOperation(); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + fixture.client->state().getOriginalDb()->createBlockSnap( fixture.client->number() ); + }; + + // With patch: expect 1 commit (one per block) + skale::fs_commit_counter::reset(); + produceBlockWithFilestorageOperations(); + BOOST_REQUIRE_EQUAL( skale::fs_commit_counter::count(), 1 ); +} +#endif + +BOOST_AUTO_TEST_CASE( recalculateExternalGas ) { + std::string _config = c_genesisConfigString; + Json::Value ret; + Json::Reader().parse( _config, ret ); + + std::string chainID = "0x15"; + ret["params"]["chainID"] = chainID; + + // remove deployment control + auto accounts = ret["accounts"]; + accounts.removeMember( "0xD2002000000000000000000000000000000000D2" ); + ret["accounts"] = accounts; + + // setup patch + time_t externalGasPatchActivationTimestamp = time( nullptr ) + 10; + ret["skaleConfig"]["sChain"]["ExternalGasPatchTimestamp"] = externalGasPatchActivationTimestamp; + + Json::FastWriter fastWriter; + std::string config = fastWriter.write( ret ); + JsonRpcFixture fixture( config, true, false ); + dev::eth::simulateMining( *( fixture.client ), 20 ); + + auto senderAddress = fixture.coinbase.address().hex(); + + // // SPDX-License-Identifier: GPL-3.0 + + // pragma solidity >=0.8.2 <0.9.0; + + // /** + // * @title Storage + // * @dev Store & retrieve value in a variable + // * @custom:dev-run-script ./scripts/deploy_with_ethers.ts + // */ + // contract Storage { + + // uint256 number; + // uint256 number1; + // uint256 number2; + + // /** + // * @dev Store value in variable + // * @param num value to store + // */ + // function store(uint256 num) public { + // number = num; + // number1 = num; + // number2 = num; + // } + + // /** + // * @dev Return value + // * @return value of 'number' + // */ + // function retrieve() public view returns (uint256){ + // return number; + // } + // } + std::string bytecode = + "608060405234801561001057600080fd5b5061015e806100206000396000f3fe60806040523480156100105760" + "0080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080" + "fd5b610043610075565b60405161005091906100e7565b60405180910390f35b61007360048036038101906100" + "6e91906100ab565b61007e565b005b60008054905090565b806000819055508060018190555080600281905550" + "50565b6000813590506100a581610111565b92915050565b6000602082840312156100c1576100c061010c565b" + "5b60006100cf84828501610096565b91505092915050565b6100e181610102565b82525050565b600060208201" + "90506100fc60008301846100d8565b92915050565b6000819050919050565b600080fd5b61011a81610102565b" + "811461012557600080fd5b5056fea2646970667358221220780703bb6ac2eec922a510d57edcae39b852b578e7" + "f63a263ddb936758dc9c4264736f6c63430008070033"; + + // deploy contact + Json::Value create; + create["from"] = senderAddress; + create["code"] = bytecode; + create["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + create["gas"] = 140000; + create["nonce"] = 0; + + std::string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + fixture.client->state().getOriginalDb()->createBlockSnap( 2 ); + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( receipt["status"].asString() == "0x1" ); + std::string contractAddress = receipt["contractAddress"].asString(); + + // send txn to a contract from the suspicious account + // store( 4 ) + Json::Value txn; + txn["from"] = "0x40797bb29d12FC0dFD04277D16a3Dd4FAc3a6e5B"; + txn["data"] = "0x6057361d0000000000000000000000000000000000000000000000000000000000000004"; + txn["gasPrice"] = "0xdffe55527a88d3775c23ecd3ae38ff1e90caf12b5beb4f7ea3ad998a990a895c"; + txn["gas"] = 140000; + txn["chainId"] = "0x15"; + txn["nonce"] = 0; + txn["to"] = contractAddress; + + auto ts = toTransactionSkeleton( txn ); + auto t = dev::eth::Transaction( + ts, dev::Secret( "7be24de049f2d0d4ecaeaa81564aecf647fa7a4c86264243d77e01da25d859a0" ) ); + + txHash = fixture.rpcClient->eth_sendRawTransaction( dev::toHex( t.toBytes() ) ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + fixture.client->state().getOriginalDb()->createBlockSnap( 3 ); + receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + + + BOOST_REQUIRE( receipt["status"].asString() == "0x0" ); + BOOST_REQUIRE( receipt["gasUsed"].asString() == "0x61cb" ); + + + sleep( 10 ); + + // push new block to update timestamp + Json::Value refill; + refill["from"] = senderAddress; + refill["to"] = dev::Address::random().hex(); + refill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + refill["value"] = 100; + refill["nonce"] = 1; + + txHash = fixture.rpcClient->eth_sendTransaction( refill ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + fixture.client->state().getOriginalDb()->createBlockSnap( 4 ); + + // send txn to a contract from another suspicious account + // store( 4 ) + txn["from"] = "0x5cdb7527ec85022991D4e27F254C438E8337ad7E"; + txn["data"] = "0x6057361d0000000000000000000000000000000000000000000000000000000000000004"; + txn["gasPrice"] = "0x974749a06d5cd0dba6a4e1f3d14d5f480db716dcbc9a34ec5496b8d86e99f898"; + txn["gas"] = 140000; + txn["chainId"] = "0x15"; + txn["nonce"] = 0; + txn["to"] = contractAddress; + + ts = toTransactionSkeleton( txn ); + t = dev::eth::Transaction( + ts, dev::Secret( "8df08814fcfc169aad0015654114be06c28b27bdcdef286cf4dbd5e2950a3ffc" ) ); + + txHash = fixture.rpcClient->eth_sendRawTransaction( dev::toHex( t.toBytes() ) ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + fixture.client->state().getOriginalDb()->createBlockSnap( 5 ); + receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + + BOOST_REQUIRE( receipt["status"].asString() == "0x1" ); + BOOST_REQUIRE( receipt["gasUsed"].asString() == "0x13ef4" ); +} +#endif + +BOOST_AUTO_TEST_CASE( skipTransactionExecution ) { + std::string _config = c_genesisConfigString; + Json::Value ret; + Json::Reader().parse( _config, ret ); + + // Set chainID = 21 + std::string chainID = "0x15"; + ret["params"]["chainID"] = chainID; + + Json::FastWriter fastWriter; + std::string config = fastWriter.write( ret ); + JsonRpcFixture fixture( config ); + dev::eth::simulateMining( *( fixture.client ), 20 ); + + auto senderAddress = fixture.coinbase.address().hex(); + + Json::Value refill; + refill["from"] = senderAddress; + refill["to"] = "0x5EdF1e852fdD1B0Bc47C0307EF755C76f4B9c251"; + refill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + refill["value"] = 1000000000000000; + refill["nonce"] = 0; + + std::string txHash = fixture.rpcClient->eth_sendTransaction( refill ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + // send txn and verify that gas used is correct + // gas used value is hardcoded in State::txnsToSkipExecution + Json::Value txn; + txn["from"] = "0x5EdF1e852fdD1B0Bc47C0307EF755C76f4B9c251"; + txn["gasPrice"] = "0x4a817c800"; + txn["gas"] = 40000; + txn["chainId"] = "0x15"; + txn["nonce"] = 0; + txn["value"] = 1; + txn["to"] = "0x5cdb7527ec85022991D4e27F254C438E8337ad7E"; + + auto ts = toTransactionSkeleton( txn ); + auto t = dev::eth::Transaction( + ts, dev::Secret( "08cee1f4bc8c37f88124bb3fc64566ccd35dbeeac84c62300f6b8809cab9ea2f" ) ); + + txHash = fixture.rpcClient->eth_sendRawTransaction( dev::toHex( t.toBytes() ) ); + BOOST_REQUIRE( txHash == "0x95fb5557db8cc6de0aff3a64c18a6d9378b0d312b24f5d77e8dbf5cc0612d74f" ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( receipt["gasUsed"].asString() == "0x5ac0" ); +} + +#ifndef FAIR +BOOST_AUTO_TEST_CASE( transactionWithoutFunds ) { + JsonRpcFixture fixture; + dev::eth::simulateMining( *( fixture.client ), 1 ); + + // pragma solidity ^0.4.22; + + // contract test + // { + // uint hello; + // function writeHello(uint value) returns(bool d) + // { + // hello = value; + // return true; + // } + // } + + + string compiled = + "6080604052341561000f57600080fd5b60c28061001d6000396000f3006" + "08060405260043610603f576000357c0100000000000000000000000000" + "000000000000000000000000000000900463ffffffff16806315b2eec31" + "46044575b600080fd5b3415604e57600080fd5b606a6004803603810190" + "80803590602001909291905050506084565b60405180821515151581526" + "0200191505060405180910390f35b600081600081905550600190509190" + "505600a165627a7a72305820d8407d9cdaaf82966f3fa7a3e665b8cf4e6" + "5ee8909b83094a3f856b9051274500029"; + + auto senderAddress = fixture.coinbase.address(); + + Json::Value create; + create["from"] = toJS( senderAddress ); + create["code"] = compiled; + create["gas"] = "180000"; // TODO or change global default of 90000? + string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + string contractAddress = receipt["contractAddress"].asString(); + + Address address2 = fixture.account2.address(); + string balanceString = fixture.rpcClient->eth_getBalance( toJS( address2 ), "latest" ); + BOOST_REQUIRE_EQUAL( toJS( 0 ), balanceString ); + + Json::Value transact; + transact["from"] = toJS( address2 ); + transact["to"] = contractAddress; + transact["data"] = "0x15b2eec30000000000000000000000000000000000000000000000000000000000000003"; + + string gasEstimateStr = fixture.rpcClient->eth_estimateGas( transact ); + u256 gasEstimate = jsToU256( gasEstimateStr ); + + u256 powGasPrice = 0; + do { + const u256 GAS_PER_HASH = 1; + u256 candidate = h256::random(); + h256 hash = dev::sha3( address2 ) ^ dev::sha3( u256( 0 ) ) ^ dev::sha3( candidate ); + u256 externalGas = ~u256( 0 ) / u256( hash ) * GAS_PER_HASH; + if ( externalGas >= gasEstimate && externalGas < gasEstimate + gasEstimate / 10 ) { + powGasPrice = candidate; + } + } while ( !powGasPrice ); + transact["gasPrice"] = toJS( powGasPrice ); + + fixture.rpcClient->eth_sendTransaction( transact ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + string storage = fixture.rpcClient->eth_getStorageAt( contractAddress, "0", "latest" ); + BOOST_CHECK_EQUAL( + storage, "0x0000000000000000000000000000000000000000000000000000000000000003" ); + + balanceString = fixture.rpcClient->eth_getBalance( toJS( address2 ), "latest" ); + BOOST_REQUIRE_EQUAL( toJS( 0 ), balanceString ); +} +#endif + +BOOST_AUTO_TEST_CASE( eth_sendRawTransaction_gasPriceTooLow ) { + JsonRpcFixture fixture; + auto senderAddress = fixture.coinbase.address(); + auto receiver = KeyPair::create(); + + // Mine to generate a non-zero account balance + const int blocksToMine = 1; +#ifdef FAIR + const u256 blockReward = + fixture.client->chainParams().blockReward( fixture.client->blockChain().info().timestamp(), + fixture.client->blockChain().info().number() ); +#else + const u256 blockReward = 2 * dev::eth::ether; +#endif + dev::eth::simulateMining( *( fixture.client ), blocksToMine ); + BOOST_CHECK_EQUAL( blockReward, fixture.client->balanceAt( senderAddress ) ); + + u256 initial_gasPrice = fixture.client->gasBidPrice(); + + Json::Value t; + t["from"] = toJS( senderAddress ); + t["to"] = toJS( receiver.address() ); + t["value"] = jsToDecimal( toJS( 10000 * dev::eth::szabo ) ); + t["gasPrice"] = jsToDecimal( toJS( initial_gasPrice ) ); + + auto signedTx = fixture.rpcClient->eth_signTransaction( t ); + BOOST_REQUIRE( !signedTx["raw"].empty() ); + + auto txHash = fixture.rpcClient->eth_sendRawTransaction( signedTx["raw"].asString() ); + BOOST_REQUIRE( !txHash.empty() ); + + mineTransaction( *fixture.client, 1 ); + BOOST_REQUIRE_EQUAL( + fixture.rpcClient->eth_getTransactionCount( toJS( senderAddress ), "latest" ), "0x1" ); + + + ///////////////////////// + + t["nonce"] = "1"; + t["gasPrice"] = jsToDecimal( toJS( initial_gasPrice - 1 ) ); + auto signedTx2 = fixture.rpcClient->eth_signTransaction( t ); + BOOST_CHECK_EQUAL( fixture.sendingRawShouldFail( signedTx2["raw"].asString() ), + "Transaction gas price lower than current eth_gasPrice." ); +} + +// different ways to ask for topic(s) +BOOST_AUTO_TEST_CASE( logs ) { + JsonRpcFixture fixture; + dev::eth::simulateMining( *( fixture.client ), 1 ); + + // will generate topics [0xxxx, 0, 0], [0xxx, 0, 1] etc + /* + pragma solidity >=0.4.10 <0.7.0; + + contract Logger{ + + uint256 i; + uint256 j; + + fallback() external payable { + log3(bytes32(block.number), bytes32(block.number), bytes32(i), bytes32(j)); + j++; + if(j==10){ + j = 0; + i++; + }// j overflow + } + }*/ + + string bytecode = + "6080604052348015600f57600080fd5b50609b8061001e6000396000f3fe608060405260015460001b60005460" + "001b4360001b4360001b6040518082815260200191505060405180910390a36001600081548092919060010191" + "90505550600a6001541415606357600060018190555060008081548092919060010191905055505b00fea26469" + "70667358221220fdf2f98961b803b6b32dfc9be766990cbdb17559d9a03724d12fc672e33804b164736f6c6343" + "00060c0033"; + + Json::Value create; + create["code"] = bytecode; + create["gas"] = "180000"; // TODO or change global default of 90000? + + string deployHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value deployReceipt = fixture.rpcClient->eth_getTransactionReceipt( deployHash ); + string contractAddress = deployReceipt["contractAddress"].asString(); + + for ( int i = 0; i <= 23; ++i ) { + Json::Value t; + t["from"] = toJS( fixture.coinbase.address() ); + t["value"] = jsToDecimal( "0" ); + t["to"] = contractAddress; + t["gas"] = "99000"; + +#ifdef FAIR + std::string txHash; + if ( i % 2 ) { + txHash = fixture.rpcClient->eth_sendTransaction( t ); + } else { + std::string addrWithout0x = contractAddress.substr( 2 ); + dev::bytes encryptedData = + formEncryptedMessageMockup( dev::bytes(), dev::Address( addrWithout0x ) ); + // account for the nonce 0 used for contract deployment + size_t nonce = static_cast< size_t >( i + 1 ); + std::string rlp = formTransactionRlp( + fixture, t["from"].asString(), dev::toHex( encryptedData ), nonce, addrWithout0x ); + txHash = fixture.rpcClient->eth_sendRawTransaction( rlp ); + } +#else + std::string txHash = fixture.rpcClient->eth_sendTransaction( t ); +#endif + BOOST_REQUIRE( !txHash.empty() ); + + dev::eth::mineTransaction( *( fixture.client ), 1 ); + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + } + BOOST_REQUIRE_EQUAL( fixture.client->number(), 26 ); // block 1 - bootstrapAll, block 2 - + // deploy + + // ask for logs + Json::Value t; + t["fromBlock"] = 3; + t["toBlock"] = 26; + t["address"] = contractAddress; + t["topics"] = Json::Value( Json::arrayValue ); + + // 1 topics = [] + Json::Value logs = fixture.rpcClient->eth_getLogs( t ); + + BOOST_REQUIRE( logs.isArray() ); + BOOST_REQUIRE_EQUAL( logs.size(), 24 ); + u256 t1 = dev::jsToU256( logs[12]["topics"][1].asString() ); + BOOST_REQUIRE_EQUAL( t1, 1 ); + u256 t2 = dev::jsToU256( logs[12]["topics"][2].asString() ); + BOOST_REQUIRE_EQUAL( t2, 2 ); + + // 2 topics = [a] + t["topics"] = Json::Value( Json::arrayValue ); + t["topics"][1] = u256_to_js( dev::u256( 2 ) ); + + logs = fixture.rpcClient->eth_getLogs( t ); + + BOOST_REQUIRE( logs.isArray() ); + BOOST_REQUIRE_EQUAL( logs.size(), 4 ); + t1 = dev::jsToU256( logs[0]["topics"][1].asString() ); + BOOST_REQUIRE_EQUAL( t1, 2 ); + t2 = dev::jsToU256( logs[0]["topics"][2].asString() ); + BOOST_REQUIRE_EQUAL( t2, 0 ); + + // 3 topics = [null, a] + t["topics"] = Json::Value( Json::arrayValue ); + t["topics"][2] = u256_to_js( dev::u256( 1 ) ); // 01,11,21 but not 1x + + logs = fixture.rpcClient->eth_getLogs( t ); + + BOOST_REQUIRE( logs.isArray() ); + BOOST_REQUIRE_EQUAL( logs.size(), 3 ); + + // 4 topics = [a,b] + t["topics"] = Json::Value( Json::arrayValue ); + t["topics"][1] = u256_to_js( dev::u256( 1 ) ); + t["topics"][2] = u256_to_js( dev::u256( 2 ) ); + + logs = fixture.rpcClient->eth_getLogs( t ); + + BOOST_REQUIRE( logs.isArray() ); + BOOST_REQUIRE_EQUAL( logs.size(), 1 ); + + // 5 topics = [[a,b]] + t["topics"] = Json::Value( Json::arrayValue ); + t["topics"][1] = Json::Value( Json::arrayValue ); + t["topics"][1][0] = u256_to_js( dev::u256( 1 ) ); + t["topics"][1][1] = u256_to_js( dev::u256( 2 ) ); + + logs = fixture.rpcClient->eth_getLogs( t ); + + BOOST_REQUIRE( logs.isArray() ); + BOOST_REQUIRE_EQUAL( logs.size(), 10 + 4 ); + + // 6 topics = [a,a] + t["topics"] = Json::Value( Json::arrayValue ); + t["topics"][1] = u256_to_js( dev::u256( 1 ) ); + t["topics"][2] = u256_to_js( dev::u256( 1 ) ); + + logs = fixture.rpcClient->eth_getLogs( t ); + + BOOST_REQUIRE( logs.isArray() ); + BOOST_REQUIRE_EQUAL( logs.size(), 1 ); + + // 7 topics = [[a,b], c] + t["topics"] = Json::Value( Json::arrayValue ); + t["topics"][1] = Json::Value( Json::arrayValue ); + t["topics"][1][0] = u256_to_js( dev::u256( 1 ) ); + t["topics"][1][1] = u256_to_js( dev::u256( 2 ) ); + t["topics"][2] = u256_to_js( dev::u256( 1 ) ); // 11, 21 + + logs = fixture.rpcClient->eth_getLogs( t ); + + BOOST_REQUIRE( logs.isArray() ); + BOOST_REQUIRE_EQUAL( logs.size(), 2 ); + t1 = dev::jsToU256( logs[0]["topics"][1].asString() ); + BOOST_REQUIRE_EQUAL( t1, 1 ); + t2 = dev::jsToU256( logs[0]["topics"][2].asString() ); + BOOST_REQUIRE_EQUAL( t2, 1 ); + t1 = dev::jsToU256( logs[1]["topics"][1].asString() ); + BOOST_REQUIRE_EQUAL( t1, 2 ); + t2 = dev::jsToU256( logs[1]["topics"][2].asString() ); + BOOST_REQUIRE_EQUAL( t2, 1 ); + + // 8 repeat #7 without address + auto logs7 = logs; + t["address"] = Json::Value( Json::arrayValue ); + logs = fixture.rpcClient->eth_getLogs( t ); + BOOST_REQUIRE_EQUAL( logs7, logs ); + + // 9 repeat #7 with 2 addresses + t["address"] = Json::Value( Json::arrayValue ); + t["address"][0] = contractAddress; + t["address"][1] = "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"; // dummy + logs = fixture.rpcClient->eth_getLogs( t ); + BOOST_REQUIRE_EQUAL( logs7, logs ); + + // 10 request address only + t["topics"] = Json::Value( Json::arrayValue ); + logs = fixture.rpcClient->eth_getLogs( t ); + BOOST_REQUIRE( logs.isArray() ); + BOOST_REQUIRE_EQUAL( logs.size(), 24 ); + + Json::Value filterReq; + filterReq["fromBlock"] = 3; + filterReq["toBlock"] = 26; + filterReq["address"] = contractAddress; + filterReq["topics"] = Json::Value( Json::arrayValue ); + std::string filterId = fixture.rpcClient->eth_newFilter( filterReq ); + Json::Value filterLogs = fixture.rpcClient->eth_getFilterLogs( filterId ); + BOOST_REQUIRE( filterLogs.isArray() ); + BOOST_REQUIRE_EQUAL( filterLogs.size(), logs.size() ); +} + +// limit on getLogs output +BOOST_AUTO_TEST_CASE( getLogs_limit ) { + JsonRpcFixture fixture( + "", true, true, false, false, false, -1, { { "getLogsBlocksLimit", "10" } } ); + + dev::eth::simulateMining( *( fixture.client ), 100 ); + + // push0Patch is enabled by default for FAIR +#ifndef FAIR + // wait for push0Patch to be activated + sleep( 10 ); + + // update block timestamp to activate patch + Json::Value txRefill; + txRefill["to"] = "0xc868AF52a6549c773082A334E5AE232e0Ea3B513"; + txRefill["from"] = toJS( fixture.coinbase.address() ); + txRefill["gas"] = "100000"; + txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txRefill["value"] = 100000000000000000; + string txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#endif + + /* + // SPDX-License-Identifier: None + pragma solidity ^0.8; + contract Logger{ + event DummyEvent(uint256, uint256); + fallback() external payable { + for(uint i=0; i<100; ++i) + emit DummyEvent(block.number, i); + } + } + */ + + string bytecode = + "6080604052348015600e575f80fd5b5060c080601a5f395ff3fe60806040525f5b6064811015604f577f907787" + "67414a5c844b9d35a8745f67697ee3b8c2c3f4feafe5d9a3e234a5a3654382604051603d9291906067565b6040" + "5180910390a18060010190506006565b005b5f819050919050565b6061816051565b82525050565b5f60408201" + "905060785f830185605a565b60836020830184605a565b939250505056fea264697066735822122040208e35f2" + "706dd92c17579466ab671c308efec51f558a755ea2cf81105ab22964736f6c63430008190033"; + + Json::Value create; + create["code"] = bytecode; + create["gas"] = "180000"; // TODO or change global default of 90000? + + string deployHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value deployReceipt = fixture.rpcClient->eth_getTransactionReceipt( deployHash ); + string contractAddress = deployReceipt["contractAddress"].asString(); + + // generate 10 blocks 10 logs each + + Json::Value t; + t["from"] = toJS( fixture.coinbase.address() ); + t["value"] = jsToDecimal( "0" ); + t["to"] = contractAddress; + t["gas"] = "999000"; + + for ( int i = 0; i < 11; ++i ) { + std::string txHash = fixture.rpcClient->eth_sendTransaction( t ); + BOOST_REQUIRE( !txHash.empty() ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE_EQUAL( receipt["status"], "0x1" ); + } + + // ask for logs + Json::Value req; + req["fromBlock"] = 1; + req["toBlock"] = 11; + req["topics"] = Json::Value( Json::arrayValue ); + + // 1 10 blocks + BOOST_REQUIRE_NO_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs( req ) ); + + // 2 with topics + req["address"] = contractAddress; + BOOST_REQUIRE_NO_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs( req ) ); + + // 3 11 blocks + req["toBlock"] = 12; + BOOST_CHECK_EXCEPTION( ( fixture.rpcClient->eth_getLogs( req ) ), jsonrpc::JsonRpcException, + []( const jsonrpc::JsonRpcException& ex ) { + return ex.GetCode() == -32005 && + std::string( ex.GetMessage() ).find( "Block range limit exceeded" ) != + std::string::npos; + } ); + + // 4 filter + string filterId = fixture.rpcClient->eth_newFilter( req ); + + BOOST_REQUIRE_NO_THROW( Json::Value res = fixture.rpcClient->eth_getFilterChanges( filterId ) ); + + req["toBlock"] = 2; + filterId = fixture.rpcClient->eth_newFilter( req ); + BOOST_REQUIRE_NO_THROW( Json::Value res = fixture.rpcClient->eth_getFilterLogs( filterId ) ); + BOOST_REQUIRE_NO_THROW( + Json::Value res2 = fixture.rpcClient->eth_getFilterChanges( filterId ) ); + + req["toBlock"] = 50; + filterId = fixture.rpcClient->eth_newFilter( req ); + BOOST_CHECK_EXCEPTION( ( fixture.rpcClient->eth_getFilterLogs( filterId ) ), + jsonrpc::JsonRpcException, []( const jsonrpc::JsonRpcException& ex ) { + std::cout << ex.GetCode() << " " << ex.GetMessage() << std::endl; + return ex.GetCode() == -32005 && + std::string( ex.GetMessage() ).find( "Block range limit exceeded" ) != + std::string::npos; + } ); +} + +BOOST_AUTO_TEST_CASE( getResponseLogCountLimit ) { + JsonRpcFixture fixture( + "", true, true, false, false, false, -1, { { "getResponseLogCountLimit", "201" } } ); + + dev::eth::simulateMining( *( fixture.client ), 1 ); + +#ifndef FAIR + sleep( 10 ); + Json::Value txRefill; + txRefill["to"] = "0xc868AF52a6549c773082A334E5AE232e0Ea3B513"; + txRefill["from"] = toJS( fixture.coinbase.address() ); + txRefill["gas"] = "100000"; + txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txRefill["value"] = 100000000000000000; + string txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#endif + + string bytecode = + "6080604052348015600e575f80fd5b5060c080601a5f395ff3fe60806040525f5b6064811015604f577f907787" + "67414a5c844b9d35a8745f67697ee3b8c2c3f4feafe5d9a3e234a5a3654382604051603d9291906067565b6040" + "5180910390a18060010190506006565b005b5f819050919050565b6061816051565b82525050565b5f60408201" + "905060785f830185605a565b60836020830184605a565b939250505056fea264697066735822122040208e35f2" + "706dd92c17579466ab671c308efec51f558a755ea2cf81105ab22964736f6c63430008190033"; + + Json::Value create; + create["code"] = bytecode; + create["gas"] = "180000"; + string deployHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + Json::Value deployReceipt = fixture.rpcClient->eth_getTransactionReceipt( deployHash ); + string contractAddress = deployReceipt["contractAddress"].asString(); + + Json::Value callTx; + callTx["from"] = toJS( fixture.coinbase.address() ); + callTx["to"] = contractAddress; + callTx["gas"] = "999000"; + + for ( int i = 0; i < 5; ++i ) { + string h = fixture.rpcClient->eth_sendTransaction( callTx ); + BOOST_REQUIRE( !h.empty() ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + } + + Json::Value req; + req["fromBlock"] = 1; + req["topics"] = Json::Value( Json::arrayValue ); + req["address"] = contractAddress; + + req["toBlock"] = 4; + BOOST_REQUIRE_NO_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs( req ) ); + + string overHash = fixture.rpcClient->eth_sendTransaction( callTx ); + BOOST_REQUIRE( !overHash.empty() ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + req["toBlock"] = fixture.client->number(); + BOOST_CHECK_EXCEPTION( ( fixture.rpcClient->eth_getLogs( req ) ), jsonrpc::JsonRpcException, + []( const jsonrpc::JsonRpcException& ex ) { + return ex.GetCode() == -32005 && + std::string( ex.GetMessage() ).find( "Response log count limit exceeded" ) != + std::string::npos; + } ); +} + +// test blockHash parameter +BOOST_AUTO_TEST_CASE( getLogs_blockHash ) { + JsonRpcFixture fixture; + dev::eth::simulateMining( *( fixture.client ), 1 ); + + string latestHash = + fixture.rpcClient->eth_getBlockByNumber( "latest", false )["hash"].asString(); + + Json::Value req; + req["blockHash"] = "xyz"; + BOOST_REQUIRE_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs( req ), std::exception ); + + req["blockHash"] = Json::Value( Json::arrayValue ); + BOOST_REQUIRE_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs( req ), std::exception ); + + req["fromBlock"] = 1; + req["toBlock"] = 1; + BOOST_REQUIRE_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs( req ), std::exception ); + + req["blockHash"] = latestHash; + BOOST_REQUIRE_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs( req ), std::exception ); + + req.removeMember( "fromBlock" ); + req.removeMember( "toBlock" ); + BOOST_REQUIRE_NO_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs( req ) ); + + req["blockHash"] = "0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b"; + BOOST_REQUIRE_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs( req ), std::exception ); + + req["blockHash"] = ""; + BOOST_REQUIRE_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs( req ), std::exception ); +} + +BOOST_AUTO_TEST_CASE( estimate_gas_low_gas_txn ) { + JsonRpcFixture fixture; + dev::eth::simulateMining( *( fixture.client ), 10 ); + + auto senderAddress = fixture.coinbase.address(); + + /* + // SPDX-License-Identifier: None + pragma solidity ^0.6.0; + + contract TestEstimateGas { + uint256[256] number; + uint256 counter = 0; + + function store(uint256 x) public { + number[counter] = x; + counter += 1; + } + + function clear(uint256 pos) public { + number[pos] = 0; + } + } + */ + + string bytecode = + "608060405260006101005534801561001657600080fd5b50610104806100266000396000f3fe60806040523480" + "15600f57600080fd5b506004361060325760003560e01c80636057361d146037578063c0fe1af8146062575b60" + "0080fd5b606060048036036020811015604b57600080fd5b8101908080359060200190929190505050608d565b" + "005b608b60048036036020811015607657600080fd5b810190808035906020019092919050505060b8565b005b" + "806000610100546101008110609e57fe5b018190555060016101006000828254019250508190555050565b6000" + "8082610100811060c657fe5b01819055505056fea26469706673582212206c8da972693a5b8c9bf59c197c4a0c" + "554e9f51abd20047572c9c19125b533d2964736f6c634300060c0033"; + + Json::Value create; + create["code"] = bytecode; + create["gas"] = "180000"; // TODO or change global default of 90000? + + string deployHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value deployReceipt = fixture.rpcClient->eth_getTransactionReceipt( deployHash ); + string contractAddress = deployReceipt["contractAddress"].asString(); + + Json::Value txStore1; // call store(1) + txStore1["to"] = contractAddress; + txStore1["data"] = "0x6057361d0000000000000000000000000000000000000000000000000000000000000001"; + txStore1["from"] = toJS( senderAddress ); + txStore1["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + fixture.rpcClient->eth_sendTransaction( txStore1 ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value estimateGasCall; // call clear(0) + estimateGasCall["to"] = contractAddress; + estimateGasCall["data"] = + "0xc0fe1af80000000000000000000000000000000000000000000000000000000000000000"; + estimateGasCall["from"] = toJS( senderAddress ); + estimateGasCall["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + string estimatedGas = fixture.rpcClient->eth_estimateGas( estimateGasCall ); + + dev::bytes data = dev::jsToBytes( estimateGasCall["data"].asString() ); + BOOST_REQUIRE( + dev::jsToU256( estimatedGas ) > + dev::eth::TransactionBase::baseGasRequired( false, &data, + fixture.client->chainParams().makeEvmSchedule( + fixture.client->latestBlock().info().timestamp(), fixture.client->number() ) ) ); + + // try to send with this gas + estimateGasCall["gas"] = toJS( jsToInt( estimatedGas ) ); + string clearHash = fixture.rpcClient->eth_sendTransaction( estimateGasCall ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + Json::Value clearReceipt = fixture.rpcClient->eth_getTransactionReceipt( clearHash ); + BOOST_REQUIRE_EQUAL( clearReceipt["status"], "0x1" ); + BOOST_REQUIRE_LT( jsToInt( clearReceipt["gasUsed"].asString() ), 21000 ); + + // try to lower gas + estimateGasCall["gas"] = toJS( jsToInt( estimatedGas ) - 1 ); + clearHash = fixture.rpcClient->eth_sendTransaction( estimateGasCall ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + clearReceipt = fixture.rpcClient->eth_getTransactionReceipt( clearHash ); + BOOST_REQUIRE_EQUAL( clearReceipt["status"], "0x0" ); + BOOST_REQUIRE_GT( jsToInt( clearReceipt["gasUsed"].asString() ), 21000 ); +} + +BOOST_AUTO_TEST_CASE( storage_limit_contract ) { + JsonRpcFixture fixture; + dev::eth::simulateMining( *( fixture.client ), 10 ); + + // pragma solidity 0.4.25; + + // contract TestStorageLimit { + + // uint[] public storageArray; + + // function store(uint256 num) public { + // storageArray.push( num ); + // } + + // function erase(uint256 index) public { + // delete storageArray[index]; + // } + + // function foo() public view { + // uint len = storageArray.length; + // storageArray.push(1); + // } + + // function storeAndCall(uint256 num) public { + // storageArray.push( num ); + // foo(); + // } + + // function zero(uint256 index) public { + // storageArray[index] = 0; + // } + + // function strangeFunction(uint256 index) public { + // storageArray[index] = 1; + // storageArray[index] = 0; + // storageArray[index] = 2; + // } + // } + + std::string bytecode = + "0x608060405234801561001057600080fd5b5061034f806100206000396000f300608060405260043610610083" + "576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630e" + "031ab1146100885780631007f753146100c95780636057361d146100f6578063c298557814610123578063c67c" + "d8841461013a578063d269ad4e14610167578063e0353e5914610194575b600080fd5b34801561009457600080" + "fd5b506100b3600480360381019080803590602001909291905050506101c1565b604051808281526020019150" + "5060405180910390f35b3480156100d557600080fd5b506100f460048036038101908080359060200190929190" + "5050506101e4565b005b34801561010257600080fd5b5061012160048036038101908080359060200190929190" + "505050610204565b005b34801561012f57600080fd5b50610138610233565b005b34801561014657600080fd5b" + "506101656004803603810190808035906020019092919050505061026c565b005b34801561017357600080fd5b" + "50610192600480360381019080803590602001909291905050506102a3565b005b3480156101a057600080fd5b" + "506101bf60048036038101908080359060200190929190505050610302565b005b6000818154811015156101d0" + "57fe5b906000526020600020016000915090505481565b6000818154811015156101f357fe5b90600052602060" + "0020016000905550565b6000819080600181540180825580915050906001820390600052602060002001600090" + "91929091909150555050565b600080805490509050600060019080600181540180825580915050906001820390" + "60005260206000200160009091929091909150555050565b600081908060018154018082558091505090600182" + "03906000526020600020016000909192909190915055506102a0610233565b50565b6001600082815481101515" + "6102b457fe5b9060005260206000200181905550600080828154811015156102d257fe5b906000526020600020" + "018190555060026000828154811015156102f157fe5b906000526020600020018190555050565b600080828154" + "8110151561031257fe5b9060005260206000200181905550505600a165627a7a723058201ed095336772c55688" + "864a6b45ca6ab89311c5533f8d38cdf931f1ce38be78080029"; + + auto senderAddress = fixture.coinbase.address(); + + Json::Value create; + create["from"] = toJS( senderAddress ); + create["data"] = bytecode; + create["gas"] = "1800000"; // TODO or change global default of 90000? + string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + string contractAddress = receipt["contractAddress"].asString(); +#ifndef FAIR + dev::Address contract = dev::Address( contractAddress ); +#endif + + Json::Value txCall; // call foo() + txCall["to"] = contractAddress; + txCall["data"] = "0xc2985578"; + txCall["from"] = toJS( senderAddress ); + txCall["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + auto callResult = fixture.rpcClient->eth_call( txCall, "latest" ); +#ifndef FAIR + BOOST_REQUIRE( + fixture.client->state().createReadOnlySnapBasedCopy().storageUsed( contract ) == 0 ); +#endif + BOOST_REQUIRE_EQUAL( callResult, std::string( "0x" ) ); + + Json::Value txPushValueAndCall; // call storeAndCall(1) + txPushValueAndCall["to"] = contractAddress; + txPushValueAndCall["data"] = + "0xc67cd8840000000000000000000000000000000000000000000000000000000000000001"; + txPushValueAndCall["from"] = toJS( senderAddress ); + txPushValueAndCall["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txPushValueAndCall["gas"] = "200000"; + txHash = fixture.rpcClient->eth_sendTransaction( txPushValueAndCall ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#ifndef FAIR + BOOST_REQUIRE( + fixture.client->state().createReadOnlySnapBasedCopy().storageUsed( contract ) == 96 ); +#endif + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); + + Json::Value txPushValue; // call store(2) + txPushValue["to"] = contractAddress; + txPushValue["data"] = + "0x6057361d0000000000000000000000000000000000000000000000000000000000000002"; + txPushValue["from"] = toJS( senderAddress ); + txPushValue["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txPushValue["gas"] = "200000"; + txHash = fixture.rpcClient->eth_sendTransaction( txPushValue ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#ifndef FAIR + BOOST_REQUIRE( + fixture.client->state().createReadOnlySnapBasedCopy().storageUsed( contract ) == 128 ); +#endif + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); + + Json::Value txThrow; // trying to call store(3) + txThrow["to"] = contractAddress; + txThrow["data"] = "0x6057361d0000000000000000000000000000000000000000000000000000000000000003"; + txThrow["from"] = toJS( senderAddress ); + txThrow["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txThrow["gas"] = "200000"; + txHash = fixture.rpcClient->eth_sendTransaction( txThrow ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#ifndef FAIR + BOOST_REQUIRE( + fixture.client->state().createReadOnlySnapBasedCopy().storageUsed( contract ) == 128 ); + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x0" ); +#else + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); +#endif + + Json::Value txEraseValue; // call erase(2) + txEraseValue["to"] = contractAddress; + txEraseValue["data"] = + "0x1007f7530000000000000000000000000000000000000000000000000000000000000002"; + txEraseValue["from"] = toJS( senderAddress ); + txEraseValue["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txEraseValue["gas"] = "200000"; + txHash = fixture.rpcClient->eth_sendTransaction( txEraseValue ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#ifndef FAIR + BOOST_REQUIRE( + fixture.client->state().createReadOnlySnapBasedCopy().storageUsed( contract ) == 96 ); +#endif + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); + + + Json::Value txZeroValue; // call zero(1) + txZeroValue["to"] = contractAddress; + txZeroValue["data"] = + "0xe0353e590000000000000000000000000000000000000000000000000000000000000001"; + txZeroValue["from"] = toJS( senderAddress ); + txZeroValue["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txZeroValue["gas"] = "200000"; + txHash = fixture.rpcClient->eth_sendTransaction( txZeroValue ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#ifndef FAIR + BOOST_REQUIRE( + fixture.client->state().createReadOnlySnapBasedCopy().storageUsed( contract ) == 64 ); +#endif + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); + + Json::Value txZeroValue1; // call zero(1) + txZeroValue1["to"] = contractAddress; + txZeroValue1["data"] = + "0xe0353e590000000000000000000000000000000000000000000000000000000000000001"; + txZeroValue1["from"] = toJS( senderAddress ); + txZeroValue1["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txZeroValue1["gas"] = "200000"; + txHash = fixture.rpcClient->eth_sendTransaction( txZeroValue1 ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#ifndef FAIR + BOOST_REQUIRE( + fixture.client->state().createReadOnlySnapBasedCopy().storageUsed( contract ) == 64 ); +#endif + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); + + Json::Value txValueChanged; // call strangeFunction(1) + txValueChanged["to"] = contractAddress; + txValueChanged["data"] = + "0xd269ad4e0000000000000000000000000000000000000000000000000000000000000001"; + txValueChanged["from"] = toJS( senderAddress ); + txValueChanged["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txValueChanged["gas"] = "200000"; + txHash = fixture.rpcClient->eth_sendTransaction( txValueChanged ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#ifndef FAIR + BOOST_REQUIRE( + fixture.client->state().createReadOnlySnapBasedCopy().storageUsed( contract ) == 96 ); +#endif + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); + + Json::Value txValueChanged1; // call strangeFunction(0) + txValueChanged1["to"] = contractAddress; + txValueChanged1["data"] = + "0xd269ad4e0000000000000000000000000000000000000000000000000000000000000000"; + txValueChanged1["from"] = toJS( senderAddress ); + txValueChanged1["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txValueChanged1["gas"] = "200000"; + txHash = fixture.rpcClient->eth_sendTransaction( txValueChanged1 ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#ifndef FAIR + BOOST_REQUIRE( + fixture.client->state().createReadOnlySnapBasedCopy().storageUsed( contract ) == 96 ); +#endif + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); + + Json::Value txValueChanged2; // call strangeFunction(2) + txValueChanged2["to"] = contractAddress; + txValueChanged2["data"] = + "0xd269ad4e0000000000000000000000000000000000000000000000000000000000000002"; + txValueChanged2["from"] = toJS( senderAddress ); + txValueChanged2["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txValueChanged2["gas"] = "200000"; + txHash = fixture.rpcClient->eth_sendTransaction( txValueChanged2 ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#ifndef FAIR + BOOST_REQUIRE( + fixture.client->state().createReadOnlySnapBasedCopy().storageUsed( contract ) == 128 ); +#endif + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); + + Json::Value txValueChanged3; // try call strangeFunction(3) + txValueChanged3["to"] = contractAddress; + txValueChanged3["data"] = + "0xd269ad4e0000000000000000000000000000000000000000000000000000000000000003"; + txValueChanged3["from"] = toJS( senderAddress ); + txValueChanged3["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txValueChanged3["gas"] = "200000"; + txHash = fixture.rpcClient->eth_sendTransaction( txValueChanged3 ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#ifndef FAIR + BOOST_REQUIRE( + fixture.client->state().createReadOnlySnapBasedCopy().storageUsed( contract ) == 128 ); + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x0" ); +#else + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); +#endif +} + +BOOST_AUTO_TEST_CASE( storage_limit_chain ) { + JsonRpcFixture fixture; + dev::eth::simulateMining( *( fixture.client ), 20 ); + // pragma solidity >=0.4.22 <0.7.0; + + // contract TestStorage1 { + + // uint[] array; + + // function store(uint256 num) public { + // array.push( num + 2 ); + // } + + // function erase(uint idx) public { + // delete array[idx]; + // } + // } + std::string bytecode1 = + "608060405234801561001057600080fd5b5061012c806100206000396000f3fe6080604052348015600f576000" + "80fd5b5060043610604f576000357c010000000000000000000000000000000000000000000000000000000090" + "0480631007f7531460545780636057361d14607f575b600080fd5b607d60048036036020811015606857600080" + "fd5b810190808035906020019092919050505060aa565b005b60a860048036036020811015609357600080fd5b" + "810190808035906020019092919050505060c7565b005b6000818154811060b657fe5b90600052602060002001" + "6000905550565b6000600282019080600181540180825580915050600190039060005260206000200160009091" + "9091909150555056fea264697066735822122055c65b9e093cdb44864dac3fb79ec15a542db86c2f897b938043" + "d8e15468ca4464736f6c63430006060033"; + + auto senderAddress = fixture.coinbase.address(); + + Json::Value create1; + create1["from"] = toJS( senderAddress ); + create1["data"] = bytecode1; + create1["gas"] = "1800000"; + string txHash = fixture.rpcClient->eth_sendTransaction( create1 ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt1 = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + string contractAddress1 = receipt1["contractAddress"].asString(); + + // pragma solidity >=0.4.22 <0.7.0; + + // contract TestStorage2 { + + // uint[] array; + + // function store(uint256 num) public { + // array.push( num ); + // } + + // function erase(uint idx) public { + // delete array[idx]; + // } + // } + Json::Value txStore; // call store(1) + txStore["to"] = contractAddress1; + txStore["data"] = "0x6057361d0000000000000000000000000000000000000000000000000000000000000001"; + txStore["from"] = toJS( senderAddress ); + txStore["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txHash = fixture.rpcClient->eth_sendTransaction( txStore ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#ifndef FAIR + BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == 64 ); +#endif + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); + + // call store(2) + txStore["to"] = contractAddress1; + txStore["data"] = "0x6057361d0000000000000000000000000000000000000000000000000000000000000002"; + txStore["from"] = toJS( senderAddress ); + txStore["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txHash = fixture.rpcClient->eth_sendTransaction( txStore ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#ifndef FAIR + BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == 96 ); +#endif + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); + + Json::Value txErase; // call erase(1) + txErase["to"] = contractAddress1; + txErase["data"] = "0x1007f7530000000000000000000000000000000000000000000000000000000000000001"; + txErase["from"] = toJS( senderAddress ); + txErase["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txHash = fixture.rpcClient->eth_sendTransaction( txErase ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#ifndef FAIR + BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == 64 ); +#endif + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); + + // pragma solidity >=0.4.22 <0.7.0; + + // contract TestStorage2 { + + // uint[] array; + + // function store(uint256 num) public { + // array.push( num ); + // } + + // function erase(uint idx) public { + // delete array[idx]; + // } + // } + std::string bytecode2 = + "608060405234801561001057600080fd5b50610129806100206000396000f3fe6080604052348015600f576000" + "80fd5b5060043610604f576000357c010000000000000000000000000000000000000000000000000000000090" + "0480631007f7531460545780636057361d14607f575b600080fd5b607d60048036036020811015606857600080" + "fd5b810190808035906020019092919050505060aa565b005b60a860048036036020811015609357600080fd5b" + "810190808035906020019092919050505060c7565b005b6000818154811060b657fe5b90600052602060002001" + "6000905550565b6000819080600181540180825580915050600190039060005260206000200160009091909190" + "9150555056fea26469706673582212202bfb5f6fb63ae4f1c9a362ed3f7de7aa5514029db925efa368e711e35d" + "9ebc0a64736f6c63430006060033"; + + Json::Value create2; + create2["from"] = toJS( senderAddress ); + create2["data"] = bytecode2; + create2["gas"] = "1800000"; + txHash = fixture.rpcClient->eth_sendTransaction( create2 ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt2 = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + string contractAddress2 = receipt2["contractAddress"].asString(); + + Json::Value txStoreSecondContract; // call store(1) + txStoreSecondContract["to"] = contractAddress2; + txStoreSecondContract["data"] = + "0x6057361d0000000000000000000000000000000000000000000000000000000000000001"; + txStoreSecondContract["from"] = toJS( senderAddress ); + txStoreSecondContract["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txHash = fixture.rpcClient->eth_sendTransaction( txStoreSecondContract ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#ifndef FAIR + BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == 128 ); +#endif + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); + + // try call store(2) to second contract + txStoreSecondContract["to"] = contractAddress2; + txStoreSecondContract["data"] = + "0x6057361d0000000000000000000000000000000000000000000000000000000000000002"; + txStoreSecondContract["from"] = toJS( senderAddress ); + txStoreSecondContract["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txHash = fixture.rpcClient->eth_sendTransaction( txStoreSecondContract ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#ifndef FAIR + BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == 128 ); + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x0" ); +#else + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); +#endif + + // try call store(3) to first contract + txStore["to"] = contractAddress1; + txStore["data"] = "0x6057361d0000000000000000000000000000000000000000000000000000000000000001"; + txStore["from"] = toJS( senderAddress ); + txStore["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txHash = fixture.rpcClient->eth_sendTransaction( txStore ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#ifndef FAIR + BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == 128 ); + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x0" ); +#else + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); +#endif + + Json::Value txZeroValue; // call zero(1) + txZeroValue["to"] = contractAddress1; + txZeroValue["data"] = + "0x1007f7530000000000000000000000000000000000000000000000000000000000000000"; + txZeroValue["from"] = toJS( senderAddress ); + txZeroValue["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txHash = fixture.rpcClient->eth_sendTransaction( txZeroValue ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#ifndef FAIR + BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == 96 ); +#endif + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); +} + +BOOST_AUTO_TEST_CASE( storage_limit_predeployed ) { + JsonRpcFixture fixture( c_genesisConfigString ); + dev::eth::simulateMining( *( fixture.client ), 20 ); +#ifndef FAIR + BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == 64 ); +#endif + + string contractAddress = "0xC2002000000000000000000000000000000000C2"; + string senderAddress = toJS( fixture.coinbase.address() ); + + Json::Value txChangeInt; + txChangeInt["to"] = contractAddress; + txChangeInt["data"] = + "0xcd16ecbf0000000000000000000000000000000000000000000000000000000000000002"; + txChangeInt["from"] = senderAddress; + txChangeInt["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + string txHash = fixture.rpcClient->eth_sendTransaction( txChangeInt ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#ifndef FAIR + BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == 64 ); +#endif + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); + + Json::Value txZeroValue; + txZeroValue["to"] = contractAddress; + txZeroValue["data"] = + "0xcd16ecbf0000000000000000000000000000000000000000000000000000000000000000"; + txZeroValue["from"] = senderAddress; + txZeroValue["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txHash = fixture.rpcClient->eth_sendTransaction( txZeroValue ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#ifndef FAIR + BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == 32 ); +#endif + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); + + Json::Value txChangeInt1; + txChangeInt["to"] = contractAddress; + txChangeInt["data"] = + "0x9b0631040000000000000000000000000000000000000000000000000000000000000001"; + txChangeInt["from"] = senderAddress; + txChangeInt["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txHash = fixture.rpcClient->eth_sendTransaction( txChangeInt ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#ifndef FAIR + BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == 64 ); +#endif + BOOST_REQUIRE_EQUAL( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"], "0x1" ); +} + +BOOST_AUTO_TEST_CASE( storage_limit_reverted ) { + JsonRpcFixture fixture; + dev::eth::simulateMining( *( fixture.client ), 1000 ); + // pragma solidity >=0.7.0 <0.9.0; + + // contract Storage { + + // uint256[10] number; + + // /** + // * @dev Store value in variable + // * @param num value to store + // */ + // function store(uint256 num, uint256 pos) public { + // number[pos] = num; + // } + // } + std::string bytecode1 = + "0x608060405234801561001057600080fd5b50610134806100206000396000f3fe6080604052348015600f5760" + "0080fd5b506004361060285760003560e01c80636ed28ed014602d575b600080fd5b6043600480360381019060" + "3f91906096565b6045565b005b81600082600a8110605757605660cf565b5b01819055505050565b600080fd5b" + "6000819050919050565b6076816065565b8114608057600080fd5b50565b600081359050609081606f565b9291" + "5050565b6000806040838503121560aa5760a96060565b5b600060b6858286016083565b925050602060c58582" + "86016083565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000" + "00000000600052603260045260246000fdfea2646970667358221220ec8739ad7fc74a76053c683510b3c836d0" + "1c7eda3687d89e65380260a97e741b64736f6c63430008120033"; + auto senderAddress = fixture.coinbase.address(); + + Json::Value create1; + create1["from"] = toJS( senderAddress ); + create1["data"] = bytecode1; + create1["gas"] = "1800000"; + string txHash = fixture.rpcClient->eth_sendTransaction( create1 ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt1 = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( receipt1["status"] == string( "0x1" ) ); + string contractAddress1 = receipt1["contractAddress"].asString(); + + // contract CallTry { + + // bool success; + // uint256 count; + // address storageAddress; + + // event Message(string mes); + + // constructor(address newAddress) { + // storageAddress = newAddress; + // } + + // function storeTry() public { + // count = 1; + // success = true; + // try Storage(storageAddress).store(10, 10) { + // emit Message("true"); + // } catch Error(string memory reason) { + // emit Message(reason); + // } catch Panic(uint errorCode) { + // emit Message(string(abi.encodePacked(errorCode))); + // } catch (bytes memory revertData) { + // emit Message(string(revertData)); + // }contractAddress1 + // count = 0; + // success = false; + // } + // } + + std::string bytecode2 = + "608060405234801561001057600080fd5b506040516106f93803806106f9833981810160405281019061003291" + "906100dc565b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373" + "ffffffffffffffffffffffffffffffffffffffff16021790555050610109565b600080fd5b600073ffffffffff" + "ffffffffffffffffffffffffffffff82169050919050565b60006100a98261007e565b9050919050565b6100b9" + "8161009e565b81146100c457600080fd5b50565b6000815190506100d6816100b0565b92915050565b60006020" + "82840312156100f2576100f1610079565b5b6000610100848285016100c7565b91505092915050565b6105e180" + "6101186000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063c1" + "8829ca14610030575b600080fd5b61003861003a565b005b6001808190555060016000806101000a81548160ff" + "021916908315150217905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffff" + "ff1673ffffffffffffffffffffffffffffffffffffffff16636ed28ed0600a806040518363ffffffff1660e01b" + "81526004016100b99291906102de565b600060405180830381600087803b1580156100d357600080fd5b505af1" + "9250505080156100e4575060015b610235576100f0610314565b806308c379a00361014c57506101046103b156" + "5b8061010f57506101c5565b7f51a7f65c6325882f237d4aeb43228179cfad48b868511d508e24b4437a819137" + "8160405161013e91906104c0565b60405180910390a150610230565b634e487b71036101c55761015e6104e256" + "5b9061016957506101c5565b7f51a7f65c6325882f237d4aeb43228179cfad48b868511d508e24b4437a819137" + "8160405160200161019b9190610524565b6040516020818303038152906040526040516101b791906104c0565b" + "60405180910390a150610230565b3d80600081146101f1576040519150601f19603f3d011682016040523d8252" + "3d6000602084013e6101f6565b606091505b507f51a7f65c6325882f237d4aeb43228179cfad48b868511d508e" + "24b4437a8191378160405161022691906104c0565b60405180910390a1505b61026b565b7f51a7f65c6325882f" + "237d4aeb43228179cfad48b868511d508e24b4437a8191376040516102629061058b565b60405180910390a15b" + "600060018190555060008060006101000a81548160ff021916908315150217905550565b600081905091905056" + "5b6000819050919050565b6000819050919050565b60006102c86102c36102be8461028f565b6102a3565b6102" + "99565b9050919050565b6102d8816102ad565b82525050565b60006040820190506102f360008301856102cf56" + "5b61030060208301846102cf565b9392505050565b60008160e01c9050919050565b600060033d111561033357" + "60046000803e610330600051610307565b90505b90565b6000604051905090565b6000601f19601f8301169050" + "919050565b7f4e487b710000000000000000000000000000000000000000000000000000000060005260416004" + "5260246000fd5b61038982610340565b810181811067ffffffffffffffff821117156103a8576103a761035156" + "5b5b80604052505050565b600060443d1061043e576103c3610336565b60043d036004823e80513d6024820111" + "67ffffffffffffffff821117156103eb57505061043e565b808201805167ffffffffffffffff81111561040957" + "5050505061043e565b80602083010160043d03850181111561042657505050505061043e565b61043582602001" + "850186610380565b82955050505050505b90565b600081519050919050565b6000828252602082019050929150" + "50565b60005b8381101561047b578082015181840152602081019050610460565b60008484015250505050565b" + "600061049282610441565b61049c818561044c565b93506104ac81856020860161045d565b6104b58161034056" + "5b840191505092915050565b600060208201905081810360008301526104da8184610487565b90509291505056" + "5b60008060233d11156104ff576020600460003e6001915060005190505b9091565b6000819050919050565b61" + "051e61051982610299565b610503565b82525050565b6000610530828461050d565b6020820191508190509291" + "5050565b7f7472756500000000000000000000000000000000000000000000000000000000600082015250565b" + "600061057560048361044c565b91506105808261053f565b602082019050919050565b60006020820190508181" + "0360008301526105a481610568565b905091905056fea26469706673582212201a522ad11a321603efd182e33e" + "10b59f65b8c9a8b84c8ec3d832ff1d0b726cc564736f6c63430008120033" + + std::string( "000000000000000000000000" ) + contractAddress1.substr( 2 ); + Json::Value create2; + create2["from"] = toJS( senderAddress ); + create2["data"] = bytecode2; + create2["gas"] = "1800000"; + txHash = fixture.rpcClient->eth_sendTransaction( create2 ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt2 = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( receipt2["status"] == string( "0x1" ) ); + string contractAddress2 = receipt2["contractAddress"].asString(); + +#ifndef FAIR + auto storageUsed = fixture.client->state().storageUsedTotal(); +#endif + + Json::Value txStoreTry; + txStoreTry["to"] = contractAddress2; + txStoreTry["data"] = "0xc18829ca"; + txStoreTry["from"] = senderAddress.hex(); + txStoreTry["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txHash = fixture.rpcClient->eth_sendTransaction( txStoreTry ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); +#ifndef FAIR + BOOST_REQUIRE( fixture.client->state().storageUsedTotal() == storageUsed ); +#endif + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( receipt["gasUsed"] != "0x0" ); + BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); +} + +BOOST_AUTO_TEST_CASE( setSchainExitTime ) { + JsonRpcFixture fixture; + Json::Value requestJson; + requestJson["finishTime"] = 100; + BOOST_REQUIRE_THROW( + fixture.rpcClient->setSchainExitTime( requestJson ), jsonrpc::JsonRpcException ); +} + +#ifndef FAIR +/* +BOOST_AUTO_TEST_CASE( oracle, *boost::unit_test::disabled() ) { + + JsonRpcFixture fixture; + std::string receipt; + std::string result; + std::time_t current = std::time(nullptr); + std::string request; + for (int i = 0; i < 1000000; ++i) { + request = +skutils::tools::format("{\"cid\":1,\"uri\":\"http://worldtimeapi.org/api/timezone/Europe/Kiev\",\"jsps\":[\"/unixtime\",\"/day_of_year\",\"/xxx\"],\"trims\":[1,1,1],\"time\":%zu000,\"pow\":%zu}", +current, i); auto os = make_shared(request); if ( os->verifyPow() ) { break; + } + } + uint64_t status = fixture.client->submitOracleRequest(request, receipt); + + BOOST_REQUIRE_EQUAL(status, 0); + BOOST_CHECK(receipt != ""); + + sleep(5); + + uint64_t resultStatus = fixture.client->checkOracleResult(receipt, result); + BOOST_REQUIRE_EQUAL(resultStatus, 0); + BOOST_CHECK(result != ""); + + + +}*/ +#endif + +BOOST_AUTO_TEST_CASE( doDbCompactionDebugCall ) { + JsonRpcFixture fixture; + + fixture.rpcClient->debug_doStateDbCompaction(); + + fixture.rpcClient->debug_doBlocksDbCompaction(); +} + +BOOST_AUTO_TEST_CASE( debugGetPatchTimestamps ) { + Json::Value configJson; + Json::Reader().parse( c_genesisConfigString, configJson ); + + // indexed by enum int value + std::vector< size_t > patchTimestamps; + + // Set custom config file & create timestamps for each patch + size_t numPatches = static_cast< size_t >( SchainPatchEnum::PatchesCount ); + for ( size_t patch = 0; patch < numPatches; patch++ ) { + SchainPatchEnum patchEnum = static_cast< SchainPatchEnum >( patch ); + size_t ts = patch + 1000; // just to offset from the default values (0, 1) + patchTimestamps.push_back( ts ); + + std::string patchName = getPatchNameForEnum( patchEnum ) + "Timestamp"; + patchName[0] = tolower( patchName[0] ); + configJson["skaleConfig"]["sChain"][patchName] = ts; + } + + Json::FastWriter fastWriter; + std::string customConfigFile = fastWriter.write( configJson ); + + JsonRpcFixture fixture( customConfigFile, false, false, false, false ); + Json::Value returnedPatchTimestamps = fixture.rpcClient->debug_getPatchTimestamps(); + + // compare returned timestamps to actual timestamps + for ( size_t patchIdx = 0; patchIdx < numPatches; patchIdx++ ) { + SchainPatchEnum patchEnum = static_cast< SchainPatchEnum >( patchIdx ); + + std::string patchName = getPatchNameForEnum( patchEnum ) + "Timestamp"; + patchName[0] = tolower( patchName[0] ); + size_t returnedTimestamp = + static_cast< size_t >( returnedPatchTimestamps[patchName].asInt() ); + + BOOST_REQUIRE_EQUAL( returnedTimestamp, patchTimestamps[patchIdx] ); + } +} + +#ifndef FAIR +BOOST_AUTO_TEST_CASE( powTxnGasLimit ) { + Json::Value configJson; + Json::Reader().parse( c_genesisConfigString, configJson ); + configJson["skaleConfig"]["sChain"]["powCheckPatchTimestamp"] = 1; + Json::FastWriter fastWriter; + std::string customConfigFile = fastWriter.write( configJson ); + JsonRpcFixture fixture( customConfigFile, false, false, true, false ); + + // mine blocks without transactions + dev::eth::simulateMining( *( fixture.client ), 2000000 ); + + string senderAddress = toJS( fixture.coinbase.address() ); + + Json::Value txPOW1; + txPOW1["to"] = "0x0000000000000000000000000000000000000033"; + txPOW1["from"] = senderAddress; + txPOW1["gas"] = "100000"; + txPOW1["gasPrice"] = + "0xa449dcaf2bca14e6bd0ac650eed9555008363002b2fc3a4c8422b7a9525a8135"; // gas 200k + txPOW1["value"] = 1; + string txHash = fixture.rpcClient->eth_sendTransaction( txPOW1 ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt1 = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( receipt1["status"] == string( "0x1" ) ); + + Json::Value txPOW2; + txPOW2["to"] = "0x0000000000000000000000000000000000000033"; + txPOW2["from"] = senderAddress; + txPOW2["gas"] = "100000"; + txPOW2["gasPrice"] = + "0xc5002ab03e1e7e196b3d0ffa9801e783fcd48d4c6d972f1389ab63f4e2d0bef0"; // gas 1m + txPOW2["value"] = 100; + + BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendTransaction( txPOW2 ), + jsonrpc::JsonRpcException ); // block gas limit reached +} +#endif + +BOOST_AUTO_TEST_CASE( EIP1898Calls ) { + JsonRpcFixture fixture; + + Json::Value eip1898WellFormed; + eip1898WellFormed["blockHash"] = dev::h256::random().hex(); + eip1898WellFormed["requireCanonical"] = true; + + Json::Value eip1898WellFormed1; + eip1898WellFormed1["blockHash"] = dev::h256::random().hex(); + + Json::Value eip1898WellFormed2; + eip1898WellFormed2["blockHash"] = dev::h256::random().hex(); + eip1898WellFormed2["requireCanonical"] = false; + + Json::Value eip1898WellFormed3; + eip1898WellFormed3["blockNumber"] = dev::h256::random().hex(); + + Json::Value eip1898BadFormed; + eip1898BadFormed["blockHashxxx"] = dev::h256::random().hex(); + eip1898BadFormed["requireCanonical"] = false; + + Json::Value eip1898BadFormed1; + eip1898BadFormed1["blockHash"] = dev::h256::random().hex(); + eip1898BadFormed1["requireCanonical"] = false; + eip1898BadFormed1["smth"] = 1; + + Json::Value eip1898BadFormed2; + eip1898BadFormed2["blockHash"] = 228; + + Json::Value eip1898BadFormed3; + eip1898BadFormed3["blockHash"] = dev::h256::random().hex(); + eip1898BadFormed3["requireCanonical"] = 228; + + Json::Value eip1898BadFormed4; + eip1898BadFormed4["blockNumber"] = dev::h256::random().hex(); + eip1898BadFormed4["requireCanonical"] = true; + + Json::Value eip1898BadFormed5; + eip1898BadFormed5["blockNumber"] = dev::h256::random().hex(); + eip1898BadFormed5["requireCanonical"] = 228; + + + std::array< Json::Value, 4 > wellFormedCalls = { eip1898WellFormed, eip1898WellFormed1, + eip1898WellFormed2, eip1898WellFormed3 }; + std::array< Json::Value, 6 > badFormedCalls = { eip1898BadFormed, eip1898BadFormed1, + eip1898BadFormed2, eip1898BadFormed3, eip1898BadFormed4, eip1898BadFormed5 }; + + + auto address = fixture.coinbase.address(); + + std::string response; + for ( const auto& call : wellFormedCalls ) { + BOOST_REQUIRE_NO_THROW( fixture.rpcClient->eth_getBalanceEIP1898( toJS( address ), call ) ); + } + + for ( const auto& call : badFormedCalls ) { + BOOST_REQUIRE_THROW( fixture.rpcClient->eth_getBalanceEIP1898( toJS( address ), call ), + jsonrpc::JsonRpcException ); + } + + + for ( const auto& call : wellFormedCalls ) { + Json::Value transactionCallObject; + transactionCallObject["to"] = "0x0000000000000000000000000000000000000005"; + transactionCallObject["data"] = "0x0000000000000000000000000000000000000005"; + BOOST_REQUIRE_NO_THROW( fixture.rpcClient->eth_callEIP1898( transactionCallObject, call ) ); + } + + for ( const auto& call : badFormedCalls ) { + Json::Value transactionCallObject; + transactionCallObject["to"] = "0x0000000000000000000000000000000000000005"; + transactionCallObject["data"] = "0x0000000000000000000000000000000000000005"; + BOOST_REQUIRE_THROW( fixture.rpcClient->eth_callEIP1898( transactionCallObject, call ), + jsonrpc::JsonRpcException ); + } + + for ( const auto& call : wellFormedCalls ) { + BOOST_REQUIRE_NO_THROW( fixture.rpcClient->eth_getCodeEIP1898( toJS( address ), call ) ); + } + + for ( const auto& call : badFormedCalls ) { + BOOST_REQUIRE_THROW( fixture.rpcClient->eth_getCodeEIP1898( toJS( address ), call ), + jsonrpc::JsonRpcException ); + } + + for ( const auto& call : wellFormedCalls ) { + BOOST_REQUIRE_NO_THROW( + fixture.rpcClient->eth_getStorageAtEIP1898( toJS( address ), toJS( address ), call ) ); + } + + for ( const auto& call : badFormedCalls ) { + BOOST_REQUIRE_THROW( + fixture.rpcClient->eth_getStorageAtEIP1898( toJS( address ), toJS( address ), call ), + jsonrpc::JsonRpcException ); + } + + for ( const auto& call : wellFormedCalls ) { + BOOST_REQUIRE_NO_THROW( + fixture.rpcClient->eth_getTransactionCountEIP1898( toJS( address ), call ) ); + } + + for ( const auto& call : badFormedCalls ) { + BOOST_REQUIRE_THROW( + fixture.rpcClient->eth_getTransactionCountEIP1898( toJS( address ), call ), + jsonrpc::JsonRpcException ); + } +} + +BOOST_AUTO_TEST_CASE( eip2930Transactions ) { + std::string _config = c_genesisConfigString; + Json::Value ret; + Json::Reader().parse( _config, ret ); + + // Set chainID = 151 + std::string chainID = "0x97"; + ret["params"]["chainID"] = chainID; + time_t eip1559PatchActivationTimestamp = time( nullptr ) + 10; + ret["skaleConfig"]["sChain"]["EIP1559TransactionsPatchTimestamp"] = + eip1559PatchActivationTimestamp; + + + Json::FastWriter fastWriter; + std::string config = fastWriter.write( ret ); + JsonRpcFixture fixture( config ); + + dev::eth::simulateMining( *( fixture.client ), 20 ); + string senderAddress = toJS( fixture.coinbase.address() ); + + Json::Value txRefill; + txRefill["to"] = "0xc868AF52a6549c773082A334E5AE232e0Ea3B513"; + txRefill["from"] = senderAddress; + txRefill["gas"] = "100000"; + txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txRefill["value"] = 100000000000000000; + string txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); + BOOST_REQUIRE( receipt["type"] == "0x0" ); + + auto result = fixture.rpcClient->eth_getTransactionByHash( txHash ); + BOOST_REQUIRE( result["type"] == "0x0" ); + BOOST_REQUIRE( !result.isMember( "yParity" ) ); + BOOST_REQUIRE( !result.isMember( "accessList" ) ); + + BOOST_REQUIRE( fixture.rpcClient->eth_getBalance( "0xc868AF52a6549c773082A334E5AE232e0Ea3B513", + "latest" ) == "0x16345785d8a0000" ); + +#ifndef FAIR + // try sending type1 txn before patchTimestmap + BOOST_REQUIRE_THROW( + fixture.rpcClient->eth_sendRawTransaction( + "0x01f8678197808504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b0180c001a01e" + "bdc546c8b85511b7ba831f47c4981069d7af972d10b7dce2c57225cb5df6a7a055ae1e84fea41d37589eb7" + "40a0a93017a5cd0e9f10ee50f165bf4b1b4c78ddae" ), + jsonrpc::JsonRpcException ); // INVALID_PARAMS + sleep( 10 ); +#endif + + // force 1 block to update timestamp + txRefill["to"] = "0xc868AF52a6549c773082A334E5AE232e0Ea3B513"; + txRefill["from"] = senderAddress; + txRefill["gas"] = "100000"; + txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txRefill["value"] = 0; + txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); + BOOST_REQUIRE( receipt["type"] == "0x0" ); + + // send 1 WEI from 0xc868AF52a6549c773082A334E5AE232e0Ea3B513 to + // 0x7D36aF85A184E220A656525fcBb9A63B9ab3C12b encoded type 1 txn + txHash = fixture.rpcClient->eth_sendRawTransaction( + "0x01f8678197808504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b0180c001a01ebdc5" + "46c8b85511b7ba831f47c4981069d7af972d10b7dce2c57225cb5df6a7a055ae1e84fea41d37589eb740a0a930" + "17a5cd0e9f10ee50f165bf4b1b4c78ddae" ); + auto pendingTransactions = fixture.rpcClient->eth_pendingTransactions(); + BOOST_REQUIRE( pendingTransactions.isArray() && pendingTransactions.size() == 1 ); + BOOST_REQUIRE( pendingTransactions[0]["type"] == "0x1" ); + BOOST_REQUIRE( pendingTransactions[0].isMember( "yParity" ) && + pendingTransactions[0].isMember( "accessList" ) ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + // compare with txn hash from geth + BOOST_REQUIRE( txHash == "0xc843560015a655b8f81f65a458be9019bdb5cd8e416b6329ca18f36de0b8244d" ); + + BOOST_REQUIRE( dev::toHexPrefixed( fixture.client->transactions( 4 )[0].toBytes() ) == + "0x01f8678197808504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b0180c" + "001a01ebdc546c8b85511b7ba831f47c4981069d7af972d10b7dce2c57225cb5df6a7a055ae1e84" + "fea41d37589eb740a0a93017a5cd0e9f10ee50f165bf4b1b4c78ddae" ); + + BOOST_REQUIRE( fixture.rpcClient->eth_getBalance( + "0x7D36aF85A184E220A656525fcBb9A63B9ab3C12b", "latest" ) == "0x1" ); + + auto block = fixture.rpcClient->eth_getBlockByNumber( "4", false ); + BOOST_REQUIRE( block["transactions"].size() == 1 ); + BOOST_REQUIRE( block["transactions"][0].asString() == txHash ); + + block = fixture.rpcClient->eth_getBlockByNumber( "4", true ); + BOOST_REQUIRE( block["transactions"].size() == 1 ); + BOOST_REQUIRE( block["transactions"][0]["hash"].asString() == txHash ); + BOOST_REQUIRE( block["transactions"][0]["type"] == "0x1" ); + + BOOST_REQUIRE( block["transactions"][0]["yParity"].asString() == + block["transactions"][0]["v"].asString() ); + + BOOST_REQUIRE( block["transactions"][0]["accessList"].isArray() ); + BOOST_REQUIRE( block["transactions"][0]["accessList"].size() == 0 ); + BOOST_REQUIRE( block["transactions"][0].isMember( "chainId" ) ); + BOOST_REQUIRE( block["transactions"][0]["chainId"].asString() == chainID ); + + std::string blockHash = block["hash"].asString(); + BOOST_REQUIRE( + fixture.client->transactionHashes( dev::h256( blockHash ) )[0] == + dev::h256( "0xc843560015a655b8f81f65a458be9019bdb5cd8e416b6329ca18f36de0b8244d" ) ); + + receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); + BOOST_REQUIRE( receipt["type"] == "0x1" ); + BOOST_REQUIRE( receipt["effectiveGasPrice"] == "0x4a817c800" ); + + result = fixture.rpcClient->eth_getTransactionByHash( txHash ); + BOOST_REQUIRE( result["hash"].asString() == txHash ); + BOOST_REQUIRE( result["type"] == "0x1" ); + + BOOST_REQUIRE( result["yParity"].asString() == result["v"].asString() ); + + BOOST_REQUIRE( result["accessList"].isArray() ); + BOOST_REQUIRE( result["accessList"].size() == 0 ); + + result = fixture.rpcClient->eth_getTransactionByBlockHashAndIndex( blockHash, "0x0" ); + BOOST_REQUIRE( result["hash"].asString() == txHash ); + BOOST_REQUIRE( result["type"] == "0x1" ); + BOOST_REQUIRE( result["yParity"].asString() == result["v"].asString() ); + BOOST_REQUIRE( result["accessList"].isArray() ); + + result = fixture.rpcClient->eth_getTransactionByBlockNumberAndIndex( "0x4", "0x0" ); + BOOST_REQUIRE( result["hash"].asString() == txHash ); + BOOST_REQUIRE( result["type"] == "0x1" ); + + BOOST_REQUIRE( result["yParity"].asString() == result["v"].asString() ); + + BOOST_REQUIRE( result["accessList"].isArray() ); + BOOST_REQUIRE( result["accessList"].size() == 0 ); + + // now the same txn with accessList and increased nonce + // [ { 'address': HexBytes( "0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae" ), 'storageKeys': ( + // "0x0000000000000000000000000000000000000000000000000000000000000003", + // "0x0000000000000000000000000000000000000000000000000000000000000007" ) } ] + txHash = fixture.rpcClient->eth_sendRawTransaction( + "0x01f8c38197018504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b0180f85bf85994de" + "0b295669a9fd93d5f28d9ec85e40f4cb697baef842a00000000000000000000000000000000000000000000000" + "000000000000000003a0000000000000000000000000000000000000000000000000000000000000000780a0b0" + "3eaf481958e22fc39bd1d526eb9255be1e6625614f02ca939e51c3d7e64bcaa05f675640c04bb050d27bd1f39c" + "07b6ff742311b04dab760bb3bc206054332879" ); + pendingTransactions = fixture.rpcClient->eth_pendingTransactions(); + BOOST_REQUIRE( pendingTransactions.isArray() && pendingTransactions.size() == 1 ); + BOOST_REQUIRE( pendingTransactions[0]["type"] == "0x1" ); + BOOST_REQUIRE( pendingTransactions[0].isMember( "yParity" ) && + pendingTransactions[0].isMember( "accessList" ) ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + // compare with txn hash from geth + BOOST_REQUIRE( txHash == "0xa6d3541e06dff71fb8344a4db2a4ad4e0b45024eb23a8f568982b70a5f50f94d" ); + BOOST_REQUIRE( + dev::toHexPrefixed( fixture.client->transactions( 5 )[0].toBytes() ) == + "0x01f8c38197018504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b0180f85bf85994de" + "0b295669a9fd93d5f28d9ec85e40f4cb697baef842a00000000000000000000000000000000000000000000000" + "000000000000000003a0000000000000000000000000000000000000000000000000000000000000000780a0b0" + "3eaf481958e22fc39bd1d526eb9255be1e6625614f02ca939e51c3d7e64bcaa05f675640c04bb050d27bd1f39c" + "07b6ff742311b04dab760bb3bc206054332879" ); + + result = fixture.rpcClient->eth_getTransactionByHash( txHash ); + BOOST_REQUIRE( result["type"] == "0x1" ); + BOOST_REQUIRE( result["accessList"].isArray() ); + BOOST_REQUIRE( result["accessList"].size() == 1 ); + BOOST_REQUIRE( result["accessList"][0].isObject() && + result["accessList"][0].getMemberNames().size() == 2 ); + BOOST_REQUIRE( result["accessList"][0].isMember( "address" ) && + result["accessList"][0].isMember( "storageKeys" ) ); + BOOST_REQUIRE( result["accessList"][0]["address"].asString() == + "0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae" ); + BOOST_REQUIRE( result["accessList"][0]["storageKeys"].isArray() && + result["accessList"][0]["storageKeys"].size() == 2 ); + BOOST_REQUIRE( result["accessList"][0]["storageKeys"][0].asString() == + "0x0000000000000000000000000000000000000000000000000000000000000003" ); + BOOST_REQUIRE( result["accessList"][0]["storageKeys"][1].asString() == + "0x0000000000000000000000000000000000000000000000000000000000000007" ); + + block = fixture.rpcClient->eth_getBlockByNumber( "5", true ); + result = block["transactions"][0]; + BOOST_REQUIRE( result["type"] == "0x1" ); + BOOST_REQUIRE( result["accessList"].isArray() ); + BOOST_REQUIRE( result["accessList"].size() == 1 ); + BOOST_REQUIRE( result["accessList"][0].isObject() && + result["accessList"][0].getMemberNames().size() == 2 ); + BOOST_REQUIRE( result["accessList"][0].isMember( "address" ) && + result["accessList"][0].isMember( "storageKeys" ) ); + BOOST_REQUIRE( result["accessList"][0]["address"].asString() == + "0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae" ); + BOOST_REQUIRE( result["accessList"][0]["storageKeys"].isArray() && + result["accessList"][0]["storageKeys"].size() == 2 ); + BOOST_REQUIRE( result["accessList"][0]["storageKeys"][0].asString() == + "0x0000000000000000000000000000000000000000000000000000000000000003" ); + BOOST_REQUIRE( result["accessList"][0]["storageKeys"][1].asString() == + "0x0000000000000000000000000000000000000000000000000000000000000007" ); +} + +BOOST_AUTO_TEST_CASE( eip1559Transactions ) { + std::string _config = c_genesisConfigString; + Json::Value ret; + Json::Reader().parse( _config, ret ); + + // Set chainID = 151 + std::string chainID = "0x97"; + ret["params"]["chainID"] = chainID; + time_t eip1559PatchActivationTimestamp = time( nullptr ) + 10; + ret["skaleConfig"]["sChain"]["EIP1559TransactionsPatchTimestamp"] = + eip1559PatchActivationTimestamp; + + Json::FastWriter fastWriter; + std::string config = fastWriter.write( ret ); + JsonRpcFixture fixture( config ); + + dev::eth::simulateMining( *( fixture.client ), 20 ); + fixture.client->state().getOriginalDb()->createBlockSnap( 2 ); + string senderAddress = toJS( fixture.coinbase.address() ); + + Json::Value txRefill; + txRefill["to"] = "0x5EdF1e852fdD1B0Bc47C0307EF755C76f4B9c251"; + txRefill["from"] = senderAddress; + txRefill["gas"] = "100000"; + txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txRefill["value"] = 100000000000000000; + string txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + fixture.client->state().getOriginalDb()->createBlockSnap( 3 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); + BOOST_REQUIRE( receipt["type"] == "0x0" ); + + auto result = fixture.rpcClient->eth_getTransactionByHash( txHash ); + BOOST_REQUIRE( result["type"] == "0x0" ); + BOOST_REQUIRE( !result.isMember( "yParity" ) ); + BOOST_REQUIRE( !result.isMember( "accessList" ) ); + + BOOST_REQUIRE( fixture.rpcClient->eth_getBalance( "0x5EdF1e852fdD1B0Bc47C0307EF755C76f4B9c251", + "latest" ) == "0x16345785d8a0000" ); + +#ifndef FAIR + // try sending type2 txn before patchTimestmap + BOOST_REQUIRE_THROW( + fixture.rpcClient->eth_sendRawTransaction( + "0x02f8c98197808504a817c8018504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b" + "0180f85bf85994de0b295669a9fd93d5f28d9ec85e40f4cb697baef842a000000000000000000000000000" + "00000000000000000000000000000000000003a00000000000000000000000000000000000000000000000" + "00000000000000000701a005bd1eedc509a8e94cfcfc84d0b5fd53a0888a475274cbeee321047da5d139f8" + "a00e7f0dd8b5277766d447ea51b7d8f571dc8bb57ff95c068c58f5b6fe9089dde8" ), + jsonrpc::JsonRpcException ); // INVALID_PARAMS + sleep( 10 ); +#endif + + // force 1 block to update timestamp + txRefill["to"] = "0xc868AF52a6549c773082A334E5AE232e0Ea3B513"; + txRefill["from"] = senderAddress; + txRefill["gas"] = "100000"; + txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txRefill["value"] = 0; + txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + fixture.client->state().getOriginalDb()->createBlockSnap( 4 ); + receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); + BOOST_REQUIRE( receipt["type"] == "0x0" ); + BOOST_REQUIRE( receipt["effectiveGasPrice"] == "0x4a817c800" ); + + + // send 1 WEI from 0x5EdF1e852fdD1B0Bc47C0307EF755C76f4B9c251 to + // 0x7D36aF85A184E220A656525fcBb9A63B9ab3C12b encoded type 2 txn + txHash = fixture.rpcClient->eth_sendRawTransaction( + "0x02f8c98197808504a817c8008504a817c801827530947d36af85a184e220a656525fcbb9a63b9ab3c12b018" + "0f85bf85994de0b295669a9fd93d5f28d9ec85e40f4cb697baef842a000000000000000000000000000000000" + "00000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000" + "00000000780a0f000a16aeee9ac96602e8b179d39caca61f347a296e78ec9c57ec06c6e378422a02462cfad48" + "32a32ed8c55fddf8a033d4a73f62fed993de3687ba14902eaea2d4" ); + + auto pendingTransactions = fixture.rpcClient->eth_pendingTransactions(); + BOOST_REQUIRE( pendingTransactions.isArray() && pendingTransactions.size() == 1 ); + BOOST_REQUIRE( pendingTransactions[0]["type"] == "0x2" ); + BOOST_REQUIRE( pendingTransactions[0].isMember( "yParity" ) && + pendingTransactions[0].isMember( "accessList" ) ); + BOOST_REQUIRE( pendingTransactions[0].isMember( "maxFeePerGas" ) && + pendingTransactions[0].isMember( "maxPriorityFeePerGas" ) ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + // compare with txn hash from geth + BOOST_REQUIRE( txHash == "0xd9463624627c7add3b3ac18a228569b3a9075cc05bec64db060ea8904f3c4288" ); + BOOST_REQUIRE( + dev::toHexPrefixed( fixture.client->transactions( 4 )[0].toBytes() ) == + "0x02f8c98197808504a817c8008504a817c801827530947d36af85a184e220a656525fcbb9a63b9ab3c12b018" + "0f85bf85994de0b295669a9fd93d5f28d9ec85e40f4cb697baef842a000000000000000000000000000000000" + "00000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000" + "00000000780a0f000a16aeee9ac96602e8b179d39caca61f347a296e78ec9c57ec06c6e378422a02462cfad48" + "32a32ed8c55fddf8a033d4a73f62fed993de3687ba14902eaea2d4" ); + + BOOST_REQUIRE( fixture.rpcClient->eth_getBalance( + "0x7D36aF85A184E220A656525fcBb9A63B9ab3C12b", "latest" ) == "0x1" ); + + auto block = fixture.rpcClient->eth_getBlockByNumber( "4", false ); + BOOST_REQUIRE( block["transactions"].size() == 1 ); + BOOST_REQUIRE( block["transactions"][0].asString() == txHash ); + + block = fixture.rpcClient->eth_getBlockByNumber( "4", true ); + BOOST_REQUIRE( !block["baseFeePerGas"].asString().empty() ); + BOOST_REQUIRE( block["transactions"].size() == 1 ); + BOOST_REQUIRE( block["transactions"][0]["hash"].asString() == txHash ); + BOOST_REQUIRE( block["transactions"][0]["type"] == "0x2" ); + + BOOST_REQUIRE( block["transactions"][0]["yParity"].asString() == + block["transactions"][0]["v"].asString() ); + + BOOST_REQUIRE( block["transactions"][0]["accessList"].isArray() ); + BOOST_REQUIRE( block["transactions"][0].isMember( "chainId" ) ); + BOOST_REQUIRE( block["transactions"][0]["chainId"].asString() == chainID ); + + std::string blockHash = block["hash"].asString(); + + receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); + BOOST_REQUIRE( receipt["type"] == "0x2" ); + BOOST_REQUIRE( receipt["effectiveGasPrice"] == "0x4a817c801" ); + + result = fixture.rpcClient->eth_getTransactionByHash( txHash ); + BOOST_REQUIRE( result["hash"].asString() == txHash ); + BOOST_REQUIRE( result["type"] == "0x2" ); + + BOOST_REQUIRE( result["yParity"].asString() == result["v"].asString() ); + + BOOST_REQUIRE( result["accessList"].isArray() ); + BOOST_REQUIRE( + result.isMember( "maxPriorityFeePerGas" ) && result["maxPriorityFeePerGas"].isString() ); + BOOST_REQUIRE( result.isMember( "maxFeePerGas" ) && result["maxFeePerGas"].isString() ); + BOOST_REQUIRE( result["maxPriorityFeePerGas"] == "0x4a817c800" ); + BOOST_REQUIRE( result["maxFeePerGas"] == "0x4a817c801" ); + + result = fixture.rpcClient->eth_getTransactionByBlockHashAndIndex( blockHash, "0x0" ); + BOOST_REQUIRE( result["hash"].asString() == txHash ); + BOOST_REQUIRE( result["type"] == "0x2" ); + + BOOST_REQUIRE( result["yParity"].asString() == result["v"].asString() ); + + BOOST_REQUIRE( result["accessList"].isArray() ); + BOOST_REQUIRE( result["maxPriorityFeePerGas"] == "0x4a817c800" ); + BOOST_REQUIRE( result["maxFeePerGas"] == "0x4a817c801" ); + + result = fixture.rpcClient->eth_getTransactionByBlockNumberAndIndex( "0x4", "0x0" ); + BOOST_REQUIRE( result["hash"].asString() == txHash ); + BOOST_REQUIRE( result["type"] == "0x2" ); + + BOOST_REQUIRE( result["yParity"].asString() == result["v"].asString() ); + + BOOST_REQUIRE( result["accessList"].isArray() ); + BOOST_REQUIRE( result["maxPriorityFeePerGas"] == "0x4a817c800" ); + BOOST_REQUIRE( result["maxFeePerGas"] == "0x4a817c801" ); + + BOOST_REQUIRE_NO_THROW( fixture.rpcClient->eth_getBlockByNumber( "0x0", false ) ); +} + +BOOST_AUTO_TEST_CASE( eip2930RpcMethods ) { + std::string _config = c_genesisConfigString; + Json::Value ret; + Json::Reader().parse( _config, ret ); + + // Set chainID = 151 + ret["params"]["chainID"] = "0x97"; + + Json::FastWriter fastWriter; + std::string config = fastWriter.write( ret ); + JsonRpcFixture fixture( config ); + + dev::eth::simulateMining( *( fixture.client ), 20 ); + string senderAddress = toJS( fixture.coinbase.address() ); + + Json::Value txRefill; + txRefill["to"] = "0x5EdF1e852fdD1B0Bc47C0307EF755C76f4B9c251"; + txRefill["from"] = senderAddress; + txRefill["gas"] = "100000"; + txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txRefill["value"] = 1000000; + string txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); + BOOST_REQUIRE( receipt["type"] == "0x0" ); + + auto accessList = fixture.rpcClient->eth_createAccessList( txRefill, "latest" ); + BOOST_REQUIRE( accessList.isMember( "accessList" ) && accessList.isMember( "gasUsed" ) ); + BOOST_REQUIRE( accessList["accessList"].isArray() && accessList["accessList"].size() == 0 ); + BOOST_REQUIRE( accessList["gasUsed"].isString() ); +} + +BOOST_AUTO_TEST_CASE( eip1559RpcMethods ) { + std::string _config = c_genesisConfigString; + Json::Value ret; + Json::Reader().parse( _config, ret ); + + // Set chainID = 151 + ret["params"]["chainID"] = "0x97"; + time_t eip1559PatchActivationTimestamp = time( nullptr ) + 5; + ret["skaleConfig"]["sChain"]["EIP1559TransactionsPatchTimestamp"] = + eip1559PatchActivationTimestamp; + + Json::FastWriter fastWriter; + std::string config = fastWriter.write( ret ); + JsonRpcFixture fixture( config ); + + dev::eth::simulateMining( *( fixture.client ), 20 ); + string senderAddress = toJS( fixture.coinbase.address() ); + + Json::Value txRefill; + txRefill["to"] = "0x5EdF1e852fdD1B0Bc47C0307EF755C76f4B9c251"; + txRefill["from"] = senderAddress; + txRefill["gas"] = "100000"; + txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txRefill["value"] = 100000000000000000; + for ( size_t i = 0; i < 10; ++i ) { + // mine 10 blocks + string txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + } + + BOOST_REQUIRE( fixture.rpcClient->eth_maxPriorityFeePerGas() == "0x0" ); + + auto bn = fixture.client->number(); + + Json::Value percentiles = Json::Value( Json::arrayValue ); + percentiles.resize( 2 ); + percentiles[0] = 20; + percentiles[1] = 80; + + size_t blockCnt = 9; + auto feeHistory = fixture.rpcClient->eth_feeHistory( toJS( blockCnt ), "latest", percentiles ); + + BOOST_REQUIRE( feeHistory["oldestBlock"] == toJS( bn - blockCnt + 1 ) ); + + BOOST_REQUIRE( feeHistory.isMember( "baseFeePerGas" ) ); + BOOST_REQUIRE( feeHistory["baseFeePerGas"].isArray() ); + + for ( Json::Value::ArrayIndex i = 0; i < blockCnt; ++i ) { + BOOST_REQUIRE( feeHistory["baseFeePerGas"][i].isString() ); + std::string estimatedBaseFeePerGas = + EIP1559TransactionsPatch::isEnabledWhen( + fixture.client->blockInfo( bn - i - 1 ).timestamp() ) ? + toJS( fixture.client->gasBidPrice( bn - i - 1 ) ) : + toJS( 0 ); + BOOST_REQUIRE( feeHistory["baseFeePerGas"][i].asString() == estimatedBaseFeePerGas ); + BOOST_REQUIRE_GT( feeHistory["gasUsedRatio"][i].asDouble(), 0 ); + BOOST_REQUIRE_GT( 1, feeHistory["gasUsedRatio"][i].asDouble() ); + for ( Json::Value::ArrayIndex j = 0; j < percentiles.size(); ++j ) { + BOOST_REQUIRE_EQUAL( feeHistory["reward"][i][j].asString(), toJS( 0 ) ); + } + } + + Json::Value floatPercentiles = Json::Value( Json::arrayValue ); + floatPercentiles.resize( 2 ); + floatPercentiles[0] = 20.5; + floatPercentiles[1] = 80.0; + + auto feeHistoryWithFloatPercentiles = + fixture.rpcClient->eth_feeHistory( toJS( blockCnt ), "latest", floatPercentiles ); + BOOST_REQUIRE( feeHistoryWithFloatPercentiles.isMember( "reward" ) ); + BOOST_REQUIRE( feeHistoryWithFloatPercentiles["reward"].isArray() ); + for ( Json::Value::ArrayIndex i = 0; i < blockCnt; ++i ) { + BOOST_REQUIRE( feeHistoryWithFloatPercentiles["reward"][i].isArray() ); + BOOST_REQUIRE_EQUAL( + feeHistoryWithFloatPercentiles["reward"][i].size(), floatPercentiles.size() ); + } + + BOOST_REQUIRE_NO_THROW( fixture.rpcClient->eth_feeHistory( blockCnt, "latest", percentiles ) ); +} + +BOOST_AUTO_TEST_CASE( vInTxnSignature ) { + std::string _config = c_genesisConfigString; + Json::Value ret; + Json::Reader().parse( _config, ret ); + + // Set chainID = 151 + ret["params"]["chainID"] = "0x97"; + time_t eip1559PatchActivationTimestamp = time( nullptr ); + ret["skaleConfig"]["sChain"]["EIP1559TransactionsPatchTimestamp"] = + eip1559PatchActivationTimestamp; + + Json::FastWriter fastWriter; + std::string config = fastWriter.write( ret ); + JsonRpcFixture fixture( config ); + + dev::eth::simulateMining( *( fixture.client ), 20 ); + string senderAddress = toJS( fixture.coinbase.address() ); + + Json::Value txRefill; + txRefill["to"] = "0x5EdF1e852fdD1B0Bc47C0307EF755C76f4B9c251"; + txRefill["from"] = senderAddress; + txRefill["gas"] = "100000"; + txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txRefill["value"] = 100000000000000000; + string txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + // send non replay protected txn + txHash = fixture.rpcClient->eth_sendRawTransaction( + "0xf864808504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b01801ba0171c7f31feaa0f" + "d7825a5a28d7b535d0b0ee200b27792f66eb7796e7a6a555d7a0081790244f21cefa563b55a7a68ee78f846673" + "8b5827be19faaeff0586fd71be" ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value txn = fixture.rpcClient->eth_getTransactionByHash( txHash ); + dev::u256 v = dev::jsToU256( txn["v"].asString() ); + BOOST_REQUIRE( v < 29 && v > 26 ); + + // send replay protected legacy txn + txHash = fixture.rpcClient->eth_sendRawTransaction( + "0xf866018504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b0180820151a018b400fc56" + "bc3568e4f23f6f93d538745a5b18054252d6030791c294c9aea9d4a00930492125784fad0a8b38b915e8621f54" + "c53f0878a77f21920c751ec5fd220a" ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + txn = fixture.rpcClient->eth_getTransactionByHash( txHash ); + v = dev::jsToU256( txn["v"].asString() ); + BOOST_REQUIRE( v < 339 && v > 336 ); // 2 * 151 + 35 + + // send type1 txn + txHash = fixture.rpcClient->eth_sendRawTransaction( + "0x01f8c38197028504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b0180f85bf85994de" + "0b295669a9fd93d5f28d9ec85e40f4cb697baef842a00000000000000000000000000000000000000000000000" + "000000000000000003a0000000000000000000000000000000000000000000000000000000000000000701a0ee" + "608b7c5df843b4a1988a3e9c24d53019fa674e06a6b2ae0c347a00601c1a84a06ed451f9cc0f4334a180458605" + "ecaa212e58f8436e1a4318e75ae417c72eba2b" ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + txn = fixture.rpcClient->eth_getTransactionByHash( txHash ); + v = dev::jsToU256( txn["v"].asString() ); + BOOST_REQUIRE( v < 2 && v >= 0 ); + + // send type2 txn + txHash = fixture.rpcClient->eth_sendRawTransaction( + "0x02f86d8197038504a817c8008504a817c801827530947d36af85a184e220a656525fcbb9a63b9ab3c12b808" + "0c001a0f399bf6ecf7f7d464d18a36a05475c6464760a111a2039b9be76eadbe185e4b4a0234c828163103039" + "446653ebc8031631ab984e59169be57a759345fe4a1bf127" ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + txn = fixture.rpcClient->eth_getTransactionByHash( txHash ); + v = dev::jsToU256( txn["v"].asString() ); + BOOST_REQUIRE( v < 2 && v >= 0 ); +} + +BOOST_AUTO_TEST_CASE( InvalidTransactionFormatPatch ) { + std::string _config = c_genesisConfigString; + Json::Value ret; + Json::Reader().parse( _config, ret ); + + // Set chainID = 151 + std::string chainID = "0x97"; + ret["params"]["chainID"] = chainID; + time_t eip1559PatchActivationTimestamp = time( nullptr ) - 1; + time_t InvalidTransactionFormatPatchActivationTimestamp = time( nullptr ) + 10; + ret["skaleConfig"]["sChain"]["InvalidTransactionFormatPatchTimestamp"] = + InvalidTransactionFormatPatchActivationTimestamp; + ret["skaleConfig"]["sChain"]["EIP1559TransactionsPatchTimestamp"] = + eip1559PatchActivationTimestamp; + + Json::FastWriter fastWriter; + std::string config = fastWriter.write( ret ); + JsonRpcFixture fixture( config ); + + dev::eth::simulateMining( *( fixture.client ), 20 ); + string senderAddress = toJS( fixture.coinbase.address() ); + + Json::Value txRefill; + txRefill["to"] = "0x5EdF1e852fdD1B0Bc47C0307EF755C76f4B9c251"; + txRefill["from"] = senderAddress; + txRefill["gas"] = "100000"; + txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txRefill["value"] = 1000000000000000000; + string txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); + + +#ifndef FAIR + // send a txn with maxPriorityFeePerGas > maxFeePerGas before + // InvalidTransactionFormatPatchTimestamp + txHash = fixture.rpcClient->eth_sendRawTransaction( + "0x02f86d8197808504a817c8018504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b8080" + "c001a0db2fe04a66fa54bfe9c6e0166d85a31b34cbff10dbde0e0584081aec6bb33c30a06b956a49c52f1460da" + "9f93fc495eaa863ae5a8c91ee9230c2f3976f5e74d4f47" ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); + + Json::Value tx = fixture.rpcClient->eth_getTransactionByHash( txHash ); + BOOST_REQUIRE( dev::jsToU256( tx["maxFeePerGas"].asString() ) < + dev::jsToU256( tx["maxPriorityFeePerGas"].asString() ) ); + + dev::eth::Transaction t = fixture.client->transaction( dev::h256( txHash ) ); + BOOST_REQUIRE( t.maxFeePerGas() < t.maxPriorityFeePerGas() ); +#endif + + sleep( 10 ); + + // force 1 block to update timestamp + txRefill["to"] = "0xc868AF52a6549c773082A334E5AE232e0Ea3B513"; + txRefill["from"] = senderAddress; + txRefill["gas"] = "100000"; + txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txRefill["value"] = 0; + txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + sleep( 1 ); + + // send a txn with maxPriorityFeePerGas > maxFeePerGas after + // InvalidTransactionFormatPatchTimestamp, it should fail + BOOST_REQUIRE_THROW( + fixture.rpcClient->eth_sendRawTransaction( + "0x02f86d8197018504a817c8018504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b" + "8080c080a0aea5ff86373cbbbb33c9f3e9a25ceb9a694ee71beff452a4d29903d73fd30ca9a00458d4f7d5" + "4be178b42d230cc5a4740540d55b8ca0f9c74c79c1d49f6686b1e6" ), + jsonrpc::JsonRpcException ); // INVALID_PARAMS +} + +BOOST_AUTO_TEST_CASE( jsonrpcVersionInResponseHeader ) { + JsonRpcFixture fixture; + + dev::eth::simulateMining( *( fixture.client ), 20 ); + // pragma solidity >=0.8.2 <0.9.0; + + // /** + // * @title Storage + // * @dev Store & retrieve value in a variable + // * @custom:dev-run-script ./scripts/deploy_with_ethers.ts + // */ + // contract Storage { + + // uint256 number; + // uint256 number1; + // uint256 number2; + + // /** + // * @dev Store value in variable + // * @param num value to store + // */ + // function store(uint256 num) public { + // number = num; + // number1 = num; + // number2 = num; + // } + + // /** + // * @dev Return value + // * @return value of 'number' + // */ + // function retrieve() public view returns (uint256){ + // return number; + // } + // } + std::string bytecode = + "6080604052348015600f57600080fd5b5061015e8061001f6000396000f3fe6080604052348015610010576000" + "80fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd" + "5b610043610075565b60405161005091906100af565b60405180910390f35b610073600480360381019061006e" + "91906100fb565b61007e565b005b60008054905090565b80600081905550806001819055508060028190555050" + "565b6000819050919050565b6100a981610096565b82525050565b60006020820190506100c460008301846100" + "a0565b92915050565b600080fd5b6100d881610096565b81146100e357600080fd5b50565b6000813590506100" + "f5816100cf565b92915050565b600060208284031215610111576101106100ca565b5b600061011f8482850161" + "00e6565b9150509291505056fea264697066735822122081840c9060f8fb10a0bdf054a92c6bd15ea462286507" + "fad9a9fe26e653e2f2e264736f6c634300081a0033"; + auto senderAddress = fixture.coinbase.address(); + + Json::Value create1; + create1["from"] = toJS( senderAddress ); + create1["data"] = bytecode; + create1["gas"] = "1800000"; + string txHash = fixture.rpcClient->eth_sendTransaction( create1 ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); + string contractAddress = receipt["contractAddress"].asString(); + + skutils::rest::client cli( skutils::rest::g_nClientConnectionTimeoutMS ); + std::string url = + std::string( "http://" ) + + fixture.skale_server_connector->opts_.netOpts_.bindOptsStandard_.strAddrHTTP4_ + + std::string( ":" ) + + std::to_string( + fixture.skale_server_connector->opts_.netOpts_.bindOptsStandard_.nBasePortHTTP4_ ); + BOOST_REQUIRE( cli.open( url ) ); + + // try to send bad call to trigger EVM reverted w/o description error + nlohmann::json joIn = nlohmann::json::object(); + joIn["jsonrpc"] = "2.0"; + joIn["method"] = "eth_call"; + nlohmann::json params = nlohmann::json::array(); + nlohmann::json callDetails = nlohmann::json::object(); + callDetails["data"] = + "0x01ffc9a7d9b67a2600000000000000000000000000000000000000000000000000000000"; + callDetails["to"] = contractAddress; + params.push_back( callDetails ); + params.push_back( "latest" ); + joIn["params"] = params; + skutils::rest::data_t d = cli.call( joIn ); + + nlohmann::json joAnswer = nlohmann::json::parse( d.s_ ); + BOOST_REQUIRE( joAnswer.count( "jsonrpc" ) > 0 ); + BOOST_REQUIRE( joAnswer["jsonrpc"] == "2.0" ); + + // try to send legit eth_call as well + joIn = nlohmann::json::object(); + joIn["jsonrpc"] = "2.0"; + joIn["method"] = "eth_call"; + params = nlohmann::json::array(); + callDetails = nlohmann::json::object(); + callDetails["data"] = "0x2e64cec1"; + callDetails["to"] = contractAddress; + callDetails["from"] = senderAddress.hex(); + callDetails["value"] = "0x0"; + params.push_back( callDetails ); + params.push_back( "latest" ); + joIn["params"] = params; + d = cli.call( joIn ); + + joAnswer = nlohmann::json::parse( d.s_ ); + BOOST_REQUIRE( joAnswer.count( "jsonrpc" ) > 0 ); + BOOST_REQUIRE( joAnswer["jsonrpc"] == "2.0" ); +} + +BOOST_AUTO_TEST_CASE( getZeroBlock ) { + JsonRpcFixture fixture; + Json::Value block = fixture.rpcClient->eth_getBlockByNumber( "0", "false" ); + BOOST_REQUIRE( block["number"] == string( "0x0" ) ); + + string blockHash = block["hash"].asString(); + Json::Value blockByHash = fixture.rpcClient->eth_getBlockByHash( blockHash, "false" ); + BOOST_REQUIRE( blockByHash["number"] == string( "0x0" ) ); + BOOST_REQUIRE( blockByHash["hash"] == blockHash ); +} + +BOOST_AUTO_TEST_CASE( getBlockRandom ) { + std::string _config = c_genesisConfigString; + Json::Value ret; + Json::Reader().parse( _config, ret ); + + time_t currentBlockRandomPatchActivationTimestamp = time( nullptr ) + 10; + ret["skaleConfig"]["sChain"]["currentBlockRandomPatchTimestamp"] = + currentBlockRandomPatchActivationTimestamp; + + Json::FastWriter fastWriter; + std::string config = fastWriter.write( ret ); + + JsonRpcFixture fixture( config ); + + dev::eth::simulateMining( *( fixture.client ), 20 ); + string senderAddress = toJS( fixture.coinbase.address() ); + + // create block and save block random for it + Json::Value txRefill; + txRefill["to"] = "0xc868AF52a6549c773082A334E5AE232e0Ea3B513"; + txRefill["from"] = toJS( senderAddress ); + txRefill["gas"] = "100000"; + txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txRefill["value"] = 1; + fixture.rpcClient->eth_sendTransaction( txRefill ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + PrecompiledExecutor blockRandomExecutor = PrecompiledRegistrar::executor( "getBlockRandom" ); + auto blockNumberEarly = fixture.client->number(); + dev::eth::PrecompiledCallContext ctx( blockNumberEarly, 0, +#ifdef BITE + 0, + dev::h256::random(), + dev::ZeroAddress, +#endif + true ); + auto blockRandomEarly = blockRandomExecutor( dev::bytesConstRef(), ctx ); + + // wait till patch is activated + sleep( 10 ); + fixture.rpcClient->eth_sendTransaction( txRefill ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + // pragma solidity ^0.8.13; + + // contract GetBlockRandomPrecompiled { + // address public constant PRECOMPILE_0X08 = address(0x08); + // bytes32 lastBlockRandom; + + // function getBlockRandom() public returns (bytes32) { + // (bool success, bytes memory result) = PRECOMPILE_0X08.staticcall(""); + // require(success, "Call to precompile 0x06 failed"); + // require(result.length >= 20, "Invalid result length"); + // lastBlockRandom = bytes32(result); + + // return lastBlockRandom; + // } + + // function getLastBlockRandom() public view returns (bytes32) { + // return lastBlockRandom; + // } + // } + std::string bytecode = + "6080604052348015600f57600080fd5b506104548061001f6000396000f3fe6080604052348015610010576000" + "80fd5b50600436106100415760003560e01c80633ec4b2de146100465780635e2e884d14610064578063dc031d" + "fe14610082575b600080fd5b61004e6100a0565b60405161005b91906101fc565b60405180910390f35b61006c" + "6100a5565b6040516100799190610230565b60405180910390f35b61008a6100ae565b60405161009791906102" + "30565b60405180910390f35b600881565b60008054905090565b6000806000600873ffffffffffffffffffffff" + "ffffffffffffffffff166040516100d79061027c565b600060405180830381855afa9150503d80600081146101" + "12576040519150601f19603f3d011682016040523d82523d6000602084013e610117565b606091505b50915091" + "508161015c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260" + "0401610153906102ee565b60405180910390fd5b6014815110156101a1576040517f08c379a000000000000000" + "00000000000000000000000000000000000000000081526004016101989061035a565b60405180910390fd5b80" + "6101ab906103b7565b6000819055506000549250505090565b600073ffffffffffffffffffffffffffffffffff" + "ffffff82169050919050565b60006101e6826101bb565b9050919050565b6101f6816101db565b82525050565b" + "600060208201905061021160008301846101ed565b92915050565b6000819050919050565b61022a8161021756" + "5b82525050565b60006020820190506102456000830184610221565b92915050565b600081905092915050565b" + "50565b600061026660008361024b565b915061027182610256565b600082019050919050565b60006102878261" + "0259565b9150819050919050565b600082825260208201905092915050565b7f43616c6c20746f20707265636f" + "6d70696c652030783036206661696c65640000600082015250565b60006102d8601e83610291565b91506102e3" + "826102a2565b602082019050919050565b60006020820190508181036000830152610307816102cb565b905091" + "9050565b7f496e76616c696420726573756c74206c656e6774680000000000000000000000600082015250565b" + "6000610344601583610291565b915061034f8261030e565b602082019050919050565b60006020820190508181" + "03600083015261037381610337565b9050919050565b600081519050919050565b600081905060208201905091" + "9050565b60006103a18251610217565b80915050919050565b600082821b905092915050565b60006103c28261" + "037a565b826103cc84610385565b90506103d781610395565b92506020821015610417576104127fffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffff836020036008026103aa565b831692505b50" + "5091905056fea26469706673582212200547f4a1b7b525d8f531c7e991887fdca3437350b86fc09b06a1acaa83" + "b5c3ad64736f6c634300081e0033"; + + // deploy contract + Json::Value create; + create["from"] = toJS( senderAddress ); + create["code"] = bytecode; + create["gas"] = "900000"; + string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + auto txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + std::string contractAddress = txReceipt["contractAddress"].asString(); + + // submit getBlockRandom transaction + Json::Value txGenerate; + txGenerate["to"] = contractAddress; + txGenerate["data"] = "0xdc031dfe"; + txGenerate["from"] = toJS( senderAddress ); + fixture.rpcClient->eth_sendTransaction( txGenerate ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + // read data from contract + Json::Value callGetLast; + callGetLast["to"] = contractAddress; + callGetLast["data"] = "0x5e2e884d"; + callGetLast["from"] = toJS( senderAddress ); + dev::bytes blockRandomFromContract = + dev::fromHex( fixture.rpcClient->eth_call( callGetLast, "latest" ) ); + + ctx = PrecompiledCallContext( fixture.client->number(), 0, +#ifdef BITE + 0, + dev::h256::random(), + dev::ZeroAddress, +#endif + true ); + auto executionResult = blockRandomExecutor( dev::bytesConstRef(), ctx ); + + BOOST_REQUIRE( executionResult.first ); + BOOST_REQUIRE( executionResult.second == blockRandomFromContract ); + +#ifdef HISTORIC_STATE + // produce more blocks, execute historic call and compare results + fixture.rpcClient->eth_sendTransaction( txRefill ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + dev::bytes blockRandomFromHistoricCall = dev::fromHex( + fixture.rpcClient->eth_call( callGetLast, toJS( fixture.client->number() - 1 ) ) ); + BOOST_REQUIRE( blockRandomFromHistoricCall == blockRandomFromContract ); + + // ask for blockRandom for early block + ctx = PrecompiledCallContext( blockNumberEarly, 0, +#ifdef BITE + 0, + dev::h256::random(), + dev::ZeroAddress, +#endif + true ); + auto blockRandomEarlyHistoric = blockRandomExecutor( dev::bytesConstRef(), ctx ); + BOOST_REQUIRE( blockRandomEarlyHistoric.first ); + BOOST_REQUIRE( blockRandomEarlyHistoric.second == blockRandomEarly.second ); +#endif +} + +#ifdef BITE + +#ifndef FAIR +static std::string const c_BITEConfigString = + R"( +{ + "sealEngine": "NoProof", + "params": { + "accountStartNonce": "0x00", + "maximumExtraDataSize": "0x1000000", + "blockReward": "0x4563918244F40000", + "allowFutureBlocks": true, + "homesteadForkBlock": "0x00", + "EIP150ForkBlock": "0x00", + "EIP158ForkBlock": "0x00", + "byzantiumForkBlock": "0x00", + "constantinopleForkBlock": "0x00", + "istanbulForkBlock": "0x00", + "skaleDisableChainIdCheck": true, + "externalGasDifficulty": "0x1", + "minGasLimit": "0xFFFFFFF", + "maxGasLimit": "7fffffffffffffff" + }, + "genesis": { + "author" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "difficulty" : "0x20000", + "gasLimit": "0xFFFFFFF", + "nonce" : "0x00", + "extraData" : "0x00", + "timestamp" : "0x00", + "mixHash" : "0x00", + "stateRoot": "0x01" + }, + "skaleConfig": { + "nodeInfo": { + "nodeID": 8, + "nodeName": "test_node", + "bindIP": "0.0.0.0", + "logLevel": "info", + "logLevelConfig": "info", + "imaMessageProxySChain": "0xd2AAa00100000000000000000000000000000000", + "imaMessageProxyMainNet": "0x337591F78cbf2b113A57D9709511a1b6E524DdaE", + "rotateAfterBlock": 10240, + "basePort": )" + + std::to_string( rand_port ) + R"(, + "logLevel": "trace", + "logLevelProposal": "trace", + "ecdsaKeyName": "NEK:d391a1af1cd9663335e0f970e59402bf16fcfe0cc421c535bf60ba618a456d68", + "wallets": { + "ima": { + "keyShareName": "BLS_KEY:SCHAIN_ID:1:NODE_ID:0:DKG_ID:0", + "t": 1, + "n": 1, + "certFile": "/skale-data/node_data/sgx_certs/sgx.crt", + "keyFile": "/skale-data/node_data/sgx_certs/sgx.key", + "commonBLSPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", + "commonBLSPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", + "commonBLSPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", + "commonBLSPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693", + "BLSPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", + "BLSPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", + "BLSPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", + "BLSPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693" + } + } + }, + "sChain": { + "schainName": "TestChain", + "schainID": 1, + "contractStorageLimit": 128, + "emptyBlockIntervalMs": -1, + "ContractCreationReadOnlyPatchTimestamp": 1, + "SingleStateCommitPerBlockPatchTimestamp": 1,)" +#ifdef BITE + R"( "Bite2PatchTimestamp": 1, + "currentBlockRandomPatchTimestamp": 1,)" +#endif + R"( "nodeGroups": { + "0": { + "nodes": { + "8": [ + 1, + 8, + "0xf925c203a30ec6cad5a263db3efab7ed4c1fd74c8688167e10a5a22e15ab5018d8553df0ac54ea105a3d21845e5660bc3d4e7c82e7af1daa3baad393b1521467" + ] + }, + "finish_ts": null, + "bls_public_key": { + "blsPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", + "blsPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", + "blsPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", + "blsPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693" + } + } + }, + "nodes": [ + { + "nodeID": 8, + "nodeName": "test_node", + "basePort": )" + + std::to_string( rand_port ) + + R"(, + "httpRpcPort": 9568, + "httpsRpcPort": 9573, + "wsRpcPort": 9567, + "wssRpcPort": 9572, + "blsPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", + "blsPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", + "blsPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", + "blsPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693", + "publicKey": "0xf925c203a30ec6cad5a263db3efab7ed4c1fd74c8688167e10a5a22e15ab5018d8553df0ac54ea105a3d21845e5660bc3d4e7c82e7af1daa3baad393b1521467", + "owner": "0x5112ce768917e907191557d7e9521c2590cdd3a0", + "schainIndex": 1, + "ip": "186.14.217.13", + "publicIP": "4.127.224.50" + } + ] + } + }, + "accounts": { + "0000000000000000000000000000000000000001": { "precompiled": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, + "0000000000000000000000000000000000000002": { "precompiled": { "name": "sha256", "linear": { "base": 60, "word": 12 } } }, + "0000000000000000000000000000000000000003": { "precompiled": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } }, + "0000000000000000000000000000000000000004": { "precompiled": { "name": "identity", "linear": { "base": 15, "word": 3 } } }, + "0000000000000000000000000000000000000005": { "precompiled": { "name": "getBlockRandom", "linear": { "base": 15, "word": 0 } } },)" +#ifdef BITE + R"( + "000000000000000000000000000000000000001A": { "precompiled": { "name": "getRandomWalletAndSignatureForCTX", "linear": { "base": 15, "word": 0 } } }, + "000000000000000000000000000000000000001B": { "precompiled": { "name": "submitCTX", "linear": { "base": 15, "word": 0 } } },)" +#endif + /* +pragma solidity ^0.4.25; +contract Caller { +function call() public { +bool status; +string memory fileName = "test"; +address sender = 0x000000000000000000000000000000AA; +assembly{ +let ptr := mload(0x40) +mstore(ptr, sender) +mstore(add(ptr, 0x20), 4) +mstore(add(ptr, 0x40), mload(add(fileName, 0x20))) +mstore(add(ptr, 0x60), 1) +status := call(not(0), 0x05, 0, ptr, 0x80, ptr, 32) +} +} + +function revertCall() public { +call(); +revert(); +} +} +*/ + R"("0x5c4e11842e8be09264dc1976943571d7af6d00f9" : { + "balance" : "1000000000000000000000000000000" + }, + "0x7aa5E36AA15E93D10F4F26357C30F052DacDde5F": { + "balance": "1000000000000000000000000000000" + }, + "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a" : { + "balance" : "0x00", + "code" : "0x6080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806328b5e32b14604e578063f38fb65b146062575b600080fd5b348015605957600080fd5b5060606076565b005b348015606d57600080fd5b50607460ec565b005b6000606060006040805190810160405280600481526020017f7465737400000000000000000000000000000000000000000000000000000000815250915060aa905060405181815260046020820152602083015160408201526001606082015260208160808360006005600019f1935050505050565b60f26076565b600080fd00a165627a7a72305820262a5822c4fe6c154b2ef3198c7827d35fc6da59da2cea2c4f2fad9d4a5ccd5e0029", + "nonce" : "0x00", + "storage" : { + } + }, + "0x095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x6001600101600055", + "nonce" : "0x00", + "storage" : { + } + }, + "0xC2002000000000000000000000000000000000C2": { + "balance": "0", + "code": "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80639b063104146037578063cd16ecbf146062575b600080fd5b606060048036036020811015604b57600080fd5b8101908080359060200190929190505050608d565b005b608b60048036036020811015607657600080fd5b81019080803590602001909291905050506097565b005b8060018190555050565b806000819055505056fea265627a7a7231582029df540a7555533ef4b3f66bc4f9abe138b00117d1496efbfd9d035a48cd595e64736f6c634300050d0032", + "storage": { + "0x0": "0x01" + }, + "nonce": "0" + }, + "0xD2002000000000000000000000000000000000D2": { + "balance": "0", + "code": "0x608060405234801561001057600080fd5b50600436106100455760003560e01c806313f44d101461005557806338eada1c146100af5780634ba79dfe146100f357610046565b5b6002801461005357600080fd5b005b6100976004803603602081101561006b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610137565b60405180821515815260200191505060405180910390f35b6100f1600480360360208110156100c557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101f4565b005b6101356004803603602081101561010957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061030f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16148061019957506101988261042b565b5b806101ed5750600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b9050919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f43616c6c6572206973206e6f7420746865206f776e657200000000000000000081525060200191505060405180910390fd5b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f43616c6c6572206973206e6f7420746865206f776e657200000000000000000081525060200191505060405180910390fd5b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600080823b90506000811191505091905056fea26469706673582212202aca1f7abb7d02061b58de9b559eabe1607c880fda3932bbdb2b74fa553e537c64736f6c634300060c0033", + "storage": { + "0x0": "0x5C4e11842E8be09264dc1976943571d7Af6d00F9" + }, + "nonce": "0" + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0xD2001300000000000000000000000000000000D4": { + "balance": "0", + "nonce": "0", + "storage": {}, + "code":"0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80632098776714610051578063b8bd717f1461007f578063d37165fa146100ad578063fdde8d66146100db575b600080fd5b61007d6004803603602081101561006757600080fd5b8101908080359060200190929190505050610109565b005b6100ab6004803603602081101561009557600080fd5b8101908080359060200190929190505050610136565b005b6100d9600480360360208110156100c357600080fd5b8101908080359060200190929190505050610170565b005b610107600480360360208110156100f157600080fd5b8101908080359060200190929190505050610191565b005b60005a90505b815a8203101561011e5761010f565b600080fd5b815a8203101561013257610123565b5050565b60005a90505b815a8203101561014b5761013c565b600060011461015957600080fd5b5a90505b815a8203101561016c5761015d565b5050565b60005a9050600081830390505b805a8303101561018c5761017d565b505050565b60005a90505b815a820310156101a657610197565b60016101b157600080fd5b5a90505b815a820310156101c4576101b5565b505056fea264697066735822122089b72532621e7d1849e444ee6efaad4fb8771258e6f79755083dce434e5ac94c64736f6c63430006000033" + } + } +} +)"; +#else +static std::string const c_BITEConfigString = + R"( +{ + "sealEngine": "NoProof", + "params": { + "accountStartNonce": "0x00", + "maximumExtraDataSize": "0x1000000", + "blockReward": "0x4563918244F40000", + "allowFutureBlocks": true, + "homesteadForkBlock": "0x00", + "EIP150ForkBlock": "0x00", + "EIP158ForkBlock": "0x00", + "byzantiumForkBlock": "0x00", + "constantinopleForkBlock": "0x00", + "istanbulForkBlock": "0x00", + "skaleDisableChainIdCheck": true, + "minGasLimit": "0xFFFFFFF", + "maxGasLimit": "7fffffffffffffff" + }, + "genesis": { + "author" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "difficulty" : "0x20000", + "gasLimit": "0xFFFFFFF", + "nonce" : "0x00", + "extraData" : "0x00", + "timestamp" : "0x00", + "mixHash" : "0x00", + "stateRoot": "0x01" + }, + "skaleConfig": { + "nodeInfo": { + "nodeID": 8, + "nodeName": "test_node", + "bindIP": "0.0.0.0", + "logLevel": "info", + "logLevelConfig": "info", + "rotateAfterBlock": 10240, + "basePort": )" + + std::to_string( rand_port ) + R"(, + "logLevel": "trace", + "logLevelProposal": "trace", + "ecdsaKeyName": "NEK:d391a1af1cd9663335e0f970e59402bf16fcfe0cc421c535bf60ba618a456d68" + }, + "sChain": { + "schainName": "TestChain", + "schainID": 1, + "emptyBlockIntervalMs": -1, + "ContractCreationReadOnlyPatchTimestamp": 1, + "SingleStateCommitPerBlockPatchTimestamp": 1,)" +#ifdef BITE + R"( "Bite2PatchTimestamp": 1, + "currentBlockRandomPatchTimestamp": 1,)" +#endif + R"( "nodeGroups": { + "0": { + "nodes": { + "8": [ + 1, + 8, + "0xf925c203a30ec6cad5a263db3efab7ed4c1fd74c8688167e10a5a22e15ab5018d8553df0ac54ea105a3d21845e5660bc3d4e7c82e7af1daa3baad393b1521467" + ] + }, + "finish_ts": null, + "bls_public_key": { + "blsPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", + "blsPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", + "blsPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", + "blsPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693" + } + } + }, + "nodes": { + "1": { + "blsKey": { + "keyShareName": "BLS_KEY:SCHAIN_ID:1:NODE_ID:0:DKG_ID:0", + "t": 1, + "n": 1, + "certFile": "/skale-data/node_data/sgx_certs/sgx.crt", + "keyFile": "/skale-data/node_data/sgx_certs/sgx.key", + "commonBLSPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", + "commonBLSPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", + "commonBLSPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", + "commonBLSPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693", + "BLSPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", + "BLSPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", + "BLSPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", + "BLSPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693" + }, + "group": [ + { + "nodeID": 8, + "nodeName": "test_node", + "basePort": )" + + std::to_string( rand_port ) + + R"(, + "httpRpcPort": 9568, + "httpsRpcPort": 9573, + "wsRpcPort": 9567, + "wssRpcPort": 9572, + "blsPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", + "blsPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", + "blsPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", + "blsPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693", + "publicKey": "0xf925c203a30ec6cad5a263db3efab7ed4c1fd74c8688167e10a5a22e15ab5018d8553df0ac54ea105a3d21845e5660bc3d4e7c82e7af1daa3baad393b1521467", + "owner": "0x5112ce768917e907191557d7e9521c2590cdd3a0", + "schainIndex": 1, + "ip": "186.14.217.13", + "publicIP": "4.127.224.50" + } + ] + }, + "-1": {} + } + } + }, + "accounts": { + "0000000000000000000000000000000000000001": { "precompiled": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, + "0000000000000000000000000000000000000002": { "precompiled": { "name": "sha256", "linear": { "base": 60, "word": 12 } } }, + "0000000000000000000000000000000000000003": { "precompiled": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } }, + "0000000000000000000000000000000000000004": { "precompiled": { "name": "identity", "linear": { "base": 15, "word": 3 } } }, + "0000000000000000000000000000000000000005": { "precompiled": { "name": "getBlockRandom", "linear": { "base": 15, "word": 0 } } },)" +#ifdef BITE + R"( + "0x000000000000000000000000000000000000001A": { "precompiled": { "name": "getRandomWalletAndSignatureForCTX", "linear": { "base": 15, "word": 0 } } }, + "0x000000000000000000000000000000000000001B": { "precompiled": { "name": "submitCTX", "linear": { "base": 15, "word": 0 } } },)" +#endif + /* +pragma solidity ^0.4.25; +contract Caller { +function call() public { +bool status; +string memory fileName = "test"; +address sender = 0x000000000000000000000000000000AA; +assembly{ +let ptr := mload(0x40) +mstore(ptr, sender) +mstore(add(ptr, 0x20), 4) +mstore(add(ptr, 0x40), mload(add(fileName, 0x20))) +mstore(add(ptr, 0x60), 1) +status := call(not(0), 0x05, 0, ptr, 0x80, ptr, 32) +} +} + +function revertCall() public { +call(); +revert(); +} +} +*/ + R"("0x5c4e11842e8be09264dc1976943571d7af6d00f9" : { + "balance" : "1000000000000000000000000000000" + }, + "0x7aa5E36AA15E93D10F4F26357C30F052DacDde5F": { + "balance": "1000000000000000000000000000000" + }, + "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a" : { + "balance" : "0x00", + "code" : "0x6080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806328b5e32b14604e578063f38fb65b146062575b600080fd5b348015605957600080fd5b5060606076565b005b348015606d57600080fd5b50607460ec565b005b6000606060006040805190810160405280600481526020017f7465737400000000000000000000000000000000000000000000000000000000815250915060aa905060405181815260046020820152602083015160408201526001606082015260208160808360006005600019f1935050505050565b60f26076565b600080fd00a165627a7a72305820262a5822c4fe6c154b2ef3198c7827d35fc6da59da2cea2c4f2fad9d4a5ccd5e0029", + "nonce" : "0x00", + "storage" : { + } + }, + "0x095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x6001600101600055", + "nonce" : "0x00", + "storage" : { + } + }, + "0xC2002000000000000000000000000000000000C2": { + "balance": "0", + "code": "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80639b063104146037578063cd16ecbf146062575b600080fd5b606060048036036020811015604b57600080fd5b8101908080359060200190929190505050608d565b005b608b60048036036020811015607657600080fd5b81019080803590602001909291905050506097565b005b8060018190555050565b806000819055505056fea265627a7a7231582029df540a7555533ef4b3f66bc4f9abe138b00117d1496efbfd9d035a48cd595e64736f6c634300050d0032", + "storage": { + "0x0": "0x01" + }, + "nonce": "0" + }, + "0xD2002000000000000000000000000000000000D2": { + "balance": "0", + "code": "0x608060405234801561001057600080fd5b50600436106100455760003560e01c806313f44d101461005557806338eada1c146100af5780634ba79dfe146100f357610046565b5b6002801461005357600080fd5b005b6100976004803603602081101561006b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610137565b60405180821515815260200191505060405180910390f35b6100f1600480360360208110156100c557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101f4565b005b6101356004803603602081101561010957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061030f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16148061019957506101988261042b565b5b806101ed5750600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b9050919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f43616c6c6572206973206e6f7420746865206f776e657200000000000000000081525060200191505060405180910390fd5b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f43616c6c6572206973206e6f7420746865206f776e657200000000000000000081525060200191505060405180910390fd5b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600080823b90506000811191505091905056fea26469706673582212202aca1f7abb7d02061b58de9b559eabe1607c880fda3932bbdb2b74fa553e537c64736f6c634300060c0033", + "storage": { + }, + "nonce": "0" + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0xD2001300000000000000000000000000000000D4": { + "balance": "0", + "nonce": "0", + "storage": {}, + "code":"0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80632098776714610051578063b8bd717f1461007f578063d37165fa146100ad578063fdde8d66146100db575b600080fd5b61007d6004803603602081101561006757600080fd5b8101908080359060200190929190505050610109565b005b6100ab6004803603602081101561009557600080fd5b8101908080359060200190929190505050610136565b005b6100d9600480360360208110156100c357600080fd5b8101908080359060200190929190505050610170565b005b610107600480360360208110156100f157600080fd5b8101908080359060200190929190505050610191565b005b60005a90505b815a8203101561011e5761010f565b600080fd5b815a8203101561013257610123565b5050565b60005a90505b815a8203101561014b5761013c565b600060011461015957600080fd5b5a90505b815a8203101561016c5761015d565b5050565b60005a9050600081830390505b805a8303101561018c5761017d565b505050565b60005a90505b815a820310156101a657610197565b60016101b157600080fd5b5a90505b815a820310156101c4576101b5565b505056fea264697066735822122089b72532621e7d1849e444ee6efaad4fb8771258e6f79755083dce434e5ac94c64736f6c63430006000033" + } + } +} +)"; + +static std::string const c_BITECommitteeRotationConfigString = + R"( +{ + "sealEngine": "NoProof", + "params": { + "accountStartNonce": "0x00", + "maximumExtraDataSize": "0x1000000", + "blockReward": "0x4563918244F40000", + "allowFutureBlocks": true, + "homesteadForkBlock": "0x00", + "EIP150ForkBlock": "0x00", + "EIP158ForkBlock": "0x00", + "byzantiumForkBlock": "0x00", + "constantinopleForkBlock": "0x00", + "istanbulForkBlock": "0x00", + "skaleDisableChainIdCheck": true, + "externalGasDifficulty": "0x1" + }, + "genesis": { + "author" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "difficulty" : "0x20000", + "gasLimit" : "0x0f4240", + "nonce" : "0x00", + "extraData" : "0x00", + "timestamp" : "0x00", + "mixHash" : "0x00", + "stateRoot": "0x01" + }, + "skaleConfig": { + "nodeInfo": { + "nodeID": 8, + "nodeName": "test_node", + "bindIP": "0.0.0.0", + "logLevel": "info", + "logLevelConfig": "info", + "imaMessageProxySChain": "0xd2AAa00100000000000000000000000000000000", + "imaMessageProxyMainNet": "0x337591F78cbf2b113A57D9709511a1b6E524DdaE", + "rotateAfterBlock": 10240, + "basePort": )" + + std::to_string( rand_port ) + R"(, + "logLevel": "trace", + "logLevelProposal": "trace", + "ecdsaKeyName": "NEK:d391a1af1cd9663335e0f970e59402bf16fcfe0cc421c535bf60ba618a456d68" + }, + "sChain": { + "schainName": "TestChain", + "schainID": 1, + "emptyBlockIntervalMs": -1, + "nodeGroups": { + "0": { + "nodes": { + "8": [ + 0, + 8, + "0xf925c203a30ec6cad5a263db3efab7ed4c1fd74c8688167e10a5a22e15ab5018d8553df0ac54ea105a3d21845e5660bc3d4e7c82e7af1daa3baad393b1521467", + "0x08151B8F80bfa7dEa760e461412AF24348224edf" + ] + }, + "finish_ts": 1, + "bls_public_key": { + "blsPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", + "blsPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", + "blsPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", + "blsPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693" + } + }, + "1": { + "nodes": { + "8": [ + 0, + 8, + "0xf925c203a30ec6cad5a263db3efab7ed4c1fd74c8688167e10a5a22e15ab5018d8553df0ac54ea105a3d21845e5660bc3d4e7c82e7af1daa3baad393b1521467", + "0x405c96D388cDFBa4f17493c875CCE9c680225276" + ] + }, + "finish_ts": null, + "bls_public_key": { + "blsPublicKey0": "3842742177969966091367527274107524613106077736353521259727282251005583743182", + "blsPublicKey1": "3497912824016228906558906422247670474553186446469877598411863912329082553081", + "blsPublicKey2": "8173996886448941320370434854289578123609627835954133538412363037981850950343", + "blsPublicKey3": "20979370720689475348670582375026949105497642726992863932315517524004804784155" + } + } + }, + "nodes": { + "1": { + "blsKey": { + "keyShareName": "BLS_KEY:SCHAIN_ID:1:NODE_ID:0:DKG_ID:0", + "t": 1, + "n": 1, + "certFile": "/skale-data/node_data/sgx_certs/sgx.crt", + "keyFile": "/skale-data/node_data/sgx_certs/sgx.key", + "commonBLSPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", + "commonBLSPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", + "commonBLSPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", + "commonBLSPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693", + "BLSPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", + "BLSPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", + "BLSPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", + "BLSPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693" + }, + "stakingContractAddress": "0x5C60C315985977b7a408eBF4256984Acdf949549", + "group": [ + { + "nodeID": 8, + "nodeName": "test_node", + "basePort": )" + + std::to_string( rand_port ) + R"(, + "httpRpcPort": 9568, + "httpsRpcPort": 9573, + "wsRpcPort": 9567, + "wssRpcPort": 9572, + "blsPublicKey0": "15959969554621958245201075983340071881770733084910870228938077786643587385029", + "blsPublicKey1": "7970122607051572307517094692346020360016825923464107614135327251488152616550", + "blsPublicKey2": "3371162264373897025322009434717052197952692496405149486989861571246537813591", + "blsPublicKey3": "13678625751515504401110635369790787716744686498431213713911601759809559919693", + "publicKey": "0xf925c203a30ec6cad5a263db3efab7ed4c1fd74c8688167e10a5a22e15ab5018d8553df0ac54ea105a3d21845e5660bc3d4e7c82e7af1daa3baad393b1521467", + "owner": "0x5112ce768917e907191557d7e9521c2590cdd3a0", + "schainIndex": 1, + "ip": "186.14.217.13", + "publicIP": "4.127.224.50" + } + ] + }, + "-1": { + "blsKey": { + "keyShareName": "BLS_KEY:SCHAIN_ID:1:NODE_ID:0:DKG_ID:0", + "t": 1, + "n": 1, + "certFile": "/skale-data/node_data/sgx_certs/sgx.crt", + "keyFile": "/skale-data/node_data/sgx_certs/sgx.key", + "commonBLSPublicKey0": "3842742177969966091367527274107524613106077736353521259727282251005583743182", + "commonBLSPublicKey1": "3497912824016228906558906422247670474553186446469877598411863912329082553081", + "commonBLSPublicKey2": "8173996886448941320370434854289578123609627835954133538412363037981850950343", + "commonBLSPublicKey3": "20979370720689475348670582375026949105497642726992863932315517524004804784155", + "BLSPublicKey0": "3842742177969966091367527274107524613106077736353521259727282251005583743182", + "BLSPublicKey1": "3497912824016228906558906422247670474553186446469877598411863912329082553081", + "BLSPublicKey2": "8173996886448941320370434854289578123609627835954133538412363037981850950343", + "BLSPublicKey3": "20979370720689475348670582375026949105497642726992863932315517524004804784155" + }, + "group": [ + { + "nodeID": 8, + "nodeName": "test_node", + "basePort": )" + + std::to_string( rand_port ) + + R"(, + "httpRpcPort": 9568, + "httpsRpcPort": 9573, + "wsRpcPort": 9567, + "wssRpcPort": 9572, + "blsPublicKey0": "3842742177969966091367527274107524613106077736353521259727282251005583743182", + "blsPublicKey1": "3497912824016228906558906422247670474553186446469877598411863912329082553081", + "blsPublicKey2": "8173996886448941320370434854289578123609627835954133538412363037981850950343", + "blsPublicKey3": "20979370720689475348670582375026949105497642726992863932315517524004804784155", + "publicKey": "0xf925c203a30ec6cad5a263db3efab7ed4c1fd74c8688167e10a5a22e15ab5018d8553df0ac54ea105a3d21845e5660bc3d4e7c82e7af1daa3baad393b1521467", + "owner": "0x5112ce768917e907191557d7e9521c2590cdd3a0", + "schainIndex": 1, + "ip": "186.14.217.13", + "publicIP": "4.127.224.50" + } + ] + } + } + } + }, + "accounts": { + "0000000000000000000000000000000000000001": { "precompiled": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } }, + "0000000000000000000000000000000000000002": { "precompiled": { "name": "sha256", "linear": { "base": 60, "word": 12 } } }, + "0000000000000000000000000000000000000003": { "precompiled": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } }, + "0000000000000000000000000000000000000004": { "precompiled": { "name": "identity", "linear": { "base": 15, "word": 3 } } },)" + /* +pragma solidity ^0.4.25; +contract Caller { +function call() public { +bool status; +string memory fileName = "test"; +address sender = 0x000000000000000000000000000000AA; +assembly{ +let ptr := mload(0x40) +mstore(ptr, sender) +mstore(add(ptr, 0x20), 4) +mstore(add(ptr, 0x40), mload(add(fileName, 0x20))) +mstore(add(ptr, 0x60), 1) +status := call(not(0), 0x05, 0, ptr, 0x80, ptr, 32) +} +} + +function revertCall() public { +call(); +revert(); +} +} +*/ + R"("0x5c4e11842e8be09264dc1976943571d7af6d00f9" : { + "balance" : "1000000000000000000000000000000" + }, + "0x7aa5E36AA15E93D10F4F26357C30F052DacDde5F": { + "balance": "1000000000000000000000000000000" + }, + "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a" : { + "balance" : "0x00", + "code" : "0x6080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806328b5e32b14604e578063f38fb65b146062575b600080fd5b348015605957600080fd5b5060606076565b005b348015606d57600080fd5b50607460ec565b005b6000606060006040805190810160405280600481526020017f7465737400000000000000000000000000000000000000000000000000000000815250915060aa905060405181815260046020820152602083015160408201526001606082015260208160808360006005600019f1935050505050565b60f26076565b600080fd00a165627a7a72305820262a5822c4fe6c154b2ef3198c7827d35fc6da59da2cea2c4f2fad9d4a5ccd5e0029", + "nonce" : "0x00", + "storage" : { + } + }, + "0x095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x6001600101600055", + "nonce" : "0x00", + "storage" : { + } + }, + "0xC2002000000000000000000000000000000000C2": { + "balance": "0", + "code": "0x6080604052348015600f57600080fd5b506004361060325760003560e01c80639b063104146037578063cd16ecbf146062575b600080fd5b606060048036036020811015604b57600080fd5b8101908080359060200190929190505050608d565b005b608b60048036036020811015607657600080fd5b81019080803590602001909291905050506097565b005b8060018190555050565b806000819055505056fea265627a7a7231582029df540a7555533ef4b3f66bc4f9abe138b00117d1496efbfd9d035a48cd595e64736f6c634300050d0032", + "storage": { + "0x0": "0x01" + }, + "nonce": "0" + }, + "0xD2002000000000000000000000000000000000D2": { + "balance": "0", + "code": "0x608060405234801561001057600080fd5b50600436106100455760003560e01c806313f44d101461005557806338eada1c146100af5780634ba79dfe146100f357610046565b5b6002801461005357600080fd5b005b6100976004803603602081101561006b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610137565b60405180821515815260200191505060405180910390f35b6100f1600480360360208110156100c557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101f4565b005b6101356004803603602081101561010957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061030f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16148061019957506101988261042b565b5b806101ed5750600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b9050919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f43616c6c6572206973206e6f7420746865206f776e657200000000000000000081525060200191505060405180910390fd5b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f43616c6c6572206973206e6f7420746865206f776e657200000000000000000081525060200191505060405180910390fd5b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600080823b90506000811191505091905056fea26469706673582212202aca1f7abb7d02061b58de9b559eabe1607c880fda3932bbdb2b74fa553e537c64736f6c634300060c0033", + "storage": { + }, + "nonce": "0" + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a7640000", + "code" : "0x", + "nonce" : "0x00", + "storage" : { + } + }, + "0xD2001300000000000000000000000000000000D4": { + "balance": "0", + "nonce": "0", + "storage": {}, + "code":"0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80632098776714610051578063b8bd717f1461007f578063d37165fa146100ad578063fdde8d66146100db575b600080fd5b61007d6004803603602081101561006757600080fd5b8101908080359060200190929190505050610109565b005b6100ab6004803603602081101561009557600080fd5b8101908080359060200190929190505050610136565b005b6100d9600480360360208110156100c357600080fd5b8101908080359060200190929190505050610170565b005b610107600480360360208110156100f157600080fd5b8101908080359060200190929190505050610191565b005b60005a90505b815a8203101561011e5761010f565b600080fd5b815a8203101561013257610123565b5050565b60005a90505b815a8203101561014b5761013c565b600060011461015957600080fd5b5a90505b815a8203101561016c5761015d565b5050565b60005a9050600081830390505b805a8303101561018c5761017d565b505050565b60005a90505b815a820310156101a657610197565b60016101b157600080fd5b5a90505b815a820310156101c4576101b5565b505056fea264697066735822122089b72532621e7d1849e444ee6efaad4fb8771258e6f79755083dce434e5ac94c64736f6c63430006000033" + } + } +} +)"; +#endif // #ifndef FAIR + + +BOOST_AUTO_TEST_CASE( getCommonPublicKey ) { + JsonRpcFixture fixture( c_BITEConfigString, false, false, true ); + + Json::Value biteInfo = fixture.rpcClient->bite_getCommitteesInfo(); + + BOOST_REQUIRE( biteInfo.isArray() ); + std::string blsPublicKey = biteInfo[0]["commonBLSPublicKey"].asString(); + uint64_t epochId = biteInfo[0]["epochId"].asUInt64(); + + auto commonPublicKeyFromConfig = fixture.client->chainParams().getCommonBlsPublicKey(); + libBLS::algebra::G2Point commonPublicKey = + libBLS::algebra::G2Point::fromString( commonPublicKeyFromConfig, libBLS::Base::DEC ); + + BOOST_REQUIRE_EQUAL( blsPublicKey.size(), 256 ); + BOOST_REQUIRE_EQUAL( libBLS::TEPublicKey( blsPublicKey, libBLS::Base::HEXA ).getPublicKeyRaw(), + commonPublicKey ); + BOOST_REQUIRE_EQUAL( epochId, fixture.client->getCurrentEpochId() ); +} + +#ifdef BITE + +// Helper function to build abi.encode(bytes[] args1, bytes[] args2) +dev::bytes buildAbiEncodedArrays( const std::vector< dev::bytes >& args1Elements, + const std::vector< dev::bytes >& args2Elements ) { + // Validate that all args1 elements meet minimum length requirement + for ( size_t i = 0; i < args1Elements.size(); ++i ) { + if ( args1Elements[i].size() < BITE_CIPHERTEXT_MIN_LEN ) { + throw std::runtime_error( + "buildAbiEncodedArrays: args1 element " + std::to_string( i ) + " is too short (" + + std::to_string( args1Elements[i].size() ) + " bytes), must be at least " + + std::to_string( BITE_CIPHERTEXT_MIN_LEN ) + " bytes" ); + } + } + + dev::bytes result; + + // Calculate total size for args1 array data + size_t args1DataSize = 32; // length field + args1DataSize += 32 * args1Elements.size(); // offsets for each element + for ( const auto& elem : args1Elements ) { + args1DataSize += 32; // length field for element + args1DataSize += ( elem.size() + 31 ) / 32 * 32; // padded element data + } + + // Write offsets to both arrays + dev::bytes args1Offset = dev::toBigEndian( dev::u256( 64 ) ); + dev::bytes args2Offset = dev::toBigEndian( dev::u256( 64 + args1DataSize ) ); + result.insert( result.end(), args1Offset.begin(), args1Offset.end() ); + result.insert( result.end(), args2Offset.begin(), args2Offset.end() ); + + // Encode args1 array + dev::bytes args1Length = dev::toBigEndian( dev::u256( args1Elements.size() ) ); + result.insert( result.end(), args1Length.begin(), args1Length.end() ); + + // Calculate and write element offsets for args1 + size_t currentOffset = 32 * args1Elements.size(); // After all offset fields + for ( const auto& elem : args1Elements ) { + dev::bytes elemOffset = dev::toBigEndian( dev::u256( currentOffset ) ); + result.insert( result.end(), elemOffset.begin(), elemOffset.end() ); + currentOffset += 32 + ( elem.size() + 31 ) / 32 * 32; // length + padded data + } + + // Write args1 element data + for ( const auto& elem : args1Elements ) { + dev::bytes elemLength = dev::toBigEndian( dev::u256( elem.size() ) ); + result.insert( result.end(), elemLength.begin(), elemLength.end() ); + result.insert( result.end(), elem.begin(), elem.end() ); + while ( result.size() % 32 != 0 ) + result.push_back( 0 ); + } + + // Encode args2 array (same structure as args1) + dev::bytes args2Length = dev::toBigEndian( dev::u256( args2Elements.size() ) ); + result.insert( result.end(), args2Length.begin(), args2Length.end() ); + + // Calculate and write element offsets for args2 + currentOffset = 32 * args2Elements.size(); + for ( const auto& elem : args2Elements ) { + dev::bytes elemOffset = dev::toBigEndian( dev::u256( currentOffset ) ); + result.insert( result.end(), elemOffset.begin(), elemOffset.end() ); + currentOffset += 32 + ( elem.size() + 31 ) / 32 * 32; + } + + // Write args2 element data + for ( const auto& elem : args2Elements ) { + dev::bytes elemLength = dev::toBigEndian( dev::u256( elem.size() ) ); + result.insert( result.end(), elemLength.begin(), elemLength.end() ); + result.insert( result.end(), elem.begin(), elem.end() ); + while ( result.size() % 32 != 0 ) + result.push_back( 0 ); + } + + return result; +} + +BOOST_AUTO_TEST_CASE( rejectExplicitCTXSubmission ) { + JsonRpcFixture fixture( c_BITEConfigString, true, true, true, true, false, -1, { { "contractStorageLimit", "100000" } } ); + string senderAddress = toJS( fixture.coinbase.address() ); + size_t nonce = 0; + std::string onDecryptSelector = dev::toHexPrefixed( dev::bite::ON_DECRYPT_FUNCTION_SELECTOR ); + Transaction t( dev::jsToBytes( formTransactionRlp( fixture, senderAddress, onDecryptSelector, nonce, dev::Address::random().hex() ) ), CheckTransaction::Everything, + false, false, false, true, true + ); + BOOST_REQUIRE_THROW( fixture.client->importTransaction( t ), IllegalCTXSubmission ); + BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendRawTransaction( dev::toHexPrefixed( t.toBytes() ) ), jsonrpc::JsonRpcException ); +} + +BOOST_AUTO_TEST_CASE( submitCTX ) { + JsonRpcFixture fixture( c_BITEConfigString, true, true, true, true, false, -1, + { { "contractStorageLimit", "100000" } } ); + + string senderAddress = toJS( fixture.coinbase.address() ); + + std::vector< dev::bytes > pregeneratedDecryptedValues{ dev::fromHex( "5b221ee6b5c5751ff5808beddbc0644dc4fdda6b5efb13dbb49d698cb0e3f172" ), + dev::fromHex( "006aa7d63edcfb03635a2ecf5064a9eec076c2466fb2a6c35d59b5f1039f2535" ) }; + std::vector< dev::bytes > pregeneratedPlaintextValues{ dev::asBytes( "plaintext1" ), dev::asBytes( "plaintext2" ) }; +// pragma solidity ^0.8.13; + +// contract Precompile0x1BCaller { +// bytes[] decrypted = new bytes[](1); +// bytes[] plaintext = new bytes[](1); +// constructor() payable {} + +// function submitCTX() public { +// uint256 randomNumber = uint256(keccak256(abi.encodePacked(block.timestamp, block.number))) % 2500000 + 1000000; +// bytes[] memory args1 = new bytes[](2); +// // Use pre-generated args1 values instead of generating them dynamically +// args1[0] = hex"f9015880b9015401cc5504bac92b5ccafa0c3202372d7bb0b8cb6861795deddafae0ed7be924ff170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006360e4a05b2e03056b2d61c7ad2deb47b0be0084ffab44bf506bfff07b951fb0bf37c171584f74d80c96306e124152458183a7a2c570a136099f7c4ffc9dde340cbed4f87133200fc4e425946925eaac958209aba78e190feeb5c9f31182ec8d458260279adb3976c158471b932bbee5bb320c"; +// args1[1] = hex"f9015880b9015401154918854780593f1c6bf620684b29ab3d4c4a4f5996dcbd1c1d0b48c06d56b40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000751884c80374b7b5d6d0ef740dacbea91b3d53ee5243eeacf94a970f131185c69dfd44e868e370602c72484bc2f34e9466255ef50ca817d34d61a46bff368318b6fff300eb566dac8d1c569a270c6d9c1f99664643582cafcb276fea83d5564cd38f4b1be0e8ee6c06e10f10f10dc39120884"; + +// bytes[] memory args2 = new bytes[](2); +// args2[0] = abi.encodePacked("plaintext1"); +// args2[1] = abi.encodePacked("plaintext2"); + +// bytes memory randomBytes = abi.encode(args1, args2); +// bytes memory input = abi.encode(randomNumber, randomBytes); + +// (bool success, bytes memory result) = address(0x1B).staticcall(input); +// require(success, "0x1B call failed"); + +// // Extract address from first 20 bytes of result and transfer +// address walletAddress = address(bytes20(result)); +// payable(walletAddress).transfer(400000000000); +// } + +// function submitCTXWithInput(bytes calldata input) public { +// (bool success, bytes memory result) = address(0x1B).staticcall(input); +// require(success, "0x1B call failed"); + +// // Extract address from first 20 bytes of result and transfer +// address walletAddress = address(bytes20(result)); +// payable(walletAddress).transfer(400000000000 ); +// } + +// function onDecrypt(bytes[] calldata decryptedArguments, bytes[] calldata plaintextArguments) public { +// delete decrypted; +// decrypted = new bytes[](decryptedArguments.length); +// for (uint i = 0; i < decryptedArguments.length; ++i) { +// decrypted[i] = decryptedArguments[i]; +// } +// delete plaintext; +// plaintext = new bytes[](plaintextArguments.length); +// for (uint i = 0; i < plaintextArguments.length; ++i) { +// plaintext[i] = plaintextArguments[i]; +// } +// return; +// } + +// function getDecrypted() public view returns (bytes[] memory) { +// return decrypted; +// } + +// function getPlaintext() public view returns (bytes[] memory) { +// return plaintext; +// } +// } + std::string bytecode = "6080604052600167ffffffffffffffff81111561001f5761001e6101ad565b5b60405190808252806020026020018201604052801561005257816020015b606081526020019060019003908161003d5790505b50600090805190602001906100689291906100d3565b50600167ffffffffffffffff811115610084576100836101ad565b5b6040519080825280602002602001820160405280156100b757816020015b60608152602001906001900390816100a25790505b50600190805190602001906100cd9291906100d3565b506104cf565b82805482825590600052602060002090810192821561011b579160200282015b8281111561011a57825182908161010a91906103fd565b50916020019190600101906100f3565b5b509050610128919061012c565b5090565b5b8082111561014c57600081816101439190610150565b5060010161012d565b5090565b50805461015c90610216565b6000825580601f1061016e575061018d565b601f01602090049060005260206000209081019061018c9190610190565b5b50565b5b808211156101a9576000816000905550600101610191565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061022e57607f821691505b602082108103610241576102406101e7565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026102a97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261026c565b6102b3868361026c565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006102fa6102f56102f0846102cb565b6102d5565b6102cb565b9050919050565b6000819050919050565b610314836102df565b61032861032082610301565b848454610279565b825550505050565b600090565b61033d610330565b61034881848461030b565b505050565b5b8181101561036c57610361600082610335565b60018101905061034e565b5050565b601f8211156103b15761038281610247565b61038b8461025c565b8101602085101561039a578190505b6103ae6103a68561025c565b83018261034d565b50505b505050565b600082821c905092915050565b60006103d4600019846008026103b6565b1980831691505092915050565b60006103ed83836103c3565b9150826002028217905092915050565b610406826101dc565b67ffffffffffffffff81111561041f5761041e6101ad565b5b6104298254610216565b610434828285610370565b600060209050601f8311600181146104675760008415610455578287015190505b61045f85826103e1565b8655506104c7565b601f19841661047586610247565b60005b8281101561049d57848901518255600182019150602085019450602081019050610478565b868310156104ba57848901516104b6601f8916826103c3565b8355505b6001600288020188555050505b505050505050565b6118b5806104de6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c806338d5a3121461005c57806357983ac81461007a5780636040c1fb146100965780637372aa26146100b2578063cc159120146100bc575b600080fd5b6100646100da565b6040516100719190610af5565b60405180910390f35b610094600480360381019061008f9190610b86565b6101b3565b005b6100b060048036038101906100ab9190610c5d565b610378565b005b6100ba61048c565b005b6100c46107cf565b6040516100d19190610af5565b60405180910390f35b60606000805480602002602001604051908101604052809291908181526020016000905b828210156101aa57838290600052602060002001805461011d90610cd9565b80601f016020809104026020016040519081016040528092919081815260200182805461014990610cd9565b80156101965780601f1061016b57610100808354040283529160200191610196565b820191906000526020600020905b81548152906001019060200180831161017957829003601f168201915b5050505050815260200190600101906100fe565b50505050905090565b6000806101c091906108a8565b8383905067ffffffffffffffff8111156101dd576101dc610d0a565b5b60405190808252806020026020018201604052801561021057816020015b60608152602001906001900390816101fb5790505b50600090805190602001906102269291906108c9565b5060005b848490508110156102915784848281811061024857610247610d39565b5b905060200281019061025a9190610d77565b6000838154811061026e5761026d610d39565b5b906000526020600020019182610285929190610f9b565b5080600101905061022a565b50600160006102a091906108a8565b8181905067ffffffffffffffff8111156102bd576102bc610d0a565b5b6040519080825280602002602001820160405280156102f057816020015b60608152602001906001900390816102db5790505b50600190805190602001906103069291906108c9565b5060005b828290508110156103715782828281811061032857610327610d39565b5b905060200281019061033a9190610d77565b6001838154811061034e5761034d610d39565b5b906000526020600020019182610365929190610f9b565b5080600101905061030a565b5050505050565b600080601b73ffffffffffffffffffffffffffffffffffffffff1684846040516103a39291906110aa565b600060405180830381855afa9150503d80600081146103de576040519150601f19603f3d011682016040523d82523d6000602084013e6103e3565b606091505b509150915081610428576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041f90611120565b60405180910390fd5b60008161043490611191565b60601c90508073ffffffffffffffffffffffffffffffffffffffff166108fc645d21dba0009081150290604051600060405180830381858888f19350505050158015610484573d6000803e3d6000fd5b505050505050565b6000620f4240622625a042436040516020016104a9929190611219565b6040516020818303038152906040528051906020012060001c6104cc9190611274565b6104d691906112d4565b90506000600267ffffffffffffffff8111156104f5576104f4610d0a565b5b60405190808252806020026020018201604052801561052857816020015b60608152602001906001900390816105135790505b50905060405180610180016040528061015b81526020016115b061015b91398160008151811061055b5761055a610d39565b5b602002602001018190525060405180610180016040528061015b815260200161170b61015b91398160018151811061059657610595610d39565b5b60200260200101819052506000600267ffffffffffffffff8111156105be576105bd610d0a565b5b6040519080825280602002602001820160405280156105f157816020015b60608152602001906001900390816105dc5790505b5090506040516020016106039061135f565b6040516020818303038152906040528160008151811061062657610625610d39565b5b6020026020010181905250604051602001610640906113c0565b6040516020818303038152906040528160018151811061066357610662610d39565b5b6020026020010181905250600082826040516020016106839291906113d5565b6040516020818303038152906040529050600084826040516020016106a9929190611465565b6040516020818303038152906040529050600080601b73ffffffffffffffffffffffffffffffffffffffff16836040516106e391906114c6565b600060405180830381855afa9150503d806000811461071e576040519150601f19603f3d011682016040523d82523d6000602084013e610723565b606091505b509150915081610768576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075f90611120565b60405180910390fd5b60008161077490611191565b60601c90508073ffffffffffffffffffffffffffffffffffffffff166108fc645d21dba0009081150290604051600060405180830381858888f193505050501580156107c4573d6000803e3d6000fd5b505050505050505050565b60606001805480602002602001604051908101604052809291908181526020016000905b8282101561089f57838290600052602060002001805461081290610cd9565b80601f016020809104026020016040519081016040528092919081815260200182805461083e90610cd9565b801561088b5780601f106108605761010080835404028352916020019161088b565b820191906000526020600020905b81548152906001019060200180831161086e57829003601f168201915b5050505050815260200190600101906107f3565b50505050905090565b50805460008255906000526020600020908101906108c69190610922565b50565b828054828255906000526020600020908101928215610911579160200282015b8281111561091057825182908161090091906114dd565b50916020019190600101906108e9565b5b50905061091e9190610922565b5090565b5b8082111561094257600081816109399190610946565b50600101610923565b5090565b50805461095290610cd9565b6000825580601f106109645750610983565b601f0160209004906000526020600020908101906109829190610986565b5b50565b5b8082111561099f576000816000905550600101610987565b5090565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610a095780820151818401526020810190506109ee565b60008484015250505050565b6000601f19601f8301169050919050565b6000610a31826109cf565b610a3b81856109da565b9350610a4b8185602086016109eb565b610a5481610a15565b840191505092915050565b6000610a6b8383610a26565b905092915050565b6000602082019050919050565b6000610a8b826109a3565b610a9581856109ae565b935083602082028501610aa7856109bf565b8060005b85811015610ae35784840389528151610ac48582610a5f565b9450610acf83610a73565b925060208a01995050600181019050610aab565b50829750879550505050505092915050565b60006020820190508181036000830152610b0f8184610a80565b905092915050565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f840112610b4657610b45610b21565b5b8235905067ffffffffffffffff811115610b6357610b62610b26565b5b602083019150836020820283011115610b7f57610b7e610b2b565b5b9250929050565b60008060008060408587031215610ba057610b9f610b17565b5b600085013567ffffffffffffffff811115610bbe57610bbd610b1c565b5b610bca87828801610b30565b9450945050602085013567ffffffffffffffff811115610bed57610bec610b1c565b5b610bf987828801610b30565b925092505092959194509250565b60008083601f840112610c1d57610c1c610b21565b5b8235905067ffffffffffffffff811115610c3a57610c39610b26565b5b602083019150836001820283011115610c5657610c55610b2b565b5b9250929050565b60008060208385031215610c7457610c73610b17565b5b600083013567ffffffffffffffff811115610c9257610c91610b1c565b5b610c9e85828601610c07565b92509250509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680610cf157607f821691505b602082108103610d0457610d03610caa565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112610d9457610d93610d68565b5b80840192508235915067ffffffffffffffff821115610db657610db5610d6d565b5b602083019250600182023603831315610dd257610dd1610d72565b5b509250929050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302610e477fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610e0a565b610e518683610e0a565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000610e98610e93610e8e84610e69565b610e73565b610e69565b9050919050565b6000819050919050565b610eb283610e7d565b610ec6610ebe82610e9f565b848454610e17565b825550505050565b600090565b610edb610ece565b610ee6818484610ea9565b505050565b5b81811015610f0a57610eff600082610ed3565b600181019050610eec565b5050565b601f821115610f4f57610f2081610de5565b610f2984610dfa565b81016020851015610f38578190505b610f4c610f4485610dfa565b830182610eeb565b50505b505050565b600082821c905092915050565b6000610f7260001984600802610f54565b1980831691505092915050565b6000610f8b8383610f61565b9150826002028217905092915050565b610fa58383610dda565b67ffffffffffffffff811115610fbe57610fbd610d0a565b5b610fc88254610cd9565b610fd3828285610f0e565b6000601f8311600181146110025760008415610ff0578287013590505b610ffa8582610f7f565b865550611062565b601f19841661101086610de5565b60005b8281101561103857848901358255600182019150602085019450602081019050611013565b868310156110555784890135611051601f891682610f61565b8355505b6001600288020188555050505b50505050505050565b600081905092915050565b82818337600083830152505050565b6000611091838561106b565b935061109e838584611076565b82840190509392505050565b60006110b7828486611085565b91508190509392505050565b600082825260208201905092915050565b7f307831422063616c6c206661696c656400000000000000000000000000000000600082015250565b600061110a6010836110c3565b9150611115826110d4565b602082019050919050565b60006020820190508181036000830152611139816110fd565b9050919050565b6000819050602082019050919050565b60007fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b60006111888251611150565b80915050919050565b600061119c826109cf565b826111a684611140565b90506111b18161117c565b925060148210156111f1576111ec7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083601403600802610e0a565b831692505b5050919050565b6000819050919050565b61121361120e82610e69565b6111f8565b82525050565b60006112258285611202565b6020820191506112358284611202565b6020820191508190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061127f82610e69565b915061128a83610e69565b92508261129a57611299611245565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006112df82610e69565b91506112ea83610e69565b9250828201905080821115611302576113016112a5565b5b92915050565b600081905092915050565b7f706c61696e746578743100000000000000000000000000000000000000000000600082015250565b6000611349600a83611308565b915061135482611313565b600a82019050919050565b600061136a8261133c565b9150819050919050565b7f706c61696e746578743200000000000000000000000000000000000000000000600082015250565b60006113aa600a83611308565b91506113b582611374565b600a82019050919050565b60006113cb8261139d565b9150819050919050565b600060408201905081810360008301526113ef8185610a80565b905081810360208301526114038184610a80565b90509392505050565b61141581610e69565b82525050565b600082825260208201905092915050565b6000611437826109cf565b611441818561141b565b93506114518185602086016109eb565b61145a81610a15565b840191505092915050565b600060408201905061147a600083018561140c565b818103602083015261148c818461142c565b90509392505050565b60006114a0826109cf565b6114aa818561106b565b93506114ba8185602086016109eb565b80840191505092915050565b60006114d28284611495565b915081905092915050565b6114e6826109cf565b67ffffffffffffffff8111156114ff576114fe610d0a565b5b6115098254610cd9565b611514828285610f0e565b600060209050601f8311600181146115475760008415611535578287015190505b61153f8582610f7f565b8655506115a7565b601f19841661155586610de5565b60005b8281101561157d57848901518255600182019150602085019450602081019050611558565b8683101561159a5784890151611596601f891682610f61565b8355505b6001600288020188555050505b50505050505056fef9015880b9015401cc5504bac92b5ccafa0c3202372d7bb0b8cb6861795deddafae0ed7be924ff170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006360e4a05b2e03056b2d61c7ad2deb47b0be0084ffab44bf506bfff07b951fb0bf37c171584f74d80c96306e124152458183a7a2c570a136099f7c4ffc9dde340cbed4f87133200fc4e425946925eaac958209aba78e190feeb5c9f31182ec8d458260279adb3976c158471b932bbee5bb320cf9015880b9015401154918854780593f1c6bf620684b29ab3d4c4a4f5996dcbd1c1d0b48c06d56b40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000751884c80374b7b5d6d0ef740dacbea91b3d53ee5243eeacf94a970f131185c69dfd44e868e370602c72484bc2f34e9466255ef50ca817d34d61a46bff368318b6fff300eb566dac8d1c569a270c6d9c1f99664643582cafcb276fea83d5564cd38f4b1be0e8ee6c06e10f10f10dc39120884a26469706673582212209f594371591c2c5cc2a967353f54d26d3d236ad0e4c36a1598ff39cef70eae1664736f6c63781c302e382e33312d7072652e312b636f6d6d69742e6235393536366636004d"; + + // deploy contract + Json::Value create; + create["from"] = toJS( senderAddress ); + create["code"] = bytecode; + create["gas"] = "1800000"; + create["value"] = "10000000000000000000"; + create["nonce"] = 0; + string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + auto txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + std::string contractAddress = txReceipt["contractAddress"].asString(); + BOOST_REQUIRE( txReceipt["status"] == "0x1" ); + + // send a transaction -> BITE2 txn queue should become non-empty + Json::Value txGenerate; + txGenerate["to"] = contractAddress; + txGenerate["gas"] = "1000000"; + txGenerate["data"] = "0x7372aa26"; + txGenerate["from"] = toJS( senderAddress ); + txGenerate["nonce"] = 1; + + txHash = fixture.rpcClient->eth_sendTransaction( txGenerate ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( txReceipt["status"] == "0x1" ); + + BOOST_REQUIRE( fixture.client->debugGetTransactionQueue()->pendingBITE2Transactions()->size() == 1 ); + auto bite2Txn = fixture.client->debugGetTransactionQueue()->pendingBITE2Transactions()->front(); + BOOST_REQUIRE( !bite2Txn.isInvalid() ); + BOOST_REQUIRE_NE( bite2Txn.sender(), dev::ZeroAddress ); + auto to = bite2Txn.to(); + BOOST_REQUIRE_EQUAL( to, dev::Address( contractAddress ) ); + + Json::Value craftedCTXs = fixture.rpcClient->bite_getCraftedCtxs( txHash ); + BOOST_REQUIRE_EQUAL( craftedCTXs.size(), 1 ); + BOOST_REQUIRE_EQUAL( craftedCTXs[0].asString(), bite2Txn.sha3().hex() ); + + dev::u256 randomGasLimit = dev::h256::Arith( dev::h256::random() ) % 2500000 + 1000000; + dev::bytes randomGasLimitBytes = dev::toBigEndian( randomGasLimit ); + + std::vector< dev::bytes > originalValues{ dev::h256::random().asBytes(), dev::h256::random().asBytes() }; + + dev::bytes encryptedArg1 = formEncryptedMessageMockup( originalValues[0], dev::Address( contractAddress ) ); + dev::bytes encryptedArg2 = formEncryptedMessageMockup( originalValues[1], dev::Address( contractAddress ) ); + + // Build abi.encode(bytes[] args1, bytes[] args2) with 2 elements each + // args1 elements must be at least BITE_CIPHERTEXT_MIN_LEN bytes (encrypted data) + std::vector args1 = { + encryptedArg1, encryptedArg2 + }; + std::vector< dev::bytes > args2 = { + dev::fromHex( "706c61696e746578743122" ), // "plaintext1" + dev::fromHex( "706c61696e746578743222" ) // "plaintext2" + }; + + dev::bytes randomData = buildAbiEncodedArrays( args1, args2 ); + + // Build ABI-encoded input: abi.encode(address, uint256, bytes) + // Format: gasLimit(32) + offset_to_bytes(32) + bytes_length(32) + bytes_data + dev::bytes resultData; + // gasLimit value (32 bytes) + resultData.insert( resultData.end(), randomGasLimitBytes.begin(), randomGasLimitBytes.end() ); + + // offset to bytes data (points to position 64 = 2 * 32) + dev::bytes dataOffset = dev::toBigEndian( dev::u256( 64 ) ); + resultData.insert( resultData.end(), dataOffset.begin(), dataOffset.end() ); + // bytes data (length + content) + dev::bytes dataLength = dev::toBigEndian( dev::u256( randomData.size() ) ); + resultData.insert( resultData.end(), dataLength.begin(), dataLength.end() ); + resultData.insert( resultData.end(), randomData.begin(), randomData.end() ); + + txGenerate["to"] = contractAddress; + txGenerate["data"] = "0x6040c1fb" + dev::toHex( dev::u256( 32 ) ) + + dev::toHex( dev::u256( resultData.size() ) ) + dev::toHex( resultData ); + txGenerate["from"] = toJS( senderAddress ); + txGenerate["nonce"] = 2; + std::string txGenerateHash = fixture.rpcClient->eth_sendTransaction( txGenerate ); + BOOST_REQUIRE_EQUAL( fixture.client->debugGetTransactionQueue()->pendingBITE2Transactions()->size(), 1 ); + BOOST_REQUIRE_EQUAL( fixture.client->pending().size(), 1 ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + PrecompiledExecutor submitCTXExecutor = PrecompiledRegistrar::executor( "submitCTX" ); + dev::eth::PrecompiledCallContext ctx( fixture.client->number(), 1, 1, dev::h256::random(), + dev::Address( contractAddress ), true ); + + dev::bytesConstRef input( resultData.data(), resultData.size() ); + auto res = submitCTXExecutor( input, ctx ); + BOOST_REQUIRE( res.first ); + + dev::Address addressFromPrecompiled( dev::bytes( res.second.begin(), res.second.begin() + dev::Address::size ) ); + + PrecompiledExecutor blockRandomExecutor = PrecompiledRegistrar::executor( "getBlockRandom" ); + auto vrs = dev::makeSignature( + blockRandomExecutor( bytesConstRef(), ctx ).second, ctx.currentTxnIndex ); + dev::u256 gasPrice = g_skaleHost->getGasPrice( ctx.blockNumber.convert_to< unsigned >() ); + + // Build expected RLP-encoded data: RLP(RLP(args1[0], args1[1]), RLP(args2[0], args2[1])) + RLPStream args1Stream; + args1Stream.appendList( args1.size() ); + for ( const auto& elem : args1 ) { + args1Stream << elem; + } + + RLPStream args2Stream; + args2Stream.appendList( args2.size() ); + for ( const auto& elem : args2 ) { + args2Stream << elem; + } + + RLPStream finalStream; + finalStream.appendList( 2 ); + finalStream.appendRaw( args1Stream.out() ); + finalStream.appendRaw( args2Stream.out() ); + + dev::bytes rlpEncodedData = finalStream.out(); + + rlpEncodedData.insert( rlpEncodedData.begin(), + dev::bite::ON_DECRYPT_FUNCTION_SELECTOR.begin(), + dev::bite::ON_DECRYPT_FUNCTION_SELECTOR.end() ); + + // Create expected transaction for signature verification using RLP-encoded data + Transaction expectedTransaction( + 0, gasPrice, randomGasLimit, dev::Address( contractAddress ), rlpEncodedData, 0 ); + dev::h256 expectedTxnHash = expectedTransaction.sha3( dev::eth::WithoutSignature ); + dev::Public expectedPublicKey = recover( vrs, expectedTxnHash ); + dev::Address expectedWalletAddress = dev::toAddress( expectedPublicKey ); + + auto bn = fixture.client->number(); + BOOST_REQUIRE_EQUAL( fixture.client->transactions( bn ).size(), 2 ); + BOOST_REQUIRE( fixture.client->transactions( bn )[0].isCTX() ); + + // call getDecrypted() + Json::Value callDecrypted; + callDecrypted["to"] = contractAddress; + callDecrypted["data"] = "0x38d5a312"; + dev::bytes result = dev::fromHex( fixture.rpcClient->eth_call( callDecrypted, "latest" ) ); + auto [rlpStreamDecrypted, decryptedLength] = dev::bite::parseAbiEncodedBytesArray( dev::bytesConstRef( result.data(), result.size() ), 32, "" ); + BOOST_REQUIRE_EQUAL( decryptedLength, pregeneratedDecryptedValues.size() ); + dev::RLP rlpDecrypted( rlpStreamDecrypted.out() ); + for (size_t i = 0; i < decryptedLength; ++i) { + dev::RLP decryptedPayload( rlpDecrypted[i].payload() ); + BOOST_REQUIRE( decryptedPayload[0].toBytes() == pregeneratedDecryptedValues[i] ); + BOOST_REQUIRE_EQUAL( dev::toHexPrefixed( decryptedPayload[1].toBytes() ), contractAddress ); + } + + // call getPlaintext() + Json::Value callPlaintext; + callPlaintext["to"] = contractAddress; + callPlaintext["data"] = "0xcc159120"; + result = dev::fromHex( fixture.rpcClient->eth_call( callPlaintext, "latest" ) ); + auto [rlpStreamPlaintext, plaintextLength] = dev::bite::parseAbiEncodedBytesArray( dev::bytesConstRef( result.data(), result.size() ), 32, "" ); + BOOST_REQUIRE_EQUAL( plaintextLength, pregeneratedPlaintextValues.size() ); + dev::RLP rlpPlaintext( rlpStreamPlaintext.out() ); + for (size_t i = 0; i < plaintextLength; ++i) { + BOOST_REQUIRE_EQUAL( dev::toHex( rlpPlaintext[i].toBytes() ), dev::toHex( pregeneratedPlaintextValues[i] ) ); + } + + BOOST_REQUIRE_EQUAL( fixture.client->debugGetTransactionQueue()->pendingBITE2Transactions()->size(), 1 ); + + auto pendingCTXs = fixture.client->blockChain().pendingCTXsList(); + BOOST_REQUIRE_EQUAL( pendingCTXs.size(), 1 ); + auto pendingCTX = pendingCTXs[0]; + BOOST_REQUIRE( pendingCTX.isCTX() ); + BOOST_REQUIRE_EQUAL( pendingCTX.to(), dev::Address( contractAddress ) ); + BOOST_REQUIRE_EQUAL( pendingCTX.gas(), randomGasLimit ); + BOOST_REQUIRE_EQUAL( pendingCTX.sender(), expectedWalletAddress ); + BOOST_REQUIRE_EQUAL( "0x" + pendingCTX.getCTXOrigin().hex(), txGenerateHash ); + + dev::eth::mineTransaction( *( fixture.client ), 1 ); + bn = fixture.client->number(); + BOOST_REQUIRE_EQUAL( fixture.client->transactions( bn ).size(), 1 ); + Transaction ctxFromBlockchain = fixture.client->transaction( fixture.client->blockInfo( bn ).hash(), unsigned( 0 ) ); + + BOOST_REQUIRE( ctxFromBlockchain.isCTX() ); + BOOST_REQUIRE_EQUAL( ctxFromBlockchain.to(), dev::Address( contractAddress ) ); + BOOST_REQUIRE_EQUAL( ctxFromBlockchain.gas(), randomGasLimit ); + BOOST_REQUIRE( ctxFromBlockchain.data() == rlpEncodedData ); + BOOST_REQUIRE( ctxFromBlockchain.signature() == vrs ); + BOOST_REQUIRE_EQUAL( ctxFromBlockchain.sender(), expectedWalletAddress ); + + auto ctxOrigin = fixture.rpcClient->bite_getCtxOrigin( "0x" + ctxFromBlockchain.sha3().hex() ); + BOOST_REQUIRE_EQUAL( "0x" + ctxOrigin, txGenerateHash ); + + // call getDecrypted() + result = dev::fromHex( fixture.rpcClient->eth_call( callDecrypted, "latest" ) ); + auto [rlpStreamDecrypted1, decryptedLength1] = dev::bite::parseAbiEncodedBytesArray( dev::bytesConstRef( result.data(), result.size() ), 32, "" ); + BOOST_REQUIRE_EQUAL( decryptedLength1, pregeneratedDecryptedValues.size() ); + dev::RLP rlpDecrypted1( rlpStreamDecrypted1.out() ); + for (size_t i = 0; i < decryptedLength1; ++i) { + dev::RLP decryptedPayload( rlpDecrypted1[i].payload() ); + BOOST_REQUIRE( decryptedPayload[0].toBytes() == originalValues[i] ); + BOOST_REQUIRE_EQUAL( dev::toHexPrefixed( decryptedPayload[1].toBytes() ), contractAddress ); + } + + // call getPlaintext() + result = dev::fromHex( fixture.rpcClient->eth_call( callPlaintext, "latest" ) ); + auto [rlpStreamPlaintext1, plaintextLength1] = dev::bite::parseAbiEncodedBytesArray( dev::bytesConstRef( result.data(), result.size() ), 32, "" ); + BOOST_REQUIRE_EQUAL( plaintextLength1, pregeneratedPlaintextValues.size() ); + dev::RLP rlpPlaintext1( rlpStreamPlaintext1.out() ); + for (size_t i = 0; i < plaintextLength1; ++i) { + BOOST_REQUIRE_EQUAL( dev::toHex( rlpPlaintext1[i].toBytes() ), dev::toHex( args2[i] ) ); + } + + // test submitCTXWithInput with randomGasLimit >> lastBlockGasLimit + dev::u256 lastBlockGasLimit = fixture.client->blockInfo( fixture.client->number() ).gasLimit(); + dev::u256 randomGasLimit2 = lastBlockGasLimit * 10; + dev::bytes randomGasLimitBytes2 = dev::toBigEndian( randomGasLimit2 ); + + std::vector< dev::bytes > originalValues2{ dev::h256::random().asBytes(), dev::h256::random().asBytes() }; + + dev::bytes encryptedArg1_2 = formEncryptedMessageMockup( originalValues2[0], dev::Address( contractAddress ) ); + dev::bytes encryptedArg2_2 = formEncryptedMessageMockup( originalValues2[1], dev::Address( contractAddress ) ); + + std::vector args1_2 = { + encryptedArg1_2, encryptedArg2_2 + }; + std::vector args2_2 = { + dev::fromHex("706c61696e746578743122"), // "plaintext1" + dev::fromHex("706c61696e746578743222") // "plaintext2" + }; + + dev::bytes randomData2 = buildAbiEncodedArrays( args1_2, args2_2 ); + + dev::bytes resultData2; + // gasLimit value (32 bytes) - much greater than block gas limit + resultData2.insert( resultData2.end(), randomGasLimitBytes2.begin(), randomGasLimitBytes2.end() ); + + // offset to bytes data (points to position 64 = 2 * 32) + dev::bytes dataOffset2 = dev::toBigEndian( dev::u256( 64 ) ); + resultData2.insert( resultData2.end(), dataOffset2.begin(), dataOffset2.end() ); + // bytes data (length + content) + dev::bytes dataLength2 = dev::toBigEndian( dev::u256( randomData2.size() ) ); + resultData2.insert( resultData2.end(), dataLength2.begin(), dataLength2.end() ); + resultData2.insert( resultData2.end(), randomData2.begin(), randomData2.end() ); + + txGenerate["to"] = contractAddress; + txGenerate["data"] = "0x6040c1fb" + dev::toHex( dev::u256( 32 ) ) + dev::toHex( dev::u256( resultData2.size() ) ) + dev::toHex( resultData2 ); + txGenerate["from"] = toJS( senderAddress ); + txGenerate["nonce"] = 3; + std::string txGenerateHash2 = fixture.rpcClient->eth_sendTransaction( txGenerate ); + BOOST_REQUIRE_EQUAL( fixture.client->pending().size(), 1 ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txGenerateHash2 ); + BOOST_REQUIRE( txReceipt["status"] == "0x0" ); + + auto bn2 = fixture.client->number(); + BOOST_REQUIRE_EQUAL( fixture.client->transactions( bn2 ).size(), 1 ); + + BOOST_REQUIRE_EQUAL( fixture.client->debugGetTransactionQueue()->pendingBITE2Transactions()->size(), 0 ); +} + +BOOST_AUTO_TEST_CASE( submitCTXInContractConstructor ) { + JsonRpcFixture fixture( c_BITEConfigString, true, true, true, true, false, -1, {{ "contractStorageLimit", "100000"}} ); + + string senderAddress = toJS( fixture.coinbase.address() ); + + std::vector< dev::bytes > pregeneratedDecryptedValues{ dev::fromHex( "5b221ee6b5c5751ff5808beddbc0644dc4fdda6b5efb13dbb49d698cb0e3f172" ), + dev::fromHex( "006aa7d63edcfb03635a2ecf5064a9eec076c2466fb2a6c35d59b5f1039f2535" ) }; + std::vector< dev::bytes > pregeneratedPlaintextValues{ dev::asBytes( "plaintext1" ), dev::asBytes( "plaintext2" ) }; +// pragma solidity ^0.8.13; + +// contract submitCTX { +// bytes[] decrypted = new bytes[](1); +// bytes[] plaintext = new bytes[](1); +// constructor() payable { +// uint256 randomNumber = uint256(keccak256(abi.encodePacked(block.timestamp, block.number))) % 2500000 + 1000000; +// bytes[] memory args1 = new bytes[](2); +// // Use pre-generated args1 values instead of generating them dynamically +// args1[0] = hex"f9015880b9015401cc5504bac92b5ccafa0c3202372d7bb0b8cb6861795deddafae0ed7be924ff170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006360e4a05b2e03056b2d61c7ad2deb47b0be0084ffab44bf506bfff07b951fb0bf37c171584f74d80c96306e124152458183a7a2c570a136099f7c4ffc9dde340cbed4f87133200fc4e425946925eaac958209aba78e190feeb5c9f31182ec8d458260279adb3976c158471b932bbee5bb320c"; +// args1[1] = hex"f9015880b9015401154918854780593f1c6bf620684b29ab3d4c4a4f5996dcbd1c1d0b48c06d56b40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000751884c80374b7b5d6d0ef740dacbea91b3d53ee5243eeacf94a970f131185c69dfd44e868e370602c72484bc2f34e9466255ef50ca817d34d61a46bff368318b6fff300eb566dac8d1c569a270c6d9c1f99664643582cafcb276fea83d5564cd38f4b1be0e8ee6c06e10f10f10dc39120884"; + +// bytes[] memory args2 = new bytes[](2); +// args2[0] = abi.encodePacked("plaintext1"); +// args2[1] = abi.encodePacked("plaintext2"); + +// bytes memory randomBytes = abi.encode(args1, args2); +// bytes memory input = abi.encode(randomNumber, randomBytes); + +// (bool success, bytes memory result) = address(0x1B).staticcall(input); +// require(success, "0x1B call failed"); + +// // Extract address from first 20 bytes of result and transfer +// address walletAddress = address(bytes20(result)); +// payable(walletAddress).transfer(400000000000); +// } +// } + std::string bytecode = "6080604052600167ffffffffffffffff81111561001f5761001e6104ee565b5b60405190808252806020026020018201604052801561005257816020015b606081526020019060019003908161003d5790505b5060009080519060200190610068929190610414565b50600167ffffffffffffffff811115610084576100836104ee565b5b6040519080825280602002602001820160405280156100b757816020015b60608152602001906001900390816100a25790505b50600190805190602001906100cd929190610414565b506000620f4240622625a042436040516020016100eb929190610548565b6040516020818303038152906040528051906020012060001c61010e91906105a3565b6101189190610603565b90506000600267ffffffffffffffff811115610137576101366104ee565b5b60405190808252806020026020018201604052801561016a57816020015b60608152602001906001900390816101555790505b50905060405180610180016040528061015b8152602001610df861015b91398160008151811061019d5761019c610637565b5b602002602001018190525060405180610180016040528061015b8152602001610f5361015b9139816001815181106101d8576101d7610637565b5b60200260200101819052506000600267ffffffffffffffff811115610200576101ff6104ee565b5b60405190808252806020026020018201604052801561023357816020015b606081526020019060019003908161021e5790505b509050604051602001610245906106bd565b6040516020818303038152906040528160008151811061026857610267610637565b5b60200260200101819052506040516020016102829061071e565b604051602081830303815290604052816001815181106102a5576102a4610637565b5b6020026020010181905250600082826040516020016102c5929190610885565b6040516020818303038152906040529050600084826040516020016102eb929190610915565b6040516020818303038152906040529050600080601b73ffffffffffffffffffffffffffffffffffffffff16836040516103259190610981565b600060405180830381855afa9150503d8060008114610360576040519150601f19603f3d011682016040523d82523d6000602084013e610365565b606091505b5091509150816103aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a1906109f5565b60405180910390fd5b6000816103b690610a73565b60601c90508073ffffffffffffffffffffffffffffffffffffffff166108fc645d21dba0009081150290604051600060405180830381858888f19350505050158015610406573d6000803e3d6000fd5b505050505050505050610dab565b82805482825590600052602060002090810192821561045c579160200282015b8281111561045b57825182908161044b9190610cd9565b5091602001919060010190610434565b5b509050610469919061046d565b5090565b5b8082111561048d57600081816104849190610491565b5060010161046e565b5090565b50805461049d90610b09565b6000825580601f106104af57506104ce565b601f0160209004906000526020600020908101906104cd91906104d1565b5b50565b5b808211156104ea5760008160009055506001016104d2565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000819050919050565b6000819050919050565b61054261053d8261051d565b610527565b82525050565b60006105548285610531565b6020820191506105648284610531565b6020820191508190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006105ae8261051d565b91506105b98361051d565b9250826105c9576105c8610574565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061060e8261051d565b91506106198361051d565b9250828201905080821115610631576106306105d4565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081905092915050565b7f706c61696e746578743100000000000000000000000000000000000000000000600082015250565b60006106a7600a83610666565b91506106b282610671565b600a82019050919050565b60006106c88261069a565b9150819050919050565b7f706c61696e746578743200000000000000000000000000000000000000000000600082015250565b6000610708600a83610666565b9150610713826106d2565b600a82019050919050565b6000610729826106fb565b9150819050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561079957808201518184015260208101905061077e565b60008484015250505050565b6000601f19601f8301169050919050565b60006107c18261075f565b6107cb818561076a565b93506107db81856020860161077b565b6107e4816107a5565b840191505092915050565b60006107fb83836107b6565b905092915050565b6000602082019050919050565b600061081b82610733565b610825818561073e565b9350836020820285016108378561074f565b8060005b85811015610873578484038952815161085485826107ef565b945061085f83610803565b925060208a0199505060018101905061083b565b50829750879550505050505092915050565b6000604082019050818103600083015261089f8185610810565b905081810360208301526108b38184610810565b90509392505050565b6108c58161051d565b82525050565b600082825260208201905092915050565b60006108e78261075f565b6108f181856108cb565b935061090181856020860161077b565b61090a816107a5565b840191505092915050565b600060408201905061092a60008301856108bc565b818103602083015261093c81846108dc565b90509392505050565b600081905092915050565b600061095b8261075f565b6109658185610945565b935061097581856020860161077b565b80840191505092915050565b600061098d8284610950565b915081905092915050565b600082825260208201905092915050565b7f307831422063616c6c206661696c656400000000000000000000000000000000600082015250565b60006109df601083610998565b91506109ea826109a9565b602082019050919050565b60006020820190508181036000830152610a0e816109d2565b9050919050565b6000819050602082019050919050565b60007fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b6000610a5d8251610a25565b80915050919050565b600082821b905092915050565b6000610a7e8261075f565b82610a8884610a15565b9050610a9381610a51565b92506014821015610ad357610ace7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083601403600802610a66565b831692505b5050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680610b2157607f821691505b602082108103610b3457610b33610ada565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600060088302610b8f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610a66565b610b998683610a66565b95508019841693508086168417925050509392505050565b6000819050919050565b6000610bd6610bd1610bcc8461051d565b610bb1565b61051d565b9050919050565b6000819050919050565b610bf083610bbb565b610c04610bfc82610bdd565b848454610b5f565b825550505050565b600090565b610c19610c0c565b610c24818484610be7565b505050565b5b81811015610c4857610c3d600082610c11565b600181019050610c2a565b5050565b601f821115610c8d57610c5e81610b3a565b610c6784610b4f565b81016020851015610c76578190505b610c8a610c8285610b4f565b830182610c29565b50505b505050565b600082821c905092915050565b6000610cb060001984600802610c92565b1980831691505092915050565b6000610cc98383610c9f565b9150826002028217905092915050565b610ce28261075f565b67ffffffffffffffff811115610cfb57610cfa6104ee565b5b610d058254610b09565b610d10828285610c4c565b600060209050601f831160018114610d435760008415610d31578287015190505b610d3b8582610cbd565b865550610da3565b601f198416610d5186610b3a565b60005b82811015610d7957848901518255600182019150602085019450602081019050610d54565b86831015610d965784890151610d92601f891682610c9f565b8355505b6001600288020188555050505b505050505050565b603f80610db96000396000f3fe6080604052600080fdfea26469706673582212207f8d440a8b67a3a94ec70a43d822504c120782b181a52230ee20ee672f58781364736f6c634300081f0033f9015880b9015401cc5504bac92b5ccafa0c3202372d7bb0b8cb6861795deddafae0ed7be924ff170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006360e4a05b2e03056b2d61c7ad2deb47b0be0084ffab44bf506bfff07b951fb0bf37c171584f74d80c96306e124152458183a7a2c570a136099f7c4ffc9dde340cbed4f87133200fc4e425946925eaac958209aba78e190feeb5c9f31182ec8d458260279adb3976c158471b932bbee5bb320cf9015880b9015401154918854780593f1c6bf620684b29ab3d4c4a4f5996dcbd1c1d0b48c06d56b40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000751884c80374b7b5d6d0ef740dacbea91b3d53ee5243eeacf94a970f131185c69dfd44e868e370602c72484bc2f34e9466255ef50ca817d34d61a46bff368318b6fff300eb566dac8d1c569a270c6d9c1f99664643582cafcb276fea83d5564cd38f4b1be0e8ee6c06e10f10f10dc39120884"; + + // deploy contract + Json::Value create; + create["from"] = toJS( senderAddress ); + create["code"] = bytecode; + create["gas"] = "1800000"; + create["value"] = "10000000000000000000"; + create["nonce"] = 0; + string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + auto txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + std::string contractAddress = txReceipt["contractAddress"].asString(); + BOOST_REQUIRE( txReceipt["status"] == "0x1" ); + + // BITE2 txn queue should become non-empty + BOOST_REQUIRE( fixture.client->debugGetTransactionQueue()->pendingBITE2Transactions()->size() == 1 ); + auto bite2Txn = fixture.client->debugGetTransactionQueue()->pendingBITE2Transactions()->front(); + BOOST_REQUIRE( !bite2Txn.isInvalid() ); + BOOST_REQUIRE_NE( bite2Txn.sender(), dev::ZeroAddress ); + auto to = bite2Txn.to(); + BOOST_REQUIRE_EQUAL( to, dev::Address( contractAddress ) ); +} + +BOOST_AUTO_TEST_CASE( CTXTransactionAfterRevert ) { + JsonRpcFixture fixture( c_BITEConfigString, true, true, true, true, false, -1, {{ "contractStorageLimit", "100000" }} ); + + string senderAddress = toJS( fixture.coinbase.address() ); + +// pragma solidity ^0.8.13; + +// contract submitCTXCaller { +// bytes[] decrypted = new bytes[](1); +// bytes[] plaintext = new bytes[](1); +// constructor() payable {} + +// function submitCTX() public { +// uint256 randomNumber = uint256(keccak256(abi.encodePacked(block.timestamp, block.number))) % 2500000 + 1000000; +// bytes[] memory args1 = new bytes[](2); +// // Use pre-generated args1 values instead of generating them dynamically +// args1[0] = hex"f9015880b9015401cc5504bac92b5ccafa0c3202372d7bb0b8cb6861795deddafae0ed7be924ff170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006360e4a05b2e03056b2d61c7ad2deb47b0be0084ffab44bf506bfff07b951fb0bf37c171584f74d80c96306e124152458183a7a2c570a136099f7c4ffc9dde340cbed4f87133200fc4e425946925eaac958209aba78e190feeb5c9f31182ec8d458260279adb3976c158471b932bbee5bb320c"; +// args1[1] = hex"f9015880b9015401154918854780593f1c6bf620684b29ab3d4c4a4f5996dcbd1c1d0b48c06d56b40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000751884c80374b7b5d6d0ef740dacbea91b3d53ee5243eeacf94a970f131185c69dfd44e868e370602c72484bc2f34e9466255ef50ca817d34d61a46bff368318b6fff300eb566dac8d1c569a270c6d9c1f99664643582cafcb276fea83d5564cd38f4b1be0e8ee6c06e10f10f10dc39120884"; + +// bytes[] memory args2 = new bytes[](2); +// args2[0] = abi.encodePacked("plaintext1"); +// args2[1] = abi.encodePacked("plaintext2"); + +// bytes memory randomBytes = abi.encode(args1, args2); +// bytes memory input = abi.encode(randomNumber, randomBytes); + +// (bool success, bytes memory result) = address(0x1B).call(input); +// require(success, "0x1B call failed"); + +// // Extract address from first 20 bytes of result and transfer +// address walletAddress = address(bytes20(result)); +// payable(walletAddress).transfer(400000000000); +// } + +// function submitCTXWithRevert() public { +// uint256 randomNumber = uint256(keccak256(abi.encodePacked(block.timestamp, block.number))) % 2500000 + 1000000; +// bytes[] memory args1 = new bytes[](2); +// // Use pre-generated args1 values instead of generating them dynamically +// args1[0] = hex"f9015880b9015401cc5504bac92b5ccafa0c3202372d7bb0b8cb6861795deddafae0ed7be924ff170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006360e4a05b2e03056b2d61c7ad2deb47b0be0084ffab44bf506bfff07b951fb0bf37c171584f74d80c96306e124152458183a7a2c570a136099f7c4ffc9dde340cbed4f87133200fc4e425946925eaac958209aba78e190feeb5c9f31182ec8d458260279adb3976c158471b932bbee5bb320c"; +// args1[1] = hex"f9015880b9015401154918854780593f1c6bf620684b29ab3d4c4a4f5996dcbd1c1d0b48c06d56b40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000751884c80374b7b5d6d0ef740dacbea91b3d53ee5243eeacf94a970f131185c69dfd44e868e370602c72484bc2f34e9466255ef50ca817d34d61a46bff368318b6fff300eb566dac8d1c569a270c6d9c1f99664643582cafcb276fea83d5564cd38f4b1be0e8ee6c06e10f10f10dc39120884"; + +// bytes[] memory args2 = new bytes[](2); +// args2[0] = abi.encodePacked("plaintext1"); +// args2[1] = abi.encodePacked("plaintext2"); + +// bytes memory randomBytes = abi.encode(args1, args2); +// bytes memory input = abi.encode(randomNumber, randomBytes); + +// (bool success, bytes memory result) = address(0x1B).staticcall(input); +// require(success, "0x1B call failed"); + +// // Extract address from first 20 bytes of result and transfer +// address walletAddress = address(bytes20(result)); +// payable(walletAddress).transfer(400000000000); +// require(false); +// } + +// function onDecrypt(bytes[] calldata decryptedArguments, bytes[] calldata plaintextArguments) public { +// delete decrypted; +// decrypted = new bytes[](decryptedArguments.length); +// for (uint i = 0; i < decryptedArguments.length; ++i) { +// decrypted[i] = decryptedArguments[i]; +// } +// delete plaintext; +// plaintext = new bytes[](plaintextArguments.length); +// for (uint i = 0; i < plaintextArguments.length; ++i) { +// plaintext[i] = plaintextArguments[i]; +// } +// return; +// } + +// function getDecrypted() public view returns (bytes[] memory) { +// return decrypted; +// } + +// function getPlaintext() public view returns (bytes[] memory) { +// return plaintext; +// } +// } + std::string bytecode = "6080604052600167ffffffffffffffff81111561001f5761001e6101ad565b5b60405190808252806020026020018201604052801561005257816020015b606081526020019060019003908161003d5790505b50600090805190602001906100689291906100d3565b50600167ffffffffffffffff811115610084576100836101ad565b5b6040519080825280602002602001820160405280156100b757816020015b60608152602001906001900390816100a25790505b50600190805190602001906100cd9291906100d3565b506104cf565b82805482825590600052602060002090810192821561011b579160200282015b8281111561011a57825182908161010a91906103fd565b50916020019190600101906100f3565b5b509050610128919061012c565b5090565b5b8082111561014c57600081816101439190610150565b5060010161012d565b5090565b50805461015c90610216565b6000825580601f1061016e575061018d565b601f01602090049060005260206000209081019061018c9190610190565b5b50565b5b808211156101a9576000816000905550600101610191565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061022e57607f821691505b602082108103610241576102406101e7565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026102a97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261026c565b6102b3868361026c565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006102fa6102f56102f0846102cb565b6102d5565b6102cb565b9050919050565b6000819050919050565b610314836102df565b61032861032082610301565b848454610279565b825550505050565b600090565b61033d610330565b61034881848461030b565b505050565b5b8181101561036c57610361600082610335565b60018101905061034e565b5050565b601f8211156103b15761038281610247565b61038b8461025c565b8101602085101561039a578190505b6103ae6103a68561025c565b83018261034d565b50505b505050565b600082821c905092915050565b60006103d4600019846008026103b6565b1980831691505092915050565b60006103ed83836103c3565b9150826002028217905092915050565b610406826101dc565b67ffffffffffffffff81111561041f5761041e6101ad565b5b6104298254610216565b610434828285610370565b600060209050601f8311600181146104675760008415610455578287015190505b61045f85826103e1565b8655506104c7565b601f19841661047586610247565b60005b8281101561049d57848901518255600182019150602085019450602081019050610478565b868310156104ba57848901516104b6601f8916826103c3565b8355505b6001600288020188555050505b505050505050565b6119ef806104de6000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c806338d5a3121461005c57806357983ac81461007a5780637372aa2614610096578063a2934a8c146100a0578063cc159120146100aa575b600080fd5b6100646100c8565b6040516100719190610d1f565b60405180910390f35b610094600480360381019061008f9190610db0565b6101a1565b005b61009e610366565b005b6100a86106ab565b005b6100b26109f9565b6040516100bf9190610d1f565b60405180910390f35b60606000805480602002602001604051908101604052809291908181526020016000905b8282101561019857838290600052602060002001805461010b90610e60565b80601f016020809104026020016040519081016040528092919081815260200182805461013790610e60565b80156101845780601f1061015957610100808354040283529160200191610184565b820191906000526020600020905b81548152906001019060200180831161016757829003601f168201915b5050505050815260200190600101906100ec565b50505050905090565b6000806101ae9190610ad2565b8383905067ffffffffffffffff8111156101cb576101ca610e91565b5b6040519080825280602002602001820160405280156101fe57816020015b60608152602001906001900390816101e95790505b5060009080519060200190610214929190610af3565b5060005b8484905081101561027f5784848281811061023657610235610ec0565b5b90506020028101906102489190610efe565b6000838154811061025c5761025b610ec0565b5b906000526020600020019182610273929190611122565b50806001019050610218565b506001600061028e9190610ad2565b8181905067ffffffffffffffff8111156102ab576102aa610e91565b5b6040519080825280602002602001820160405280156102de57816020015b60608152602001906001900390816102c95790505b50600190805190602001906102f4929190610af3565b5060005b8282905081101561035f5782828281811061031657610315610ec0565b5b90506020028101906103289190610efe565b6001838154811061033c5761033b610ec0565b5b906000526020600020019182610353929190611122565b508060010190506102f8565b5050505050565b6000620f4240622625a04243604051602001610383929190611213565b6040516020818303038152906040528051906020012060001c6103a6919061126e565b6103b091906112ce565b90506000600267ffffffffffffffff8111156103cf576103ce610e91565b5b60405190808252806020026020018201604052801561040257816020015b60608152602001906001900390816103ed5790505b50905060405180610180016040528061015b81526020016116ea61015b91398160008151811061043557610434610ec0565b5b602002602001018190525060405180610180016040528061015b815260200161184561015b9139816001815181106104705761046f610ec0565b5b60200260200101819052506000600267ffffffffffffffff81111561049857610497610e91565b5b6040519080825280602002602001820160405280156104cb57816020015b60608152602001906001900390816104b65790505b5090506040516020016104dd90611359565b60405160208183030381529060405281600081518110610500576104ff610ec0565b5b602002602001018190525060405160200161051a906113ba565b6040516020818303038152906040528160018151811061053d5761053c610ec0565b5b60200260200101819052506000828260405160200161055d9291906113cf565b60405160208183030381529060405290506000848260405160200161058392919061145f565b6040516020818303038152906040529050600080601b73ffffffffffffffffffffffffffffffffffffffff16836040516105bd91906114cb565b6000604051808303816000865af19150503d80600081146105fa576040519150601f19603f3d011682016040523d82523d6000602084013e6105ff565b606091505b509150915081610644576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161063b9061153f565b60405180910390fd5b600081610650906115b0565b60601c90508073ffffffffffffffffffffffffffffffffffffffff166108fc645d21dba0009081150290604051600060405180830381858888f193505050501580156106a0573d6000803e3d6000fd5b505050505050505050565b6000620f4240622625a042436040516020016106c8929190611213565b6040516020818303038152906040528051906020012060001c6106eb919061126e565b6106f591906112ce565b90506000600267ffffffffffffffff81111561071457610713610e91565b5b60405190808252806020026020018201604052801561074757816020015b60608152602001906001900390816107325790505b50905060405180610180016040528061015b81526020016116ea61015b91398160008151811061077a57610779610ec0565b5b602002602001018190525060405180610180016040528061015b815260200161184561015b9139816001815181106107b5576107b4610ec0565b5b60200260200101819052506000600267ffffffffffffffff8111156107dd576107dc610e91565b5b60405190808252806020026020018201604052801561081057816020015b60608152602001906001900390816107fb5790505b50905060405160200161082290611359565b6040516020818303038152906040528160008151811061084557610844610ec0565b5b602002602001018190525060405160200161085f906113ba565b6040516020818303038152906040528160018151811061088257610881610ec0565b5b6020026020010181905250600082826040516020016108a29291906113cf565b6040516020818303038152906040529050600084826040516020016108c892919061145f565b6040516020818303038152906040529050600080601b73ffffffffffffffffffffffffffffffffffffffff168360405161090291906114cb565b600060405180830381855afa9150503d806000811461093d576040519150601f19603f3d011682016040523d82523d6000602084013e610942565b606091505b509150915081610987576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097e9061153f565b60405180910390fd5b600081610993906115b0565b60601c90508073ffffffffffffffffffffffffffffffffffffffff166108fc645d21dba0009081150290604051600060405180830381858888f193505050501580156109e3573d6000803e3d6000fd5b5060006109ef57600080fd5b5050505050505050565b60606001805480602002602001604051908101604052809291908181526020016000905b82821015610ac9578382906000526020600020018054610a3c90610e60565b80601f0160208091040260200160405190810160405280929190818152602001828054610a6890610e60565b8015610ab55780601f10610a8a57610100808354040283529160200191610ab5565b820191906000526020600020905b815481529060010190602001808311610a9857829003601f168201915b505050505081526020019060010190610a1d565b50505050905090565b5080546000825590600052602060002090810190610af09190610b4c565b50565b828054828255906000526020600020908101928215610b3b579160200282015b82811115610b3a578251829081610b2a9190611617565b5091602001919060010190610b13565b5b509050610b489190610b4c565b5090565b5b80821115610b6c5760008181610b639190610b70565b50600101610b4d565b5090565b508054610b7c90610e60565b6000825580601f10610b8e5750610bad565b601f016020900490600052602060002090810190610bac9190610bb0565b5b50565b5b80821115610bc9576000816000905550600101610bb1565b5090565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610c33578082015181840152602081019050610c18565b60008484015250505050565b6000601f19601f8301169050919050565b6000610c5b82610bf9565b610c658185610c04565b9350610c75818560208601610c15565b610c7e81610c3f565b840191505092915050565b6000610c958383610c50565b905092915050565b6000602082019050919050565b6000610cb582610bcd565b610cbf8185610bd8565b935083602082028501610cd185610be9565b8060005b85811015610d0d5784840389528151610cee8582610c89565b9450610cf983610c9d565b925060208a01995050600181019050610cd5565b50829750879550505050505092915050565b60006020820190508181036000830152610d398184610caa565b905092915050565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f840112610d7057610d6f610d4b565b5b8235905067ffffffffffffffff811115610d8d57610d8c610d50565b5b602083019150836020820283011115610da957610da8610d55565b5b9250929050565b60008060008060408587031215610dca57610dc9610d41565b5b600085013567ffffffffffffffff811115610de857610de7610d46565b5b610df487828801610d5a565b9450945050602085013567ffffffffffffffff811115610e1757610e16610d46565b5b610e2387828801610d5a565b925092505092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680610e7857607f821691505b602082108103610e8b57610e8a610e31565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112610f1b57610f1a610eef565b5b80840192508235915067ffffffffffffffff821115610f3d57610f3c610ef4565b5b602083019250600182023603831315610f5957610f58610ef9565b5b509250929050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302610fce7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610f91565b610fd88683610f91565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b600061101f61101a61101584610ff0565b610ffa565b610ff0565b9050919050565b6000819050919050565b61103983611004565b61104d61104582611026565b848454610f9e565b825550505050565b600090565b611062611055565b61106d818484611030565b505050565b5b818110156110915761108660008261105a565b600181019050611073565b5050565b601f8211156110d6576110a781610f6c565b6110b084610f81565b810160208510156110bf578190505b6110d36110cb85610f81565b830182611072565b50505b505050565b600082821c905092915050565b60006110f9600019846008026110db565b1980831691505092915050565b600061111283836110e8565b9150826002028217905092915050565b61112c8383610f61565b67ffffffffffffffff81111561114557611144610e91565b5b61114f8254610e60565b61115a828285611095565b6000601f8311600181146111895760008415611177578287013590505b6111818582611106565b8655506111e9565b601f19841661119786610f6c565b60005b828110156111bf5784890135825560018201915060208501945060208101905061119a565b868310156111dc57848901356111d8601f8916826110e8565b8355505b6001600288020188555050505b50505050505050565b6000819050919050565b61120d61120882610ff0565b6111f2565b82525050565b600061121f82856111fc565b60208201915061122f82846111fc565b6020820191508190509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061127982610ff0565b915061128483610ff0565b9250826112945761129361123f565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006112d982610ff0565b91506112e483610ff0565b92508282019050808211156112fc576112fb61129f565b5b92915050565b600081905092915050565b7f706c61696e746578743100000000000000000000000000000000000000000000600082015250565b6000611343600a83611302565b915061134e8261130d565b600a82019050919050565b600061136482611336565b9150819050919050565b7f706c61696e746578743200000000000000000000000000000000000000000000600082015250565b60006113a4600a83611302565b91506113af8261136e565b600a82019050919050565b60006113c582611397565b9150819050919050565b600060408201905081810360008301526113e98185610caa565b905081810360208301526113fd8184610caa565b90509392505050565b61140f81610ff0565b82525050565b600082825260208201905092915050565b600061143182610bf9565b61143b8185611415565b935061144b818560208601610c15565b61145481610c3f565b840191505092915050565b60006040820190506114746000830185611406565b81810360208301526114868184611426565b90509392505050565b600081905092915050565b60006114a582610bf9565b6114af818561148f565b93506114bf818560208601610c15565b80840191505092915050565b60006114d7828461149a565b915081905092915050565b600082825260208201905092915050565b7f307831422063616c6c206661696c656400000000000000000000000000000000600082015250565b60006115296010836114e2565b9150611534826114f3565b602082019050919050565b600060208201905081810360008301526115588161151c565b9050919050565b6000819050602082019050919050565b60007fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b60006115a7825161156f565b80915050919050565b60006115bb82610bf9565b826115c58461155f565b90506115d08161159b565b925060148210156116105761160b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083601403600802610f91565b831692505b5050919050565b61162082610bf9565b67ffffffffffffffff81111561163957611638610e91565b5b6116438254610e60565b61164e828285611095565b600060209050601f831160018114611681576000841561166f578287015190505b6116798582611106565b8655506116e1565b601f19841661168f86610f6c565b60005b828110156116b757848901518255600182019150602085019450602081019050611692565b868310156116d457848901516116d0601f8916826110e8565b8355505b6001600288020188555050505b50505050505056fef9015880b9015401cc5504bac92b5ccafa0c3202372d7bb0b8cb6861795deddafae0ed7be924ff170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006360e4a05b2e03056b2d61c7ad2deb47b0be0084ffab44bf506bfff07b951fb0bf37c171584f74d80c96306e124152458183a7a2c570a136099f7c4ffc9dde340cbed4f87133200fc4e425946925eaac958209aba78e190feeb5c9f31182ec8d458260279adb3976c158471b932bbee5bb320cf9015880b9015401154918854780593f1c6bf620684b29ab3d4c4a4f5996dcbd1c1d0b48c06d56b40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000751884c80374b7b5d6d0ef740dacbea91b3d53ee5243eeacf94a970f131185c69dfd44e868e370602c72484bc2f34e9466255ef50ca817d34d61a46bff368318b6fff300eb566dac8d1c569a270c6d9c1f99664643582cafcb276fea83d5564cd38f4b1be0e8ee6c06e10f10f10dc39120884a2646970667358221220fc4b359f946612f95cce9c035d3fb72316657813aa43c0d7e630b942efcc079e64736f6c63781c302e382e33312d7072652e312b636f6d6d69742e6235393536366636004d"; + + // deploy contract + Json::Value create; + create["from"] = toJS( senderAddress ); + create["code"] = bytecode; + create["gas"] = "1800000"; + create["value"] = "10000000000000000000"; + create["nonce"] = 0; + string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + auto txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + std::string contractAddress = txReceipt["contractAddress"].asString(); + BOOST_REQUIRE( txReceipt["status"] == "0x1" ); + + // call submitCTX() + // BITE2 queue should become non-empty + Json::Value txGenerate; + txGenerate["to"] = contractAddress; + txGenerate["gas"] = "1000000"; + txGenerate["data"] = "0x7372aa26"; + txGenerate["from"] = toJS( senderAddress ); + txGenerate["nonce"] = 1; + txHash = fixture.rpcClient->eth_sendTransaction( txGenerate ); + + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( txReceipt["status"] == "0x1" ); + BOOST_REQUIRE_EQUAL( fixture.client->debugGetTransactionQueue()->pendingBITE2Transactions()->size(), 1 ); + + + // call submitCTXWithRevert() + // BITE2 queue size should remain empty + Json::Value txFailGenerate; + txFailGenerate["to"] = contractAddress; + txFailGenerate["gas"] = "1000000"; + txFailGenerate["data"] = "0xa2934a8c"; + txFailGenerate["from"] = toJS( senderAddress ); + txFailGenerate["nonce"] = 2; + txHash = fixture.rpcClient->eth_sendTransaction( txFailGenerate ); + + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( txReceipt["status"] == "0x0" ); + + BOOST_REQUIRE_EQUAL( fixture.client->debugGetTransactionQueue()->pendingBITE2Transactions()->size(), 0 ); +} + +BOOST_AUTO_TEST_CASE( CTXOutOfBlockGasLimit ) { + JsonRpcFixture fixture( c_BITEConfigString, true, true, true, true, false, -1, {{ "contractStorageLimit", "100000" }} ); + + dev::eth::g_skaleHost = fixture.client->skaleHost(); + + string senderAddress = toJS( fixture.coinbase.address() ); + + // pragma solidity ^0.8.13; + + // contract Precompile0x07Caller { + // bytes[] decrypted = new bytes[](1); + // bytes[] plaintext = new bytes[](1); + // constructor() payable {} + + // function submitCTX(uint256 gasAmount) public { + // uint256 randomNumber = gasAmount + 100000; + // bytes[] memory args1 = new bytes[](2); + // // Use pre-generated args1 values instead of generating them dynamically + // args1[0] = hex"f9015880b9015401cc5504bac92b5ccafa0c3202372d7bb0b8cb6861795deddafae0ed7be924ff170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006360e4a05b2e03056b2d61c7ad2deb47b0be0084ffab44bf506bfff07b951fb0bf37c171584f74d80c96306e124152458183a7a2c570a136099f7c4ffc9dde340cbed4f87133200fc4e425946925eaac958209aba78e190feeb5c9f31182ec8d458260279adb3976c158471b932bbee5bb320c"; + // args1[1] = hex"f9015880b9015401154918854780593f1c6bf620684b29ab3d4c4a4f5996dcbd1c1d0b48c06d56b40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000751884c80374b7b5d6d0ef740dacbea91b3d53ee5243eeacf94a970f131185c69dfd44e868e370602c72484bc2f34e9466255ef50ca817d34d61a46bff368318b6fff300eb566dac8d1c569a270c6d9c1f99664643582cafcb276fea83d5564cd38f4b1be0e8ee6c06e10f10f10dc39120884"; + + // bytes[] memory args2 = new bytes[](1); + // args2[0] = abi.encode(gasAmount); + + // bytes memory randomBytes = abi.encode(args1, args2); + // bytes memory input = abi.encode(randomNumber, randomBytes); + + // (bool success, bytes memory result) = address(0x1B).staticcall(input); + // require(success, "0x1B call failed"); + + // // Extract address from first 20 bytes of result and transfer + // address walletAddress = address(bytes20(result)); + // payable(walletAddress).transfer(25169190900000); + // } + + // function onDecrypt(bytes[] calldata decryptedArguments, bytes[] calldata plaintextArguments) public { + // delete decrypted; + // decrypted = new bytes[](decryptedArguments.length); + // for (uint i = 0; i < decryptedArguments.length; ++i) { + // decrypted[i] = decryptedArguments[i]; + // } + // delete plaintext; + // plaintext = new bytes[](plaintextArguments.length); + // for (uint i = 0; i < plaintextArguments.length; ++i) { + // plaintext[i] = plaintextArguments[i]; + // } + // uint256 gasAmount = abi.decode(plaintext[0], (uint256)); + // uint256 startGas = gasleft(); + // while (startGas - gasleft() < gasAmount && gasleft() > 50000) { + // plaintext.push(abi.encode(gasleft())); + // } + // return; + // } + + // function getDecrypted() public view returns (bytes[] memory) { + // return decrypted; + // } + + // function getPlaintext() public view returns (bytes[] memory) { + // return plaintext; + // } + // } + + std::string bytecode = "6080604052600167ffffffffffffffff81111561001f5761001e6101ad565b5b60405190808252806020026020018201604052801561005257816020015b606081526020019060019003908161003d5790505b50600090805190602001906100689291906100d3565b50600167ffffffffffffffff811115610084576100836101ad565b5b6040519080825280602002602001820160405280156100b757816020015b60608152602001906001900390816100a25790505b50600190805190602001906100cd9291906100d3565b506104cf565b82805482825590600052602060002090810192821561011b579160200282015b8281111561011a57825182908161010a91906103fd565b50916020019190600101906100f3565b5b509050610128919061012c565b5090565b5b8082111561014c57600081816101439190610150565b5060010161012d565b5090565b50805461015c90610216565b6000825580601f1061016e575061018d565b601f01602090049060005260206000209081019061018c9190610190565b5b50565b5b808211156101a9576000816000905550600101610191565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061022e57607f821691505b602082108103610241576102406101e7565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026102a97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8261026c565b6102b3868361026c565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006102fa6102f56102f0846102cb565b6102d5565b6102cb565b9050919050565b6000819050919050565b610314836102df565b61032861032082610301565b848454610279565b825550505050565b600090565b61033d610330565b61034881848461030b565b505050565b5b8181101561036c57610361600082610335565b60018101905061034e565b5050565b601f8211156103b15761038281610247565b61038b8461025c565b8101602085101561039a578190505b6103ae6103a68561025c565b83018261034d565b50505b505050565b600082821c905092915050565b60006103d4600019846008026103b6565b1980831691505092915050565b60006103ed83836103c3565b9150826002028217905092915050565b610406826101dc565b67ffffffffffffffff81111561041f5761041e6101ad565b5b6104298254610216565b610434828285610370565b600060209050601f8311600181146104675760008415610455578287015190505b61045f85826103e1565b8655506104c7565b601f19841661047586610247565b60005b8281101561049d57848901518255600182019150602085019450602081019050610478565b868310156104ba57848901516104b6601f8916826103c3565b8355505b6001600288020188555050505b505050505050565b6116da806104de6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806338d5a312146100515780634c6f6c221461006f57806357983ac81461008b578063cc159120146100a7575b600080fd5b6100596100c5565b6040516100669190610a9a565b60405180910390f35b61008960048036038101906100849190610afc565b61019e565b005b6100a560048036038101906100a09190610b8e565b61046f565b005b6100af610774565b6040516100bc9190610a9a565b60405180910390f35b60606000805480602002602001604051908101604052809291908181526020016000905b8282101561019557838290600052602060002001805461010890610c3e565b80601f016020809104026020016040519081016040528092919081815260200182805461013490610c3e565b80156101815780601f1061015657610100808354040283529160200191610181565b820191906000526020600020905b81548152906001019060200180831161016457829003601f168201915b5050505050815260200190600101906100e9565b50505050905090565b6000620186a0826101af9190610c9e565b90506000600267ffffffffffffffff8111156101ce576101cd610cd2565b5b60405190808252806020026020018201604052801561020157816020015b60608152602001906001900390816101ec5790505b50905060405180610180016040528061015b81526020016113d561015b91398160008151811061023457610233610d01565b5b602002602001018190525060405180610180016040528061015b815260200161153061015b91398160018151811061026f5761026e610d01565b5b60200260200101819052506000600167ffffffffffffffff81111561029757610296610cd2565b5b6040519080825280602002602001820160405280156102ca57816020015b60608152602001906001900390816102b55790505b509050836040516020016102de9190610d3f565b6040516020818303038152906040528160008151811061030157610300610d01565b5b602002602001018190525060008282604051602001610321929190610d5a565b604051602081830303815290604052905060008482604051602001610347929190610ddb565b6040516020818303038152906040529050600080601b73ffffffffffffffffffffffffffffffffffffffff16836040516103819190610e47565b600060405180830381855afa9150503d80600081146103bc576040519150601f19603f3d011682016040523d82523d6000602084013e6103c1565b606091505b509150915081610406576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103fd90610ebb565b60405180910390fd5b60008161041290610f39565b60601c90508073ffffffffffffffffffffffffffffffffffffffff166108fc6516e428aed1209081150290604051600060405180830381858888f19350505050158015610463573d6000803e3d6000fd5b50505050505050505050565b60008061047c919061084d565b8383905067ffffffffffffffff81111561049957610498610cd2565b5b6040519080825280602002602001820160405280156104cc57816020015b60608152602001906001900390816104b75790505b50600090805190602001906104e292919061086e565b5060005b8484905081101561054d5784848281811061050457610503610d01565b5b90506020028101906105169190610faf565b6000838154811061052a57610529610d01565b5b9060005260206000200191826105419291906111bc565b508060010190506104e6565b506001600061055c919061084d565b8181905067ffffffffffffffff81111561057957610578610cd2565b5b6040519080825280602002602001820160405280156105ac57816020015b60608152602001906001900390816105975790505b50600190805190602001906105c292919061086e565b5060005b8282905081101561062d578282828181106105e4576105e3610d01565b5b90506020028101906105f69190610faf565b6001838154811061060a57610609610d01565b5b9060005260206000200191826106219291906111bc565b508060010190506105c6565b506000600160008154811061064557610644610d01565b5b90600052602060002001805461065a90610c3e565b80601f016020809104026020016040519081016040528092919081815260200182805461068690610c3e565b80156106d35780601f106106a8576101008083540402835291602001916106d3565b820191906000526020600020905b8154815290600101906020018083116106b657829003601f168201915b50505050508060200190518101906106eb91906112a1565b905060005a90505b815a8261070091906112ce565b10801561070e575061c3505a115b1561076c5760015a6040516020016107269190610d3f565b6040516020818303038152906040529080600181540180825580915050600190039060005260206000200160009091909190915090816107669190611302565b506106f3565b505050505050565b60606001805480602002602001604051908101604052809291908181526020016000905b828210156108445783829060005260206000200180546107b790610c3e565b80601f01602080910402602001604051908101604052809291908181526020018280546107e390610c3e565b80156108305780601f1061080557610100808354040283529160200191610830565b820191906000526020600020905b81548152906001019060200180831161081357829003601f168201915b505050505081526020019060010190610798565b50505050905090565b508054600082559060005260206000209081019061086b91906108c7565b50565b8280548282559060005260206000209081019282156108b6579160200282015b828111156108b55782518290816108a59190611302565b509160200191906001019061088e565b5b5090506108c391906108c7565b5090565b5b808211156108e757600081816108de91906108eb565b506001016108c8565b5090565b5080546108f790610c3e565b6000825580601f106109095750610928565b601f016020900490600052602060002090810190610927919061092b565b5b50565b5b8082111561094457600081600090555060010161092c565b5090565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60005b838110156109ae578082015181840152602081019050610993565b60008484015250505050565b6000601f19601f8301169050919050565b60006109d682610974565b6109e0818561097f565b93506109f0818560208601610990565b6109f9816109ba565b840191505092915050565b6000610a1083836109cb565b905092915050565b6000602082019050919050565b6000610a3082610948565b610a3a8185610953565b935083602082028501610a4c85610964565b8060005b85811015610a885784840389528151610a698582610a04565b9450610a7483610a18565b925060208a01995050600181019050610a50565b50829750879550505050505092915050565b60006020820190508181036000830152610ab48184610a25565b905092915050565b600080fd5b600080fd5b6000819050919050565b610ad981610ac6565b8114610ae457600080fd5b50565b600081359050610af681610ad0565b92915050565b600060208284031215610b1257610b11610abc565b5b6000610b2084828501610ae7565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f840112610b4e57610b4d610b29565b5b8235905067ffffffffffffffff811115610b6b57610b6a610b2e565b5b602083019150836020820283011115610b8757610b86610b33565b5b9250929050565b60008060008060408587031215610ba857610ba7610abc565b5b600085013567ffffffffffffffff811115610bc657610bc5610ac1565b5b610bd287828801610b38565b9450945050602085013567ffffffffffffffff811115610bf557610bf4610ac1565b5b610c0187828801610b38565b925092505092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680610c5657607f821691505b602082108103610c6957610c68610c0f565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610ca982610ac6565b9150610cb483610ac6565b9250828201905080821115610ccc57610ccb610c6f565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b610d3981610ac6565b82525050565b6000602082019050610d546000830184610d30565b92915050565b60006040820190508181036000830152610d748185610a25565b90508181036020830152610d888184610a25565b90509392505050565b600082825260208201905092915050565b6000610dad82610974565b610db78185610d91565b9350610dc7818560208601610990565b610dd0816109ba565b840191505092915050565b6000604082019050610df06000830185610d30565b8181036020830152610e028184610da2565b90509392505050565b600081905092915050565b6000610e2182610974565b610e2b8185610e0b565b9350610e3b818560208601610990565b80840191505092915050565b6000610e538284610e16565b915081905092915050565b600082825260208201905092915050565b7f307831422063616c6c206661696c656400000000000000000000000000000000600082015250565b6000610ea5601083610e5e565b9150610eb082610e6f565b602082019050919050565b60006020820190508181036000830152610ed481610e98565b9050919050565b6000819050602082019050919050565b60007fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b6000610f238251610eeb565b80915050919050565b600082821b905092915050565b6000610f4482610974565b82610f4e84610edb565b9050610f5981610f17565b92506014821015610f9957610f947fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083601403600802610f2c565b831692505b5050919050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112610fcc57610fcb610fa0565b5b80840192508235915067ffffffffffffffff821115610fee57610fed610fa5565b5b60208301925060018202360383131561100a57611009610faa565b5b509250929050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b6000600883026110727fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610f2c565b61107c8683610f2c565b95508019841693508086168417925050509392505050565b6000819050919050565b60006110b96110b46110af84610ac6565b611094565b610ac6565b9050919050565b6000819050919050565b6110d38361109e565b6110e76110df826110c0565b848454611042565b825550505050565b600090565b6110fc6110ef565b6111078184846110ca565b505050565b5b8181101561112b576111206000826110f4565b60018101905061110d565b5050565b601f821115611170576111418161101d565b61114a84611032565b81016020851015611159578190505b61116d61116585611032565b83018261110c565b50505b505050565b600082821c905092915050565b600061119360001984600802611175565b1980831691505092915050565b60006111ac8383611182565b9150826002028217905092915050565b6111c68383611012565b67ffffffffffffffff8111156111df576111de610cd2565b5b6111e98254610c3e565b6111f482828561112f565b6000601f8311600181146112235760008415611211578287013590505b61121b85826111a0565b865550611283565b601f1984166112318661101d565b60005b8281101561125957848901358255600182019150602085019450602081019050611234565b868310156112765784890135611272601f891682611182565b8355505b6001600288020188555050505b50505050505050565b60008151905061129b81610ad0565b92915050565b6000602082840312156112b7576112b6610abc565b5b60006112c58482850161128c565b91505092915050565b60006112d982610ac6565b91506112e483610ac6565b92508282039050818111156112fc576112fb610c6f565b5b92915050565b61130b82610974565b67ffffffffffffffff81111561132457611323610cd2565b5b61132e8254610c3e565b61133982828561112f565b600060209050601f83116001811461136c576000841561135a578287015190505b61136485826111a0565b8655506113cc565b601f19841661137a8661101d565b60005b828110156113a25784890151825560018201915060208501945060208101905061137d565b868310156113bf57848901516113bb601f891682611182565b8355505b6001600288020188555050505b50505050505056fef9015880b9015401cc5504bac92b5ccafa0c3202372d7bb0b8cb6861795deddafae0ed7be924ff170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006360e4a05b2e03056b2d61c7ad2deb47b0be0084ffab44bf506bfff07b951fb0bf37c171584f74d80c96306e124152458183a7a2c570a136099f7c4ffc9dde340cbed4f87133200fc4e425946925eaac958209aba78e190feeb5c9f31182ec8d458260279adb3976c158471b932bbee5bb320cf9015880b9015401154918854780593f1c6bf620684b29ab3d4c4a4f5996dcbd1c1d0b48c06d56b40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000751884c80374b7b5d6d0ef740dacbea91b3d53ee5243eeacf94a970f131185c69dfd44e868e370602c72484bc2f34e9466255ef50ca817d34d61a46bff368318b6fff300eb566dac8d1c569a270c6d9c1f99664643582cafcb276fea83d5564cd38f4b1be0e8ee6c06e10f10f10dc39120884a26469706673582212207709b91a00629c07db20a39f6c7636d35cc5abbd73e615e9843332b487d0f11664736f6c63781c302e382e33312d7072652e312b636f6d6d69742e6235393536366636004d"; + + // deploy contract + Json::Value create; + create["from"] = toJS( senderAddress ); + create["code"] = bytecode; + create["gas"] = "1800000"; + create["value"] = "10000000000000000000"; + create["nonce"] = 0; + string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + auto txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + std::string contractAddress = txReceipt["contractAddress"].asString(); + BOOST_REQUIRE( txReceipt["status"] == "0x1" ); + + fixture.rpcClient->debug_pauseConsensus( true ); + + // get block gas limit + dev::u256 blockGasLimit = fixture.client->blockInfo( fixture.client->number() ).gasLimit(); + + // send 2 submitCTXWithInput transactions in one block + // total gasLimit specified in the payload of these transactions should extend block gas limit + // gasUsed of these transactions corresponds to their gasLimit + // regular txns should not be processed until CTX queue is not empty + dev::u256 highGasLimit = (blockGasLimit * 90) / 100; + dev::bytes highGasLimitBytes = dev::toBigEndian( highGasLimit ); + + dev::u256 gasAmountForTx = highGasLimit; + + std::string calldata = "0x4c6f6c22" + dev::toHex( gasAmountForTx ); + + auto startBlockNumber = fixture.client->number(); + + // send a transaction -> BITE2 txn queue should become non-empty + Json::Value txGenerate; + txGenerate["to"] = contractAddress; + txGenerate["gas"] = "1000000"; + txGenerate["data"] = calldata; + txGenerate["from"] = toJS( senderAddress ); + txGenerate["nonce"] = 1; + fixture.rpcClient->eth_sendTransaction( txGenerate ); + + txGenerate["from"] = toJS( senderAddress ); + txGenerate["nonce"] = 2; + fixture.rpcClient->eth_sendTransaction( txGenerate ); + + fixture.rpcClient->debug_pauseConsensus( false ); + + // sleep 50 ms - enough for pendingTransactions() to complete + usleep( 50000 ); + + // stop again to freeze the following pending queue state: 2 CTXs + 1 regular txn + fixture.rpcClient->debug_pauseConsensus( true ); + + while ( fixture.client->number() != startBlockNumber + 1 ) + usleep( 10000 ); + + // sample regular txn + Json::Value txRefill; + txRefill["from"] = toJS( senderAddress ); + txRefill["to"] = "0xc868AF52a6549c773082A334E5AE232e0Ea3B513"; + txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txRefill["gas"] = 30000; + txRefill["nonce"] = 3; + fixture.rpcClient->eth_sendTransaction( txRefill ); + + fixture.rpcClient->debug_pauseConsensus( false ); + + // call mineTransaction to create a block + dev::eth::mineTransaction( *( fixture.client ), 2 ); + + // wait for 3 blocks to appear + auto endBlockNumber = fixture.client->number(); + BOOST_REQUIRE_EQUAL( endBlockNumber, startBlockNumber + 3 ); + + // check two last block - each should contain 1 CTX + // last block also contains a regular txn + auto beforeLastBlock = fixture.client->blockInfo( endBlockNumber - 1 ); + auto lastBlock = fixture.client->blockInfo( endBlockNumber ); + BOOST_REQUIRE_LT( lastBlock.gasUsed(), blockGasLimit ); + BOOST_REQUIRE_LT( beforeLastBlock.gasUsed(), blockGasLimit ); + + auto beforeLastBlockTxns = fixture.client->transactions( endBlockNumber - 1 ); + auto lastBlockTxns = fixture.client->transactions( endBlockNumber ); + BOOST_REQUIRE_EQUAL( beforeLastBlockTxns.size(), 1 ); + BOOST_REQUIRE( beforeLastBlockTxns[0].isCTX() ); + BOOST_REQUIRE_EQUAL( lastBlockTxns.size(), 2 ); + BOOST_REQUIRE( lastBlockTxns[0].isCTX() ); + BOOST_REQUIRE( !lastBlockTxns[1].isCTX() ); + + // check transactions status + auto txnHashes = fixture.client->transactionHashes( endBlockNumber - 1 ); + auto receipt = fixture.rpcClient->eth_getTransactionReceipt( "0x" + txnHashes[0].hex() ); + BOOST_REQUIRE( receipt["status"] == "0x1" ); + + txnHashes = fixture.client->transactionHashes( endBlockNumber ); + BOOST_REQUIRE_EQUAL( txnHashes.size(), 2 ); + for ( const auto& hash: txnHashes ) { + auto receipt = fixture.rpcClient->eth_getTransactionReceipt( "0x" + hash.hex() ); + BOOST_REQUIRE( receipt["status"] == "0x1" ); + } +} + +#endif // BITE + +#ifdef FAIR +BOOST_AUTO_TEST_CASE( getBLSPublicKey ) { + JsonRpcFixture fixture( c_BITEConfigString, false, false, true ); + + Json::Value blsPublicKey = fixture.rpcClient->skale_getBLSPublicKey(); + + BOOST_REQUIRE_EQUAL( blsPublicKey["BLSPublicKey0"], + "15959969554621958245201075983340071881770733084910870228938077786643587385029" ); + BOOST_REQUIRE_EQUAL( blsPublicKey["BLSPublicKey1"], + "7970122607051572307517094692346020360016825923464107614135327251488152616550" ); + BOOST_REQUIRE_EQUAL( blsPublicKey["BLSPublicKey2"], + "3371162264373897025322009434717052197952692496405149486989861571246537813591" ); + BOOST_REQUIRE_EQUAL( blsPublicKey["BLSPublicKey3"], + "13678625751515504401110635369790787716744686498431213713911601759809559919693" ); +} + +BOOST_AUTO_TEST_CASE( dencunOpcodesInConstructor ) { + JsonRpcFixture fixture( c_BITEConfigString, false, false, true ); + + // contract TLoadInConstructor { + + // constructor(uint256 _input) { + // assembly { + // let val := tload(0x0) + // sstore(0x0, val) + // } + // } + // } + + string compiled = + "6080604052348015600e575f5ffd5b505f5c805f555060ac8060205f395ff3fe6080604052348015600e575f5f" + "fd5b50600436106026575f3560e01c80636d619daa14602a575b5f5ffd5b60306044565b604051603b9190605f" + "565b60405180910390f35b5f5481565b5f819050919050565b6059816049565b82525050565b5f602082019050" + "60705f8301846052565b9291505056fea26469706673582212201a73df3522b78621c03ab2198ced2428e80055" + "f4b32dc9b71881cb75acf3788e64736f6c634300081e0033"; + auto senderAddress = fixture.coinbase.address(); + + Json::Value create; + create["from"] = toJS( senderAddress ); + create["code"] = compiled; + create["gas"] = "900000"; + string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + try { + fixture.rpcClient->eth_estimateGas( create, "latest" ); + } catch ( jsonrpc::JsonRpcException& ex ) { + BOOST_CHECK_EQUAL( ex.GetCode(), 3 ); + BOOST_CHECK_EQUAL( ex.GetMessage(), + "Contract uses unsupported Dencun opcode. Please ensure it is compiled for EVM <= " + "Shanghai" ); + } + + auto txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE_EQUAL( txReceipt["status"].asString(), std::string( "0x0" ) ); + BOOST_REQUIRE_EQUAL( txReceipt["revertReason"].asString(), + std::string( "Contract uses unsupported Dencun opcode. Please ensure it is compiled for " + "EVM <= Shanghai" ) ); +} + +BOOST_AUTO_TEST_CASE( dencunOpcodesInTransaction ) { + JsonRpcFixture fixture( c_BITEConfigString, false, false, true ); + + // contract DencunContract { + // uint256 public storedValue; + + // function test(uint256 _input) external { + // assembly { + // tstore(0x0, _input) + + // let val := tload(0x0) + + // sstore(0x0, val) + // } + // } + + // function mcopyTest() public pure returns (uint256) { + // uint256[] memory source = new uint256[](3); + // source[0] = 10; + // source[1] = 20; + // source[2] = 30; + + // uint256[] memory destination = new uint256[](3); + + // assembly { + // let length := mul(3, 32) // 3 elements * 32 bytes each + + // mcopy(destination, add(source, 32), length) + // } + + // return destination[0]; + // } + // } + + string compiled = + "6080604052348015600e575f5ffd5b506102f58061001c5f395ff3fe608060405234801561000f575f5ffd5b50" + "6004361061003f575f3560e01c806325c696111461004357806329e99f07146100615780636d619daa1461007d" + "575b5f5ffd5b61004b61009b565b60405161005891906101f3565b60405180910390f35b61007b600480360381" + "0190610076919061023a565b6101ca565b005b6100856101d6565b60405161009291906101f3565b6040518091" + "0390f35b5f5f600367ffffffffffffffff8111156100b8576100b7610265565b5b604051908082528060200260" + "2001820160405280156100e65781602001602082028036833780820191505090505b509050600a815f81518110" + "6100fe576100fd610292565b5b6020026020010181815250506014816001815181106101205761011f61029256" + "5b5b602002602001018181525050601e8160028151811061014257610141610292565b5b602002602001018181" + "5250505f600367ffffffffffffffff81111561016a57610169610265565b5b6040519080825280602002602001" + "820160405280156101985781602001602082028036833780820191505090505b50905060206003028060208401" + "835e50805f815181106101bb576101ba610292565b5b60200260200101519250505090565b805f5d5f5c805f55" + "5050565b5f5481565b5f819050919050565b6101ed816101db565b82525050565b5f6020820190506102065f83" + "01846101e4565b92915050565b5f5ffd5b610219816101db565b8114610223575f5ffd5b50565b5f8135905061" + "023481610210565b92915050565b5f6020828403121561024f5761024e61020c565b5b5f61025c848285016102" + "26565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000" + "5f52604160045260245ffd5b7f4e487b7100000000000000000000000000000000000000000000000000000000" + "5f52603260045260245ffdfea2646970667358221220879e6b5abbaea0d21b84075bdae00106284ac238ab5826" + "f8e7e6519d744550b464736f6c634300081e0033"; + auto senderAddress = fixture.coinbase.address(); + + Json::Value create; + create["from"] = toJS( senderAddress ); + create["code"] = compiled; + create["gas"] = "900000"; + string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + auto txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + std::string contractAddress = txReceipt["contractAddress"].asString(); + + // Call DencunContract.test(111) + Json::Value sampleTx; + sampleTx["data"] = "0x29e99f07000000000000000000000000000000000000000000000000000000000000006f"; + sampleTx["to"] = contractAddress; + + try { + fixture.rpcClient->eth_estimateGas( sampleTx, "latest" ); + } catch ( jsonrpc::JsonRpcException& ex ) { + BOOST_CHECK_EQUAL( ex.GetCode(), 3 ); + BOOST_CHECK_EQUAL( ex.GetMessage(), + "Contract uses unsupported Dencun opcode. Please ensure it is compiled for EVM <= " + "Shanghai" ); + } + + try { + fixture.rpcClient->eth_call( sampleTx, "latest" ); + } catch ( jsonrpc::JsonRpcException& ex ) { + BOOST_CHECK_EQUAL( ex.GetCode(), 3 ); + BOOST_CHECK_EQUAL( ex.GetMessage(), + "Contract uses unsupported Dencun opcode. Please ensure it is compiled for EVM <= " + "Shanghai" ); + } + + txHash = fixture.rpcClient->eth_sendTransaction( sampleTx ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE_EQUAL( txReceipt["status"].asString(), std::string( "0x0" ) ); + BOOST_REQUIRE_EQUAL( txReceipt["revertReason"].asString(), + std::string( "Contract uses unsupported Dencun opcode. Please ensure it is compiled for " + "EVM <= Shanghai" ) ); + + // Call DencunContract.mcopyTest() + sampleTx["data"] = "0x25c69611"; + txHash = fixture.rpcClient->eth_sendTransaction( sampleTx ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + txReceipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE_EQUAL( txReceipt["status"].asString(), std::string( "0x0" ) ); + BOOST_REQUIRE_EQUAL( txReceipt["revertReason"].asString(), + std::string( "Contract uses unsupported Dencun opcode. Please ensure it is compiled for " + "EVM <= Shanghai" ) ); +} + +#endif // FAIR + +BOOST_AUTO_TEST_CASE( importInvalidBITETransaction ) { + JsonRpcFixture fixture( c_BITEConfigString, false, false, true, true ); + + dev::bite::isCiphertextValidationEnabled = true; + + string senderAddress = toJS( fixture.coinbase.address() ); + size_t nonce = 0; + std::string biteAddress = "0x" + std::string( BITE_ADDRESS_AS_STRING ); + + /// Normal valid BITE transaction -> should not throw + std::string message = + h256::random().hex() + std::string( "5EdF1e852fdD1B0Bc47C0307EF755C76f4B9c251" ); + auto messageBytes = libBLS::ThresholdUtils::hexCStringToBytes( message.c_str() ); + + auto biteInfo = fixture.rpcClient->bite_getCommitteesInfo(); + auto blsPublicKey = biteInfo[0]["commonBLSPublicKey"].asString(); + u256 epochId = biteInfo[0]["epochId"].asUInt64(); + + auto encryptedMessage = libBLS::ThresholdEncryption::encrypt( + messageBytes, libBLS::TEPublicKey( blsPublicKey, libBLS::Base::HEXA ) ); + auto encryptedBytes = encryptedMessage.toBytes(); + + auto dataField = formBITEPayloadRlp( epochId, encryptedBytes ); + + auto validBITETransactionRlp = + formTransactionRlp( fixture, senderAddress, dataField, nonce, biteAddress ); + BOOST_REQUIRE_NO_THROW( fixture.rpcClient->eth_sendRawTransaction( validBITETransactionRlp ) ); + + /// Spoiling the BITE address -> should not throw any excpetion because txn is not + /// BITE-formatted + auto spoiledBiteAddress = + libBLS::ThresholdUtils::hexCStringToBytes( std::string( BITE_ADDRESS_AS_STRING ).c_str() ); + size_t idxToSpoil = rand() % 20; + spoiledBiteAddress[idxToSpoil]++; + std::string spoiledBiteAddressHex = + libBLS::ThresholdUtils::bytesToHexString( spoiledBiteAddress ); + + auto validNonBITETransactionRlp = + formTransactionRlp( fixture, senderAddress, dataField, nonce, spoiledBiteAddressHex ); + BOOST_REQUIRE_NO_THROW( + fixture.rpcClient->eth_sendRawTransaction( validNonBITETransactionRlp ) ); + + /// Provide wrong epochId -> txn is not validated - should throw an exception + auto dataFieldWrongEpochId = formBITEPayloadRlp( epochId + 1, encryptedBytes ); + auto invalidBITETransactionRlp = + formTransactionRlp( fixture, senderAddress, dataFieldWrongEpochId, nonce, biteAddress ); + BOOST_REQUIRE_THROW( + fixture.client->importTransaction( Transaction( + dev::jsToBytes( invalidBITETransactionRlp ), CheckTransaction::None, false ) ), + dev::eth::InvalidBITETransaction ); + BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendRawTransaction( invalidBITETransactionRlp ), + jsonrpc::JsonRpcException ); + + /// No data in the data field -> data is bad formatted - should throw an exception + invalidBITETransactionRlp = + formTransactionRlp( fixture, senderAddress, "", nonce, biteAddress ); + BOOST_REQUIRE_THROW( + fixture.client->importTransaction( Transaction( + dev::jsToBytes( invalidBITETransactionRlp ), CheckTransaction::None, false ) ), + dev::eth::InvalidBITETransaction ); + BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendRawTransaction( invalidBITETransactionRlp ), + jsonrpc::JsonRpcException ); + + RLPStream tooShortRlp; + + /// Only epoch in data field -> data is too short - should throw an exception + tooShortRlp.appendList( 1 ); + tooShortRlp << epochId; + dev::bytes invalidTooShortBITETxnData = tooShortRlp.out(); + invalidBITETransactionRlp = formTransactionRlp( fixture, senderAddress, + dev::toHexPrefixed( invalidTooShortBITETxnData ), nonce, biteAddress ); + BOOST_REQUIRE_THROW( + fixture.client->importTransaction( Transaction( + dev::jsToBytes( invalidBITETransactionRlp ), CheckTransaction::None, false ) ), + dev::eth::InvalidBITETransaction ); + BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendRawTransaction( invalidBITETransactionRlp ), + jsonrpc::JsonRpcException ); + tooShortRlp.clear(); + + /// Only epoch + key -> no data - should throw an exception + encryptedMessage.data = std::make_shared< dev::bytes >(); + tooShortRlp.appendList( 2 ); + tooShortRlp << epochId; + tooShortRlp << encryptedMessage.toBytes(); + invalidTooShortBITETxnData = tooShortRlp.out(); + invalidBITETransactionRlp = formTransactionRlp( fixture, senderAddress, + dev::toHexPrefixed( invalidTooShortBITETxnData ), nonce, biteAddress ); + BOOST_REQUIRE_THROW( + fixture.client->importTransaction( Transaction( + dev::jsToBytes( invalidBITETransactionRlp ), CheckTransaction::None, false ) ), + dev::eth::BITETransactionTooShort ); + BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendRawTransaction( invalidBITETransactionRlp ), + jsonrpc::JsonRpcException ); + + /// Spoiling key part of ciphertext + auto randomEncryptedKeyObj = libBLS::CipheredKey::random(); + randomEncryptedKeyObj.V = encryptedMessage.keys[0].V; + auto randomEncryptedKeyByteArray = randomEncryptedKeyObj.toBytes(); + auto spoiledMessageBytes = encryptedBytes; + // overwrite key part + std::copy( randomEncryptedKeyByteArray.begin(), randomEncryptedKeyByteArray.end(), + spoiledMessageBytes.begin() ); + + RLPStream spoiledBITEDataRlp; + spoiledBITEDataRlp.appendList( 2 ); + spoiledBITEDataRlp << epochId; + spoiledBITEDataRlp << spoiledMessageBytes; + dev::bytes invalidBITETxnData = spoiledBITEDataRlp.out(); + + invalidBITETransactionRlp = formTransactionRlp( + fixture, senderAddress, dev::toHexPrefixed( invalidBITETxnData ), nonce, biteAddress ); + BOOST_REQUIRE_THROW( + fixture.client->importTransaction( Transaction( + dev::jsToBytes( invalidBITETransactionRlp ), CheckTransaction::None, false ) ), + dev::eth::InvalidBITETransaction ); + BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendRawTransaction( invalidBITETransactionRlp ), + jsonrpc::JsonRpcException ); + spoiledBITEDataRlp.clear(); + + /// Encrypted key is not well formed -> should throw exception + randomEncryptedKeyObj.U.setXC0( libBLS::algebra::FqElement::random() ); + randomEncryptedKeyObj.W.setY( libBLS::algebra::FqElement::random() ); + randomEncryptedKeyByteArray = randomEncryptedKeyObj.toBytes(); + std::copy( randomEncryptedKeyByteArray.begin(), randomEncryptedKeyByteArray.end(), + spoiledMessageBytes.begin() ); + + spoiledBITEDataRlp.appendList( 2 ); + spoiledBITEDataRlp << epochId; + spoiledBITEDataRlp << spoiledMessageBytes; + invalidBITETxnData = spoiledBITEDataRlp.out(); + + invalidBITETransactionRlp = formTransactionRlp( + fixture, senderAddress, dev::toHexPrefixed( invalidBITETxnData ), nonce, biteAddress ); + BOOST_REQUIRE_THROW( + fixture.client->importTransaction( Transaction( + dev::jsToBytes( invalidBITETransactionRlp ), CheckTransaction::None, false ) ), + dev::eth::InvalidBITETransaction ); + BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendRawTransaction( invalidBITETransactionRlp ), + jsonrpc::JsonRpcException ); + + // now send BITE txn with multiple epochIds / encryptedAESKeys + libBLS::TEPublicKey publicKey2 = libBLS::TEPublicKey::random(); + u256 epochId2 = epochId + 5; + + encryptedMessage = libBLS::ThresholdEncryption::encrypt( + messageBytes, { libBLS::TEPublicKey( blsPublicKey, libBLS::Base::HEXA ), publicKey2 } ); + auto encryptedBITEDataBytes = encryptedMessage.toBytes(); + + // Create payload with 2 encrypted AES keys + RLPStream bitePayload; + bitePayload.appendList( 2 ); + bitePayload << epochId; + bitePayload << encryptedBITEDataBytes; + + auto rlpBytes = bitePayload.out(); + dev::bytes twoPayloadBITETxnData = dev::bytes( rlpBytes.begin(), rlpBytes.end() ); + + validBITETransactionRlp = formTransactionRlp( + fixture, senderAddress, dev::toHexPrefixed( twoPayloadBITETxnData ), nonce, biteAddress ); + BOOST_REQUIRE_NO_THROW( fixture.rpcClient->eth_sendRawTransaction( validBITETransactionRlp ) ); + + // 3 elements in payload is not allowed + + RLPStream threeElementsPayload; + threeElementsPayload.appendList( 3 ); + threeElementsPayload << epochId; + threeElementsPayload << epochId2; + threeElementsPayload << encryptedBITEDataBytes; + + auto threeElementsRlpBytes = threeElementsPayload.out(); + dev::bytes threeElementsBITETxnData = + dev::bytes( threeElementsRlpBytes.begin(), threeElementsRlpBytes.end() ); + + std::string threeElementsBITETxnRlp = formTransactionRlp( fixture, senderAddress, + dev::toHexPrefixed( threeElementsBITETxnData ), nonce, biteAddress ); + BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendRawTransaction( threeElementsBITETxnRlp ), + jsonrpc::JsonRpcException ); + + // epochId doesn't match and only 1 encrypted AES keys + libBLS::TEPublicKey publicKey3 = libBLS::TEPublicKey::random(); + + auto encryptedMessage1Key = libBLS::ThresholdEncryption::encrypt( messageBytes, publicKey3 ); + auto encryptedBITEDataBytes1Key = encryptedMessage1Key.toBytes(); + + RLPStream mismatchPayload; + mismatchPayload.appendList( 2 ); + mismatchPayload << epochId2; + mismatchPayload << encryptedBITEDataBytes1Key; + + auto mismatchRlpBytes = mismatchPayload.out(); + dev::bytes mismatchBITETxnData = dev::bytes( mismatchRlpBytes.begin(), mismatchRlpBytes.end() ); + + std::string mismatchBITETxnRlp = formTransactionRlp( + fixture, senderAddress, dev::toHexPrefixed( mismatchBITETxnData ), nonce, biteAddress ); + BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendRawTransaction( mismatchBITETxnRlp ), + jsonrpc::JsonRpcException ); + + // 2 encrypted AES keys submitted, but one key is corrupt + auto corruptEncryptedMessage = libBLS::ThresholdEncryption::encrypt( + messageBytes, { libBLS::TEPublicKey( blsPublicKey, libBLS::Base::HEXA ), publicKey2 } ); + + // Corrupt the first key by replacing it with a random one + corruptEncryptedMessage.keys[0] = libBLS::CipheredKey( libBLS::algebra::G2Point::random(), + corruptEncryptedMessage.keys[0].V, libBLS::algebra::G1Point::random() ); + + auto corruptEncryptedBITEDataBytes = corruptEncryptedMessage.toBytes(); + + RLPStream corruptPayload; + corruptPayload.appendList( 2 ); + corruptPayload << epochId; + corruptPayload << corruptEncryptedBITEDataBytes; + + auto corruptRlpBytes = corruptPayload.out(); + dev::bytes corruptBITETxnData = dev::bytes( corruptRlpBytes.begin(), corruptRlpBytes.end() ); + + std::string corruptBITETxnRlp = formTransactionRlp( + fixture, senderAddress, dev::toHexPrefixed( corruptBITETxnData ), nonce, biteAddress ); + BOOST_REQUIRE_THROW( + fixture.rpcClient->eth_sendRawTransaction( corruptBITETxnRlp ), jsonrpc::JsonRpcException ); +} + +BOOST_AUTO_TEST_CASE( BITETransactionCouldNotBeDecrypted ) { + JsonRpcFixture fixture( c_BITEConfigString, false, false, true, true ); + + string senderAddress = toJS( fixture.coinbase.address() ); + + // address 0x7aa5e36aa15e93d10f4f26357c30f052dacdde5f is preset in config + auto balanceBefore = + fixture.rpcClient->eth_getBalance( "0x7aa5e36aa15e93d10f4f26357c30f052dacdde5f", "latest" ); + auto balanceBeforeU256 = dev::jsToU256( balanceBefore ); + BOOST_REQUIRE( + balanceBeforeU256 == dev::u256( dev::bigint( "1000000000000000000000000000000" ) ) ); + + // data must have the destination address and the original message + RLPStream biteDataRlp( 2 ); + biteDataRlp << ( dev::h256::Arith ) h256::random(); + biteDataRlp << ( dev::Address::Arith ) dev::Address( + "0x7aa5e36aa15e93d10f4f26357c30f052dacdde5f" ); + + auto messageBytes = biteDataRlp.out(); + + auto biteInfo = fixture.rpcClient->bite_getCommitteesInfo(); + auto blsPublicKey = biteInfo[0]["commonBLSPublicKey"].asString(); + u256 epochId = biteInfo[0]["epochId"].asUInt64(); + + auto ciphertext = libBLS::ThresholdEncryption::encrypt( + messageBytes, libBLS::TEPublicKey( blsPublicKey, libBLS::Base::HEXA ) ); + auto ciphertextBytes = ciphertext.toBytes(); + + // spoil random element in decryptedData + // only tamper the data part + // | -- Number of keys --| | --- KEY ---- | | --- Data - tamper this part ----| + size_t idxToSpoil = + 1 + libBLS::CipheredKey::CIPHERED_KEY_SIZE_BYTES + + rand() % ( ciphertextBytes.size() - libBLS::CipheredKey::CIPHERED_KEY_SIZE_BYTES ); + ciphertextBytes[idxToSpoil]++; + + auto invalidEncryptedData = libBLS::ThresholdUtils::bytesToHexString( ciphertextBytes ); + + size_t nonce = 0; + + RLPStream bitePayloadRlp( 2 ); + + bitePayloadRlp << epochId; + bitePayloadRlp << ciphertextBytes; + + auto rlpBytes = bitePayloadRlp.out(); + std::string biteAddress = "0x" + std::string( BITE_ADDRESS_AS_STRING ); + std::string txnRlp = formTransactionRlp( fixture, "0x7aa5e36aa15e93d10f4f26357c30f052dacdde5f", + dev::toHexPrefixed( rlpBytes ), nonce, biteAddress ); + + Transaction t( dev::fromHex( txnRlp ), dev::eth::CheckTransaction::None ); + auto minGasRequired = t.baseGasRequired( fixture.client->evmSchedule() ); + + auto gasPrice = fixture.rpcClient->eth_gasPrice(); + auto invalidTxnHash = fixture.rpcClient->eth_sendRawTransaction( txnRlp ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + auto balanceAfter = + fixture.rpcClient->eth_getBalance( "0x7aa5e36aa15e93d10f4f26357c30f052dacdde5f", "latest" ); + BOOST_REQUIRE_EQUAL( + balanceAfter, dev::toJS( balanceBeforeU256 - minGasRequired * dev::jsToU256( gasPrice ) ) ); + + try { + fixture.rpcClient->bite_getDecryptedTransactionData( invalidTxnHash ); + } catch ( const jsonrpc::JsonRpcException& ex ) { + std::string errorMessage = + "Transaction with provided hash does not have any decrypted data associated with it."; + BOOST_REQUIRE( ex.what() == errorMessage ); + } + + auto receipt = fixture.rpcClient->eth_getTransactionReceipt( invalidTxnHash ); + BOOST_REQUIRE( + receipt["revertReason"] == std::string( "Could not decrypt BITE transaction." ) ); +} + + +BOOST_AUTO_TEST_CASE( getDecryptedTransactionData ) { + std::string _config = c_genesisConfigString; + Json::Value ret; + Json::Reader().parse( _config, ret ); + // enable type1 & type2 txs + ret["skaleConfig"]["sChain"]["EIP1559TransactionsPatchTimestamp"] = 1; + // Set chainID = 151 + std::string chainID = "0x97"; + ret["params"]["chainID"] = chainID; +#ifndef FAIR + // set contractStorageLimit + ret["skaleConfig"]["sChain"]["contractStorageLimit"] = 1000000; +#endif + + Json::FastWriter fastWriter; + std::string config = fastWriter.write( ret ); + JsonRpcFixture fixture( + config, true, true, false, false, false, -1, { { "contractStorageLimit", "1000000" } } ); + + dev::eth::simulateMining( *( fixture.client ), 20 ); + string senderAddress = toJS( fixture.coinbase.address() ); + + int nonce = 0; + + // ---- Legacy ----- + Json::Value legacyTx; + + dev::Address originalToAddress( "0x5edf1e852fdd1b0bc47c0307ef755c76f4b9c251" ); + std::string plaintext = + "0x6057361d0000000000000000000000000000000000000000000000000000000000000001"; + std::string encryptedDataPlusToAddressLegacy = dev::toHexPrefixed( + formEncryptedMessageMockup( dev::fromHex( plaintext ), originalToAddress ) ); + + // signal BITE tx + legacyTx["to"] = toJS( "0x" + std::string( BITE_ADDRESS_AS_STRING ) ); + legacyTx["from"] = senderAddress; + legacyTx["gas"] = "100000"; + legacyTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + legacyTx["value"] = "20000000000000000000"; // send all fixture.coinbase.address() balance to + // cover for next calls + legacyTx["data"] = encryptedDataPlusToAddressLegacy; + legacyTx["nonce"] = nonce++; + + TransactionSkeleton legacyTs = toTransactionSkeleton( legacyTx ); + legacyTs = fixture.client->populateTransactionWithDefaults( legacyTs ); + pair< bool, Secret > legacyAr = fixture.accountHolder->authenticate( legacyTs ); + Transaction legacyTransaction( legacyTs, legacyAr.second ); + + std::string legacyRLP = dev::toHexPrefixed( legacyTransaction.toBytes() ); + std::string legacyHash = fixture.rpcClient->eth_sendRawTransaction( legacyRLP ); + + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + auto legacyTxReceipt = fixture.rpcClient->eth_getTransactionReceipt( legacyHash ); + BOOST_REQUIRE( legacyTxReceipt["status"].asString() == std::string( "0x1" ) ); + BOOST_REQUIRE( + legacyTxReceipt["blockNumber"].asString() == fixture.rpcClient->eth_blockNumber() ); + BOOST_REQUIRE( legacyTxReceipt["to"].asString() == "0x" + originalToAddress.hex() ); + + auto legacyEncryptedResponse = fixture.rpcClient->eth_getTransactionByHash( legacyHash ); + BOOST_REQUIRE( + legacyEncryptedResponse["input"].asString() == encryptedDataPlusToAddressLegacy ); + + auto legacyDecryptedResponse = + fixture.rpcClient->bite_getDecryptedTransactionData( legacyHash ); + BOOST_REQUIRE( legacyDecryptedResponse["data"] == plaintext ); + BOOST_REQUIRE( legacyDecryptedResponse["to"] == "0x" + originalToAddress.hex() ); + + // ---- Type1 tx ----- + /* + transaction1['nonce'] = 0 + transaction1['gasPrice'] = 20000000000 + transaction1['gas'] = 80000 + transaction1['to'] = 0xc868af52a6549c773082a334e5ae232e0ea3b513 + transaction1['value'] = 0 + transaction1['chainId'] = 151 + transaction1['type'] = 1 + transaction1['data'] = call to SC + */ + std::string originalToAddressType1 = "c868af52a6549c773082a334e5ae232e0ea3b513"; + // data ciphered from a single run of formEncryptedMessageMockup( plaintext, originalToAddress ) + // since it differs each run, and the RLP-encoded tx was built outside this test case (via an + // external script), we need to set this manually Note that the encryptedData includes the 'To' + // address already + std::string encryptedDataPlusToAddressType1 = + "0xf9015d80b901590192084354e0f043e108c255d159de7360e5a972bacdbaf3257420f66478d79b9300000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "00000000000000005b87049973afc70916c3588f2e5bcdd65acdc73f544d201979b4ce8307815fda7281e03240" + "2b0e1d82ccc830046e5de0c7a2e8f9fd4ea6dcd9e85230a5f278373f5c873b1ed1bae995c74899927c92b8e2b4" + "1af3adfba46def6b857a4e74b7595e2bb9c84773ba4a1167fc73bd17ca65334d12eaf9401897"; + std::string type1Tx = + "0x01f901ca8197808504a817c800830138809442495445204d452049274d20454e43525950544480b90160f901" + "5d80b901590192084354e0f043e108c255d159de7360e5a972bacdbaf3257420f66478d79b9300000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "00000000005b87049973afc70916c3588f2e5bcdd65acdc73f544d201979b4ce8307815fda7281e032402b0e1d" + "82ccc830046e5de0c7a2e8f9fd4ea6dcd9e85230a5f278373f5c873b1ed1bae995c74899927c92b8e2b41af3ad" + "fba46def6b857a4e74b7595e2bb9c84773ba4a1167fc73bd17ca65334d12eaf9401897c001a05b144ba5643c7f" + "f31cfefdeaf4043e222c0c32f5c849c21598f89e82abdea07fa048762844d57807403777d655dec56623026675" + "9e173c187e4cecebfa4579ea66"; + + std::string type1Hash = fixture.rpcClient->eth_sendRawTransaction( type1Tx ); + + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + auto type1TxReceipt = fixture.rpcClient->eth_getTransactionReceipt( type1Hash ); + BOOST_REQUIRE( type1TxReceipt["status"].asString() == std::string( "0x1" ) ); + BOOST_REQUIRE( + type1TxReceipt["blockNumber"].asString() == fixture.rpcClient->eth_blockNumber() ); + BOOST_REQUIRE( type1TxReceipt["to"].asString() == "0x" + originalToAddressType1 ); + + auto type1EncryptedResponse = fixture.rpcClient->eth_getTransactionByHash( type1Hash ); + BOOST_REQUIRE( type1EncryptedResponse["input"].asString() == encryptedDataPlusToAddressType1 ); + + auto type1DecryptedResponse = fixture.rpcClient->bite_getDecryptedTransactionData( type1Hash ); + BOOST_REQUIRE( type1DecryptedResponse["data"] == plaintext ); + BOOST_REQUIRE( type1DecryptedResponse["to"] == "0x" + originalToAddressType1 ); + + // ---- Type2 tx ----- + /* + transaction1['nonce'] = 1 + transaction1['gas'] = 80000 + transaction1['maxFeePerGas'] = 20000000000 + transaction1['maxPriorityFeePerGas'] = 20000000000 - 1 + transaction1['to'] = 0xc868AF52a6549c773082A334E5AE232e0Ea3B513 + transaction1['value'] = 0 + transaction1['chainId'] = 151 + transaction1['type'] = 2 + transaction1['data'] = encryptedData + */ + + std::string originalToAddressType2 = originalToAddressType1; + std::string encryptedDataPlusToAddressType2 = encryptedDataPlusToAddressType1; + std::string type2Tx = + "0x02f901d08197018504a817c7ff8504a817c800830138809442495445204d452049274d20454e435259505444" + "80b90160f9015d80b901590192084354e0f043e108c255d159de7360e5a972bacdbaf3257420f66478d79b9300" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000005b87049973afc70916c3588f2e5bcdd65acdc73f544d201979b4ce8307815fda7281" + "e032402b0e1d82ccc830046e5de0c7a2e8f9fd4ea6dcd9e85230a5f278373f5c873b1ed1bae995c74899927c92" + "b8e2b41af3adfba46def6b857a4e74b7595e2bb9c84773ba4a1167fc73bd17ca65334d12eaf9401897c080a0c8" + "512955420b554abcde1ea13d67bef9a38bf541938a8b915c514722821481f2a03f3ca19e2513078f058462c622" + "bd07ea0b6f15b5bc28998bcc79c59c3c0400db"; + std::string type2Hash = fixture.rpcClient->eth_sendRawTransaction( type2Tx ); + + + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + auto type2TxReceipt = fixture.rpcClient->eth_getTransactionReceipt( type2Hash ); + BOOST_REQUIRE( type2TxReceipt["status"].asString() == std::string( "0x1" ) ); + BOOST_REQUIRE( + type2TxReceipt["blockNumber"].asString() == fixture.rpcClient->eth_blockNumber() ); + BOOST_REQUIRE( type2TxReceipt["to"].asString() == "0x" + originalToAddressType2 ); + + auto type2EncryptedResponse = fixture.rpcClient->eth_getTransactionByHash( type2Hash ); + BOOST_REQUIRE( type2EncryptedResponse["input"].asString() == encryptedDataPlusToAddressType2 ); + + auto type2DecryptedResponse = fixture.rpcClient->bite_getDecryptedTransactionData( type2Hash ); + BOOST_REQUIRE( type2DecryptedResponse["data"] == plaintext ); + BOOST_REQUIRE( type2DecryptedResponse["to"] == "0x" + originalToAddressType2 ); + + + // pragma solidity >=0.8.2 <0.9.0; + + // /** + // * @title Storage + // * @dev Store & retrieve value in a variable + // * @custom:dev-run-script ./scripts/deploy_with_ethers.ts + // */ + // contract Storage { + + // uint256 number; + // uint256 number1; + // uint256 number2; + + // /** + // * @dev Store value in variable + // * @param num value to store + // */ + // function store(uint256 num) public { + // number = num; + // number1 = num; + // number2 = num; + // } + + // /** + // * @dev Return value + // * @return value of 'number' + // */ + // function retrieve() public view returns (uint256){ + // return number; + // } + // } + string bytecode = + "608060405234801561001057600080fd5b50610155806100206000396000f3fe60806040523" + "4801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b57" + "80636057361d14610059575b600080fd5b610043610075565b60405161005091906100e3565" + "b60405180910390f35b610073600480360381019061006e91906100ab565b61007e565b005b" + "60008054905090565b80600081905550806001819055508060028190555050565b600081359" + "0506100a581610108565b92915050565b6000602082840312156100bd57600080fd5b600061" + "00cb84828501610096565b91505092915050565b6100dd816100fe565b82525050565b60006" + "020820190506100f860008301846100d4565b92915050565b6000819050919050565b610111" + "816100fe565b811461011c57600080fd5b5056fea2646970667358221220edbb1123b5e4538" + "463747d4497720f4c0b79ff718b7bf245e6ba81dc37dc1a0364736f6c63430008040033"; + + Json::Value create; + create["from"] = toJS( senderAddress ); + create["data"] = bytecode; // SC creation goes in plaintext + create["gas"] = "180000"; + std::string txHash = fixture.rpcClient->eth_sendTransaction( create ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( receipt["status"] == string( "0x1" ) ); + + std::string contractAddress = receipt["contractAddress"].asString(); + std::string contractAddressWithout0x = contractAddress.substr( 2 ); + + // verify state is empty + Json::Value call; + call["to"] = contractAddress; + call["data"] = "0x2e64cec1"; + call["from"] = toJS( senderAddress ); + BOOST_REQUIRE( u256( 0 ) == dev::jsToU256( fixture.rpcClient->eth_call( call, "latest" ) ) ); + + string dataStore1 = "6057361d0000000000000000000000000000000000000000000000000000000000000001"; + string dataStoreInvalid = + "6057361e0000000000000000000000000000000000000000000000000000000000000001"; + + // send txn to change state + Json::Value store1; + store1["to"] = toJS( "0x" + std::string( BITE_ADDRESS_AS_STRING ) ); + store1["data"] = dev::toHexPrefixed( formEncryptedMessageMockup( + dev::fromHex( dataStore1 ), dev::Address( contractAddressWithout0x ) ) ); + store1["from"] = toJS( senderAddress ); + store1["gasPrice"] = fixture.rpcClient->eth_gasPrice(); +#ifdef FAIR + store1["gas"] = "200000"; // EIP-2929: need more gas for cold access costs +#else + store1["gas"] = "111000"; +#endif + txHash = fixture.rpcClient->eth_sendTransaction( store1 ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( receipt["status"] == std::string( "0x1" ) ); + + // check that previous txn changed the state + call["to"] = contractAddress; + call["data"] = "0x2e64cec1"; + call["from"] = toJS( senderAddress ); + BOOST_REQUIRE( u256( 1 ) == dev::jsToU256( fixture.rpcClient->eth_call( call, "latest" ) ) ); + + // send invalid call to the contract - txn should fail + Json::Value txInvalidContractCall; + txInvalidContractCall["to"] = toJS( "0x" + std::string( BITE_ADDRESS_AS_STRING ) ); + txInvalidContractCall["data"] = dev::toHexPrefixed( formEncryptedMessageMockup( + dev::fromHex( dataStoreInvalid ), dev::Address( contractAddressWithout0x ) ) ); + txInvalidContractCall["from"] = toJS( senderAddress ); + txInvalidContractCall["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txHash = fixture.rpcClient->eth_sendTransaction( txInvalidContractCall ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( receipt["status"] == std::string( "0x0" ) ); +} + +#ifdef FAIR +BOOST_AUTO_TEST_CASE( committeeRotation ) { + std::string _config = c_BITECommitteeRotationConfigString; + Json::Value ret; + Json::Reader().parse( _config, ret ); + + auto firstGroupObject = ret["skaleConfig"]["sChain"]["nodes"]["1"]; + auto secondGroupObject = ret["skaleConfig"]["sChain"]["nodes"]["-1"]; + + std::array< std::string, 4 > firstGroupCommonPublicKey; + firstGroupCommonPublicKey[0] = firstGroupObject["blsKey"]["commonBLSPublicKey0"].asString(); + firstGroupCommonPublicKey[1] = firstGroupObject["blsKey"]["commonBLSPublicKey1"].asString(); + firstGroupCommonPublicKey[2] = firstGroupObject["blsKey"]["commonBLSPublicKey2"].asString(); + firstGroupCommonPublicKey[3] = firstGroupObject["blsKey"]["commonBLSPublicKey3"].asString(); + + std::array< std::string, 4 > secondGroupCommonPublicKey; + secondGroupCommonPublicKey[0] = secondGroupObject["blsKey"]["commonBLSPublicKey0"].asString(); + secondGroupCommonPublicKey[1] = secondGroupObject["blsKey"]["commonBLSPublicKey1"].asString(); + secondGroupCommonPublicKey[2] = secondGroupObject["blsKey"]["commonBLSPublicKey2"].asString(); + secondGroupCommonPublicKey[3] = secondGroupObject["blsKey"]["commonBLSPublicKey3"].asString(); + + BOOST_REQUIRE( firstGroupCommonPublicKey != secondGroupCommonPublicKey ); + + ret["skaleConfig"]["sChain"]["nodes"].clear(); + + auto currentTime = time( nullptr ); + auto firstGroupTs = currentTime; + auto secondGroupTs = firstGroupTs + 10; + + ret["skaleConfig"]["sChain"]["nodes"][std::to_string( firstGroupTs )] = firstGroupObject; + ret["skaleConfig"]["sChain"]["nodes"][std::to_string( secondGroupTs )] = secondGroupObject; + + ret["skaleConfig"]["sChain"]["nodeGroups"]["0"]["finish_ts"] = secondGroupTs; + + auto blsPublicKeyStringToStringArray = []( const std::string& publicKeyStr ) { + libBLS::TEPublicKey publicKey( publicKeyStr, libBLS::Base::HEXA ); + auto rawPublicKey = publicKey.getPublicKeyRaw(); + return rawPublicKey.toStringArray( libBLS::Base::DEC ); + }; + + Json::FastWriter fastWriter; + std::string config = fastWriter.write( ret ); + JsonRpcFixture fixture( config, false, false, true ); + + Json::Value txRefill; + txRefill["to"] = "0xc868AF52a6549c773082A334E5AE232e0Ea3B513"; + txRefill["from"] = toJS( fixture.coinbase.address() ); + txRefill["gas"] = "100000"; + txRefill["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + txRefill["value"] = 100000000000000000; + string txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + auto receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( receipt["status"] == std::string( "0x1" ) ); + + auto latestBlockTs = fixture.client->blockChain().info().timestamp(); + BOOST_REQUIRE( latestBlockTs < secondGroupTs && latestBlockTs > firstGroupTs ); + BOOST_REQUIRE( + fixture.client->chainParams().getCommonBlsPublicKey() == firstGroupCommonPublicKey ); + BOOST_REQUIRE( fixture.client->isCommitteeRotationSoon() ); + + auto biteInfo = fixture.rpcClient->bite_getCommitteesInfo(); + BOOST_REQUIRE( biteInfo.isArray() ); + BOOST_REQUIRE_EQUAL( biteInfo.size(), 2 ); + BOOST_REQUIRE( + blsPublicKeyStringToStringArray( biteInfo[0]["commonBLSPublicKey"].asString() ) == + firstGroupCommonPublicKey ); + BOOST_REQUIRE_EQUAL( biteInfo[0]["epochId"].asUInt64(), 0 ); + BOOST_REQUIRE( + blsPublicKeyStringToStringArray( biteInfo[1]["commonBLSPublicKey"].asString() ) == + secondGroupCommonPublicKey ); + BOOST_REQUIRE_EQUAL( biteInfo[1]["epochId"].asUInt64(), 1 ); + + while ( latestBlockTs++ < secondGroupTs ) + sleep( 1 ); + + txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( receipt["status"] == std::string( "0x1" ) ); + + BOOST_REQUIRE( latestBlockTs >= secondGroupTs ); + BOOST_REQUIRE( + fixture.client->chainParams().getCommonBlsPublicKey() == secondGroupCommonPublicKey ); + + biteInfo = fixture.rpcClient->bite_getCommitteesInfo(); + BOOST_REQUIRE_EQUAL( biteInfo.size(), 1 ); + BOOST_REQUIRE( + blsPublicKeyStringToStringArray( biteInfo[0]["commonBLSPublicKey"].asString() ) == + secondGroupCommonPublicKey ); + BOOST_REQUIRE_EQUAL( biteInfo[0]["epochId"].asUInt64(), 1 ); + BOOST_REQUIRE( !fixture.client->isCommitteeRotationSoon() ); + + // HACK: currently on committee rotation skaled calls exitGracefully in consensus + // it interferes with exit procedure + // put sleep here to avoid collisions + sleep( 10 ); + + txHash = fixture.rpcClient->eth_sendTransaction( txRefill ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE( receipt["status"] == std::string( "0x1" ) ); +} + + +BOOST_AUTO_TEST_CASE( fetchingBlockRewardBeneficiary ) { + std::string config = c_BITECommitteeRotationConfigString; + Json::Value ret; + Json::Reader().parse( config, ret ); + + Json::FastWriter fastWriter; + config = fastWriter.write( ret ); + JsonRpcFixture fixture( config, false, false, true ); + + Address rewardWalletAddress = + fixture.client->chainParams().getNodeBeneficiaryInHistoricGroup( 0, 1 ); + BOOST_REQUIRE( rewardWalletAddress == Address( "0x08151B8F80bfa7dEa760e461412AF24348224edf" ) ); + rewardWalletAddress = fixture.client->chainParams().getNodeBeneficiaryInHistoricGroup( 1, 1 ); + BOOST_REQUIRE( rewardWalletAddress == Address( "0x405c96D388cDFBa4f17493c875CCE9c680225276" ) ); +} + +BOOST_AUTO_TEST_CASE( block_author_balance ) { + // when rewardWalletAddress is not defined + + // for testBlockRewardsActivationPatchAddress + setenv( "TEST_BLOCK_REWARDS_ACTIVATION", "1", 1 ); + + std::string _config = c_genesisConfigString; + Json::Value ret; + Json::Reader().parse( _config, ret ); + // Set FAIR chainID + std::string chainID = "0x3a6"; + ret["params"]["chainID"] = chainID; + // disable block rewards at startup + ret["params"]["blockReward"] = "0x00"; + + Json::FastWriter fastWriter; + std::string config = fastWriter.write( ret ); + JsonRpcFixture fixture( config, false, false, true ); + + string etherbase = fixture.rpcClient->eth_coinbase(); + + BOOST_REQUIRE( !BlockRewardsActivationPatch::isEnabled( fixture.client->chainId() ) ); + + // checksumed address: 0x0E7d7F1D34a502bD609542576941C3FCc087c588 + auto node_owner = "0x0e7d7f1d34a502bd609542576941c3fcc087c588"; + + auto etherbase_address = jsToAddress( etherbase ); + + u256 etherbaseBalance = fixture.client->balanceAt( etherbase_address ); + BOOST_REQUIRE_EQUAL( etherbaseBalance, 0 ); + + dev::Address stakingContractAddress = fixture.client->chainParams().getStakingContractAddress(); + BOOST_REQUIRE_EQUAL( fixture.client->balanceAt( stakingContractAddress ), 0 ); + + // mine transaction not from testBlockRewardsActivationPatchAddress - block rewards should stay + // disabled + Json::Value silentTx; + silentTx["value"] = 1; + // address has preset balance in config + // silentTx["from"] = dev::Address( "0x5C4e11842E8be09264dc1976943571d7Af6d00F9" ).hex(); + silentTx["to"] = BlockRewardsActivationPatch::getMagicAddress().hex(); + silentTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + silentTx["gas"] = 30000; + silentTx["nonce"] = 0; + + auto silentTs = toTransactionSkeleton( silentTx ); + auto silentT = dev::eth::Transaction( silentTs, + dev::Secret( "1c2cd4b70c2b8c6cd7144bbbfbd1e5c6eacb4a5efd9c86d0e29cbbec4e8483b9" ) ); + + std::string txHash = + fixture.rpcClient->eth_sendRawTransaction( dev::toHex( silentT.toBytes() ) ); + BOOST_REQUIRE( !txHash.empty() ); + + dev::eth::mineTransaction( *( fixture.client ), 1 ); + BOOST_REQUIRE( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"] == "0x1" ); + BOOST_REQUIRE( !BlockRewardsActivationPatch::isEnabled( fixture.client->chainId() ) ); + // staking contract balance only gets changed when block rewards are activated + BOOST_REQUIRE_EQUAL( fixture.client->balanceAt( stakingContractAddress ), 0 ); + etherbaseBalance = fixture.client->balanceAt( etherbase_address ); + BOOST_REQUIRE_EQUAL( etherbaseBalance, 0 ); + + // mine transaction from testBlockRewardsActivationPatchAddress - block rewards should enable + Json::Value activationTx; + // activationTx["from"] = "0x5339Ef05428d1b87f4e2F2db64E782c68E9cDA56"; + activationTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + activationTx["gas"] = 30000; + activationTx["chainId"] = "0x3a9"; + activationTx["nonce"] = 0; + activationTx["to"] = dev::Address::random().hex(); + + auto ts = toTransactionSkeleton( activationTx ); + auto t = dev::eth::Transaction( + ts, dev::Secret( "0e394ff21db60660a27a6383aedf8c75070648965acbef7c369c1bae2141a485" ) ); + + txHash = fixture.rpcClient->eth_sendRawTransaction( dev::toHex( t.toBytes() ) ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + BOOST_REQUIRE( fixture.rpcClient->eth_getTransactionReceipt( txHash )["status"] == "0x1" ); + BOOST_REQUIRE( BlockRewardsActivationPatch::isEnabled( fixture.client->chainId() ) ); + etherbaseBalance = fixture.client->balanceAt( etherbase_address ); + BOOST_REQUIRE_EQUAL( etherbaseBalance, 0 ); + BOOST_REQUIRE_EQUAL( fixture.client->balanceAt( stakingContractAddress ), 0 ); + + etherbaseBalance = fixture.client->balanceAt( jsToAddress( etherbase ) ); + + auto authorInitialBalance = + fixture.client->balanceAt( jsToAddress( "0x0E7d7F1D34a502bD609542576941C3FCc087c588" ) ); + auto stakingContractInitialBalance = fixture.client->balanceAt( stakingContractAddress ); + + auto initialBlockNumber = jsToU256( fixture.rpcClient->eth_blockNumber() ); + + // push random transaction, check balance difference + Json::Value sampleTx; + sampleTx["value"] = 1000000; + sampleTx["data"] = toJS( bytes() ); + sampleTx["from"] = fixture.coinbase.address().hex(); + sampleTx["to"] = fixture.account2.address().hex(); + sampleTx["gasPrice"] = 1000000000000; + txHash = fixture.rpcClient->eth_sendTransaction( sampleTx ); + BOOST_REQUIRE( !txHash.empty() ); + + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + fixture.client->state().getOriginalDb()->createBlockSnap( 2 ); + BOOST_REQUIRE_EQUAL( fixture.client->balanceAt( fixture.account2.address() ), u256( 1000000 ) ); + + auto txData = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + + auto blockNumAsString = fixture.rpcClient->eth_blockNumber(); + + auto author = fixture.rpcClient->eth_getBlockByNumber( blockNumAsString, false )["author"]; + auto blockNumber = jsToU256( blockNumAsString ); + + BOOST_REQUIRE( author == node_owner ); + + auto totalReward = fixture.client->chainParams().blockReward( + fixture.client->latestBlock().info().timestamp(), fixture.client->number() ); + auto blockAuthorReward = dev::calculateShareWithPrecision( + totalReward, fixture.client->evmSchedule().shareOfBlockRewardToBlockAuthorPromille ); + auto stakingContractReward = totalReward - blockAuthorReward; + + auto feeForTx = + jsToU256( sampleTx["gasPrice"].asString() ) * jsToU256( txData["gasUsed"].asString() ); + feeForTx = dev::calculateShareWithPrecision( + feeForTx, fixture.client->evmSchedule().shareOfTransactionFeeToRewardPromille ); + + auto expectedAuthorBalanceChange = + ( blockNumber - initialBlockNumber ) * blockAuthorReward + feeForTx; + auto expectedContractBalanceChange = + ( blockNumber - initialBlockNumber ) * stakingContractReward; + + BOOST_REQUIRE_EQUAL( + fixture.client->balanceAt( jsToAddress( author.asString() ) ) - authorInitialBalance, + expectedAuthorBalanceChange ); + BOOST_REQUIRE_EQUAL( + fixture.client->balanceAt( stakingContractAddress ) - stakingContractInitialBalance, + expectedContractBalanceChange ); +} + +BOOST_AUTO_TEST_CASE( block_author_balance_reward_wallet ) { + // when rewardWalletAddress is defined + + // checksumed address: 0xfa3fe33E351a7c60039E59D923e417A6362D1C3E + auto node_reward_wallet = "0xfa3fe33e351a7c60039e59d923e417a6362d1c3e"; + auto node_reward_wallet_address = jsToAddress( node_reward_wallet ); + + nlohmann::json configJson = nlohmann::json::parse( c_BITECommitteeRotationConfigString ); + // configJson["skaleConfig"]["sChain"]["nodeGroups"]["0"]["nodes"]["8"][3] = node_reward_wallet; + configJson["skaleConfig"]["sChain"]["nodeGroups"]["1"]["nodes"]["8"][3] = node_reward_wallet; + // configJson["skaleConfig"]["sChain"]["node"]["1"]["group"][0]["rewardWalletAddress"] = + // node_reward_wallet; + + auto noRewardWalletAddressConfig = configJson.dump(); + JsonRpcFixture fixture( noRewardWalletAddressConfig, false, false, true ); + + auto authorInitialBalance = fixture.client->balanceAt( node_reward_wallet_address ); + + auto initialBlockNumber = jsToU256( fixture.rpcClient->eth_blockNumber() ); + + // mine block without transactions + dev::eth::simulateMining( *( fixture.client ), 1 ); + sleep( 3 ); + + // mine transaction + Json::Value sampleTx; + sampleTx["value"] = 1000000; + sampleTx["data"] = toJS( bytes() ); + sampleTx["from"] = fixture.coinbase.address().hex(); + sampleTx["to"] = fixture.account2.address().hex(); + sampleTx["gasPrice"] = 1000000000000; + std::string txHash = fixture.rpcClient->eth_sendTransaction( sampleTx ); + BOOST_REQUIRE( !txHash.empty() ); + + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + fixture.client->state().getOriginalDb()->createBlockSnap( 2 ); + BOOST_REQUIRE_EQUAL( fixture.client->balanceAt( fixture.account2.address() ), u256( 1000000 ) ); + + auto txData = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + + auto blockNumAsString = fixture.rpcClient->eth_blockNumber(); + + auto author = fixture.rpcClient->eth_getBlockByNumber( blockNumAsString, false )["author"]; + auto blockNumber = jsToU256( blockNumAsString ); + BOOST_REQUIRE( author == node_reward_wallet ); + + auto totalReward = fixture.client->chainParams().blockReward( + fixture.client->latestBlock().info().timestamp(), fixture.client->number() ); + auto blockAuthorReward = dev::calculateShareWithPrecision( + totalReward, fixture.client->evmSchedule().shareOfBlockRewardToBlockAuthorPromille ); + + auto feeForTx = + jsToU256( sampleTx["gasPrice"].asString() ) * jsToU256( txData["gasUsed"].asString() ); + feeForTx = dev::calculateShareWithPrecision( + feeForTx, fixture.client->evmSchedule().shareOfTransactionFeeToRewardPromille ); + auto expectedBalanceChange = + ( blockNumber - initialBlockNumber ) * blockAuthorReward + feeForTx; + + BOOST_REQUIRE_EQUAL( + fixture.client->balanceAt( jsToAddress( author.asString() ) ) - authorInitialBalance, + expectedBalanceChange ); +} +#endif // FAIR + +#endif // #ifdef BITE + +#ifndef FAIR +BOOST_AUTO_TEST_CASE( etherbase_generation2 ) { + JsonRpcFixture fixture( c_genesisGeneration2ConfigString, false, false, true ); + string etherbase = fixture.rpcClient->eth_coinbase(); + + u256 etherbaseBalance = fixture.client->balanceAt( jsToAddress( etherbase ) ); + + // mine block without transactions + dev::eth::simulateMining( *( fixture.client ), 1 ); + sleep( 3 ); + etherbaseBalance = fixture.client->balanceAt( jsToAddress( etherbase ) ); + BOOST_REQUIRE_GT( etherbaseBalance, 0 ); + + // mine transaction + Json::Value sampleTx; + sampleTx["value"] = 1000000; + sampleTx["data"] = toJS( bytes() ); + sampleTx["from"] = fixture.coinbase.address().hex(); + sampleTx["to"] = fixture.account2.address().hex(); + sampleTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + std::string txHash = fixture.rpcClient->eth_sendTransaction( sampleTx ); + BOOST_REQUIRE( !txHash.empty() ); + dev::eth::mineTransaction( *( fixture.client ), 2 ); + fixture.client->state().getOriginalDb()->createBlockSnap( 2 ); + BOOST_REQUIRE_EQUAL( fixture.client->balanceAt( fixture.account2.address() ), u256( 1000000 ) ); + + // partially retrieve 1000000 + etherbaseBalance = fixture.client->balanceAt( jsToAddress( etherbase ) ); + u256 balance = + fixture.client->balanceAt( jsToAddress( "0x7aa5E36AA15E93D10F4F26357C30F052DacDde5F" ) ); + + Json::Value partiallyRetrieveTx; + partiallyRetrieveTx["data"] = + "0xc6427474000000000000000000000000d2c0deface0000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000006000000000000000000000000000000000000000000000000000000000000000e4b61d" + "27f6000000000000000000000000d2ba3e00000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "00000000000000600000000000000000000000000000000000000000000000000000000000000044204a3e9300" + "00000000000000000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f0000000000000000000000000000" + "0000000000000000000000000000000f4240000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000"; + partiallyRetrieveTx["from"] = "0x5C4e11842E8be09264dc1976943571d7Af6d00F9"; + partiallyRetrieveTx["to"] = "0xD244519000000000000000000000000000000000"; + partiallyRetrieveTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + partiallyRetrieveTx["gas"] = toJS( "1000000" ); + txHash = fixture.rpcClient->eth_sendTransaction( partiallyRetrieveTx ); + BOOST_REQUIRE( !txHash.empty() ); + dev::eth::mineTransaction( *( fixture.client ), 2 ); + + fixture.client->state().getOriginalDb()->createBlockSnap( 3 ); + auto t = fixture.rpcClient->eth_getTransactionReceipt( txHash ); +#ifdef FAIR + // reward goes to the node owner, not etherbase + BOOST_REQUIRE_EQUAL( + fixture.client->balanceAt( jsToAddress( etherbase ) ), etherbaseBalance - u256( 1000000 ) ); +#else + BOOST_REQUIRE_EQUAL( fixture.client->balanceAt( jsToAddress( etherbase ) ), + etherbaseBalance + + jsToU256( t["gasUsed"].asString() ) * + jsToU256( partiallyRetrieveTx["gasPrice"].asString() ) - + u256( 1000000 ) ); +#endif + BOOST_REQUIRE_EQUAL( + fixture.client->balanceAt( jsToAddress( "0x7aa5E36AA15E93D10F4F26357C30F052DacDde5F" ) ), + balance + u256( 1000000 ) ); + + // retrieve all + u256 oldEtherbaseBalance = fixture.client->balanceAt( jsToAddress( etherbase ) ); + balance = + fixture.client->balanceAt( jsToAddress( "0x7aa5E36AA15E93D10F4F26357C30F052DacDde5F" ) ); + + Json::Value retrieveTx; + retrieveTx["data"] = + "0xc6427474000000000000000000000000d2c0deface0000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000006000000000000000000000000000000000000000000000000000000000000000c4b61d" + "27f6000000000000000000000000d2ba3e00000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000006000000000000000000000000000000000000000000000000000000000000000240a79309b00" + "00000000000000000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f0000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + retrieveTx["from"] = "0x5C4e11842E8be09264dc1976943571d7Af6d00F9"; + retrieveTx["to"] = "0xD244519000000000000000000000000000000000"; + retrieveTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + retrieveTx["gas"] = toJS( "1000000" ); + txHash = fixture.rpcClient->eth_sendTransaction( retrieveTx ); + BOOST_REQUIRE( !txHash.empty() ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + fixture.client->state().getOriginalDb()->createBlockSnap( 4 ); + t = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + etherbaseBalance = fixture.client->balanceAt( jsToAddress( etherbase ) ); +#ifdef FAIR + // reward goes to the node owner, not etherbase + BOOST_REQUIRE_EQUAL( etherbaseBalance, 0 ); +#else + BOOST_REQUIRE_EQUAL( + etherbaseBalance, jsToU256( t["gasUsed"].asString() ) * + jsToU256( partiallyRetrieveTx["gasPrice"].asString() ) ); +#endif + BOOST_REQUIRE_EQUAL( + fixture.client->balanceAt( jsToAddress( "0x7aa5E36AA15E93D10F4F26357C30F052DacDde5F" ) ), + balance + oldEtherbaseBalance ); +} + +BOOST_AUTO_TEST_CASE( deploy_controller_generation2 ) { + JsonRpcFixture fixture( c_genesisGeneration2ConfigString, false, false, true ); + + Json::Value hasRoleBeforeGrantingCall; + hasRoleBeforeGrantingCall["data"] = + "0x91d14854fc425f2263d0df187444b70e47283d622c70181c5baebb1306a01edba1ce184c0000000000000000" + "000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f"; + hasRoleBeforeGrantingCall["to"] = "0xD2002000000000000000000000000000000000d2"; + BOOST_REQUIRE( + jsToInt( fixture.rpcClient->eth_call( hasRoleBeforeGrantingCall, "latest" ) ) == 0 ); + + string compiled = + "6080604052341561000f57600080fd5b60b98061001d6000396000f300" + "608060405260043610603f576000357c01000000000000000000000000" + "00000000000000000000000000000000900463ffffffff168063b3de64" + "8b146044575b600080fd5b3415604e57600080fd5b606a600480360381" + "019080803590602001909291905050506080565b604051808281526020" + "0191505060405180910390f35b60006007820290509190505600a16562" + "7a7a72305820f294e834212334e2978c6dd090355312a3f0f9476b8eb9" + "8fb480406fc2728a960029"; + + Json::Value deployContractWithoutRoleTx; + deployContractWithoutRoleTx["from"] = "0x7aa5e36aa15e93d10f4f26357c30f052dacdde5f"; + deployContractWithoutRoleTx["code"] = compiled; + deployContractWithoutRoleTx["gas"] = "1000000"; + deployContractWithoutRoleTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + + string txHash = fixture.rpcClient->eth_sendTransaction( deployContractWithoutRoleTx ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x0" ) ); + Json::Value code = + fixture.rpcClient->eth_getCode( receipt["contractAddress"].asString(), "latest" ); + BOOST_REQUIRE( code.asString() == "0x" ); + + // grant deployer role to 0x7aa5e36aa15e93d10f4f26357c30f052dacdde5f + Json::Value grantDeployerRoleTx; + grantDeployerRoleTx["data"] = + "0xc6427474000000000000000000000000d2c0deface0000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000006000000000000000000000000000000000000000000000000000000000000000c4b61d" + "27f6000000000000000000000000d2002000000000000000000000000000000000d20000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "00000000000000600000000000000000000000000000000000000000000000000000000000000024e43252d700" + "00000000000000000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f0000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + grantDeployerRoleTx["from"] = "0x5C4e11842E8be09264dc1976943571d7Af6d00F9"; + grantDeployerRoleTx["to"] = "0xD244519000000000000000000000000000000000"; + grantDeployerRoleTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + grantDeployerRoleTx["gas"] = toJS( "1000000" ); + txHash = fixture.rpcClient->eth_sendTransaction( grantDeployerRoleTx ); + BOOST_REQUIRE( !txHash.empty() ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value hasRoleCall; + hasRoleCall["data"] = + "0x91d14854fc425f2263d0df187444b70e47283d622c70181c5baebb1306a01edba1ce184c0000000000000000" + "000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f"; + hasRoleCall["to"] = "0xD2002000000000000000000000000000000000d2"; + BOOST_REQUIRE( jsToInt( fixture.rpcClient->eth_call( hasRoleCall, "latest" ) ) == 1 ); + + // contract test { + // function f(uint a) returns(uint d) { return a * 7; } + // } + + Json::Value deployContractTx; + deployContractTx["from"] = "0x7aa5e36aa15e93d10f4f26357c30f052dacdde5f"; + deployContractTx["code"] = compiled; + deployContractTx["gas"] = "1000000"; + deployContractTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + + txHash = fixture.rpcClient->eth_sendTransaction( deployContractTx ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x1" ) ); + BOOST_REQUIRE( !receipt["contractAddress"].isNull() ); + code = fixture.rpcClient->eth_getCode( receipt["contractAddress"].asString(), "latest" ); + BOOST_REQUIRE( code.asString().substr( 2 ) == compiled.substr( 58 ) ); +} + +BOOST_AUTO_TEST_CASE( deployment_control_v2 ) { + // Inserting ConfigController mockup into config and enabling flexibleDeploymentPatch. + // ConfigController mockup contract: + + // pragma solidity ^0.8.9; + // contract ConfigController { + // bool public freeContractDeployment = false; + // function isAddressWhitelisted(address addr) external view returns (bool) { + // return false; + // } + // function isDeploymentAllowed(address origin, address sender) + // external view returns (bool) { + // return freeContractDeployment; + // } + // function setFreeContractDeployment() external { + // freeContractDeployment = true; + // } + // } + + string configControllerV2 = + "0x608060405234801561001057600080fd5b506004361061004c576000" + "3560e01c806313f44d1014610051578063a2306c4f14610081578063d0" + "f557f41461009f578063f7e2a91b146100cf575b600080fd5b61006b60" + "048036038101906100669190610189565b6100d9565b60405161007891" + "906101d1565b60405180910390f35b6100896100e0565b604051610096" + "91906101d1565b60405180910390f35b6100b960048036038101906100" + "b491906101ec565b6100f1565b6040516100c691906101d1565b604051" + "80910390f35b6100d761010a565b005b6000919050565b600080549061" + "01000a900460ff1681565b60008060009054906101000a900460ff1690" + "5092915050565b60016000806101000a81548160ff0219169083151502" + "17905550565b600080fd5b600073ffffffffffffffffffffffffffffff" + "ffffffffff82169050919050565b60006101568261012b565b90509190" + "50565b6101668161014b565b811461017157600080fd5b50565b600081" + "3590506101838161015d565b92915050565b6000602082840312156101" + "9f5761019e610126565b5b60006101ad84828501610174565b91505092" + "915050565b60008115159050919050565b6101cb816101b6565b825250" + "50565b60006020820190506101e660008301846101c2565b9291505056" + "5b6000806040838503121561020357610202610126565b5b6000610211" + "85828601610174565b925050602061022285828601610174565b915050" + "925092905056fea2646970667358221220b5f971b16f7bbba22272b220" + "7e02f10abf1682c17fe636c7bf6406c5cae5716064736f6c63430008090033"; + + + std::string _config = c_genesisGeneration2ConfigString; + Json::Value ret; + Json::Reader().parse( _config, ret ); + ret["accounts"]["0xD2002000000000000000000000000000000000d2"]["code"] = configControllerV2; + ret["skaleConfig"]["sChain"]["flexibleDeploymentPatchTimestamp"] = 1; + Json::FastWriter fastWriter; + std::string config = fastWriter.write( ret ); + + JsonRpcFixture fixture( config, false, false, true ); + Address senderAddress = fixture.coinbase.address(); + fixture.client->setAuthor( senderAddress ); + + // contract test { + // function f(uint a) returns(uint d) { return a * 7; } + // } + + string compiled = + "6080604052341561000f57600080fd5b60b98061001d6000396000f300" + "608060405260043610603f576000357c01000000000000000000000000" + "00000000000000000000000000000000900463ffffffff168063b3de64" + "8b146044575b600080fd5b3415604e57600080fd5b606a600480360381" + "019080803590602001909291905050506080565b604051808281526020" + "0191505060405180910390f35b60006007820290509190505600a16562" + "7a7a72305820f294e834212334e2978c6dd090355312a3f0f9476b8eb9" + "8fb480406fc2728a960029"; + + + // Trying to deploy contract without permission + Json::Value deployContractWithoutRoleTx; + deployContractWithoutRoleTx["from"] = senderAddress.hex(); + deployContractWithoutRoleTx["code"] = compiled; + deployContractWithoutRoleTx["gas"] = "1000000"; + deployContractWithoutRoleTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + + string txHash = fixture.rpcClient->eth_sendTransaction( deployContractWithoutRoleTx ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x0" ) ); + + Json::Value code = + fixture.rpcClient->eth_getCode( receipt["contractAddress"].asString(), "latest" ); + BOOST_REQUIRE( code.asString() == "0x" ); + + // Allow to deploy by calling setFreeContractDeployment() + Json::Value grantDeployerRoleTx; + grantDeployerRoleTx["data"] = "0xf7e2a91b"; + grantDeployerRoleTx["from"] = senderAddress.hex(); + grantDeployerRoleTx["to"] = "0xD2002000000000000000000000000000000000D2"; + grantDeployerRoleTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + grantDeployerRoleTx["gas"] = toJS( "1000000" ); + txHash = fixture.rpcClient->eth_sendTransaction( grantDeployerRoleTx ); + BOOST_REQUIRE( !txHash.empty() ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + // Deploying with permission + Json::Value deployContractTx; + deployContractTx["from"] = senderAddress.hex(); + deployContractTx["code"] = compiled; + deployContractTx["gas"] = "1000000"; + deployContractTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + + txHash = fixture.rpcClient->eth_sendTransaction( deployContractTx ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x1" ) ); + BOOST_REQUIRE( !receipt["contractAddress"].isNull() ); + code = fixture.rpcClient->eth_getCode( receipt["contractAddress"].asString(), "latest" ); + BOOST_REQUIRE( code.asString().substr( 2 ) == compiled.substr( 58 ) ); +} + +BOOST_AUTO_TEST_CASE( filestorage_generation2 ) { + JsonRpcFixture fixture( c_genesisGeneration2ConfigString, false, false, true ); + + Json::Value hasRoleBeforeGrantingCall; + hasRoleBeforeGrantingCall["data"] = + "0x91d1485468bf109b95a5c15fb2bb99041323c27d15f8675e11bf7420a1cd6ad64c394f460000000000000000" + "000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f"; + hasRoleBeforeGrantingCall["to"] = "0xD3002000000000000000000000000000000000d3"; + BOOST_REQUIRE( + jsToInt( fixture.rpcClient->eth_call( hasRoleBeforeGrantingCall, "latest" ) ) == 0 ); + + Json::Value reserveSpaceBeforeGrantRoleTx; + reserveSpaceBeforeGrantRoleTx["data"] = + "0x1cfe4e3b0000000000000000000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f0000000000000000" + "000000000000000000000000000000000000000000000064"; + reserveSpaceBeforeGrantRoleTx["from"] = "0x7aa5e36aa15e93d10f4f26357c30f052dacdde5f"; + reserveSpaceBeforeGrantRoleTx["to"] = "0xD3002000000000000000000000000000000000d3"; + reserveSpaceBeforeGrantRoleTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + reserveSpaceBeforeGrantRoleTx["gas"] = toJS( "1000000" ); + std::string txHash = fixture.rpcClient->eth_sendTransaction( reserveSpaceBeforeGrantRoleTx ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x0" ) ); + + Json::Value grantRoleTx; + grantRoleTx["data"] = + "0xc6427474000000000000000000000000d2c0deface0000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000006000000000000000000000000000000000000000000000000000000000000000e4b61d" + "27f6000000000000000000000000d3002000000000000000000000000000000000d30000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000006000000000000000000000000000000000000000000000000000000000000000442f2ff15d68" + "bf109b95a5c15fb2bb99041323c27d15f8675e11bf7420a1cd6ad64c394f460000000000000000000000007aa5" + "e36aa15e93d10f4f26357c30f052dacdde5f000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000"; + grantRoleTx["from"] = "0x5C4e11842E8be09264dc1976943571d7Af6d00F9"; + grantRoleTx["to"] = "0xD244519000000000000000000000000000000000"; + grantRoleTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + grantRoleTx["gas"] = toJS( "1000000" ); + txHash = fixture.rpcClient->eth_sendTransaction( grantRoleTx ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x1" ) ); + + Json::Value hasRoleCall; + hasRoleCall["data"] = + "0x91d1485468bf109b95a5c15fb2bb99041323c27d15f8675e11bf7420a1cd6ad64c394f460000000000000000" + "000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f"; + hasRoleCall["to"] = "0xD3002000000000000000000000000000000000d3"; + BOOST_REQUIRE( jsToInt( fixture.rpcClient->eth_call( hasRoleCall, "latest" ) ) == 1 ); + + Json::Value reserveSpaceTx; + reserveSpaceTx["data"] = + "0x1cfe4e3b0000000000000000000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f0000000000000000" + "000000000000000000000000000000000000000000000064"; + reserveSpaceTx["from"] = "0x7aa5e36aa15e93d10f4f26357c30f052dacdde5f"; + reserveSpaceTx["to"] = "0xD3002000000000000000000000000000000000d3"; + reserveSpaceTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + reserveSpaceTx["gas"] = toJS( "1000000" ); + txHash = fixture.rpcClient->eth_sendTransaction( reserveSpaceTx ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + BOOST_REQUIRE_EQUAL( receipt["status"], string( "0x1" ) ); + + Json::Value getReservedSpaceCall; + hasRoleCall["data"] = + "0xbb559d160000000000000000000000007aa5e36aa15e93d10f4f26357c30f052dacdde5f"; + hasRoleCall["to"] = "0xD3002000000000000000000000000000000000d3"; + BOOST_REQUIRE( jsToInt( fixture.rpcClient->eth_call( hasRoleCall, "latest" ) ) == 100 ); +} +#endif + +BOOST_AUTO_TEST_CASE( PrecompiledPrintFakeEth, + *boost::unit_test::precondition( []( unsigned long ) -> bool { return false; } ) ) { + JsonRpcFixture fixture( c_genesisConfigString, false, false ); + dev::eth::simulateMining( *( fixture.client ), 20 ); + + fixture.accountHolder->setAccounts( { fixture.coinbase, fixture.account2, + dev::KeyPair( dev::Secret( + "0x1c2cd4b70c2b8c6cd7144bbbfbd1e5c6eacb4a5efd9c86d0e29cbbec4e8483b9" ) ) } ); + + u256 balance = + fixture.client->balanceAt( jsToAddress( "0x5C4e11842E8Be09264DC1976943571D7AF6d00f8" ) ); + BOOST_REQUIRE_EQUAL( balance, 0 ); + + Json::Value printFakeEthFromDisallowedAddressTx; + printFakeEthFromDisallowedAddressTx["data"] = + "0x5C4e11842E8Be09264DC1976943571D7AF6d00f8000000000000000000000000000000000000000000000000" + "0000000000000010"; + printFakeEthFromDisallowedAddressTx["from"] = fixture.coinbase.address().hex(); + printFakeEthFromDisallowedAddressTx["to"] = "0000000000000000000000000000000000000006"; + printFakeEthFromDisallowedAddressTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + fixture.rpcClient->eth_sendTransaction( printFakeEthFromDisallowedAddressTx ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + balance = + fixture.client->balanceAt( jsToAddress( "0x5C4e11842E8Be09264DC1976943571D7AF6d00f8" ) ); + BOOST_REQUIRE_EQUAL( balance, 0 ); + + Json::Value printFakeEthTx; + printFakeEthTx["data"] = + "0x5C4e11842E8Be09264DC1976943571D7AF6d00f8000000000000000000000000000000000000000000000000" + "0000000000000010"; + printFakeEthTx["from"] = "0x5C4e11842E8be09264dc1976943571d7Af6d00F9"; + printFakeEthTx["to"] = "0000000000000000000000000000000000000006"; + printFakeEthTx["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + fixture.rpcClient->eth_sendTransaction( printFakeEthTx ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + balance = + fixture.client->balanceAt( jsToAddress( "0x5C4e11842E8Be09264DC1976943571D7AF6d00f8" ) ); + BOOST_REQUIRE_EQUAL( balance, 16 ); + + Json::Value printFakeEthCall; + + printFakeEthCall["data"] = + "0x5C4e11842E8Be09264DC1976943571D7AF6d00f8000000000000000000000000000000000000000000000000" + "0000000000000010"; + + printFakeEthCall["from"] = "0x5C4e11842E8be09264dc1976943571d7Af6d00F9"; + printFakeEthCall["to"] = "0000000000000000000000000000000000000006"; + printFakeEthCall["gasPrice"] = fixture.rpcClient->eth_gasPrice(); + fixture.rpcClient->eth_call( printFakeEthCall, "latest" ); + + balance = + fixture.client->balanceAt( jsToAddress( "0x5C4e11842E8Be09264DC1976943571D7AF6d00f8" ) ); + BOOST_REQUIRE_EQUAL( balance, 16 ); + + // pragma solidity ^0.4.25; + + // contract Caller { + // function call() public view { + // bool status; + // uint amount = 16; + // address to = 0x5C4e11842E8Be09264DC1976943571D7AF6d00f8; + // assembly{ + // let ptr := mload(0x40) + // mstore(ptr, to) + // mstore(add(ptr, 0x20), amount) + // status := delegatecall(not(0), 0x06, ptr, 0x40, ptr, 32) + // } + // } + // } + + string compiled = + "0x6080604052348015600f57600080fd5b5060a78061001e6000396000f3006080604052600436106022576000" + "3560e01c63ffffffff16806328b5e32b146027575b600080fd5b348015603257600080fd5b506039603b565b00" + "5b600080600060109150735c4e11842e8be09264dc1976943571d7af6d00f89050604051818152826020820152" + "6020816040836006600019f49350505050505600a165627a7a72305820c99b5f7e9e41fb0fee1724d382ca0f2c" + "003087f66b3b46037ca6c7d452b076f20029"; + + Json::Value create; + create["from"] = fixture.coinbase.address().hex(); + create["code"] = compiled; + create["gas"] = "1000000"; + + TransactionSkeleton ts = toTransactionSkeleton( create ); + ts = fixture.client->populateTransactionWithDefaults( ts ); + pair< bool, Secret > ar = fixture.accountHolder->authenticate( ts ); + Transaction tx( ts, ar.second ); + + auto txHash = fixture.rpcClient->eth_sendRawTransaction( toJS( tx.toBytes() ) ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash ); + string contractAddress = receipt["contractAddress"].asString(); + + Json::Value transactionCallObject; + transactionCallObject["to"] = contractAddress; + transactionCallObject["data"] = "0x28b5e32b"; + + fixture.rpcClient->eth_call( transactionCallObject, "latest" ); + balance = + fixture.client->balanceAt( jsToAddress( "0x5C4e11842E8Be09264DC1976943571D7AF6d00f8" ) ); + BOOST_REQUIRE_EQUAL( balance, 16 ); +} + +BOOST_AUTO_TEST_CASE( mtm_import_sequential_txs ) { + JsonRpcFixture fixture( c_genesisConfigString, true, true, false, true ); + dev::eth::simulateMining( *( fixture.client ), 1 ); + + Json::Value txJson; + txJson["from"] = fixture.coinbase.address().hex(); + txJson["gas"] = "100000"; + + txJson["nonce"] = "0"; + TransactionSkeleton ts1 = toTransactionSkeleton( txJson ); + ts1 = fixture.client->populateTransactionWithDefaults( ts1 ); + pair< bool, Secret > ar1 = fixture.accountHolder->authenticate( ts1 ); + Transaction tx1( ts1, ar1.second ); + + txJson["nonce"] = "1"; + TransactionSkeleton ts2 = toTransactionSkeleton( txJson ); + ts2 = fixture.client->populateTransactionWithDefaults( ts2 ); + pair< bool, Secret > ar2 = fixture.accountHolder->authenticate( ts2 ); + Transaction tx2( ts2, ar2.second ); + + txJson["nonce"] = "2"; + TransactionSkeleton ts3 = toTransactionSkeleton( txJson ); + ts3 = fixture.client->populateTransactionWithDefaults( ts3 ); + pair< bool, Secret > ar3 = fixture.accountHolder->authenticate( ts3 ); + Transaction tx3( ts3, ar3.second ); + + h256 h1 = fixture.client->importTransaction( tx1, TransactionBroadcast::DontBroadcast ); + h256 h2 = fixture.client->importTransaction( tx2, TransactionBroadcast::DontBroadcast ); + h256 h3 = fixture.client->importTransaction( tx3, TransactionBroadcast::DontBroadcast ); + BOOST_REQUIRE( h1 ); + BOOST_REQUIRE( h2 ); + BOOST_REQUIRE( h3 ); + BOOST_REQUIRE( fixture.client->transactionQueueStatus().current == 3 ); +} + +BOOST_AUTO_TEST_CASE( mtm_import_future_txs ) { + JsonRpcFixture fixture( c_genesisConfigString, true, true, false, true ); + dev::eth::simulateMining( *( fixture.client ), 1 ); + auto tq = fixture.client->debugGetTransactionQueue(); + fixture.client->skaleHost()->pauseConsensus( true ); + + Json::Value txJson; + txJson["from"] = fixture.coinbase.address().hex(); + txJson["gas"] = "100000"; + + txJson["nonce"] = "0"; + TransactionSkeleton ts1 = toTransactionSkeleton( txJson ); + ts1 = fixture.client->populateTransactionWithDefaults( ts1 ); + pair< bool, Secret > ar1 = fixture.accountHolder->authenticate( ts1 ); + Transaction tx1( ts1, ar1.second ); + + txJson["nonce"] = "1"; + TransactionSkeleton ts2 = toTransactionSkeleton( txJson ); + ts2 = fixture.client->populateTransactionWithDefaults( ts2 ); + pair< bool, Secret > ar2 = fixture.accountHolder->authenticate( ts2 ); + Transaction tx2( ts2, ar2.second ); + + txJson["nonce"] = "2"; + TransactionSkeleton ts3 = toTransactionSkeleton( txJson ); + ts3 = fixture.client->populateTransactionWithDefaults( ts3 ); + pair< bool, Secret > ar3 = fixture.accountHolder->authenticate( ts3 ); + Transaction tx3( ts3, ar3.second ); + + txJson["nonce"] = "3"; + TransactionSkeleton ts4 = toTransactionSkeleton( txJson ); + ts4 = fixture.client->populateTransactionWithDefaults( ts4 ); + pair< bool, Secret > ar4 = fixture.accountHolder->authenticate( ts4 ); + Transaction tx4( ts4, ar4.second ); + + txJson["nonce"] = "4"; + TransactionSkeleton ts5 = toTransactionSkeleton( txJson ); + ts5 = fixture.client->populateTransactionWithDefaults( ts5 ); + pair< bool, Secret > ar5 = fixture.accountHolder->authenticate( ts5 ); + Transaction tx5( ts5, ar5.second ); + + h256 h1 = fixture.client->importTransaction( tx5 ); + BOOST_REQUIRE( h1 ); + BOOST_REQUIRE_EQUAL( tq->futureSize(), 1 ); + + Json::Value call = fixture.rpcClient->debug_getFutureTransactions(); + BOOST_REQUIRE_EQUAL( call.size(), 1 ); + + h256 h2 = fixture.client->importTransaction( tx3 ); + BOOST_REQUIRE( h2 ); + BOOST_REQUIRE_EQUAL( tq->futureSize(), 2 ); + + call = fixture.rpcClient->debug_getFutureTransactions(); + BOOST_REQUIRE_EQUAL( call.size(), 2 ); + BOOST_REQUIRE_EQUAL( call[0]["from"], string( "0x" ) + txJson["from"].asString() ); + + h256 h3 = fixture.client->importTransaction( tx2 ); + BOOST_REQUIRE( h3 ); + BOOST_REQUIRE_EQUAL( tq->futureSize(), 3 ); + + call = fixture.rpcClient->debug_getFutureTransactions(); + BOOST_REQUIRE_EQUAL( call.size(), 3 ); + + h256 h4 = fixture.client->importTransaction( tx1 ); + BOOST_REQUIRE( h4 ); + BOOST_REQUIRE_EQUAL( tq->futureSize(), 1 ); + BOOST_REQUIRE_EQUAL( tq->status().current, 3 ); + + call = fixture.rpcClient->debug_getFutureTransactions(); + BOOST_REQUIRE_EQUAL( call.size(), 1 ); + + h256 h5 = fixture.client->importTransaction( tx4 ); + BOOST_REQUIRE( h5 ); + BOOST_REQUIRE_EQUAL( tq->futureSize(), 0 ); + BOOST_REQUIRE_EQUAL( tq->status().current, 5 ); + + call = fixture.rpcClient->debug_getFutureTransactions(); + BOOST_REQUIRE_EQUAL( call.size(), 0 ); + + fixture.client->skaleHost()->pauseConsensus( false ); +} + +// TODO: Enable for multitransaction mode checking + + +// historic node shall ignore invalid transactions in block +BOOST_AUTO_TEST_CASE( skip_invalid_transactions ) { + sleep( 1 ); + JsonRpcFixture fixture( c_genesisConfigString, true, true, false, true ); + dev::eth::simulateMining( *( fixture.client ), 1 ); // 2 Ether + + cout << " Balance: " + << fixture.rpcClient->eth_getBalance( + fixture.accountHolder->allAccounts()[0].hex(), "latest" ) + << endl; + + // 1 import 1 transaction to increase block number + // also send some eth to account2 + // TODO repair mineMoney function! (it asserts) + Json::Value txJson; + txJson["from"] = fixture.coinbase.address().hex(); + txJson["gas"] = "200000"; + txJson["gasPrice"] = "5000000000000"; + txJson["to"] = fixture.account2.address().hex(); +#ifdef FAIR + txJson["value"] = "3500000000000000000"; +#else + txJson["value"] = "1000000000000000000"; +#endif + + txJson["nonce"] = "0"; + TransactionSkeleton ts1 = toTransactionSkeleton( txJson ); + ts1 = fixture.client->populateTransactionWithDefaults( ts1 ); + pair< bool, Secret > ar1 = fixture.accountHolder->authenticate( ts1 ); + Transaction tx1( ts1, ar1.second ); + fixture.client->importTransaction( tx1 ); + + // 1 eth left (returned to author) + dev::eth::mineTransaction( *( fixture.client ), 1 ); + cout << fixture.accountHolder->allAccounts()[0].hex() << " Balance2: " + << fixture.rpcClient->eth_getBalance( + fixture.accountHolder->allAccounts()[0].hex(), "latest" ) + << endl; + + // 2 import 4 transactions with money for 1st, 2nd, and 3rd + // require full 1 Ether for gas+value + txJson["gas"] = "100000"; + txJson["nonce"] = "1"; + txJson["value"] = "500000000000000000"; // take 0.5 eth out + ts1 = toTransactionSkeleton( txJson ); + ts1 = fixture.client->populateTransactionWithDefaults( ts1 ); + ar1 = fixture.accountHolder->authenticate( ts1 ); + tx1 = Transaction( ts1, ar1.second ); + + txJson["nonce"] = "2"; + TransactionSkeleton ts2 = toTransactionSkeleton( txJson ); + ts2 = fixture.client->populateTransactionWithDefaults( ts2 ); + pair< bool, Secret > ar2 = fixture.accountHolder->authenticate( ts2 ); + Transaction tx2( ts2, ar2.second ); + + txJson["from"] = fixture.account2.address().hex(); + txJson["nonce"] = "0"; + txJson["value"] = "0"; + txJson["gasPrice"] = "20000000000"; + txJson["gas"] = "53000"; + TransactionSkeleton ts3 = toTransactionSkeleton( txJson ); + ts3 = fixture.client->populateTransactionWithDefaults( ts3 ); + pair< bool, Secret > ar3 = fixture.accountHolder->authenticate( ts3 ); + Transaction tx3( ts3, ar3.second ); + + txJson["nonce"] = "1"; + TransactionSkeleton ts4 = toTransactionSkeleton( txJson ); + ts3 = fixture.client->populateTransactionWithDefaults( ts4 ); + pair< bool, Secret > ar4 = fixture.accountHolder->authenticate( ts4 ); + Transaction tx4( ts3, ar3.second ); + + // pause consensus to make sure all txs are imported at once, and + // will all be placed in the same block + fixture.client->skaleHost()->pauseConsensus( true ); + + h256 h4 = fixture.client->importTransaction( tx4 ); // ok + h256 h2 = fixture.client->importTransaction( tx2 ); // invalid + h256 h3 = fixture.client->importTransaction( tx3 ); // ok + h256 h1 = fixture.client->importTransaction( tx1 ); // ok + + fixture.client->skaleHost()->pauseConsensus( false ); + + dev::eth::mineTransaction( *( fixture.client ), 1 ); + cout << "Balance3: " + << fixture.rpcClient->eth_getBalance( + fixture.accountHolder->allAccounts()[0].hex(), "latest" ) + << endl; + + ( void ) h1; + ( void ) h2; + ( void ) h3; + ( void ) h4; + +#ifdef HISTORIC_STATE + // 3 check that historic node sees only 3 txns + + string explicitNumberStr = to_string( fixture.client->number() ); + + // 1 Block + Json::Value block = fixture.rpcClient->eth_getBlockByNumber( "latest", "false" ); + + string bh = block["hash"].asString(); + + // 2 transaction count + Json::Value cnt = fixture.rpcClient->eth_getBlockTransactionCountByNumber( "latest" ); + BOOST_REQUIRE_EQUAL( cnt.asString(), "0x3" ); + cnt = fixture.rpcClient->eth_getBlockTransactionCountByNumber( explicitNumberStr ); + BOOST_REQUIRE_EQUAL( cnt.asString(), "0x3" ); + cnt = fixture.rpcClient->eth_getBlockTransactionCountByHash( bh ); + BOOST_REQUIRE_EQUAL( cnt.asString(), "0x3" ); + + + BOOST_REQUIRE_EQUAL( block["transactions"].size(), 3 ); + BOOST_REQUIRE_EQUAL( block["transactions"][0]["transactionIndex"], "0x0" ); + BOOST_REQUIRE_EQUAL( block["transactions"][1]["transactionIndex"], "0x1" ); + BOOST_REQUIRE_EQUAL( block["transactions"][2]["transactionIndex"], "0x2" ); + + // same with explicit number + block = fixture.rpcClient->eth_getBlockByNumber( explicitNumberStr, "false" ); + + BOOST_REQUIRE_EQUAL( block["transactions"].size(), 3 ); + BOOST_REQUIRE_EQUAL( block["transactions"][0]["transactionIndex"], "0x0" ); + BOOST_REQUIRE_EQUAL( block["transactions"][1]["transactionIndex"], "0x1" ); + BOOST_REQUIRE_EQUAL( block["transactions"][2]["transactionIndex"], "0x2" ); + + // 3 receipts + Json::Value r1, r3, r4; + BOOST_REQUIRE_NO_THROW( r1 = fixture.rpcClient->eth_getTransactionReceipt( toJS( h1 ) ) ); + BOOST_REQUIRE_THROW( + fixture.rpcClient->eth_getTransactionReceipt( toJS( h2 ) ), jsonrpc::JsonRpcException ); + BOOST_REQUIRE_NO_THROW( r3 = fixture.rpcClient->eth_getTransactionReceipt( toJS( h3 ) ) ); + BOOST_REQUIRE_NO_THROW( r4 = fixture.rpcClient->eth_getTransactionReceipt( toJS( h4 ) ) ); + + BOOST_REQUIRE_EQUAL( r1["transactionIndex"], "0x0" ); + BOOST_REQUIRE_EQUAL( r3["transactionIndex"], "0x1" ); + BOOST_REQUIRE_EQUAL( r4["transactionIndex"], "0x2" ); + + // 4 transaction by index + Json::Value t0 = fixture.rpcClient->eth_getTransactionByBlockNumberAndIndex( "latest", "0" ); + Json::Value t1 = fixture.rpcClient->eth_getTransactionByBlockNumberAndIndex( "latest", "1" ); + Json::Value t2 = fixture.rpcClient->eth_getTransactionByBlockNumberAndIndex( "latest", "2" ); + BOOST_REQUIRE_EQUAL( jsToFixed< 32 >( t0["hash"].asString() ), h1 ); + BOOST_REQUIRE_EQUAL( jsToFixed< 32 >( t1["hash"].asString() ), h3 ); + BOOST_REQUIRE_EQUAL( jsToFixed< 32 >( t2["hash"].asString() ), h4 ); + + // same with explicit block number + + t0 = fixture.rpcClient->eth_getTransactionByBlockNumberAndIndex( explicitNumberStr, "0" ); + t1 = fixture.rpcClient->eth_getTransactionByBlockNumberAndIndex( explicitNumberStr, "1" ); + t2 = fixture.rpcClient->eth_getTransactionByBlockNumberAndIndex( explicitNumberStr, "2" ); + BOOST_REQUIRE_EQUAL( jsToFixed< 32 >( t0["hash"].asString() ), h1 ); + BOOST_REQUIRE_EQUAL( jsToFixed< 32 >( t1["hash"].asString() ), h3 ); + BOOST_REQUIRE_EQUAL( jsToFixed< 32 >( t2["hash"].asString() ), h4 ); + + BOOST_REQUIRE_EQUAL( bh, r1["blockHash"].asString() ); + + t0 = fixture.rpcClient->eth_getTransactionByBlockHashAndIndex( bh, "0" ); + t1 = fixture.rpcClient->eth_getTransactionByBlockHashAndIndex( bh, "1" ); + t2 = fixture.rpcClient->eth_getTransactionByBlockHashAndIndex( bh, "2" ); + + BOOST_REQUIRE_EQUAL( jsToFixed< 32 >( t0["hash"].asString() ), h1 ); + BOOST_REQUIRE_EQUAL( jsToFixed< 32 >( t1["hash"].asString() ), h3 ); + BOOST_REQUIRE_EQUAL( jsToFixed< 32 >( t2["hash"].asString() ), h4 ); + + // 5 transaction by hash + BOOST_REQUIRE_THROW( + fixture.rpcClient->eth_getTransactionByHash( toJS( h2 ) ), jsonrpc::JsonRpcException ); + + // send it successfully + + // make money + dev::eth::simulateMining( *fixture.client, 1 ); + + h2 = fixture.client->importTransaction( tx2 ); // invalid + + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + // checks: + Json::Value r2; + BOOST_REQUIRE_NO_THROW( r2 = fixture.rpcClient->eth_getTransactionReceipt( toJS( h2 ) ) ); + BOOST_REQUIRE_EQUAL( r2["blockNumber"], toJS( fixture.client->number() ) ); +#endif +} + +BOOST_AUTO_TEST_CASE( eth_signAndSendRawTransaction, + *boost::unit_test::precondition( dev::test::manuallyRunningTest ) ) { + SkaledFixture fixture( skaledConfigFileName ); + fixture.setupFirstKey(); + auto firstAccount = fixture.testAccounts.begin()->second; + auto gasPrice = fixture.getCurrentGasPrice(); + for ( uint64_t i = 0; i < 3; i++ ) { + auto dst = SkaledAccount::generate(); + fixture.splitAccountInHalves( + firstAccount, dst, gasPrice, TransactionWait::WAIT_FOR_COMPLETION ); + } +} + +BOOST_AUTO_TEST_CASE( perf_sendManyParalelEthTransfers, + *boost::unit_test::precondition( dev::test::manuallyRunningTest ) ) { + SkaledFixture fixture( skaledConfigFileName ); + vector< Secret > accountPieces; + + fixture.verifyTransactions = false; + fixture.threadsCountForTestTransactions = 8; + fixture.mtmBatchSize = 1; + + fixture.setupFirstKey(); + fixture.deployERC20(); + + fixture.setupTwoToTheNKeys( 12 ); + + fixture.sendTinyTransfersForAllAccounts( 10, TransferType::NATIVE ); +} + + +BOOST_AUTO_TEST_CASE( + perf_calls, *boost::unit_test::precondition( dev::test::manuallyRunningTest ) ) { + SkaledFixture fixture( skaledConfigFileName ); + vector< Secret > accountPieces; + + fixture.threadsCountForTestTransactions = 8; + + + fixture.setupFirstKey(); + fixture.deployERC20(); + + fixture.setupTwoToTheNKeys( 12 ); + + fixture.sendCallsForAllAccounts( 1, CallType::BLOCK_BY_NUMBER, "eth_getBlockByNumber" ); + fixture.sendCallsForAllAccounts( 1, CallType::TRANSACTION_COUNT, "eth_transactionCount" ); + fixture.sendCallsForAllAccounts( 1, CallType::BALANCE, "eth_getBalance" ); + fixture.sendCallsForAllAccounts( 1, CallType::BLOCK_NUMBER, "eth_blockNumber" ); + fixture.sendCallsForAllAccounts( 1, CallType::CHAIN_ID, "eth_chainId" ); + fixture.sendCallsForAllAccounts( 1, CallType::NET_VERSION, "net_version" ); + fixture.sendCallsForAllAccounts( 1, CallType::GAS_PRICE, "eth_gasPrice" ); + fixture.sendCallsForAllAccounts( 1, CallType::HASH_RATE, "eth_hashrate" ); + fixture.sendCallsForAllAccounts( 1, CallType::MINING, "eth_mining" ); + fixture.sendCallsForAllAccounts( 1, CallType::SYNCING, "eth_syncing" ); + fixture.sendCallsForAllAccounts( 1, CallType::WEB3_CLIENT_VERSION, "web3_clientVersion" ); +} + + +BOOST_AUTO_TEST_CASE( perf_sendManyParalelEthMTMTransfers, + *boost::unit_test::precondition( dev::test::manuallyRunningTest ) ) { + SkaledFixture fixture( skaledConfigFileName ); + vector< Secret > accountPieces; + + fixture.verifyTransactions = false; + fixture.threadsCountForTestTransactions = 8; + fixture.mtmBatchSize = 5; + + fixture.setupFirstKey(); + fixture.setupTwoToTheNKeys( 8 ); + + fixture.sendTinyTransfersForAllAccounts( 10, TransferType::NATIVE ); +} + +BOOST_AUTO_TEST_CASE( perf_sendManyParalelEthType1Transfers, + *boost::unit_test::precondition( dev::test::manuallyRunningTest ) ) { + SkaledFixture fixture( skaledConfigFileName ); + vector< Secret > accountPieces; + + fixture.verifyTransactions = false; + fixture.threadsCountForTestTransactions = 8; + fixture.transactionType = TransactionType::Type1; + + fixture.setupFirstKey(); + fixture.deployERC20(); + + fixture.setupTwoToTheNKeys( 12 ); + + fixture.sendTinyTransfersForAllAccounts( 1000, TransferType::NATIVE ); +} + +BOOST_AUTO_TEST_CASE( perf_sendManyParalelEthType2Transfers, + *boost::unit_test::precondition( dev::test::manuallyRunningTest ) ) { + SkaledFixture fixture( skaledConfigFileName ); + vector< Secret > accountPieces; + + fixture.verifyTransactions = false; + fixture.threadsCountForTestTransactions = 8; + fixture.transactionType = TransactionType::Type2; + + fixture.setupFirstKey(); + fixture.deployERC20(); + + fixture.setupTwoToTheNKeys( 12 ); + + fixture.sendTinyTransfersForAllAccounts( 1000, TransferType::NATIVE ); +} + +BOOST_AUTO_TEST_CASE( perf_sendManyParalelEthPowTransfers, + *boost::unit_test::precondition( dev::test::manuallyRunningTest ) ) { + SkaledFixture fixture( skaledConfigFileName ); + vector< Secret > accountPieces; + + fixture.verifyTransactions = false; + fixture.threadsCountForTestTransactions = 8; +#ifndef FAIR + fixture.usePow = true; +#endif + + fixture.setupFirstKey(); + fixture.deployERC20(); + + fixture.setupTwoToTheNKeys( 4 ); + + fixture.sendTinyTransfersForAllAccounts( 1000, TransferType::NATIVE ); +} + +BOOST_AUTO_TEST_CASE( perf_sendManyParalelERC20Transfers, + *boost::unit_test::precondition( dev::test::manuallyRunningTest ) ) { + SkaledFixture fixture( skaledConfigFileName ); + vector< Secret > accountPieces; + + fixture.verifyTransactions = false; + fixture.threadsCountForTestTransactions = 8; + + fixture.setupFirstKey(); + + fixture.deployERC20(); + + fixture.setupTwoToTheNKeys( 12 ); + fixture.mintAllKeysWithERC20(); + + fixture.sendTinyTransfersForAllAccounts( 10, TransferType::ERC20 ); +} + + +#ifndef FAIR +BOOST_FIXTURE_TEST_SUITE( RestrictedAddressSuite, RestrictedAddressFixture ) + +BOOST_AUTO_TEST_CASE( direct_call ) { + Json::Value transactionCallObject; + transactionCallObject["to"] = "0x0000000000000000000000000000000000000005"; + transactionCallObject["data"] = data; + + rpcClient->eth_call( transactionCallObject, "latest" ); + BOOST_REQUIRE( !boost::filesystem::exists( path ) ); + + transactionCallObject["from"] = "0xdeadbeef01234567896c27aa97d1a86395877b3a"; + rpcClient->eth_call( transactionCallObject, "latest" ); + BOOST_REQUIRE( !boost::filesystem::exists( path ) ); + + transactionCallObject["from"] = "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a"; + rpcClient->eth_call( transactionCallObject, "latest" ); + BOOST_REQUIRE( !boost::filesystem::exists( path ) ); +} + +BOOST_AUTO_TEST_CASE( transaction_from_restricted_address ) { + auto senderAddress = coinbase.address(); + client->setAuthor( senderAddress ); + dev::eth::simulateMining( *( client ), 1000 ); + + Json::Value transactionCallObject; + transactionCallObject["from"] = toJS( senderAddress ); + transactionCallObject["to"] = "0x0000000000000000000000000000000000000005"; + transactionCallObject["data"] = data; + + TransactionSkeleton ts = toTransactionSkeleton( transactionCallObject ); + ts = client->populateTransactionWithDefaults( ts ); + pair< bool, Secret > ar = accountHolder->authenticate( ts ); + Transaction tx( ts, ar.second ); + + auto txHash = rpcClient->eth_sendRawTransaction( toJS( tx.toBytes() ) ); + dev::eth::mineTransaction( *( client ), 1 ); + + BOOST_REQUIRE( !boost::filesystem::exists( path ) ); +} + +BOOST_AUTO_TEST_CASE( transaction_from_allowed_address ) { + auto senderAddress = coinbase.address(); + client->setAuthor( senderAddress ); + dev::eth::simulateMining( *( client ), 1000 ); + + Json::Value transactionCallObject; + transactionCallObject["from"] = toJS( senderAddress ); + transactionCallObject["to"] = "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a"; + transactionCallObject["data"] = "0x28b5e32b"; + + TransactionSkeleton ts = toTransactionSkeleton( transactionCallObject ); + ts = client->populateTransactionWithDefaults( ts ); + pair< bool, Secret > ar = accountHolder->authenticate( ts ); + Transaction tx( ts, ar.second ); + + auto txHash = rpcClient->eth_sendRawTransaction( toJS( tx.toBytes() ) ); + dev::eth::mineTransaction( *( client ), 1 ); + + BOOST_REQUIRE( boost::filesystem::exists( path ) ); +} + +BOOST_AUTO_TEST_CASE( delegate_call ) { + auto senderAddress = coinbase.address(); + client->setAuthor( senderAddress ); + dev::eth::simulateMining( *( client ), 1000 ); + + // pragma solidity ^0.4.25; + // + // contract Caller { + // function call() public view { + // bool status; + // string memory fileName = "test"; + // address sender = 0x000000000000000000000000000000AA; + // assembly{ + // let ptr := mload(0x40) + // mstore(ptr, sender) + // mstore(add(ptr, 0x20), 4) + // mstore(add(ptr, 0x40), mload(add(fileName, 0x20))) + // mstore(add(ptr, 0x60), 1) + // status := delegatecall(not(0), 0x05, ptr, 0x80, ptr, 32) + // } + // } + // } + + string compiled = + "6080604052348015600f57600080fd5b5060f88061001e6000396000f300608060405260043610603f57600035" + "7c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806328b5e32b14" + "6044575b600080fd5b348015604f57600080fd5b5060566058565b005b60006060600060408051908101604052" + "80600481526020017f746573740000000000000000000000000000000000000000000000000000000081525091" + "5060aa905060405181815260046020820152602083015160408201526001606082015260208160808360056000" + "19f49350505050505600a165627a7a72305820172a27e3e21f45218a47c53133bb33150ee9feac9e9d5d13294b" + "48b03773099a0029"; + + Json::Value create; + + create["from"] = toJS( senderAddress ); + create["code"] = compiled; + create["gas"] = "1000000"; + + TransactionSkeleton ts = toTransactionSkeleton( create ); + ts = client->populateTransactionWithDefaults( ts ); + pair< bool, Secret > ar = accountHolder->authenticate( ts ); + Transaction tx( ts, ar.second ); + + auto txHash = rpcClient->eth_sendRawTransaction( toJS( tx.toBytes() ) ); + dev::eth::mineTransaction( *( client ), 1 ); + + Json::Value receipt = rpcClient->eth_getTransactionReceipt( txHash ); + string contractAddress = receipt["contractAddress"].asString(); + + Json::Value transactionCallObject; + transactionCallObject["to"] = contractAddress; + transactionCallObject["data"] = "0x28b5e32b"; + + rpcClient->eth_call( transactionCallObject, "latest" ); + BOOST_REQUIRE( !boost::filesystem::exists( path ) ); + + transactionCallObject["from"] = ownerAddress.hex(); + rpcClient->eth_call( transactionCallObject, "latest" ); + BOOST_REQUIRE( !boost::filesystem::exists( path ) ); + + transactionCallObject["to"] = "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a"; + rpcClient->eth_call( transactionCallObject, "latest" ); + BOOST_REQUIRE( !boost::filesystem::exists( path ) ); +} + +BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE( FilestorageCacheSuite ) + +BOOST_AUTO_TEST_CASE( cached_filestorage ) { + auto _config = c_genesisConfigString; + Json::Value ret; + Json::Reader().parse( _config, ret ); + ret["skaleConfig"]["sChain"]["revertableFSPatchTimestamp"] = 1; + Json::FastWriter fastWriter; + std::string config = fastWriter.write( ret ); + RestrictedAddressFixture fixture( config ); + + auto senderAddress = fixture.coinbase.address(); + fixture.client->setAuthor( senderAddress ); + dev::eth::simulateMining( *( fixture.client ), 1000 ); + + Json::Value transactionCallObject; + transactionCallObject["from"] = toJS( senderAddress ); + transactionCallObject["to"] = "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a"; + transactionCallObject["data"] = "0xf38fb65b"; + + TransactionSkeleton ts = toTransactionSkeleton( transactionCallObject ); + ts = fixture.client->populateTransactionWithDefaults( ts ); + pair< bool, Secret > ar = fixture.accountHolder->authenticate( ts ); + Transaction tx( ts, ar.second ); + + auto txHash = fixture.rpcClient->eth_sendRawTransaction( toJS( tx.toBytes() ) ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + BOOST_REQUIRE( !boost::filesystem::exists( fixture.path ) ); +} + +BOOST_AUTO_TEST_CASE( uncached_filestorage ) { + auto _config = c_genesisConfigString; + Json::Value ret; + Json::Reader().parse( _config, ret ); + ret["skaleConfig"]["sChain"]["revertableFSPatchTimestamp"] = 9999999999999; + Json::FastWriter fastWriter; + std::string config = fastWriter.write( ret ); + RestrictedAddressFixture fixture( config ); + + auto senderAddress = fixture.coinbase.address(); + fixture.client->setAuthor( senderAddress ); + dev::eth::simulateMining( *( fixture.client ), 1000 ); + + Json::Value transactionCallObject; + transactionCallObject["from"] = toJS( senderAddress ); + transactionCallObject["to"] = "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a"; + transactionCallObject["data"] = "0xf38fb65b"; + + TransactionSkeleton ts = toTransactionSkeleton( transactionCallObject ); + ts = fixture.client->populateTransactionWithDefaults( ts ); + pair< bool, Secret > ar = fixture.accountHolder->authenticate( ts ); + Transaction tx( ts, ar.second ); + + auto txHash = fixture.rpcClient->eth_sendRawTransaction( toJS( tx.toBytes() ) ); + dev::eth::mineTransaction( *( fixture.client ), 1 ); + + BOOST_REQUIRE( boost::filesystem::exists( fixture.path ) ); +} + +BOOST_AUTO_TEST_SUITE_END() +#endif + +BOOST_FIXTURE_TEST_SUITE( GappedCacheSuite, JsonRpcFixture ) + +#ifdef HISTORIC_STATE + +BOOST_AUTO_TEST_CASE( test_blocks ) { + dev::rpc::_detail::GappedTransactionIndexCache cache( 10, *client ); + BOOST_REQUIRE_EQUAL( cache.realBlockTransactionCount( LatestBlock ), 0 ); + BOOST_REQUIRE_EQUAL( cache.realBlockTransactionCount( PendingBlock ), 0 ); + BOOST_REQUIRE_EQUAL( cache.realBlockTransactionCount( 999999999 ), 0 ); +} + +BOOST_AUTO_TEST_CASE( test_transactions ) { + simulateMining( *client, 1, Address( "0xf6c2a4ba2350e58a45916a03d0faa70dcc5dcfbf" ) ); + + // give it some time since testing fixture is not reliable + // to do - move to real skaled testing + sleep( 3 ); + + dev::rpc::_detail::GappedTransactionIndexCache cache( 10, *client ); + + Transaction invalid( fromHex( "0x00112233445566778899001122334455667788990011223344556677889900" + "11223344556677889900112233" + "4455667788990011223344556677889900112233445566778899001122334455" + "66778899001122334455667788" + "990011223344556677889900112233445566778899" ), + CheckTransaction::None, true ); + + Transaction valid( + fromHex( "0xf86c808504a817c80083015f90943d7112ee86223baf0a506b9d2a77595cbbba51d1872386f26fc" + "10000801ca0655757fd0650a65a373c48a4dc0f3d6ac5c3831aa0cc2cb863a5909dc6c25f72a07188" + "2ee8633466a243c0ea64dadb3120c1ca7a5cc7433c6c0b1c861a85322265" ), + CheckTransaction::None ); +#ifndef FAIR + valid.ignoreExternalGas(); +#endif + + // give it some time since testing fixture is not reliable + // to do - move to real skaled testing + sleep( 3 ); + + client->importTransactionsAsBlock( Transactions{ invalid, valid }, +#ifdef BITE + DecryptedTransactions{ +#ifdef BITE + std::make_shared< DecryptedCTXTxsMap >(), +#endif // BITE + std::make_shared< DecryptedRegularTxsMap >() + }, +#endif + +#ifdef FAIR + 1, +#endif + 1 ); + +#ifndef FAIR + BOOST_REQUIRE_EQUAL( cache.realBlockTransactionCount( LatestBlock ), 2 ); + BOOST_REQUIRE_EQUAL( cache.realIndexFromGapped( LatestBlock, 0 ), 1 ); + BOOST_REQUIRE_EQUAL( cache.gappedIndexFromReal( LatestBlock, 1 ), 0 ); + BOOST_REQUIRE_THROW( cache.gappedIndexFromReal( LatestBlock, 0 ), std::out_of_range ); + BOOST_REQUIRE_EQUAL( cache.transactionPresent( LatestBlock, 0 ), false ); + BOOST_REQUIRE_EQUAL( cache.transactionPresent( LatestBlock, 1 ), true ); +#else + BOOST_REQUIRE_EQUAL( cache.realBlockTransactionCount( LatestBlock ), 1 ); + BOOST_REQUIRE_EQUAL( cache.gappedBlockTransactionCount( LatestBlock ), 1 ); + BOOST_REQUIRE_EQUAL( cache.realIndexFromGapped( LatestBlock, 0 ), 0 ); + BOOST_REQUIRE_NO_THROW( cache.gappedIndexFromReal( LatestBlock, 0 ) ); + BOOST_REQUIRE_EQUAL( cache.transactionPresent( LatestBlock, 0 ), true ); + BOOST_REQUIRE_THROW( cache.transactionPresent( LatestBlock, 1 ), std::out_of_range ); +#endif +} + +BOOST_AUTO_TEST_CASE( test_exceptions ) { + simulateMining( *client, 1, Address( "0xf6c2a4ba2350e58a45916a03d0faa70dcc5dcfbf" ) ); + + dev::rpc::_detail::GappedTransactionIndexCache cache( 10, *client ); + + Transaction invalid( fromHex( "0x00112233445566778899001122334455667788990011223344556677889900" + "11223344556677889900112233" + "4455667788990011223344556677889900112233445566778899001122334455" + "66778899001122334455667788" + "990011223344556677889900112233445566778899" ), + CheckTransaction::None, true ); + + Transaction valid( + fromHex( "0xf86c808504a817c80083015f90943d7112ee86223baf0a506b9d2a77595cbbba51d1872386f26fc" + "10000801ca0655757fd0650a65a373c48a4dc0f3d6ac5c3831aa0cc2cb863a5909dc6c25f72a07188" + "2ee8633466a243c0ea64dadb3120c1ca7a5cc7433c6c0b1c861a85322265" ), + CheckTransaction::None ); + +#ifndef FAIR + valid.ignoreExternalGas(); +#endif + + client->importTransactionsAsBlock( Transactions{ invalid, valid }, +#ifdef BITE + DecryptedTransactions{ +#ifdef BITE + std::make_shared< DecryptedCTXTxsMap >(), +#endif // BITE + std::make_shared< DecryptedRegularTxsMap >() + }, +#endif + +#ifdef FAIR + 1, +#endif + 1 ); + BOOST_REQUIRE_THROW( cache.realIndexFromGapped( LatestBlock, 1 ), std::out_of_range ); + BOOST_REQUIRE_THROW( cache.realIndexFromGapped( LatestBlock, 2 ), std::out_of_range ); + BOOST_REQUIRE_THROW( cache.gappedIndexFromReal( LatestBlock, 2 ), std::out_of_range ); +#ifndef FAIR + BOOST_REQUIRE_THROW( cache.gappedIndexFromReal( LatestBlock, 0 ), std::out_of_range ); +#endif + BOOST_REQUIRE_THROW( cache.transactionPresent( LatestBlock, 2 ), std::out_of_range ); +} + +#endif + +BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE_END() diff --git a/test/unittests/mapreduce_consensus/ConsensusEngine.cpp b/test/unittests/mapreduce_consensus/ConsensusEngine.cpp index 062019e16..2b79c2900 100644 --- a/test/unittests/mapreduce_consensus/ConsensusEngine.cpp +++ b/test/unittests/mapreduce_consensus/ConsensusEngine.cpp @@ -41,8 +41,8 @@ #include #include -#include #include +#include #include @@ -87,7 +87,6 @@ class TestIpcClient : public jsonrpc::IClientConnector { }; class SingleNodeConsensusFixture : public ConsensusExtFace { - TransientDirectory m_tempDir; protected: @@ -112,18 +111,18 @@ class SingleNodeConsensusFixture : public ConsensusExtFace { ////////////////////////////////////////////// - setenv("DATA_DIR", m_tempDir.path().c_str(), 1); + setenv( "DATA_DIR", m_tempDir.path().c_str(), 1 ); - m_consensus.reset( new ConsensusEngine( - *this, 0, BlockHeader( chainParams.genesisBlock() ).timestamp(), - 0, std::map() ) ); + m_consensus.reset( + new ConsensusEngine( *this, 0, BlockHeader( chainParams.genesisBlock() ).timestamp(), 0, + std::map< std::string, std::uint64_t >() ) ); #ifdef FAIR m_consensus->parseFullConfigAndCreateNode( chainParams.getConfigForConsensus(), "" ); #else m_consensus->parseFullConfigAndCreateNode( chainParams.getOriginalJson(), "" ); #endif m_consensusThread = std::thread( [this]() { - sleep(1); + sleep( 1 ); m_consensus->startAll(); m_consensus->bootStrapAll(); } ); @@ -142,8 +141,8 @@ class SingleNodeConsensusFixture : public ConsensusExtFace { #ifdef BITE DecryptedTransactions /*_decryptedTransactions*/, #endif - uint64_t _timeStamp, - uint32_t _timeStampMs, uint64_t _blockID, u256 _gasPrice, u256 /*_stateRoot*/, uint64_t /*_winningNodeIndex*/ ) override { + uint64_t _timeStamp, uint32_t _timeStampMs, uint64_t _blockID, u256 _gasPrice, + u256 /*_stateRoot*/, uint64_t /*_winningNodeIndex*/ ) override { transaction_promise = decltype( transaction_promise )(); std::cerr << "Block arrived with " << _approvedTransactions.size() << " txns" << std::endl; @@ -159,7 +158,7 @@ class SingleNodeConsensusFixture : public ConsensusExtFace { m_consensusThread.join(); while ( m_consensus->getStatus() != CONSENSUS_EXITED ) { - timespec ms100{0, 100000000}; + timespec ms100{ 0, 100000000 }; nanosleep( &ms100, nullptr ); } } @@ -200,11 +199,10 @@ class ConsensusExtFaceFixture : public ConsensusExtFace { unique_ptr< WebThreeStubClient > rpcClient; unique_ptr< FixedAccountHolder > accountHolder; - dev::KeyPair coinbase{KeyPair::create()}; + dev::KeyPair coinbase{ KeyPair::create() }; public: ConsensusExtFaceFixture() { - chainParams = std::make_shared< ChainParams >(); chainParams->sealEngineName = NoProof::name(); chainParams->allowFutureBlocks = true; @@ -216,17 +214,24 @@ class ConsensusExtFaceFixture : public ConsensusExtFace { #ifdef FAIR - sChainNode node2{u256( 2 ), jsToAddress( "0x0000000000000000000000000000000000000000" ), jsToAddress( "0x0000000000000000000000000000000000000000" ), "127.0.0.12", u256( 11111 ), "::1", u256( 11111 ), u256( 1 ), "0xfa", {"0", "1", "0", "1"}}; + sChainNode node2{ u256( 2 ), jsToAddress( "0x0000000000000000000000000000000000000000" ), + jsToAddress( "0x0000000000000000000000000000000000000000" ), "127.0.0.12", + u256( 11111 ), "::1", u256( 11111 ), u256( 1 ), "0xfa", + { "0", + "1", + "0", + "1" } }; #else - sChainNode node2{u256( 2 ), "127.0.0.12", u256( 11111 ), "::1", u256( 11111 ), u256( 1 ), "0xfa", {"0", "1", "0", "1"}}; + sChainNode node2{ u256( 2 ), "127.0.0.12", u256( 11111 ), "::1", u256( 11111 ), u256( 1 ), + "0xfa", { "0", "1", "0", "1" } }; #endif chainParams->sChain.nodes.push_back( node2 ); ////////////////////////////////////////////// - m_consensus.reset( new ConsensusEngine( - *this, 0, BlockHeader( chainParams->genesisBlock() ).timestamp(), 0 , - std::map())); + m_consensus.reset( + new ConsensusEngine( *this, 0, BlockHeader( chainParams->genesisBlock() ).timestamp(), + 0, std::map< std::string, std::uint64_t >() ) ); #ifdef FAIR m_consensus->parseFullConfigAndCreateNode( chainParams->getConfigForConsensus(), "" ); #else @@ -246,10 +251,10 @@ class ConsensusExtFaceFixture : public ConsensusExtFace { auto monitor = make_shared< InstanceMonitor >("test"); - setenv("DATA_DIR", m_tempDir.path().c_str(), 1); - client.reset( - new eth::Client( chainParams, ( int ) chainParams->getNetworkId(), shared_ptr< GasPricer >(), - NULL, monitor, m_tempDir.path().c_str(), WithExisting::Kill, TransactionQueue::Limits{100000, 1024} ) ); + setenv( "DATA_DIR", m_tempDir.path().c_str(), 1 ); + client.reset( new eth::Client( chainParams, ( int ) chainParams->getNetworkId(), + shared_ptr< GasPricer >(), NULL, monitor, m_tempDir.path().c_str(), WithExisting::Kill, + TransactionQueue::Limits{ 100000, 1024 } ) ); client->injectSkaleHost(); client->startWorking(); @@ -257,12 +262,12 @@ class ConsensusExtFaceFixture : public ConsensusExtFace { client->setAuthor( coinbase.address() ); accountHolder.reset( new FixedAccountHolder( [&]() { return client.get(); }, {} ) ); - accountHolder->setAccounts( {coinbase} ); + accountHolder->setAccounts( { coinbase } ); using FullServer = ModularServer< rpc::EthFace, rpc::SkaleFace, rpc::Web3Face, rpc::DebugFace, rpc::TestFace >; - auto ethFace = new rpc::Eth( std::string(""), *client, *accountHolder.get() ); + auto ethFace = new rpc::Eth( std::string( "" ), *client, *accountHolder.get() ); rpcServer.reset( new FullServer( ethFace, new rpc::Skale( *client ), new rpc::Web3( /*web3->clientVersion()*/ ), new rpc::Debug( *client ), // TODO add @@ -272,7 +277,7 @@ class ConsensusExtFaceFixture : public ConsensusExtFace { rpcServer->addConnector( ipcServer ); ipcServer->StartListening(); - auto client = new TestIpcClient{*ipcServer}; + auto client = new TestIpcClient{ *ipcServer }; rpcClient = unique_ptr< WebThreeStubClient >( new WebThreeStubClient( *client ) ); } @@ -295,8 +300,7 @@ class ConsensusExtFaceFixture : public ConsensusExtFace { #ifdef BITE DecryptedTransactions _decryptedTransactions, #endif - uint64_t _timeStamp, - uint32_t /* timeStampMs */, uint64_t _blockID, u256 /*_gasPrice */, + uint64_t _timeStamp, uint32_t /* timeStampMs */, uint64_t _blockID, u256 /*_gasPrice */, u256 /*_stateRoot*/, uint64_t /*_winningNodeIndex*/ ) override { ( void ) _timeStamp; ( void ) _blockID; @@ -453,17 +457,17 @@ BOOST_AUTO_TEST_CASE( OneTransaction, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( TwoTransactions, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + TwoTransactions, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( DifferentTransactions, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + DifferentTransactions, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( MissingTransaction1, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + MissingTransaction1, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} -BOOST_AUTO_TEST_CASE( MissingTransaction2, - *boost::unit_test::precondition( dev::test::run_not_express ) ) {} +BOOST_AUTO_TEST_CASE( + MissingTransaction2, *boost::unit_test::precondition( dev::test::run_not_express ) ) {} BOOST_AUTO_TEST_SUITE_END()