more tests, prefixes and small refactor
This commit is contained in:
parent
4d6f22e09a
commit
ef5a1ce38f
4 changed files with 546 additions and 220 deletions
244
db/db_test.go
244
db/db_test.go
|
@ -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)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
416
db/prefixes/prefixes_test.go
Normal file
416
db/prefixes/prefixes_test.go
Normal 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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
10
resources/reposted_claim.csv
Normal file
10
resources/reposted_claim.csv
Normal 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
|
|
Loading…
Reference in a new issue