@@ -3,6 +3,7 @@ package derive
33import (
44 "context"
55 "fmt"
6+ "math/big"
67
78 "github.com/ethereum/go-ethereum/common"
89 "github.com/ethereum/go-ethereum/common/hexutil"
@@ -11,12 +12,14 @@ import (
1112 "github.com/ethereum-optimism/optimism/op-bindings/predeploys"
1213 "github.com/ethereum-optimism/optimism/op-node/eth"
1314 "github.com/ethereum-optimism/optimism/op-node/rollup"
15+ opservice "github.com/ethereum-optimism/optimism/op-service"
1416)
1517
1618// L1ReceiptsFetcher fetches L1 header info and receipts for the payload attributes derivation (the info tx and deposits)
1719type L1ReceiptsFetcher interface {
1820 InfoByHash (ctx context.Context , hash common.Hash ) (eth.BlockInfo , error )
1921 FetchReceipts (ctx context.Context , blockHash common.Hash ) (eth.BlockInfo , types.Receipts , error )
22+ InfoAndTxsByHash (ctx context.Context , hash common.Hash ) (eth.BlockInfo , types.Transactions , error )
2023}
2124
2225type SystemConfigL2Fetcher interface {
@@ -53,6 +56,14 @@ func (ba *FetchingAttributesBuilder) PreparePayloadAttributes(ctx context.Contex
5356 return nil , NewTemporaryError (fmt .Errorf ("failed to retrieve L2 parent block: %w" , err ))
5457 }
5558
59+ var gasPrice * big.Int
60+ if opservice .ForBSC {
61+ gasPrice , err = ba .prepareAverageGasPrice (ctx , epoch )
62+ if err != nil {
63+ return nil , NewTemporaryError (fmt .Errorf ("failed to prepare average gas price: %w" , err ))
64+ }
65+ }
66+
5667 // If the L1 origin changed this block, then we are in the first block of the epoch. In this
5768 // case we need to fetch all transaction receipts from the L1 origin block so we can scan for
5869 // user deposits.
@@ -76,7 +87,9 @@ func (ba *FetchingAttributesBuilder) PreparePayloadAttributes(ctx context.Contex
7687 if err := UpdateSystemConfigWithL1Receipts (& sysConfig , receipts , ba .cfg ); err != nil {
7788 return nil , NewCriticalError (fmt .Errorf ("failed to apply derived L1 sysCfg updates: %w" , err ))
7889 }
79-
90+ if opservice .ForBSC {
91+ info = newGasPriceWrapper (info , gasPrice )
92+ }
8093 l1Info = info
8194 depositTxs = deposits
8295 seqNumber = 0
@@ -88,6 +101,9 @@ func (ba *FetchingAttributesBuilder) PreparePayloadAttributes(ctx context.Contex
88101 if err != nil {
89102 return nil , NewTemporaryError (fmt .Errorf ("failed to fetch L1 block info: %w" , err ))
90103 }
104+ if opservice .ForBSC {
105+ info = newGasPriceWrapper (info , gasPrice )
106+ }
91107 l1Info = info
92108 depositTxs = nil
93109 seqNumber = l2Parent .SequenceNumber + 1
@@ -118,3 +134,43 @@ func (ba *FetchingAttributesBuilder) PreparePayloadAttributes(ctx context.Contex
118134 GasLimit : (* eth .Uint64Quantity )(& sysConfig .GasLimit ),
119135 }, nil
120136}
137+
138+ var bscDefaultGasPrice = big .NewInt (5000000000 )
139+
140+ func (ba * FetchingAttributesBuilder ) prepareAverageGasPrice (ctx context.Context , epoch eth.BlockID ) (* big.Int , error ) {
141+ _ , txs , err := ba .l1 .InfoAndTxsByHash (ctx , epoch .Hash )
142+ if err != nil {
143+ return nil , err
144+ }
145+ count := 0
146+ var sum big.Int
147+ for _ , tx := range txs {
148+ if tx .GasPrice ().Cmp (common .Big0 ) <= 0 {
149+ continue
150+ }
151+ sum .Add (& sum , tx .GasPrice ())
152+ count += 1
153+ }
154+ if count == 0 {
155+ return bscDefaultGasPrice , nil
156+ }
157+ return sum .Div (& sum , big .NewInt (int64 (count ))), nil
158+ }
159+
160+ type gasPriceWrapper struct {
161+ eth.BlockInfo
162+ gasprice * big.Int
163+ }
164+
165+ var _ (eth.BlockInfo ) = (* gasPriceWrapper )(nil )
166+
167+ func newGasPriceWrapper (info eth.BlockInfo , gasprice * big.Int ) * gasPriceWrapper {
168+ return & gasPriceWrapper {
169+ BlockInfo : info ,
170+ gasprice : gasprice ,
171+ }
172+ }
173+
174+ func (w * gasPriceWrapper ) BaseFee () * big.Int {
175+ return w .gasprice
176+ }
0 commit comments