Skip to content

Commit

Permalink
Merge pull request #2020 from skalenetwork/develop-to-3.20.0
Browse files Browse the repository at this point in the history
Develop to 3.20.0
  • Loading branch information
DmytroNazarenko authored Oct 10, 2024
2 parents 244bcb8 + 56a1549 commit bdf628b
Show file tree
Hide file tree
Showing 17 changed files with 1,609 additions and 125 deletions.
1,134 changes: 1,067 additions & 67 deletions docs/json-rpc-interface.md

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions libethereum/Block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,7 @@ pair< TransactionReceipts, bool > Block::sync(
// caller if we hit the limit

for ( Transaction& transaction : transactions ) {
transaction.checkOutExternalGas(
_bc.chainParams(), _bc.info().timestamp(), _bc.number(), false );
transaction.checkOutExternalGas( _bc.chainParams(), _bc.info().timestamp(), _bc.number() );
}

assert( _bc.currentHash() == m_currentBlock.parentHash() );
Expand Down Expand Up @@ -633,7 +632,7 @@ u256 Block::enact( VerifiedBlockRef const& _block, BlockChain const& _bc ) {
// << state().getNonce( tr.from() ) << ") value = " << tr.value() <<
// endl;
const_cast< Transaction& >( tr ).checkOutExternalGas(
_bc.chainParams(), _bc.info().timestamp(), _bc.number(), false );
_bc.chainParams(), _bc.info().timestamp(), _bc.number() );
execute( _bc.lastBlockHashes(), tr );
// cerr << "Now: "
// << "State #" << state().getNonce( tr.from() ) << endl;
Expand Down
4 changes: 2 additions & 2 deletions libethereum/Client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1172,7 +1172,7 @@ h256 Client::importTransaction( Transaction const& _t ) {
// We need to check external gas under mutex to be sure about current block number
// correctness
const_cast< Transaction& >( _t ).checkOutExternalGas(
chainParams(), bc().info().timestamp(), number(), false );
chainParams(), bc().info().timestamp(), number() );
}

