Commit 21859d61 authored by Andreas Bigger's avatar Andreas Bigger

Backwards-compatible WithdrawalNetwork Go type.

parent 90111ed7
...@@ -99,7 +99,7 @@ type DeployConfig struct { ...@@ -99,7 +99,7 @@ type DeployConfig struct {
// L2GenesisRegolithTimeOffset is the number of seconds after genesis block that Regolith hard fork activates. // L2GenesisRegolithTimeOffset is the number of seconds after genesis block that Regolith hard fork activates.
// Set it to 0 to activate at genesis. Nil to disable regolith. // Set it to 0 to activate at genesis. Nil to disable regolith.
L2GenesisRegolithTimeOffset *hexutil.Uint64 `json:"l2GenesisRegolithTimeOffset,omitempty"` L2GenesisRegolithTimeOffset *hexutil.Uint64 `json:"l2GenesisRegolithTimeOffset,omitempty"`
// Configurable extradata. Will default to []byte("BEDROCK") if left unspecified. // L2GenesisBlockExtraData is configurable extradata. Will default to []byte("BEDROCK") if left unspecified.
L2GenesisBlockExtraData []byte `json:"l2GenesisBlockExtraData"` L2GenesisBlockExtraData []byte `json:"l2GenesisBlockExtraData"`
// ProxyAdminOwner represents the owner of the ProxyAdmin predeploy on L2. // ProxyAdminOwner represents the owner of the ProxyAdmin predeploy on L2.
ProxyAdminOwner common.Address `json:"proxyAdminOwner"` ProxyAdminOwner common.Address `json:"proxyAdminOwner"`
...@@ -124,11 +124,11 @@ type DeployConfig struct { ...@@ -124,11 +124,11 @@ type DeployConfig struct {
// SequencerFeeVaultMinimumWithdrawalAmount represents the minimum withdrawal amount for the SequencerFeeVault. // SequencerFeeVaultMinimumWithdrawalAmount represents the minimum withdrawal amount for the SequencerFeeVault.
SequencerFeeVaultMinimumWithdrawalAmount *hexutil.Big `json:"sequencerFeeVaultMinimumWithdrawalAmount"` SequencerFeeVaultMinimumWithdrawalAmount *hexutil.Big `json:"sequencerFeeVaultMinimumWithdrawalAmount"`
// BaseFeeVaultWithdrawalNetwork represents the withdrawal network for the BaseFeeVault. // BaseFeeVaultWithdrawalNetwork represents the withdrawal network for the BaseFeeVault.
BaseFeeVaultWithdrawalNetwork uint8 `json:"baseFeeVaultWithdrawalNetwork"` BaseFeeVaultWithdrawalNetwork WithdrawalNetwork `json:"baseFeeVaultWithdrawalNetwork"`
// L1FeeVaultWithdrawalNetwork represents the withdrawal network for the L1FeeVault. // L1FeeVaultWithdrawalNetwork represents the withdrawal network for the L1FeeVault.
L1FeeVaultWithdrawalNetwork uint8 `json:"l1FeeVaultWithdrawalNetwork"` L1FeeVaultWithdrawalNetwork WithdrawalNetwork `json:"l1FeeVaultWithdrawalNetwork"`
// SequencerFeeVaultWithdrawalNetwork represents the withdrawal network for the SequencerFeeVault. // SequencerFeeVaultWithdrawalNetwork represents the withdrawal network for the SequencerFeeVault.
SequencerFeeVaultWithdrawalNetwork uint8 `json:"sequencerFeeVaultWithdrawalNetwork"` SequencerFeeVaultWithdrawalNetwork WithdrawalNetwork `json:"sequencerFeeVaultWithdrawalNetwork"`
// L1StandardBridgeProxy represents the address of the L1StandardBridgeProxy on L1 and is used // L1StandardBridgeProxy represents the address of the L1StandardBridgeProxy on L1 and is used
// as part of building the L2 genesis state. // as part of building the L2 genesis state.
L1StandardBridgeProxy common.Address `json:"l1StandardBridgeProxy"` L1StandardBridgeProxy common.Address `json:"l1StandardBridgeProxy"`
...@@ -253,13 +253,13 @@ func (d *DeployConfig) Check() error { ...@@ -253,13 +253,13 @@ func (d *DeployConfig) Check() error {
if d.SequencerFeeVaultRecipient == (common.Address{}) { if d.SequencerFeeVaultRecipient == (common.Address{}) {
return fmt.Errorf("%w: SequencerFeeVaultRecipient cannot be address(0)", ErrInvalidDeployConfig) return fmt.Errorf("%w: SequencerFeeVaultRecipient cannot be address(0)", ErrInvalidDeployConfig)
} }
if d.BaseFeeVaultWithdrawalNetwork >= 2 { if !d.BaseFeeVaultWithdrawalNetwork.Valid() {
return fmt.Errorf("%w: BaseFeeVaultWithdrawalNetwork can only be 0 (L1) or 1 (L2)", ErrInvalidDeployConfig) return fmt.Errorf("%w: BaseFeeVaultWithdrawalNetwork can only be 0 (L1) or 1 (L2)", ErrInvalidDeployConfig)
} }
if d.L1FeeVaultWithdrawalNetwork >= 2 { if !d.L1FeeVaultWithdrawalNetwork.Valid() {
return fmt.Errorf("%w: L1FeeVaultWithdrawalNetwork can only be 0 (L1) or 1 (L2)", ErrInvalidDeployConfig) return fmt.Errorf("%w: L1FeeVaultWithdrawalNetwork can only be 0 (L1) or 1 (L2)", ErrInvalidDeployConfig)
} }
if d.SequencerFeeVaultWithdrawalNetwork >= 2 { if !d.SequencerFeeVaultWithdrawalNetwork.Valid() {
return fmt.Errorf("%w: SequencerFeeVaultWithdrawalNetwork can only be 0 (L1) or 1 (L2)", ErrInvalidDeployConfig) return fmt.Errorf("%w: SequencerFeeVaultWithdrawalNetwork can only be 0 (L1) or 1 (L2)", ErrInvalidDeployConfig)
} }
if d.GasPriceOracleOverhead == 0 { if d.GasPriceOracleOverhead == 0 {
...@@ -536,17 +536,17 @@ func NewL2ImmutableConfig(config *DeployConfig, block *types.Block) (immutables. ...@@ -536,17 +536,17 @@ func NewL2ImmutableConfig(config *DeployConfig, block *types.Block) (immutables.
immutable["SequencerFeeVault"] = immutables.ImmutableValues{ immutable["SequencerFeeVault"] = immutables.ImmutableValues{
"recipient": config.SequencerFeeVaultRecipient, "recipient": config.SequencerFeeVaultRecipient,
"minimumWithdrawalAmount": config.SequencerFeeVaultMinimumWithdrawalAmount, "minimumWithdrawalAmount": config.SequencerFeeVaultMinimumWithdrawalAmount,
"withdrawalNetwork": config.SequencerFeeVaultWithdrawalNetwork, "withdrawalNetwork": config.SequencerFeeVaultWithdrawalNetwork.ToUint8(),
} }
immutable["L1FeeVault"] = immutables.ImmutableValues{ immutable["L1FeeVault"] = immutables.ImmutableValues{
"recipient": config.L1FeeVaultRecipient, "recipient": config.L1FeeVaultRecipient,
"minimumWithdrawalAmount": config.L1FeeVaultMinimumWithdrawalAmount, "minimumWithdrawalAmount": config.L1FeeVaultMinimumWithdrawalAmount,
"withdrawalNetwork": config.L1FeeVaultWithdrawalNetwork, "withdrawalNetwork": config.L1FeeVaultWithdrawalNetwork.ToUint8(),
} }
immutable["BaseFeeVault"] = immutables.ImmutableValues{ immutable["BaseFeeVault"] = immutables.ImmutableValues{
"recipient": config.BaseFeeVaultRecipient, "recipient": config.BaseFeeVaultRecipient,
"minimumWithdrawalAmount": config.BaseFeeVaultMinimumWithdrawalAmount, "minimumWithdrawalAmount": config.BaseFeeVaultMinimumWithdrawalAmount,
"withdrawalNetwork": config.BaseFeeVaultWithdrawalNetwork, "withdrawalNetwork": config.BaseFeeVaultWithdrawalNetwork.ToUint8(),
} }
return immutable, nil return immutable, nil
......
...@@ -27,9 +27,9 @@ ...@@ -27,9 +27,9 @@
"baseFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", "baseFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000",
"l1FeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", "l1FeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000",
"sequencerFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", "sequencerFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000",
"baseFeeVaultWithdrawalNetwork": 0, "baseFeeVaultWithdrawalNetwork": "local",
"l1FeeVaultWithdrawalNetwork": 0, "l1FeeVaultWithdrawalNetwork": "local",
"sequencerFeeVaultWithdrawalNetwork": 0, "sequencerFeeVaultWithdrawalNetwork": "local",
"l1ERC721BridgeProxy": "0xff000000000000000000000000000000000000ff", "l1ERC721BridgeProxy": "0xff000000000000000000000000000000000000ff",
"l1StandardBridgeProxy": "0xff000000000000000000000000000000000000fd", "l1StandardBridgeProxy": "0xff000000000000000000000000000000000000fd",
......
...@@ -44,9 +44,9 @@ ...@@ -44,9 +44,9 @@
"baseFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", "baseFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000",
"l1FeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", "l1FeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000",
"sequencerFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000", "sequencerFeeVaultMinimumWithdrawalAmount": "0x8ac7230489e80000",
"baseFeeVaultWithdrawalNetwork": 0, "baseFeeVaultWithdrawalNetwork": "remote",
"l1FeeVaultWithdrawalNetwork": 0, "l1FeeVaultWithdrawalNetwork": "local",
"sequencerFeeVaultWithdrawalNetwork": 0, "sequencerFeeVaultWithdrawalNetwork": "local",
"l1StandardBridgeProxy": "0x42000000000000000000000000000000000000f8", "l1StandardBridgeProxy": "0x42000000000000000000000000000000000000f8",
"l1CrossDomainMessengerProxy": "0x42000000000000000000000000000000000000f9", "l1CrossDomainMessengerProxy": "0x42000000000000000000000000000000000000f9",
"l1ERC721BridgeProxy": "0x4200000000000000000000000000000000000060", "l1ERC721BridgeProxy": "0x4200000000000000000000000000000000000060",
......
package genesis
import (
"encoding/json"
"fmt"
"strconv"
)
// WithdrawalNetwork represents the network that withdrawals are sent to.
// Its value when marshalled in json is intended to be a consistent with its
// internal string type but is backwards-compatible with uint8 values.
// That is, WithdrawalNetwork can be unmarshalled from a JSON field into a uint8.
type WithdrawalNetwork string
// Valid returns if the withdrawal network is valid.
func (w *WithdrawalNetwork) Valid() bool {
switch *w {
case "local", "remote":
return true
default:
return false
}
}
// ToUint8 converts a WithdrawalNetwork to a uint8.
func (w *WithdrawalNetwork) ToUint8() uint8 {
switch *w {
case "remote":
return 0
default:
return 1
}
}
// FromUint8 converts a uint8 to a WithdrawalNetwork.
func FromUint8(i uint8) WithdrawalNetwork {
switch i {
case 0:
return WithdrawalNetwork("remote")
case 1:
return WithdrawalNetwork("local")
default:
return WithdrawalNetwork(strconv.Itoa(int(i)))
}
}
// UnmarshalJSON implements the json.Unmarshaler interface, which
// allows us to ingest values of any json type as an int and run our custom conversion
func (w *WithdrawalNetwork) UnmarshalJSON(b []byte) error {
var s WithdrawalNetwork
if b[0] == '"' {
if err := json.Unmarshal(b, (*string)(&s)); err != nil {
return err
}
} else {
var i uint8
if err := json.Unmarshal(b, &i); err != nil {
return err
}
s = FromUint8(i)
}
if !s.Valid() {
return fmt.Errorf("invalid withdrawal network: %v", s)
}
*w = s
return nil
}
package genesis
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/require"
)
// TestWithdrawalNetworkValid checks that valid withdrawal networks are detected.
func TestWithdrawalNetworkValid(t *testing.T) {
localWithdrawalNetwork := WithdrawalNetwork("local")
require.True(t, localWithdrawalNetwork.Valid())
remoteWithdrawalNetwork := WithdrawalNetwork("remote")
require.True(t, remoteWithdrawalNetwork.Valid())
invalidWithdrawalNetwork := WithdrawalNetwork("invalid")
require.False(t, invalidWithdrawalNetwork.Valid())
}
// TestWithdrawalNetworkToUint8 checks that withdrawal networks are converted to uint8 correctly.
func TestWithdrawalNetworkToUint8(t *testing.T) {
localWithdrawalNetwork := WithdrawalNetwork("local")
require.EqualValues(t, 1, localWithdrawalNetwork.ToUint8())
remoteWithdrawalNetwork := WithdrawalNetwork("remote")
require.EqualValues(t, 0, remoteWithdrawalNetwork.ToUint8())
invalidWithdrawalNetwork := WithdrawalNetwork("invalid")
require.EqualValues(t, 1, invalidWithdrawalNetwork.ToUint8())
}
// TestWithdrawalNetworkFromUint8 checks that uint8s are converted to withdrawal networks correctly.
func TestWithdrawalNetworkFromUint8(t *testing.T) {
require.EqualValues(t, "local", FromUint8(1))
require.EqualValues(t, "remote", FromUint8(0))
// invalid uint8s are converted to their uint8 string representation
// this will be caught by the Valid() check
require.EqualValues(t, "2", FromUint8(2))
}
// TestWithdrawalNetworkUnmarshalJSON checks that withdrawal networks are unmarshalled correctly.
func TestWithdrawalNetworkUnmarshalJSON(t *testing.T) {
t.Run("LocalInt", func(t *testing.T) {
var w WithdrawalNetwork
require.NoError(t, json.Unmarshal([]byte(`1`), &w))
require.EqualValues(t, "local", w)
})
t.Run("RemoteInt", func(t *testing.T) {
var w WithdrawalNetwork
require.NoError(t, json.Unmarshal([]byte(`0`), &w))
require.EqualValues(t, "remote", w)
})
t.Run("InvalidInt", func(t *testing.T) {
var w WithdrawalNetwork
require.Error(t, json.Unmarshal([]byte(`2`), &w))
})
t.Run("LocalString", func(t *testing.T) {
var w WithdrawalNetwork
require.NoError(t, json.Unmarshal([]byte(`"local"`), &w))
require.EqualValues(t, "local", w)
})
t.Run("RemoteString", func(t *testing.T) {
var w WithdrawalNetwork
require.NoError(t, json.Unmarshal([]byte(`"remote"`), &w))
require.EqualValues(t, "remote", w)
})
t.Run("InvalidString", func(t *testing.T) {
var w WithdrawalNetwork
require.Error(t, json.Unmarshal([]byte(`"invalid"`), &w))
})
}
// TestWithdrawalNetworkInlineJSON tests unmarshalling of withdrawal networks in inline JSON.
func TestWithdrawalNetworkInlineJSON(t *testing.T) {
type tempNetworks struct {
BaseFeeVaultWithdrawalNetwork WithdrawalNetwork `json:"baseFeeVaultWithdrawalNetwork"`
L1FeeVaultWithdrawalNetwork WithdrawalNetwork `json:"l1FeeVaultWithdrawalNetwork"`
SequencerFeeVaultWithdrawalNetwork WithdrawalNetwork `json:"sequencerFeeVaultWithdrawalNetwork"`
}
jsonString := `{
"baseFeeVaultWithdrawalNetwork": "remote",
"l1FeeVaultWithdrawalNetwork": "local",
"sequencerFeeVaultWithdrawalNetwork": "local"
}`
t.Run("StringMarshaling", func(t *testing.T) {
decoded := new(tempNetworks)
require.NoError(t, json.Unmarshal([]byte(jsonString), decoded))
require.Equal(t, WithdrawalNetwork("remote"), decoded.BaseFeeVaultWithdrawalNetwork)
require.Equal(t, WithdrawalNetwork("local"), decoded.L1FeeVaultWithdrawalNetwork)
require.Equal(t, WithdrawalNetwork("local"), decoded.SequencerFeeVaultWithdrawalNetwork)
encoded, err := json.Marshal(decoded)
require.NoError(t, err)
require.JSONEq(t, jsonString, string(encoded))
})
t.Run("IntMarshaling", func(t *testing.T) {
intJsonString := `{
"baseFeeVaultWithdrawalNetwork": 0,
"l1FeeVaultWithdrawalNetwork": 1,
"sequencerFeeVaultWithdrawalNetwork": 1
}`
decoded := new(tempNetworks)
require.NoError(t, json.Unmarshal([]byte(intJsonString), decoded))
require.Equal(t, WithdrawalNetwork("remote"), decoded.BaseFeeVaultWithdrawalNetwork)
require.Equal(t, WithdrawalNetwork("local"), decoded.L1FeeVaultWithdrawalNetwork)
require.Equal(t, WithdrawalNetwork("local"), decoded.SequencerFeeVaultWithdrawalNetwork)
encoded, err := json.Marshal(decoded)
require.NoError(t, err)
require.JSONEq(t, jsonString, string(encoded))
})
}
...@@ -105,12 +105,12 @@ func MakeDeployParams(t require.TestingT, tp *TestParams) *DeployParams { ...@@ -105,12 +105,12 @@ func MakeDeployParams(t require.TestingT, tp *TestParams) *DeployParams {
SequencerFeeVaultRecipient: common.Address{19: 1}, SequencerFeeVaultRecipient: common.Address{19: 1},
BaseFeeVaultRecipient: common.Address{19: 2}, BaseFeeVaultRecipient: common.Address{19: 2},
L1FeeVaultRecipient: common.Address{19: 3}, L1FeeVaultRecipient: common.Address{19: 3},
BaseFeeVaultMinimumWithdrawalAmount: uint64ToBig(1000_000_000), // 1 gwei BaseFeeVaultMinimumWithdrawalAmount: uint64ToBig(1000_000_000), // 1 gwei
L1FeeVaultMinimumWithdrawalAmount: uint64ToBig(1000_000_000), // 1 gwei L1FeeVaultMinimumWithdrawalAmount: uint64ToBig(1000_000_000), // 1 gwei
SequencerFeeVaultMinimumWithdrawalAmount: uint64ToBig(1000_000_000), // 1 gwei SequencerFeeVaultMinimumWithdrawalAmount: uint64ToBig(1000_000_000), // 1 gwei
BaseFeeVaultWithdrawalNetwork: uint8(1), // L2 withdrawal network BaseFeeVaultWithdrawalNetwork: genesis.WithdrawalNetwork("local"), // L2 withdrawal network
L1FeeVaultWithdrawalNetwork: uint8(1), // L2 withdrawal network L1FeeVaultWithdrawalNetwork: genesis.WithdrawalNetwork("local"), // L2 withdrawal network
SequencerFeeVaultWithdrawalNetwork: uint8(1), // L2 withdrawal network SequencerFeeVaultWithdrawalNetwork: genesis.WithdrawalNetwork("local"), // L2 withdrawal network
EIP1559Elasticity: 10, EIP1559Elasticity: 10,
EIP1559Denominator: 50, EIP1559Denominator: 50,
......
...@@ -128,12 +128,12 @@ func DefaultSystemConfig(t *testing.T) SystemConfig { ...@@ -128,12 +128,12 @@ func DefaultSystemConfig(t *testing.T) SystemConfig {
SequencerFeeVaultRecipient: common.Address{19: 1}, SequencerFeeVaultRecipient: common.Address{19: 1},
BaseFeeVaultRecipient: common.Address{19: 2}, BaseFeeVaultRecipient: common.Address{19: 2},
L1FeeVaultRecipient: common.Address{19: 3}, L1FeeVaultRecipient: common.Address{19: 3},
BaseFeeVaultMinimumWithdrawalAmount: uint642big(1000_000_000), // 1 gwei BaseFeeVaultMinimumWithdrawalAmount: uint642big(1000_000_000), // 1 gwei
L1FeeVaultMinimumWithdrawalAmount: uint642big(1000_000_000), // 1 gwei L1FeeVaultMinimumWithdrawalAmount: uint642big(1000_000_000), // 1 gwei
SequencerFeeVaultMinimumWithdrawalAmount: uint642big(1000_000_000), // 1 gwei SequencerFeeVaultMinimumWithdrawalAmount: uint642big(1000_000_000), // 1 gwei
BaseFeeVaultWithdrawalNetwork: uint8(1), // L2 withdrawal network BaseFeeVaultWithdrawalNetwork: genesis.WithdrawalNetwork("local"), // L2 withdrawal network
L1FeeVaultWithdrawalNetwork: uint8(1), // L2 withdrawal network L1FeeVaultWithdrawalNetwork: genesis.WithdrawalNetwork("local"), // L2 withdrawal network
SequencerFeeVaultWithdrawalNetwork: uint8(1), // L2 withdrawal network SequencerFeeVaultWithdrawalNetwork: genesis.WithdrawalNetwork("local"), // L2 withdrawal network
DeploymentWaitConfirmations: 1, DeploymentWaitConfirmations: 1,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment