private string GetProof(MPTTrie <StorageKey, StorageItem> trie, int contract_id, byte[] key) { StorageKey skey = new StorageKey { Id = contract_id, Key = key, }; var result = trie.TryGetProof(skey, out var proof); if (!result) { throw new RpcException(-100, "Unknown value"); } using MemoryStream ms = new(); using BinaryWriter writer = new(ms, Utility.StrictUTF8); writer.WriteVarBytes(skey.ToArray()); writer.WriteVarInt(proof.Count); foreach (var item in proof) { writer.WriteVarBytes(item); } writer.Flush(); return(Convert.ToBase64String(ms.ToArray())); }
public void TestVerifyProof() { var mpt = new MPTTrie <TestKey, TestValue>(mptdb.GetSnapshot(), root.Hash); var result = mpt.TryGetProof("ac01".HexToBytes(), out var proof); Assert.IsTrue(result); TestValue value = MPTTrie <TestKey, TestValue> .VerifyProof(root.Hash, "ac01".HexToBytes(), proof); Assert.IsNotNull(value); Assert.AreEqual(value.ToString(), "abcd"); }
public void TestGetProof() { var b = MPTNode.NewBranch(); var r = MPTNode.NewExtension("0a0c".HexToBytes(), b); var v1 = MPTNode.NewLeaf("abcd".HexToBytes()); //key=ac01 var v2 = MPTNode.NewLeaf("2222".HexToBytes()); //key=ac var v3 = MPTNode.NewLeaf(Encoding.ASCII.GetBytes("existing")); //key=acae var v4 = MPTNode.NewLeaf(Encoding.ASCII.GetBytes("missing")); var h3 = MPTNode.NewHash(v3.Hash); var e1 = MPTNode.NewExtension(new byte[] { 0x01 }, v1); var e3 = MPTNode.NewExtension(new byte[] { 0x0e }, h3); var e4 = MPTNode.NewExtension(new byte[] { 0x01 }, v4); b.Children[0] = e1; b.Children[10] = e3; b.Children[16] = v2; b.Children[15] = MPTNode.NewHash(e4.Hash); var mpt = new MPTTrie <TestKey, TestValue>(mptdb.GetSnapshot(), r.Hash); Assert.AreEqual(r.Hash.ToString(), mpt.Root.Hash.ToString()); var result = mpt.TryGetProof("ac01".HexToBytes(), out var proof); Assert.IsTrue(result); Assert.AreEqual(4, proof.Count); Assert.IsTrue(proof.Contains(b.ToArrayWithoutReference())); Assert.IsTrue(proof.Contains(r.ToArrayWithoutReference())); Assert.IsTrue(proof.Contains(e1.ToArrayWithoutReference())); Assert.IsTrue(proof.Contains(v1.ToArrayWithoutReference())); result = mpt.TryGetProof("ac".HexToBytes(), out proof); Assert.AreEqual(3, proof.Count); result = mpt.TryGetProof("ac10".HexToBytes(), out proof); Assert.IsFalse(result); result = mpt.TryGetProof("acae".HexToBytes(), out proof); Assert.AreEqual(4, proof.Count); Assert.ThrowsException <ArgumentException>(() => mpt.TryGetProof(Array.Empty <byte>(), out proof)); result = mpt.TryGetProof("ac0100".HexToBytes(), out proof); Assert.IsFalse(result); Assert.ThrowsException <InvalidOperationException>(() => mpt.TryGetProof("acf1".HexToBytes(), out var proof)); }
public void TestEmptyValueIssue633() { var key = "01".HexToBytes(); var snapshot = new TestSnapshot(); var mpt = new MPTTrie <TestKey, TestValue>(snapshot, null); mpt.Put(key, Array.Empty <byte>()); var val = mpt["01".HexToBytes()]; Assert.IsNotNull(val); Assert.AreEqual(0, val.Size); var r = mpt.TryGetProof(key, out var proof); Assert.IsTrue(r); val = MPTTrie <TestKey, TestValue> .VerifyProof(mpt.Root.Hash, key, proof); Assert.IsNotNull(val); Assert.AreEqual(0, val.Size); }
public void TestSplitKey() { var store = new MemoryStore(); var snapshot = store.GetSnapshot(); var mpt1 = new MPTTrie <TestKey, TestValue>(snapshot, null); mpt1.Put(new byte[] { 0xab, 0xcd }, new byte[] { 0x01 }); mpt1.Put(new byte[] { 0xab }, new byte[] { 0x02 }); var r = mpt1.TryGetProof(new byte[] { 0xab, 0xcd }, out var set1); Assert.IsTrue(r); Assert.AreEqual(4, set1.Count); var mpt2 = new MPTTrie <TestKey, TestValue>(snapshot, null); mpt2.Put(new byte[] { 0xab }, new byte[] { 0x02 }); mpt2.Put(new byte[] { 0xab, 0xcd }, new byte[] { 0x01 }); r = mpt2.TryGetProof(new byte[] { 0xab, 0xcd }, out var set2); Assert.IsTrue(r); Assert.AreEqual(4, set2.Count); Assert.AreEqual(mpt1.Root.Hash, mpt2.Root.Hash); }