Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(lib/runtime): Implement trie_blake2_256_verify_proof host function #1920

Merged
merged 69 commits into from
Nov 9, 2021
Merged
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
7dd7c4b
feat: add verify_proof function
EclesioMeloJunior Oct 8, 2021
e6a3415
chore: adding helpers
EclesioMeloJunior Oct 8, 2021
cff7280
chore: build the tree from proof slice
EclesioMeloJunior Oct 11, 2021
2d816a4
chore: remove Nibbles custom type
EclesioMeloJunior Oct 11, 2021
6a4552a
Merge branch 'development' into eclesio/verify-proof
EclesioMeloJunior Oct 11, 2021
e6a02d8
chore: fix lint warns
EclesioMeloJunior Oct 11, 2021
71cb795
Merge branch 'eclesio/verify-proof' of github.com:ChainSafe/gossamer …
EclesioMeloJunior Oct 11, 2021
e92276b
chore: add benchmark tests
EclesioMeloJunior Oct 11, 2021
493dddb
chore: fix deepsource warns
EclesioMeloJunior Oct 12, 2021
c129de5
Merge branch 'development' into eclesio/verify-proof
EclesioMeloJunior Oct 13, 2021
4de95ec
Merge branch 'development' into eclesio/verify-proof
EclesioMeloJunior Oct 13, 2021
9455e13
chore: redefine LoadFromProof function
EclesioMeloJunior Oct 13, 2021
e8d4912
chore: remove logs
EclesioMeloJunior Oct 13, 2021
10dd296
chore: address comments
EclesioMeloJunior Oct 14, 2021
34b8dd0
Merge branch 'development' into eclesio/verify-proof
EclesioMeloJunior Oct 15, 2021
35abff5
Merge branch 'development' into eclesio/verify-proof
EclesioMeloJunior Oct 15, 2021
e3debb7
Merge branch 'development' into eclesio/verify-proof
EclesioMeloJunior Oct 18, 2021
8e4a1c1
chore: fix the condition to load the proof
EclesioMeloJunior Oct 18, 2021
76893e2
chore: address comments
EclesioMeloJunior Oct 18, 2021
7ee1756
Merge branch 'development' into eclesio/verify-proof
EclesioMeloJunior Oct 19, 2021
c07ab85
chore: create test cases
EclesioMeloJunior Oct 19, 2021
7f24a65
chore: improve find function
EclesioMeloJunior Oct 19, 2021
5a6d3f8
chore: use map to avoid duplicate keys
EclesioMeloJunior Oct 19, 2021
8bd6a33
chore: add test cases to duplicate values and nil values
EclesioMeloJunior Oct 19, 2021
f4081ba
chore: fix unused param lint error
EclesioMeloJunior Oct 19, 2021
d8a5e41
chore: use the shortest form
EclesioMeloJunior Oct 19, 2021
6465be8
chore: use set just for find dupl keys
EclesioMeloJunior Oct 19, 2021
6204ba4
Merge branch 'development' into eclesio/verify-proof
EclesioMeloJunior Oct 19, 2021
c0a88a9
chore: fixing test cases
EclesioMeloJunior Oct 19, 2021
8836808
Merge branch 'eclesio/verify-proof' into eclesio/runtime-verify-proof
EclesioMeloJunior Oct 19, 2021
0193014
wip: waiting w3f response about host fun
EclesioMeloJunior Oct 19, 2021
8406e94
chore: trie without rtm prefix
EclesioMeloJunior Oct 20, 2021
7fe1e94
feat: add ext_trie_blake2_256_verify_proof_version_1 host function
EclesioMeloJunior Oct 22, 2021
ee4a4a4
Merge branch 'development' into eclesio/runtime-verify-proof
EclesioMeloJunior Oct 22, 2021
3c92e65
Merge branch 'development' into eclesio/runtime-verify-proof
EclesioMeloJunior Oct 22, 2021
b23be22
chore: remove uneeded condition
EclesioMeloJunior Oct 22, 2021
cf034a0
Merge branch 'eclesio/runtime-verify-proof' of github.com:ChainSafe/g…
EclesioMeloJunior Oct 22, 2021
81ce63d
chore: put back test main
EclesioMeloJunior Oct 22, 2021
a426769
chore: fix tests
EclesioMeloJunior Oct 22, 2021
5c28b75
Merge branch 'development' into eclesio/runtime-verify-proof
EclesioMeloJunior Oct 25, 2021
fd00ea1
chore: group param to one type
EclesioMeloJunior Oct 25, 2021
5a31f8e
chore: improve verify proof condition and simplify errors comments
EclesioMeloJunior Oct 25, 2021
d006213
Merge branch 'development' into eclesio/runtime-verify-proof
EclesioMeloJunior Oct 25, 2021
05c28d0
Merge branch 'development' into eclesio/runtime-verify-proof
EclesioMeloJunior Oct 25, 2021
020b04c
Merge branch 'development' into eclesio/runtime-verify-proof
EclesioMeloJunior Oct 26, 2021
ec95003
Merge branch 'development' into eclesio/runtime-verify-proof
EclesioMeloJunior Oct 27, 2021
df5c7db
Merge branch 'development' into eclesio/runtime-verify-proof
noot Oct 27, 2021
d16881e
Merge branch 'development' into eclesio/runtime-verify-proof
noot Oct 27, 2021
c4eb31f
Merge branch 'development' into eclesio/runtime-verify-proof
noot Oct 27, 2021
de632e8
Merge branch 'development' into eclesio/runtime-verify-proof
EclesioMeloJunior Oct 28, 2021
b879c61
Merge branch 'development' into eclesio/runtime-verify-proof
noot Oct 28, 2021
be909f2
Merge branch 'development' into eclesio/runtime-verify-proof
EclesioMeloJunior Oct 29, 2021
c988651
Merge branch 'development' into eclesio/runtime-verify-proof
EclesioMeloJunior Oct 29, 2021
321dcb6
Merge branch 'development' into eclesio/runtime-verify-proof
EclesioMeloJunior Oct 29, 2021
2960125
chore: remove tmp dir after test finish
EclesioMeloJunior Nov 1, 2021
3cb4bf4
chore: update tests
EclesioMeloJunior Nov 1, 2021
371ce96
chore: use map on tests
EclesioMeloJunior Nov 1, 2021
76e8c44
chore: fix lint warns
EclesioMeloJunior Nov 1, 2021
a49d819
Merge branch 'development' into eclesio/runtime-verify-proof
EclesioMeloJunior Nov 1, 2021
53ed87b
chore: update the polkadot-runtime commit
EclesioMeloJunior Nov 1, 2021
3cbe155
Merge branch 'eclesio/runtime-verify-proof' of github.com:ChainSafe/g…
EclesioMeloJunior Nov 1, 2021
b2c1d13
chore: remove comment, add parallel to tests
EclesioMeloJunior Nov 3, 2021
8f29223
chore: fix deepsource warns
EclesioMeloJunior Nov 5, 2021
92828de
Merge branch 'development' into eclesio/runtime-verify-proof
EclesioMeloJunior Nov 5, 2021
54f98cb
chore: create a client rather than the default client
EclesioMeloJunior Nov 5, 2021
b46a01a
chore: update verify-proof trie root param to u32
EclesioMeloJunior Nov 8, 2021
c684da5
chore: change host api commit
EclesioMeloJunior Nov 8, 2021
245cb35
Merge branch 'development' into eclesio/runtime-verify-proof
EclesioMeloJunior Nov 9, 2021
2ada338
using ioutil.ReadAll
EclesioMeloJunior Nov 9, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 29 additions & 4 deletions lib/runtime/wasmer/imports.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ package wasmer
//
// extern int32_t ext_trie_blake2_256_root_version_1(void *context, int64_t a);
// extern int32_t ext_trie_blake2_256_ordered_root_version_1(void *context, int64_t a);
// extern int32_t ext_trie_blake2_256_verify_proof_version_1(void *context, int32_t a, int64_t b, int64_t c, int64_t d);
// extern int32_t ext_trie_blake2_256_verify_proof_version_1(void *context, int64_t a, int64_t b, int64_t c, int64_t d);
//
// extern int64_t ext_misc_runtime_version_version_1(void *context, int64_t a);
// extern void ext_misc_print_hex_version_1(void *context, int64_t a);
Expand Down Expand Up @@ -899,10 +899,35 @@ func ext_trie_blake2_256_ordered_root_version_1(context unsafe.Pointer, dataSpan
}

