Skip to content

Commit

Permalink
Finish wiring the json file writing everywhere.
Browse files Browse the repository at this point in the history
At this point the location of the output file is hardcoded to be in
the `$HOME/.arbitrum` directory. Hopefully, this will be okay.
  • Loading branch information
eljobe committed Aug 22, 2024
1 parent e547683 commit 39cd0a7
Show file tree
Hide file tree
Showing 11 changed files with 69 additions and 81 deletions.
16 changes: 16 additions & 0 deletions arbnode/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/offchainlabs/nitro/arbutil"
"github.com/offchainlabs/nitro/staker"
"github.com/offchainlabs/nitro/validator"
"github.com/offchainlabs/nitro/validator/server_api"
)

type BlockValidatorAPI struct {
Expand Down Expand Up @@ -54,3 +55,18 @@ func (a *BlockValidatorDebugAPI) ValidateMessageNumber(
result.Valid = valid
return result, err
}

func (a *BlockValidatorDebugAPI) ValidationInputsAt(ctx context.Context, msgNum hexutil.Uint64, moduleRootOptional *common.Hash,
) (server_api.InputJSON, error) {
var moduleRoot common.Hash
if moduleRootOptional != nil {
moduleRoot = *moduleRootOptional
} else {
var err error
moduleRoot, err = a.val.GetLatestWasmModuleRoot(ctx)
if err != nil {
return server_api.InputJSON{}, fmt.Errorf("no latest WasmModuleRoot configured, must provide parameter: %w", err)
}
}
return a.val.ValidationInputsAt(ctx, arbutil.MessageIndex(msgNum), moduleRoot)
}
15 changes: 7 additions & 8 deletions staker/block_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/offchainlabs/nitro/util/stopwaiter"
"github.com/offchainlabs/nitro/validator"
"github.com/offchainlabs/nitro/validator/client/redis"
"github.com/offchainlabs/nitro/validator/server_api"
"github.com/spf13/pflag"
)

Expand Down Expand Up @@ -504,18 +505,16 @@ func (v *BlockValidator) sendRecord(s *validationStatus) error {
}

