Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BOLD: Avoid repeating the last hash in state hashes #2149

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bold
Submodule bold updated 61 files
+2 −0 api/backend/BUILD.bazel
+26 −2 api/backend/backend.go
+5 −5 api/db/db.go
+4 −4 api/db/db_test.go
+3 −3 api/server/methods.go
+23 −22 api/types.go
+4 −4 assertions/poster.go
+7 −14 chain-abstraction/interfaces.go
+0 −13 chain-abstraction/sol-implementation/assertion_chain.go
+2 −2 chain-abstraction/sol-implementation/assertion_chain_test.go
+91 −71 chain-abstraction/sol-implementation/edge_challenge_manager.go
+31 −14 chain-abstraction/sol-implementation/edge_challenge_manager_test.go
+6 −20 chain-abstraction/sol-implementation/transact.go
+1 −0 chain-abstraction/sol-implementation/types.go
+12 −0 challenge-manager/chain-watcher/BUILD.bazel
+337 −54 challenge-manager/chain-watcher/watcher.go
+236 −236 challenge-manager/chain-watcher/watcher_test.go
+2 −2 challenge-manager/challenge-tree/BUILD.bazel
+0 −176 challenge-manager/challenge-tree/compute_ancestors_test.go
+126 −7 challenge-manager/challenge-tree/generalized_path_timer.go
+684 −0 challenge-manager/challenge-tree/generalized_path_timer_test.go
+214 −214 challenge-manager/challenge-tree/local_timer_test.go
+15 −4 challenge-manager/challenge-tree/mock/edge.go
+0 −111 challenge-manager/challenge-tree/tree.go
+1 −120 challenge-manager/challenge-tree/tree_test.go
+0 −2 challenge-manager/challenges.go
+1 −0 challenge-manager/edge-tracker/BUILD.bazel
+162 −23 challenge-manager/edge-tracker/tracker.go
+90 −3 challenge-manager/manager_test.go
+20 −45 contracts/src/challengeV2/EdgeChallengeManager.sol
+2 −6 contracts/src/challengeV2/libraries/ChallengeEdgeLib.sol
+35 −40 contracts/src/challengeV2/libraries/EdgeChallengeManagerLib.sol
+72 −65 contracts/test/challengeV2/EdgeChallengeManager.t.sol
+2 −2 contracts/test/challengeV2/EdgeChallengeManagerLib.t.sol
+1 −0 layer2-state-provider/BUILD.bazel
+47 −49 layer2-state-provider/history_commitment_provider.go
+0 −2 layer2-state-provider/provider.go
+1 −1 runtime/retry.go
+2 −2 solgen/go/assertionStakingPoolgen/assertionStakingPoolgen.go
+1 −1 solgen/go/bridgegen/bridgegen.go
+64 −191 solgen/go/challengeV2gen/challengeV2gen.go
+2 −2 solgen/go/mocksgen/mocksgen.go
+10 −10 solgen/go/rollupgen/rollupgen.go
+2 −0 state-commitments/history/BUILD.bazel
+11 −9 state-commitments/history/commitments.go
+3 −1 state-commitments/history/commitments_test.go
+2 −0 state-commitments/inclusion-proofs/BUILD.bazel
+15 −12 state-commitments/inclusion-proofs/inclusion_proofs.go
+7 −5 state-commitments/inclusion-proofs/inclusion_proofs_test.go
+2 −0 state-commitments/prefix-proofs/BUILD.bazel
+8 −6 state-commitments/prefix-proofs/merkle_expansions.go
+7 −5 state-commitments/prefix-proofs/prefix_proofs.go
+4 −2 state-commitments/prefix-proofs/prefix_proofs_test.go
+9 −0 state-commitments/state-hashes/BUILD.bazel
+70 −0 state-commitments/state-hashes/state_hashes.go
+1 −1 testing/endtoend/e2e_test.go
+6 −19 testing/mocks/mocks.go
+1 −0 testing/mocks/state-provider/BUILD.bazel
+5 −3 testing/mocks/state-provider/history_provider.go
+4 −2 testing/mocks/state-provider/layer2_state_provider.go
+3 −3 util/safe.go
26 changes: 14 additions & 12 deletions staker/challenge-cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ import (
"path/filepath"
"strings"

state_hashes "github.com/OffchainLabs/bold/state-commitments/state-hashes"

protocol "github.com/OffchainLabs/bold/chain-abstraction"
l2stateprovider "github.com/OffchainLabs/bold/layer2-state-provider"
"github.com/ethereum/go-ethereum/common"
Expand All @@ -58,8 +60,8 @@ var (

// HistoryCommitmentCacher can retrieve history commitment state roots given lookup keys.
type HistoryCommitmentCacher interface {
Get(lookup *Key, numToRead uint64) ([]common.Hash, error)
Put(lookup *Key, stateRoots []common.Hash) error
Get(lookup *Key, numToRead uint64) (*state_hashes.StateHashes, error)
Put(lookup *Key, stateRoots *state_hashes.StateHashes) error
}

// Cache for history commitments on disk.
Expand Down Expand Up @@ -88,7 +90,7 @@ type Key struct {
func (c *Cache) Get(
lookup *Key,
numToRead uint64,
) ([]common.Hash, error) {
) (*state_hashes.StateHashes, error) {
fName, err := determineFilePath(c.baseDir, lookup)
if err != nil {
return nil, err
Expand All @@ -114,9 +116,9 @@ func (c *Cache) Get(
// State roots are saved as files in a directory hierarchy for the cache.
// This function first creates a temporary file, writes the state roots to it, and then renames the file
// to the final directory to ensure atomic writes.
func (c *Cache) Put(lookup *Key, stateRoots []common.Hash) error {
func (c *Cache) Put(lookup *Key, stateRoots *state_hashes.StateHashes) error {
// We should error if trying to put 0 state roots to disk.
if len(stateRoots) == 0 {
if stateRoots.Length() == 0 {
return ErrNoStateRoots
}
fName, err := determineFilePath(c.baseDir, lookup)
Expand Down Expand Up @@ -156,7 +158,7 @@ func (c *Cache) Put(lookup *Key, stateRoots []common.Hash) error {
}

// Reads 32 bytes at a time from a reader up to a specified height. If none, then read all.
func readStateRoots(r io.Reader, numToRead uint64) ([]common.Hash, error) {
func readStateRoots(r io.Reader, numToRead uint64) (*state_hashes.StateHashes, error) {
br := bufio.NewReader(r)
stateRoots := make([]common.Hash, 0)
buf := make([]byte, 0, 32)
Expand All @@ -182,21 +184,21 @@ func readStateRoots(r io.Reader, numToRead uint64) ([]common.Hash, error) {
len(stateRoots),
)
}
return stateRoots, nil
return state_hashes.NewStateHashes(stateRoots, uint64(len(stateRoots))), nil
}

func writeStateRoots(w io.Writer, stateRoots []common.Hash) error {
for i, rt := range stateRoots {
n, err := w.Write(rt[:])
func writeStateRoots(w io.Writer, stateRoots *state_hashes.StateHashes) error {
for i := uint64(0); i < stateRoots.Length(); i++ {
n, err := w.Write(stateRoots.At(i).Bytes())
if err != nil {
return err
}
if n != len(rt) {
if n != len(stateRoots.At(i)) {
return fmt.Errorf(
"for state root %d, wrote %d bytes, expected to write %d bytes",
i,
n,
len(rt),
len(stateRoots.At(i)),
)
}
}
Expand Down
55 changes: 29 additions & 26 deletions staker/challenge-cache/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"testing"

l2stateprovider "github.com/OffchainLabs/bold/layer2-state-provider"
state_hashes "github.com/OffchainLabs/bold/state-commitments/state-hashes"
"github.com/ethereum/go-ethereum/common"
)

Expand Down Expand Up @@ -40,15 +41,16 @@ func TestCache(t *testing.T) {
}
})
t.Run("Putting empty root fails", func(t *testing.T) {
if err := cache.Put(key, []common.Hash{}); !errors.Is(err, ErrNoStateRoots) {
if err := cache.Put(key, state_hashes.NewStateHashes([]common.Hash{}, 0)); !errors.Is(err, ErrNoStateRoots) {
t.Fatalf("Unexpected error: %v", err)
}
})
want := []common.Hash{
wantHashes := []common.Hash{
common.BytesToHash([]byte("foo")),
common.BytesToHash([]byte("bar")),
common.BytesToHash([]byte("baz")),
}
want := state_hashes.NewStateHashes(wantHashes, uint64(len(wantHashes)))
err := cache.Put(key, want)
if err != nil {
t.Fatal(err)
Expand All @@ -57,12 +59,12 @@ func TestCache(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if len(got) != len(want) {
t.Fatalf("Wrong number of roots. Expected %d, got %d", len(want), len(got))
if got.Length() != want.Length() {
t.Fatalf("Wrong number of roots. Expected %d, got %d", want.Length(), got.Length())
}
for i, rt := range got {
if rt != want[i] {
t.Fatalf("Wrong root. Expected %#x, got %#x", want[i], rt)
for i := uint64(0); i < got.Length(); i++ {
if got.At(i) != want.At(i) {
t.Fatalf("Wrong root. Expected %#x, got %#x", want.At(i), got.At(i))
}
}
}
Expand All @@ -86,11 +88,11 @@ func TestReadWriteStateRoots(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if len(roots) == 0 {
if roots.Length() == 0 {
t.Fatal("Got no roots")
}
if roots[0] != want {
t.Fatalf("Wrong root. Expected %#x, got %#x", want, roots[0])
if roots.At(0) != want {
t.Fatalf("Wrong root. Expected %#x, got %#x", want, roots.At(0))
}
})
t.Run("Three roots exist, want to read only two", func(t *testing.T) {
Expand All @@ -105,24 +107,24 @@ func TestReadWriteStateRoots(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if len(roots) != 2 {
t.Fatalf("Expected two roots, got %d", len(roots))
if roots.Length() != 2 {
t.Fatalf("Expected two roots, got %d", roots.Length())
}
if roots[0] != foo {
t.Fatalf("Wrong root. Expected %#x, got %#x", foo, roots[0])
if roots.At(0) != foo {
t.Fatalf("Wrong root. Expected %#x, got %#x", foo, roots.At(0))
}
if roots[1] != bar {
t.Fatalf("Wrong root. Expected %#x, got %#x", bar, roots[1])
if roots.At(1) != bar {
t.Fatalf("Wrong root. Expected %#x, got %#x", bar, roots.At(1))
}
})
t.Run("Fails to write enough data to writer", func(t *testing.T) {
m := &mockWriter{wantErr: true}
err := writeStateRoots(m, []common.Hash{common.BytesToHash([]byte("foo"))})
err := writeStateRoots(m, state_hashes.NewStateHashes([]common.Hash{common.BytesToHash([]byte("foo"))}, 1))
if err == nil {
t.Fatal("Wanted error")
}
m = &mockWriter{wantErr: false, numWritten: 16}
err = writeStateRoots(m, []common.Hash{common.BytesToHash([]byte("foo"))})
err = writeStateRoots(m, state_hashes.NewStateHashes([]common.Hash{common.BytesToHash([]byte("foo"))}, 1))
if err == nil {
t.Fatal("Wanted error")
}
Expand Down Expand Up @@ -221,11 +223,11 @@ func Test_readStateRoots(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if len(want) != len(got) {
if uint64(len(want)) != got.Length() {
t.Fatal("Wrong number of roots")
}
for i, rt := range got {
if rt != want[i] {
for i := uint64(0); i < got.Length(); i++ {
if got.At(i) != want[i] {
t.Fatal("Wrong root")
}
}
Expand Down Expand Up @@ -297,10 +299,11 @@ func BenchmarkCache_Read_32Mb(b *testing.B) {
StepHeights: []l2stateprovider.Height{l2stateprovider.Height(0)},
}
numRoots := 1 << 20
roots := make([]common.Hash, numRoots)
for i := range roots {
roots[i] = common.BytesToHash([]byte(fmt.Sprintf("%d", i)))
rootsHashes := make([]common.Hash, numRoots)
for i := range rootsHashes {
rootsHashes[i] = common.BytesToHash([]byte(fmt.Sprintf("%d", i)))
}
roots := state_hashes.NewStateHashes(rootsHashes, uint64(len(rootsHashes)))
if err := cache.Put(key, roots); err != nil {
b.Fatal(err)
}
Expand All @@ -311,8 +314,8 @@ func BenchmarkCache_Read_32Mb(b *testing.B) {
if err != nil {
b.Fatal(err)
}
if len(roots) != numRoots {
b.Fatalf("Wrong number of roots. Expected %d, got %d", numRoots, len(roots))
if roots.Length() != uint64(numRoots) {
b.Fatalf("Wrong number of roots. Expected %d, got %d", numRoots, roots.Length())
}
}
}
16 changes: 8 additions & 8 deletions staker/state_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
protocol "github.com/OffchainLabs/bold/chain-abstraction"
"github.com/OffchainLabs/bold/containers/option"
l2stateprovider "github.com/OffchainLabs/bold/layer2-state-provider"
state_hashes "github.com/OffchainLabs/bold/state-commitments/state-hashes"

"github.com/offchainlabs/nitro/arbutil"
challengecache "github.com/offchainlabs/nitro/staker/challenge-cache"
Expand Down Expand Up @@ -181,7 +182,7 @@ func (s *StateManager) StatesInBatchRange(
toHeight l2stateprovider.Height,
fromBatch,
toBatch l2stateprovider.Batch,
) ([]common.Hash, error) {
) (*state_hashes.StateHashes, error) {
// Check the integrity of the arguments.
if fromBatch >= toBatch {
return nil, fmt.Errorf("from batch %v cannot be greater than or equal to batch %v", fromBatch, toBatch)
Expand Down Expand Up @@ -256,10 +257,9 @@ func (s *StateManager) StatesInBatchRange(
machineHashes = append(machineHashes, machineHash(state))
prevBatchMsgCount = batchMessageCount
}
for uint64(len(machineHashes)) < uint64(totalDesiredHashes) {
machineHashes = append(machineHashes, machineHashes[len(machineHashes)-1])
}
return machineHashes[fromHeight : toHeight+1], nil
return state_hashes.NewStateHashes(
machineHashes, uint64(totalDesiredHashes),
).SubSlice(uint64(fromHeight), uint64(toHeight+1)), nil
}

func machineHash(gs validator.GoGlobalState) common.Hash {
Expand Down Expand Up @@ -299,7 +299,7 @@ func (s *StateManager) L2MessageStatesUpTo(
toHeight option.Option[l2stateprovider.Height],
fromBatch,
toBatch l2stateprovider.Batch,
) ([]common.Hash, error) {
) (*state_hashes.StateHashes, error) {
var to l2stateprovider.Height
if !toHeight.IsNone() {
to = toHeight.Unwrap()
Expand All @@ -317,7 +317,7 @@ func (s *StateManager) L2MessageStatesUpTo(
// CollectMachineHashes Collects a list of machine hashes at a message number based on some configuration parameters.
func (s *StateManager) CollectMachineHashes(
ctx context.Context, cfg *l2stateprovider.HashCollectorConfig,
) ([]common.Hash, error) {
) (*state_hashes.StateHashes, error) {
s.Lock()
defer s.Unlock()
prevBatchMsgCount, err := s.validator.inboxTracker.GetBatchMessageCount(uint64(cfg.FromBatch - 1))
Expand Down Expand Up @@ -360,7 +360,7 @@ func (s *StateManager) CollectMachineHashes(
}
log.Info(fmt.Sprintf("Finished gathering machine hashes for request %+v", cfg))
// Do not save a history commitment of length 1 to the cache.
if len(result) > 1 && s.historyCache != nil {
if result.Length() > 1 && s.historyCache != nil {
if err := s.historyCache.Put(cacheKey, result); err != nil {
if !errors.Is(err, challengecache.ErrFileAlreadyExists) {
return nil, err
Expand Down
6 changes: 4 additions & 2 deletions system_tests/validation_mock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
"testing"
"time"

state_hashes "github.com/OffchainLabs/bold/state-commitments/state-hashes"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/node"
Expand Down Expand Up @@ -72,7 +74,7 @@

func (s *mockSpawner) CreateExecutionRun(wasmModuleRoot common.Hash, input *validator.ValidationInput) containers.PromiseInterface[validator.ExecutionRun] {
s.ExecSpawned = append(s.ExecSpawned, input.Id)
return containers.NewReadyPromise[validator.ExecutionRun](&mockExecRun{

Check failure on line 77 in system_tests/validation_mock_test.go

View workflow job for this annotation

GitHub Actions / Go Tests (defaults)

cannot use &mockExecRun{…} (value of type *mockExecRun) as validator.ExecutionRun value in argument to containers.NewReadyPromise[validator.ExecutionRun]: *mockExecRun does not implement validator.ExecutionRun (wrong type for method GetLeavesWithStepSize)

Check failure on line 77 in system_tests/validation_mock_test.go

View workflow job for this annotation

GitHub Actions / Go Tests (race)

cannot use &mockExecRun{…} (value of type *mockExecRun) as validator.ExecutionRun value in argument to containers.NewReadyPromise[validator.ExecutionRun]: *mockExecRun does not implement validator.ExecutionRun (wrong type for method GetLeavesWithStepSize)

Check failure on line 77 in system_tests/validation_mock_test.go

View workflow job for this annotation

GitHub Actions / Go Tests (challenge)

cannot use &mockExecRun{…} (value of type *mockExecRun) as validator.ExecutionRun value in argument to containers.NewReadyPromise[validator.ExecutionRun]: *mockExecRun does not implement validator.ExecutionRun (wrong type for method GetLeavesWithStepSize)
startState: input.StartState,
endState: globalstateFromTestPreimages(input.Preimages),
}, nil)
Expand Down Expand Up @@ -121,9 +123,9 @@
}, nil)
}

func (r *mockExecRun) GetLeavesWithStepSize(machineStartIndex, stepSize, numDesiredLeaves uint64, claimId common.Hash) containers.PromiseInterface[[]common.Hash] {
func (r *mockExecRun) GetLeavesWithStepSize(machineStartIndex, stepSize, numDesiredLeaves uint64, claimId common.Hash) containers.PromiseInterface[*state_hashes.StateHashes] {
// TODO: Add mock implementation for GetLeavesWithStepSize
return containers.NewReadyPromise[[]common.Hash](nil, nil)
return containers.NewReadyPromise[*state_hashes.StateHashes](nil, nil)
}

func (r *mockExecRun) GetLastStep() containers.PromiseInterface[*validator.MachineStepResult] {
Expand Down
4 changes: 3 additions & 1 deletion validator/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (

"github.com/ethereum/go-ethereum/common"

state_hashes "github.com/OffchainLabs/bold/state-commitments/state-hashes"

"github.com/offchainlabs/nitro/util/containers"
)

Expand All @@ -31,7 +33,7 @@ type ExecutionSpawner interface {

type ExecutionRun interface {
GetStepAt(uint64) containers.PromiseInterface[*MachineStepResult]
GetLeavesWithStepSize(fromBatch, machineStartIndex, stepSize, numDesiredLeaves uint64) containers.PromiseInterface[[]common.Hash]
GetLeavesWithStepSize(fromBatch, machineStartIndex, stepSize, numDesiredLeaves uint64) containers.PromiseInterface[*state_hashes.StateHashes]
GetLastStep() containers.PromiseInterface[*MachineStepResult]
GetProofAt(uint64) containers.PromiseInterface[[]byte]
PrepareRange(uint64, uint64) containers.PromiseInterface[struct{}]
Expand Down
4 changes: 3 additions & 1 deletion validator/server_api/validation_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"sync"
"time"

state_hashes "github.com/OffchainLabs/bold/state-commitments/state-hashes"

"github.com/ethereum/go-ethereum/common"

"github.com/offchainlabs/nitro/util/stopwaiter"
Expand Down Expand Up @@ -159,7 +161,7 @@ func (a *ExecServerAPI) GetStepAt(ctx context.Context, execid uint64, position u
return MachineStepResultToJson(res), nil
}

func (a *ExecServerAPI) GetLeavesWithStepSize(ctx context.Context, execid, fromBatch, fromStep, stepSize, numDesiredLeaves uint64) ([]common.Hash, error) {
func (a *ExecServerAPI) GetLeavesWithStepSize(ctx context.Context, execid, fromBatch, fromStep, stepSize, numDesiredLeaves uint64) (*state_hashes.StateHashes, error) {
run, err := a.getRun(execid)
if err != nil {
return nil, err
Expand Down
8 changes: 5 additions & 3 deletions validator/server_api/validation_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/node"

state_hashes "github.com/OffchainLabs/bold/state-commitments/state-hashes"
)

type ValidationClient struct {
Expand Down Expand Up @@ -195,9 +197,9 @@ func (r *ExecutionClientRun) GetStepAt(pos uint64) containers.PromiseInterface[*
})
}

func (r *ExecutionClientRun) GetLeavesWithStepSize(fromBatch, machineStartIndex, stepSize, numDesiredLeaves uint64) containers.PromiseInterface[[]common.Hash] {
return stopwaiter.LaunchPromiseThread[[]common.Hash](r, func(ctx context.Context) ([]common.Hash, error) {
var resJson []common.Hash
func (r *ExecutionClientRun) GetLeavesWithStepSize(fromBatch, machineStartIndex, stepSize, numDesiredLeaves uint64) containers.PromiseInterface[*state_hashes.StateHashes] {
return stopwaiter.LaunchPromiseThread[*state_hashes.StateHashes](r, func(ctx context.Context) (*state_hashes.StateHashes, error) {
var resJson *state_hashes.StateHashes
err := r.client.client.CallContext(ctx, &resJson, Namespace+"_getLeavesWithStepSize", r.id, fromBatch, machineStartIndex, stepSize, numDesiredLeaves)
if err != nil {
return nil, err
Expand Down
16 changes: 7 additions & 9 deletions validator/server_arb/execution_run.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import (

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"

"github.com/ethereum/go-ethereum/log"

state_hashes "github.com/OffchainLabs/bold/state-commitments/state-hashes"

"github.com/offchainlabs/nitro/util/containers"
"github.com/offchainlabs/nitro/util/stopwaiter"
"github.com/offchainlabs/nitro/validator"
Expand Down Expand Up @@ -64,8 +66,8 @@ func (e *executionRun) GetStepAt(position uint64) containers.PromiseInterface[*v
})
}

func (e *executionRun) GetLeavesWithStepSize(fromBatch, machineStartIndex, stepSize, numDesiredLeaves uint64) containers.PromiseInterface[[]common.Hash] {
return stopwaiter.LaunchPromiseThread[[]common.Hash](e, func(ctx context.Context) ([]common.Hash, error) {
func (e *executionRun) GetLeavesWithStepSize(fromBatch, machineStartIndex, stepSize, numDesiredLeaves uint64) containers.PromiseInterface[*state_hashes.StateHashes] {
return stopwaiter.LaunchPromiseThread[*state_hashes.StateHashes](e, func(ctx context.Context) (*state_hashes.StateHashes, error) {
if stepSize == 1 {
e.cache = NewMachineCache(e.GetContext(), e.initialMachineGetter, e.config, server_common.WithAlwaysMerkleize())
log.Info("Enabling Merkleization of machines for faster hashing. However, advancing to start index might take a while...")
Expand Down Expand Up @@ -95,7 +97,7 @@ func (e *executionRun) GetLeavesWithStepSize(fromBatch, machineStartIndex, stepS

// If we only want 1 state root, we can return early.
if numDesiredLeaves == 1 {
return stateRoots, nil
return state_hashes.NewStateHashes(stateRoots, uint64(len(stateRoots))), nil
}

logInterval := numDesiredLeaves / 20 // Log every 5% progress
Expand Down Expand Up @@ -168,11 +170,7 @@ func (e *executionRun) GetLeavesWithStepSize(fromBatch, machineStartIndex, stepS
// If the machine finished in less than the number of hashes we anticipate, we pad
// to the expected value by repeating the last machine hash until the state roots are the correct
// length.
lastStateRoot := stateRoots[len(stateRoots)-1]
for len(stateRoots) < int(numDesiredLeaves) {
stateRoots = append(stateRoots, lastStateRoot)
}
return stateRoots[:numDesiredLeaves], nil
return state_hashes.NewStateHashes(stateRoots, numDesiredLeaves), nil
})
}

Expand Down
Loading