Skip to content

Commit

Permalink
Merge pull request #2073 from skalenetwork/bug/1994-max-fee-per-gas-c…
Browse files Browse the repository at this point in the history
…heck
  • Loading branch information
olehnikolaiev authored Feb 13, 2025
2 parents ed2ff59 + ff08798 commit fb2b6e4
Show file tree
Hide file tree
Showing 13 changed files with 134 additions and 47 deletions.
20 changes: 11 additions & 9 deletions libethcore/TransactionBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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 {
Expand All @@ -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_maxFeePerGas : m_maxPriorityFeePerGas;
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)" ) );
Expand Down Expand Up @@ -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 );
Expand All @@ -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(
Expand All @@ -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 );
}
Expand Down
15 changes: 9 additions & 6 deletions libethcore/TransactionBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -329,13 +332,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;
Expand Down
6 changes: 3 additions & 3 deletions libethereum/BlockChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1736,13 +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() ) );
false, EIP1559TransactionsPatch::isEnabledWhen( blockTimestamp ),
MaxFeePerGasPatch::isEnabledWhen( blockTimestamp ) );
Ethash::verifyTransaction( chainParams(), _ir, t,
this->info( numberHash( h.number() - 1 ) ).timestamp(), h,
0 ); // the gasUsed vs
Expand Down
28 changes: 16 additions & 12 deletions libethereum/ClientBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,9 +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() ) );
EIP1559TransactionsPatch::isEnabledWhen( blockTimestamp ),
MaxFeePerGasPatch::isEnabledWhen( blockTimestamp ) );
}

LocalisedTransaction ClientBase::localisedTransaction( h256 const& _transactionHash ) const {
Expand All @@ -373,20 +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() ) );
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() ) );
EIP1559TransactionsPatch::isEnabledWhen( blockTimestamp ),
MaxFeePerGasPatch::isEnabledWhen( blockTimestamp ) );
return LocalisedTransaction( t, _blockHash, _i, numberFromHash( _blockHash ) );
}

Expand All @@ -397,11 +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() ) );
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 )
Expand Down Expand Up @@ -432,11 +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() ) );
EIP1559TransactionsPatch::isEnabledWhen( blockTimestamp ),
MaxFeePerGasPatch::isEnabledWhen( blockTimestamp ) );
}
return res;
}
Expand Down
4 changes: 4 additions & 0 deletions libethereum/SchainPatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
}
Expand Down Expand Up @@ -74,6 +76,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 ) ) );
Expand Down
6 changes: 6 additions & 0 deletions libethereum/SchainPatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,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
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 {
VerifyBlsSyncPatch,
FlexibleDeploymentPatch,
ExternalGasPatch,
MaxFeePerGasPatch,
PatchesCount
};

Expand Down
7 changes: 4 additions & 3 deletions libethereum/SkaleHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,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();

//
Expand Down Expand Up @@ -575,9 +576,9 @@ void SkaleHost::createBlock( const ConsensusExtFace::transactions_vector& _appro
h256 sha = sha3( data );
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() );

Expand Down
15 changes: 8 additions & 7 deletions libethereum/Transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) {
Expand Down
5 changes: 3 additions & 2 deletions libethereum/Transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
8 changes: 5 additions & 3 deletions libethereum/TransactionQueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -528,8 +529,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 ( ... ) {
Expand Down
6 changes: 4 additions & 2 deletions libweb3jsonrpc/Eth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) );
}
Expand All @@ -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, TransactionBroadcast::BroadcastToAll ) );
}

Expand Down
Loading

0 comments on commit fb2b6e4

Please sign in to comment.