//nolint:gosec
func (v *BlockValidator) writeToFile(validationEntry *validationEntry, moduleRoot common.Hash) error {
func (v *BlockValidator) writeToFile(validationEntry *validationEntry) error {
input, err := validationEntry.ToInput([]rawdb.Target{rawdb.TargetWavm})
if err != nil {
return err
}
for _, spawner := range v.execSpawners {
if validator.SpawnerSupportsModule(spawner, moduleRoot) {
_, err = spawner.WriteToFile(input, moduleRoot).Await(v.GetContext())
return err
}
inputJson := server_api.ValidationInputToJson(input)
if err := inputJson.WriteToFile("BlockValidator"); err != nil {
return err
}
return errors.New("did not find exec spawner for wasmModuleRoot")
return nil
}

func (v *BlockValidator) SetCurrentWasmModuleRoot(hash common.Hash) error {
Expand Down Expand Up @@ -783,7 +782,7 @@ validationsLoop:
runEnd, err := run.Current()
if err == nil && runEnd != validationStatus.Entry.End {
err = fmt.Errorf("validation failed: expected %v got %v", validationStatus.Entry.End, runEnd)
writeErr := v.writeToFile(validationStatus.Entry, run.WasmModuleRoot())
writeErr := v.writeToFile(validationStatus.Entry)
if writeErr != nil {
log.Warn("failed to write debug results file", "err", writeErr)
}
Expand Down
27 changes: 7 additions & 20 deletions staker/stateless_block_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/offchainlabs/nitro/util/rpcclient"
"github.com/offchainlabs/nitro/validator"
"github.com/offchainlabs/nitro/validator/client/redis"
"github.com/offchainlabs/nitro/validator/server_api"

validatorclient "github.com/offchainlabs/nitro/validator/client"
)
Expand Down Expand Up @@ -463,30 +464,16 @@ func (v *StatelessBlockValidator) ValidateResult(
return true, &entry.End, nil
}

func (v *StatelessBlockValidator) RecordValidationInput(ctx context.Context, pos arbutil.MessageIndex, moduleRoot common.Hash) error {
func (v *StatelessBlockValidator) ValidationInputsAt(ctx context.Context, pos arbutil.MessageIndex, moduleRoot common.Hash) (server_api.InputJSON, error) {
entry, err := v.CreateReadyValidationEntry(ctx, pos)
if err != nil {
return err
return server_api.InputJSON{}, err
}
found := false
for _, spawner := range v.execSpawners {
if validator.SpawnerSupportsModule(spawner, moduleRoot) {
found = true
// Hardcoded to use wavm so that it can be read by the prover.
input, err := entry.ToInput([]rawdb.Target{rawdb.TargetWavm})
if err != nil {
return err
}
_, err = spawner.WriteToFile(input, moduleRoot).Await(ctx)
if err != nil {
return err
}
}
}
if !found {
return fmt.Errorf("validation with WasmModuleRoot %v not supported by node", moduleRoot)
input, err := entry.ToInput([]rawdb.Target{rawdb.TargetWavm})
if err != nil {
return server_api.InputJSON{}, err
}
return nil
return *server_api.ValidationInputToJson(input), nil
}

func (v *StatelessBlockValidator) OverrideRecorder(t *testing.T, recorder execution.ExecutionRecorder) {
Expand Down
17 changes: 17 additions & 0 deletions system_tests/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1459,6 +1459,23 @@ func logParser[T any](t *testing.T, source string, name string) func(*types.Log)
}
}

// recordBlock writes a json file with all of the data needed to validate a block.
//
// This can be used as an input to the arbitrator prover to validate a block.
func recordBlock(t *testing.T, block uint64, builder *NodeBuilder) {
t.Helper()
ctx := builder.ctx
wasmModuleRoot := currentRootModule(t)
inboxPos := arbutil.MessageIndex(block)
inputJson, err := builder.L2.ConsensusNode.StatelessBlockValidator.ValidationInputsAt(ctx, inboxPos, wasmModuleRoot)
if err != nil {
Fatal(t, "failed to get validation inputs", block, err)
}
if err := inputJson.WriteToFile(t.Name()); err != nil {
Fatal(t, "failed to write validation inputs", block, err)
}
}

func populateMachineDir(t *testing.T, cr *github.ConsensusRelease) string {
baseDir := t.TempDir()
machineDir := baseDir + "/machines"
Expand Down
13 changes: 0 additions & 13 deletions system_tests/program_norace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,19 +104,6 @@ func validateBlockRange(
}
}

// recordBlock writes a json file with all of the data needed to validate a block.
//
// This can be used as an input to the arbitrator prover to validate a block.
func recordBlock(t *testing.T, block uint64, builder *NodeBuilder) {
t.Helper()
ctx := builder.ctx
wasmModuleRoot := currentRootModule(t)
inboxPos := arbutil.MessageIndex(block)
if err := builder.L2.ConsensusNode.StatelessBlockValidator.RecordValidationInput(ctx, inboxPos, wasmModuleRoot); err != nil {
Fatal(t, "failed to record block", block, err)
}
}

func TestProgramEvmData(t *testing.T) {
t.Parallel()
testEvmData(t, true)
Expand Down
4 changes: 0 additions & 4 deletions system_tests/validation_mock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,6 @@ func (s *mockSpawner) LatestWasmModuleRoot() containers.PromiseInterface[common.
return containers.NewReadyPromise[common.Hash](mockWasmModuleRoots[0], nil)
}

func (s *mockSpawner) WriteToFile(input *validator.ValidationInput, moduleRoot common.Hash) containers.PromiseInterface[struct{}] {
return containers.NewReadyPromise[struct{}](struct{}{}, nil)
}

type mockValRun struct {
containers.Promise[validator.GoGlobalState]
root common.Hash
Expand Down
8 changes: 0 additions & 8 deletions validator/client/validation_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,14 +186,6 @@ func (c *ExecutionClient) LatestWasmModuleRoot() containers.PromiseInterface[com
})
}

func (c *ExecutionClient) WriteToFile(input *validator.ValidationInput, moduleRoot common.Hash) containers.PromiseInterface[struct{}] {
jsonInput := server_api.ValidationInputToJson(input)
return stopwaiter.LaunchPromiseThread[struct{}](c, func(ctx context.Context) (struct{}, error) {
err := c.client.CallContext(ctx, nil, server_api.Namespace+"_writeToFile", jsonInput, moduleRoot)
return struct{}{}, err
})
}

func (r *ExecutionClientRun) SendKeepAlive(ctx context.Context) time.Duration {
err := r.client.client.CallContext(ctx, nil, server_api.Namespace+"_execKeepAlive", r.id)
if err != nil {
Expand Down
1 change: 0 additions & 1 deletion validator/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ type ExecutionSpawner interface {
ValidationSpawner
CreateExecutionRun(wasmModuleRoot common.Hash, input *ValidationInput) containers.PromiseInterface[ExecutionRun]
LatestWasmModuleRoot() containers.PromiseInterface[common.Hash]
WriteToFile(input *ValidationInput, moduleRoot common.Hash) containers.PromiseInterface[struct{}]
}

type ExecutionRun interface {
Expand Down
24 changes: 22 additions & 2 deletions validator/server_api/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"errors"
"fmt"
"os"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
Expand Down Expand Up @@ -68,12 +69,31 @@ type InputJSON struct {
DebugChain bool
}

func (i *InputJSON) WriteToFile() error {
// WriteToFile writes the InputJSON to a file in JSON format.
//
// The path to the file is determined in part by the slug parameter so
// callers can provide a recognizable name to differentiate various
// contexts in which the InputJSON is being written.
//
// The file is created at a path
//
// $HOME/.arbuitrum/validation-inputs/<slug>/<YYYMMDD_HHMMSS>/block_inputs_<id>.json
func (i *InputJSON) WriteToFile(slug string) error {
homeDir, err := os.UserHomeDir()
if err != nil {
return err
}
t := time.Now()
tStr := t.Format("20060102_150405")
dir := fmt.Sprintf("%s/.arbitrum/validation-inputs/%s/%s", homeDir, slug, tStr)
if err = os.MkdirAll(dir, 0700); err != nil {
return err
}
contents, err := json.MarshalIndent(i, "", " ")
if err != nil {
return err
}
if err = os.WriteFile(fmt.Sprintf("block_inputs_%d.json", i.Id), contents, 0600); err != nil {
if err = os.WriteFile(fmt.Sprintf("%s/block_inputs_%d.json", dir, i.Id), contents, 0600); err != nil {
return err
}
return nil
Expand Down
16 changes: 0 additions & 16 deletions validator/server_arb/validator_spawner.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"github.com/offchainlabs/nitro/util/containers"
"github.com/offchainlabs/nitro/util/stopwaiter"
"github.com/offchainlabs/nitro/validator"
"github.com/offchainlabs/nitro/validator/server_api"
"github.com/offchainlabs/nitro/validator/server_common"
"github.com/offchainlabs/nitro/validator/valnode/redis"

Expand Down Expand Up @@ -203,21 +202,6 @@ func (v *ArbitratorSpawner) Room() int {
return avail
}

func (v *ArbitratorSpawner) writeToFile(_ context.Context, input *validator.ValidationInput, _ common.Hash) error {
jsonInput := server_api.ValidationInputToJson(input)
if err := jsonInput.WriteToFile(); err != nil {
return err
}
return nil
}

func (v *ArbitratorSpawner) WriteToFile(input *validator.ValidationInput, moduleRoot common.Hash) containers.PromiseInterface[struct{}] {
return stopwaiter.LaunchPromiseThread[struct{}](v, func(ctx context.Context) (struct{}, error) {
err := v.writeToFile(ctx, input, moduleRoot)
return struct{}{}, err
})
}

func (v *ArbitratorSpawner) CreateExecutionRun(wasmModuleRoot common.Hash, input *validator.ValidationInput) containers.PromiseInterface[validator.ExecutionRun] {
getMachine := func(ctx context.Context) (MachineInterface, error) {
initialFrozenMachine, err := v.machineLoader.GetZeroStepMachine(ctx, wasmModuleRoot)
Expand Down
9 changes: 0 additions & 9 deletions validator/valnode/validation_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,15 +118,6 @@ func (a *ExecServerAPI) Start(ctx_in context.Context) {
a.CallIteratively(a.removeOldRuns)
}

func (a *ExecServerAPI) WriteToFile(ctx context.Context, jsonInput *server_api.InputJSON, moduleRoot common.Hash) error {
input, err := server_api.ValidationInputFromJson(jsonInput)
if err != nil {
return err
}
_, err = a.execSpawner.WriteToFile(input, moduleRoot).Await(ctx)
return err
}

var errRunNotFound error = errors.New("run not found")

func (a *ExecServerAPI) getRun(id uint64) (validator.ExecutionRun, error) {
Expand Down

0 comments on commit 39cd0a7

Please sign in to comment.