Files
zeekayandHanzo Dev 64f0c83190 Three runtimes implement the precompiles and nothing compared them
Each of them tests its own, and each passes, which is the shape of the
problem: a suite written against an implementation agrees with the
implementation it was written against. Whether the three charge the same price
and return the same bytes for the same call is a question none of them can ask
from the inside.

This is the Go side of that comparison and the corpus it writes: 235 calls,
most borrowed from geth's own precompile test data on the reasoning that an
input the reference tests itself against is one the other two should survive,
the rest covering what that data does not reach — the three precompiles it
ships no vectors for, an empty input to every address, addresses nobody
serves, and the boundary between paying and not paying.

Two things it already establishes about Go alone. At 0x0100 the stock table
charges 6900 and the Lux secp256r1 module charges 3450, and the module is what
answers, because LuxPrecompileOverrider is consulted before the standard
table; the reference asks in that order, so the corpus records the price a
chain actually charges. And address zero is not unclaimed: the dead-address
module is registered there, reads chain state, and cannot be answered for
without a chain — so it says that rather than being answered for, and rather
than taking the run down, which is what a nil state did to it.

`make precompiles` refuses to run with one implementation. That is correct and
it is the next piece of work.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-05 13:15:10 -07:00

60 lines
1.5 KiB
Go

// SPDX-License-Identifier: BSD-3-Clause-Eco
// The Go side of the cross-language precompile differential: it writes the
// corpus, and it is one of the three evaluators that read it.
//
// Two verbs, the same two the chain generator has:
//
// precompile emit <dir> build the corpus and write
// <dir>/precompile_vectors.tsv and
// <dir>/precompile_expected.tsv
// precompile eval <vectors> read a corpus and print this
// implementation's verdicts
//
// `emit` writes the expectations by running `eval` over the vectors it just
// built, so they are what Go said when it read them back rather than a second
// opinion typed beside the bytes.
//
// This module depends on luxfi/geth and luxfi/precompile, and nothing else in
// node2 does. It is a separate Go module for that reason, the same way the
// chain reference is.
package main
import (
"fmt"
"os"
)
func main() {
if len(os.Args) < 2 {
usage()
}
switch os.Args[1] {
case "emit":
dir := "../corpus"
if len(os.Args) > 2 {
dir = os.Args[2]
}
if err := emit(dir); err != nil {
fmt.Fprintln(os.Stderr, "emit:", err)
os.Exit(1)
}
case "eval":
path := "../corpus/precompile_vectors.tsv"
if len(os.Args) > 2 {
path = os.Args[2]
}
if err := eval(path, os.Stdout); err != nil {
fmt.Fprintln(os.Stderr, "eval:", err)
os.Exit(1)
}
default:
usage()
}
}
func usage() {
fmt.Fprintln(os.Stderr, "usage: precompile emit <corpus-dir> | precompile eval <vectors.tsv>")
os.Exit(2)
}