more tests, prefixes and small refactor

This commit is contained in:
Jeffrey Picard 2022-01-09 23:46:52 -05:00
parent 4d6f22e09a
commit ef5a1ce38f
4 changed files with 546 additions and 220 deletions

View file

@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"encoding/csv" "encoding/csv"
"encoding/hex" "encoding/hex"
"fmt"
"log" "log"
"os" "os"
"testing" "testing"
@ -13,11 +12,9 @@ import (
"github.com/linxGnu/grocksdb" "github.com/linxGnu/grocksdb"
) )
const tmpPath = "../resources/tmp_rocksdb/" func TestIter(t *testing.T) {
func TestClaimDiff(t *testing.T) { filePath := "../resources/reposted_claim.csv"
filePath := "../resources/claim_diff.csv"
log.Println(filePath) log.Println(filePath)
file, err := os.Open(filePath) file, err := os.Open(filePath)
@ -37,7 +34,13 @@ func TestClaimDiff(t *testing.T) {
if err != nil { if err != nil {
log.Println(err) log.Println(err)
} }
defer db.Close() defer func() {
db.Close()
err = os.RemoveAll("./tmp")
if err != nil {
log.Println(err)
}
}()
for _, record := range records { for _, record := range records {
key, err := hex.DecodeString(record[0]) key, err := hex.DecodeString(record[0])
if err != nil { if err != nil {
@ -50,13 +53,29 @@ func TestClaimDiff(t *testing.T) {
db.Put(wOpts, key, val) db.Put(wOpts, key, val)
} }
// test prefix // test prefix
options := NewIterateOptions().WithPrefix([]byte{prefixes.ClaimDiff}).WithIncludeValue(true) options := NewIterateOptions().WithPrefix([]byte{prefixes.RepostedClaim}).WithIncludeValue(true)
ch := Iter(db, options) ch := Iter(db, options)
var i = 0 var i = 0
for kv := range ch { for kv := range ch {
// log.Println(kv.Key) // log.Println(kv.Key)
gotKey := kv.Key.(*prefixes.TouchedOrDeletedClaimKey).PackKey() gotKey := kv.Key.(*prefixes.RepostedKey).PackKey()
got := kv.Value.(*prefixes.TouchedOrDeletedClaimValue).PackValue()
keyPartial3 := prefixes.RepostedKeyPackPartial(kv.Key.(*prefixes.RepostedKey), 3)
keyPartial2 := prefixes.RepostedKeyPackPartial(kv.Key.(*prefixes.RepostedKey), 2)
keyPartial1 := prefixes.RepostedKeyPackPartial(kv.Key.(*prefixes.RepostedKey), 1)
// Check pack partial for sanity
if !bytes.HasPrefix(gotKey, keyPartial3) {
t.Errorf("%+v should be prefix of %+v\n", keyPartial3, gotKey)
}
if !bytes.HasPrefix(gotKey, keyPartial2) {
t.Errorf("%+v should be prefix of %+v\n", keyPartial2, gotKey)
}
if !bytes.HasPrefix(gotKey, keyPartial1) {
t.Errorf("%+v should be prefix of %+v\n", keyPartial1, gotKey)
}
got := kv.Value.(*prefixes.RepostedValue).PackValue()
wantKey, err := hex.DecodeString(records[i][0]) wantKey, err := hex.DecodeString(records[i][0])
if err != nil { if err != nil {
log.Println(err) log.Println(err)
@ -73,10 +92,7 @@ func TestClaimDiff(t *testing.T) {
} }
i++ i++
} }
err = os.RemoveAll("tmp")
if err != nil {
log.Println(err)
}
// Test start / stop // Test start / stop
start, err := hex.DecodeString(records[0][0]) start, err := hex.DecodeString(records[0][0])
if err != nil { if err != nil {
@ -90,8 +106,7 @@ func TestClaimDiff(t *testing.T) {
ch2 := Iter(db, options2) ch2 := Iter(db, options2)
i = 0 i = 0
for kv := range ch2 { for kv := range ch2 {
log.Println(kv.Key) got := kv.Value.(*prefixes.RepostedValue).PackValue()
got := kv.Value.(*prefixes.TouchedOrDeletedClaimValue).PackValue()
want, err := hex.DecodeString(records[i][1]) want, err := hex.DecodeString(records[i][1])
if err != nil { if err != nil {
log.Println(err) log.Println(err)
@ -101,203 +116,4 @@ func TestClaimDiff(t *testing.T) {
} }
i++ i++
} }
err = os.RemoveAll("tmp")
if err != nil {
log.Println(err)
}
}
func TestUTXO(t *testing.T) {
filePath := "../resources/utxo.csv"
log.Println(filePath)
file, err := os.Open(filePath)
if err != nil {
log.Println(err)
}
reader := csv.NewReader(file)
records, err := reader.ReadAll()
if err != nil {
log.Println(err)
}
wOpts := grocksdb.NewDefaultWriteOptions()
opts := grocksdb.NewDefaultOptions()
opts.SetCreateIfMissing(true)
db, err := grocksdb.OpenDb(opts, "tmp")
if err != nil {
log.Println(err)
}
defer db.Close()
for _, record := range records {
key, err := hex.DecodeString(record[0])
if err != nil {
log.Println(err)
}
val, err := hex.DecodeString(record[1])
if err != nil {
log.Println(err)
}
db.Put(wOpts, key, val)
}
// test prefix
options := NewIterateOptions().WithPrefix([]byte{prefixes.UTXO}).WithIncludeValue(true)
ch := Iter(db, options)
var i = 0
for kv := range ch {
log.Println(kv.Key)
got := kv.Value.(*prefixes.UTXOValue).PackValue()
want, err := hex.DecodeString(records[i][1])
if err != nil {
log.Println(err)
}
if !bytes.Equal(got, want) {
t.Errorf("got: %+v, want: %+v\n", got, want)
}
i++
}
err = os.RemoveAll("./tmp")
if err != nil {
log.Println(err)
}
// Test start / stop
start, err := hex.DecodeString(records[0][0])
if err != nil {
log.Println(err)
}
stop, err := hex.DecodeString(records[9][0])
if err != nil {
log.Println(err)
}
options2 := NewIterateOptions().WithStart(start).WithStop(stop).WithIncludeValue(true)
ch2 := Iter(db, options2)
i = 0
for kv := range ch2 {
log.Println(kv.Key)
got := kv.Value.(*prefixes.UTXOValue).PackValue()
want, err := hex.DecodeString(records[i][1])
if err != nil {
log.Println(err)
}
if !bytes.Equal(got, want) {
t.Errorf("got: %+v, want: %+v\n", got, want)
}
i++
}
err = os.RemoveAll("./tmp")
if err != nil {
log.Println(err)
}
}
func TestHashXUTXO(t *testing.T) {
tests := []struct {
name string
filePath string
}{
{
name: "Read HashX_UTXO correctly",
filePath: "../resources/hashx_utxo.csv",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
log.Println(tt.filePath)
file, err := os.Open(tt.filePath)
if err != nil {
log.Println(err)
}
reader := csv.NewReader(file)
records, err := reader.ReadAll()
if err != nil {
log.Println(err)
}
wOpts := grocksdb.NewDefaultWriteOptions()
opts := grocksdb.NewDefaultOptions()
opts.SetCreateIfMissing(true)
db, err := grocksdb.OpenDb(opts, "tmp")
if err != nil {
log.Println(err)
}
defer db.Close()
for _, record := range records {
key, err := hex.DecodeString(record[0])
if err != nil {
log.Println(err)
}
val, err := hex.DecodeString(record[1])
if err != nil {
log.Println(err)
}
db.Put(wOpts, key, val)
}
start, err := hex.DecodeString(records[0][0])
if err != nil {
log.Println(err)
}
options := NewIterateOptions().WithPrefix([]byte{prefixes.HashXUTXO}).WithStart(start).WithIncludeValue(true)
ch := Iter(db, options)
var i = 0
for kv := range ch {
log.Println(kv.Key)
got := kv.Value.(*prefixes.HashXUTXOValue).PackValue()
want, err := hex.DecodeString(records[i][1])
if err != nil {
log.Println(err)
}
if !bytes.Equal(got, want) {
t.Errorf("got: %+v, want: %+v\n", got, want)
}
i++
if i > 9 {
return
}
}
err = os.RemoveAll("./tmp")
if err != nil {
log.Println(err)
}
})
}
}
func TestUTXOKey_String(t *testing.T) {
tests := []struct {
name string
prefix []byte
hashx []byte
txnum uint32
nout uint16
want string
}{
{
name: "Converts to string",
prefix: []byte("u"),
hashx: []byte("AAAAAAAAAA"),
txnum: 0,
nout: 0,
want: "*prefixes.UTXOKey(hashX=41414141414141414141, tx_num=0, nout=0)",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
key := &prefixes.UTXOKey{
Prefix: tt.prefix,
HashX: tt.hashx,
TxNum: tt.txnum,
Nout: tt.nout,
}
got := fmt.Sprint(key)
log.Println(got)
if got != tt.want {
t.Errorf("got: %s, want: %s\n", got, tt.want)
}
})
}
} }

View file

@ -747,14 +747,97 @@ class RepostedValue(typing.NamedTuple):
type RepostedKey struct { type RepostedKey struct {
Prefix []byte `json:"prefix"` Prefix []byte `json:"prefix"`
RepostedClaimHash []byte `json:"reposted_claim_hash"` RepostedClaimHash []byte `json:"reposted_claim_hash"`
TxNum int32 `json:"tx_num"` TxNum uint32 `json:"tx_num"`
Position int32 `json:"position"` Position uint16 `json:"position"`
} }
type RepostedValue struct { type RepostedValue struct {
ClaimHash []byte `json:"claim_hash"` ClaimHash []byte `json:"claim_hash"`
} }
func (k *RepostedKey) PackKey() []byte {
prefixLen := 1
// b'>20sLH'
n := prefixLen + 20 + 4 + 2
key := make([]byte, n)
copy(key, k.Prefix)
copy(key[prefixLen:], k.RepostedClaimHash)
binary.BigEndian.PutUint32(key[prefixLen+20:], k.TxNum)
binary.BigEndian.PutUint16(key[prefixLen+24:], k.Position)
return key
}
func (v *RepostedValue) PackValue() []byte {
// b'>20s'
value := make([]byte, 20)
copy(value, v.ClaimHash)
return value
}
func RepostedKeyPackPartialNFields(nFields int) func(*RepostedKey) []byte {
return func(u *RepostedKey) []byte {
return RepostedKeyPackPartial(u, nFields)
}
}
func RepostedKeyPackPartial(k *RepostedKey, nFields int) []byte {
// Limit nFields between 0 and number of fields, we always at least need
// the prefix, and we never need to iterate past the number of fields.
if nFields > 3 {
nFields = 3
}
if nFields < 0 {
nFields = 0
}
prefixLen := 1
var n = prefixLen
for i := 0; i <= nFields; i++ {
switch i {
case 1:
n += 20
case 2:
n += 4
case 3:
n += 2
}
}
key := make([]byte, n)
for i := 0; i <= nFields; i++ {
switch i {
case 0:
copy(key, k.Prefix)
case 1:
copy(key[prefixLen:], k.RepostedClaimHash)
case 2:
binary.BigEndian.PutUint32(key[prefixLen+20:], k.TxNum)
case 3:
binary.BigEndian.PutUint16(key[prefixLen+24:], k.Position)
}
}
return key
}
func RepostedKeyUnpack(key []byte) *RepostedKey {
return &RepostedKey{
Prefix: key[:1],
RepostedClaimHash: key[1:21],
TxNum: binary.BigEndian.Uint32(key[21:]),
Position: binary.BigEndian.Uint16(key[25:]),
}
}
func RepostedValueUnpack(value []byte) *RepostedValue {
return &RepostedValue{
ClaimHash: value[:20],
}
}
// //
// TouchedOrDeletedClaimKey / TouchedOrDeletedClaimValue // TouchedOrDeletedClaimKey / TouchedOrDeletedClaimValue
// //
@ -848,6 +931,7 @@ func (v *TouchedOrDeletedClaimValue) PackValue() []byte {
value := make([]byte, n) value := make([]byte, n)
binary.BigEndian.PutUint32(value, touchedLen) binary.BigEndian.PutUint32(value, touchedLen)
binary.BigEndian.PutUint32(value[4:], deletedLen) binary.BigEndian.PutUint32(value[4:], deletedLen)
// These are sorted for consistency with the Python implementation
sort.Slice(v.TouchedClaims, func(i, j int) bool { return bytes.Compare(v.TouchedClaims[i], v.TouchedClaims[j]) < 0 }) sort.Slice(v.TouchedClaims, func(i, j int) bool { return bytes.Compare(v.TouchedClaims[i], v.TouchedClaims[j]) < 0 })
sort.Slice(v.DeletedClaims, func(i, j int) bool { return bytes.Compare(v.DeletedClaims[i], v.DeletedClaims[j]) < 0 }) sort.Slice(v.DeletedClaims, func(i, j int) bool { return bytes.Compare(v.DeletedClaims[i], v.DeletedClaims[j]) < 0 })
@ -917,14 +1001,10 @@ func TouchedOrDeletedClaimValueUnpack(value []byte) *TouchedOrDeletedClaimValue
deletedClaims := make([][]byte, deletedLen) deletedClaims := make([][]byte, deletedLen)
var j = 8 var j = 8
for i := 0; i < int(touchedLen); i++ { for i := 0; i < int(touchedLen); i++ {
//touchedClaims[i] = make([]byte, 20)
//copy(touchedClaims[i], value[j:j+20])
touchedClaims[i] = value[j : j+20] touchedClaims[i] = value[j : j+20]
j += 20 j += 20
} }
for i := 0; i < int(deletedLen); i++ { for i := 0; i < int(deletedLen); i++ {
//deletedClaims[i] = make([]byte, 20)
//copy(deletedClaims[i], value[j:j+20])
deletedClaims[i] = value[j : j+20] deletedClaims[i] = value[j : j+20]
j += 20 j += 20
} }
@ -1167,7 +1247,9 @@ func UnpackGenericKey(key []byte) (byte, interface{}, error) {
case ActiveAmount: case ActiveAmount:
case Repost: case Repost:
return 0x0, nil, errors.Base("key unpack function for %v not implemented", firstByte)
case RepostedClaim: case RepostedClaim:
return RepostedClaim, RepostedKeyUnpack(key), nil
case Undo: case Undo:
return 0x0, nil, errors.Base("key unpack function for %v not implemented", firstByte) return 0x0, nil, errors.Base("key unpack function for %v not implemented", firstByte)
@ -1223,7 +1305,9 @@ func UnpackGenericValue(key, value []byte) (byte, interface{}, error) {
case ActiveAmount: case ActiveAmount:
case Repost: case Repost:
return 0x0, nil, nil
case RepostedClaim: case RepostedClaim:
return RepostedClaim, RepostedValueUnpack(value), nil
case Undo: case Undo:
return 0x0, nil, nil return 0x0, nil, nil

View file

@ -0,0 +1,416 @@
package prefixes_test
import (
"bytes"
"encoding/csv"
"encoding/hex"
"fmt"
"log"
"os"
"testing"
dbpkg "github.com/lbryio/hub/db"
"github.com/lbryio/hub/db/prefixes"
"github.com/linxGnu/grocksdb"
)
func TestRepostedClaim(t *testing.T) {
filePath := "../../resources/reposted_claim.csv"
log.Println(filePath)
file, err := os.Open(filePath)
if err != nil {
log.Println(err)
}
reader := csv.NewReader(file)
records, err := reader.ReadAll()
if err != nil {
log.Println(err)
}
wOpts := grocksdb.NewDefaultWriteOptions()
opts := grocksdb.NewDefaultOptions()
opts.SetCreateIfMissing(true)
db, err := grocksdb.OpenDb(opts, "tmp")
if err != nil {
log.Println(err)
}
defer func() {
db.Close()
err = os.RemoveAll("./tmp")
if err != nil {
log.Println(err)
}
}()
for _, record := range records {
key, err := hex.DecodeString(record[0])
if err != nil {
log.Println(err)
}
val, err := hex.DecodeString(record[1])
if err != nil {
log.Println(err)
}
db.Put(wOpts, key, val)
}
// test prefix
options := dbpkg.NewIterateOptions().WithPrefix([]byte{prefixes.RepostedClaim}).WithIncludeValue(true)
ch := dbpkg.Iter(db, options)
var i = 0
for kv := range ch {
// log.Println(kv.Key)
gotKey := kv.Key.(*prefixes.RepostedKey).PackKey()
keyPartial3 := prefixes.RepostedKeyPackPartial(kv.Key.(*prefixes.RepostedKey), 3)
keyPartial2 := prefixes.RepostedKeyPackPartial(kv.Key.(*prefixes.RepostedKey), 2)
keyPartial1 := prefixes.RepostedKeyPackPartial(kv.Key.(*prefixes.RepostedKey), 1)
// Check pack partial for sanity
if !bytes.HasPrefix(gotKey, keyPartial3) {
t.Errorf("%+v should be prefix of %+v\n", keyPartial3, gotKey)
}
if !bytes.HasPrefix(gotKey, keyPartial2) {
t.Errorf("%+v should be prefix of %+v\n", keyPartial2, gotKey)
}
if !bytes.HasPrefix(gotKey, keyPartial1) {
t.Errorf("%+v should be prefix of %+v\n", keyPartial1, gotKey)
}
got := kv.Value.(*prefixes.RepostedValue).PackValue()
wantKey, err := hex.DecodeString(records[i][0])
if err != nil {
log.Println(err)
}
want, err := hex.DecodeString(records[i][1])
if err != nil {
log.Println(err)
}
if !bytes.Equal(gotKey, wantKey) {
t.Errorf("gotKey: %+v, wantKey: %+v\n", got, want)
}
if !bytes.Equal(got, want) {
t.Errorf("got: %+v, want: %+v\n", got, want)
}
i++
}
// Test start / stop
start, err := hex.DecodeString(records[0][0])
if err != nil {
log.Println(err)
}
stop, err := hex.DecodeString(records[9][0])
if err != nil {
log.Println(err)
}
options2 := dbpkg.NewIterateOptions().WithStart(start).WithStop(stop).WithIncludeValue(true)
ch2 := dbpkg.Iter(db, options2)
i = 0
for kv := range ch2 {
got := kv.Value.(*prefixes.RepostedValue).PackValue()
want, err := hex.DecodeString(records[i][1])
if err != nil {
log.Println(err)
}
if !bytes.Equal(got, want) {
t.Errorf("got: %+v, want: %+v\n", got, want)
}
i++
}
}
func TestClaimDiff(t *testing.T) {
filePath := "../../resources/claim_diff.csv"
log.Println(filePath)
file, err := os.Open(filePath)
if err != nil {
log.Println(err)
}
reader := csv.NewReader(file)
records, err := reader.ReadAll()
if err != nil {
log.Println(err)
}
wOpts := grocksdb.NewDefaultWriteOptions()
opts := grocksdb.NewDefaultOptions()
opts.SetCreateIfMissing(true)
db, err := grocksdb.OpenDb(opts, "tmp")
if err != nil {
log.Println(err)
}
defer func() {
db.Close()
err = os.RemoveAll("./tmp")
if err != nil {
log.Println(err)
}
}()
for _, record := range records {
key, err := hex.DecodeString(record[0])
if err != nil {
log.Println(err)
}
val, err := hex.DecodeString(record[1])
if err != nil {
log.Println(err)
}
db.Put(wOpts, key, val)
}
// test prefix
options := dbpkg.NewIterateOptions().WithPrefix([]byte{prefixes.ClaimDiff}).WithIncludeValue(true)
ch := dbpkg.Iter(db, options)
var i = 0
for kv := range ch {
// log.Println(kv.Key)
gotKey := kv.Key.(*prefixes.TouchedOrDeletedClaimKey).PackKey()
keyPartial1 := prefixes.TouchedOrDeletedClaimKeyPackPartial(kv.Key.(*prefixes.TouchedOrDeletedClaimKey), 1)
// Check pack partial for sanity
if !bytes.HasPrefix(gotKey, keyPartial1) {
t.Errorf("%+v should be prefix of %+v\n", keyPartial1, gotKey)
}
got := kv.Value.(*prefixes.TouchedOrDeletedClaimValue).PackValue()
wantKey, err := hex.DecodeString(records[i][0])
if err != nil {
log.Println(err)
}
want, err := hex.DecodeString(records[i][1])
if err != nil {
log.Println(err)
}
if !bytes.Equal(gotKey, wantKey) {
t.Errorf("gotKey: %+v, wantKey: %+v\n", got, want)
}
if !bytes.Equal(got, want) {
t.Errorf("got: %+v, want: %+v\n", got, want)
}
i++
}
// Test start / stop
start, err := hex.DecodeString(records[0][0])
if err != nil {
log.Println(err)
}
stop, err := hex.DecodeString(records[9][0])
if err != nil {
log.Println(err)
}
options2 := dbpkg.NewIterateOptions().WithStart(start).WithStop(stop).WithIncludeValue(true)
ch2 := dbpkg.Iter(db, options2)
i = 0
for kv := range ch2 {
log.Println(kv.Key)
got := kv.Value.(*prefixes.TouchedOrDeletedClaimValue).PackValue()
want, err := hex.DecodeString(records[i][1])
if err != nil {
log.Println(err)
}
if !bytes.Equal(got, want) {
t.Errorf("got: %+v, want: %+v\n", got, want)
}
i++
}
}
func TestUTXO(t *testing.T) {
filePath := "../../resources/utxo.csv"
log.Println(filePath)
file, err := os.Open(filePath)
if err != nil {
log.Println(err)
}
reader := csv.NewReader(file)
records, err := reader.ReadAll()
if err != nil {
log.Println(err)
}
wOpts := grocksdb.NewDefaultWriteOptions()
opts := grocksdb.NewDefaultOptions()
opts.SetCreateIfMissing(true)
db, err := grocksdb.OpenDb(opts, "tmp")
if err != nil {
log.Println(err)
}
defer func() {
db.Close()
err = os.RemoveAll("./tmp")
if err != nil {
log.Println(err)
}
}()
for _, record := range records {
key, err := hex.DecodeString(record[0])
if err != nil {
log.Println(err)
}
val, err := hex.DecodeString(record[1])
if err != nil {
log.Println(err)
}
db.Put(wOpts, key, val)
}
// test prefix
options := dbpkg.NewIterateOptions().WithPrefix([]byte{prefixes.UTXO}).WithIncludeValue(true)
ch := dbpkg.Iter(db, options)
var i = 0
for kv := range ch {
log.Println(kv.Key)
got := kv.Value.(*prefixes.UTXOValue).PackValue()
want, err := hex.DecodeString(records[i][1])
if err != nil {
log.Println(err)
}
if !bytes.Equal(got, want) {
t.Errorf("got: %+v, want: %+v\n", got, want)
}
i++
}
// Test start / stop
start, err := hex.DecodeString(records[0][0])
if err != nil {
log.Println(err)
}
stop, err := hex.DecodeString(records[9][0])
if err != nil {
log.Println(err)
}
options2 := dbpkg.NewIterateOptions().WithStart(start).WithStop(stop).WithIncludeValue(true)
ch2 := dbpkg.Iter(db, options2)
i = 0
for kv := range ch2 {
log.Println(kv.Key)
got := kv.Value.(*prefixes.UTXOValue).PackValue()
want, err := hex.DecodeString(records[i][1])
if err != nil {
log.Println(err)
}
if !bytes.Equal(got, want) {
t.Errorf("got: %+v, want: %+v\n", got, want)
}
i++
}
}
func TestHashXUTXO(t *testing.T) {
tests := []struct {
name string
filePath string
}{
{
name: "Read HashX_UTXO correctly",
filePath: "../../resources/hashx_utxo.csv",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
log.Println(tt.filePath)
file, err := os.Open(tt.filePath)
if err != nil {
log.Println(err)
}
reader := csv.NewReader(file)
records, err := reader.ReadAll()
if err != nil {
log.Println(err)
}
wOpts := grocksdb.NewDefaultWriteOptions()
opts := grocksdb.NewDefaultOptions()
opts.SetCreateIfMissing(true)
db, err := grocksdb.OpenDb(opts, "tmp")
if err != nil {
log.Println(err)
}
defer func() {
db.Close()
err = os.RemoveAll("./tmp")
if err != nil {
log.Println(err)
}
}()
for _, record := range records {
key, err := hex.DecodeString(record[0])
if err != nil {
log.Println(err)
}
val, err := hex.DecodeString(record[1])
if err != nil {
log.Println(err)
}
db.Put(wOpts, key, val)
}
start, err := hex.DecodeString(records[0][0])
if err != nil {
log.Println(err)
}
options := dbpkg.NewIterateOptions().WithPrefix([]byte{prefixes.HashXUTXO}).WithStart(start).WithIncludeValue(true)
ch := dbpkg.Iter(db, options)
var i = 0
for kv := range ch {
log.Println(kv.Key)
got := kv.Value.(*prefixes.HashXUTXOValue).PackValue()
want, err := hex.DecodeString(records[i][1])
if err != nil {
log.Println(err)
}
if !bytes.Equal(got, want) {
t.Errorf("got: %+v, want: %+v\n", got, want)
}
i++
if i > 9 {
return
}
}
})
}
}
func TestUTXOKey_String(t *testing.T) {
tests := []struct {
name string
prefix []byte
hashx []byte
txnum uint32
nout uint16
want string
}{
{
name: "Converts to string",
prefix: []byte("u"),
hashx: []byte("AAAAAAAAAA"),
txnum: 0,
nout: 0,
want: "*prefixes.UTXOKey(hashX=41414141414141414141, tx_num=0, nout=0)",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
key := &prefixes.UTXOKey{
Prefix: tt.prefix,
HashX: tt.hashx,
TxNum: tt.txnum,
Nout: tt.nout,
}
got := fmt.Sprint(key)
log.Println(got)
if got != tt.want {
t.Errorf("got: %s, want: %s\n", got, tt.want)
}
})
}
}

View file

@ -0,0 +1,10 @@
5700003eb3f3f17af2cf79b286dc1952f6c3df2e1d03947d150000,4dd814e8ae0fc8feead86bf6c723bcc45b224c44
570000997ae50674ed318475cb207bf1902e01de7b02d931f70000,70e7073d180053a3e8815116e68466b8a9819eaa
570000997ae50674ed318475cb207bf1902e01de7b031b5d5b0000,1d89ae62063d38c9ad5833721af2a2a8670a60ff
5700009c47ca0687ea07155efc2a6ba803180066f1029e8f850000,028adb1480ac50803d11ebd97d54a21b8a7b7839
5700009d1409ca5962d3d2c8f638cd75a312af03c4015f8a440000,ca28a84248c434bb6f2d6484cae2fbd8f841362b
570000bcdff7762b712ac3a74634a0b27bcdd6b7e400c721410000,033c9374b2dd89eb357769ff234742c7d9e91ee4
570000cda50bcdc44f55045c8c0ce4ba094a17ef6d012a443d0000,0a23389dfba22c2a955e7283e0a23c44590c429a
570001034f15a28f221d469e42edc38b48a244cabd0329f5a60000,b30442f45c7c0dd4595e492cf02529c5fc6c58ac
57000115df1d87a9346c1402dfba75fe04c4a66e36032e99280000,b13a360dda378ed53c5a502a0769cd841b85ea60
570001205a75aeb993d1e47d370c40301b1c77a2f60249e1fa0000,7e243aee3dbefe46c285dadd354dea427cc167e3
1 5700003eb3f3f17af2cf79b286dc1952f6c3df2e1d03947d150000 4dd814e8ae0fc8feead86bf6c723bcc45b224c44
2 570000997ae50674ed318475cb207bf1902e01de7b02d931f70000 70e7073d180053a3e8815116e68466b8a9819eaa
3 570000997ae50674ed318475cb207bf1902e01de7b031b5d5b0000 1d89ae62063d38c9ad5833721af2a2a8670a60ff
4 5700009c47ca0687ea07155efc2a6ba803180066f1029e8f850000 028adb1480ac50803d11ebd97d54a21b8a7b7839
5 5700009d1409ca5962d3d2c8f638cd75a312af03c4015f8a440000 ca28a84248c434bb6f2d6484cae2fbd8f841362b
6 570000bcdff7762b712ac3a74634a0b27bcdd6b7e400c721410000 033c9374b2dd89eb357769ff234742c7d9e91ee4
7 570000cda50bcdc44f55045c8c0ce4ba094a17ef6d012a443d0000 0a23389dfba22c2a955e7283e0a23c44590c429a
8 570001034f15a28f221d469e42edc38b48a244cabd0329f5a60000 b30442f45c7c0dd4595e492cf02529c5fc6c58ac
9 57000115df1d87a9346c1402dfba75fe04c4a66e36032e99280000 b13a360dda378ed53c5a502a0769cd841b85ea60
10 570001205a75aeb993d1e47d370c40301b1c77a2f60249e1fa0000 7e243aee3dbefe46c285dadd354dea427cc167e3