diff --git a/core/types/block.go b/core/types/block.go
index 5272d4c2297d..9cf53db28a46 100644
--- a/core/types/block.go
+++ b/core/types/block.go
@@ -60,7 +60,8 @@ func (n *BlockNonce) UnmarshalText(input []byte) error {
}
//go:generate go run github.com/fjl/gencodec -type Header -field-override headerMarshaling -out gen_header_json.go
-//go:generate go run ../../rlp/rlpgen -type Header -internal_methods -out gen_header_rlp.go
+//go:generate go run ../../rlp/rlpgen -type Header -out gen_header_rlp.go
+//go:generate go run ../../libevm/cmd/internalise -file gen_header_rlp.go Header.EncodeRLP
// Header represents a block header in the Ethereum blockchain.
type Header struct {
diff --git a/libevm/cmd/internalise/main.go b/libevm/cmd/internalise/main.go
new file mode 100644
index 000000000000..5bb1b928ce97
--- /dev/null
+++ b/libevm/cmd/internalise/main.go
@@ -0,0 +1,117 @@
+// Copyright 2024 the libevm authors.
+//
+// The libevm additions to go-ethereum are free software: you can redistribute
+// them and/or modify them under the terms of the GNU Lesser General Public License
+// as published by the Free Software Foundation, either version 3 of the License,
+// or (at your option) any later version.
+//
+// The libevm additions are distributed in the hope that they will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+// General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see
+// .
+
+// The internalise command modifies Go files in place, making exported methods
+// internal.
+//
+// Usage:
+//
+// internalise -file . [. [...]]
+//
+// For example, with file foo.go containing declarations:
+//
+// func (f *Foo) Bar() { ... }
+//
+// func (Foo) Baz() { ... }
+//
+// running
+//
+// internalise -file foo.go Foo.Bar Foo.Baz
+//
+// results in
+//
+// func (f *Foo) bar() { ... }
+//
+// func (Foo) baz() { ... }
+package main
+
+import (
+ "flag"
+ "fmt"
+ "go/ast"
+ "go/format"
+ "go/parser"
+ "go/token"
+ "os"
+ "strings"
+)
+
+func main() {
+ file := flag.String("file", "", "File to modify")
+ flag.Parse()
+
+ if err := run(*file, flag.Args()...); err != nil {
+ fmt.Fprint(os.Stderr, err)
+ os.Exit(1)
+ }
+}
+
+func run(fileName string, args ...string) error {
+ methods := make(map[string]map[string]struct{})
+ for _, a := range args {
+ a = strings.TrimPrefix(strings.TrimSpace(a), "*")
+ parts := strings.Split(a, ".")
+ if len(parts) != 2 {
+ return fmt.Errorf("invalid method identifier %q", a)
+ }
+ typ, fn := parts[0], parts[1]
+ if _, ok := methods[typ]; !ok {
+ methods[typ] = make(map[string]struct{})
+ }
+ methods[typ][fn] = struct{}{}
+ }
+
+ fset := token.NewFileSet()
+ mode := parser.SkipObjectResolution | parser.ParseComments
+ parsed, err := parser.ParseFile(fset, fileName, nil, mode)
+ if err != nil {
+ return fmt.Errorf("parser.ParseFile(%q): %v", fileName, err)
+ }
+
+ for _, d := range parsed.Decls {
+ fn, ok := d.(*ast.FuncDecl)
+ if !ok || fn.Recv.NumFields() != 1 {
+ continue
+ }
+
+ var typ string
+ switch t := fn.Recv.List[0].Type.(type) {
+ case *ast.Ident:
+ typ = t.Name
+ case *ast.StarExpr:
+ typ = t.X.(*ast.Ident).Name //nolint:forcetypeassert // Invariant of valid Go method
+ }
+
+ name := &fn.Name.Name
+ if _, ok := methods[typ][*name]; !ok {
+ continue
+ }
+ if n := []rune(*name); n[0] >= 'A' && n[0] <= 'Z' {
+ n[0] += 'a' - 'A'
+ *name = string(n)
+ }
+ }
+
+ // Since we're not creating, the zero perm/mode is ignored.
+ f, err := os.OpenFile(fileName, os.O_TRUNC|os.O_WRONLY, 0) //nolint:gosec // Variable file is under our direct control in go:generate
+ if err != nil {
+ return fmt.Errorf("os.OpenFile(%q, [write-only, truncate]): %v", fileName, err)
+ }
+ if err := format.Node(f, fset, parsed); err != nil {
+ return fmt.Errorf("format.Node(%T): %v", parsed, err)
+ }
+ return f.Close()
+}
diff --git a/rlp/rlpgen/gen.go b/rlp/rlpgen/gen.go
index e641a0564f7e..150797c7aa57 100644
--- a/rlp/rlpgen/gen.go
+++ b/rlp/rlpgen/gen.go
@@ -35,8 +35,6 @@ type buildContext struct {
rawValueType *types.Named
typeToStructCache map[types.Type]*rlpstruct.Type
-
- internalMethods bool
}
func newBuildContext(packageRLP *types.Package) *buildContext {
@@ -100,8 +98,6 @@ type genContext struct {
inPackage *types.Package
imports map[string]struct{}
tempCounter int
-
- internalMethods bool
}
func newGenContext(inPackage *types.Package) *genContext {
@@ -740,7 +736,7 @@ func generateDecoder(ctx *genContext, typ string, op op) []byte {
result, code := op.genDecode(ctx)
var b bytes.Buffer
- fmt.Fprintf(&b, "func (obj *%s) %s(dec *rlp.Stream) error {\n", typ, ctx.decoderMethod())
+ fmt.Fprintf(&b, "func (obj *%s) DecodeRLP(dec *rlp.Stream) error {\n", typ)
fmt.Fprint(&b, code)
fmt.Fprintf(&b, " *obj = %s\n", result)
fmt.Fprintf(&b, " return nil\n")
@@ -755,7 +751,7 @@ func generateEncoder(ctx *genContext, typ string, op op) []byte {
ctx.addImport(pathOfPackageRLP)
var b bytes.Buffer
- fmt.Fprintf(&b, "func (obj *%s) %s(_w io.Writer) error {\n", typ, ctx.encoderMethod())
+ fmt.Fprintf(&b, "func (obj *%s) EncodeRLP(_w io.Writer) error {\n", typ)
fmt.Fprintf(&b, " w := rlp.NewEncoderBuffer(_w)\n")
fmt.Fprint(&b, op.genWrite(ctx, "obj"))
fmt.Fprintf(&b, " return w.Flush()\n")
@@ -777,7 +773,6 @@ func (bctx *buildContext) generate(typ *types.Named, encoder, decoder bool) ([]b
encSource []byte
decSource []byte
)
- ctx.internalMethods = bctx.internalMethods
if encoder {
encSource = generateEncoder(ctx, typ.Obj().Name(), op)
}
diff --git a/rlp/rlpgen/gen.libevm.go b/rlp/rlpgen/gen.libevm.go
deleted file mode 100644
index 63b52c4e1af3..000000000000
--- a/rlp/rlpgen/gen.libevm.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2024 the libevm authors.
-//
-// The libevm additions to go-ethereum are free software: you can redistribute
-// them and/or modify them under the terms of the GNU Lesser General Public License
-// as published by the Free Software Foundation, either version 3 of the License,
-// or (at your option) any later version.
-//
-// The libevm additions are distributed in the hope that they will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
-// General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see
-// .
-
-package main
-
-func (ctx *genContext) encoderMethod() string {
- if ctx.internalMethods {
- return "encodeRLP"
- }
- return "EncodeRLP"
-}
-
-func (ctx *genContext) decoderMethod() string {
- if ctx.internalMethods {
- return "decodeRLP"
- }
- return "DecodeRLP"
-}
diff --git a/rlp/rlpgen/main.go b/rlp/rlpgen/main.go
index e9ac5cd0e650..3e9310458afe 100644
--- a/rlp/rlpgen/main.go
+++ b/rlp/rlpgen/main.go
@@ -36,7 +36,6 @@ func main() {
genEncoder = flag.Bool("encoder", true, "generate EncodeRLP?")
genDecoder = flag.Bool("decoder", false, "generate DecodeRLP?")
typename = flag.String("type", "", "type to generate methods for")
- internal = flag.Bool("internal_methods", false, "generate internal (lower-case) method names")
)
flag.Parse()
@@ -45,7 +44,6 @@ func main() {
Type: *typename,
GenerateEncoder: *genEncoder,
GenerateDecoder: *genDecoder,
- InternalMethods: *internal,
}
code, err := cfg.process()
if err != nil {
@@ -69,8 +67,6 @@ type Config struct {
GenerateEncoder bool
GenerateDecoder bool
-
- InternalMethods bool
}
// process generates the Go code.
@@ -105,7 +101,6 @@ func (cfg *Config) process() (code []byte, err error) {
}
}
bctx := newBuildContext(packageRLP)
- bctx.internalMethods = cfg.InternalMethods
// Find the type and generate.
typ, err := lookupStructType(pkg.Scope(), cfg.Type)