Catchup to python-herald schema. Plus lots of refactoring. #49

Merged
moodyjon merged 18 commits from schema_catchup into master 2022-08-16 07:45:42 +02:00
4 changed files with 548 additions and 143 deletions
Showing only changes of commit 9d1992e95f - Show all commits

517
db/prefixes/generic.go Normal file
View file

@ -0,0 +1,517 @@
package prefixes
import (
"encoding/binary"
"fmt"
"reflect"
"strings"
"github.com/go-restruct/restruct"
)
func init() {
restruct.EnableExprBeta()
}
type tableMeta struct {
newKey func() interface{}
newValue func() interface{}
newKeyUnpack func([]byte) interface{}
newValueUnpack func([]byte) interface{}
}
var tableRegistry = map[byte]tableMeta{
ClaimToSupport: {
newKey: func() interface{} {
return &ClaimToSupportKey{Prefix: []byte{ClaimToSupport}}
},
newValue: func() interface{} {
return &ClaimToSupportValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return ClaimToSupportKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return ClaimToSupportValueUnpack(buf)
},
},
SupportToClaim: {
newKey: func() interface{} {
return &SupportToClaimKey{Prefix: []byte{SupportToClaim}}
},
newValue: func() interface{} {
return &SupportToClaimValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return SupportToClaimKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return SupportToClaimValueUnpack(buf)
},
},
ClaimToTXO: {
newKey: func() interface{} {
return &ClaimToTXOKey{Prefix: []byte{ClaimToTXO}}
},
newValue: func() interface{} {
return &ClaimToTXOValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return ClaimToTXOKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return ClaimToTXOValueUnpack(buf)
},
},
TXOToClaim: {
newKey: func() interface{} {
return &TXOToClaimKey{Prefix: []byte{TXOToClaim}}
},
newValue: func() interface{} {
return &TXOToClaimValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return TXOToClaimKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return TXOToClaimValueUnpack(buf)
},
},
ClaimToChannel: {
newKey: func() interface{} {
return &ClaimToChannelKey{Prefix: []byte{ClaimToChannel}}
},
newValue: func() interface{} {
return &ClaimToChannelValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return ClaimToChannelKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return ClaimToChannelValueUnpack(buf)
},
},
ChannelToClaim: {
newKey: func() interface{} {
return &ChannelToClaimKey{Prefix: []byte{ChannelToClaim}}
},
newValue: func() interface{} {
return &ChannelToClaimValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return ChannelToClaimKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return ChannelToClaimValueUnpack(buf)
},
},
ClaimShortIdPrefix: {
newKey: func() interface{} {
return &ClaimShortIDKey{Prefix: []byte{ClaimShortIdPrefix}}
},
newValue: func() interface{} {
return &ClaimShortIDValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return ClaimShortIDKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return ClaimShortIDValueUnpack(buf)
},
},
EffectiveAmount: {
newKey: func() interface{} {
return &EffectiveAmountKey{Prefix: []byte{EffectiveAmount}}
},
newValue: func() interface{} {
return &EffectiveAmountValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return EffectiveAmountKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return EffectiveAmountValueUnpack(buf)
},
},
ClaimExpiration: {
newKey: func() interface{} {
return &ClaimExpirationKey{Prefix: []byte{ClaimExpiration}}
},
newValue: func() interface{} {
return &ClaimExpirationValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return ClaimExpirationKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return ClaimExpirationValueUnpack(buf)
},
},
ClaimTakeover: {
newKey: func() interface{} {
return &ClaimTakeoverKey{Prefix: []byte{ClaimTakeover}}
},
newValue: func() interface{} {
return &ClaimTakeoverValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return ClaimTakeoverKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return ClaimTakeoverValueUnpack(buf)
},
},
PendingActivation: {
newKey: func() interface{} {
return &PendingActivationKey{Prefix: []byte{PendingActivation}}
},
newValue: func() interface{} {
return &PendingActivationValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return PendingActivationKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return PendingActivationValueUnpack(buf)
},
},
ActivatedClaimAndSupport: {
newKey: func() interface{} {
return &ActivationKey{Prefix: []byte{ActivatedClaimAndSupport}}
},
newValue: func() interface{} {
return &ActivationValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return ActivationKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return ActivationValueUnpack(buf)
},
},
ActiveAmount: {
newKey: func() interface{} {
return &ActiveAmountKey{Prefix: []byte{ActiveAmount}}
},
newValue: func() interface{} {
return &ActiveAmountValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return ActiveAmountKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return ActiveAmountValueUnpack(buf)
},
},
Repost: {
newKey: func() interface{} {
return &RepostKey{Prefix: []byte{Repost}}
},
newValue: func() interface{} {
return &RepostValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return RepostKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return RepostValueUnpack(buf)
},
},
RepostedClaim: {
newKey: func() interface{} {
return &RepostedKey{Prefix: []byte{RepostedClaim}}
},
newValue: func() interface{} {
return &RepostedValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return RepostedKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return RepostedValueUnpack(buf)
},
},
Undo: {
newKey: func() interface{} {
return &UndoKey{Prefix: []byte{Undo}}
},
newValue: func() interface{} {
return &UndoValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return UndoKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return UndoValueUnpack(buf)
},
},
TouchedOrDeleted: {
newKey: func() interface{} {
return &TouchedOrDeletedClaimKey{Prefix: []byte{TouchedOrDeleted}}
},
newValue: func() interface{} {
return &TouchedOrDeletedClaimValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return TouchedOrDeletedClaimKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return TouchedOrDeletedClaimValueUnpack(buf)
},
},
Tx: {
newKey: func() interface{} {
return &TxKey{Prefix: []byte{Tx}}
},
newValue: func() interface{} {
return &TxValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return TxKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return TxValueUnpack(buf)
},
},
BlockHash: {
newKey: func() interface{} {
return &BlockHashKey{Prefix: []byte{BlockHash}}
},
newValue: func() interface{} {
return &BlockHashValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return BlockHashKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return BlockHashValueUnpack(buf)
},
},
Header: {
newKey: func() interface{} {
return &BlockHeaderKey{Prefix: []byte{Header}}
},
newValue: func() interface{} {
return &BlockHeaderValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return BlockHeaderKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return BlockHeaderValueUnpack(buf)
},
},
TxNum: {
newKey: func() interface{} {
return &TxNumKey{Prefix: []byte{TxNum}}
},
newValue: func() interface{} {
return &TxNumValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return TxNumKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return TxNumValueUnpack(buf)
},
},
TxCount: {
newKey: func() interface{} {
return &TxCountKey{Prefix: []byte{TxCount}}
},
newValue: func() interface{} {
return &TxCountValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return TxCountKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return TxCountValueUnpack(buf)
},
},
TxHash: {
newKey: func() interface{} {
return &TxHashKey{Prefix: []byte{TxHash}}
},
newValue: func() interface{} {
return &TxHashValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return TxHashKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return TxHashValueUnpack(buf)
},
},
UTXO: {
newKey: func() interface{} {
return &UTXOKey{Prefix: []byte{UTXO}}
},
newValue: func() interface{} {
return &UTXOValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return UTXOKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return UTXOValueUnpack(buf)
},
},
HashXUTXO: {
newKey: func() interface{} {
return &HashXUTXOKey{Prefix: []byte{HashXUTXO}}
},
newValue: func() interface{} {
return &HashXUTXOValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return HashXUTXOKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return HashXUTXOValueUnpack(buf)
},
},
HashXHistory: {
newKey: func() interface{} {
return &HashXHistoryKey{Prefix: []byte{HashXHistory}}
},
newValue: func() interface{} {
return &HashXHistoryValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return HashXHistoryKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return HashXHistoryValueUnpack(buf)
},
},
DBState: {
newKey: func() interface{} {
return &DBStateKey{Prefix: []byte{DBState}}
},
newValue: func() interface{} {
return &DBStateValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return DBStateKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return DBStateValueUnpack(buf)
},
},
ChannelCount: {
newKey: func() interface{} {
return &ChannelCountKey{Prefix: []byte{ChannelCount}}
},
newValue: func() interface{} {
return &ChannelCountValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return ChannelCountKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return ChannelCountValueUnpack(buf)
},
},
SupportAmount: {
newKey: func() interface{} {
return &SupportAmountKey{Prefix: []byte{SupportAmount}}
},
newValue: func() interface{} {
return &SupportAmountValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return SupportAmountKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return SupportAmountValueUnpack(buf)
},
},
BlockTXs: {
newKey: func() interface{} {
return &BlockTxsKey{Prefix: []byte{BlockTXs}}
},
newValue: func() interface{} {
return &BlockTxsValue{}
},
newKeyUnpack: func(buf []byte) interface{} {
return BlockTxsKeyUnpack(buf)
},
newValueUnpack: func(buf []byte) interface{} {
return BlockTxsValueUnpack(buf)
},
},
}
func genericNew(prefix []byte, key bool) (interface{}, error) {
t, ok := tableRegistry[prefix[0]]
if !ok {
panic(fmt.Sprintf("not handled: prefix=%v", prefix))
}
if key {
return t.newKey(), nil
}
return t.newValue(), nil
}
func GenericPack(kv interface{}, fields int) ([]byte, error) {
// Locate the byte offset of the first excluded field.
offset := 0
if fields > 0 {
v := reflect.ValueOf(kv)
t := v.Type()
// Handle indirection to reach kind=Struct.
switch t.Kind() {
case reflect.Interface, reflect.Pointer:
v = v.Elem()
t = v.Type()
default:
panic(fmt.Sprintf("not handled: %v", t.Kind()))
}
count := 0
for _, sf := range reflect.VisibleFields(t) {
if !sf.IsExported() {
continue
}
if sf.Anonymous && strings.HasPrefix(sf.Name, "LengthEncoded") {
fields += 1 // Skip it but process NameLen and Name instead.
continue
}
if count > fields {
break
}
sz, err := restruct.SizeOf(v.FieldByIndex(sf.Index).Interface())
if err != nil {
panic(fmt.Sprintf("not handled: %v: %v", sf.Name, sf.Type.Kind()))
}
offset += sz
count += 1
}
}
// Pack the struct. No ability to partially pack.
buf, err := restruct.Pack(binary.BigEndian, kv)
if err != nil {
panic(fmt.Sprintf("not handled: %v", err))
}
// Return a prefix if some fields were excluded.
if fields > 0 {
return buf[:offset], nil
}
return buf, nil
}
func GenericUnpack(pfx []byte, key bool, buf []byte) (interface{}, error) {
kv, _ := genericNew(pfx, key)
err := restruct.Unpack(buf, binary.BigEndian, kv)
if err != nil {
panic(fmt.Sprintf("not handled: %v", err))
}
return kv, nil
}

