-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
072255c
commit b3b8f83
Showing
4 changed files
with
277 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// Copyright 2023 The Accumulate Authors | ||
// | ||
// Use of this source code is governed by an MIT-style | ||
// license that can be found in the LICENSE file or at | ||
// https://opensource.org/licenses/MIT. | ||
|
||
package bpt | ||
|
||
import ( | ||
"bytes" | ||
"sort" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
"gitlab.com/accumulatenetwork/accumulate/internal/database/smt/common" | ||
"gitlab.com/accumulatenetwork/accumulate/pkg/database/keyvalue" | ||
"gitlab.com/accumulatenetwork/accumulate/pkg/database/keyvalue/memory" | ||
"gitlab.com/accumulatenetwork/accumulate/pkg/types/record" | ||
) | ||
|
||
// TestBPT_receipt | ||
// Build a reasonable size BPT, then prove we can create a receipt for every | ||
// element in said BPT. | ||
func TestBPT_receipt(t *testing.T) { | ||
kvs := memory.New(nil).Begin(nil, true) | ||
store := keyvalue.RecordStore{Store: kvs} | ||
bpt := newBPT(nil, nil, store, nil, "BPT") | ||
|
||
numberEntries := 50000 // A pretty reasonable sized BPT | ||
|
||
var keys, values common.RandHash // use the default sequence for keys | ||
values.SetSeed([]byte{1, 2, 3}) // use a different sequence for values | ||
for i := 0; i < numberEntries; i++ { // For the number of Entries specified for the BPT | ||
chainID := keys.NextAList() // Get a key, keep a list | ||
value := values.NextA() // Get some value (don't really care what it is) | ||
err := bpt.Insert(record.KeyFromHash(chainID), value) // Insert the Key with the value into the BPT | ||
require.NoError(t, err) | ||
} | ||
require.NoError(t, bpt.Commit()) | ||
|
||
keyList := append([][]byte{}, keys.List...) // Get all the keys | ||
sort.Slice(keyList, func(i, j int) bool { return bytes.Compare(keyList[i], keyList[j]) < 0 }) // | ||
|
||
// Recreate the BPT to throw away the pending list, otherwise GetReceipt | ||
// spends a lot of time iterating over it and doing nothing | ||
bpt = newBPT(nil, nil, store, nil, "BPT") | ||
|
||
// Make sure every key we added to the BPT has a valid receipt | ||
for i := range keys.List { // go through the list of keys | ||
r, err := bpt.GetReceipt(keys.GetAElement(i)) | ||
require.NoError(t, err) | ||
v := r.Validate(nil) | ||
require.Truef(t, v, "should validate BPT element %d", i+1) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// Copyright 2023 The Accumulate Authors | ||
// | ||
// Use of this source code is governed by an MIT-style | ||
// license that can be found in the LICENSE file or at | ||
// https://opensource.org/licenses/MIT. | ||
|
||
package bpt | ||
|
||
import ( | ||
"crypto/sha256" | ||
"fmt" | ||
"io" | ||
"os" | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
"gitlab.com/accumulatenetwork/accumulate/internal/database/smt/common" | ||
"gitlab.com/accumulatenetwork/accumulate/internal/database/smt/storage" | ||
ioutil2 "gitlab.com/accumulatenetwork/accumulate/internal/util/io" | ||
"gitlab.com/accumulatenetwork/accumulate/pkg/database/keyvalue" | ||
"gitlab.com/accumulatenetwork/accumulate/pkg/database/keyvalue/badger" | ||
"gitlab.com/accumulatenetwork/accumulate/pkg/database/keyvalue/memory" | ||
"gitlab.com/accumulatenetwork/accumulate/pkg/types/record" | ||
) | ||
|
||
func TestSaveState(t *testing.T) { | ||
|
||
numberEntries := 5001 // A pretty reasonable sized BPT | ||
|
||
DirName, err := os.MkdirTemp("", "AccDB") | ||
require.Nil(t, err, "failed to create directory") | ||
defer os.RemoveAll(DirName) | ||
|
||
BDB, err := badger.New(DirName + "/add") | ||
require.Nil(t, err, "failed to create db") | ||
defer BDB.Close() | ||
|
||
storeTx := BDB.Begin(nil, true) // and begin its use. | ||
store := keyvalue.RecordStore{Store: storeTx} // | ||
bpt := newBPT(nil, nil, store, nil, "BPT") // Create a BptManager. We will create a new one each cycle. | ||
var keys, values common.RandHash // use the default sequence for keys | ||
values.SetSeed([]byte{1, 2, 3}) // use a different sequence for values | ||
for i := 0; i < numberEntries; i++ { // For the number of Entries specified for the BPT | ||
chainID := keys.NextAList() // Get a key, keep a list | ||
value := values.GetRandBuff(int(values.GetRandInt64() % 100)) | ||
hash := sha256.Sum256(value) | ||
err := storeTx.Put(record.KeyFromHash(hash), value) | ||
require.NoError(t, err) | ||
err = bpt.Insert(record.KeyFromHash(chainID), hash) // Insert the Key with the value into the BPT | ||
require.NoError(t, err) | ||
} | ||
require.NoError(t, bpt.Commit()) | ||
storeTx = BDB.Begin(nil, true) | ||
store = keyvalue.RecordStore{Store: storeTx} | ||
bpt = newBPT(nil, nil, store, nil, "BPT") | ||
|
||
f, err := os.Create(filepath.Join(DirName, "SnapShot")) | ||
require.NoError(t, err) | ||
defer f.Close() | ||
|
||
err = SaveSnapshotV1(bpt, f, func(key storage.Key, hash [32]byte) ([]byte, error) { | ||
return storeTx.Get(record.KeyFromHash(hash)) | ||
}) | ||
require.NoError(t, err) | ||
|
||
_, err = f.Seek(0, io.SeekStart) | ||
require.NoError(t, err) | ||
|
||
kvs2 := memory.New(nil).Begin(nil, true) | ||
store2 := keyvalue.RecordStore{Store: kvs2} | ||
bpt2 := newBPT(nil, nil, store2, nil, "BPT") | ||
err = LoadSnapshotV1(bpt2, f, func(key storage.Key, hash [32]byte, reader ioutil2.SectionReader) error { | ||
value, err := io.ReadAll(reader) | ||
if err != nil { | ||
return err | ||
} | ||
valueHash := sha256.Sum256(value) | ||
if hash != valueHash { | ||
return fmt.Errorf("hash does not match for key %X", key) | ||
} | ||
return nil | ||
}) | ||
require.NoError(t, err) | ||
require.NoError(t, bpt.Commit()) | ||
r1, err := bpt.GetRootHash() | ||
require.NoError(t, err) | ||
r2, err := bpt2.GetRootHash() | ||
require.NoError(t, err) | ||
require.Equal(t, r1, r2) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// Copyright 2023 The Accumulate Authors | ||
// | ||
// Use of this source code is governed by an MIT-style | ||
// license that can be found in the LICENSE file or at | ||
// https://opensource.org/licenses/MIT. | ||
|
||
package bpt | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"sort" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
"gitlab.com/accumulatenetwork/accumulate/internal/database/smt/common" | ||
"gitlab.com/accumulatenetwork/accumulate/pkg/database/keyvalue" | ||
"gitlab.com/accumulatenetwork/accumulate/pkg/database/keyvalue/memory" | ||
"gitlab.com/accumulatenetwork/accumulate/pkg/types/record" | ||
) | ||
|
||
var _ = fmt.Print | ||
|
||
func TestGetRange(t *testing.T) { | ||
for i := 0; i < 15000; i += 1017 { | ||
GetRangeFor(t, i, 13) | ||
} | ||
} | ||
|
||
func GetRangeFor(t *testing.T, numberEntries, rangeNum int) { | ||
fmt.Println(numberEntries) | ||
kvs := memory.New(nil).Begin(nil, true) // Build a BPT | ||
store := keyvalue.RecordStore{Store: kvs} // | ||
bpt := newBPT(nil, nil, store, nil, "BPT") // | ||
var keys, values common.RandHash // use the default sequence for keys | ||
values.SetSeed([]byte{1, 2, 3}) // use a different sequence for values | ||
for i := 0; i < numberEntries; i++ { // For the number of Entries specified for the BPT | ||
chainID := keys.NextAList() // Get a key, keep a list | ||
value := values.NextA() // Get some value (don't really care what it is) | ||
err := bpt.Insert(record.KeyFromHash(chainID), value) // Insert the Key with the value into the BPT | ||
require.NoError(t, err) | ||
} | ||
|
||
cnt := 0 | ||
|
||
// The BPT will sort the keys, so we take the list of keys we used, and sort them | ||
sort.Slice(keys.List, func(i, j int) bool { return bytes.Compare(keys.List[i], keys.List[j]) > 0 }) | ||
|
||
// We ask for a range of rangeNum entries at a time. | ||
it := bpt.Iterate(13) | ||
for i := 0; i < numberEntries; i += rangeNum { | ||
require.True(t, it.Next(), "Must be more BPT entries") | ||
bptValues := it.Value() | ||
if len(bptValues) == 0 { | ||
break | ||
} | ||
for j, v := range bptValues { | ||
k := keys.List[i+j] | ||
require.Truef(t, bytes.Equal(v.Key[:], k), "i,j= %d:%d %02x should be %02x", i, j, v.Key[:2], k[:2]) | ||
} | ||
cnt += len(bptValues) | ||
} | ||
|
||
require.Equal(t, len(keys.List), cnt) | ||
} |