//export ext_trie_blake2_256_verify_proof_version_1
func ext_trie_blake2_256_verify_proof_version_1(context unsafe.Pointer, a C.int32_t, b, c, d C.int64_t) C.int32_t {
func ext_trie_blake2_256_verify_proof_version_1(context unsafe.Pointer, rootSpan, proofSpan, keySpan, valueSpan C.int64_t) C.int32_t {
logger.Debug("[ext_trie_blake2_256_verify_proof_version_1] executing...")
logger.Warn("[ext_trie_blake2_256_verify_proof_version_1] unimplemented")
return 0

instanceContext := wasm.IntoInstanceContext(context)

toDecProofs := asMemorySlice(instanceContext, proofSpan)
var decProofs [][]byte
err := scale.Unmarshal(toDecProofs, &decProofs)
if err != nil {
logger.Error("[ext_trie_blake2_256_verify_proof_version_1]", "error", err)
return C.int32_t(0)
}

key := asMemorySlice(instanceContext, keySpan)
value := asMemorySlice(instanceContext, valueSpan)
trieRoot := asMemorySlice(instanceContext, rootSpan)

exists, err := trie.VerifyProof(decProofs, trieRoot, []trie.Pair{{Key: key, Value: value}})
if err != nil {
logger.Error("[ext_trie_blake2_256_verify_proof_version_1]", "error", err)
return C.int32_t(0)
}

var result C.int32_t = 0
if exists {
result = 1
}

return result
}

//export ext_misc_print_hex_version_1
Expand Down
92 changes: 92 additions & 0 deletions lib/runtime/wasmer/imports_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ package wasmer
import (
"bytes"
"encoding/binary"
"io/ioutil"
"os"
"sort"
"testing"

"github.com/ChainSafe/chaindb"
"github.com/ChainSafe/gossamer/lib/common"
"github.com/ChainSafe/gossamer/lib/common/optional"
"github.com/ChainSafe/gossamer/lib/common/types"
Expand Down Expand Up @@ -1506,3 +1508,93 @@ func Test_ext_trie_blake2_256_root_version_1(t *testing.T) {
expected := tt.MustHash()
require.Equal(t, expected[:], hash)
}

func Test_ext_trie_blake2_256_verify_proof_version_1(t *testing.T) {
t.Parallel()

tmp, err := ioutil.TempDir("", "*-test-trie")
qdm12 marked this conversation as resolved.
Show resolved Hide resolved
require.NoError(t, err)

memdb, err := chaindb.NewBadgerDB(&chaindb.Config{
InMemory: true,
DataDir: tmp,
})
require.NoError(t, err)

otherTrie := trie.NewEmptyTrie()
otherTrie.Put([]byte("simple"), []byte("cat"))

otherHash, err := otherTrie.Hash()
require.NoError(t, err)

tr := trie.NewEmptyTrie()
tr.Put([]byte("do"), []byte("verb"))
tr.Put([]byte("domain"), []byte("website"))
tr.Put([]byte("other"), []byte("random"))
tr.Put([]byte("otherwise"), []byte("randomstuff"))
tr.Put([]byte("cat"), []byte("another animal"))

err = tr.Store(memdb)
require.NoError(t, err)

hash, err := tr.Hash()
require.NoError(t, err)

keys := [][]byte{
[]byte("do"),
[]byte("domain"),
[]byte("other"),
[]byte("otherwise"),
[]byte("cat"),
}

root := hash.ToBytes()
otherRoot := otherHash.ToBytes()

proof, err := trie.GenerateProof(root, keys, memdb)
require.NoError(t, err)

testcases := []struct {
root, key, value []byte
proof [][]byte
expect bool
}{
{root: root, key: []byte("do"), proof: proof, value: []byte("verb"), expect: true},
{root: []byte{}, key: []byte("do"), proof: proof, value: []byte("verb"), expect: false},
{root: otherRoot, key: []byte("do"), proof: proof, value: []byte("verb"), expect: false},
{root: root, key: []byte("do"), proof: proof, value: nil, expect: true},
{root: root, key: []byte("unknow"), proof: proof, value: nil, expect: false},
{root: root, key: []byte("unknow"), proof: proof, value: []byte("unknow"), expect: false},
{root: root, key: []byte("do"), proof: [][]byte{}, value: nil, expect: false},
}

inst := NewTestInstance(t, runtime.HOST_API_TEST_RUNTIME)

for _, testcase := range testcases {
hashEnc, err := scale.Marshal(testcase.root)
qdm12 marked this conversation as resolved.
Show resolved Hide resolved
require.NoError(t, err)

args := []byte{}
args = append(args, hashEnc...)

encProof, err := scale.Marshal(testcase.proof)
require.NoError(t, err)
args = append(args, encProof...)

keyEnc, err := scale.Marshal(testcase.key)
require.NoError(t, err)
args = append(args, keyEnc...)

valueEnc, err := scale.Marshal(testcase.value)
require.NoError(t, err)
args = append(args, valueEnc...)

res, err := inst.Exec("rtm_ext_trie_blake2_256_verify_proof_version_1", args)
require.NoError(t, err)

var got bool
err = scale.Unmarshal(res, &got)
require.NoError(t, err)
require.Equal(t, testcase.expect, got)
}
}
18 changes: 11 additions & 7 deletions lib/trie/proof.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,23 @@ import (
)

var (
// ErrEmptyTrieRoot occurs when trying to craft a prove with an empty trie root
// ErrEmptyTrieRoot ...
ErrEmptyTrieRoot = errors.New("provided trie must have a root")

// ErrValueNotFound indicates that a returned verify proof value doesnt match with the expected value on items array
// ErrValueNotFound ...
ErrValueNotFound = errors.New("expected value not found in the trie")

// ErrDuplicateKeys not allowed to verify proof with duplicate keys
// ErrKeyNotFound ...
ErrKeyNotFound = errors.New("expected key not found in the trie")

// ErrDuplicateKeys ...
ErrDuplicateKeys = errors.New("duplicate keys on verify proof")

// ErrLoadFromProof occurs when there are problems with the proof slice while building the partial proof trie
// ErrLoadFromProof ...
qdm12 marked this conversation as resolved.
Show resolved Hide resolved
ErrLoadFromProof = errors.New("failed to build the proof trie")
)

// GenerateProof receive the keys to proof, the trie root and a reference to database
// will
func GenerateProof(root []byte, keys [][]byte, db chaindb.Database) ([][]byte, error) {
trackedProofs := make(map[string][]byte)

Expand Down Expand Up @@ -100,9 +102,11 @@ func VerifyProof(proof [][]byte, root []byte, items []Pair) (bool, error) {

for _, item := range items {
recValue := proofTrie.Get(item.Key)

if recValue == nil {
return false, ErrKeyNotFound
}
// here we need to compare value only if the caller pass the value
if item.Value != nil && !bytes.Equal(item.Value, recValue) {
if len(item.Value) > 0 && !bytes.Equal(item.Value, recValue) {
EclesioMeloJunior marked this conversation as resolved.
Show resolved Hide resolved
return false, ErrValueNotFound
}
}
Expand Down