Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IS 1074 fix externalGas calculation #1999

Merged
merged 9 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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: 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
8 changes: 4 additions & 4 deletions test/unittests/libethereum/SkaleHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,7 @@ BOOST_AUTO_TEST_CASE( transactionDropReceive

// 1st tx
Transaction tx1 = fixture.tx_from_json( json );
tx1.checkOutExternalGas( client->chainParams(), client->latestBlock().info().timestamp(), client->number(), false );
tx1.checkOutExternalGas( client->chainParams(), client->latestBlock().info().timestamp(), client->number() );

// submit it!
tq->import( tx1 );
Expand Down Expand Up @@ -964,7 +964,7 @@ BOOST_AUTO_TEST_CASE( transactionDropQueue,

// 1st tx
Transaction tx1 = fixture.tx_from_json( json );
tx1.checkOutExternalGas( client->chainParams(), client->latestBlock().info().timestamp(), client->number(), false );
tx1.checkOutExternalGas( client->chainParams(), client->latestBlock().info().timestamp(), client->number() );

// submit it!
tq->import( tx1 );
Expand Down Expand Up @@ -1025,7 +1025,7 @@ BOOST_AUTO_TEST_CASE( transactionDropByGasPrice

// 1st tx
Transaction tx1 = fixture.tx_from_json( json );
tx1.checkOutExternalGas( client->chainParams(), client->latestBlock().info().timestamp(), client->number(), false );
tx1.checkOutExternalGas( client->chainParams(), client->latestBlock().info().timestamp(), client->number() );

// submit it!
tq->import( tx1 );
Expand Down Expand Up @@ -1094,7 +1094,7 @@ BOOST_AUTO_TEST_CASE( transactionDropByGasPriceReceive

// 1st tx
Transaction tx1 = fixture.tx_from_json( json );
tx1.checkOutExternalGas( client->chainParams(), client->latestBlock().info().timestamp(), client->number(), false );
tx1.checkOutExternalGas( client->chainParams(), client->latestBlock().info().timestamp(), client->number() );

// receive it!
skaleHost->receiveTransaction( toJS( tx1.toBytes() ) );
Expand Down
Loading
Loading