From 81925717b6c26242aefcbc679d81dffa249aa332 Mon Sep 17 00:00:00 2001 From: George Knee Date: Thu, 19 Dec 2024 17:10:06 +0000 Subject: [PATCH] op-chain-ops/ecotone-scalar: prefer `.FillBytes()` to `.Bytes()` and `copy` (#13472) * prefer .FillBytes() to .Bytes() and copy The latter can result in an error if the number is less than 32 bytes in length (it gets padded incorrectly). * add tests * output to JSON * add test case for OPM * tidy up * use const in test --- op-chain-ops/cmd/ecotone-scalar/main.go | 30 +++++++--- op-chain-ops/cmd/ecotone-scalar/main_test.go | 58 ++++++++++++++++++++ 2 files changed, 80 insertions(+), 8 deletions(-) create mode 100644 op-chain-ops/cmd/ecotone-scalar/main_test.go diff --git a/op-chain-ops/cmd/ecotone-scalar/main.go b/op-chain-ops/cmd/ecotone-scalar/main.go index f512901142e8..b1908340bac5 100644 --- a/op-chain-ops/cmd/ecotone-scalar/main.go +++ b/op-chain-ops/cmd/ecotone-scalar/main.go @@ -1,6 +1,7 @@ package main import ( + "encoding/json" "flag" "fmt" "math" @@ -10,6 +11,14 @@ import ( "github.com/ethereum-optimism/optimism/op-service/eth" ) +// These names match those used in the SystemConfig contract +type outputTy struct { + BaseFee uint `json:"baseFeeScalar"` + BlobbaseFeeScalar uint `json:"blobbaseFeeScalar"` + ScalarHex string `json:"scalarHex"` + Scalar *big.Int `json:"scalar"` // post-ecotone +} + func main() { var scalar, blobScalar uint var decode string @@ -43,13 +52,13 @@ func main() { flag.Usage() os.Exit(2) } - encodedSlice := uint256.Bytes() - if len(encodedSlice) > 32 { + byteLen := (uint256.BitLen() + 7) / 8 + if byteLen > 32 { fmt.Fprintln(flag.CommandLine.Output(), "post-ecotone scalar out of uint256 range") flag.Usage() os.Exit(2) } - copy(encoded[:], encodedSlice) + uint256.FillBytes(encoded[:]) decoded, err := eth.DecodeScalar(encoded) if err != nil { fmt.Fprintln(flag.CommandLine.Output(), "post-ecotone scalar could not be decoded:", err) @@ -66,9 +75,14 @@ func main() { } i := new(big.Int).SetBytes(encoded[:]) - fmt.Println("# base fee scalar :", scalar) - fmt.Println("# blob base fee scalar:", blobScalar) - fmt.Printf("# v1 hex encoding : 0x%x\n", encoded[:]) - fmt.Println("# uint value for the 'scalar' parameter in SystemConfigProxy.setGasConfig():") - fmt.Println(i) + o, err := json.Marshal(outputTy{ + BaseFee: scalar, + BlobbaseFeeScalar: blobScalar, + ScalarHex: fmt.Sprintf("0x%x", encoded[:]), + Scalar: i, + }) + if err != nil { + panic(err) + } + fmt.Println(string(o)) } diff --git a/op-chain-ops/cmd/ecotone-scalar/main_test.go b/op-chain-ops/cmd/ecotone-scalar/main_test.go new file mode 100644 index 000000000000..6eaf49bade6a --- /dev/null +++ b/op-chain-ops/cmd/ecotone-scalar/main_test.go @@ -0,0 +1,58 @@ +package main + +import ( + "bytes" + "encoding/json" + "math/big" + "os/exec" + "testing" + + "github.com/stretchr/testify/require" +) + +func runMainWithArgs(t *testing.T, args []string) (string, error) { + t.Helper() + cmd := exec.Command("go", "run", "main.go") + cmd.Args = append(cmd.Args, args...) + + var stdout, stderr bytes.Buffer + cmd.Stdout = &stdout + cmd.Stderr = &stderr + + err := cmd.Run() + output := stdout.String() + stderr.String() + return output, err +} + +func TestMain_PreEcotoneScalar(t *testing.T) { + output, err := runMainWithArgs(t, []string{"-decode=684000"}) + require.NoError(t, err) + + o := new(outputTy) + err = json.Unmarshal([]byte(output), o) + require.NoError(t, err) + require.Equal(t, "0x00000000000000000000000000000000000000000000000000000000000a6fe0", o.ScalarHex) +} + +func TestMain_PostEcotoneScalar(t *testing.T) { + longScalar := "452312848583266388373324160190187140051835877600158453279135543542576845931" + output, err := runMainWithArgs(t, []string{"-decode=" + longScalar}) + require.NoError(t, err) + + o := new(outputTy) + err = json.Unmarshal([]byte(output), o) + if err != nil { + t.Fatal(err) + } + + expected := &outputTy{ + BaseFee: 5227, + BlobbaseFeeScalar: 1014213, + ScalarHex: "0x010000000000000000000000000000000000000000000000000f79c50000146b", + Scalar: new(big.Int), + } + _, ok := expected.Scalar.SetString(longScalar, 0) + + require.True(t, ok) + require.Equal(t, expected, o) +}