View file

@ -3223,158 +3223,39 @@ func UTXOValueUnpack(value []byte) *UTXOValue {
}
}
// generic simulates a generic key packing / unpacking function for the prefixes
func generic(voidstar interface{}, firstByte byte, function byte, functionName string) (interface{}, error) {
var data []byte
if function < 2 {
data = voidstar.([]byte)
}
switch uint16(firstByte) | uint16(function)<<8 {
case ClaimToSupport:
return ClaimToSupportKeyUnpack(data), nil
case ClaimToSupport | 1<<8:
return ClaimToSupportValueUnpack(data), nil
case SupportToClaim:
return SupportToClaimKeyUnpack(data), nil
case SupportToClaim | 1<<8:
return SupportToClaimValueUnpack(data), nil
case ClaimToTXO:
return ClaimToTXOKeyUnpack(data), nil
case ClaimToTXO | 1<<8:
return ClaimToTXOValueUnpack(data), nil
return TXOToClaimKeyUnpack(data), nil
case TXOToClaim | 1<<8:
return TXOToClaimValueUnpack(data), nil
case ClaimToChannel:
return ClaimToChannelKeyUnpack(data), nil
case ClaimToChannel | 1<<8:
return ClaimToChannelValueUnpack(data), nil
case ChannelToClaim:
return ChannelToClaimKeyUnpack(data), nil
case ChannelToClaim | 1<<8:
return ChannelToClaimValueUnpack(data), nil
case ClaimShortIdPrefix:
return ClaimShortIDKeyUnpack(data), nil
case ClaimShortIdPrefix | 1<<8:
return ClaimShortIDValueUnpack(data), nil
case EffectiveAmount:
return EffectiveAmountKeyUnpack(data), nil
case EffectiveAmount | 1<<8:
return EffectiveAmountValueUnpack(data), nil
case ClaimExpiration:
return ClaimExpirationKeyUnpack(data), nil
case ClaimExpiration | 1<<8:
return ClaimExpirationValueUnpack(data), nil
case ClaimTakeover:
return ClaimTakeoverKeyUnpack(data), nil
case ClaimTakeover | 1<<8:
return ClaimTakeoverValueUnpack(data), nil
case PendingActivation:
return PendingActivationKeyUnpack(data), nil
case PendingActivation | 1<<8:
return PendingActivationValueUnpack(data), nil
case ActivatedClaimAndSupport:
return ActivationKeyUnpack(data), nil
case ActivatedClaimAndSupport | 1<<8:
return ActivationValueUnpack(data), nil
case ActiveAmount:
return ActiveAmountKeyUnpack(data), nil
case ActiveAmount | 1<<8:
return ActiveAmountValueUnpack(data), nil
case Repost:
return RepostKeyUnpack(data), nil
case Repost | 1<<8:
return RepostValueUnpack(data), nil
case RepostedClaim:
return RepostedKeyUnpack(data), nil
case RepostedClaim | 1<<8:
return RepostedValueUnpack(data), nil
case Undo:
return UndoKeyUnpack(data), nil
case Undo | 1<<8:
return UndoValueUnpack(data), nil
case ClaimDiff:
return TouchedOrDeletedClaimKeyUnpack(data), nil
case ClaimDiff | 1<<8:
return TouchedOrDeletedClaimValueUnpack(data), nil
case Tx:
return TxKeyUnpack(data), nil
case Tx | 1<<8:
return TxValueUnpack(data), nil
case BlockHash:
return BlockHashKeyUnpack(data), nil
case BlockHash | 1<<8:
return BlockHashValueUnpack(data), nil
case Header:
return BlockHeaderKeyUnpack(data), nil
case Header | 1<<8:
return BlockHeaderValueUnpack(data), nil
case TxNum:
return TxNumKeyUnpack(data), nil
case TxNum | 1<<8:
return TxNumValueUnpack(data), nil
case TxCount:
return TxCountKeyUnpack(data), nil
case TxCount | 1<<8:
return TxCountValueUnpack(data), nil
case TxHash:
return TxHashKeyUnpack(data), nil
case TxHash | 1<<8:
return TxHashValueUnpack(data), nil
case UTXO:
return UTXOKeyUnpack(data), nil
case UTXO | 1<<8:
return UTXOValueUnpack(data), nil
case HashXUTXO:
return HashXUTXOKeyUnpack(data), nil
case HashXUTXO | 1<<8:
return HashXUTXOValueUnpack(data), nil
case HashXHistory:
return HashXHistoryKeyUnpack(data), nil
case HashXHistory | 1<<8:
return HashXHistoryValueUnpack(data), nil
case DBState:
return DBStateKeyUnpack(data), nil
case DBState | 1<<8:
return DBStateValueUnpack(data), nil
case ChannelCount:
return ChannelCountKeyUnpack(data), nil
case ChannelCount | 1<<8:
return ChannelCountValueUnpack(data), nil
case SupportAmount:
return SupportAmountKeyUnpack(data), nil
case SupportAmount | 1<<8:
return SupportAmountValueUnpack(data), nil
case BlockTXs:
return BlockTxsKeyUnpack(data), nil
case BlockTXs | 1<<8:
return BlockTxsValueUnpack(data), nil
}
return nil, fmt.Errorf("%s function for %v not implemented", functionName, firstByte)
}
func UnpackGenericKey(key []byte) (interface{}, error) {
func UnpackGenericKey(key []byte) (BaseKey, error) {
if len(key) == 0 {
return nil, fmt.Errorf("key length zero")
}
return generic(key, key[0], 0, "unpack key")
// Look up the prefix metadata, and use the registered function(s)
// to create and unpack key of appropriate type.
t, ok := tableRegistry[key[0]]
if !ok {
return nil, fmt.Errorf("unpack key function for %v not implemented", key[0])
}
if t.newKeyUnpack != nil {
return t.newKeyUnpack(key).(BaseKey), nil
}
return nil, fmt.Errorf("unpack key function for %v not implemented", key[0])
}
func UnpackGenericValue(key, value []byte) (interface{}, error) {
func UnpackGenericValue(key []byte, value []byte) (BaseValue, error) {
if len(key) == 0 {
return nil, fmt.Errorf("key length zero")
}
if len(value) == 0 {
return nil, fmt.Errorf("value length zero")
}
return generic(value, key[0], 1, "unpack value")
// Look up the prefix metadata, and use the registered function(s)
// to create and unpack value of appropriate type.
t, ok := tableRegistry[key[0]]
if !ok {
return nil, fmt.Errorf("unpack value function for %v not implemented", key[0])
}
if t.newValueUnpack != nil {
return t.newValueUnpack(value).(BaseValue), nil
}
return nil, fmt.Errorf("unpack key function for %v not implemented", key[0])
}
func PackPartialGenericKey(key BaseKey, fields int) ([]byte, error) {

7
go.mod
View file

@ -8,7 +8,7 @@ require (
github.com/ReneKroon/ttlcache/v2 v2.8.1
github.com/akamensky/argparse v1.2.2
github.com/lbryio/lbry.go/v3 v3.0.1-beta
github.com/linxGnu/grocksdb v1.6.42
github.com/linxGnu/grocksdb v1.7.0
github.com/olivere/elastic/v7 v7.0.24
github.com/prometheus/client_golang v1.11.0
github.com/prometheus/client_model v0.2.0
@ -19,7 +19,10 @@ require (
gopkg.in/karalabe/cookiejar.v1 v1.0.0-20141109175019-e1490cae028c
)
require golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b // indirect
require (
github.com/go-restruct/restruct v1.2.0-alpha // indirect
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b // indirect
)
require (
github.com/beorn7/perks v1.0.1 // indirect

4
go.sum
View file

@ -179,6 +179,8 @@ github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ozzo/ozzo-validation v3.6.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU=
github.com/go-restruct/restruct v1.2.0-alpha h1:2Lp474S/9660+SJjpVxoKuWX09JsXHSrdV7Nv3/gkvc=
github.com/go-restruct/restruct v1.2.0-alpha/go.mod h1:KqrpKpn4M8OLznErihXTGLlsXFGeLxHUrLRRI/1YjGk=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
@ -362,6 +364,8 @@ github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-b
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
github.com/linxGnu/grocksdb v1.6.42 h1:nJLoXFuzwBwQQQrXTUgRGRz1QRm7y8pR6CNV/gwrbqs=
github.com/linxGnu/grocksdb v1.6.42/go.mod h1:JcMMDBFaDNhRXFYcYXmgQwb/RarSld1PulTI7UzE+w0=
github.com/linxGnu/grocksdb v1.7.0 h1:UyFDykX0CUfxDN10cqlFho/rwt9K6KoDaLXL9Ej5z9g=
github.com/linxGnu/grocksdb v1.7.0/go.mod h1:JcMMDBFaDNhRXFYcYXmgQwb/RarSld1PulTI7UzE+w0=
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
github.com/lyoshenka/bencode v0.0.0-20180323155644-b7abd7672df5/go.mod h1:H0aPCWffGOaDcjkw1iB7W9DVLp6GXmfcJY/7YZCWPA4=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=