From eac1d8b517f6a6c22cf59ec2392c695c33197c64 Mon Sep 17 00:00:00 2001 From: Roy Crihfield Date: Sat, 6 Jul 2024 22:34:52 +0800 Subject: [PATCH 1/4] Fix tracker.Restore test --- tracker/tracker.go | 3 ++- tracker/tracker_test.go | 17 +++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/tracker/tracker.go b/tracker/tracker.go index 730eb58..87dd0e1 100644 --- a/tracker/tracker.go +++ b/tracker/tracker.go @@ -189,7 +189,7 @@ func (tr *TrackerImpl) Restore(makeIterator iter.IteratorConstructor) ( } } - // force the lower bound path to an even length (required by geth API/HexToKeyBytes) + // force the lower bound path to an even length (required by NodeIterator constructor) if len(recoveredPath)&1 == 1 { // to avoid skipped nodes, we must rewind by one index recoveredPath = rewindPath(recoveredPath) @@ -246,6 +246,7 @@ func (it *Iterator) Next(descend bool) bool { return ret } +// Bounds returns the bounds of the underlying PrefixBoundIterator, if any func (it *Iterator) Bounds() ([]byte, []byte) { if impl, ok := it.NodeIterator.(*iter.PrefixBoundIterator); ok { return impl.Bounds() diff --git a/tracker/tracker_test.go b/tracker/tracker_test.go index ae8f61d..bfcc9c5 100644 --- a/tracker/tracker_test.go +++ b/tracker/tracker_test.go @@ -25,7 +25,6 @@ func TestTracker(t *testing.T) { tr := tracker.New(recoveryFile, NumIters) defer tr.CloseAndSave() - var prevPath []byte count := 0 nodeit, err := tree.NodeIterator(nil) if err != nil { @@ -33,9 +32,9 @@ func TestTracker(t *testing.T) { } for it := tr.Tracked(nodeit); it.Next(true); { if count == interrupt { - return prevPath // tracker rewinds one node to prevent gaps + t.Logf("interrupting at: i=%d path=%v", count, it.Path()) + return it.Path() } - prevPath = it.Path() count++ } return nil @@ -58,8 +57,18 @@ func TestTracker(t *testing.T) { if uint(len(its)) != NumIters { t.Fatalf("expected to restore %d iterators, got %d", NumIters, len(its)) } + if !its[0].Next(true) { + t.Fatal("iterator ends prematurely after restore") + } if !bytes.Equal(failedAt, its[0].Path()) { - t.Fatalf("iterator restored to wrong position: expected %v, got %v", failedAt, its[0].Path()) + // Due to the constraint that NodeIterator can only be initialized with an even-length path, + // we sometimes rewind an extra node when restoring (e.g. [1 2 0] => [1 2]). + if !its[0].Next(true) { + t.Fatal("iterator ends prematurely after restore") + } + if !bytes.Equal(failedAt, its[0].Path()) { + t.Fatalf("iterator restored to wrong position: expected %v, got %v", failedAt, its[0].Path()) + } } if fileExists(recoveryFile) { -- 2.45.2 From 7aad19c85d64d72583b393e49043b37df6f8a90d Mon Sep 17 00:00:00 2001 From: Roy Crihfield Date: Fri, 5 Jul 2024 20:02:13 +0800 Subject: [PATCH 2/4] Don't modify arg in rewindPath --- tracker/tracker.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tracker/tracker.go b/tracker/tracker.go index 87dd0e1..48b8a3a 100644 --- a/tracker/tracker.go +++ b/tracker/tracker.go @@ -254,20 +254,21 @@ func (it *Iterator) Bounds() ([]byte, []byte) { return nil, nil } -// Rewinds to the path of the previous (pre-order) node: +// Returns the path, rewound to the previous (pre-order) node: +// If path is the root (empty) or a leaf path, it's returned. // If the last byte of the path is zero, pops it (e.g. [1 0] => [1]). // Otherwise, decrements it and pads with 0xF to 64 bytes (e.g. [1] => [0 f f f ...]). // The passed slice is not modified. func rewindPath(path []byte) []byte { - if len(path) == 0 { + if len(path) == 0 || path[len(path)-1] == 0x10 { return path } if path[len(path)-1] == 0 { return path[:len(path)-1] } - path[len(path)-1]-- padded := make([]byte, 64) i := copy(padded, path) + padded[len(path)-1]-- for ; i < len(padded); i++ { padded[i] = 0xf } -- 2.45.2 From 9fce1dc0b76b450f18a313f43be49d4555fc9853 Mon Sep 17 00:00:00 2001 From: Roy Crihfield Date: Fri, 5 Jul 2024 20:02:25 +0800 Subject: [PATCH 3/4] Upgrade go to 1.21 --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index f5127e9..263e145 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/cerc-io/eth-iterator-utils -go 1.19 +go 1.21 require ( github.com/cerc-io/eth-testing v0.4.0 -- 2.45.2 From ec6b6821b9ac32e99adbb046ec3b0ca2da65c81f Mon Sep 17 00:00:00 2001 From: Roy Crihfield Date: Thu, 4 Jul 2024 11:30:02 +0800 Subject: [PATCH 4/4] Add unit test workflow w/ extra runs for tracker test --- .github/workflows/test.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..7620cf2 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,23 @@ +name: Test + +on: + pull_request: + branches: '*' + push: + branches: + - main + +jobs: + test: + name: Run unit tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v3 + with: + go-version-file: go.mod + check-latest: true + - name: Run unit tests + run: | + go test -v -p 1 ./... + go test -v ./tracker -count 20 -- 2.45.2