Commit db28a833 authored by protolambda's avatar protolambda Committed by GitHub

change handling of non-zero padding for version 0 scalar (#9068)

Co-authored-by: default avatarRoberto Bayardo <bayardo@alum.mit.edu>
parent 705db877
...@@ -3,7 +3,9 @@ package eth ...@@ -3,7 +3,9 @@ package eth
import ( import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"errors"
"fmt" "fmt"
"math"
"math/big" "math/big"
"reflect" "reflect"
"strconv" "strconv"
...@@ -24,6 +26,10 @@ const ( ...@@ -24,6 +26,10 @@ const (
InvalidPayloadAttributes ErrorCode = -38003 // Payload attributes are invalid / inconsistent. InvalidPayloadAttributes ErrorCode = -38003 // Payload attributes are invalid / inconsistent.
) )
var (
ErrBedrockScalarPaddingNotEmpty = errors.New("version 0 scalar value has non-empty padding")
)
// InputError distinguishes an user-input error from regular rpc errors, // InputError distinguishes an user-input error from regular rpc errors,
// to help the (Engine) API user divert from accidental input mistakes. // to help the (Engine) API user divert from accidental input mistakes.
type InputError struct { type InputError struct {
...@@ -347,6 +353,11 @@ const ( ...@@ -347,6 +353,11 @@ const (
func (sysCfg *SystemConfig) EcotoneScalars() (blobBaseFeeScalar, baseFeeScalar uint32, err error) { func (sysCfg *SystemConfig) EcotoneScalars() (blobBaseFeeScalar, baseFeeScalar uint32, err error) {
if err := CheckEcotoneL1SystemConfigScalar(sysCfg.Scalar); err != nil { if err := CheckEcotoneL1SystemConfigScalar(sysCfg.Scalar); err != nil {
if errors.Is(err, ErrBedrockScalarPaddingNotEmpty) {
// L2 spec mandates we set baseFeeScalar to MaxUint32 if there are non-zero bytes in
// the padding area.
return 0, math.MaxUint32, nil
}
return 0, 0, err return 0, 0, err
} }
switch sysCfg.Scalar[0] { switch sysCfg.Scalar[0] {
...@@ -367,7 +378,7 @@ func CheckEcotoneL1SystemConfigScalar(scalar [32]byte) error { ...@@ -367,7 +378,7 @@ func CheckEcotoneL1SystemConfigScalar(scalar [32]byte) error {
switch versionByte { switch versionByte {
case L1ScalarBedrock: case L1ScalarBedrock:
if ([27]byte)(scalar[1:28]) != ([27]byte{}) { // check padding if ([27]byte)(scalar[1:28]) != ([27]byte{}) { // check padding
return fmt.Errorf("invalid version 0 scalar padding: %x", scalar[1:28]) return ErrBedrockScalarPaddingNotEmpty
} }
return nil return nil
case L1ScalarEcotone: case L1ScalarEcotone:
......
...@@ -2,6 +2,7 @@ package eth ...@@ -2,6 +2,7 @@ package eth
import ( import (
"errors" "errors"
"math"
"testing" "testing"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
...@@ -29,9 +30,10 @@ type scalarTest struct { ...@@ -29,9 +30,10 @@ type scalarTest struct {
func TestEcotoneScalars(t *testing.T) { func TestEcotoneScalars(t *testing.T) {
testCases := []scalarTest{ testCases := []scalarTest{
{"invalid v0 scalar", Bytes32{0: 0, 27: 1, 31: 2}, true, 0, 0}, {"dirty padding v0 scalar", Bytes32{0: 0, 27: 1, 31: 2}, false, 0, math.MaxUint32},
{"dirty padding v0 scalar v2", Bytes32{0: 0, 1: 1, 31: 2}, false, 0, math.MaxUint32},
{"valid v0 scalar", Bytes32{0: 0, 27: 0, 31: 2}, false, 0, 2}, {"valid v0 scalar", Bytes32{0: 0, 27: 0, 31: 2}, false, 0, 2},
{"invalid v1 scalar", Bytes32{0: 0, 7: 1, 31: 2}, true, 0, 0}, {"invalid v1 scalar", Bytes32{0: 1, 7: 1, 31: 2}, true, 0, 0},
{"valid v1 scalar with 0 blob scalar", Bytes32{0: 1, 27: 0, 31: 2}, false, 0, 2}, {"valid v1 scalar with 0 blob scalar", Bytes32{0: 1, 27: 0, 31: 2}, false, 0, 2},
{"valid v1 scalar with non-0 blob scalar", Bytes32{0: 1, 27: 123, 31: 2}, false, 123, 2}, {"valid v1 scalar with non-0 blob scalar", Bytes32{0: 1, 27: 123, 31: 2}, false, 123, 2},
{"valid v1 scalar with non-0 blob scalar and 0 scalar", Bytes32{0: 1, 27: 123, 31: 0}, false, 123, 0}, {"valid v1 scalar with non-0 blob scalar and 0 scalar", Bytes32{0: 1, 27: 123, 31: 0}, false, 123, 0},
......
...@@ -61,9 +61,10 @@ The `scalar` is encoded as big-endian `uint256`, interpreted as `bytes32`, and c ...@@ -61,9 +61,10 @@ The `scalar` is encoded as big-endian `uint256`, interpreted as `bytes32`, and c
- `0`: scalar-version byte - `0`: scalar-version byte
- `[1, 32)`: depending scalar-version: - `[1, 32)`: depending scalar-version:
- Scalar-version `0`: - Scalar-version `0`:
- `[1, 28)`: padding, must be zero. - `[1, 28)`: padding, should be zero.
- `[28, 32)`: big-endian `uint32`, encoding the L1-fee `baseFeeScalar` - `[28, 32)`: big-endian `uint32`, encoding the L1-fee `baseFeeScalar`
- This version implies the L1-fee `blobBaseFeeScalar` is set to 0. - This version implies the L1-fee `blobBaseFeeScalar` is set to 0.
- In the event there are non-zero bytes in the padding area, `baseFeeScalar` must be set to MaxUint32.
- This version is compatible with the pre-Ecotone `scalar` value (assuming a `uint32` range). - This version is compatible with the pre-Ecotone `scalar` value (assuming a `uint32` range).
- Scalar-version `1`: - Scalar-version `1`:
- `[1, 24)`: padding, must be zero. - `[1, 24)`: padding, must be zero.
......
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