OpenFusionist's optimism fork diff

+140
-14

These are some really important code modifications in the fork. The original can be found at github.com/ethereum-optimism/optimism. And the fork at OpenFusionist/optimism/.

Support for non-eip-1559 L1 and compatibility with BAS chain.

diff --git ethereum-optimism/optimism/op-chain-ops/genesis/config.go OpenFusionist/optimism/op-chain-ops/genesis/config.go index b706f59dd7cdefd5abf91b0363a64ec93953b681..dd7e13c26aaee6a3c9c76d4ec8c3facd4710aee6 100644 --- ethereum-optimism/optimism/op-chain-ops/genesis/config.go +++ OpenFusionist/optimism/op-chain-ops/genesis/config.go @@ -5,6 +5,7 @@ "bytes" "encoding/json" "errors" "fmt" + "github.com/ethereum-optimism/optimism/op-service/bas" "math/big" "os" "path/filepath" @@ -720,9 +721,6 @@ if block.Number() == nil { return storage, errors.New("block number not set") } - if block.BaseFee() == nil { - return storage, errors.New("block base fee not set") - }   storage["L2ToL1MessagePasser"] = state.StorageValues{ "msgNonce": 0, @@ -741,7 +739,7 @@ } storage["L1Block"] = state.StorageValues{ "number": block.Number(), "timestamp": block.Time(), - "basefee": block.BaseFee(), + "basefee": bas.BaseFeeByTransactions(block.Transactions()), "hash": block.Hash(), "sequenceNumber": 0, "batcherHash": eth.AddressAsLeftPaddedHash(config.BatchSenderAddress),
diff --git ethereum-optimism/optimism/op-node/rollup/derive/attributes.go OpenFusionist/optimism/op-node/rollup/derive/attributes.go index b65f680952f3fd332ebfbf787de32ff16b13a179..8a6ec07da5c3b66ca4568192fdabfc41c65d7960 100644 --- ethereum-optimism/optimism/op-node/rollup/derive/attributes.go +++ OpenFusionist/optimism/op-node/rollup/derive/attributes.go @@ -3,7 +3,7 @@ import ( "context" "fmt" - + "github.com/ethereum-optimism/optimism/op-service/bas" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" @@ -16,6 +16,7 @@ // L1ReceiptsFetcher fetches L1 header info and receipts for the payload attributes derivation (the info tx and deposits) type L1ReceiptsFetcher interface { InfoByHash(ctx context.Context, hash common.Hash) (eth.BlockInfo, error) + InfoAndTxsByHash(ctx context.Context, hash common.Hash) (eth.BlockInfo, types.Transactions, error) FetchReceipts(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Receipts, error) }   @@ -53,6 +54,14 @@ if err != nil { return nil, NewTemporaryError(fmt.Errorf("failed to retrieve L2 parent block: %w", err)) }   + // Calculate bsc block base fee + _, transactions, err := ba.l1.InfoAndTxsByHash(ctx, epoch.Hash) + if err != nil { + return nil, NewTemporaryError(fmt.Errorf("failed to fetch L1 block info and txs: %w", err)) + } + l1BaseFee := bas.BaseFeeByTransactions(transactions) + fmt.Println("PreparePayloadAttributes l1BaseFee: ", l1BaseFee) + // If the L1 origin changed this block, then we are in the first block of the epoch. In this // case we need to fetch all transaction receipts from the L1 origin block so we can scan for // user deposits. @@ -92,6 +101,8 @@ l1Info = info depositTxs = nil seqNumber = l2Parent.SequenceNumber + 1 } + + l1Info = bas.NewBlockInfoBSCWrapper(l1Info, l1BaseFee)   // Sanity check the L1 origin was correctly selected to maintain the time invariant between L1 and L2 nextL2Time := l2Parent.Time + ba.cfg.BlockTime
diff --git ethereum-optimism/optimism/op-service/bas/compat.go OpenFusionist/optimism/op-service/bas/compat.go new file mode 100644 index 0000000000000000000000000000000000000000..3c9208af5fca804aadbfd6280c6753405ada6425 --- /dev/null +++ OpenFusionist/optimism/op-service/bas/compat.go @@ -0,0 +1,69 @@ +package bas + +import ( + "math/big" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + + "github.com/ethereum-optimism/optimism/op-service/eth" +) + +var DefaultBaseFeeByTransactions = big.NewInt(1000000000) + +type BlockInfoBSCWrapper struct { + eth.BlockInfo + baseFee *big.Int +} + +var _ eth.BlockInfo = (*BlockInfoBSCWrapper)(nil) + +func NewBlockInfoBSCWrapper(info eth.BlockInfo, baseFee *big.Int) *BlockInfoBSCWrapper { + return &BlockInfoBSCWrapper{ + BlockInfo: info, + baseFee: baseFee, + } +} + +func (b *BlockInfoBSCWrapper) BaseFee() *big.Int { + return b.baseFee +} + +// BaseFeeByTransactions calculates the average gas price of the non-zero-gas-price transactions in the block. +// If there is no non-zero-gas-price transaction in the block, it returns DefaultBaseFeeByTransactions. +func BaseFeeByTransactions(transactions types.Transactions) *big.Int { + nonZeroTxsCnt := big.NewInt(0) + nonZeroTxsSum := big.NewInt(0) + for _, tx := range transactions { + if tx.GasPrice().Cmp(common.Big0) > 0 { + nonZeroTxsCnt.Add(nonZeroTxsCnt, big.NewInt(1)) + nonZeroTxsSum.Add(nonZeroTxsSum, tx.GasPrice()) + } + } + + if nonZeroTxsCnt.Cmp(big.NewInt(0)) == 0 { + return DefaultBaseFeeByTransactions + } + return nonZeroTxsSum.Div(nonZeroTxsSum, nonZeroTxsCnt) +} + +func ToLegacyTx(dynTx *types.DynamicFeeTx) types.TxData { + return &types.LegacyTx{ + Nonce: dynTx.Nonce, + GasPrice: dynTx.GasFeeCap, + Gas: dynTx.Gas, + To: dynTx.To, + Value: dynTx.Value, + Data: dynTx.Data, + } +} + +func ToLegacyCallMsg(callMsg ethereum.CallMsg) ethereum.CallMsg { + return ethereum.CallMsg{ + From: callMsg.From, + To: callMsg.To, + GasPrice: callMsg.GasFeeCap, + Data: callMsg.Data, + } +}
diff --git ethereum-optimism/optimism/op-service/txmgr/txmgr.go OpenFusionist/optimism/op-service/txmgr/txmgr.go index 54dd5feddaaca938186a097bca0ab1e20ef71572..566c17e5360dd3ed7b9a60ba9bab3f97c3bcedf8 100644 --- ethereum-optimism/optimism/op-service/txmgr/txmgr.go +++ OpenFusionist/optimism/op-service/txmgr/txmgr.go @@ -10,6 +10,8 @@ "sync" "sync/atomic" "time"   + "github.com/ethereum-optimism/optimism/op-service/bas" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" @@ -224,14 +226,14 @@ if candidate.GasLimit != 0 { rawTx.Gas = candidate.GasLimit } else { // Calculate the intrinsic gas for the transaction - gas, err := m.backend.EstimateGas(ctx, ethereum.CallMsg{ + gas, err := m.backend.EstimateGas(ctx, bas.ToLegacyCallMsg(ethereum.CallMsg{ From: m.cfg.From, To: candidate.To, GasFeeCap: gasFeeCap, GasTipCap: gasTipCap, Data: rawTx.Data, Value: rawTx.Value, - }) + })) if err != nil { return nil, fmt.Errorf("failed to estimate gas: %w", err) } @@ -265,9 +267,10 @@ *m.nonce++ }   rawTx.Nonce = *m.nonce + legacyTx := bas.ToLegacyTx(rawTx) ctx, cancel := context.WithTimeout(ctx, m.cfg.NetworkTimeout) defer cancel() - tx, err := m.cfg.Signer(ctx, m.cfg.From, types.NewTx(rawTx)) + tx, err := m.cfg.Signer(ctx, m.cfg.From, types.NewTx(legacyTx)) if err != nil { // decrement the nonce, so we can retry signing with the same nonce next time // signWithNextNonce is called @@ -553,9 +556,11 @@ m.l.Info("re-estimated gas differs", "oldgas", tx.Gas(), "newgas", gas) } rawTx.Gas = gas   + legacyTx := bas.ToLegacyTx(rawTx) + ctx, cancel := context.WithTimeout(ctx, m.cfg.NetworkTimeout) defer cancel() - newTx, err := m.cfg.Signer(ctx, m.cfg.From, types.NewTx(rawTx)) + newTx, err := m.cfg.Signer(ctx, m.cfg.From, types.NewTx(legacyTx)) if err != nil { m.l.Warn("failed to sign new transaction", "err", err) return tx, nil @@ -569,8 +574,7 @@ cCtx, cancel := context.WithTimeout(ctx, m.cfg.NetworkTimeout) defer cancel() tip, err := m.backend.SuggestGasTipCap(cCtx) if err != nil { - m.metr.RPCError() - return nil, nil, fmt.Errorf("failed to fetch the suggested gas tip cap: %w", err) + tip = big.NewInt(1000000000) } else if tip == nil { return nil, nil, errors.New("the suggested tip was nil") } @@ -581,7 +585,7 @@ if err != nil { m.metr.RPCError() return nil, nil, fmt.Errorf("failed to fetch the suggested basefee: %w", err) } else if head.BaseFee == nil { - return nil, nil, errors.New("txmgr does not support pre-london blocks that do not have a basefee") + return tip, big.NewInt(0), nil } return tip, head.BaseFee, nil }

ResourceMetering.sol is compatible with BAS chain.

diff --git ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/ResourceMetering.sol OpenFusionist/optimism/packages/contracts-bedrock/src/L1/ResourceMetering.sol index b4d061c0266fb2580b9adbc42cb8d96d8eaa0d90..5ccabad5da050900a89965a89927e7e065a6a941 100644 --- ethereum-optimism/optimism/packages/contracts-bedrock/src/L1/ResourceMetering.sol +++ OpenFusionist/optimism/packages/contracts-bedrock/src/L1/ResourceMetering.sol @@ -134,7 +134,7 @@ // into gas by dividing by the L1 base fee. We assume a minimum base fee of 1 gwei to avoid // division by zero for L1s that don't support 1559 or to avoid excessive gas burns during // periods of extremely low L1 demand. One-day average gas fee hasn't dipped below 1 gwei // during any 1 day period in the last 5 years, so should be fine. - uint256 gasCost = resourceCost / Math.max(block.basefee, 1 gwei); + uint256 gasCost = resourceCost / 1 gwei;   // Give the user a refund based on the amount of gas they used to do all of the work up to // this point. Since we're at the end of the modifier, this should be pretty accurate. Acts

Added support for L1 blocks without ‘safe’ and ‘finalized’ labels.

diff --git ethereum-optimism/optimism/op-service/sources/eth_client.go OpenFusionist/optimism/op-service/sources/eth_client.go index 553615857908c0eb1de2230676bf99341df65581..85d13c9a6c5a47b65a919d1d13bcc19d2da16f09 100644 --- ethereum-optimism/optimism/op-service/sources/eth_client.go +++ OpenFusionist/optimism/op-service/sources/eth_client.go @@ -303,6 +303,26 @@ return s.headerCall(ctx, "eth_getBlockByNumber", numberID(number)) }   func (s *EthClient) InfoByLabel(ctx context.Context, label eth.BlockLabel) (eth.BlockInfo, error) { + if label == eth.Safe { + byLabel, err := s.InfoByLabel(ctx, eth.Unsafe) + if err != nil { + return nil, err + } + if byLabel.NumberU64() <= 10 { + return nil, ethereum.NotFound + } + return s.InfoByNumber(ctx, byLabel.NumberU64()-10) + } + if label == eth.Finalized { + byLabel, err := s.InfoByLabel(ctx, eth.Unsafe) + if err != nil { + return nil, err + } + if byLabel.NumberU64() <= 15 { + return nil, ethereum.NotFound + } + return s.InfoByNumber(ctx, byLabel.NumberU64()-15) + } // can't hit the cache when querying the head due to reorgs / changes. return s.headerCall(ctx, "eth_getBlockByNumber", label) } @@ -338,6 +358,26 @@ return s.payloadCall(ctx, "eth_getBlockByNumber", numberID(number)) }   func (s *EthClient) PayloadByLabel(ctx context.Context, label eth.BlockLabel) (*eth.ExecutionPayload, error) { + if label == eth.Safe { + byLabel, err := s.PayloadByLabel(ctx, eth.Unsafe) + if err != nil { + return nil, err + } + if byLabel.BlockNumber <= 10 { + return nil, ethereum.NotFound + } + return s.PayloadByNumber(ctx, uint64(byLabel.BlockNumber-10)) + } + if label == eth.Finalized { + byLabel, err := s.PayloadByLabel(ctx, eth.Unsafe) + if err != nil { + return nil, err + } + if byLabel.BlockNumber <= 15 { + return nil, ethereum.NotFound + } + return s.PayloadByNumber(ctx, uint64(byLabel.BlockNumber-15)) + } return s.payloadCall(ctx, "eth_getBlockByNumber", label) }

Establish default values for gas tip cap when it’s nil.

diff --git ethereum-optimism/optimism/op-service/txmgr/metrics/tx_metrics.go OpenFusionist/optimism/op-service/txmgr/metrics/tx_metrics.go index 919e769ff8261d5894e83da3f061412bfd28e612..a49f8061d01061311d6a2ebe4ee8dc5bbdb20a70 100644 --- ethereum-optimism/optimism/op-service/txmgr/metrics/tx_metrics.go +++ OpenFusionist/optimism/op-service/txmgr/metrics/tx_metrics.go @@ -4,6 +4,7 @@ import ( "github.com/ethereum-optimism/optimism/op-service/metrics" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" + "math/big"   "github.com/prometheus/client_golang/prometheus" ) @@ -117,6 +118,9 @@ }   // TxConfirmed records lots of information about the confirmed transaction func (t *TxMetrics) TxConfirmed(receipt *types.Receipt) { + if receipt.EffectiveGasPrice == nil { + receipt.EffectiveGasPrice = big.NewInt(1000000000) + } fee := float64(receipt.EffectiveGasPrice.Uint64() * receipt.GasUsed / params.GWei) t.confirmEvent.Record(receiptStatusString(receipt)) t.TxL1GasFee.Set(fee)

Updated and managed project dependencies.

diff --git ethereum-optimism/optimism/go.mod OpenFusionist/optimism/go.mod index 3713a12490c6db13b0df2042b224bd1159105751..859bfc48e125d5c218077374b1040e9068d8fbfb 100644 --- ethereum-optimism/optimism/go.mod +++ OpenFusionist/optimism/go.mod @@ -209,7 +209,7 @@ lukechampine.com/blake3 v1.2.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect )   -replace github.com/ethereum/go-ethereum v1.13.1 => github.com/ethereum-optimism/op-geth v1.101303.0-rc.2.0.20231024150425-5023660bf92d +replace github.com/ethereum/go-ethereum v1.13.1 => github.com/OpenFusionist/op-geth v1.101303.0-rc.2.0.20231026075306-0665187cbd4e   //replace github.com/ethereum-optimism/superchain-registry/superchain => ../superchain-registry/superchain //replace github.com/ethereum/go-ethereum v1.13.1 => ../go-ethereum
diff --git ethereum-optimism/optimism/go.sum OpenFusionist/optimism/go.sum index 1627f592ddca5af36628a0494606e0dc0fe48497..d59f3ebc62525ce3b4fc943c15a0dd3bdbd580c5 100644 --- ethereum-optimism/optimism/go.sum +++ OpenFusionist/optimism/go.sum @@ -17,6 +17,8 @@ github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/OpenFusionist/op-geth v1.101303.0-rc.2.0.20231026075306-0665187cbd4e h1:ZkMnXJAtVl2izOPnn+KNkqBJoYJUmBtB1zdYLRPn/uA= +github.com/OpenFusionist/op-geth v1.101303.0-rc.2.0.20231026075306-0665187cbd4e/go.mod h1:hl28ffXoV4maInP7dvhvNgDO79Q5M3MEYrPZZO6u3W8= github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= @@ -151,8 +153,6 @@ github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 h1:RWHKLhCrQThMfch+QJ1Z8veEq5ZO3DfIhZ7xgRP9WTc= github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3/go.mod h1:QziizLAiF0KqyLdNJYD7O5cpDlaFMNZzlxYNcWsJUxs= -github.com/ethereum-optimism/op-geth v1.101303.0-rc.2.0.20231024150425-5023660bf92d h1:5dptu9FNKPcZ3o5h2incAbQWH411Mw4HKlsZ4sF4llY= -github.com/ethereum-optimism/op-geth v1.101303.0-rc.2.0.20231024150425-5023660bf92d/go.mod h1:hl28ffXoV4maInP7dvhvNgDO79Q5M3MEYrPZZO6u3W8= github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231018202221-fdba3d104171 h1:MjCUj16JSLZRDnQQ6OOUy6Chfb4dKo7ahFceNi0RKZ8= github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20231018202221-fdba3d104171/go.mod h1:/70H/KqrtKcvWvNGVj6S3rAcLC+kUPr3t2aDmYIS+Xk= github.com/ethereum/c-kzg-4844 v0.3.1 h1:sR65+68+WdnMKxseNWxSJuAv2tsUrihTpVBTfM/U5Zg=