mpt: implement NEO storage key conversion
This commit is contained in:
parent
103c45850a
commit
314430be1d
3 changed files with 68 additions and 29 deletions
|
@ -8,6 +8,7 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/mpt"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
)
|
||||
|
@ -33,35 +34,7 @@ func toNeoStorageKey(key []byte) []byte {
|
|||
if len(key) < util.Uint160Size {
|
||||
panic("invalid key in storage")
|
||||
}
|
||||
|
||||
var nkey []byte
|
||||
for i := util.Uint160Size - 1; i >= 0; i-- {
|
||||
nkey = append(nkey, key[i])
|
||||
}
|
||||
|
||||
key = key[util.Uint160Size:]
|
||||
|
||||
index := 0
|
||||
remain := len(key)
|
||||
for remain >= 16 {
|
||||
nkey = append(nkey, key[index:index+16]...)
|
||||
nkey = append(nkey, 0)
|
||||
index += 16
|
||||
remain -= 16
|
||||
}
|
||||
|
||||
if remain > 0 {
|
||||
nkey = append(nkey, key[index:]...)
|
||||
}
|
||||
|
||||
padding := 16 - remain
|
||||
for i := 0; i < padding; i++ {
|
||||
nkey = append(nkey, 0)
|
||||
}
|
||||
|
||||
nkey = append(nkey, byte(padding))
|
||||
|
||||
return nkey
|
||||
return mpt.ToNeoStorageKey(key)
|
||||
}
|
||||
|
||||
// batchToMap converts batch to a map so that JSON is compatible
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package mpt
|
||||
|
||||
import "github.com/nspcc-dev/neo-go/pkg/util"
|
||||
|
||||
// lcp returns longest common prefix of a and b.
|
||||
// Note: it does no allocations.
|
||||
func lcp(a, b []byte) []byte {
|
||||
|
@ -33,3 +35,37 @@ func toNibbles(path []byte) []byte {
|
|||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// ToNeoStorageKey converts storage key to C# neo node's format.
|
||||
// Key is expected to be at least 20 bytes in length.
|
||||
// our format: script hash in BE + key
|
||||
// neo format: script hash in LE + key with 0 between every 16 bytes, padded to len 16.
|
||||
func ToNeoStorageKey(key []byte) []byte {
|
||||
const groupSize = 16
|
||||
|
||||
var nkey []byte
|
||||
for i := util.Uint160Size - 1; i >= 0; i-- {
|
||||
nkey = append(nkey, key[i])
|
||||
}
|
||||
|
||||
key = key[util.Uint160Size:]
|
||||
|
||||
index := 0
|
||||
remain := len(key)
|
||||
for remain >= groupSize {
|
||||
nkey = append(nkey, key[index:index+groupSize]...)
|
||||
nkey = append(nkey, 0)
|
||||
index += groupSize
|
||||
remain -= groupSize
|
||||
}
|
||||
|
||||
if remain > 0 {
|
||||
nkey = append(nkey, key[index:]...)
|
||||
}
|
||||
|
||||
padding := groupSize - remain
|
||||
for i := 0; i < padding; i++ {
|
||||
nkey = append(nkey, 0)
|
||||
}
|
||||
return append(nkey, byte(padding))
|
||||
}
|
||||
|
|
30
pkg/core/mpt/helpers_test.go
Normal file
30
pkg/core/mpt/helpers_test.go
Normal file
|
@ -0,0 +1,30 @@
|
|||
package mpt
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestToNeoStorageKey(t *testing.T) {
|
||||
testCases := []struct{ key, res string }{
|
||||
{
|
||||
"0102030405060708091011121314151617181920",
|
||||
"20191817161514131211100908070605040302010000000000000000000000000000000010",
|
||||
},
|
||||
{
|
||||
"010203040506070809101112131415161718192021222324",
|
||||
"2019181716151413121110090807060504030201212223240000000000000000000000000c",
|
||||
},
|
||||
{
|
||||
"0102030405060708091011121314151617181920212223242526272829303132333435363738",
|
||||
"20191817161514131211100908070605040302012122232425262728293031323334353600373800000000000000000000000000000e",
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
key, _ := hex.DecodeString(tc.key)
|
||||
res, _ := hex.DecodeString(tc.res)
|
||||
require.Equal(t, res, ToNeoStorageKey(key))
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue