From 2b52c2138a77ae6e6b23d5977da2648d05af57a9 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Wed, 8 Jan 2025 17:06:54 +0000 Subject: [PATCH 1/7] #1994 fix maxFeePerGas check --- libethcore/TransactionBase.cpp | 20 +++++++++++--------- libethcore/TransactionBase.h | 15 +++++++++------ 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/libethcore/TransactionBase.cpp b/libethcore/TransactionBase.cpp index 55dbeb154..8d6fd486c 100644 --- a/libethcore/TransactionBase.cpp +++ b/libethcore/TransactionBase.cpp @@ -48,7 +48,6 @@ std::vector< bytes > validateAccessListRLP( const RLP& _data ) { return {}; } - for ( const auto& d : rlpList ) { if ( !d.isList() ) BOOST_THROW_EXCEPTION( InvalidTransactionFormat() << errinfo_comment( @@ -236,8 +235,8 @@ void TransactionBase::fillFromBytesType1( } } -void TransactionBase::fillFromBytesType2( - bytesConstRef _rlpData, CheckTransaction _checkSig, bool _allowInvalid ) { +void TransactionBase::fillFromBytesType2( bytesConstRef _rlpData, CheckTransaction _checkSig, + bool _allowInvalid, bool _maxFeePerGasPatchEnabled ) { bytes croppedRlp( _rlpData.begin() + 1, _rlpData.end() ); RLP const rlp( croppedRlp ); try { @@ -249,7 +248,9 @@ void TransactionBase::fillFromBytesType2( m_nonce = rlp[1].toInt< u256 >(); m_maxPriorityFeePerGas = rlp[2].toInt< u256 >(); m_maxFeePerGas = rlp[3].toInt< u256 >(); - if ( m_maxPriorityFeePerGas > m_maxPriorityFeePerGas ) + + auto toCompare = _maxFeePerGasPatchEnabled ? m_maxPriorityFeePerGas : m_maxFeePerGas; + if ( m_maxPriorityFeePerGas > toCompare ) BOOST_THROW_EXCEPTION( InvalidTransactionFormat() << errinfo_comment( "maxFeePerGas cannot be less than maxPriorityFeePerGas (The " "total must be the larger of the two)" ) ); @@ -305,7 +306,7 @@ void TransactionBase::fillFromBytesType2( } void TransactionBase::fillFromBytesByType( bytesConstRef _rlpData, CheckTransaction _checkSig, - bool _allowInvalid, TransactionType _type ) { + bool _allowInvalid, TransactionType _type, bool _maxFeePerGasPatchEnabled ) { switch ( _type ) { case TransactionType::Legacy: fillFromBytesLegacy( _rlpData, _checkSig, _allowInvalid ); @@ -314,7 +315,7 @@ void TransactionBase::fillFromBytesByType( bytesConstRef _rlpData, CheckTransact fillFromBytesType1( _rlpData, _checkSig, _allowInvalid ); break; case TransactionType::Type2: - fillFromBytesType2( _rlpData, _checkSig, _allowInvalid ); + fillFromBytesType2( _rlpData, _checkSig, _allowInvalid, _maxFeePerGasPatchEnabled ); break; default: BOOST_THROW_EXCEPTION( @@ -331,13 +332,14 @@ TransactionType TransactionBase::getTransactionType( bytesConstRef _rlp ) { return TransactionType( _rlp[0] ); } -TransactionBase::TransactionBase( - bytesConstRef _rlpData, CheckTransaction _checkSig, bool _allowInvalid, bool _eip1559Enabled ) { +TransactionBase::TransactionBase( bytesConstRef _rlpData, CheckTransaction _checkSig, + bool _allowInvalid, bool _eip1559Enabled, bool _maxFeePerGasPatchEnabled ) { MICROPROFILE_SCOPEI( "TransactionBase", "ctor", MP_GOLD2 ); try { if ( _eip1559Enabled ) { TransactionType txnType = getTransactionType( _rlpData ); - fillFromBytesByType( _rlpData, _checkSig, _allowInvalid, txnType ); + fillFromBytesByType( + _rlpData, _checkSig, _allowInvalid, txnType, _maxFeePerGasPatchEnabled ); } else { fillFromBytesLegacy( _rlpData, _checkSig, _allowInvalid ); } diff --git a/libethcore/TransactionBase.h b/libethcore/TransactionBase.h index 36a3cd192..a2c65635c 100644 --- a/libethcore/TransactionBase.h +++ b/libethcore/TransactionBase.h @@ -99,12 +99,15 @@ class TransactionBase { /// Constructs a transaction from the given RLP. explicit TransactionBase( bytesConstRef _rlp, CheckTransaction _checkSig, - bool _allowInvalid = false, bool _eip1559Enabled = false ); + bool _allowInvalid = false, bool _eip1559Enabled = false, + bool _maxFeePerGasPatchEnabled = false ); /// Constructs a transaction from the given RLP. explicit TransactionBase( bytes const& _rlp, CheckTransaction _checkSig, - bool _allowInvalid = false, bool _eip1559Enabled = false ) - : TransactionBase( &_rlp, _checkSig, _allowInvalid, _eip1559Enabled ) {} + bool _allowInvalid = false, bool _eip1559Enabled = false, + bool _maxFeePerGasPatchEnabled = false ) + : TransactionBase( + &_rlp, _checkSig, _allowInvalid, _eip1559Enabled, _maxFeePerGasPatchEnabled ) {} TransactionBase( TransactionBase const& ) = default; @@ -313,13 +316,13 @@ class TransactionBase { /// Constructs a transaction from the given RLP and transaction type. void fillFromBytesByType( bytesConstRef _rlpData, CheckTransaction _checkSig, - bool _allowInvalid, TransactionType _type ); + bool _allowInvalid, TransactionType _type, bool _maxFeePerGasPatchEnabled ); void fillFromBytesLegacy( bytesConstRef _rlpData, CheckTransaction _checkSig, bool _allowInvalid ); void fillFromBytesType1( bytesConstRef _rlpData, CheckTransaction _checkSig, bool _allowInvalid ); - void fillFromBytesType2( - bytesConstRef _rlpData, CheckTransaction _checkSig, bool _allowInvalid ); + void fillFromBytesType2( bytesConstRef _rlpData, CheckTransaction _checkSig, bool _allowInvalid, + bool _maxFeePerGasPatchEnabled ); void streamLegacyTransaction( RLPStream& _s, IncludeSignature _sig, bool _forEip155hash ) const; void streamType1Transaction( RLPStream& _s, IncludeSignature _sig ) const; From 2c1029d07ffa2816cdeb73eb0be1cc007d28f309 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Wed, 8 Jan 2025 17:13:50 +0000 Subject: [PATCH 2/7] #1994 add maxFeePerGas patch --- libethereum/SchainPatch.cpp | 4 ++++ libethereum/SchainPatch.h | 6 ++++++ libethereum/SchainPatchEnum.h | 1 + 3 files changed, 11 insertions(+) diff --git a/libethereum/SchainPatch.cpp b/libethereum/SchainPatch.cpp index fde678f6c..322feb419 100644 --- a/libethereum/SchainPatch.cpp +++ b/libethereum/SchainPatch.cpp @@ -38,6 +38,8 @@ SchainPatchEnum getEnumForPatchName( const std::string& _patchName ) { return SchainPatchEnum::FlexibleDeploymentPatch; else if ( _patchName == "ExternalGasPatch" ) return SchainPatchEnum::ExternalGasPatch; + else if ( _patchName == "MaxFeePerGasPatch" ) + return SchainPatchEnum::MaxFeePerGasPatch; else throw std::out_of_range( _patchName ); } @@ -76,6 +78,8 @@ std::string getPatchNameForEnum( SchainPatchEnum _enumValue ) { return "FlexibleDeploymentPatch"; case SchainPatchEnum::ExternalGasPatch: return "ExternalGasPatch"; + case SchainPatchEnum::MaxFeePerGasPatch: + return "MaxFeePerGasPatch"; default: throw std::out_of_range( "UnknownPatch #" + std::to_string( static_cast< size_t >( _enumValue ) ) ); diff --git a/libethereum/SchainPatch.h b/libethereum/SchainPatch.h index 75f2c878f..654947f28 100644 --- a/libethereum/SchainPatch.h +++ b/libethereum/SchainPatch.h @@ -151,4 +151,10 @@ DEFINE_SIMPLE_PATCH( FlexibleDeploymentPatch ); */ DEFINE_SIMPLE_PATCH( ExternalGasPatch ); +/* + * Context: fix the check in transaction constructor + * maxFeePerGas cannot be less than maxPriorityFeePerGas + */ +DEFINE_SIMPLE_PATCH( MaxFeePerGasPatch ); + #endif // SCHAINPATCH_H diff --git a/libethereum/SchainPatchEnum.h b/libethereum/SchainPatchEnum.h index 69f023143..8a96a8e75 100644 --- a/libethereum/SchainPatchEnum.h +++ b/libethereum/SchainPatchEnum.h @@ -21,6 +21,7 @@ enum class SchainPatchEnum { VerifyBlsSyncPatch, FlexibleDeploymentPatch, ExternalGasPatch, + MaxFeePerGasPatch, PatchesCount }; From a571b80ca4e0a6ebc1d361e1087dd0e97e1e4157 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Wed, 8 Jan 2025 18:41:32 +0000 Subject: [PATCH 3/7] #1994 add unit test --- libethcore/TransactionBase.cpp | 2 +- test/unittests/libweb3jsonrpc/jsonrpc.cpp | 57 +++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/libethcore/TransactionBase.cpp b/libethcore/TransactionBase.cpp index 8d6fd486c..5282e791b 100644 --- a/libethcore/TransactionBase.cpp +++ b/libethcore/TransactionBase.cpp @@ -249,7 +249,7 @@ void TransactionBase::fillFromBytesType2( bytesConstRef _rlpData, CheckTransacti m_maxPriorityFeePerGas = rlp[2].toInt< u256 >(); m_maxFeePerGas = rlp[3].toInt< u256 >(); - auto toCompare = _maxFeePerGasPatchEnabled ? m_maxPriorityFeePerGas : m_maxFeePerGas; + auto toCompare = _maxFeePerGasPatchEnabled ? m_maxFeePerGas : m_maxPriorityFeePerGas; if ( m_maxPriorityFeePerGas > toCompare ) BOOST_THROW_EXCEPTION( InvalidTransactionFormat() << errinfo_comment( "maxFeePerGas cannot be less than maxPriorityFeePerGas (The " diff --git a/test/unittests/libweb3jsonrpc/jsonrpc.cpp b/test/unittests/libweb3jsonrpc/jsonrpc.cpp index 948b90ec3..8dc5bf95e 100644 --- a/test/unittests/libweb3jsonrpc/jsonrpc.cpp +++ b/test/unittests/libweb3jsonrpc/jsonrpc.cpp @@ -3337,6 +3337,63 @@ BOOST_AUTO_TEST_CASE( vInTxnSignature ) { BOOST_REQUIRE( v < 2 && v >= 0 ); } +BOOST_AUTO_TEST_CASE( maxFeePerGasPatch ) { + 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 maxFeePerGasPatchActivationTimestamp = time(nullptr) + 10; + ret["skaleConfig"]["sChain"]["MaxFeePerGasPatchTimestamp"] = maxFeePerGasPatchActivationTimestamp; + 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" ) ); + + // send a txn with maxPriorityFeePerGas > maxFeePerGas before MaxFeePerGasPatchTimestamp + txHash = fixture.rpcClient->eth_sendRawTransaction( "0x02f86d8197808504a817c8018504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b8080c001a0db2fe04a66fa54bfe9c6e0166d85a31b34cbff10dbde0e0584081aec6bb33c30a06b956a49c52f1460da9f93fc495eaa863ae5a8c91ee9230c2f3976f5e74d4f47" ); + 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() ) ); + + 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 ); + + // send a txn with maxPriorityFeePerGas > maxFeePerGas before MaxFeePerGasPatchTimestamp, it should fail + BOOST_REQUIRE_THROW( fixture.rpcClient->eth_sendRawTransaction( "0x02f86d8197018504a817c8018504a817c800827530947d36af85a184e220a656525fcbb9a63b9ab3c12b8080c080a0aea5ff86373cbbbb33c9f3e9a25ceb9a694ee71beff452a4d29903d73fd30ca9a00458d4f7d54be178b42d230cc5a4740540d55b8ca0f9c74c79c1d49f6686b1e6" ), jsonrpc::JsonRpcException ); // INVALID_PARAMS +} + BOOST_AUTO_TEST_CASE( etherbase_generation2 ) { JsonRpcFixture fixture(c_genesisGeneration2ConfigString, false, false, true); string etherbase = fixture.rpcClient->eth_coinbase(); From 3f1e2a52ae2847b3fe488d37a9e14596f5ca22ec Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Wed, 8 Jan 2025 18:53:41 +0000 Subject: [PATCH 4/7] #1994 use maxFeePerGasPatch --- libethereum/BlockChain.cpp | 2 ++ libethereum/ClientBase.cpp | 10 ++++++++++ libethereum/SkaleHost.cpp | 6 ++++-- libethereum/Transaction.cpp | 15 ++++++++------- libethereum/Transaction.h | 5 +++-- libethereum/TransactionQueue.cpp | 8 +++++--- libweb3jsonrpc/Eth.cpp | 6 ++++-- 7 files changed, 36 insertions(+), 16 deletions(-) diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index e2339685e..0c77eb8f9 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -1742,6 +1742,8 @@ VerifiedBlockRef BlockChain::verifyBlock( bytesConstRef _block, CheckTransaction::None, false, EIP1559TransactionsPatch::isEnabledWhen( + this->info( numberHash( h.number() - 1 ) ).timestamp() ), + MaxFeePerGasPatch::isEnabledWhen( this->info( numberHash( h.number() - 1 ) ).timestamp() ) ); Ethash::verifyTransaction( chainParams(), _ir, t, this->info( numberHash( h.number() - 1 ) ).timestamp(), h, diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 200fb295f..697fc36ec 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -383,6 +383,8 @@ Transaction ClientBase::transaction( h256 _transactionHash ) const { auto tl = bc().transactionLocation( _transactionHash ); return Transaction( bc().transaction( _transactionHash ), CheckTransaction::Cheap, true, EIP1559TransactionsPatch::isEnabledWhen( + blockInfo( numberFromHash( tl.first ) - 1 ).timestamp() ), + MaxFeePerGasPatch::isEnabledWhen( blockInfo( numberFromHash( tl.first ) - 1 ).timestamp() ) ); } @@ -398,6 +400,8 @@ Transaction ClientBase::transaction( h256 _blockHash, unsigned _i ) const { // allow invalid return Transaction( b[1][_i].data(), CheckTransaction::Cheap, true, EIP1559TransactionsPatch::isEnabledWhen( + blockInfo( numberFromHash( _blockHash ) - 1 ).timestamp() ), + MaxFeePerGasPatch::isEnabledWhen( blockInfo( numberFromHash( _blockHash ) - 1 ).timestamp() ) ); else return Transaction(); @@ -407,6 +411,8 @@ LocalisedTransaction ClientBase::localisedTransaction( h256 const& _blockHash, u // allow invalid Transaction t = Transaction( bc().transaction( _blockHash, _i ), CheckTransaction::Cheap, true, EIP1559TransactionsPatch::isEnabledWhen( + blockInfo( numberFromHash( _blockHash ) - 1 ).timestamp() ), + MaxFeePerGasPatch::isEnabledWhen( blockInfo( numberFromHash( _blockHash ) - 1 ).timestamp() ) ); return LocalisedTransaction( t, _blockHash, _i, numberFromHash( _blockHash ) ); } @@ -422,6 +428,8 @@ LocalisedTransactionReceipt ClientBase::localisedTransactionReceipt( Transaction t = Transaction( bc().transaction( tl.first, tl.second ), CheckTransaction::Cheap, true, EIP1559TransactionsPatch::isEnabledWhen( + blockInfo( numberFromHash( tl.first ) - 1 ).timestamp() ), + MaxFeePerGasPatch::isEnabledWhen( blockInfo( numberFromHash( tl.first ) - 1 ).timestamp() ) ); TransactionReceipt tr = bc().transactionReceipt( tl.first, tl.second ); u256 gasUsed = tr.cumulativeGasUsed(); @@ -457,6 +465,8 @@ Transactions ClientBase::transactions( h256 _blockHash ) const { auto txRlp = b[1][i]; res.emplace_back( bytesRefFromTransactionRlp( txRlp ), CheckTransaction::Cheap, true, EIP1559TransactionsPatch::isEnabledWhen( + blockInfo( numberFromHash( _blockHash ) - 1 ).timestamp() ), + MaxFeePerGasPatch::isEnabledWhen( blockInfo( numberFromHash( _blockHash ) - 1 ).timestamp() ) ); } return res; diff --git a/libethereum/SkaleHost.cpp b/libethereum/SkaleHost.cpp index 0f925c7bb..a5c045e86 100644 --- a/libethereum/SkaleHost.cpp +++ b/libethereum/SkaleHost.cpp @@ -337,7 +337,8 @@ h256 SkaleHost::receiveTransaction( std::string _rlp ) { } Transaction transaction( jsToBytes( _rlp, OnFailed::Throw ), CheckTransaction::None, false, - EIP1559TransactionsPatch::isEnabledInWorkingBlock() ); + EIP1559TransactionsPatch::isEnabledInWorkingBlock(), + MaxFeePerGasPatch::isEnabledInWorkingBlock() ); h256 sha = transaction.sha3(); // @@ -672,7 +673,8 @@ void SkaleHost::createBlock( const ConsensusExtFace::transactions_vector& _appro // ).detach(); } else { Transaction t( data, CheckTransaction::Everything, true, - EIP1559TransactionsPatch::isEnabledInWorkingBlock() ); + EIP1559TransactionsPatch::isEnabledInWorkingBlock(), + MaxFeePerGasPatch::isEnabledInWorkingBlock() ); t.checkOutExternalGas( m_client.chainParams(), latestInfo.timestamp(), m_client.number() ); out_txns.push_back( t ); diff --git a/libethereum/Transaction.cpp b/libethereum/Transaction.cpp index eee35a457..e95d43cd8 100644 --- a/libethereum/Transaction.cpp +++ b/libethereum/Transaction.cpp @@ -164,13 +164,14 @@ Transaction::Transaction( const u256& _value, const u256& _gasPrice, const u256& const bytes& _data, const u256& _nonce ) : TransactionBase( _value, _gasPrice, _gas, _data, _nonce ) {} -Transaction::Transaction( - bytesConstRef _rlpData, CheckTransaction _checkSig, bool _allowInvalid, bool _eip1559Enabled ) - : TransactionBase( _rlpData, _checkSig, _allowInvalid, _eip1559Enabled ) {} - -Transaction::Transaction( - const bytes& _rlp, CheckTransaction _checkSig, bool _allowInvalid, bool _eip1559Enabled ) - : Transaction( &_rlp, _checkSig, _allowInvalid, _eip1559Enabled ) {} +Transaction::Transaction( bytesConstRef _rlpData, CheckTransaction _checkSig, bool _allowInvalid, + bool _eip1559Enabled, bool _maxFeePerGasPatchEnabled ) + : TransactionBase( + _rlpData, _checkSig, _allowInvalid, _eip1559Enabled, _maxFeePerGasPatchEnabled ) {} + +Transaction::Transaction( const bytes& _rlp, CheckTransaction _checkSig, bool _allowInvalid, + bool _eip1559Enabled, bool _maxFeePerGasPatchEnabled ) + : Transaction( &_rlp, _checkSig, _allowInvalid, _eip1559Enabled, _maxFeePerGasPatchEnabled ) {} bool Transaction::hasExternalGas() const { if ( !m_externalGasIsChecked ) { diff --git a/libethereum/Transaction.h b/libethereum/Transaction.h index 1aecefaaa..86c3ce8cd 100644 --- a/libethereum/Transaction.h +++ b/libethereum/Transaction.h @@ -108,11 +108,12 @@ class Transaction : public TransactionBase { /// Constructs a transaction from the given RLP. explicit Transaction( bytesConstRef _rlp, CheckTransaction _checkSig, - bool _allowInvalid = false, bool _eip1559Enabled = false ); + bool _allowInvalid = false, bool _eip1559Enabled = false, + bool _maxFeePerGasPatchEnabled = false ); /// Constructs a transaction from the given RLP. explicit Transaction( bytes const& _rlp, CheckTransaction _checkSig, bool _allowInvalid = false, - bool _eip1559Enabled = false ); + bool _eip1559Enabled = false, bool _maxFeePerGasPatchEnabled = false ); Transaction( Transaction const& ) = default; diff --git a/libethereum/TransactionQueue.cpp b/libethereum/TransactionQueue.cpp index 16e726e76..7e1e7b9f9 100644 --- a/libethereum/TransactionQueue.cpp +++ b/libethereum/TransactionQueue.cpp @@ -96,7 +96,8 @@ ImportResult TransactionQueue::import( bytesConstRef _transactionRLP, IfDropped _ik, bool _isFuture ) { try { Transaction t = Transaction( _transactionRLP, CheckTransaction::Everything, false, - EIP1559TransactionsPatch::isEnabledInWorkingBlock() ); + EIP1559TransactionsPatch::isEnabledInWorkingBlock(), + MaxFeePerGasPatch::isEnabledInWorkingBlock() ); return import( t, _ik, _isFuture ); } catch ( Exception const& ) { return ImportResult::Malformed; @@ -527,8 +528,9 @@ void TransactionQueue::verifierBody() { try { Transaction t( work.transaction, CheckTransaction::Cheap, false, - EIP1559TransactionsPatch::isEnabledInWorkingBlock() ); // Signature will be - // checked later + EIP1559TransactionsPatch::isEnabledInWorkingBlock(), + MaxFeePerGasPatch::isEnabledInWorkingBlock() ); // Signature will be + // checked later ImportResult ir = import( t ); m_onImport( ir, t.sha3(), work.nodeId ); } catch ( ... ) { diff --git a/libweb3jsonrpc/Eth.cpp b/libweb3jsonrpc/Eth.cpp index 6a39183fd..164a69e00 100644 --- a/libweb3jsonrpc/Eth.cpp +++ b/libweb3jsonrpc/Eth.cpp @@ -415,7 +415,8 @@ Json::Value Eth::setSchainExitTime( Json::Value const& /*_transaction*/ ) { Json::Value Eth::eth_inspectTransaction( std::string const& _rlp ) { try { return toJson( Transaction( jsToBytes( _rlp, OnFailed::Throw ), - CheckTransaction::Everything, EIP1559TransactionsPatch::isEnabledInWorkingBlock() ) ); + CheckTransaction::Everything, EIP1559TransactionsPatch::isEnabledInWorkingBlock(), + MaxFeePerGasPatch::isEnabledInWorkingBlock() ) ); } catch ( ... ) { BOOST_THROW_EXCEPTION( JsonRpcException( Errors::ERROR_RPC_INVALID_PARAMS ) ); } @@ -427,7 +428,8 @@ string Eth::eth_sendRawTransaction( std::string const& _rlp ) { // Don't need to check the transaction signature (CheckTransaction::None) since it // will be checked as a part of transaction import Transaction t( jsToBytes( _rlp, OnFailed::Throw ), CheckTransaction::None, false, - EIP1559TransactionsPatch::isEnabledInWorkingBlock() ); + EIP1559TransactionsPatch::isEnabledInWorkingBlock(), + MaxFeePerGasPatch::isEnabledInWorkingBlock() ); return toJS( client()->importTransaction( t ) ); } From 0ae45c3f8e41721d4e253a3a9663769d2f756919 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Wed, 15 Jan 2025 12:21:56 +0000 Subject: [PATCH 5/7] #1994 add tests --- test/unittests/libweb3jsonrpc/jsonrpc.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/unittests/libweb3jsonrpc/jsonrpc.cpp b/test/unittests/libweb3jsonrpc/jsonrpc.cpp index 7057e6488..461cb9278 100644 --- a/test/unittests/libweb3jsonrpc/jsonrpc.cpp +++ b/test/unittests/libweb3jsonrpc/jsonrpc.cpp @@ -3671,6 +3671,9 @@ BOOST_AUTO_TEST_CASE( maxFeePerGasPatch ) { 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() ); + sleep( 10 ); // force 1 block to update timestamp From 7ae83b6691494e02261b1634252c45d110fe340d Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Thu, 16 Jan 2025 17:37:27 +0000 Subject: [PATCH 6/7] #1994 format code --- libethereum/ClientBase.cpp | 38 ++++++++++++++++---------------------- libethereum/SkaleHost.cpp | 3 ++- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 1afdc02c0..74f1b5722 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -360,11 +360,10 @@ BlockDetails ClientBase::blockDetails( h256 _hash ) const { Transaction ClientBase::transaction( h256 _transactionHash ) const { // allow invalid! auto tl = bc().transactionLocation( _transactionHash ); + auto blockTimestamp = blockInfo( numberFromHash( tl.first ) - 1 ).timestamp(); return Transaction( bc().transaction( _transactionHash ), CheckTransaction::Cheap, true, - EIP1559TransactionsPatch::isEnabledWhen( - blockInfo( numberFromHash( tl.first ) - 1 ).timestamp() ), - MaxFeePerGasPatch::isEnabledWhen( - blockInfo( numberFromHash( tl.first ) - 1 ).timestamp() ) ); + EIP1559TransactionsPatch::isEnabledWhen( blockTimestamp ), + MaxFeePerGasPatch::isEnabledWhen( blockTimestamp ) ); } LocalisedTransaction ClientBase::localisedTransaction( h256 const& _transactionHash ) const { @@ -375,24 +374,22 @@ LocalisedTransaction ClientBase::localisedTransaction( h256 const& _transactionH Transaction ClientBase::transaction( h256 _blockHash, unsigned _i ) const { auto bl = bc().block( _blockHash ); RLP b( bl ); + auto blockTimestamp = blockInfo( numberFromHash( _blockHash ) - 1 ).timestamp(); if ( _i < b[1].itemCount() ) // allow invalid return Transaction( b[1][_i].data(), CheckTransaction::Cheap, true, - EIP1559TransactionsPatch::isEnabledWhen( - blockInfo( numberFromHash( _blockHash ) - 1 ).timestamp() ), - MaxFeePerGasPatch::isEnabledWhen( - blockInfo( numberFromHash( _blockHash ) - 1 ).timestamp() ) ); + EIP1559TransactionsPatch::isEnabledWhen( blockTimestamp ), + MaxFeePerGasPatch::isEnabledWhen( blockTimestamp ) ); else return Transaction(); } LocalisedTransaction ClientBase::localisedTransaction( h256 const& _blockHash, unsigned _i ) const { + auto blockTimestamp = blockInfo( numberFromHash( _blockHash ) - 1 ).timestamp(); // allow invalid Transaction t = Transaction( bc().transaction( _blockHash, _i ), CheckTransaction::Cheap, true, - EIP1559TransactionsPatch::isEnabledWhen( - blockInfo( numberFromHash( _blockHash ) - 1 ).timestamp() ), - MaxFeePerGasPatch::isEnabledWhen( - blockInfo( numberFromHash( _blockHash ) - 1 ).timestamp() ) ); + EIP1559TransactionsPatch::isEnabledWhen( blockTimestamp ), + MaxFeePerGasPatch::isEnabledWhen( blockTimestamp ) ); return LocalisedTransaction( t, _blockHash, _i, numberFromHash( _blockHash ) ); } @@ -403,13 +400,11 @@ TransactionReceipt ClientBase::transactionReceipt( h256 const& _transactionHash LocalisedTransactionReceipt ClientBase::localisedTransactionReceipt( h256 const& _transactionHash ) const { std::pair< h256, unsigned > tl = bc().transactionLocation( _transactionHash ); + auto blockTimestamp = blockInfo( numberFromHash( tl.first ) - 1 ).timestamp(); // allow invalid - Transaction t = - Transaction( bc().transaction( tl.first, tl.second ), CheckTransaction::Cheap, true, - EIP1559TransactionsPatch::isEnabledWhen( - blockInfo( numberFromHash( tl.first ) - 1 ).timestamp() ), - MaxFeePerGasPatch::isEnabledWhen( - blockInfo( numberFromHash( tl.first ) - 1 ).timestamp() ) ); + Transaction t = Transaction( bc().transaction( tl.first, tl.second ), CheckTransaction::Cheap, + true, EIP1559TransactionsPatch::isEnabledWhen( blockTimestamp ), + MaxFeePerGasPatch::isEnabledWhen( blockTimestamp ) ); TransactionReceipt tr = bc().transactionReceipt( tl.first, tl.second ); u256 gasUsed = tr.cumulativeGasUsed(); if ( tl.second > 0 ) @@ -440,13 +435,12 @@ Transactions ClientBase::transactions( h256 _blockHash ) const { auto bl = bc().block( _blockHash ); RLP b( bl ); Transactions res; + auto blockTimestamp = blockInfo( numberFromHash( _blockHash ) - 1 ).timestamp(); for ( unsigned i = 0; i < b[1].itemCount(); i++ ) { auto txRlp = b[1][i]; res.emplace_back( bytesRefFromTransactionRlp( txRlp ), CheckTransaction::Cheap, true, - EIP1559TransactionsPatch::isEnabledWhen( - blockInfo( numberFromHash( _blockHash ) - 1 ).timestamp() ), - MaxFeePerGasPatch::isEnabledWhen( - blockInfo( numberFromHash( _blockHash ) - 1 ).timestamp() ) ); + EIP1559TransactionsPatch::isEnabledWhen( blockTimestamp ), + MaxFeePerGasPatch::isEnabledWhen( blockTimestamp ) ); } return res; } diff --git a/libethereum/SkaleHost.cpp b/libethereum/SkaleHost.cpp index 036f6531a..c9c2ab25b 100644 --- a/libethereum/SkaleHost.cpp +++ b/libethereum/SkaleHost.cpp @@ -577,7 +577,8 @@ void SkaleHost::createBlock( const ConsensusExtFace::transactions_vector& _appro LOG( m_traceLogger ) << "Arrived txn: " << sha; Transaction t( data, CheckTransaction::Everything, true, - EIP1559TransactionsPatch::isEnabledInWorkingBlock() ); + EIP1559TransactionsPatch::isEnabledInWorkingBlock(), + MaxFeePerGasPatch::isEnabledInWorkingBlock() ); t.checkOutExternalGas( m_client.chainParams(), latestInfo.timestamp(), m_client.number() ); From b800595a90f369191dd46fe5bc0666e71e658ee2 Mon Sep 17 00:00:00 2001 From: Oleh Nikolaiev Date: Thu, 16 Jan 2025 17:42:54 +0000 Subject: [PATCH 7/7] #1994 format code --- libethereum/BlockChain.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index c12d59590..1e7bce09a 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -1736,15 +1736,13 @@ VerifiedBlockRef BlockChain::verifyBlock( bytesConstRef _block, for ( RLP const& tr : r[1] ) { bytesConstRef d = bytesRefFromTransactionRlp( tr ); try { + auto blockTimestamp = this->info( numberHash( h.number() - 1 ) ).timestamp(); Transaction t( d, ( _ir & ImportRequirements::TransactionSignatures ) ? CheckTransaction::Everything : CheckTransaction::None, - false, - EIP1559TransactionsPatch::isEnabledWhen( - this->info( numberHash( h.number() - 1 ) ).timestamp() ), - MaxFeePerGasPatch::isEnabledWhen( - this->info( numberHash( h.number() - 1 ) ).timestamp() ) ); + false, EIP1559TransactionsPatch::isEnabledWhen( blockTimestamp ), + MaxFeePerGasPatch::isEnabledWhen( blockTimestamp ) ); Ethash::verifyTransaction( chainParams(), _ir, t, this->info( numberHash( h.number() - 1 ) ).timestamp(), h, 0 ); // the gasUsed vs