@@ -71,8 +71,104 @@ pub enum TransactValueCallCreate {
7171pub struct TransactValue {
7272 /// Call/Create status.
7373 pub call_create : TransactValueCallCreate ,
74- /// Used gas minus the refund.
75- pub effective_gas : U256 ,
74+ /// Used gas.
75+ pub used_gas : U256 ,
76+ }
77+
78+ /// Transact gas price.
79+ #[ derive( Clone , Debug , Copy , Eq , PartialEq ) ]
80+ pub enum TransactGasPrice {
81+ /// Legacy gas price.
82+ Legacy ( U256 ) ,
83+ /// EIP-1559 fee market.
84+ FeeMarket {
85+ /// `max_priority_fee_per_gas` according to EIP-1559.
86+ max_priority : U256 ,
87+ /// `max_fee_per_gas` according to EIP-1559.
88+ max : U256 ,
89+ } ,
90+ }
91+
92+ impl TransactGasPrice {
93+ /// Caller fee.
94+ pub fn fee < H : RuntimeEnvironment > (
95+ & self ,
96+ gas_limit : U256 ,
97+ config : & Config ,
98+ handler : & H ,
99+ ) -> U256 {
100+ let effective_gas_price = self . effective_gas_price ( config, handler) ;
101+ gas_limit. saturating_mul ( effective_gas_price)
102+ }
103+
104+ /// Refunded caller fee after call.
105+ pub fn refunded_fee < H : RuntimeEnvironment > (
106+ & self ,
107+ refunded_gas : U256 ,
108+ config : & Config ,
109+ handler : & H ,
110+ ) -> U256 {
111+ let effective_gas_price = self . effective_gas_price ( config, handler) ;
112+ refunded_gas. saturating_mul ( effective_gas_price)
113+ }
114+
115+ /// Coinbase reward.
116+ pub fn coinbase_reward < H : RuntimeEnvironment > (
117+ & self ,
118+ used_gas : U256 ,
119+ config : & Config ,
120+ handler : & H ,
121+ ) -> U256 {
122+ if config. eip1559_fee_market {
123+ let max_priority = match self {
124+ Self :: Legacy ( gas_price) => * gas_price,
125+ Self :: FeeMarket { max_priority, .. } => * max_priority,
126+ } ;
127+ let max = match self {
128+ Self :: Legacy ( gas_price) => * gas_price,
129+ Self :: FeeMarket { max, .. } => * max,
130+ } ;
131+ let priority = min (
132+ max_priority,
133+ max. saturating_sub ( handler. block_base_fee_per_gas ( ) ) ,
134+ ) ;
135+ used_gas. saturating_mul ( priority)
136+ } else {
137+ let effective_gas_price = self . effective_gas_price ( config, handler) ;
138+ used_gas. saturating_mul ( effective_gas_price)
139+ }
140+ }
141+
142+ /// Effective gas price as returned by `GASPRICE` opcode.
143+ pub fn effective_gas_price < H : RuntimeEnvironment > ( & self , config : & Config , handler : & H ) -> U256 {
144+ if config. eip1559_fee_market {
145+ let max_priority = match self {
146+ Self :: Legacy ( gas_price) => * gas_price,
147+ Self :: FeeMarket { max_priority, .. } => * max_priority,
148+ } ;
149+ let max = match self {
150+ Self :: Legacy ( gas_price) => * gas_price,
151+ Self :: FeeMarket { max, .. } => * max,
152+ } ;
153+
154+ let priority = min (
155+ max_priority,
156+ max. saturating_sub ( handler. block_base_fee_per_gas ( ) ) ,
157+ ) ;
158+ priority. saturating_add ( handler. block_base_fee_per_gas ( ) )
159+ } else {
160+ match self {
161+ Self :: Legacy ( gas_price) => * gas_price,
162+ Self :: FeeMarket { max_priority, .. } => * max_priority,
163+ }
164+ }
165+ }
166+ }
167+
168+ impl From < U256 > for TransactGasPrice {
169+ fn from ( gas_price : U256 ) -> Self {
170+ Self :: Legacy ( gas_price)
171+ }
76172}
77173
78174/// The invoke used in a top-layer transaction stack.
@@ -82,7 +178,7 @@ pub struct TransactInvoke<'config> {
82178 /// Gas limit.
83179 pub gas_limit : U256 ,
84180 /// Gas price.
85- pub gas_price : U256 ,
181+ pub gas_price : TransactGasPrice ,
86182 /// Caller.
87183 pub caller : H160 ,
88184 /// Config used for the transaction.
@@ -120,7 +216,7 @@ pub struct TransactArgs<'config> {
120216 /// Transaction gas limit.
121217 pub gas_limit : U256 ,
122218 /// Transaction gas price.
123- pub gas_price : U256 ,
219+ pub gas_price : TransactGasPrice ,
124220 /// Access list information, in the format of (address, storage keys).
125221 pub access_list : Vec < ( H160 , Vec < H256 > ) > ,
126222 /// Config of this arg.
@@ -187,9 +283,11 @@ where
187283 > {
188284 let caller = AsRef :: < TransactArgs > :: as_ref ( & args) . caller ;
189285 let gas_price = AsRef :: < TransactArgs > :: as_ref ( & args) . gas_price ;
190- let gas_fee = AsRef :: < TransactArgs > :: as_ref ( & args)
191- . gas_limit
192- . saturating_mul ( gas_price) ;
286+ let gas_fee = gas_price. fee (
287+ AsRef :: < TransactArgs > :: as_ref ( & args) . gas_limit ,
288+ AsRef :: < TransactArgs > :: as_ref ( & args) . config ,
289+ handler,
290+ ) ;
193291 let coinbase = handler. block_coinbase ( ) ;
194292
195293 let address = match & AsRef :: < TransactArgs > :: as_ref ( & args) . call_create {
@@ -225,6 +323,8 @@ where
225323 config : AsRef :: < TransactArgs > :: as_ref ( & args) . config ,
226324 } ;
227325
326+ handler. mark_hot ( coinbase, TouchKind :: Coinbase ) ;
327+
228328 if handler. code_size ( caller) != U256 :: zero ( ) {
229329 handler. push_substate ( ) ;
230330 return Ok ( (
@@ -276,7 +376,8 @@ where
276376 } ;
277377 let transaction_context = TransactionContext {
278378 origin : caller,
279- gas_price,
379+ gas_price : gas_price
380+ . effective_gas_price ( AsRef :: < TransactArgs > :: as_ref ( & args) . config , handler) ,
280381 } ;
281382 let transfer = Transfer {
282383 source : caller,
@@ -297,7 +398,6 @@ where
297398 }
298399 }
299400
300- handler. mark_hot ( coinbase, TouchKind :: Coinbase ) ;
301401 handler. mark_hot ( caller, TouchKind :: Access ) ;
302402 handler. mark_hot ( caller, TouchKind :: StateChange ) ;
303403 handler. mark_hot ( address, TouchKind :: Access ) ;
@@ -423,27 +523,19 @@ where
423523 }
424524 }
425525
426- let refunded_fee = effective_gas. saturating_mul ( invoke. gas_price ) ;
526+ let used_gas = invoke. gas_limit . saturating_sub ( effective_gas) ;
527+ let refunded_fee = invoke
528+ . gas_price
529+ . refunded_fee ( effective_gas, invoke. config , handler) ;
427530 handler. deposit ( invoke. caller , refunded_fee) ;
428- // Reward coinbase address
429- // EIP-1559 updated the fee system so that miners only get to keep the priority fee.
430- // The base fee is always burned.
431- let coinbase_gas_price = if invoke. config . eip1559_fee_market {
432- invoke
433- . gas_price
434- . saturating_sub ( handler. block_base_fee_per_gas ( ) )
435- } else {
436- invoke. gas_price
437- } ;
438531 let coinbase_reward = invoke
439- . gas_limit
440- . saturating_mul ( coinbase_gas_price)
441- . saturating_sub ( refunded_fee) ;
532+ . gas_price
533+ . coinbase_reward ( used_gas, invoke. config , handler) ;
442534 handler. deposit ( handler. block_coinbase ( ) , coinbase_reward) ;
443535
444536 result. map ( |call_create| TransactValue {
445537 call_create,
446- effective_gas ,
538+ used_gas ,
447539 } )
448540 }
449541
0 commit comments