diff --git a/deploy.sh b/deploy.sh new file mode 100644 index 000000000000..458542ae75e3 --- /dev/null +++ b/deploy.sh @@ -0,0 +1,417 @@ +#!/bin/bash + +# L2 chain id, use 901 +export OP_L2_CHAIN_ID=${OP_L2_CHAIN_ID:-"901"} + +# OP_DEPLOYER is deploy account,need balance +export OP_DEPLOYER_ADDRESS=${OP_DEPLOYER_ADDRESS?"required"} +export OP_DEPLOYER_PRIVKEY=${OP_DEPLOYER_PRIVKEY?"required"} + +# OP_BATCHER,need balance,submit L2 transaction information OP_BATCHER_SEQUENCER_BATCH_INBOX_ADDRESS +export OP_BATCHER_PRIVKEY=${OP_BATCHER_PRIVKEY?"required"} +export OP_BATCHER_ADDRESS=${OP_BATCHER_ADDRESS?"required"} + +# OP_PROPOSER,need balance,submit L2 transaction result to L1 contract +export OP_PROPOSER_PRIVKEY=${OP_PROPOSER_PRIVKEY?"required"} +export OP_PROPOSER_ADDRESS=${OP_PROPOSER_ADDRESS?"required"} + +# EOA address +export OP_BATCHER_SEQUENCER_BATCH_INBOX_ADDRESS=${OP_BATCHER_SEQUENCER_BATCH_INBOX_ADDRESS?"required"} + +export BSC_TESTNET="https://data-seed-prebsc-1-s1.binance.org:8545" +export BSC_QANET="http://tf-dex-qa-ec2-bsc-test-alb-1168080131.ap-northeast-1.elb.amazonaws.com:8545" +export L1_ENDPOINT="$BSC_TESTNET" + +# ethereum-optimism/optimism root dir +export OP_ROOT_DIR=${OP_ROOT_DIR?"required"} +export OP_NETWORK_NAME="bsc-testnet" +export OP_DATA_DIR=$OP_ROOT_DIR/.$OP_NETWORK_NAME + +clean() { + docker stop l2 op-node op-batcher op-proposer + + rm -rf $OP_DATA_DIR + rm -rf $OP_ROOT_DIR/packages/contracts-bedrock/deployments/$OP_NETWORK_NAME + mkdir $OP_DATA_DIR +} + +l1_chain_id() { + curl $L1_ENDPOINT -X POST --data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":74}' -H 'Content-Type: application/json' \ + | jq '.result' \ + | xargs -I {} printf '%d' {} +} + +l1_tip() { + l1_tip_number=$(curl $L1_ENDPOINT -X POST --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":74}' -H 'Content-Type: application/json' \ + | jq '.result') + l1_tip_timestamp=$(curl $L1_ENDPOINT -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":['"$l1_tip_number"', false],"id":74}' -H 'Content-Type: application/json' \ + | jq '.result.timestamp') + echo "$l1_tip_number" "$l1_tip_timestamp" +} + +start_admin() { + blockhash=$(curl http://127.0.0.1:9546 -X POST --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest", true],"id":74}' -H 'Content-Type: application/json' | jq '.result.hash') + result=$(curl http://127.0.0.1:7546 -X POST --data '{"method":"admin_startSequencer","params":['"$blockhash"'],"id":1,"jsonrpc":"2.0"}' -H 'Content-Type: application/json' | jq '.result') + echo "$blockhash" "$result" +} + +generate_deploy_config() { + l1_chain_id_=$(l1_chain_id) + l1_tip_number=$(l1_tip | awk '{print $1}') + l1_tip_timestamp=$(l1_tip | awk '{print $2}') + + DEPLOY_CONFIG_TEMPLATE=$OP_ROOT_DIR/packages/contracts-bedrock/deploy-config/devnetL1.json + DEPLOY_CONFIG_TARGET=$OP_ROOT_DIR/packages/contracts-bedrock/deploy-config/$OP_NETWORK_NAME.json + cat $DEPLOY_CONFIG_TEMPLATE \ + | jq ".l2ChainID = $OP_L2_CHAIN_ID" \ + | jq ".l1ChainID = $l1_chain_id_" \ + | jq ".l1StartingBlockTag = $l1_tip_number" \ + | jq ".l1GenesisBlockTimestamp = $l1_tip_timestamp" \ + | jq ".sequencerWindowSize = 14400" \ + | jq ".l2BlockTime = 1" \ + | jq --arg OP_DEPLOYER_ADDRESS "$OP_DEPLOYER_ADDRESS" '.controller = $OP_DEPLOYER_ADDRESS' \ + | jq --arg OP_DEPLOYER_ADDRESS "$OP_DEPLOYER_ADDRESS" '.baseFeeVaultRecipient = $OP_DEPLOYER_ADDRESS' \ + | jq --arg OP_DEPLOYER_ADDRESS "$OP_DEPLOYER_ADDRESS" '.proxyAdminOwner = $OP_DEPLOYER_ADDRESS' \ + | jq --arg OP_DEPLOYER_ADDRESS "$OP_DEPLOYER_ADDRESS" '.finalSystemOwner = $OP_DEPLOYER_ADDRESS' \ + | jq --arg OP_DEPLOYER_ADDRESS "$OP_DEPLOYER_ADDRESS" '.governanceTokenOwner = $OP_DEPLOYER_ADDRESS' \ + | jq --arg OP_BATCHER_ADDRESS "$OP_BATCHER_ADDRESS" '.batchSenderAddress = $OP_BATCHER_ADDRESS' \ + | jq --arg OP_PROPOSER_ADDRESS "$OP_PROPOSER_ADDRESS" '.l2OutputOracleProposer = $OP_PROPOSER_ADDRESS' \ + | jq --arg OP_BATCHER_ADDRESS "$OP_BATCHER_ADDRESS" '.p2pSequencerAddress = $OP_BATCHER_ADDRESS' \ + | jq --arg OP_BATCHER_SEQUENCER_BATCH_INBOX_ADDRESS "$OP_BATCHER_SEQUENCER_BATCH_INBOX_ADDRESS" '.batchInboxAddress = $OP_BATCHER_SEQUENCER_BATCH_INBOX_ADDRESS' \ + | tee $DEPLOY_CONFIG_TARGET +} + +deploy_contracts() { + cd $OP_ROOT_DIR/packages/contracts-bedrock + + CHAIN_ID=$(l1_chain_id) \ + L1_RPC=$L1_ENDPOINT \ + PRIVATE_KEY_DEPLOYER=$OP_DEPLOYER_PRIVKEY \ + yarn hardhat --network $OP_NETWORK_NAME deploy +} + +output_addresses() { + DEPLOYMENT_DIR=$OP_ROOT_DIR/packages/contracts-bedrock/deployments/$OP_NETWORK_NAME + ADDRESSES_JSON_PATH=$OP_DATA_DIR/addresses.json + SDK_ADDRESSES_JSON_PATH=$OP_DATA_DIR/sdk-addresses.json + + CONTRACTS=$(ls -1 $DEPLOYMENT_DIR/*.json) + addresses="{}" + for contract_path in $(ls -1 $DEPLOYMENT_DIR/*.json); do + contract_name=$(echo $contract_path | xargs -I {} basename {} | awk -F '.' '{print $1}') + contract_addr=$(cat $contract_path | jq '.address') + addresses=$(echo $addresses | jq ".$contract_name = $contract_addr") + done + echo $addresses | jq | tee $ADDRESSES_JSON_PATH + + sdk_addresses="{ + \"AddressManager\": \"0x0000000000000000000000000000000000000000\", + \"StateCommitmentChain\": \"0x0000000000000000000000000000000000000000\", + \"CanonicalTransactionChain\": \"0x0000000000000000000000000000000000000000\", + \"BondManager\": \"0x0000000000000000000000000000000000000000\", + \"L1CrossDomainMessenger\": $(echo $addresses | jq '.Proxy__OVM_L1CrossDomainMessenger'), + \"L1StandardBridge\": $(echo $addresses | jq '.Proxy__OVM_L1StandardBridge'), + \"OptimismPortal\": $(echo $addresses | jq '.OptimismPortalProxy'), + \"L2OutputOracle\": $(echo $addresses | jq '.L2OutputOracleProxy') + }" + echo $sdk_addresses | jq | tee $SDK_ADDRESSES_JSON_PATH +} + +generate_rollup_config() { + cd $OP_ROOT_DIR/op-node/ + + go run cmd/main.go genesis l2 \ + --l1-rpc $L1_ENDPOINT \ + --deploy-config $OP_ROOT_DIR/packages/contracts-bedrock/deploy-config/$OP_NETWORK_NAME.json \ + --deployment-dir $OP_ROOT_DIR/packages/contracts-bedrock/deployments/$OP_NETWORK_NAME \ + --outfile.l2 $OP_DATA_DIR/genesis-l2.json \ + --outfile.rollup $OP_DATA_DIR/rollup.json +} + +launch_op_geth() { + docker run \ + --name l2 -d -it --rm \ + -p "9545:8545" \ + -p "8551:8551" \ + -v "$OP_DATA_DIR/db:/db" \ + -v "$OP_DATA_DIR/genesis-l2.json:/genesis.json" \ + -v "$OP_ROOT_DIR/ops-bedrock/test-jwt-secret.txt:/config/test-jwt-secret.txt" \ + l2geth:latest --authrpc.jwtsecret=/config/test-jwt-secret.txt + sleep 60 +} + +launch_op_geth_bak() { + docker run \ + --name l2_bak -it --rm \ + -p "9546:8545" \ + -p "8552:8551" \ + -v "$OP_DATA_DIR/db_bak:/db" \ + -v "$OP_DATA_DIR/genesis-l2.json:/genesis.json" \ + -v "$OP_ROOT_DIR/ops-bedrock/test-jwt-secret.txt:/config/test-jwt-secret.txt" \ + l2geth:latest --authrpc.jwtsecret=/config/test-jwt-secret.txt + sleep 60 +} + +launch_op_node() { + docker run \ + --name op-node -d -it --rm \ + -p "7545:8545" \ + -p "9003:9003" \ + -p "7300:7300" \ + -p "6060:6060" \ + -v "$OP_ROOT_DIR/ops-bedrock/p2p-sequencer-key.txt:/config/p2p-sequencer-key.txt" \ + -v "$OP_ROOT_DIR/ops-bedrock/p2p-node-key.txt:/config/p2p-node-key.txt" \ + -v "$OP_ROOT_DIR/ops-bedrock/test-jwt-secret.txt:/config/test-jwt-secret.txt" \ + -v "$OP_DATA_DIR/rollup.json:/rollup.json" \ + -v "$OP_DATA_DIR/op_log:/op_log" \ + op-node:latest \ + op-node \ + --l1.trustrpc \ + --l1=$L1_ENDPOINT \ + --l2=http://host.docker.internal:8551 \ + --l2.jwt-secret=/config/test-jwt-secret.txt \ + --sequencer.enabled \ + --sequencer.stopped \ + --sequencer.l1-confs=0 \ + --verifier.l1-confs=0 \ + --p2p.sequencer.key="$OP_BATCHER_PRIVKEY" \ + --rollup.config=/rollup.json \ + --rpc.addr=0.0.0.0 \ + --rpc.port=8545 \ + --p2p.listen.ip=0.0.0.0 \ + --p2p.listen.tcp=9003 \ + --p2p.listen.udp=9003 \ + --snapshotlog.file=/op_log/snapshot.log \ + --p2p.priv.path=/config/p2p-node-key.txt \ + --metrics.enabled \ + --metrics.addr=0.0.0.0 \ + --metrics.port=7300 \ + --pprof.enabled \ + --rpc.enable-admin + sleep 10 +} + +launch_op_node_bak() { + docker run \ + --name op-node_bak -it --rm \ + -p "7546:8545" \ + -p "9004:9003" \ + -p "7303:7300" \ + -p "6063:6060" \ + -v "$OP_ROOT_DIR/ops-bedrock/p2p-sequencer-key.txt:/config/p2p-sequencer-key.txt" \ + -v "$OP_ROOT_DIR/ops-bedrock/p2p-node-key.txt:/config/p2p-node-key.txt" \ + -v "$OP_ROOT_DIR/ops-bedrock/test-jwt-secret.txt:/config/test-jwt-secret.txt" \ + -v "$OP_DATA_DIR/rollup.json:/rollup.json" \ + -v "$OP_DATA_DIR/op_log_bak:/op_log" \ + op-node:latest \ + op-node \ + --l1.trustrpc \ + --l1=$L1_ENDPOINT \ + --l2=http://host.docker.internal:8552 \ + --l2.jwt-secret=/config/test-jwt-secret.txt \ + --sequencer.enabled \ + --sequencer.stopped \ + --sequencer.l1-confs=0 \ + --verifier.l1-confs=0 \ + --p2p.sequencer.key="$OP_BATCHER_PRIVKEY" \ + --rollup.config=/rollup.json \ + --rpc.addr=0.0.0.0 \ + --rpc.port=8545 \ + --p2p.listen.ip=0.0.0.0 \ + --p2p.listen.tcp=9003 \ + --p2p.listen.udp=9003 \ + --snapshotlog.file=/op_log/snapshot.log \ + --p2p.priv.path=/config/p2p-node-key.txt \ + --metrics.enabled \ + --metrics.addr=0.0.0.0 \ + --metrics.port=7300 \ + --pprof.enabled \ + --rpc.enable-admin + sleep 10 +} + +launch_op_batcher() { + docker run \ + --name op-batcher -d -it --rm \ + -p "6061:6060" \ + -p "7301:7300" \ + --env OP_BATCHER_L1_ETH_RPC=$L1_ENDPOINT \ + --env OP_BATCHER_L2_ETH_RPC="http://host.docker.internal:9545" \ + --env OP_BATCHER_ROLLUP_RPC="http://host.docker.internal:7545" \ + --env OP_BATCHER_MAX_L1_TX_SIZE_BYTES=120000 \ + --env OP_BATCHER_TARGET_L1_TX_SIZE_BYTES=624 \ + --env OP_BATCHER_TARGET_NUM_FRAMES=1 \ + --env OP_BATCHER_APPROX_COMPR_RATIO="1.0" \ + --env OP_BATCHER_CHANNEL_TIMEOUT=40 \ + --env OP_BATCHER_POLL_INTERVAL="10ms" \ + --env OP_BATCHER_NUM_CONFIRMATIONS=1 \ + --env OP_BATCHER_SAFE_ABORT_NONCE_TOO_LOW_COUNT=3 \ + --env OP_BATCHER_RESUBMISSION_TIMEOUT="30s" \ + --env OP_BATCHER_PRIVATE_KEY="${OP_BATCHER_PRIVKEY}" \ + --env OP_BATCHER_SEQUENCER_BATCH_INBOX_ADDRESS="${OP_BATCHER_SEQUENCER_BATCH_INBOX_ADDRESS}" \ + --env OP_BATCHER_LOG_TERMINAL="true" \ + --env OP_BATCHER_PPROF_ENABLED="true" \ + --env OP_BATCHER_METRICS_ENABLED="true" \ + --env OP_BATCHER_SUB_SAFETY_MARGIN=20 \ + op-batcher:latest +} + +launch_op_batcher_bak() { + docker run \ + --name op-batcher_bak -it --rm \ + -p "6064:6060" \ + -p "7304:7300" \ + --env OP_BATCHER_L1_ETH_RPC=$L1_ENDPOINT \ + --env OP_BATCHER_L2_ETH_RPC="http://host.docker.internal:9546" \ + --env OP_BATCHER_ROLLUP_RPC="http://host.docker.internal:7546" \ + --env OP_BATCHER_MAX_L1_TX_SIZE_BYTES=120000 \ + --env OP_BATCHER_TARGET_L1_TX_SIZE_BYTES=624 \ + --env OP_BATCHER_TARGET_NUM_FRAMES=1 \ + --env OP_BATCHER_APPROX_COMPR_RATIO="1.0" \ + --env OP_BATCHER_CHANNEL_TIMEOUT=40 \ + --env OP_BATCHER_POLL_INTERVAL="10ms" \ + --env OP_BATCHER_NUM_CONFIRMATIONS=1 \ + --env OP_BATCHER_SAFE_ABORT_NONCE_TOO_LOW_COUNT=3 \ + --env OP_BATCHER_RESUBMISSION_TIMEOUT="30s" \ + --env OP_BATCHER_PRIVATE_KEY="${OP_BATCHER_PRIVKEY}" \ + --env OP_BATCHER_SEQUENCER_BATCH_INBOX_ADDRESS="${OP_BATCHER_SEQUENCER_BATCH_INBOX_ADDRESS}" \ + --env OP_BATCHER_LOG_TERMINAL="true" \ + --env OP_BATCHER_PPROF_ENABLED="true" \ + --env OP_BATCHER_METRICS_ENABLED="true" \ + --env OP_BATCHER_SUB_SAFETY_MARGIN=20 \ + op-batcher:latest +} + +launch_op_proposer() { + export L2OO_ADDRESS=$(cat $OP_DATA_DIR/addresses.json | jq '.L2OutputOracleProxy' | awk -F '"' '{print $2}') + docker run \ + --name op-proposer -d -it --rm \ + -p "6062:6060" \ + -p "7302:7300" \ + -e OP_PROPOSER_L1_ETH_RPC=$L1_ENDPOINT \ + -e OP_PROPOSER_ROLLUP_RPC="http://host.docker.internal:7545" \ + -e OP_PROPOSER_POLL_INTERVAL="1s" \ + -e OP_PROPOSER_NUM_CONFIRMATIONS=1 \ + -e OP_PROPOSER_SAFE_ABORT_NONCE_TOO_LOW_COUNT=3 \ + -e OP_PROPOSER_RESUBMISSION_TIMEOUT="30s" \ + -e OP_PROPOSER_LOG_TERMINAL="true" \ + -e OP_PROPOSER_L2OO_ADDRESS=${L2OO_ADDRESS} \ + -e OP_PROPOSER_PPROF_ENABLED="true" \ + -e OP_PROPOSER_METRICS_ENABLED="true" \ + -e OP_PROPOSER_ALLOW_NON_FINALIZED="true" \ + -e OP_PROPOSER_PRIVATE_KEY="${OP_PROPOSER_PRIVKEY}" \ + op-proposer:latest +} + +launch_op_proposer_bak() { + export L2OO_ADDRESS=$(cat $OP_DATA_DIR/addresses.json | jq '.L2OutputOracleProxy' | awk -F '"' '{print $2}') + docker run \ + --name op-proposer_bak -it --rm \ + -p "6065:6060" \ + -p "7305:7300" \ + -e OP_PROPOSER_L1_ETH_RPC=$L1_ENDPOINT \ + -e OP_PROPOSER_ROLLUP_RPC="http://host.docker.internal:7546" \ + -e OP_PROPOSER_POLL_INTERVAL="1s" \ + -e OP_PROPOSER_NUM_CONFIRMATIONS=1 \ + -e OP_PROPOSER_SAFE_ABORT_NONCE_TOO_LOW_COUNT=3 \ + -e OP_PROPOSER_RESUBMISSION_TIMEOUT="30s" \ + -e OP_PROPOSER_LOG_TERMINAL="true" \ + -e OP_PROPOSER_L2OO_ADDRESS=${L2OO_ADDRESS} \ + -e OP_PROPOSER_PPROF_ENABLED="true" \ + -e OP_PROPOSER_METRICS_ENABLED="true" \ + -e OP_PROPOSER_ALLOW_NON_FINALIZED="true" \ + -e OP_PROPOSER_PRIVATE_KEY="${OP_PROPOSER_PRIVKEY}" \ + op-proposer:latest +} + +build_all() { + cd $OP_ROOT_DIR + + docker build --file ops-bedrock/Dockerfile.l2 --tag l2geth:latest ops-bedrock + + docker build --file op-node/Dockerfile --tag op-node:latest . + + docker build --file op-batcher/Dockerfile --tag op-batcher:latest . + + docker build --file op-proposer/Dockerfile --tag op-proposer:latest . +} + +main() { + if [ "$#" = "0" ]; then + usage + exit 0 + fi + + command="$1" + shift 1 + + case $command in + "clean") + clean + ;; + "deploy") + generate_deploy_config + deploy_contracts + ;; + "generate_rollup_config") + output_addresses + generate_rollup_config + ;; + "build_all") + build_all + ;; + "launch_all") + launch_op_geth + launch_op_node + launch_op_batcher + launch_op_proposer + ;; + "launch_all_bak") + launch_op_geth_bak + launch_op_node_bak + launch_op_batcher_bak + launch_op_proposer_bak + ;; + "launch_op_geth") + launch_op_geth + ;; + "launch_op_node") + launch_op_node + ;; + "launch_op_batcher") + launch_op_batcher + ;; + "launch_op_proposer") + launch_op_proposer + ;; + "launch_op_geth_bak") + launch_op_geth_bak + ;; + "launch_op_node_bak") + launch_op_node_bak + ;; + "launch_op_batcher_bak") + launch_op_batcher_bak + ;; + "launch_op_proposer_bak") + launch_op_proposer_bak + ;; + "stop_op_geth") + docker stop l2 + ;; + "stop_op_node") + docker stop op-node + ;; + "stop_op_batcher") + docker stop op-batcher + ;; + "stop_op_proposer") + docker stop op-proposer + ;; + "start_admin") + start_admin + ;; + esac +} + +main "$@" diff --git a/op-batcher/batcher/txmgr.go b/op-batcher/batcher/txmgr.go index 3cc6e89812cc..25637a39377d 100644 --- a/op-batcher/batcher/txmgr.go +++ b/op-batcher/batcher/txmgr.go @@ -6,6 +6,7 @@ import ( "math/big" "time" + opservice "github.com/ethereum-optimism/optimism/op-service" "github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" @@ -86,10 +87,14 @@ func (t *TransactionManager) calcGasTipAndFeeCap(ctx context.Context) (gasTipCap if err != nil || head == nil { return nil, nil, fmt.Errorf("failed to get L1 head block for fee cap: %w", err) } - if head.BaseFee == nil { - return nil, nil, fmt.Errorf("failed to get L1 basefee in block %d for fee cap", head.Number) + if opservice.ForBSC { + gasFeeCap = txmgr.CalcGasFeeCap(big.NewInt(0), gasTipCap) + } else { + if head.BaseFee == nil { + return nil, nil, fmt.Errorf("failed to get L1 basefee in block %d for fee cap", head.Number) + } + gasFeeCap = txmgr.CalcGasFeeCap(head.BaseFee, gasTipCap) } - gasFeeCap = txmgr.CalcGasFeeCap(head.BaseFee, gasTipCap) return gasTipCap, gasFeeCap, nil } @@ -102,6 +107,7 @@ func (t *TransactionManager) CraftTx(ctx context.Context, data []byte) (*types.T if err != nil { return nil, err } + _ = gasTipCap childCtx, cancel := context.WithTimeout(ctx, networkTimeout) nonce, err := t.l1Client.NonceAt(childCtx, t.senderAddress, nil) @@ -110,14 +116,20 @@ func (t *TransactionManager) CraftTx(ctx context.Context, data []byte) (*types.T return nil, fmt.Errorf("failed to get nonce: %w", err) } - rawTx := &types.DynamicFeeTx{ - ChainID: t.chainID, - Nonce: nonce, - To: &t.batchInboxAddress, - GasTipCap: gasTipCap, - GasFeeCap: gasFeeCap, - Data: data, + rawTx := &types.LegacyTx{ + Nonce: nonce, + To: &t.batchInboxAddress, + GasPrice: gasFeeCap, + Data: data, } + // rawTx := &types.DynamicFeeTx{ + // ChainID: t.chainID, + // Nonce: nonce, + // To: &t.batchInboxAddress, + // GasTipCap: gasTipCap, + // GasFeeCap: gasFeeCap, + // Data: data, + // } t.log.Info("creating tx", "to", rawTx.To, "from", t.senderAddress) gas, err := core.IntrinsicGas(rawTx.Data, nil, false, true, true, false) diff --git a/op-chain-ops/genesis/config.go b/op-chain-ops/genesis/config.go index f8b5c8454f32..b2182e752633 100644 --- a/op-chain-ops/genesis/config.go +++ b/op-chain-ops/genesis/config.go @@ -20,6 +20,8 @@ import ( "github.com/ethereum-optimism/optimism/op-chain-ops/state" "github.com/ethereum-optimism/optimism/op-node/eth" "github.com/ethereum-optimism/optimism/op-node/rollup" + "github.com/ethereum-optimism/optimism/op-node/rollup/derive" + opservice "github.com/ethereum-optimism/optimism/op-service" ) var ( @@ -420,8 +422,10 @@ func NewL2StorageConfig(config *DeployConfig, block *types.Block) (state.Storage 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") + if !opservice.ForBSC { + if block.BaseFee() == nil { + return storage, errors.New("block base fee not set") + } } storage["L2ToL1MessagePasser"] = state.StorageValues{ @@ -434,8 +438,8 @@ func NewL2StorageConfig(config *DeployConfig, block *types.Block) (state.Storage "msgNonce": 0, } storage["L1Block"] = state.StorageValues{ - "number": block.Number(), - "timestamp": block.Time(), + "number": block.Number(), + "timestamp": block.Time(), "basefee": block.BaseFee(), "hash": block.Hash(), "sequenceNumber": 0, @@ -443,6 +447,9 @@ func NewL2StorageConfig(config *DeployConfig, block *types.Block) (state.Storage "l1FeeOverhead": config.GasPriceOracleOverhead, "l1FeeScalar": config.GasPriceOracleScalar, } + if opservice.ForBSC { + storage["L1Block"]["basefee"] = derive.BSCFakeBaseFee + } storage["LegacyERC20ETH"] = state.StorageValues{ "_name": "Ether", "_symbol": "ETH", diff --git a/op-e2e/actions/action.go b/op-e2e/actions/action.go index 53b710a44e21..50ffadb35147 100644 --- a/op-e2e/actions/action.go +++ b/op-e2e/actions/action.go @@ -5,6 +5,7 @@ import ( "os" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils" + opservice "github.com/ethereum-optimism/optimism/op-service" ) var enableParallelTesting bool = true @@ -13,6 +14,7 @@ func init() { if os.Getenv("OP_E2E_DISABLE_PARALLEL") == "true" { enableParallelTesting = false } + opservice.ForBSC = false } func parallel(t e2eutils.TestingBase) { diff --git a/op-e2e/system_test.go b/op-e2e/system_test.go index ce6b30bccd02..07e1bdcb5450 100644 --- a/op-e2e/system_test.go +++ b/op-e2e/system_test.go @@ -35,6 +35,7 @@ import ( "github.com/ethereum-optimism/optimism/op-node/sources" "github.com/ethereum-optimism/optimism/op-node/testlog" "github.com/ethereum-optimism/optimism/op-node/withdrawals" + opservice "github.com/ethereum-optimism/optimism/op-service" ) var enableParallelTesting bool = true @@ -53,6 +54,7 @@ func init() { if os.Getenv("OP_E2E_DISABLE_PARALLEL") == "true" { enableParallelTesting = false } + opservice.ForBSC = false } func parallel(t *testing.T) { diff --git a/op-node/eth/heads.go b/op-node/eth/heads.go index af92990f0f1d..0ea669553a2d 100644 --- a/op-node/eth/heads.go +++ b/op-node/eth/heads.go @@ -8,6 +8,8 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" + + opservice "github.com/ethereum-optimism/optimism/op-service" ) // HeadSignalFn is used as callback function to accept head-signals @@ -48,8 +50,11 @@ func WatchHeadChanges(ctx context.Context, src NewHeadSource, fn HeadSignalFn) ( type L1BlockRefsSource interface { L1BlockRefByLabel(ctx context.Context, label BlockLabel) (L1BlockRef, error) + L1BlockRefByNumber(ctx context.Context, num uint64) (L1BlockRef, error) } +var finalizedBlockNumberForBSC uint64 = 15 + // PollBlockChanges opens a polling loop to fetch the L1 block reference with the given label, // on provided interval and with request timeout. Results are returned with provided callback fn, // which may block to pause/back-pressure polling. @@ -72,7 +77,24 @@ func PollBlockChanges(ctx context.Context, log log.Logger, src L1BlockRefsSource if err != nil { log.Warn("failed to poll L1 block", "label", label, "err", err) } else { - fn(ctx, ref) + if opservice.ForBSC { + reqCtx, reqCancel := context.WithTimeout(ctx, timeout) + number := ref.Number + if number < finalizedBlockNumberForBSC { + number = 0 + } else { + number -= finalizedBlockNumberForBSC + } + ref, err := src.L1BlockRefByNumber(reqCtx, number) + reqCancel() + if err != nil { + log.Warn("failed to poll L1 block", "number", number, "err", err) + } else { + fn(ctx, ref) + } + } else { + fn(ctx, ref) + } } case <-ctx.Done(): return ctx.Err() diff --git a/op-node/flags/flags.go b/op-node/flags/flags.go index df0deb56be5f..1f6c418510fe 100644 --- a/op-node/flags/flags.go +++ b/op-node/flags/flags.go @@ -99,6 +99,13 @@ var ( Usage: "Initialize the sequencer in a stopped state. The sequencer can be started using the admin_startSequencer RPC", EnvVar: prefixEnvVar("SEQUENCER_STOPPED"), } + SequencerMaxSafeLagFlag = cli.Uint64Flag{ + Name: "sequencer.max-safe-lag", + Usage: "Maximum number of L2 blocks for restricting the distance between L2 safe and unsafe", + EnvVar: prefixEnvVar("SEQUENCER_MAX_SAFE_LAG"), + Required: false, + Value: 0, + } SequencerL1Confs = cli.Uint64Flag{ Name: "sequencer.l1-confs", Usage: "Number of L1 blocks to keep distance from the L1 head as a sequencer for picking an L1 origin.", @@ -203,6 +210,7 @@ var optionalFlags = append([]cli.Flag{ VerifierL1Confs, SequencerEnabledFlag, SequencerStoppedFlag, + SequencerMaxSafeLagFlag, SequencerL1Confs, L1EpochPollIntervalFlag, LogLevelFlag, diff --git a/op-node/node/node.go b/op-node/node/node.go index ed194818d2f8..b44ce2fce605 100644 --- a/op-node/node/node.go +++ b/op-node/node/node.go @@ -145,9 +145,9 @@ func (n *OpNode) initL1(ctx context.Context, cfg *Config) error { // Poll for the safe L1 block and finalized block, // which only change once per epoch at most and may be delayed. - n.l1SafeSub = eth.PollBlockChanges(n.resourcesCtx, n.log, n.l1Source, n.OnNewL1Safe, eth.Safe, + n.l1SafeSub = eth.PollBlockChanges(n.resourcesCtx, n.log, n.l1Source, n.OnNewL1Safe, eth.Unsafe, cfg.L1EpochPollInterval, time.Second*10) - n.l1FinalizedSub = eth.PollBlockChanges(n.resourcesCtx, n.log, n.l1Source, n.OnNewL1Finalized, eth.Finalized, + n.l1FinalizedSub = eth.PollBlockChanges(n.resourcesCtx, n.log, n.l1Source, n.OnNewL1Finalized, eth.Unsafe, cfg.L1EpochPollInterval, time.Second*10) return nil } diff --git a/op-node/rollup/derive/l1_block_info.go b/op-node/rollup/derive/l1_block_info.go index 0e4733d71069..7c45ac08571d 100644 --- a/op-node/rollup/derive/l1_block_info.go +++ b/op-node/rollup/derive/l1_block_info.go @@ -12,6 +12,7 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/predeploys" "github.com/ethereum-optimism/optimism/op-node/eth" + opservice "github.com/ethereum-optimism/optimism/op-service" ) const ( @@ -54,11 +55,13 @@ func (info *L1BlockInfo) MarshalBinary() ([]byte, error) { offset += 32 binary.BigEndian.PutUint64(data[offset+24:offset+32], info.Time) offset += 32 - // Ensure that the baseFee is not too large. - if info.BaseFee.BitLen() > 256 { - return nil, fmt.Errorf("base fee exceeds 256 bits: %d", info.BaseFee) + if info.BaseFee != nil { + // Ensure that the baseFee is not too large. + if info.BaseFee.BitLen() > 256 { + return nil, fmt.Errorf("base fee exceeds 256 bits: %d", info.BaseFee) + } + info.BaseFee.FillBytes(data[offset : offset+32]) } - info.BaseFee.FillBytes(data[offset : offset+32]) offset += 32 copy(data[offset:offset+32], info.BlockHash.Bytes()) offset += 32 @@ -117,6 +120,8 @@ func L1InfoDepositTxData(data []byte) (L1BlockInfo, error) { return info, err } +var BSCFakeBaseFee = big.NewInt(5000000000) + // L1InfoDeposit creates a L1 Info deposit transaction based on the L1 block, // and the L2 block-height difference with the start of the epoch. func L1InfoDeposit(seqNumber uint64, block eth.BlockInfo, sysCfg eth.SystemConfig, regolith bool) (*types.DepositTx, error) { @@ -130,6 +135,9 @@ func L1InfoDeposit(seqNumber uint64, block eth.BlockInfo, sysCfg eth.SystemConfi L1FeeOverhead: sysCfg.Overhead, L1FeeScalar: sysCfg.Scalar, } + if opservice.ForBSC { + infoDat.BaseFee = BSCFakeBaseFee + } data, err := infoDat.MarshalBinary() if err != nil { return nil, err diff --git a/op-node/rollup/derive/l1_block_info_test.go b/op-node/rollup/derive/l1_block_info_test.go index 721046178eee..7a841e5b5f41 100644 --- a/op-node/rollup/derive/l1_block_info_test.go +++ b/op-node/rollup/derive/l1_block_info_test.go @@ -12,6 +12,7 @@ import ( "github.com/ethereum-optimism/optimism/op-node/eth" "github.com/ethereum-optimism/optimism/op-node/testutils" + opservice "github.com/ethereum-optimism/optimism/op-service" ) var _ eth.BlockInfo = (*testutils.MockBlockInfo)(nil) @@ -35,6 +36,7 @@ func randomL1Cfg(rng *rand.Rand, l1Info eth.BlockInfo) eth.SystemConfig { var MockDepositContractAddr = common.HexToAddress("0xdeadbeefdeadbeefdeadbeefdeadbeef00000000") func TestParseL1InfoDepositTxData(t *testing.T) { + opservice.ForBSC = false randomSeqNr := func(rng *rand.Rand) uint64 { return rng.Uint64() } diff --git a/op-node/rollup/driver/config.go b/op-node/rollup/driver/config.go index e59ae55c9bae..906770e8af32 100644 --- a/op-node/rollup/driver/config.go +++ b/op-node/rollup/driver/config.go @@ -16,4 +16,7 @@ type Config struct { // SequencerStopped is false when the driver should sequence new blocks. SequencerStopped bool `json:"sequencer_stopped"` + + // SequencerMaxSafeLag is the maximum number of L2 blocks for restricting the distance between L2 safe and unsafe. + SequencerMaxSafeLag uint64 `json:"sequencer_max_safe_lag"` } diff --git a/op-node/service.go b/op-node/service.go index 39c3a17ab7d9..ce737dcdefff 100644 --- a/op-node/service.go +++ b/op-node/service.go @@ -136,10 +136,11 @@ func NewL2EndpointConfig(ctx *cli.Context, log log.Logger) (*node.L2EndpointConf func NewDriverConfig(ctx *cli.Context) (*driver.Config, error) { return &driver.Config{ - VerifierConfDepth: ctx.GlobalUint64(flags.VerifierL1Confs.Name), - SequencerConfDepth: ctx.GlobalUint64(flags.SequencerL1Confs.Name), - SequencerEnabled: ctx.GlobalBool(flags.SequencerEnabledFlag.Name), - SequencerStopped: ctx.GlobalBool(flags.SequencerStoppedFlag.Name), + VerifierConfDepth: ctx.GlobalUint64(flags.VerifierL1Confs.Name), + SequencerConfDepth: ctx.GlobalUint64(flags.SequencerL1Confs.Name), + SequencerEnabled: ctx.GlobalBool(flags.SequencerEnabledFlag.Name), + SequencerStopped: ctx.GlobalBool(flags.SequencerStoppedFlag.Name), + SequencerMaxSafeLag: ctx.GlobalUint64(flags.SequencerMaxSafeLagFlag.Name), }, nil } diff --git a/op-proposer/proposer/l2_output_submitter.go b/op-proposer/proposer/l2_output_submitter.go index cde9c485b673..6a6000f44749 100644 --- a/op-proposer/proposer/l2_output_submitter.go +++ b/op-proposer/proposer/l2_output_submitter.go @@ -19,11 +19,13 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" "github.com/urfave/cli" "github.com/ethereum-optimism/optimism/op-bindings/bindings" "github.com/ethereum-optimism/optimism/op-node/eth" "github.com/ethereum-optimism/optimism/op-node/sources" + opservice "github.com/ethereum-optimism/optimism/op-service" opcrypto "github.com/ethereum-optimism/optimism/op-service/crypto" oplog "github.com/ethereum-optimism/optimism/op-service/log" opmetrics "github.com/ethereum-optimism/optimism/op-service/metrics" @@ -321,6 +323,39 @@ func (l *L2OutputSubmitter) FetchNextOutputInfo(ctx context.Context) (*eth.Outpu return output, true, nil } +// calcGasTipAndFeeCap queries L1 to determine what a suitable miner tip & basefee limit would be for timely inclusion +func (t *L2OutputSubmitter) calcGasTipAndFeeCap(ctx context.Context) (gasTipCap *big.Int, gasFeeCap *big.Int, err error) { + networkTimeout := 10 * time.Second + childCtx, cancel := context.WithTimeout(ctx, networkTimeout) + gasTipCap, err = t.l1Client.SuggestGasTipCap(childCtx) + cancel() + if err != nil { + return nil, nil, fmt.Errorf("failed to get suggested gas tip cap: %w", err) + } + + if gasTipCap == nil { + t.log.Warn("unexpected unset gasTipCap, using default 2 gwei") + gasTipCap = new(big.Int).SetUint64(params.GWei * 2) + } + + childCtx, cancel = context.WithTimeout(ctx, networkTimeout) + head, err := t.l1Client.HeaderByNumber(childCtx, nil) + cancel() + if err != nil || head == nil { + return nil, nil, fmt.Errorf("failed to get L1 head block for fee cap: %w", err) + } + if opservice.ForBSC { + gasFeeCap = txmgr.CalcGasFeeCap(big.NewInt(0), gasTipCap) + } else { + if head.BaseFee == nil { + return nil, nil, fmt.Errorf("failed to get L1 basefee in block %d for fee cap", head.Number) + } + gasFeeCap = txmgr.CalcGasFeeCap(head.BaseFee, gasTipCap) + } + + return gasTipCap, gasFeeCap, nil +} + // CreateProposalTx transforms an output response into a signed output transaction. // It does not send the transaction to the transaction pool. func (l *L2OutputSubmitter) CreateProposalTx(ctx context.Context, output *eth.OutputResponse) (*types.Transaction, error) { @@ -330,21 +365,29 @@ func (l *L2OutputSubmitter) CreateProposalTx(ctx context.Context, output *eth.Ou return nil, err } + gasTipCap, gasFeeCap, err := l.calcGasTipAndFeeCap(ctx) + if err != nil { + return nil, err + } + _ = gasTipCap + opts := &bind.TransactOpts{ From: l.from, Signer: func(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { return l.signerFn(ctx, addr, tx) }, - Context: ctx, - Nonce: new(big.Int).SetUint64(nonce), - NoSend: true, + Context: ctx, + Nonce: new(big.Int).SetUint64(nonce), + GasPrice: gasFeeCap, + NoSend: true, } tx, err := l.l2ooContract.ProposeL2Output( opts, output.OutputRoot, new(big.Int).SetUint64(output.BlockRef.Number), - output.Status.CurrentL1.Hash, + // output.Status.CurrentL1.Hash, + [32]byte{}, new(big.Int).SetUint64(output.Status.CurrentL1.Number)) if err != nil { l.log.Error("failed to create the ProposeL2Output transaction", "err", err) diff --git a/op-service/util.go b/op-service/util.go index 2f282dccffa0..41e1497c6a34 100644 --- a/op-service/util.go +++ b/op-service/util.go @@ -9,6 +9,8 @@ import ( "time" ) +var ForBSC = true + func PrefixEnvVar(prefix, suffix string) string { return prefix + "_" + suffix } diff --git a/op-signer/client/transaction_args.go b/op-signer/client/transaction_args.go index 480d46a15e10..7cfec5069fdb 100644 --- a/op-signer/client/transaction_args.go +++ b/op-signer/client/transaction_args.go @@ -65,20 +65,28 @@ func (args *TransactionArgs) data() []byte { // ToTransaction converts the arguments to a transaction. func (args *TransactionArgs) ToTransaction() *types.Transaction { var data types.TxData - al := types.AccessList{} - if args.AccessList != nil { - al = *args.AccessList - } - data = &types.DynamicFeeTx{ - To: args.To, - ChainID: (*big.Int)(args.ChainID), - Nonce: uint64(*args.Nonce), - Gas: uint64(*args.Gas), - GasFeeCap: (*big.Int)(args.MaxFeePerGas), - GasTipCap: (*big.Int)(args.MaxPriorityFeePerGas), - Value: (*big.Int)(args.Value), - Data: args.data(), - AccessList: al, + // al := types.AccessList{} + // if args.AccessList != nil { + // al = *args.AccessList + // } + // data = &types.DynamicFeeTx{ + // To: args.To, + // ChainID: (*big.Int)(args.ChainID), + // Nonce: uint64(*args.Nonce), + // Gas: uint64(*args.Gas), + // GasFeeCap: (*big.Int)(args.MaxFeePerGas), + // GasTipCap: (*big.Int)(args.MaxPriorityFeePerGas), + // Value: (*big.Int)(args.Value), + // Data: args.data(), + // AccessList: al, + // } + data = &types.LegacyTx{ + To: args.To, + Nonce: uint64(*args.Nonce), + Gas: uint64(*args.Gas), + GasPrice: args.GasPrice.ToInt(), + Value: (*big.Int)(args.Value), + Data: args.data(), } return types.NewTx(data) } diff --git a/ops-bedrock/docker-compose-bsc-multiple-nodes.yml b/ops-bedrock/docker-compose-bsc-multiple-nodes.yml new file mode 100644 index 000000000000..3a9886a9012e --- /dev/null +++ b/ops-bedrock/docker-compose-bsc-multiple-nodes.yml @@ -0,0 +1,239 @@ +version: '3.4' + +# This Compose file is expected to be used with the devnet-up.sh script. +# The volumes below mount the configs generated by the script into each +# service. + +#volumes: +# l2_data: +# l2_data_bak: +# op_log: + + +services: + l2: + image: l2geth + command: > + --authrpc.jwtsecret=/config/test-jwt-secret.txt + --mine + ports: + - "9545:8545" + - "8551:8551" + volumes: + - "${PWD}/../.bsc-testnet/l2_data:/db" + - "${PWD}/../.bsc-testnet/genesis-l2.json:/genesis.json" + - "${PWD}/test-jwt-secret.txt:/config/test-jwt-secret.txt" + + l2_bak: + image: l2geth + command: > + --authrpc.jwtsecret=/config/test-jwt-secret.txt + --rollup.sequencerhttp=http://l2:8545 + --mine + ports: + - "9546:8545" + - "8552:8551" + volumes: + - "${PWD}/../.bsc-testnet/l2_data_bak:/db" + - "${PWD}/../.bsc-testnet/genesis-l2.json:/genesis.json" + - "${PWD}/test-jwt-secret.txt:/config/test-jwt-secret.txt" + + op-node: + depends_on: + # - l1 + - l2 + image: op-node + command: > + op-node + --l1.trustrpc + --l1=https://data-seed-prebsc-1-s1.binance.org:8545 + --l2=http://l2:8551 + --l2.jwt-secret=/config/test-jwt-secret.txt + --sequencer.enabled + --sequencer.l1-confs=0 + --verifier.l1-confs=0 + --p2p.sequencer.key=26222080cf5f7b76c8a0a7fe3382ed3014317b622fa6965ac701a1655b8b756f + --rollup.config=/rollup.json + --rpc.addr=0.0.0.0 + --rpc.port=8545 + --p2p.listen.ip=0.0.0.0 + --p2p.listen.tcp=9004 + --p2p.listen.udp=9004 + --p2p.priv.path=/config/p2p-node-key.txt + --snapshotlog.file=/op_log/snapshot.log + --metrics.enabled + --metrics.addr=0.0.0.0 + --metrics.port=7300 + --pprof.enabled + --rpc.enable-admin + ports: + - "7545:8545" + - "9003:9003" + - "7300:7300" + - "6060:6060" + volumes: + - "${PWD}/p2p-sequencer-key.txt:/config/p2p-sequencer-key.txt" + - "${PWD}/p2p-node-key.txt:/config/p2p-node-key.txt" + - "${PWD}/test-jwt-secret.txt:/config/test-jwt-secret.txt" + - "${PWD}/../.bsc-testnet/rollup.json:/rollup.json" + - "${PWD}/../.bsc-testnet/op_log:/op_log" + + op-node_bak: + depends_on: + # - l1 + - l2_bak + image: op-node + command: > + op-node + --l1.trustrpc + --l1=https://data-seed-prebsc-1-s1.binance.org:8545 + --l2=http://l2_bak:8551 + --l2.jwt-secret=/config/test-jwt-secret.txt + --sequencer.enabled + --sequencer.stopped + --sequencer.l1-confs=0 + --verifier.l1-confs=0 + --p2p.sequencer.key=26222080cf5f7b76c8a0a7fe3382ed3014317b622fa6965ac701a1655b8b756f + --rollup.config=/rollup.json + --rpc.addr=0.0.0.0 + --rpc.port=8545 + --p2p.listen.ip=0.0.0.0 + --p2p.listen.tcp=9003 + --p2p.listen.udp=9003 + --p2p.static=/ip4/172.19.0.4/tcp/9004/p2p/16Uiu2HAmHqrXGts25TtKMBRHtvhWZLNypsobKoggpZye1XQtJpbZ + --p2p.priv.path=/config/p2p-node-key.txt + --snapshotlog.file=/op_log/snapshot.log + --metrics.enabled + --metrics.addr=0.0.0.0 + --metrics.port=7300 + --pprof.enabled + --rpc.enable-admin + ports: + - "7546:8545" + - "9004:9003" + - "7303:7300" + - "6063:6060" + volumes: + - "${PWD}/p2p-sequencer-key.txt:/config/p2p-sequencer-key.txt" + - "${PWD}/p2p-node-key-bak.txt:/config/p2p-node-key.txt" + - "${PWD}/test-jwt-secret.txt:/config/test-jwt-secret.txt" + - "${PWD}/../.bsc-testnet/rollup.json:/rollup.json" + - "${PWD}/../.bsc-testnet/op_log_bak:/op_log" + + op-proposer: + depends_on: + # - l1 + - l2 + - op-node + image: op-proposer + ports: + - "6062:6060" + - "7302:7300" + environment: + OP_PROPOSER_L1_ETH_RPC: https://data-seed-prebsc-1-s1.binance.org:8545 + OP_PROPOSER_ROLLUP_RPC: http://op-node:8545 + OP_PROPOSER_POLL_INTERVAL: 1s + OP_PROPOSER_NUM_CONFIRMATIONS: 1 + OP_PROPOSER_SAFE_ABORT_NONCE_TOO_LOW_COUNT: 3 + OP_PROPOSER_RESUBMISSION_TIMEOUT: 30s + OP_PROPOSER_LOG_TERMINAL: "true" + OP_PROPOSER_L2OO_ADDRESS: "0x93Ac1e79eA2EB895BeECbFD01d647eeaa61275BB" + OP_PROPOSER_PPROF_ENABLED: "true" + OP_PROPOSER_METRICS_ENABLED: "true" + OP_PROPOSER_ALLOW_NON_FINALIZED: "true" + OP_PROPOSER_PRIVATE_KEY: "2bc6925c018204d0b1fd8519293b0fb898e4ed232a6ecb011c9b939690b836e3" + + op-proposer_bak: + depends_on: + # - l1 + - l2_bak + - op-node_bak + image: op-proposer + ports: + - "6065:6060" + - "7305:7300" + environment: + OP_PROPOSER_L1_ETH_RPC: https://data-seed-prebsc-1-s1.binance.org:8545 + OP_PROPOSER_ROLLUP_RPC: http://op-node_bak:8545 + OP_PROPOSER_POLL_INTERVAL: 1s + OP_PROPOSER_NUM_CONFIRMATIONS: 1 + OP_PROPOSER_SAFE_ABORT_NONCE_TOO_LOW_COUNT: 3 + OP_PROPOSER_RESUBMISSION_TIMEOUT: 30s + OP_PROPOSER_LOG_TERMINAL: "true" + OP_PROPOSER_L2OO_ADDRESS: "0x93Ac1e79eA2EB895BeECbFD01d647eeaa61275BB" + OP_PROPOSER_PPROF_ENABLED: "true" + OP_PROPOSER_METRICS_ENABLED: "true" + OP_PROPOSER_ALLOW_NON_FINALIZED: "true" + OP_PROPOSER_PRIVATE_KEY: "2bc6925c018204d0b1fd8519293b0fb898e4ed232a6ecb011c9b939690b836e3" + + op-batcher: + depends_on: + # - l1 + - l2 + - op-node + image: op-batcher + ports: + - "6061:6060" + - "7301:7300" + environment: + OP_BATCHER_L1_ETH_RPC: https://data-seed-prebsc-1-s1.binance.org:8545 + OP_BATCHER_L2_ETH_RPC: http://l2:8545 + OP_BATCHER_ROLLUP_RPC: http://op-node:8545 + OP_BATCHER_MAX_L1_TX_SIZE_BYTES: 120000 + OP_BATCHER_TARGET_L1_TX_SIZE_BYTES: 100000 + OP_BATCHER_TARGET_NUM_FRAMES: 1 + OP_BATCHER_APPROX_COMPR_RATIO: 1.0 + OP_BATCHER_CHANNEL_TIMEOUT: 40 + OP_BATCHER_POLL_INTERVAL: 10ms + OP_BATCHER_NUM_CONFIRMATIONS: 1 + OP_BATCHER_SAFE_ABORT_NONCE_TOO_LOW_COUNT: 3 + OP_BATCHER_RESUBMISSION_TIMEOUT: 30s + OP_BATCHER_PRIVATE_KEY: 26222080cf5f7b76c8a0a7fe3382ed3014317b622fa6965ac701a1655b8b756f + OP_BATCHER_SEQUENCER_BATCH_INBOX_ADDRESS: 0xf66063977037A073D8c3828eC1fd0574f45Fc861 + OP_BATCHER_LOG_TERMINAL: "true" + OP_BATCHER_PPROF_ENABLED: "true" + OP_BATCHER_METRICS_ENABLED: "true" + OP_BATCHER_SUB_SAFETY_MARGIN: 20 + + op-batcher_bak: + depends_on: + # - l1 + - l2_bak + - op-node_bak + image: op-batcher + ports: + - "6064:6060" + - "7304:7300" + environment: + OP_BATCHER_L1_ETH_RPC: https://data-seed-prebsc-1-s1.binance.org:8545 + OP_BATCHER_L2_ETH_RPC: http://l2_bak:8545 + OP_BATCHER_ROLLUP_RPC: http://op-node_bak:8545 + OP_BATCHER_MAX_L1_TX_SIZE_BYTES: 120000 + OP_BATCHER_TARGET_L1_TX_SIZE_BYTES: 100000 + OP_BATCHER_TARGET_NUM_FRAMES: 1 + OP_BATCHER_APPROX_COMPR_RATIO: 1.0 + OP_BATCHER_CHANNEL_TIMEOUT: 40 + OP_BATCHER_POLL_INTERVAL: 10ms + OP_BATCHER_NUM_CONFIRMATIONS: 1 + OP_BATCHER_SAFE_ABORT_NONCE_TOO_LOW_COUNT: 3 + OP_BATCHER_RESUBMISSION_TIMEOUT: 30s + OP_BATCHER_PRIVATE_KEY: 26222080cf5f7b76c8a0a7fe3382ed3014317b622fa6965ac701a1655b8b756f + OP_BATCHER_SEQUENCER_BATCH_INBOX_ADDRESS: 0xf66063977037A073D8c3828eC1fd0574f45Fc861 + OP_BATCHER_LOG_TERMINAL: "true" + OP_BATCHER_PPROF_ENABLED: "true" + OP_BATCHER_METRICS_ENABLED: "true" + OP_BATCHER_SUB_SAFETY_MARGIN: 20 + +# stateviz: +# build: +# context: ../ +# dockerfile: ./ops-bedrock/Dockerfile.stateviz +# command: +# - stateviz +# - -addr=0.0.0.0:8080 +# - -snapshot=/op_log/snapshot.log +# - -refresh=10s +# ports: +# - "9090:8080" +# volumes: +# - op_log:/op_log:ro diff --git a/packages/contracts-bedrock/contracts/L1/ResourceMetering.sol b/packages/contracts-bedrock/contracts/L1/ResourceMetering.sol index b2322f2ea73b..1393c0ca67c3 100644 --- a/packages/contracts-bedrock/contracts/L1/ResourceMetering.sol +++ b/packages/contracts-bedrock/contracts/L1/ResourceMetering.sol @@ -157,7 +157,8 @@ abstract contract ResourceMetering is Initializable { // 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 / Math.max(block.basefee, 1 gwei); + uint256 gasCost = resourceCost / 5 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