mirror of
https://github.com/luxfi/chains.git
synced 2026-07-27 03:39:41 +00:00
The package exported ExecuteBlockV1, V2, V3, V4 and ExecuteBlock for a single operation, plus BlockResult and BlockResultV2 for a single result. V2/V3/V4 were pure argument adapters over the same implementation and V1 additionally downcast the result into a lossy struct, so the versions described how the API had grown rather than anything a caller needs to choose between. Now: ExecuteBlock(backend, numThreads, txs, ctx, state) -> *BlockResult. Callers without a block context or state snapshot pass nil, which is what the adapters did on their behalf. BlockResult carries the full shape; the lossy variant is gone. Nothing outside the package used the versioned names. The duplicate tests went with them — TestExecuteBlockEmpty existed three times and the backend smoke test twice, one per version, all exercising the same function. Merged, keeping every distinct assertion. go vet clean; ./evm/cevm and ./evm/cevm/parallel both pass. Co-authored-by: Hanzo Dev <dev@hanzo.ai>
164 lines
4.6 KiB
Go
164 lines
4.6 KiB
Go
package cevm
|
|
|
|
import "testing"
|
|
|
|
// Tests in this file run under both `cgo` and `!cgo` builds. They cover the
|
|
// parts of the API that don't depend on the C++ library: enum stringers,
|
|
// constant exports, and the empty-input fast-paths that ExecuteBlock /
|
|
// ExecuteBlock promise to return without error.
|
|
|
|
func TestBackendString(t *testing.T) {
|
|
tests := []struct {
|
|
b Backend
|
|
want string
|
|
}{
|
|
{CPUSequential, "cpu-sequential"},
|
|
{CPUParallel, "cpu-parallel"},
|
|
{GPUMetal, "gpu-metal"},
|
|
{GPUCUDA, "gpu-cuda"},
|
|
{Backend(99), "unknown(99)"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
if got := tt.b.String(); got != tt.want {
|
|
t.Errorf("Backend(%d).String() = %q, want %q", int(tt.b), got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTxStatusString(t *testing.T) {
|
|
tests := []struct {
|
|
s TxStatus
|
|
want string
|
|
}{
|
|
{TxOK, "ok"},
|
|
{TxReturn, "return"},
|
|
{TxRevert, "revert"},
|
|
{TxOOG, "oog"},
|
|
{TxError, "error"},
|
|
{TxCallNotSupported, "call-not-supported"},
|
|
{TxStatus(99), "status(99)"},
|
|
}
|
|
for _, tt := range tests {
|
|
if got := tt.s.String(); got != tt.want {
|
|
t.Errorf("TxStatus(%d).String() = %q, want %q", int(tt.s), got, tt.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestVMID(t *testing.T) {
|
|
if got := VMID(); got != "cevm" {
|
|
t.Errorf("VMID() = %q, want %q", got, "cevm")
|
|
}
|
|
}
|
|
|
|
func TestPluginPath(t *testing.T) {
|
|
p := PluginPath()
|
|
if p == "" {
|
|
t.Skip("could not determine home directory")
|
|
}
|
|
const suffix = "work/luxcpp/evm/build/bin/cevm"
|
|
if len(p) < len(suffix) {
|
|
t.Fatalf("PluginPath() too short: %q", p)
|
|
}
|
|
got := p[len(p)-len(suffix):]
|
|
if got != suffix {
|
|
t.Errorf("PluginPath() suffix = %q, want %q", got, suffix)
|
|
}
|
|
}
|
|
|
|
func TestPluginExists(t *testing.T) {
|
|
// This test just verifies the function runs without panicking.
|
|
// Whether it returns true or false depends on the build environment.
|
|
_ = PluginExists()
|
|
}
|
|
|
|
// TestExecuteBlockEmpty pins the contract for a block with no transactions:
|
|
// no error, no gas, and the ABI the linked library reports.
|
|
func TestExecuteBlockEmpty(t *testing.T) {
|
|
result, err := ExecuteBlock(CPUSequential, 0, nil, nil, nil)
|
|
if err != nil {
|
|
t.Fatalf("ExecuteBlock(nil): %v", err)
|
|
}
|
|
if result.TotalGas != 0 {
|
|
t.Errorf("TotalGas = %d, want 0 for an empty block", result.TotalGas)
|
|
}
|
|
if result.ABIVersion != ABIVersion {
|
|
t.Errorf("ABIVersion = %d, want %d", result.ABIVersion, ABIVersion)
|
|
}
|
|
}
|
|
|
|
// TestAvailableBackends_NonEmpty: every build must expose at least one backend.
|
|
// Under nocgo, that's CPUSequential. Under cgo, it's whatever the loaded
|
|
// library reports — but never zero.
|
|
func TestAvailableBackends_NonEmpty(t *testing.T) {
|
|
bs := AvailableBackends()
|
|
if len(bs) == 0 {
|
|
t.Fatal("AvailableBackends() returned empty list")
|
|
}
|
|
}
|
|
|
|
func TestBackendName_NonEmpty(t *testing.T) {
|
|
for _, b := range []Backend{CPUSequential, CPUParallel, GPUMetal, GPUCUDA} {
|
|
if BackendName(b) == "" {
|
|
t.Errorf("BackendName(%d) is empty", int(b))
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestHealth_AlwaysReturnsReports: Health() must never return nil. Under
|
|
// nocgo it returns a single non-OK report. Under cgo it returns one report
|
|
// per available backend.
|
|
func TestHealth_AlwaysReturnsReports(t *testing.T) {
|
|
reports := Health()
|
|
if len(reports) == 0 {
|
|
t.Fatal("Health() returned no reports — even nocgo must report status")
|
|
}
|
|
}
|
|
|
|
// TestABIVersion locks the ABIVersion constant so a careless bump is caught
|
|
// by code review. Update both this test and ABIVersion together when the
|
|
// C ABI surface changes.
|
|
func TestABIVersion(t *testing.T) {
|
|
const want uint32 = 6
|
|
if ABIVersion != want {
|
|
t.Errorf("ABIVersion = %d, want %d (update C-side EVM_GPU_ABI_VERSION in lockstep)",
|
|
ABIVersion, want)
|
|
}
|
|
}
|
|
|
|
// TestBlockContextLayout asserts the Go BlockContext fields are the right
|
|
// widths in the right order. The C-side layout assertion lives in
|
|
// go_bridge.cpp (static_assert sizeof(BlockContext) == sizeof(CBlockContext));
|
|
// this test catches Go-side reordering before it reaches the C ABI.
|
|
func TestBlockContextLayout(t *testing.T) {
|
|
var ctx BlockContext
|
|
ctx.Origin[0] = 0xAA
|
|
ctx.Origin[19] = 0xBB
|
|
ctx.GasPrice = 1
|
|
ctx.Timestamp = 2
|
|
ctx.Number = 3
|
|
ctx.Prevrandao[0] = 0xCC
|
|
ctx.Prevrandao[31] = 0xDD
|
|
ctx.GasLimit = 4
|
|
ctx.ChainID = 96369
|
|
ctx.BaseFee = 5
|
|
ctx.BlobBaseFee = 6
|
|
ctx.Coinbase[0] = 0xEE
|
|
ctx.Coinbase[19] = 0xFF
|
|
ctx.BlobHashes[0][0] = 0x11
|
|
ctx.BlobHashes[7][31] = 0x22
|
|
ctx.NumBlobHashes = 8
|
|
|
|
// Sanity: the struct round-trips its own fields.
|
|
if ctx.ChainID != 96369 {
|
|
t.Errorf("ChainID round-trip failed: got %d", ctx.ChainID)
|
|
}
|
|
if ctx.Origin[0] != 0xAA || ctx.Origin[19] != 0xBB {
|
|
t.Errorf("Origin round-trip failed: got %x..%x", ctx.Origin[0], ctx.Origin[19])
|
|
}
|
|
if ctx.NumBlobHashes != 8 {
|
|
t.Errorf("NumBlobHashes round-trip failed: got %d", ctx.NumBlobHashes)
|
|
}
|
|
}
|