Executive::verifyTransaction( _t, bc().info().timestamp(),
Expand Down Expand Up @@ -1348,7 +1348,7 @@ Json::Value Client::traceBlock( BlockNumber _blockNumber, Json::Value const& _js
Transaction tx = transactions.at( k );
auto hashString = toHexPrefixed( tx.sha3() );
transactionLog["txHash"] = hashString;
tx.checkOutExternalGas( chainParams(), bc().info().timestamp(), number(), false );
tx.checkOutExternalGas( chainParams(), bc().info().timestamp(), number() );
auto tracer =
std::make_shared< AlethStandardTrace >( tx, historicBlock.author(), traceOptions );
auto executionResult =
Expand Down
4 changes: 2 additions & 2 deletions libethereum/ClientBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ std::pair< bool, ExecutionResult > ClientBase::estimateGasStep( int64_t _gas, Bl
t.forceChainId( chainId() );
t.ignoreExternalGas();
EnvInfo const env( _pendingBlock.info(), bc().lastBlockHashes(),
_pendingBlock.previousInfo().timestamp(), 0, _gas );
// Make a copy of state!! It will be deleted after step!
_pendingBlock.previousInfo().timestamp(), 0, _gas, bc().chainParams().chainID );
// Make a copy of the state, it will be deleted after this step
State tempState = _latestBlock.mutableState();
tempState.addBalance( _from, ( u256 )( t.gas() * t.gasPrice() + t.value() ) );
ExecutionResult executionResult =
Expand Down
4 changes: 4 additions & 0 deletions libethereum/SchainPatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ SchainPatchEnum getEnumForPatchName( const std::string& _patchName ) {
return SchainPatchEnum::VerifyBlsSyncPatch;
else if ( _patchName == "FlexibleDeploymentPatch" )
return SchainPatchEnum::FlexibleDeploymentPatch;
else if ( _patchName == "ExternalGasPatch" )
return SchainPatchEnum::ExternalGasPatch;
else
throw std::out_of_range( _patchName );
}
Expand Down Expand Up @@ -72,6 +74,8 @@ std::string getPatchNameForEnum( SchainPatchEnum _enumValue ) {
return "VerifyBlsSyncPatch";
case SchainPatchEnum::FlexibleDeploymentPatch:
return "FlexibleDeploymentPatch";
case SchainPatchEnum::ExternalGasPatch:
return "ExternalGasPatch";
default:
throw std::out_of_range(
"UnknownPatch #" + std::to_string( static_cast< size_t >( _enumValue ) ) );
Expand Down
5 changes: 5 additions & 0 deletions libethereum/SchainPatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,9 @@ DEFINE_AMNESIC_PATCH( VerifyBlsSyncPatch );
*/
DEFINE_SIMPLE_PATCH( FlexibleDeploymentPatch );

/*
* Context: fix externalGas calculation
*/
DEFINE_SIMPLE_PATCH( ExternalGasPatch );

#endif // SCHAINPATCH_H
1 change: 1 addition & 0 deletions libethereum/SchainPatchEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ enum class SchainPatchEnum {
EIP1559TransactionsPatch,
VerifyBlsSyncPatch,
FlexibleDeploymentPatch,
ExternalGasPatch,
PatchesCount
};

Expand Down
4 changes: 2 additions & 2 deletions libethereum/SkaleHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ void SkaleHost::createBlock( const ConsensusExtFace::transactions_vector& _appro
if ( m_m_transaction_cache.find( sha.asArray() ) != m_m_transaction_cache.cend() ) {
Transaction t = m_m_transaction_cache.at( sha.asArray() );
t.checkOutExternalGas(
m_client.chainParams(), latestInfo.timestamp(), m_client.number(), true );
m_client.chainParams(), latestInfo.timestamp(), m_client.number() );
out_txns.push_back( t );
LOG( m_debugLogger ) << "Dropping good txn " << sha << std::endl;
m_debugTracer.tracepoint( "drop_good" );
Expand All @@ -675,7 +675,7 @@ void SkaleHost::createBlock( const ConsensusExtFace::transactions_vector& _appro
Transaction t( data, CheckTransaction::Everything, true,
EIP1559TransactionsPatch::isEnabledInWorkingBlock() );
t.checkOutExternalGas(
m_client.chainParams(), latestInfo.timestamp(), m_client.number(), false );
m_client.chainParams(), latestInfo.timestamp(), m_client.number() );
out_txns.push_back( t );
LOG( m_debugLogger ) << "Will import consensus-born txn";
m_debugTracer.tracepoint( "import_consensus_born" );
Expand Down
19 changes: 15 additions & 4 deletions libethereum/Transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,12 +195,23 @@ u256 Transaction::gasPrice() const {
}
}

void Transaction::checkOutExternalGas( const ChainParams& _cp, time_t _committedBlockTimestamp,
uint64_t _committedBlockNumber, bool _force ) {
void Transaction::checkOutExternalGas(
const ChainParams& _cp, time_t _committedBlockTimestamp, uint64_t _committedBlockNumber ) {
u256 const& difficulty = _cp.externalGasDifficulty;
assert( difficulty > 0 );
if ( ( _force || !m_externalGasIsChecked ) && !isInvalid() ) {
h256 hash = dev::sha3( sender().ref() ) ^ dev::sha3( nonce() ) ^ dev::sha3( gasPrice() );
if ( !isInvalid() ) {
h256 hash;
if ( !ExternalGasPatch::isEnabledWhen( _committedBlockTimestamp ) ) {
hash = dev::sha3( sender().ref() ) ^ dev::sha3( nonce() ) ^ dev::sha3( gasPrice() );
} else {
// reset externalGas value
// we may face patch activation after txn was added to the queue but before it was
// executed. therefore we need to recalculate externalGas
m_externalGasIsChecked = false;
m_externalGas.reset();
hash = dev::sha3( sender().ref() ) ^ dev::sha3( nonce() ) ^
dev::sha3( TransactionBase::gasPrice() );
}
if ( !hash ) {
hash = h256( 1 );
}
Expand Down
4 changes: 2 additions & 2 deletions libethereum/Transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ class Transaction : public TransactionBase {

u256 gasPrice() const;

void checkOutExternalGas( const ChainParams& _cp, time_t _committedBlockTimestamp,
uint64_t _committedBlockNumber, bool _force );
void checkOutExternalGas(
const ChainParams& _cp, time_t _committedBlockTimestamp, uint64_t _committedBlockNumber );

void ignoreExternalGas() {
m_externalGasIsChecked = true;
Expand Down
53 changes: 46 additions & 7 deletions libskale/State.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ using dev::eth::TransactionReceipt;
#define ETH_VMTRACE 0
#endif

const std::map< std::pair< uint64_t, std::string >, uint64_t > State::txnsToSkipExecution{
{ { 1020352220, "3464b9a165a29fde2ce644882e82d99edbff5f530413f6cc18b26bf97e6478fb" }, 40729 },
{ { 1482601649, "d3f25440b752f4ad048b618554f71cec08a73af7bf88b6a7d55581f3a792d823" }, 32151 },
{ { 974399131, "fcd7ecb7c359af0a93a02e5d84957e0c6f90da4584c058e9c5e988b27a237693" }, 23700 },
{ { 1482601649, "6f2074cfe73a258c049ac2222101b7020461c2d40dcd5ab9587d5bbdd13e4c68" }, 55293 },
{ { 21, "95fb5557db8cc6de0aff3a64c18a6d9378b0d312b24f5d77e8dbf5cc0612d74f" }, 23232 }
}; // the last value is for the test

State::State( dev::u256 const& _accountStartNonce, boost::filesystem::path const& _dbPath,
dev::h256 const& _genesis, BaseState _bs, dev::u256 _initialFunds,
dev::s256 _contractStorageLimit )
Expand Down Expand Up @@ -1004,6 +1012,14 @@ bool State::empty() const {
return false;
}

bool State::ifShouldSkipExecution( uint64_t _chainId, const dev::h256& _hash ) {
return txnsToSkipExecution.count( { _chainId, _hash.hex() } ) > 0;
}

uint64_t State::getGasUsedForSkippedTransaction( uint64_t _chainId, const dev::h256& _hash ) {
return txnsToSkipExecution.at( { _chainId, _hash.hex() } );
}

std::pair< ExecutionResult, TransactionReceipt > State::execute( EnvInfo const& _envInfo,
eth::ChainOperationParams const& _chainParams, Transaction const& _t, Permanence _p,
OnOpFunc const& _onOp ) {
Expand All @@ -1024,7 +1040,15 @@ std::pair< ExecutionResult, TransactionReceipt > State::execute( EnvInfo const&
onOp = e.simpleTrace();
#endif
u256 const startGasUsed = _envInfo.gasUsed();
bool const statusCode = executeTransaction( e, _t, onOp );
bool statusCodeTmp = false;
if ( _p == Permanence::Committed && ifShouldSkipExecution( _chainParams.chainID, _t.sha3() ) ) {
e.initialize( _t );
e.execute();
statusCodeTmp = false;
} else {
statusCodeTmp = executeTransaction( e, _t, onOp );
}
bool const statusCode = statusCodeTmp;

std::string strRevertReason;
if ( res.excepted == dev::eth::TransactionException::RevertInstruction ) {
Expand Down Expand Up @@ -1056,9 +1080,17 @@ std::pair< ExecutionResult, TransactionReceipt > State::execute( EnvInfo const&
// shaLastTx.hex() << "\n";

TransactionReceipt receipt =
_envInfo.number() >= _chainParams.byzantiumForkBlock ?
TransactionReceipt( statusCode, startGasUsed + e.gasUsed(), e.logs() ) :
TransactionReceipt( EmptyTrie, startGasUsed + e.gasUsed(), e.logs() );
TransactionReceipt( statusCode, startGasUsed + e.gasUsed(), e.logs() );
if ( _p == Permanence::Committed &&
ifShouldSkipExecution( _chainParams.chainID, _t.sha3() ) ) {
receipt = TransactionReceipt( statusCode,
startGasUsed + getGasUsedForSkippedTransaction( _chainParams.chainID, _t.sha3() ),
e.logs() );
} else {
receipt = _envInfo.number() >= _chainParams.byzantiumForkBlock ?
TransactionReceipt( statusCode, startGasUsed + e.gasUsed(), e.logs() ) :
TransactionReceipt( EmptyTrie, startGasUsed + e.gasUsed(), e.logs() );
}
receipt.setRevertReason( strRevertReason );
m_db_ptr->addReceiptToPartials( receipt );
m_fs_ptr->commit();
Expand All @@ -1075,9 +1107,16 @@ std::pair< ExecutionResult, TransactionReceipt > State::execute( EnvInfo const&
}

TransactionReceipt receipt =
_envInfo.number() >= _chainParams.byzantiumForkBlock ?
TransactionReceipt( statusCode, startGasUsed + e.gasUsed(), e.logs() ) :
TransactionReceipt( EmptyTrie, startGasUsed + e.gasUsed(), e.logs() );
TransactionReceipt( statusCode, startGasUsed + e.gasUsed(), e.logs() );
if ( _p == Permanence::Committed && ifShouldSkipExecution( _chainParams.chainID, _t.sha3() ) ) {
receipt = TransactionReceipt( statusCode,
startGasUsed + getGasUsedForSkippedTransaction( _chainParams.chainID, _t.sha3() ),
e.logs() );
} else {
receipt = _envInfo.number() >= _chainParams.byzantiumForkBlock ?
TransactionReceipt( statusCode, startGasUsed + e.gasUsed(), e.logs() ) :
TransactionReceipt( EmptyTrie, startGasUsed + e.gasUsed(), e.logs() );
}
receipt.setRevertReason( strRevertReason );

return make_pair( res, receipt );
Expand Down
6 changes: 6 additions & 0 deletions libskale/State.h
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,10 @@ class State {
}
};

static bool ifShouldSkipExecution( uint64_t _chainId, const dev::h256& _hash );

static uint64_t getGasUsedForSkippedTransaction( uint64_t _chainId, const dev::h256& _hash );

public:
bool checkVersion() const;

Expand Down Expand Up @@ -508,6 +512,8 @@ class State {
uint64_t _batchNumber );
#endif

static const std::map< std::pair< uint64_t, std::string >, uint64_t > txnsToSkipExecution;

public:
std::shared_ptr< batched_io::db_face > db() {
std::shared_ptr< batched_io::db_face > pDB;
Expand Down
24 changes: 19 additions & 5 deletions libweb3jsonrpc/Eth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ const uint64_t MAX_CALL_CACHE_ENTRIES = 1024;
const uint64_t MAX_RECEIPT_CACHE_ENTRIES = 1024;
const u256 MAX_BLOCK_RANGE = 1024;

// Geth compatible error code for a revert
const uint64_t REVERT_RPC_ERROR_CODE = 3;

#ifdef HISTORIC_STATE

using namespace dev::rpc::_detail;
Expand Down Expand Up @@ -486,11 +489,13 @@ string Eth::eth_call( TransactionSkeleton& t, string const&
strRevertReason = skutils::eth::call_error_message_2_str( er.output );
if ( strRevertReason.empty() )
strRevertReason = "EVM revert instruction without description message";
std::string strTx = t.toString();
std::string strOut = "Error message from eth_call(): " + strRevertReason +
", with call arguments: " + strTx +
", and using blockNumber=" + blockNumber;
cerror << strOut;

if ( !er.output.empty() ) {
Json::Value output = toJS( er.output );
BOOST_THROW_EXCEPTION(
JsonRpcException( REVERT_RPC_ERROR_CODE, strRevertReason, output ) );
}

throw std::logic_error( strRevertReason );
}

Expand All @@ -515,11 +520,20 @@ string Eth::eth_estimateGas( Json::Value const& _json ) {
strRevertReason = skutils::eth::call_error_message_2_str( result.second.output );
if ( strRevertReason.empty() )
strRevertReason = "EVM revert instruction without description message";

if ( !result.second.output.empty() ) {
Json::Value output = toJS( result.second.output );
BOOST_THROW_EXCEPTION(
JsonRpcException( REVERT_RPC_ERROR_CODE, strRevertReason, output ) );
}

throw std::logic_error( strRevertReason );
}
return toJS( result.first );
} catch ( std::logic_error& error ) {
throw error;
} catch ( jsonrpc::JsonRpcException& error ) {
throw error;
} catch ( ... ) {
BOOST_THROW_EXCEPTION( JsonRpcException( Errors::ERROR_RPC_INVALID_PARAMS ) );
}
Expand Down
35 changes: 27 additions & 8 deletions libweb3jsonrpc/JsonHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,18 @@ Json::Value toJson( dev::eth::Transaction const& _t, std::pair< h256, unsigned >
res["blockHash"] = toJS( _location.first );
res["transactionIndex"] = toJS( _location.second );
res["blockNumber"] = toJS( _blockNumber );
res["v"] = _t.isReplayProtected() ? toJS( 2 * _t.chainId() + 35 + _t.signature().v ) :
toJS( 27 + _t.signature().v );
if ( _t.txType() == dev::eth::TransactionType::Legacy )
if ( _t.isReplayProtected() )
res["v"] = toJS( 2 * _t.chainId() + 35 + _t.signature().v );
else
res["v"] = toJS( 27 + _t.signature().v );
else
res["v"] = toJS( _t.signature().v );
res["r"] = toJS( _t.signature().r );
res["s"] = toJS( _t.signature().s );
res["type"] = toJS( int( _t.txType() ) );
if ( _t.txType() != dev::eth::TransactionType::Legacy ) {
res["chainId"] = toJS( _t.chainId() );
res["yParity"] = toJS( _t.signature().v );
res["accessList"] = Json::Value( Json::arrayValue );
for ( const auto& d : _t.accessList() ) {
Expand All @@ -119,7 +125,7 @@ Json::Value toJson( dev::eth::Transaction const& _t, std::pair< h256, unsigned >
}
res["accessList"].append( accessList );
}
if ( _t.txType() != dev::eth::TransactionType::Type1 ) {
if ( _t.txType() == dev::eth::TransactionType::Type2 ) {
res["maxPriorityFeePerGas"] = toJS( _t.maxPriorityFeePerGas() );
res["maxFeePerGas"] = toJS( _t.maxFeePerGas() );
}
Expand Down Expand Up @@ -349,9 +355,16 @@ Json::Value toJson( dev::eth::Transaction const& _t ) {
res["nonce"] = toJS( _t.nonce() );
res["r"] = toJS( _t.signature().r );
res["s"] = toJS( _t.signature().s );
res["v"] = toJS( _t.signature().v );
if ( _t.txType() == dev::eth::TransactionType::Legacy )
if ( _t.isReplayProtected() )
res["v"] = toJS( 2 * _t.chainId() + 35 + _t.signature().v );
else
res["v"] = toJS( 27 + _t.signature().v );
else
res["v"] = toJS( _t.signature().v );
res["type"] = toJS( int( _t.txType() ) );
if ( _t.txType() != dev::eth::TransactionType::Legacy ) {
res["chainId"] = toJS( _t.chainId() );
res["yParity"] = toJS( _t.signature().v );
res["accessList"] = Json::Value( Json::arrayValue );
for ( const auto& d : _t.accessList() ) {
Expand All @@ -364,7 +377,7 @@ Json::Value toJson( dev::eth::Transaction const& _t ) {
}
res["accessList"].append( accessList );
}
if ( _t.txType() != dev::eth::TransactionType::Type1 ) {
if ( _t.txType() == dev::eth::TransactionType::Type2 ) {
res["maxPriorityFeePerGas"] = toJS( _t.maxPriorityFeePerGas() );
res["maxFeePerGas"] = toJS( _t.maxFeePerGas() );
}
Expand Down Expand Up @@ -398,12 +411,18 @@ Json::Value toJson( dev::eth::LocalisedTransaction const& _t ) {
res["to"] = _t.isCreation() ? Json::Value() : toJS( _t.receiveAddress() );
res["transactionIndex"] = toJS( _t.transactionIndex() );
res["value"] = toJS( _t.value() );
res["v"] = _t.isReplayProtected() ? toJS( 2 * _t.chainId() + 35 + _t.signature().v ) :
toJS( 27 + _t.signature().v );
if ( _t.txType() == dev::eth::TransactionType::Legacy )
if ( _t.isReplayProtected() )
res["v"] = toJS( 2 * _t.chainId() + 35 + _t.signature().v );
else
res["v"] = toJS( 27 + _t.signature().v );
else
res["v"] = toJS( _t.signature().v );
res["r"] = toJS( _t.signature().r.hex() );
res["s"] = toJS( _t.signature().s.hex() );
res["type"] = toJS( int( _t.txType() ) );
if ( _t.txType() != dev::eth::TransactionType::Legacy ) {
res["chainId"] = toJS( _t.chainId() );
res["yParity"] = toJS( _t.signature().v );
res["accessList"] = Json::Value( Json::arrayValue );
for ( const auto& d : _t.accessList() ) {
Expand All @@ -418,7 +437,7 @@ Json::Value toJson( dev::eth::LocalisedTransaction const& _t ) {
}
if ( _t.txType() != dev::eth::TransactionType::Type1 ) {
res["maxPriorityFeePerGas"] = toJS( _t.maxPriorityFeePerGas() );
res["maxFeePerGas"] = toJS( _t.maxPriorityFeePerGas() );
res["maxFeePerGas"] = toJS( _t.maxFeePerGas() );
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions libweb3jsonrpc/rapidjson_handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ void wrapJsonRpcException( const rapidjson::Document& /*joRequest*/,
Json::Value joData = exception.GetData();
if ( joData != Json::nullValue ) {
joError.AddMember( "data", rapidjson::Value(), joResponse.GetAllocator() );
Json::FastWriter fastWriter;
std::string data = fastWriter.write( joData );
std::string data = joData.asString();
joError["data"].SetString( data.c_str(), data.size(), joResponse.GetAllocator() );
}

Expand Down
Loading

0 comments on commit bdf628b

Please sign in to comment.