From 40ddcbf3f2b7aa01eba611f71caafbbb388f27ad Mon Sep 17 00:00:00 2001 From: p4u Date: Sun, 21 Mar 2021 19:10:15 +0100 Subject: [PATCH] initial commit - Code copied from https://github.com/aergoio/aergo - Make it a go module - Added Walk and GetWithRoot new methods - Create custom hasher based on blake256 Signed-off-by: p4u --- README.md | 220 +++++++++++ go.mod | 9 + go.sum | 225 +++++++++++ hash.go | 18 + pictures/batch.png | Bin 0 -> 69429 bytes pictures/deleted.png | Bin 0 -> 87078 bytes pictures/mod.png | Bin 0 -> 76922 bytes pictures/smt.png | Bin 0 -> 70004 bytes trie.go | 585 ++++++++++++++++++++++++++++ trie_cache.go | 63 +++ trie_merkle_proof.go | 210 ++++++++++ trie_revert.go | 178 +++++++++ trie_test.go | 883 +++++++++++++++++++++++++++++++++++++++++++ trie_tools.go | 273 +++++++++++++ util.go | 42 ++ 15 files changed, 2706 insertions(+) create mode 100644 README.md create mode 100644 go.mod create mode 100644 go.sum create mode 100644 hash.go create mode 100644 pictures/batch.png create mode 100644 pictures/deleted.png create mode 100644 pictures/mod.png create mode 100644 pictures/smt.png create mode 100644 trie.go create mode 100644 trie_cache.go create mode 100644 trie_merkle_proof.go create mode 100644 trie_revert.go create mode 100644 trie_test.go create mode 100644 trie_tools.go create mode 100644 util.go diff --git a/README.md b/README.md new file mode 100644 index 0000000..432f330 --- /dev/null +++ b/README.md @@ -0,0 +1,220 @@ +# AERGO StateTrie + +## Features + +* Efficient Merkle proof verification (binary tree structure) +* Efficient database reads and storage through node batching +* Reduced data storage (leaf nodes for subtrees contain 1 key) +* Reduced hash computation (leaf nodes for subtrees contain 1 key) +* Simultaneous update of multiple keys with goroutines + +Aergo Trie is a modified version of a Sparse Merkle Tree which stores values at the highest subtree containing only one key. +The benefit achieved from this is that, on average, in a tree containing N random keys, just log(N) hashes are required to update a key in the tree. Therefore the trie height is on average log(N), making inclusion and non-inclusion proofs shorter. + + +## Standard Sparse Merkle Tree + +![smt](pictures/smt.png) + +*Figure 1. An example sparse Merkle tree of height=4 (4-bit keys) containing 3 keys. The 3 keys are shown in red and blue. Default nodes are shown in green. Non-default nodes are shown in purple.* + +Medium article about the Standard SMT : [https://medium.com/@ouvrard.pierre.alain/sparse-merkle-tree-86e6e2fc26da](https://medium.com/@ouvrard.pierre.alain/sparse-merkle-tree-86e6e2fc26da) + +Implementation of the standard SMT : [https://github.com/aergoio/SMT](https://github.com/aergoio/SMT) + +## Aergo Trie +### Modification of the Sparse Merkle Tree +To reduce the number of hashing operations necessary to update a key in a tree, we created leaf nodes. A leaf node is stored at the highest subtree that contains only 1 non-default key. So, the hashing of the tree starts from the height of leaf nodes instead of height 0. If the tree contains N random keys, then on average, leaf nodes will be created around height = log(N). + +Another benefit of the Aergo Trie is that Default Hashes are no longer necessary. We add the following property to the hash function : H(0,0) = 0. Looking at the example below, **D1 = Hash(D0,D0) = Hash(byte(0),byte(0)) = byte(0) = D2 =...= D256**. + +![mod](pictures/mod.png) +*Figure 2. H3 was the highest subtree containing only one key: the red one. So, Value will take its place in the modified sparse Merkle tree.* + +### Merkle Proofs +Using a binary tree gives us very simple and easy-to-use Merkle proofs. +On the diagram above, the Merkle proof of the red key is composed of the node with a red circle: [h3] +In case of the standard SMT that proof would have been [D0, D1, D2, h3] + +### Compressed Merkle proofs +Like in the standard sparse Merkle tree, Merkle proofs can also be compressed. We can use a bitmap and set a bit for every index that is not default in the proof. The proof that the blue LeafNode1 is included in the tree is: [LeafNode2, D1, D2, LeafNode]. This proof can be compressed to 1001[LeafNode2, LeafNode]. The verifier of the compressed Merkle proof should know to use D1 to compute h2 because the second index of the bitmap is 0, and D2 for the third proof element, etc. + +### Proofs of non-inclusion +There are 2 ways to prove that a key is not included in the tree : +- prove that the Leaf node of another key is included in the tree and is on the path of the non-included key. +- prove that a default node (byte(0)) is included in the tree and is on the path of the non-included key. + +For example, a proof that key=0000 is not included in the tree is a proof that LeafNode is on the path of key and is included in the tree. A proof that key=1111 is not included in the tree is a proof that D2 is on the path of the key and is included in the tree. + +### Deleting from the tree +When a leaf is removed from the tree, special care is taken by the Update() function to keep leaf nodes at the highest subtree containing only 1 key. Otherwise, if a node has a different position in the tree, the resulting trie root would be different even though keys and values are the same. + +So, when a key is deleted, Update() checks if it’s sibling is also a leaf node and moves it up until the highest subtree root containing only that non-default key. + +![deleted](pictures/deleted.png) +*Figure 3. The same tree after deleting a blue key : LeafNode1 moves up to the highest subtree containing one key* + +### Node batching +When storing each node as a root with 2 children, the quantity of nodes to store grows very quickly and a bottleneck happens due to multiple threads loading nodes from memory. A hex Merkle tree would solve this problem as each key has 16 children and a smaller height of 64 (256/4), though as we said earlier, we need the tree to be binary. We can achieve the same features of a hex tree by using node batching. + +Instead of storing 2 children for one node, we store the subtree of height 4 for that node. A tree of height 4 has 16 leaves at height 0 (like hex). So, the value of a node is an array containing all the nodes of the 4-bit tree. The children of a node at index i in the tree can be found at index 2*i+1 and 2*i+2. + +A node is encoded as follows: + +``` +{ Root : [ [ byte(0/1) to flag a leaf node ], 3–0, 3–1, 2–0, 2–1, 2–2, 2–3, 1–0, 1–1, 1–2, 1–3, 1–4, 1–5, 1–6, 1–7, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f ] } +``` + +For example, to get the children of node 3–0 at index id=1 in the array, we can access the left child 2–0 at index (2 * id + 1) = index 3 and the right child 2–1 at index (2 * id + 2) = index 4. + +To each node, we append a byte flag to recognize the leaf nodes. Since the nature of Root is not know ahead of time, the byte flag is stored at the first index of the nodes array. + +![batch](pictures/batch.png) +*Figure 4. A visual representation of node batching. The first batch is blue, and all 16 leaves of a batch are roots to other batches (green). A batch contains 30 nodes.* + +The example from figure 2 will be encoded as follows : +``` +{Root : [ [byte(0)], LeafNodeHash, h3, LeafNodeKey, LeafNodeValue, h2, D2=nil, nil, nil, nil, nil, h1, D1=nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, LeafNode1Hash, LeafNode2Hash, nil, nil, nil, nil, nil, nil ]} +``` +Where LeafNodeHash = Hash(key, value, height) + +To store the batch in the database, it is serialized with a bitmap which allows us to store only the non default nodes. +The bitmap is 4 bytes = 32 bits. The first 30 bits are for the batch nodes, the 31st bit is the flag to make a shortcut batch (a batch that only contains a key and a value at 3-0 and 3-1), the 32nd bit is not used. + +The figure 2 example after serialization: +``` +11111000001000000000001100000010 [LeafNodeHash][h3][LeafNodeKey][LeafNodeValue][h2][h1][LeafNode1Hash][LeafNode2Hash] +``` + +Node batching has two benefits : reduced number of database reads and concurrent update of the height 4 subtree without the need for a lock. + +## Usage + +- NewTrie + +```go +func NewTrie(root []byte, hash func(data …[]byte) []byte, store db.DB) *Trie { +``` + +When creating an empty tree, set root to nil. A nil root means that it is equal to the default value of its height. Use a custom hash function or use the Hasher in utils and specify a database if you plan to commit nodes. + + +- Update + +```go +func (s *Trie) Update(keys, values [][]byte) ([]byte, error) { +``` + +‘keys [][]byte’ is a sorted array of keys, ‘values [][]byte’ contains the matching values of keys. + +Update will recursively go down the tree and split the keys and values according to the side of the tree they belong to: multiple parts of the tree can be simultaneously updated. + +If update is called several times before Commit, only the last state is committed. + +- AtomicUpdate + +```go +func (s *Trie) AtomicUpdate(keys, values [][]byte) ([]byte, error) { +``` + +AtomicUpdate updates the tree with sorted keys and values just like Update. But unlike update, if AtomicUpdate is called several times before Commit, all the intermediate states from AtomicUpdate calls will be recorded. This can be useful when authenticating the state of each block, but not committing to the database right away. + +- Get + +```go +func (s *Trie) Get(key []byte) ([]byte, error) { +``` + +Get the value of a key stored in the tree, if a key is default, i.e., not stored, return nil. + +- Commit + +```go +func (s *Trie) Commit() error { +``` + +Commit the updated nodes to the database. When update is called, the new nodes are stored in smt.db.updatedNodes. Commit then stores to disk. + +- StageUpdates + +```go +func (s *Trie) StageUpdates(txn *db.Transaction) { +``` +StageUpdates loads the updated nodes into the given database transaction. It enables the commit of the trie with an external database transaction. + +- Stash + +```go +func (s *Trie) Stash(rollbackCache bool) error { +``` + +Use the Stash function to revert the update without committing. + +- Revert + +```go +func (s *SMT) Revert(toOldRoot []byte) error { +``` + +When revert is called, the trees to rollback (between the current tree and toOldRoot) are deleted from the database. + +- MerkleProof + +```go +func (s *Trie) MerkleProof(key []byte) ([][]byte, bool, []byte, []byte, error) { +``` + +MerkleProof creates a Merkle proof of inclusion/non-inclusion of the key. The Merkle proof is an array of hashes. + +If the key is not included, MerkleProof will return false along with the proof leaf on the path of the key. + +- MerkleProofPast + +```go +func (s *Trie) MerkleProofPast(key []byte, root []byte) ([][]byte, bool, []byte, []byte, error) { +``` + +MerkleProofPast creates a Merkle proof of inclusion/non-inclusion of the key at a given trie root. This is used to query state at a different block than the last one. + +- MerkleProofCompressed + +```go +func (s *Trie) MerkleProofCompressed(key []byte) ([]byte, [][]byte, uint64, bool, []byte, []byte, error) { +``` + +MerkleProofCompressed creates the same Merkle proof as MerkleProof but compressed using a bitmap + +- VerifyInclusion + +```go +func (s *Trie) VerifyInclusion(ap [][]byte, key, value []byte) bool { +``` + +Verifies that the key-value pair is included in the tree at the current Root. + +- VerifyNonInclusion + +```go +func (s *Trie) VerifyNonInclusion(ap [][]byte, key, value, proofKey []byte) bool { +``` + +Verify a proof of non-inclusion. Verifies that a leaf(proofKey, proofValue, height) of empty subtree is on the path of the non-included key. + +- VerifyInclusionC + +```go +func (s *Trie) VerifyInclusionC(bitmap, key, value []byte, ap [][]byte, length int) bool { +``` + +Verifies a compressed proof of inclusion. ‘length’ is the height of the leaf key-value being verified. + +- VerifyNonInclusionC + +```go +func (s *Trie) VerifyNonInclusionC(ap [][]byte, length int, bitmap, key, value, proofKey []byte) bool { +``` + +Verify a compressed proof of non-inclusion. Verifies that a leaf (proofKey, proofValue, height) of empty subtree is on the path of the non-included key. + + +For more information about the Aergo StateTrie : [https://medium.com/aergo/releasing-statetrie-a-hash-tree-built-for-high-performance-interoperability-6ce0406b12ae](https://medium.com/aergo/releasing-statetrie-a-hash-tree-built-for-high-performance-interoperability-6ce0406b12ae) diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..30ed0d3 --- /dev/null +++ b/go.mod @@ -0,0 +1,9 @@ +module github.com/p4u/asmt + +go 1.16 + +require ( + github.com/aergoio/aergo-lib v1.0.2 + github.com/spf13/afero v1.2.1 // indirect + golang.org/x/crypto v0.0.0-20210317152858-513c2a44f670 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..0508d3c --- /dev/null +++ b/go.sum @@ -0,0 +1,225 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M= +github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/aergoio/aergo-lib v1.0.2 h1:Zp0hGS+SCdURCgAsXAjXQedq5JBSrslZWIkXXaM84sc= +github.com/aergoio/aergo-lib v1.0.2/go.mod h1:hxL0B2opPLGkc1e0hdxiQNM5shqrxSrFA7cj1UJ1/m4= +github.com/aergoio/badger v1.6.0-gcfix h1:VUUwHyUpjfA7WbEqNsjH69R2mgNlSqhLN3xe3UWOQmQ= +github.com/aergoio/badger v1.6.0-gcfix/go.mod h1:GwmHJc3SDzMZotppuSPcMT1HY9+SYt7nlDP2QevCbx4= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= +github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.8-0.20180830220226-ccc981bf8038 h1:j2xrf/etQ7t7yE6yPggWVr8GLKpISYIwxxLiHdOCHis= +github.com/fsnotify/fsnotify v1.4.8-0.20180830220226-ccc981bf8038/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/guptarohit/asciigraph v0.4.1 h1:YHmCMN8VH81BIUIgTg2Fs3B52QDxNZw2RQ6j5pGoSxo= +github.com/guptarohit/asciigraph v0.4.1/go.mod h1:9fYEfE5IGJGxlP1B+w8wHFy7sNZMhPtn59f0RLtpRFM= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/hcl v1.0.1-0.20180906183839-65a6292f0157 h1:uyodBE3xDz0ynKs1tLBU26wOQoEkAqqiY18DbZ+FZrA= +github.com/hashicorp/hcl v1.0.1-0.20180906183839-65a6292f0157/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3 h1:OoxbjfXVZyod1fmWYhI7SEyaD8B00ynP3T+D5GiyHOY= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.2.1-0.20180930205832-81a861c69d25 h1:a49/z+9Z5t53bD9NMajAJMe5tN0Kcz5Y6bvFxD/TPwo= +github.com/pelletier/go-toml v1.2.1-0.20180930205832-81a861c69d25/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.16.1-0.20191111091419-e709c5d91e35 h1:GSGuq6eajGCJ6fQFt4I8pT1lbTAtl3XdXOsIZ3qYQQI= +github.com/rs/zerolog v1.16.1-0.20191111091419-e709c5d91e35/go.mod h1:9nvC1axdVrAHcu/s9taAVfBuIdTZLVQmKQyvrUjF5+I= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.1 h1:qgMbHoJbPbw579P+1zVY+6n4nIFuIchaIjzZ/I/Yq8M= +github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.5.0 h1:GpsTwfsQ27oS/Aha/6d1oD7tpKIqWnOA6tgOX9HHkt4= +github.com/spf13/viper v1.5.0/go.mod h1:AkYRkVJF8TkSG/xet6PzXX+l39KhhXa2pdqVSxnTcn4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210317152858-513c2a44f670 h1:gzMM0EjIYiRmJI3+jBdFuoynZlpxa2JQZsolKu09BXo= +golang.org/x/crypto v0.0.0-20210317152858-513c2a44f670/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20181030141323-6f44c5a2ea40/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/hash.go b/hash.go new file mode 100644 index 0000000..55d7b80 --- /dev/null +++ b/hash.go @@ -0,0 +1,18 @@ +package trie + +import ( + "golang.org/x/crypto/blake2b" +) + +// Hasher exports default hash function for trie +var Hasher = func(data ...[]byte) []byte { + hasher, err := blake2b.New256(nil) + if err != nil { + panic(err) + } + //hasher := sha256.New() + for i := 0; i < len(data); i++ { + hasher.Write(data[i]) + } + return hasher.Sum(nil) +} diff --git a/pictures/batch.png b/pictures/batch.png new file mode 100644 index 0000000000000000000000000000000000000000..babb22d96b3a394c8317a79ee46b2994088c0497 GIT binary patch literal 69429 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 z¨qs4VCgEUxTPaUJv*3u1&4_q*hY4eiwNs)Feyn(6G74Sr`Zw`gP~m?KO3dNDpr z<#9q!MoS>Y%(hKs(TpYaS@ad3JA>flpt;!5+A57CfPyN<ao;#2BE1c?POWDf zPp4`ep;0YLigst8RR|ZCmR#n)qMNc1Nt`V0EtMDuy)-=UxM6T|u;wCx_d*~w{o(d5 zydm#lM&b47{x6U21g6|9k3>oX@<+BZ;Uhg?^mk-p@IA5@suOYVoIr^; zh{$RLhx44Mn-5$BJ4Sx+X4}=bGW;&@KI|y&e3;wnV!Ncdq@Khl6Xj-odOG`;&t;`* zqj&R@&@sILN5!A#*sll>=8x}3(t}f`zUcvT*dnNeC8^P?)DDl!q+6}bbSF0}E9l9` z^Qp%24BN#5^@W^zew!8R;M(V#E7>DNu_T*G67sjAH_P#o;0aUinTEK~J`k)ns74yr zg!D7*I4!}bw$-r#?8$CnB2j|-aR>d)g5GDZzSCLbiRSj6%|%msx_1=esXS%iO4`Q3 zOG4uE9GQJTbFl8aw?ESD{Q4`&&@7d(XVm$MdZoj|S48l{)?8@#4#-i%oIFV4urTJ* zURuyps6wFv8i$Z|!Y}W{rw=PI%G}mS!+n-22b)CIS)X=35wJHX6rDxp4%EDBJ}vsi z>SA+0Omb-94-Bs@TX*rUbJ9~D`);aU&TuE1_gnkXx3ObO%L1FC4*H6%`05|H4}Py0 zG&#R^pEB)O)IVholr|xVQq-E5JUd&+pDOxc+@Yv?+Y%*toaSPXOD`MG*wfiNLtZ;C zr!@BX^8({ytoDaj36*Qvp?4vJ=U<+dLGA%VLKKpyXlW$iv-~mf*tod7EbdGK8@h5_uyGQIfb++$(>ouKgpr^N#W{K^-2V0trz^hBD+;Oa#G9%*+>FsX`xm zxDg>C+Ay>2s}o`70=Q1{K&0U+}0G*U(QN=6}mKQ18shD@7<%=irOO{-E>jS z`*r?`Dfwf?<pcm-U-w4%YDy+A&Z>2o9Ek z0c>I!rJq0l_u@!_pq7)H3pE!nVC%6Sz8@Mpmk$cx#?_js>ic53%)Xr^gAVp)Yl}_> z=Jnj$6_Q#PwulOrrUH{c(hDg`6{-cY>RCMg;*gOfg(}xR-cRD}s$i4b_QF9KDNXJ@ zUmp*7)UDhZKjbG5OAk}5kUdwQhDny{FT>8R=y?E>RYy}O{hp17+elIDXwdJyU?)gh)z% zOC@`E$>Nw>ef*o^nF9>iHKAz{BATVn;)G%810*}=r}U)x-GplsHG*Bj zuI(M`E(>JRi+FvWlqg9?nyj?GPgZ$$FH?^@TegfSW@ZB{qd8Q+4Ag9NEE_cPH}V)J zW{g*#8T^Y7Cork}xYF>9Dm;yg7m3WO{ft?68&UDd)AJO{q$?|yfXc}yTzCg5$(#*z zSPiOQW<0q+QDz*NpT8_8BrBtwaWA7qaso%<=kPEyd6eAXH*bAfX_c5DR+hqtN@23D z-pyv*EP99Yb^e%414Fr5#N|6)!uAeN=W74m5mayr`*kj~5{{G!lk9%LYb5SZkrV|w z`43E&RWL@h9PxNCo6fzqzHuK5IXWDiC7tp{Tz9Vdx};wtojFv4Vb@n>fW6z6Gu``9 z6VpoV1D$v!x=8RxV@$K{DypzJ#%aa6=m7_7kXYtODfVR0rm+|QtNYX(L0?&}BA6AC z1aKN*8aInpDIhHoz7PR_(Rr$?3*%J)mzDhC12pFi&U|kreY7e7aGb$XbVr zxnj=%okd?NcCS&{$Q!By&uHoO3D$1@P%qFtmVVSPqv6(FP z`GzO4kF)1prJ0tglzG}Mj2G3Pv6_`@_mG7iH)z7uyyM?7{`Onlvbgjox|?fLMHP9j zQo<2IrOqjJ&cS#%(S?iW$#$shiu<1rb`sOV|4uH=)tGFL8EiTq>Hskk10V`2gl&e8 z==~-?-y5~u3CgExqWZ-5BqwUC`ecdAnK^r8e&x4d&kq91<)(XT#j5Sr;T>ME3=zmq zKo8v$4`9--=V4^L?kf`b*0E&X2H=lz;6~75pb(I1)+)KSpV@gG&AS>py$KhQ%F4_g zYctgR`gume^?I9Mt=>c-bkIJUiJRe+!zJ%66$rojwvc74VLA_8VLxO%-^(b6nE6i?x*|WUD&A z@Uz8WokGx}UP$RY^4IfUE9v$_bbw-7BKY_`Z!KtB_%zOWx1E1oe)K&lO5-?dGt|{> zKXlzjo9rzA)3o%DO~QN%BmR>wdnJXINUqV$*eumn!Zlf$#-zlxyOicu{Qtf#&z=c5 zdY!aBM2126yU)XG&hdaW*0LqUM?bFNE1wSTr&!8jMo^jf40?WWXXdG>zw5b*%}iiO9(%S zzp~PlY?jrH`gAq2l2J&AD9lzV1WJ$p2B*c@VG#xIl4k8Xpr$N?dRsak%z8K2btON; zjk@)>q5iyI)PS!pCg0M{smyTI!Q}yRzmn2qIA3mITi~z;Q@2IunP&8;6hHGeCEs|C zsyhGIS3M)b=hd!9I~!%0#+Svz6zX`~-A3rGVsIV=_EK=Q@70y;Nn0}56iIS_uYx*p zJY7+7)SJVigh!4mfmGfq+3%%e@x&G+BD^y`8UECgNQtV&)RBjYl%J3OP49Del%8Ip?V~$M3A>M#riiCo%3a33 z6C*Dp?3w|hfs2bPCME{m14uq@Vx{X}sd&>qKML}q2cQpOu1ohUae+VcX$W zhG!3C-p6PZepK_ncB3iYdnva?szcE`Ueq{`gW;a0$Jx(Bz2MH&ONB?zaPuP7Bat%7 z7|qluYbj7e+Z-LS(qz@|x2*hk>5NnirAALkdYJB|fiFiz{=>z5>YWVvohtiwED4p% zssA#|162yg8uyn2*A>!eRMaen8KM+FkqZ9&ou=uMn?si5WUu#I?y+>Xm}pd%ENXa( zY=^wx%uFmQJfpOv4Uu2#+iarxhKuV_&zI`x!u>%^g$C{HkC7a2C7+Mx*QMsqpH=9M z;7oM3NUb&8!KX0PV=h#+i17&j;_&T@U?++EB}Zig#^rO{aPj5xCv}5Sj;d-5ki3#d8FxVb4QWz_Av6LJot*xzqz-(`C zho;`YSjvOa0*~D;b>kU|{Ry*IBV7gU3)PT9(uW1)Pzt&2q~-SM3pqCLrP!0xR?VGF z_hx{Po`|5}FH_YQJvm3|s4);lHrb1 zs!vyPdVW`~OKq^YeOe-A_j8BM+Gv%OX7oR6Onw?K$BCAX?$K-cGO=QtW8>CQ)P&lH zK9r}0*_^@iw+xuz~;Jm&ndJ`$iptkiLlU8zC0dB$h&th=8C|5S~zD!i#os*Xb zbDgJBamDx?Y%8jCC>xLK4k(X5>GKhCa*Y#>R)4GQFH_>zks~Su*x5fpSx!nq0*XQJ zpg4{84I+-%czA-)q>5wKIoe&_m&Gp{`F4GkQK9x#3Xgk$7_;|peP+_ifR>*-m84p# z2Ve56%qa9CCtUj9jD4AX)_hD*O&8oCF3 zDYk-M!&FVl8kR9}p4aj!8Cd*XwlZc4rIA9#*KB@QldKgD$)qm7X6Os+{yI*m8sh*Ayd$IgHEl@!PLuQM| zgExawiYXYk#D{QYggS7Jd}28WhXCGN=>x~IK?&(KbAxY7 z-|r*LZ$OjcaBC6VZ4#FaBrIOp9ixRr1Oc*vH(z3Xlz&?IzT2GRi2a8$Mw_W45WtH> zWe2eJ!rx2wSGHP{U$DSit>=DjXomHx95z-^H+NSN2? zrfO#wql!(-c%AsdI*nlXQtb!rGG8GX0;t+$4J62$cAj3l>au==+&0_H@a4ZH1MHBw z>lmhY1f89nMo5Vy2$(RpRqSQd-?kRT^BPb?$|OLUrq~}#`c|Vby8?{P0~yuA5g`^Y z^YNPK;_#sRdF?vvYzerrve_f%!A+9srB1}PhYwy$9A5Pg#HS&}Z(&aq3$NDK%hg~A zZkmmi{4#{fV>&)<&6gRN#$2jkG$GtrJdFl5@OoGZIW}+Z>~li27B2c-Nc1fluN`d`N`o}MQg&-EgeXTQA{Um~1lJy`pd zub2{6BcQ*Kt8hu`eOl7K&E$6}d|Ata0)^gQE%LoG&%p3C!I-4jAu|zS%CtVCa@*PJ zM1oresyo!jD|neKDRyVCQNO(A_v`leDcHXBROE^=kIiE_I66dex6Yhw%i4=(j7XDV zMvF#0fuSmCDT(=b|G)V@j(!3FvO?(Fu>F*u zsuAVKsL6$|@tTj;N$Hz@U++*{dE}Hf@$MtNpJZZ!b8P402m!VX8$3{WDqBW%`k${# zO`CsoqmYO4qP7}}dzEDS>%Z3&WfyMZVm6P*mfDz2X(XymYQ4htGmI*-lu_4zr8tqP z$`WDrg}tXHGSN|R$U)hgC9P1SP=-(R7BqvJ?{4twhU?O@uMAFfPCNd|yOr~M+I?q* zc}N=DZ!S8yhjENb*p2F(fzosNId@A)Dv%nB&z~i_ zOVQJXgkR0yxd&*DGP-P-1- zHev@~7I!9rnEYOR*ErMnXpRK=xUAx>z1^ht96eWgTf7G)%AAJ67(P{Rk)5TbrO@zY zepdbq3?deWa>*tAZotS`zkd6x3NSarU&zv7-kNh^BW~q*L*^D3JR3Bjq zfvEW?0Mq(L?ys{eFnfa1Ae~k%UNMb|%k52uEnT*%;>{fyvD`B_Qamo=|>Llwy^p`b?vYKneyV)k6I9YfG9c|`FiK4upcHd=v{Mom?6taE2 zT`5ToRbZQ}Di+02BVRmXS-1cB&+tS-%kMmFSt(@9s2r<7?Z$>^8LTBXsZ12KGc?p^ zdwUu;J6@#v*iE(+l^30yur|d`d4Dl{1ooeP)R^sA)7eY5?XKN|5ZNe28Z6n_{`ZoZ zD%z;EH};aWDT{A@CVKzat#sy$0{;k_xip<@FFgGvgFOilGao_AuLMj0fOepGElS$2 zKR;zsqMRK!AVVsudcREnJE~{Baq_8aiQ%Nwr{3Dc zZnZwj(CmR_*|#76==(|tcPk#He6~|?)6yC?+dzH4_Zp-PLqw5v|+x9ixW`$ zX3`=#8M4#n#CJN?X@IGXzb5>$RE(JpJv0$Act<*Kq21|$=b1LMDZC2E;pi?>MM}O& zcf;9zp+vcI5=&X;;oGsoEZt3>W<4=3D5>zCzTVZ*p(%&{FYVWFWBXA{`?Z-0e`BTZ zY2bGFd2l8kAgzwquBTAY#n_j8()s1v%kUl-7Ripe~;NJu6sbY7_!E=I&wI{8`G7hVtSMWOOxE%2w^_e)7R#j-V2 zKA5@aMIkFmQSvZVxf+)?v$#MzUs-mQ?8%XlUZiy4NR$()|M!E1D)y@`Tat?8vxQ1j zw9UgeKQMaha;y)9_AYXK|C&i3(q_s?6w+0`rKra@w9HYd-D^_TMJaS=C76diT%MK& zJF55jCv);d*)HR)m0ti!i5Goz=6%31a3BCBp+FjwTeu|mO5#Uu5sKyx@mibQAK>uY>X}LY&eZ$=!lzR`xV4#aC#;8 zzgT6%4oFrW?p~n}aXX@nCY8->8G3-Nol+67ckZbzZZW};^H3)!01siO2^68Uv{?YP zLE9%16VjoRDj+rjYl~Y*s1bmQ3a+mHlFvTo-IMm)J8xmBh>2^N53%6G5!0b5u}n7G z|Jy>3j&@*PCwllU)cX|KuplywWmq)eHh`y&u=;W@h*V6U4wW6r;fH)e-r(k}x4@!yn6@a zqbH>32M`9p{C~xM@08USFyR6VM@l`3OyVY?=)ik+M8yqzdwW2Hh^wg$16Csvv%)!n z{IXp;^uB;gC3N(MMp(FM?C6Ws%|D~eo6V%WS46CgtgN~h9sK?M73AgJ_WlNoq$?Ox zUv~9`g0+&oypyx@>EBO%?=cYwj^++3Z{T(Tody`CzhHEm2-tMKVhX^Vj+fE!@Bo}| zQ~C-5@xdBe-EMAfK#l;)0Kh)5Fed4f-SJ9Z09p++`()(hTW7Zrh`BKO3(m-=($ev2 zdzwLX*ItA^WNUxF52)Q?VQZr(vdfncKHR{}0yZh|27o4DjO41|O<=@TIB8q@^G8ct zyVkhlhLaTn;ra=%gKlnofGGd;iIIin;*G88%E$nD6dDb(N=iTi!oolxW_U3DZ;_D! z)W`tfHc%(SxD2fyTi}24@bgCyKfce$_d&Ad48BM&Jup%M+qb{718oUmSWcn@_!@Hn z*aGY%Oqo3c4gq>;DtrJ|3xx5xIYVEO{w8m4jLRr0%Ic2q^-w@i`_ACg+rA0mx59MMe4wv^o`3=?MYw;ju9%s;iqE9E^=# z!>YoZoc6J?_-4Z=Po7}C6@!nxNh|!NsUR;;3+kcrwB6sniBw@Cd`3m+2>~_`^yI#~ z`!V30FBZpi3g|C@{Q3IT2sq8ews;5xDi20&0z8SF+cvqda20rC=ww}-?0szP;-5b} zwo^PkHW+Zb&W;YVnfljqaZJ4KdrX5q8dsO}TRs8Rk%W@+-^vP~-HbriCAb~bV>^Jv z3EVni*rr*RP#C}UTV~M!--iz^Cdyv`|N9Ai;r_1Pgva7Y0@SllIra5Zy}fw8B33?` zV;jO~y062pZxF;m;oxGai2#ZEtk!860Qk^n3`IvE+M()&8USK!>*z>IOuPr*!(0b| zi*V2Z=OZr4r zO$>eMC^YZF09^?*TR2uy=rhi|0+bRU1SdZ>mIQbndMmtY>FeujZf@@ASOS!v^c8JN z7Ms8603IczqFVp^_uc#`+=>OzJ(e(>_xc^C(yA&c(*CGN`?WMjFq(X5Xz29x6j~P{ z90)|Z-Uor#Y-xS?H*NqNc5`b>jJn_GB1eWi9B$h7%Arkm?{^iew1prUn zW!8>KNeM$+8GSi@{ZuGN0?QgwohP|N(2_wo$pid-C|3y>l|bQV81(rqj*o*QhO;(a z0z;;kmi9a8(g5~!AKo&EuUK1yEdw*xW>l7){ou0iZ=Yt5wF%%N8ygt`X+-E??h5+* zh}>+2qYCsfn6UlizWvLWB52Fc$_V?l7SX=sTLEE z;i18fKBXJn;2dBzR{*#wD;p9Xegh6Z;y}rXPmqi26{L*-mrhJfytpYVWRh@cd1WOY zJ_xfAz``Ty>%q==fVe8KS?{vwijZ#9rcJ;eqBsDJRq#VAb91Gxn?~qG>c;>I^vKv4 zJ~sBi&`^uCwJQa2&)9EI5T=AL9*kZjeFK0r0<0Opb^zJ3%(|2}Mj@xH+z+w||LulIu(My1fX@h{ zkkCR6K|xr2DdDg=YEPf$tAUpxA|iVH_%R^$M5*C^b{cwmDL{c%&6fvvBf#SNAc1^v z4|X0fC;QDS-o3*`I}M-T>6w|)$;oJrDyXM^{I7-LTnCg$aB$;b)ea6^S>gfK18%Jl zIbaS30X6`5S-@jsUcNNE`ih>N-4UqlAcmn^WlM4Kr7!)jgI!g%51Ip!nDw~H?$f3o zz^j0EH+1g-lf!#)p$yd8$4j64gMI*Xh2cWt-}+T}fcRCEk=fkcP2qI}7$2vMmc$!?O7xr5IID5Tfv5!#sfR4u})0v`?d5Y@|^>H1aA!4vd! zb;(LgKVoMWNAFuZO(6dO+dDN?Urg+>q*03_?8Z?!hS=J=I$_rhYG!79>VFd3FFi_Fa{^)mtM^8`x z6099qH6x?@{=VHxux+$cAlb&gO$&$82niIJaK~+(BfV|{)27Vv--+CU}r z5E2FsEKuveeue0phMdGk4~9w-0KnFyGwMHxEL`b8<+0%_LakM0s|U5Fh6X|O8yS58 z)*hZ5q9*_#N}<2A&DWTRPay^aGq}34@`!*83-`B`Ah;VZFwnq**{ zw)39dGaDOJW~MRh4~Rt2c2DF-c5ZI`hYzwh-=w7I$;e<|7HtTqO3%tN0VobwY*{%u zm|TwzOCanj)56Ba1}wjmgTq&8>tQQ%3-Dm}4i4qO@+f_NB|ryak_s}k_yoU8ab4Xp z?4w`~KI)zZFMhO6!0PHT81MxGW7r6LX0WgL`1oKE0s;a6rYA{FfpgatSfCS3W#yayeXu($s}2D1A^M4D zH3;VbpVkWl`KAE|ZDb4+xmMny&oQ4L@CJdW4(=6Y(3C3K^1=>GQ-C=Kse!>P{1t@0 z2?+_*H{lt>GmDEsxhIr52o9OAh>yr5x5pbxY}n$>&7#?=fGGHg{>Dxm@IAou!fGA; z3}poj`YkMQy>VZ^ie0-F$f8#Zde0J4QrFNn%t-{WhtRvHkqQSaDbRfHpx2wWtGCw~ zhRSkU4g;SI?b}4IRT;H~Kv)dCFR&Qc78RO2`?Vyez?cCmi}t?4-a_c3=OYQv91#=* zgFiPR{C&qUN!8O}%K}Gq=Ce%_)HVQQgjKS}4Mn6IA zQviZM2*|;AU0iuG1c3sK!IcaruR&WnUvMww0LBN)NsB}#{1=uW4!B1~Mu7MTZx8Ct zU#0)Px^n%H_8}pTo!vT60zvB_1HCw3LV@%GYVp~s%X4$eIy#{u@LKEuHeX>ra39La z;4-YO0RjinwlHUS>%YP5P}qmIwk+s%X#$aX0G5A9OaxC~rp1Kb*a%iT2qMty=i<`z zdYg98eDwlFJkJUB$B7?5+yNyIeJynG32p%Ffhk)ectr?I*}1u;sBP|IZZ{Oe|Ayqb zrnkP! zyaYY~7#Q%HSXsJ2bmSQxvt z6zEL`XSKXMBslo_C%|XHr5|*prN2S(7Q$LqgGSgr7;sph-DTC^+1fh#6|Dq;2YNdK zRu1GjC?oEYlUo}Z4Hjy$Vhnc8%OA!=KpXkzk2x!A3BJ$)0&Sv1t{($HA5t9%w?MH7 zF#Eyq%71(Y7%ot;1*xeG2eV|*Sr}p_1Sm9si3blF7axCobael{#&!S0GjX6+Kt&G7 z3e&ktR2PeGr)h6r26`W$ECZ3AOceV2FayB_{1_t>(^Q2;^nYmt#PjKpN5IJRUek`Y zHqdjx7@UOF+=e;{_*I}P01D{h(2A_yBg6r6(SgSqh?8#~Y#L+uxlLmd5)ncCM@&X` zfvkzhVHI1U?mLe`w_( z-+DbB-Z#`(_vz{X0Q3}2F4zCO>xEwcb%oovqv5@g;*E_pa8d}mRcb@kGX)aS4W8;PKajkc)wzd@a4f54MmM9X|Fe=LLVht(6e0@c=wLgHhaB_m3@&rsuNp?lW zaC5USbr3{&G&D3!yzp>NBA0!sA3n^7#vbstFA}od+F*3^BqasV(jaj3W&UO93|!eC z`8F^RI)9zh)29$dOJCVNiUqs(8UnnhIr7cHCvXiSOh8Z&)G^@S-bc%HSp(#gYle-+ z9pN_PrOhoZ3n0fqzwpcN1&#_^a$?xrRgC(J+RwJ9vOZ)7gaMhyzhMTgoa+22-NT0U% z_RgT11huHrWb|DXxQtq{C@4}OjRHTu^LOI5FNeYp%AS2-GSSk~!Yw>@2Bfs)(DxnN z0Sr4}a^YG?c+jcDVA;wp#Gx*0lhEPjfHTU3gbTlrZ32%J)Pz8POHEUgRj-!Nx4z&r zUji!!#|}`>gM)*i{h%d*z9)Af?3QUX+3z2eGO`BDv9bimtU&e-LJAQ7g1rYaYfSgx zQW3{I6bdMMCXa~W2E@UqTa)8vw}PMi{Pjx>5{<}6--|8T?*U0B{EWo?NN}^j@40Ld zxO)W42~j^RG%P&zO~XyNAL0X%e{)bs$jVp=2qZ0_%O}!x1sCE~_Vy&eH&at1j6)lW z^fnAkOfMKG0vQe@VPd4``8LV!r?AOjCJDGxbcsQW9WL~VbAd8kULHM&F#)%h*rHy9 zjQCQM=oQxKF3;9$TwZ9{|2(YuDur@J4;(L-b>b1iMg%%j40Y?w4oEG!N zm5g+B9UylG_T%jAOgeLIWEGYl1}@V;9ak!XQi}n7)o6No`5;6q!^0e0Tz4!^o-#I6 zsIbHzA0ECiHHBJIIyz86R8T^g52pdx_^@f9Ns5&PryqE*kh5}fZ~!0?_*^8RXs_8{ z0BA1jAD{`UAqs0RFNT3BQ z{a1-%!i6hEbnGFi0woSmH9Lq_5)vgvz4*5a@dTJ2bR9)0EnFQPshErBD5bFw1VcbX z6Dh5$r^oL~iu(D-89Fjh)&Sds4z(!=;mUMoC|_;^Fttaf=yHbAi+EiQ-ptOT}o#*kMUa6rd1br*c*K0r$2WW0-LY}a} zwV3X_dIDGa>>>XP93bA(EYV*xUr(VVBpm)KyanD3%n=w)z0cMpuY}OozUmwujq5Z4 zEmdglLmb?&P`?>R+2gV?*Zk%U2GH-`NuXb%`7Ah@F)##kb8}Ej2J%~`e$#6-4zJO( z4rZ1N=RYk&y97jqJLJy4HeG#veZgkIHm8_pu9`Az1aFosJRycjHV_xGjmwS0^0T!72$$Yfb0TlAK#X?VIiTF@QMlU=W`>pWxlno?U}YV z1UV)zUS#Mum4iT#rsfzx4qMyXKOaY1qd#}<1;*8@3TZ;qP^bfswzh@GHC8hwe178S z>UscSP}$3QvA>e&D>o`2!iJv&{h_`@_S}?)N>h>^7oavnCIkUKBqm1d=(X`N>q!;V zp}zSBTnLmd`1xTCrM0yuVHnP6iGi@?F#TV?i~H%WHy#)J`Zhxa1!%hfQTWk&?AAgT z_~z|f$Tk4Fe5nP6zTup3Yf+8=k^!vU zHY3i%;vfa89&}g?b^*fglZO47mJ4r&uxkY_HXR`jbV zp3MncHUGIx4zZmgRMVhtcX9fBxUE1;19qC=%Q+Eqb91?~DG*N7YjERy^axDjBOV^D z!jaF)4L7i{d7W3(AUc6^ejFA0NoRQE42Qh?I{Kdth2q{)nX?bt>-Z`%aTEviC@t+#w4NQqVJb$pfF_e+?gmP!E>+J^*JL z2A`=hj6lr|a$qQ)eAx1P7;@AX#>UPLs8c}SuPrYJbE3l&pSUWpJz(%aOErv?v*6IH z3t#x;<=M$=s8d5;#uER7Y4->q`VjAfS4s0adN@jie%cu{RUCHL_lb$u(0)MeNt|_b z-UI8?_3hinf0Z>2v}uOkI!uIjteJv0US1A*6(ysG_YItO_-JW=L!kqD9-xfW;ea-$ zB32N`%q=Z(8-DSDknyux33vlX2M2=Nw}H%57J|N8zZ>L0wKX+>$c9`VW?X3OPNuRa zD6z!5yShU05qO#xX*=93v#>A;;Mpc@I;O}ytC7{gK~*IsC6Jf^`vm8gi4uLk3Nc+4 zbkEejRo^k9)$4&bKkqL%;&3oP#ARk?#+plqA=YRSeQCNgl+l^)FmiE$C@3Un3JH%g z?0-5l7K{Oor5@&INh3i?K{lJf3cauh6bZ1Wwhuv~2U0fB|FLx5Mduq(h`ok)>*5d4 zu0;R-fByzekBh(jfByD=U;4lQ`v3YTM6PXkUqNJay*6c&2#Y|kjEschlVUMLzyAY< C57b@& literal 0 HcmV?d00001 diff --git a/pictures/deleted.png b/pictures/deleted.png new file mode 100644 index 0000000000000000000000000000000000000000..a18c28f52d7c981967d99f3eb877efd9f9262138 GIT binary patch literal 87078 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%0Db@E1pKssH$DiAQc7#> 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 z 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 rqJMYkD3m1qxBlP%=RO|k>c(Elb8MlxZ>(x literal 0 HcmV?d00001 diff --git a/trie.go b/trie.go new file mode 100644 index 0000000..37f018f --- /dev/null +++ b/trie.go @@ -0,0 +1,585 @@ +/** + * @file + * @copyright defined in aergo/LICENSE.txt + */ + +package trie + +import ( + "bytes" + "fmt" + "sync" + + "github.com/aergoio/aergo-lib/db" +) + +// Trie is a modified sparse Merkle tree. +// Instead of storing values at the leaves of the tree, +// the values are stored at the highest subtree root that contains only that value. +// If the tree is sparse, this requires fewer hashing operations. +type Trie struct { + db *CacheDB + // Root is the current root of the smt. + Root []byte + // prevRoot is the root before the last update + prevRoot []byte + // lock is for the whole struct + lock sync.RWMutex + // hash is the hash function used in the trie + hash func(data ...[]byte) []byte + // TrieHeight is the number if bits in a key + TrieHeight int + // LoadDbCounter counts the nb of db reads in on update + LoadDbCounter int + // loadDbMux is a lock for LoadDbCounter + loadDbMux sync.RWMutex + // LoadCacheCounter counts the nb of cache reads in on update + LoadCacheCounter int + // liveCountMux is a lock fo LoadCacheCounter + liveCountMux sync.RWMutex + // counterOn is used to enable/diseable for efficiency + counterOn bool + // CacheHeightLimit is the number of tree levels we want to store in cache + CacheHeightLimit int + // pastTries stores the past maxPastTries trie roots to revert + pastTries [][]byte + // atomicUpdate, commit all the changes made by intermediate update calls + atomicUpdate bool +} + +// NewSMT creates a new SMT given a keySize and a hash function. +func NewTrie(root []byte, hash func(data ...[]byte) []byte, store db.DB) *Trie { + s := &Trie{ + hash: hash, + TrieHeight: len(hash([]byte("height"))) * 8, // hash any string to get output length + counterOn: false, + } + s.db = &CacheDB{ + liveCache: make(map[Hash][][]byte), + updatedNodes: make(map[Hash][][]byte), + Store: store, + } + // don't store any cache by default (contracts state don't use cache) + s.CacheHeightLimit = s.TrieHeight + 1 + s.Root = root + return s +} + +// Update adds and deletes a sorted list of keys and their values to the trie +// Adding and deleting can be simultaneous. +// To delete, set the value to DefaultLeaf. +// If Update is called multiple times, only the state after the last update +// is commited. +func (s *Trie) Update(keys, values [][]byte) ([]byte, error) { + s.lock.Lock() + defer s.lock.Unlock() + s.atomicUpdate = false + s.LoadDbCounter = 0 + s.LoadCacheCounter = 0 + ch := make(chan mresult, 1) + s.update(s.Root, keys, values, nil, 0, s.TrieHeight, ch) + result := <-ch + if result.err != nil { + return nil, result.err + } + if len(result.update) != 0 { + s.Root = result.update[:HashLength] + } else { + s.Root = nil + } + return s.Root, nil +} + +// AtomicUpdate can be called multiple times and all the updated nodes will be commited +// and roots will be stored in past tries. +// Can be used for updating several blocks before committing to DB. +func (s *Trie) AtomicUpdate(keys, values [][]byte) ([]byte, error) { + s.lock.Lock() + defer s.lock.Unlock() + s.atomicUpdate = true + s.LoadDbCounter = 0 + s.LoadCacheCounter = 0 + ch := make(chan mresult, 1) + s.update(s.Root, keys, values, nil, 0, s.TrieHeight, ch) + result := <-ch + if result.err != nil { + return nil, result.err + } + if len(result.update) != 0 { + s.Root = result.update[:HashLength] + } else { + s.Root = nil + } + s.updatePastTries() + return s.Root, nil +} + +// mresult is used to contain the result of goroutines and is sent through a channel. +type mresult struct { + update []byte + // flag if a node was deleted and a shortcut node maybe has to move up the tree + deleted bool + err error +} + +// update adds and deletes a sorted list of keys and their values to the trie. +// Adding and deleting can be simultaneous. +// To delete, set the value to DefaultLeaf. +// It returns the root of the updated tree. +func (s *Trie) update(root []byte, keys, values, batch [][]byte, iBatch, height int, ch chan<- (mresult)) { + if height == 0 { + if bytes.Equal(DefaultLeaf, values[0]) { + // Delete the key-value from the trie if it is being set to DefaultLeaf + // The value will be set to [] in batch by maybeMoveupShortcut or interiorHash + s.deleteOldNode(root, height, false) + ch <- mresult{nil, true, nil} + } else { + // create a new shortcut batch. + // simply storing the value will make it hard to move up the + // shortcut in case of sibling deletion + batch = make([][]byte, 31, 31) + node := s.leafHash(keys[0], values[0], root, batch, 0, height) + ch <- mresult{node, false, nil} + } + return + } + + // Load the node to update + batch, iBatch, lnode, rnode, isShortcut, err := s.loadChildren(root, height, iBatch, batch) + if err != nil { + ch <- mresult{nil, false, err} + return + } + // Check if the keys are updating the shortcut node + if isShortcut { + keys, values = s.maybeAddShortcutToKV(keys, values, lnode[:HashLength], rnode[:HashLength]) + if iBatch == 0 { + // shortcut is moving so it's root will change + s.deleteOldNode(root, height, false) + } + // The shortcut node was added to keys and values so consider this subtree default. + lnode, rnode = nil, nil + // update in the batch (set key, value to default so the next loadChildren is correct) + batch[2*iBatch+1] = nil + batch[2*iBatch+2] = nil + if len(keys) == 0 { + // Set true so that a potential sibling shortcut may move up. + ch <- mresult{nil, true, nil} + return + } + } + // Store shortcut node + if (len(lnode) == 0) && (len(rnode) == 0) && (len(keys) == 1) { + // We are adding 1 key to an empty subtree so store it as a shortcut + if bytes.Equal(DefaultLeaf, values[0]) { + ch <- mresult{nil, true, nil} + } else { + node := s.leafHash(keys[0], values[0], root, batch, iBatch, height) + ch <- mresult{node, false, nil} + } + return + } + + // Split the keys array so each branch can be updated in parallel + lkeys, rkeys := s.splitKeys(keys, s.TrieHeight-height) + splitIndex := len(lkeys) + lvalues, rvalues := values[:splitIndex], values[splitIndex:] + + switch { + case len(lkeys) == 0 && len(rkeys) > 0: + s.updateRight(lnode, rnode, root, keys, values, batch, iBatch, height, ch) + case len(lkeys) > 0 && len(rkeys) == 0: + s.updateLeft(lnode, rnode, root, keys, values, batch, iBatch, height, ch) + default: + s.updateParallel(lnode, rnode, root, lkeys, rkeys, lvalues, rvalues, batch, iBatch, height, ch) + } +} + +// updateRight updates the right side of the tree +func (s *Trie) updateRight(lnode, rnode, root []byte, keys, values, batch [][]byte, iBatch, height int, ch chan<- (mresult)) { + // all the keys go in the right subtree + newch := make(chan mresult, 1) + s.update(rnode, keys, values, batch, 2*iBatch+2, height-1, newch) + result := <-newch + if result.err != nil { + ch <- mresult{nil, false, result.err} + return + } + // Move up a shortcut node if necessary. + if result.deleted { + if s.maybeMoveUpShortcut(lnode, result.update, root, batch, iBatch, height, ch) { + return + } + } + node := s.interiorHash(lnode, result.update, root, batch, iBatch, height) + ch <- mresult{node, false, nil} +} + +// updateLeft updates the left side of the tree +func (s *Trie) updateLeft(lnode, rnode, root []byte, keys, values, batch [][]byte, iBatch, height int, ch chan<- (mresult)) { + // all the keys go in the left subtree + newch := make(chan mresult, 1) + s.update(lnode, keys, values, batch, 2*iBatch+1, height-1, newch) + result := <-newch + if result.err != nil { + ch <- mresult{nil, false, result.err} + return + } + // Move up a shortcut node if necessary. + if result.deleted { + if s.maybeMoveUpShortcut(result.update, rnode, root, batch, iBatch, height, ch) { + return + } + } + node := s.interiorHash(result.update, rnode, root, batch, iBatch, height) + ch <- mresult{node, false, nil} +} + +// updateParallel updates both sides of the trie simultaneously +func (s *Trie) updateParallel(lnode, rnode, root []byte, lkeys, rkeys, lvalues, rvalues, batch [][]byte, iBatch, height int, ch chan<- (mresult)) { + lch := make(chan mresult, 1) + rch := make(chan mresult, 1) + go s.update(lnode, lkeys, lvalues, batch, 2*iBatch+1, height-1, lch) + go s.update(rnode, rkeys, rvalues, batch, 2*iBatch+2, height-1, rch) + lresult := <-lch + rresult := <-rch + if lresult.err != nil { + ch <- mresult{nil, false, lresult.err} + return + } + if rresult.err != nil { + ch <- mresult{nil, false, rresult.err} + return + } + + // Move up a shortcut node if it's sibling is default + if lresult.deleted || rresult.deleted { + if s.maybeMoveUpShortcut(lresult.update, rresult.update, root, batch, iBatch, height, ch) { + return + } + } + node := s.interiorHash(lresult.update, rresult.update, root, batch, iBatch, height) + ch <- mresult{node, false, nil} +} + +// deleteOldNode deletes an old node that has been updated +func (s *Trie) deleteOldNode(root []byte, height int, movingUp bool) { + var node Hash + copy(node[:], root) + if !s.atomicUpdate || movingUp { + // dont delete old nodes with atomic updated except when + // moving up a shortcut, we dont record every single move + s.db.updatedMux.Lock() + delete(s.db.updatedNodes, node) + s.db.updatedMux.Unlock() + } + if height >= s.CacheHeightLimit { + s.db.liveMux.Lock() + delete(s.db.liveCache, node) + s.db.liveMux.Unlock() + } +} + +// splitKeys devides the array of keys into 2 so they can update left and right branches in parallel +func (s *Trie) splitKeys(keys [][]byte, height int) ([][]byte, [][]byte) { + for i, key := range keys { + if bitIsSet(key, height) { + return keys[:i], keys[i:] + } + } + return keys, nil +} + +// maybeMoveUpShortcut moves up a shortcut if it's sibling node is default +func (s *Trie) maybeMoveUpShortcut(left, right, root []byte, batch [][]byte, iBatch, height int, ch chan<- (mresult)) bool { + if len(left) == 0 && len(right) == 0 { + // Both update and sibling are deleted subtrees + if iBatch == 0 { + // If the deleted subtrees are at the root, then delete it. + s.deleteOldNode(root, height, true) + } else { + batch[2*iBatch+1] = nil + batch[2*iBatch+2] = nil + } + ch <- mresult{nil, true, nil} + return true + } else if len(left) == 0 { + // If right is a shortcut move it up + if right[HashLength] == 1 { + s.moveUpShortcut(right, root, batch, iBatch, 2*iBatch+2, height, ch) + return true + } + } else if len(right) == 0 { + // If left is a shortcut move it up + if left[HashLength] == 1 { + s.moveUpShortcut(left, root, batch, iBatch, 2*iBatch+1, height, ch) + return true + } + } + return false +} + +func (s *Trie) moveUpShortcut(shortcut, root []byte, batch [][]byte, iBatch, iShortcut, height int, ch chan<- (mresult)) { + // it doesn't matter if atomic update is true or false since the batch is node modified + _, _, shortcutKey, shortcutVal, _, err := s.loadChildren(shortcut, height-1, iShortcut, batch) + if err != nil { + ch <- mresult{nil, false, err} + return + } + // when moving up the shortcut, it's hash will change because height is +1 + newShortcut := s.hash(shortcutKey[:HashLength], shortcutVal[:HashLength], []byte{byte(height)}) + newShortcut = append(newShortcut, byte(1)) + + if iBatch == 0 { + // Modify batch to a shortcut batch + batch[0] = []byte{1} + batch[2*iBatch+1] = shortcutKey + batch[2*iBatch+2] = shortcutVal + batch[2*iShortcut+1] = nil + batch[2*iShortcut+2] = nil + // cache and updatedNodes deleted by store node + s.storeNode(batch, newShortcut, root, height) + } else if (height-1)%4 == 0 { + // move up shortcut and delete old batch + batch[2*iBatch+1] = shortcutKey + batch[2*iBatch+2] = shortcutVal + // set true so that AtomicUpdate can also delete a node moving up + // otherwise every nodes moved up is recorded + s.deleteOldNode(shortcut, height, true) + } else { + //move up shortcut + batch[2*iBatch+1] = shortcutKey + batch[2*iBatch+2] = shortcutVal + batch[2*iShortcut+1] = nil + batch[2*iShortcut+2] = nil + } + // Return the left sibling node to move it up + ch <- mresult{newShortcut, true, nil} +} + +// maybeAddShortcutToKV adds a shortcut key to the keys array to be updated. +// this is used when a subtree containing a shortcut node is being updated +func (s *Trie) maybeAddShortcutToKV(keys, values [][]byte, shortcutKey, shortcutVal []byte) ([][]byte, [][]byte) { + newKeys := make([][]byte, 0, len(keys)+1) + newVals := make([][]byte, 0, len(keys)+1) + + if bytes.Compare(shortcutKey, keys[0]) < 0 { + newKeys = append(newKeys, shortcutKey) + newKeys = append(newKeys, keys...) + newVals = append(newVals, shortcutVal) + newVals = append(newVals, values...) + } else if bytes.Compare(shortcutKey, keys[len(keys)-1]) > 0 { + newKeys = append(newKeys, keys...) + newKeys = append(newKeys, shortcutKey) + newVals = append(newVals, values...) + newVals = append(newVals, shortcutVal) + } else { + higher := false + for i, key := range keys { + if bytes.Equal(shortcutKey, key) { + if !bytes.Equal(DefaultLeaf, values[i]) { + // Do nothing if the shortcut is simply updated + return keys, values + } + // Delete shortcut if it is updated to DefaultLeaf + newKeys = append(newKeys, keys[:i]...) + newKeys = append(newKeys, keys[i+1:]...) + newVals = append(newVals, values[:i]...) + newVals = append(newVals, values[i+1:]...) + } + if !higher && bytes.Compare(shortcutKey, key) > 0 { + higher = true + continue + } + if higher && bytes.Compare(shortcutKey, key) < 0 { + // insert shortcut in slices + newKeys = append(newKeys, keys[:i]...) + newKeys = append(newKeys, shortcutKey) + newKeys = append(newKeys, keys[i:]...) + newVals = append(newVals, values[:i]...) + newVals = append(newVals, shortcutVal) + newVals = append(newVals, values[i:]...) + break + } + } + } + return newKeys, newVals +} + +// loadChildren looks for the children of a node. +// if the node is not stored in cache, it will be loaded from db. +func (s *Trie) loadChildren(root []byte, height, iBatch int, batch [][]byte) ([][]byte, int, []byte, []byte, bool, error) { + isShortcut := false + if height%4 == 0 { + if len(root) == 0 { + // create a new default batch + batch = make([][]byte, 31, 31) + batch[0] = []byte{0} + } else { + var err error + batch, err = s.loadBatch(root) + if err != nil { + return nil, 0, nil, nil, false, err + } + } + iBatch = 0 + if batch[0][0] == 1 { + isShortcut = true + } + } else { + if len(batch[iBatch]) != 0 && batch[iBatch][HashLength] == 1 { + isShortcut = true + } + } + return batch, iBatch, batch[2*iBatch+1], batch[2*iBatch+2], isShortcut, nil +} + +// loadBatch fetches a batch of nodes in cache or db +func (s *Trie) loadBatch(root []byte) ([][]byte, error) { + var node Hash + copy(node[:], root) + + s.db.liveMux.RLock() + val, exists := s.db.liveCache[node] + s.db.liveMux.RUnlock() + if exists { + if s.counterOn { + s.liveCountMux.Lock() + s.LoadCacheCounter++ + s.liveCountMux.Unlock() + } + if s.atomicUpdate { + // Return a copy so that Commit() doesnt have to be called at + // each block and still commit every state transition. + // Before Commit, the same batch is in liveCache and in updatedNodes + newVal := make([][]byte, 31, 31) + copy(newVal, val) + return newVal, nil + } + return val, nil + } + // checking updated nodes is useful if get() or update() is called twice in a row without db commit + s.db.updatedMux.RLock() + val, exists = s.db.updatedNodes[node] + s.db.updatedMux.RUnlock() + if exists { + if s.atomicUpdate { + // Return a copy so that Commit() doesnt have to be called at + // each block and still commit every state transition. + newVal := make([][]byte, 31, 31) + copy(newVal, val) + return newVal, nil + } + return val, nil + } + //Fetch node in disk database + if s.db.Store == nil { + return nil, fmt.Errorf("DB not connected to trie") + } + if s.counterOn { + s.loadDbMux.Lock() + s.LoadDbCounter++ + s.loadDbMux.Unlock() + } + s.db.lock.Lock() + dbval := s.db.Store.Get(root[:HashLength]) + s.db.lock.Unlock() + nodeSize := len(dbval) + if nodeSize != 0 { + return s.parseBatch(dbval), nil + } + return nil, fmt.Errorf("the trie node %x is unavailable in the disk db, db may be corrupted", root) +} + +// parseBatch decodes the byte data into a slice of nodes and bitmap +func (s *Trie) parseBatch(val []byte) [][]byte { + batch := make([][]byte, 31, 31) + bitmap := val[:4] + // check if the batch root is a shortcut + if bitIsSet(val, 31) { + batch[0] = []byte{1} + batch[1] = val[4 : 4+33] + batch[2] = val[4+33 : 4+33*2] + } else { + batch[0] = []byte{0} + j := 0 + for i := 1; i <= 30; i++ { + if bitIsSet(bitmap, i-1) { + batch[i] = val[4+33*j : 4+33*(j+1)] + j++ + } + } + } + return batch +} + +// leafHash returns the hash of key_value_byte(height) concatenated, stores it in the updatedNodes and maybe in liveCache. +// leafHash is never called for a default value. Default value should not be stored. +func (s *Trie) leafHash(key, value, oldRoot []byte, batch [][]byte, iBatch, height int) []byte { + // byte(height) is here for 2 reasons. + // 1- to prevent potential problems with merkle proofs where if an account + // has the same address as a node, it would be possible to prove a + // different value for the account. + // 2- when accounts are added to the trie, accounts on their path get pushed down the tree + // with them. if an old account changes position from a shortcut batch to another + // shortcut batch of different height, if would be deleted when reverting. + h := s.hash(key, value, []byte{byte(height)}) + h = append(h, byte(1)) // byte(1) is a flag for the shortcut + batch[2*iBatch+2] = append(value, byte(2)) + batch[2*iBatch+1] = append(key, byte(2)) + if height%4 == 0 { + batch[0] = []byte{1} // byte(1) is a flag for the shortcut batch + s.storeNode(batch, h, oldRoot, height) + } + return h +} + +// storeNode stores a batch and deletes the old node from cache +func (s *Trie) storeNode(batch [][]byte, h, oldRoot []byte, height int) { + if !bytes.Equal(h, oldRoot) { + var node Hash + copy(node[:], h) + // record new node + s.db.updatedMux.Lock() + s.db.updatedNodes[node] = batch + s.db.updatedMux.Unlock() + // Cache the shortcut node if it's height is over CacheHeightLimit + if height >= s.CacheHeightLimit { + s.db.liveMux.Lock() + s.db.liveCache[node] = batch + s.db.liveMux.Unlock() + } + s.deleteOldNode(oldRoot, height, false) + } +} + +// interiorHash hashes 2 children to get the parent hash and stores it in the updatedNodes and maybe in liveCache. +func (s *Trie) interiorHash(left, right, oldRoot []byte, batch [][]byte, iBatch, height int) []byte { + var h []byte + // left and right cannot both be default. It is handled by maybeMoveUpShortcut() + if len(left) == 0 { + h = s.hash(DefaultLeaf, right[:HashLength]) + } else if len(right) == 0 { + h = s.hash(left[:HashLength], DefaultLeaf) + } else { + h = s.hash(left[:HashLength], right[:HashLength]) + } + h = append(h, byte(0)) + batch[2*iBatch+2] = right + batch[2*iBatch+1] = left + if height%4 == 0 { + batch[0] = []byte{0} + s.storeNode(batch, h, oldRoot, height) + } + return h +} + +// updatePastTries appends the current Root to the list of past tries +func (s *Trie) updatePastTries() { + if len(s.pastTries) >= maxPastTries { + copy(s.pastTries, s.pastTries[1:]) + s.pastTries[len(s.pastTries)-1] = s.Root + } else { + s.pastTries = append(s.pastTries, s.Root) + } +} diff --git a/trie_cache.go b/trie_cache.go new file mode 100644 index 0000000..3c41da5 --- /dev/null +++ b/trie_cache.go @@ -0,0 +1,63 @@ +/** + * @file + * @copyright defined in aergo/LICENSE.txt + */ + +package trie + +import ( + "sync" + + "github.com/aergoio/aergo-lib/db" +) + +// DbTx represents Set and Delete interface to store data +type DbTx interface { + Set(key, value []byte) + Delete(key []byte) +} + +type CacheDB struct { + // liveCache contains the first levels of the trie (nodes that have 2 non default children) + liveCache map[Hash][][]byte + // liveMux is a lock for liveCache + liveMux sync.RWMutex + // updatedNodes that have will be flushed to disk + updatedNodes map[Hash][][]byte + // updatedMux is a lock for updatedNodes + updatedMux sync.RWMutex + // nodesToRevert will be deleted from db + nodesToRevert [][]byte + // revertMux is a lock for updatedNodes + revertMux sync.RWMutex + // lock for CacheDB + lock sync.RWMutex + // store is the interface to disk db + Store db.DB +} + +// commit adds updatedNodes to the given database transaction. +func (c *CacheDB) commit(txn *DbTx) { + c.updatedMux.Lock() + defer c.updatedMux.Unlock() + for key, batch := range c.updatedNodes { + var node []byte + (*txn).Set(append(node, key[:]...), c.serializeBatch(batch)) + } +} + +// serializeBatch serialises the 2D [][]byte into a []byte for db +func (c *CacheDB) serializeBatch(batch [][]byte) []byte { + serialized := make([]byte, 4) //, 30*33) + if batch[0][0] == 1 { + // the batch node is a shortcut + bitSet(serialized, 31) + } + for i := 1; i < 31; i++ { + if len(batch[i]) != 0 { + bitSet(serialized, i-1) + serialized = append(serialized, batch[i]...) + } + } + return serialized +} diff --git a/trie_merkle_proof.go b/trie_merkle_proof.go new file mode 100644 index 0000000..cb3c590 --- /dev/null +++ b/trie_merkle_proof.go @@ -0,0 +1,210 @@ +/** + * @file + * @copyright defined in aergo/LICENSE.txt + */ + +package trie + +import ( + "bytes" +) + +// MerkleProof generates a Merke proof of inclusion or non-inclusion +// for the current trie root +// returns the audit path, bool (key included), key, value, error +// (key,value) can be 1- (nil, value), value of the included key, 2- the kv of a LeafNode +// on the path of the non-included key, 3- (nil, nil) for a non-included key +// with a DefaultLeaf on the path +func (s *Trie) MerkleProof(key []byte) ([][]byte, bool, []byte, []byte, error) { + s.lock.RLock() + defer s.lock.RUnlock() + s.atomicUpdate = false // so loadChildren doesnt return a copy + return s.merkleProof(s.Root, key, nil, s.TrieHeight, 0) +} + +// MerkleProofPast generates a Merke proof of inclusion or non-inclusion +// for a given past trie root +// returns the audit path, bool (key included), key, value, error +// (key,value) can be 1- (nil, value), value of the included key, 2- the kv of a LeafNode +// on the path of the non-included key, 3- (nil, nil) for a non-included key +// with a DefaultLeaf on the path +func (s *Trie) MerkleProofR(key, root []byte) ([][]byte, bool, []byte, []byte, error) { + s.lock.RLock() + defer s.lock.RUnlock() + s.atomicUpdate = false // so loadChildren doesnt return a copy + return s.merkleProof(root, key, nil, s.TrieHeight, 0) +} + +// MerkleProofCompressed returns a compressed merkle proof in the given trie +func (s *Trie) MerkleProofCompressedR(key, root []byte) ([]byte, [][]byte, int, bool, []byte, []byte, error) { + return s.merkleProofCompressed(key, root) +} + +// MerkleProofCompressed returns a compressed merkle proof +func (s *Trie) MerkleProofCompressed(key []byte) ([]byte, [][]byte, int, bool, []byte, []byte, error) { + return s.merkleProofCompressed(key, s.Root) +} + +func (s *Trie) merkleProofCompressed(key, root []byte) ([]byte, [][]byte, int, bool, []byte, []byte, error) { + s.lock.RLock() + defer s.lock.RUnlock() + s.atomicUpdate = false // so loadChildren doesnt return a copy + // create a regular merkle proof and then compress it + mpFull, included, proofKey, proofVal, err := s.merkleProof(root, key, nil, s.TrieHeight, 0) + if err != nil { + return nil, nil, 0, true, nil, nil, err + } + // the height of the shortcut in the tree will be needed for the proof verification + height := len(mpFull) + var mp [][]byte + bitmap := make([]byte, len(mpFull)/8+1) + for i, node := range mpFull { + if !bytes.Equal(node, DefaultLeaf) { + bitSet(bitmap, i) + mp = append(mp, node) + } + } + return bitmap, mp, height, included, proofKey, proofVal, nil +} + +// merkleProof generates a Merke proof of inclusion or non-inclusion +// for a given trie root. +// returns the audit path, bool (key included), key, value, error +// (key,value) can be 1- (nil, value), value of the included key, 2- the kv of a LeafNode +// on the path of the non-included key, 3- (nil, nil) for a non-included key +// with a DefaultLeaf on the path +func (s *Trie) merkleProof(root, key []byte, batch [][]byte, height, iBatch int) ([][]byte, bool, []byte, []byte, error) { + if len(root) == 0 { + // proove that an empty subtree is on the path of the key + return nil, false, nil, nil, nil + } + // Fetch the children of the node + batch, iBatch, lnode, rnode, isShortcut, err := s.loadChildren(root, height, iBatch, batch) + if err != nil { + return nil, false, nil, nil, err + } + if isShortcut || height == 0 { + if bytes.Equal(lnode[:HashLength], key) { + // return the value so a call to trie.Get() is not needed. + return nil, true, nil, rnode[:HashLength], nil + } + // Return the proof of the leaf key that is on the path of the non included key + return nil, false, lnode[:HashLength], rnode[:HashLength], nil + } + + // append the left or right node to the proof + if bitIsSet(key, s.TrieHeight-height) { + mp, included, proofKey, proofValue, err := s.merkleProof(rnode, key, batch, height-1, 2*iBatch+2) + if err != nil { + return nil, false, nil, nil, err + } + if len(lnode) != 0 { + return append(mp, lnode[:HashLength]), included, proofKey, proofValue, nil + } else { + return append(mp, DefaultLeaf), included, proofKey, proofValue, nil + } + + } + mp, included, proofKey, proofValue, err := s.merkleProof(lnode, key, batch, height-1, 2*iBatch+1) + if err != nil { + return nil, false, nil, nil, err + } + if len(rnode) != 0 { + return append(mp, rnode[:HashLength]), included, proofKey, proofValue, nil + } else { + return append(mp, DefaultLeaf), included, proofKey, proofValue, nil + } +} + +// VerifyInclusion verifies that key/value is included in the trie with latest root +func (s *Trie) VerifyInclusion(ap [][]byte, key, value []byte) bool { + leafHash := s.hash(key, value, []byte{byte(s.TrieHeight - len(ap))}) + return bytes.Equal(s.Root, s.verifyInclusion(ap, 0, key, leafHash)) +} + +// verifyInclusion returns the merkle root by hashing the merkle proof items +func (s *Trie) verifyInclusion(ap [][]byte, keyIndex int, key, leafHash []byte) []byte { + if keyIndex == len(ap) { + return leafHash + } + if bitIsSet(key, keyIndex) { + return s.hash(ap[len(ap)-keyIndex-1], s.verifyInclusion(ap, keyIndex+1, key, leafHash)) + } + return s.hash(s.verifyInclusion(ap, keyIndex+1, key, leafHash), ap[len(ap)-keyIndex-1]) +} + +// VerifyNonInclusion verifies a proof of non inclusion, +// Returns true if the non-inclusion is verified +func (s *Trie) VerifyNonInclusion(ap [][]byte, key, value, proofKey []byte) bool { + // Check if an empty subtree is on the key path + if len(proofKey) == 0 { + // return true if a DefaultLeaf in the key path is included in the trie + return bytes.Equal(s.Root, s.verifyInclusion(ap, 0, key, DefaultLeaf)) + } + // Check if another kv leaf is on the key path in 2 steps + // 1- Check the proof leaf exists + if !s.VerifyInclusion(ap, proofKey, value) { + // the proof leaf is not included in the trie + return false + } + // 2- Check the proof leaf is on the key path + var b int + for b = 0; b < len(ap); b++ { + if bitIsSet(key, b) != bitIsSet(proofKey, b) { + // the proofKey leaf node is not on the path of the key + return false + } + } + // return true because we verified another leaf is on the key path + return true +} + +// VerifyInclusionC verifies that key/value is included in the trie with latest root +func (s *Trie) VerifyInclusionC(bitmap, key, value []byte, ap [][]byte, length int) bool { + leafHash := s.hash(key, value, []byte{byte(s.TrieHeight - length)}) + return bytes.Equal(s.Root, s.verifyInclusionC(bitmap, key, leafHash, ap, length, 0, 0)) +} + +// verifyInclusionC returns the merkle root by hashing the merkle proof items +func (s *Trie) verifyInclusionC(bitmap, key, leafHash []byte, ap [][]byte, length, keyIndex, apIndex int) []byte { + if keyIndex == length { + return leafHash + } + if bitIsSet(key, keyIndex) { + if bitIsSet(bitmap, length-keyIndex-1) { + return s.hash(ap[len(ap)-apIndex-1], s.verifyInclusionC(bitmap, key, leafHash, ap, length, keyIndex+1, apIndex+1)) + } + return s.hash(DefaultLeaf, s.verifyInclusionC(bitmap, key, leafHash, ap, length, keyIndex+1, apIndex)) + + } + if bitIsSet(bitmap, length-keyIndex-1) { + return s.hash(s.verifyInclusionC(bitmap, key, leafHash, ap, length, keyIndex+1, apIndex+1), ap[len(ap)-apIndex-1]) + } + return s.hash(s.verifyInclusionC(bitmap, key, leafHash, ap, length, keyIndex+1, apIndex), DefaultLeaf) +} + +// VerifyNonInclusionC verifies a proof of non inclusion, +// Returns true if the non-inclusion is verified +func (s *Trie) VerifyNonInclusionC(ap [][]byte, length int, bitmap, key, value, proofKey []byte) bool { + // Check if an empty subtree is on the key path + if len(proofKey) == 0 { + // return true if a DefaultLeaf in the key path is included in the trie + return bytes.Equal(s.Root, s.verifyInclusionC(bitmap, key, DefaultLeaf, ap, length, 0, 0)) + } + // Check if another kv leaf is on the key path in 2 steps + // 1- Check the proof leaf exists + if !s.VerifyInclusionC(bitmap, proofKey, value, ap, length) { + // the proof leaf is not included in the trie + return false + } + // 2- Check the proof leaf is on the key path + var b int + for b = 0; b < length; b++ { + if bitIsSet(key, b) != bitIsSet(proofKey, b) { + // the proofKey leaf node is not on the path of the key + return false + } + } + // return true because we verified another leaf is on the key path + return true +} diff --git a/trie_revert.go b/trie_revert.go new file mode 100644 index 0000000..5dd6e5b --- /dev/null +++ b/trie_revert.go @@ -0,0 +1,178 @@ +/** + * @file + * @copyright defined in aergo/LICENSE.txt + */ + +package trie + +import ( + "bytes" + "fmt" +) + +// Revert rewinds the state tree to a previous version +// All the nodes (subtree roots and values) reverted are deleted from the database. +func (s *Trie) Revert(toOldRoot []byte) error { + s.lock.RLock() + defer s.lock.RUnlock() + + // safety precaution if reverting to a shortcut batch that might have been deleted + s.atomicUpdate = false // so loadChildren doesnt return a copy + batch, _, _, _, isShortcut, err := s.loadChildren(toOldRoot, s.TrieHeight, 0, nil) + if err != nil { + return err + } + + //check if toOldRoot is in s.pastTries + canRevert := false + toIndex := 0 + for i, r := range s.pastTries { + if bytes.Equal(r, toOldRoot) { + canRevert = true + toIndex = i + break + } + } + if !canRevert || bytes.Equal(s.Root, toOldRoot) { + return fmt.Errorf("The root cannot be reverted, because already latest of not in pastTries : current : %x, target : %x", s.Root, toOldRoot) + } + + // For every node of toOldRoot, compare it to the equivalent node in other pasttries between toOldRoot and current s.Root. If a node is different, delete the one from pasttries + s.db.nodesToRevert = make([][]byte, 0) + for i := toIndex + 1; i < len(s.pastTries); i++ { + ch := make(chan error, 1) + s.maybeDeleteSubTree(toOldRoot, s.pastTries[i], s.TrieHeight, 0, nil, nil, ch) + err := <-ch + if err != nil { + return err + } + } + // NOTE The tx interface doesnt handle ErrTxnTooBig + txn := s.db.Store.NewTx() + for _, key := range s.db.nodesToRevert { + txn.Delete(key[:HashLength]) + } + txn.Commit() + + s.pastTries = s.pastTries[:toIndex+1] + s.Root = toOldRoot + s.db.liveCache = make(map[Hash][][]byte) + s.db.updatedNodes = make(map[Hash][][]byte) + if isShortcut { + // If toOldRoot is a shortcut batch, it is possible that + // revert has deleted it if the key was ever stored at height0 + // because in leafHash byte(0) = byte(256) + s.db.Store.Set(toOldRoot, s.db.serializeBatch(batch)) + } + return nil +} + +// maybeDeleteSubTree compares the subtree nodes of 2 tries and keeps only the older one +func (s *Trie) maybeDeleteSubTree(original, maybeDelete []byte, height, iBatch int, batch, batch2 [][]byte, ch chan<- (error)) { + if height == 0 { + if !bytes.Equal(original, maybeDelete) && len(maybeDelete) != 0 { + s.maybeDeleteRevertedNode(maybeDelete, 0) + } + ch <- nil + return + } + if bytes.Equal(original, maybeDelete) || len(maybeDelete) == 0 { + ch <- nil + return + } + // if this point os reached, then the root of the batch is same + // so the batch is also same. + batch, iBatch, lnode, rnode, isShortcut, lerr := s.loadChildren(original, height, iBatch, batch) + if lerr != nil { + ch <- lerr + return + } + batch2, _, lnode2, rnode2, isShortcut2, rerr := s.loadChildren(maybeDelete, height, iBatch, batch2) + if rerr != nil { + ch <- rerr + return + } + + if isShortcut != isShortcut2 { + if isShortcut { + ch1 := make(chan error, 1) + s.deleteSubTree(maybeDelete, height, iBatch, batch2, ch1) + err := <-ch1 + if err != nil { + ch <- err + return + } + } else { + s.maybeDeleteRevertedNode(maybeDelete, iBatch) + } + } else { + if isShortcut { + // Delete shortcut if not equal + if !bytes.Equal(lnode, lnode2) || !bytes.Equal(rnode, rnode2) { + s.maybeDeleteRevertedNode(maybeDelete, iBatch) + } + } else { + // Delete subtree if not equal + s.maybeDeleteRevertedNode(maybeDelete, iBatch) + ch1 := make(chan error, 1) + ch2 := make(chan error, 1) + go s.maybeDeleteSubTree(lnode, lnode2, height-1, 2*iBatch+1, batch, batch2, ch1) + go s.maybeDeleteSubTree(rnode, rnode2, height-1, 2*iBatch+2, batch, batch2, ch2) + err1, err2 := <-ch1, <-ch2 + if err1 != nil { + ch <- err1 + return + } + if err2 != nil { + ch <- err2 + return + } + } + } + ch <- nil +} + +// deleteSubTree deletes all the nodes contained in a tree +func (s *Trie) deleteSubTree(root []byte, height, iBatch int, batch [][]byte, ch chan<- (error)) { + if len(root) == 0 || height == 0 { + if height == 0 { + s.maybeDeleteRevertedNode(root, 0) + } + ch <- nil + return + } + batch, iBatch, lnode, rnode, isShortcut, err := s.loadChildren(root, height, iBatch, batch) + if err != nil { + ch <- err + return + } + if !isShortcut { + ch1 := make(chan error, 1) + ch2 := make(chan error, 1) + go s.deleteSubTree(lnode, height-1, 2*iBatch+1, batch, ch1) + go s.deleteSubTree(rnode, height-1, 2*iBatch+2, batch, ch2) + lerr := <-ch1 + rerr := <-ch2 + + if lerr != nil { + ch <- lerr + return + } + if rerr != nil { + ch <- rerr + return + } + } + s.maybeDeleteRevertedNode(root, iBatch) + ch <- nil +} + +// maybeDeleteRevertedNode adds the node to updatedNodes to be reverted +// if it is a batch node at height%4 == 0 +func (s *Trie) maybeDeleteRevertedNode(root []byte, iBatch int) { + if iBatch == 0 { + s.db.revertMux.Lock() + s.db.nodesToRevert = append(s.db.nodesToRevert, root) + s.db.revertMux.Unlock() + } +} diff --git a/trie_test.go b/trie_test.go new file mode 100644 index 0000000..1754ca7 --- /dev/null +++ b/trie_test.go @@ -0,0 +1,883 @@ +/** + * @file + * @copyright defined in aergo/LICENSE.txt + */ + +package trie + +import ( + "bytes" + "runtime" + + //"io/ioutil" + "os" + "path" + "time" + + //"encoding/hex" + "fmt" + "math/rand" + "sort" + "testing" + + "github.com/aergoio/aergo-lib/db" +) + +func TestTrieEmpty(t *testing.T) { + smt := NewTrie(nil, Hasher, nil) + if len(smt.Root) != 0 { + t.Fatal("empty trie root hash not correct") + } +} + +func TestTrieUpdateAndGet(t *testing.T) { + smt := NewTrie(nil, Hasher, nil) + smt.atomicUpdate = false + + // Add data to empty trie + keys := getFreshData(10, 32) + values := getFreshData(10, 32) + ch := make(chan mresult, 1) + smt.update(smt.Root, keys, values, nil, 0, smt.TrieHeight, ch) + res := <-ch + root := res.update + + // Check all keys have been stored + for i, key := range keys { + value, _ := smt.get(root, key, nil, 0, smt.TrieHeight) + if !bytes.Equal(values[i], value) { + t.Fatal("value not updated") + } + } + + // Append to the trie + newKeys := getFreshData(5, 32) + newValues := getFreshData(5, 32) + ch = make(chan mresult, 1) + smt.update(root, newKeys, newValues, nil, 0, smt.TrieHeight, ch) + res = <-ch + newRoot := res.update + if bytes.Equal(root, newRoot) { + t.Fatal("trie not updated") + } + for i, newKey := range newKeys { + newValue, _ := smt.get(newRoot, newKey, nil, 0, smt.TrieHeight) + if !bytes.Equal(newValues[i], newValue) { + t.Fatal("failed to get value") + } + } +} + +func TestTrieAtomicUpdate(t *testing.T) { + smt := NewTrie(nil, Hasher, nil) + smt.CacheHeightLimit = 0 + keys := getFreshData(1, 32) + values := getFreshData(1, 32) + root, _ := smt.AtomicUpdate(keys, values) + updatedNb := len(smt.db.updatedNodes) + cacheNb := len(smt.db.liveCache) + newvalues := getFreshData(1, 32) + smt.AtomicUpdate(keys, newvalues) + if len(smt.db.updatedNodes) != 2*updatedNb { + t.Fatal("Atomic update doesnt store all tries") + } + if len(smt.db.liveCache) != cacheNb { + t.Fatal("Cache size should remain the same") + } + + // check keys of previous atomic update are accessible in + // updated nodes with root. + smt.atomicUpdate = false + for i, key := range keys { + value, _ := smt.get(root, key, nil, 0, smt.TrieHeight) + if !bytes.Equal(values[i], value) { + t.Fatal("failed to get value") + } + } +} + +func TestTriePublicUpdateAndGet(t *testing.T) { + smt := NewTrie(nil, Hasher, nil) + smt.CacheHeightLimit = 0 + // Add data to empty trie + keys := getFreshData(20, 32) + values := getFreshData(20, 32) + root, _ := smt.Update(keys, values) + updatedNb := len(smt.db.updatedNodes) + cacheNb := len(smt.db.liveCache) + + // Check all keys have been stored + for i, key := range keys { + value, _ := smt.Get(key) + if !bytes.Equal(values[i], value) { + t.Fatal("trie not updated") + } + } + if !bytes.Equal(root, smt.Root) { + t.Fatal("Root not stored") + } + + newValues := getFreshData(20, 32) + smt.Update(keys, newValues) + + if len(smt.db.updatedNodes) != updatedNb { + t.Fatal("multiple updates don't actualise updated nodes") + } + if len(smt.db.liveCache) != cacheNb { + t.Fatal("multiple updates don't actualise liveCache") + } + // Check all keys have been modified + for i, key := range keys { + value, _ := smt.Get(key) + if !bytes.Equal(newValues[i], value) { + t.Fatal("trie not updated") + } + } +} + +func TestGetWithRoot(t *testing.T) { + dbPath := t.TempDir() + st := db.NewDB(db.BadgerImpl, dbPath) + smt := NewTrie(nil, Hasher, st) + smt.CacheHeightLimit = 0 + + // Add data to empty trie + keys := getFreshData(20, 32) + values := getFreshData(20, 32) + root, _ := smt.Update(keys, values) + + // Check all keys have been stored + for i, key := range keys { + value, _ := smt.Get(key) + if !bytes.Equal(values[i], value) { + t.Fatal("trie not updated") + } + } + if !bytes.Equal(root, smt.Root) { + t.Fatal("Root not stored") + } + if err := smt.Commit(); err != nil { + t.Fatal(err) + } + // Delete two values (0 and 1) + if _, err := smt.Update([][]byte{keys[0], keys[1]}, [][]byte{DefaultLeaf, DefaultLeaf}); err != nil { + t.Fatal(err) + } + + // Change one value + oldValue3 := make([]byte, 32) + copy(oldValue3, values[3]) + values[3] = getFreshData(1, 32)[0] + if _, err := smt.Update([][]byte{keys[3]}, [][]byte{values[3]}); err != nil { + t.Fatal(err) + } + + // Check root has been actually updated + if bytes.Equal(smt.Root, root) { + t.Fatal("root not updated") + } + + // Get the third value with the new root + v3, err := smt.GetWithRoot(keys[3], smt.Root) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(v3, values[3]) { + t.Fatalf("GetWithRoot did not keep the value: %x != %x", v3, values[3]) + } + + // Get the third value with the old root + v3, err = smt.GetWithRoot(keys[3], root) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(v3, oldValue3) { + t.Fatalf("GetWithRoot did not keep the value: %x != %x", v3, oldValue3) + } + st.Close() +} + +func TestTrieWalk(t *testing.T) { + dbPath := t.TempDir() + st := db.NewDB(db.BadgerImpl, dbPath) + + smt := NewTrie(nil, Hasher, st) + smt.CacheHeightLimit = 0 + // Add data to empty trie + keys := getFreshData(20, 32) + values := getFreshData(20, 32) + root, _ := smt.Update(keys, values) + + // Check all keys have been stored + for i, key := range keys { + value, _ := smt.Get(key) + if !bytes.Equal(values[i], value) { + t.Fatal("trie not updated") + } + } + if !bytes.Equal(root, smt.Root) { + t.Fatal("Root not stored") + } + + // Walk over the whole tree and compare the values + i := 0 + if err := smt.Walk(nil, func(v *WalkResult) int32 { + if !bytes.Equal(v.Value, values[i]) { + t.Fatalf("walk value does not match %x != %x", v.Value, values[i]) + } + if !bytes.Equal(v.Key, keys[i]) { + t.Fatalf("walk key does not match %x != %x", v.Key, keys[i]) + } + i++ + return 0 + }); err != nil { + t.Fatal(err) + } + + // Delete two values (0 and 3) + if _, err := smt.Update([][]byte{keys[0], keys[3]}, [][]byte{DefaultLeaf, DefaultLeaf}); err != nil { + t.Fatal(err) + } + + // Delete two elements and walk again + i = 1 + if err := smt.Walk(nil, func(v *WalkResult) int32 { + if i == 3 { + i++ + } + if !bytes.Equal(v.Value, values[i]) { + t.Fatalf("walk value does not match %x == %x\n", v.Value, values[i]) + } + if !bytes.Equal(v.Key, keys[i]) { + t.Fatalf("walk key does not match %x == %x\n", v.Key, keys[i]) + } + i++ + return 0 + }); err != nil { + t.Fatal(err) + } + + // Add one new value to preivous deleted key + values[3] = getFreshData(1, 32)[0] + if _, err := smt.Update([][]byte{keys[3]}, [][]byte{values[3]}); err != nil { + t.Fatal(err) + } + + // Walk and check again + i = 1 + if err := smt.Walk(nil, func(v *WalkResult) int32 { + if !bytes.Equal(v.Value, values[i]) { + t.Fatalf("walk value does not match %x != %x\n", v.Value, values[i]) + } + if !bytes.Equal(v.Key, keys[i]) { + t.Fatalf("walk key does not match %x != %x\n", v.Key, keys[i]) + } + i++ + return 0 + }); err != nil { + t.Fatal(err) + } + + // Find a specific value and test stop + i = 0 + if err := smt.Walk(nil, func(v *WalkResult) int32 { + if bytes.Equal(v.Value, values[5]) { + return 1 + } + i++ + return 0 + }); err != nil { + t.Fatal(err) + } + if i != 4 { + t.Fatalf("Needed more iterations on walk than expected: %d != 4", i) + } + + st.Close() +} + +func TestTrieDelete(t *testing.T) { + smt := NewTrie(nil, Hasher, nil) + // Add data to empty trie + keys := getFreshData(20, 32) + values := getFreshData(20, 32) + ch := make(chan mresult, 1) + smt.update(smt.Root, keys, values, nil, 0, smt.TrieHeight, ch) + result := <-ch + root := result.update + value, _ := smt.get(root, keys[0], nil, 0, smt.TrieHeight) + if !bytes.Equal(values[0], value) { + t.Fatal("trie not updated") + } + + // Delete from trie + // To delete a key, just set it's value to Default leaf hash. + ch = make(chan mresult, 1) + smt.update(root, keys[0:1], [][]byte{DefaultLeaf}, nil, 0, smt.TrieHeight, ch) + result = <-ch + updatedNb := len(smt.db.updatedNodes) + newRoot := result.update + newValue, _ := smt.get(newRoot, keys[0], nil, 0, smt.TrieHeight) + if len(newValue) != 0 { + t.Fatal("Failed to delete from trie") + } + // Remove deleted key from keys and check root with a clean trie. + smt2 := NewTrie(nil, Hasher, nil) + ch = make(chan mresult, 1) + smt2.update(smt.Root, keys[1:], values[1:], nil, 0, smt.TrieHeight, ch) + result = <-ch + cleanRoot := result.update + if !bytes.Equal(newRoot, cleanRoot) { + t.Fatal("roots mismatch") + } + + if len(smt2.db.updatedNodes) != updatedNb { + t.Fatal("deleting doesn't actualise updated nodes") + } + + //Empty the trie + var newValues [][]byte + for i := 0; i < 20; i++ { + newValues = append(newValues, DefaultLeaf) + } + ch = make(chan mresult, 1) + smt.update(root, keys, newValues, nil, 0, smt.TrieHeight, ch) + result = <-ch + root = result.update + //if !bytes.Equal(smt.DefaultHash(256), root) { + if len(root) != 0 { + t.Fatal("empty trie root hash not correct") + } + + // Test deleting an already empty key + smt = NewTrie(nil, Hasher, nil) + keys = getFreshData(2, 32) + values = getFreshData(2, 32) + root, _ = smt.Update(keys, values) + key0 := make([]byte, 32, 32) + key1 := make([]byte, 32, 32) + smt.Update([][]byte{key0, key1}, [][]byte{DefaultLeaf, DefaultLeaf}) + if !bytes.Equal(root, smt.Root) { + t.Fatal("deleting a default key shouldnt' modify the tree") + } +} + +// test updating and deleting at the same time +func TestTrieUpdateAndDelete(t *testing.T) { + smt := NewTrie(nil, Hasher, nil) + smt.CacheHeightLimit = 0 + key0 := make([]byte, 32, 32) + values := getFreshData(1, 32) + root, _ := smt.Update([][]byte{key0}, values) + cacheNb := len(smt.db.liveCache) + updatedNb := len(smt.db.updatedNodes) + smt.atomicUpdate = false + _, _, k, v, isShortcut, _ := smt.loadChildren(root, smt.TrieHeight, 0, nil) + if !isShortcut || !bytes.Equal(k[:HashLength], key0) || !bytes.Equal(v[:HashLength], values[0]) { + t.Fatal("leaf shortcut didn't move up to root") + } + + key1 := make([]byte, 32, 32) + // set the last bit + bitSet(key1, 255) + keys := [][]byte{key0, key1} + values = [][]byte{DefaultLeaf, getFreshData(1, 32)[0]} + root, _ = smt.Update(keys, values) + + if len(smt.db.liveCache) != cacheNb { + t.Fatal("number of cache nodes not correct after delete") + } + if len(smt.db.updatedNodes) != updatedNb { + t.Fatal("number of cache nodes not correct after delete") + } + + smt.atomicUpdate = false + _, _, k, v, isShortcut, _ = smt.loadChildren(root, smt.TrieHeight, 0, nil) + if !isShortcut || !bytes.Equal(k[:HashLength], key1) || !bytes.Equal(v[:HashLength], values[1]) { + t.Fatal("leaf shortcut didn't move up to root") + } +} + +func TestTrieMerkleProof(t *testing.T) { + smt := NewTrie(nil, Hasher, nil) + // Add data to empty trie + keys := getFreshData(10, 32) + values := getFreshData(10, 32) + smt.Update(keys, values) + + for i, key := range keys { + ap, _, k, v, _ := smt.MerkleProof(key) + if !smt.VerifyInclusion(ap, key, values[i]) { + t.Fatalf("failed to verify inclusion proof") + } + if !bytes.Equal(key, k) && !bytes.Equal(values[i], v) { + t.Fatalf("merkle proof didnt return the correct key-value pair") + } + } + emptyKey := Hasher([]byte("non-member")) + ap, included, proofKey, proofValue, _ := smt.MerkleProof(emptyKey) + if included { + t.Fatalf("failed to verify non inclusion proof") + } + if !smt.VerifyNonInclusion(ap, emptyKey, proofValue, proofKey) { + t.Fatalf("failed to verify non inclusion proof") + } +} + +func TestTrieMerkleProofCompressed(t *testing.T) { + smt := NewTrie(nil, Hasher, nil) + // Add data to empty trie + keys := getFreshData(10, 32) + values := getFreshData(10, 32) + smt.Update(keys, values) + + for i, key := range keys { + bitmap, ap, length, _, k, v, _ := smt.MerkleProofCompressed(key) + if !smt.VerifyInclusionC(bitmap, key, values[i], ap, length) { + t.Fatalf("failed to verify inclusion proof") + } + if !bytes.Equal(key, k) && !bytes.Equal(values[i], v) { + t.Fatalf("merkle proof didnt return the correct key-value pair") + } + } + emptyKey := Hasher([]byte("non-member")) + bitmap, ap, length, included, proofKey, proofValue, _ := smt.MerkleProofCompressed(emptyKey) + if included { + t.Fatalf("failed to verify non inclusion proof") + } + if !smt.VerifyNonInclusionC(ap, length, bitmap, emptyKey, proofValue, proofKey) { + t.Fatalf("failed to verify non inclusion proof") + } +} + +func TestTrieCommit(t *testing.T) { + dbPath := path.Join(".aergo", "db") + if _, err := os.Stat(dbPath); os.IsNotExist(err) { + _ = os.MkdirAll(dbPath, 0711) + } + st := db.NewDB(db.BadgerImpl, dbPath) + + smt := NewTrie(nil, Hasher, st) + keys := getFreshData(10, 32) + values := getFreshData(10, 32) + smt.Update(keys, values) + smt.Commit() + // liveCache is deleted so the key is fetched in badger db + smt.db.liveCache = make(map[Hash][][]byte) + for i, key := range keys { + value, _ := smt.Get(key) + if !bytes.Equal(value, values[i]) { + t.Fatal("failed to get value in committed db") + } + } + st.Close() + os.RemoveAll(".aergo") +} + +func TestTrieStageUpdates(t *testing.T) { + dbPath := path.Join(".aergo", "db") + if _, err := os.Stat(dbPath); os.IsNotExist(err) { + _ = os.MkdirAll(dbPath, 0711) + } + st := db.NewDB(db.BadgerImpl, dbPath) + + smt := NewTrie(nil, Hasher, st) + keys := getFreshData(10, 32) + values := getFreshData(10, 32) + smt.Update(keys, values) + txn := st.NewTx() + smt.StageUpdates(txn.(DbTx)) + txn.Commit() + // liveCache is deleted so the key is fetched in badger db + smt.db.liveCache = make(map[Hash][][]byte) + for i, key := range keys { + value, _ := smt.Get(key) + if !bytes.Equal(value, values[i]) { + t.Fatal("failed to get value in committed db") + } + } + st.Close() + os.RemoveAll(".aergo") +} + +func TestTrieRevert(t *testing.T) { + dbPath := path.Join(".aergo", "db") + if _, err := os.Stat(dbPath); os.IsNotExist(err) { + _ = os.MkdirAll(dbPath, 0711) + } + st := db.NewDB(db.BadgerImpl, dbPath) + + smt := NewTrie(nil, Hasher, st) + + // Edge case : Test that revert doesnt delete shortcut nodes + // when moved to a different position in tree + key0 := make([]byte, 32, 32) + key1 := make([]byte, 32, 32) + // setting the bit at 251 creates 2 shortcut batches at height 252 + bitSet(key1, 251) + values := getFreshData(2, 32) + keys := [][]byte{key0, key1} + root, _ := smt.Update([][]byte{key0}, [][]byte{values[0]}) + smt.Commit() + root2, _ := smt.Update([][]byte{key1}, [][]byte{values[1]}) + smt.Commit() + smt.Revert(root) + if len(smt.db.Store.Get(root)) == 0 { + t.Fatal("shortcut node shouldnt be deleted by revert") + } + if len(smt.db.Store.Get(root2)) != 0 { + t.Fatal("reverted root should have been deleted") + } + key1 = make([]byte, 32, 32) + // setting the bit at 255 stores the keys as the tip + bitSet(key1, 255) + smt.Update([][]byte{key1}, [][]byte{values[1]}) + smt.Commit() + smt.Revert(root) + if len(smt.db.Store.Get(root)) == 0 { + t.Fatal("shortcut node shouldnt be deleted by revert") + } + + // Test all nodes are reverted in the usual case + // Add data to empty trie + keys = getFreshData(10, 32) + values = getFreshData(10, 32) + root, _ = smt.Update(keys, values) + smt.Commit() + + // Update the values + newValues := getFreshData(10, 32) + smt.Update(keys, newValues) + updatedNodes1 := smt.db.updatedNodes + smt.Commit() + newKeys := getFreshData(10, 32) + newValues = getFreshData(10, 32) + smt.Update(newKeys, newValues) + updatedNodes2 := smt.db.updatedNodes + smt.Commit() + + smt.Revert(root) + + if !bytes.Equal(smt.Root, root) { + t.Fatal("revert failed") + } + if len(smt.pastTries) != 2 { // contains empty trie + reverted trie + t.Fatal("past tries not updated after revert") + } + // Check all keys have been reverted + for i, key := range keys { + value, _ := smt.Get(key) + if !bytes.Equal(values[i], value) { + t.Fatal("revert failed, values not updated") + } + } + if len(smt.db.liveCache) != 0 { + t.Fatal("live cache not reset after revert") + } + // Check all reverted nodes have been deleted + for node, _ := range updatedNodes2 { + if len(smt.db.Store.Get(node[:])) != 0 { + t.Fatal("nodes not deleted from database", node) + } + } + for node, _ := range updatedNodes1 { + if len(smt.db.Store.Get(node[:])) != 0 { + t.Fatal("nodes not deleted from database", node) + } + } + st.Close() + os.RemoveAll(".aergo") +} + +func TestTrieRaisesError(t *testing.T) { + dbPath := path.Join(".aergo", "db") + if _, err := os.Stat(dbPath); os.IsNotExist(err) { + _ = os.MkdirAll(dbPath, 0711) + } + st := db.NewDB(db.BadgerImpl, dbPath) + + smt := NewTrie(nil, Hasher, st) + // Add data to empty trie + keys := getFreshData(10, 32) + values := getFreshData(10, 32) + smt.Update(keys, values) + smt.db.liveCache = make(map[Hash][][]byte) + smt.db.updatedNodes = make(map[Hash][][]byte) + + // Check errors are raised is a keys is not in cache nore db + for _, key := range keys { + _, err := smt.Get(key) + if err == nil { + t.Fatal("Error not created if database doesnt have a node") + } + } + _, _, _, _, _, _, err := smt.MerkleProofCompressed(keys[0]) + if err == nil { + t.Fatal("Error not created if database doesnt have a node") + } + _, err = smt.Update(keys, values) + if err == nil { + t.Fatal("Error not created if database doesnt have a node") + } + st.Close() + os.RemoveAll(".aergo") + + smt = NewTrie(nil, Hasher, nil) + err = smt.Commit() + if err == nil { + t.Fatal("Error not created if database not connected") + } + smt.db.liveCache = make(map[Hash][][]byte) + smt.atomicUpdate = false + _, _, _, _, _, err = smt.loadChildren(make([]byte, 32, 32), smt.TrieHeight, 0, nil) + if err == nil { + t.Fatal("Error not created if database not connected") + } + err = smt.LoadCache(make([]byte, 32)) + if err == nil { + t.Fatal("Error not created if database not connected") + } +} + +func TestTrieLoadCache(t *testing.T) { + dbPath := path.Join(".aergo", "db") + if _, err := os.Stat(dbPath); os.IsNotExist(err) { + _ = os.MkdirAll(dbPath, 0711) + } + st := db.NewDB(db.BadgerImpl, dbPath) + + smt := NewTrie(nil, Hasher, st) + // Test size of cache + smt.CacheHeightLimit = 0 + key0 := make([]byte, 32, 32) + key1 := make([]byte, 32, 32) + bitSet(key1, 255) + values := getFreshData(2, 32) + smt.Update([][]byte{key0, key1}, values) + if len(smt.db.liveCache) != 66 { + // the nodes are at the tip, so 64 + 2 = 66 + t.Fatal("cache size incorrect") + } + + // Add data to empty trie + keys := getFreshData(10, 32) + values = getFreshData(10, 32) + smt.Update(keys, values) + smt.Commit() + + // Simulate node restart by deleting and loading cache + cacheSize := len(smt.db.liveCache) + smt.db.liveCache = make(map[Hash][][]byte) + + err := smt.LoadCache(smt.Root) + + if err != nil { + t.Fatal(err) + } + if cacheSize != len(smt.db.liveCache) { + t.Fatal("Cache loading from db incorrect") + } + st.Close() + os.RemoveAll(".aergo") +} + +func TestHeight0LeafShortcut(t *testing.T) { + keySize := 32 + smt := NewTrie(nil, Hasher, nil) + // Add 2 sibling keys that will be stored at height 0 + key0 := make([]byte, keySize, keySize) + key1 := make([]byte, keySize, keySize) + bitSet(key1, keySize*8-1) + keys := [][]byte{key0, key1} + values := getFreshData(2, 32) + smt.Update(keys, values) + updatedNb := len(smt.db.updatedNodes) + + // Check all keys have been stored + for i, key := range keys { + value, _ := smt.Get(key) + if !bytes.Equal(values[i], value) { + t.Fatal("trie not updated") + } + } + bitmap, ap, length, _, k, v, err := smt.MerkleProofCompressed(key1) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(key1, k) && !bytes.Equal(values[1], v) { + t.Fatalf("merkle proof didnt return the correct key-value pair") + } + if length != smt.TrieHeight { + t.Fatal("proof should have length equal to trie height for a leaf shortcut") + } + if !smt.VerifyInclusionC(bitmap, key1, values[1], ap, length) { + t.Fatal("failed to verify inclusion proof") + } + + // Delete one key and check that the remaining one moved up to the root of the tree + newRoot, _ := smt.AtomicUpdate(keys[0:1], [][]byte{DefaultLeaf}) + + // Nb of updated nodes remains same because the new shortcut root was already stored at height 0. + if len(smt.db.updatedNodes) != updatedNb { + fmt.Println(len(smt.db.updatedNodes), updatedNb) + t.Fatal("number of cache nodes not correct after delete") + } + smt.atomicUpdate = false + _, _, k, v, isShortcut, err := smt.loadChildren(newRoot, smt.TrieHeight, 0, nil) + if err != nil { + t.Fatal(err) + } + if !isShortcut || !bytes.Equal(k[:HashLength], key1) || !bytes.Equal(v[:HashLength], values[1]) { + t.Fatal("leaf shortcut didn't move up to root") + } + + _, _, length, _, k, v, _ = smt.MerkleProofCompressed(key1) + if length != 0 { + t.Fatal("proof should have length equal to trie height for a leaf shortcut") + } + if !bytes.Equal(key1, k) && !bytes.Equal(values[1], v) { + t.Fatalf("merkle proof didnt return the correct key-value pair") + } +} + +func TestStash(t *testing.T) { + dbPath := path.Join(".aergo", "db") + if _, err := os.Stat(dbPath); os.IsNotExist(err) { + _ = os.MkdirAll(dbPath, 0711) + } + st := db.NewDB(db.BadgerImpl, dbPath) + smt := NewTrie(nil, Hasher, st) + // Add data to empty trie + keys := getFreshData(20, 32) + values := getFreshData(20, 32) + root, _ := smt.Update(keys, values) + cacheSize := len(smt.db.liveCache) + smt.Commit() + if len(smt.pastTries) != 1 { + t.Fatal("Past tries not updated after commit") + } + values = getFreshData(20, 32) + smt.Update(keys, values) + smt.Stash(true) + if len(smt.pastTries) != 1 { + t.Fatal("Past tries not updated after commit") + } + if !bytes.Equal(smt.Root, root) { + t.Fatal("Trie not rolled back") + } + if len(smt.db.updatedNodes) != 0 { + t.Fatal("Trie not rolled back") + } + if len(smt.db.liveCache) != cacheSize { + t.Fatal("Trie not rolled back") + } + keys = getFreshData(20, 32) + values = getFreshData(20, 32) + smt.AtomicUpdate(keys, values) + values = getFreshData(20, 32) + smt.AtomicUpdate(keys, values) + if len(smt.pastTries) != 3 { + t.Fatal("Past tries not updated after commit") + } + smt.Stash(true) + if !bytes.Equal(smt.Root, root) { + t.Fatal("Trie not rolled back") + } + if len(smt.db.updatedNodes) != 0 { + t.Fatal("Trie not rolled back") + } + if len(smt.db.liveCache) != cacheSize { + t.Fatal("Trie not rolled back") + } + if len(smt.pastTries) != 1 { + t.Fatal("Past tries not updated after commit") + } + st.Close() + os.RemoveAll(".aergo") +} + +func benchmark10MAccounts10Ktps(smt *Trie, b *testing.B) { + //b.ReportAllocs() + keys := getFreshData(100, 32) + values := getFreshData(100, 32) + smt.Update(keys, values) + fmt.Println("\nLoading b.N x 1000 accounts") + for i := 0; i < b.N; i++ { + newkeys := getFreshData(1000, 32) + newvalues := getFreshData(1000, 32) + start := time.Now() + smt.Update(newkeys, newvalues) + end := time.Now() + smt.Commit() + end2 := time.Now() + for j, key := range newkeys { + val, _ := smt.Get(key) + if !bytes.Equal(val, newvalues[j]) { + b.Fatal("new key not included") + } + } + end3 := time.Now() + elapsed := end.Sub(start) + elapsed2 := end2.Sub(end) + elapsed3 := end3.Sub(end2) + var m runtime.MemStats + runtime.ReadMemStats(&m) + fmt.Println(i, " : update time : ", elapsed, "commit time : ", elapsed2, + "\n1000 Get time : ", elapsed3, + "\ndb read : ", smt.LoadDbCounter, " cache read : ", smt.LoadCacheCounter, + "\ncache size : ", len(smt.db.liveCache), + "\nRAM : ", m.Sys/1024/1024, " MiB") + } +} + +//go test -run=xxx -bench=. -benchmem -test.benchtime=20s +func BenchmarkCacheHeightLimit233(b *testing.B) { + dbPath := path.Join(".aergo", "db") + if _, err := os.Stat(dbPath); os.IsNotExist(err) { + _ = os.MkdirAll(dbPath, 0711) + } + st := db.NewDB(db.BadgerImpl, dbPath) + smt := NewTrie(nil, Hasher, st) + smt.CacheHeightLimit = 233 + benchmark10MAccounts10Ktps(smt, b) + st.Close() + os.RemoveAll(".aergo") +} +func BenchmarkCacheHeightLimit238(b *testing.B) { + dbPath := path.Join(".aergo", "db") + if _, err := os.Stat(dbPath); os.IsNotExist(err) { + _ = os.MkdirAll(dbPath, 0711) + } + st := db.NewDB(db.BadgerImpl, dbPath) + smt := NewTrie(nil, Hasher, st) + smt.CacheHeightLimit = 238 + benchmark10MAccounts10Ktps(smt, b) + st.Close() + os.RemoveAll(".aergo") +} +func BenchmarkCacheHeightLimit245(b *testing.B) { + dbPath := path.Join(".aergo", "db") + if _, err := os.Stat(dbPath); os.IsNotExist(err) { + _ = os.MkdirAll(dbPath, 0711) + } + st := db.NewDB(db.BadgerImpl, dbPath) + smt := NewTrie(nil, Hasher, st) + smt.CacheHeightLimit = 245 + benchmark10MAccounts10Ktps(smt, b) + st.Close() + os.RemoveAll(".aergo") +} + +func getFreshData(size, length int) [][]byte { + var data [][]byte + for i := 0; i < size; i++ { + key := make([]byte, 32) + _, err := rand.Read(key) + if err != nil { + panic(err) + } + data = append(data, Hasher(key)[:length]) + } + sort.Sort(DataArray(data)) + return data +} diff --git a/trie_tools.go b/trie_tools.go new file mode 100644 index 0000000..4241fbd --- /dev/null +++ b/trie_tools.go @@ -0,0 +1,273 @@ +/** + * @file + * @copyright defined in aergo/LICENSE.txt + */ + +package trie + +import ( + "bytes" + "fmt" + "sync" + "sync/atomic" + + "github.com/aergoio/aergo-lib/db" +) + +// LoadCache loads the first layers of the merkle tree given a root +// This is called after a node restarts so that it doesnt become slow with db reads +// LoadCache also updates the Root with the given root. +func (s *Trie) LoadCache(root []byte) error { + if s.db.Store == nil { + return fmt.Errorf("DB not connected to trie") + } + s.db.liveCache = make(map[Hash][][]byte) + ch := make(chan error, 1) + s.loadCache(root, nil, 0, s.TrieHeight, ch) + s.Root = root + return <-ch +} + +// loadCache loads the first layers of the merkle tree given a root +func (s *Trie) loadCache(root []byte, batch [][]byte, iBatch, height int, ch chan<- (error)) { + if height < s.CacheHeightLimit || len(root) == 0 { + ch <- nil + return + } + if height%4 == 0 { + // Load the node from db + s.db.lock.Lock() + dbval := s.db.Store.Get(root[:HashLength]) + s.db.lock.Unlock() + if len(dbval) == 0 { + ch <- fmt.Errorf("the trie node %x is unavailable in the disk db, db may be corrupted", root) + return + } + //Store node in cache. + var node Hash + copy(node[:], root) + batch = s.parseBatch(dbval) + s.db.liveMux.Lock() + s.db.liveCache[node] = batch + s.db.liveMux.Unlock() + iBatch = 0 + if batch[0][0] == 1 { + // if height == 0 this will also return + ch <- nil + return + } + } + if iBatch != 0 && batch[iBatch][HashLength] == 1 { + // Check if node is a leaf node + ch <- nil + } else { + // Load subtree + lnode, rnode := batch[2*iBatch+1], batch[2*iBatch+2] + + lch := make(chan error, 1) + rch := make(chan error, 1) + go s.loadCache(lnode, batch, 2*iBatch+1, height-1, lch) + go s.loadCache(rnode, batch, 2*iBatch+2, height-1, rch) + if err := <-lch; err != nil { + ch <- err + return + } + if err := <-rch; err != nil { + ch <- err + return + } + ch <- nil + } +} + +// Get fetches the value of a key by going down the current trie root. +func (s *Trie) Get(key []byte) ([]byte, error) { + s.lock.RLock() + defer s.lock.RUnlock() + s.atomicUpdate = false + return s.get(s.Root, key, nil, 0, s.TrieHeight) +} + +// GetWithRoot fetches the value of a key by going down for the specified root. +func (s *Trie) GetWithRoot(key []byte, root []byte) ([]byte, error) { + s.lock.RLock() + defer s.lock.RUnlock() + s.atomicUpdate = false + if root == nil { + root = s.Root + } + return s.get(root, key, nil, 0, s.TrieHeight) +} + +// get fetches the value of a key given a trie root +func (s *Trie) get(root, key []byte, batch [][]byte, iBatch, height int) ([]byte, error) { + if len(root) == 0 { + // the trie does not contain the key + return nil, nil + } + // Fetch the children of the node + batch, iBatch, lnode, rnode, isShortcut, err := s.loadChildren(root, height, iBatch, batch) + if err != nil { + return nil, err + } + if isShortcut { + if bytes.Equal(lnode[:HashLength], key) { + return rnode[:HashLength], nil + } + // also returns nil if height 0 is not a shortcut + return nil, nil + } + if bitIsSet(key, s.TrieHeight-height) { + return s.get(rnode, key, batch, 2*iBatch+2, height-1) + } + return s.get(lnode, key, batch, 2*iBatch+1, height-1) +} + +// WalkResult contains the key and value obtained with a Walk() operation +type WalkResult struct { + Value []byte + Key []byte +} + +// Walk finds all the trie stored values from left to right and calls callback. +// If callback returns a number diferent from 0, the walk will stop, else it will continue. +func (s *Trie) Walk(root []byte, callback func(*WalkResult) int32) error { + walkc := make(chan *WalkResult) + s.lock.RLock() + defer s.lock.RUnlock() + if root == nil { + root = s.Root + } + s.atomicUpdate = false + finishedWalk := make(chan (bool), 1) + stop := int32(0) + wg := sync.WaitGroup{} // WaitGroup to avoid Walk() return before all callback executions are finished. + go func() { + for { + select { + case <-finishedWalk: + return + case value := <-walkc: + stopCallback := callback(value) + wg.Done() + // In order to avoid data races we need to check the current value of stop, while at the + // same time we store our callback value. If our callback value is 0 means that we have + // override the previous non-zero value, so we need to restore it. + if cv := atomic.SwapInt32(&stop, stopCallback); cv != 0 || stopCallback != 0 { + if stopCallback == 0 { + atomic.StoreInt32(&stop, cv) + } + // We need to return (instead of break) in order to stop iterating if some callback returns non zero + return + } + } + } + }() + err := s.walk(walkc, &stop, root, nil, 0, s.TrieHeight, &wg) + finishedWalk <- true + wg.Wait() + return err +} + +// walk fetches the value of a key given a trie root +func (s *Trie) walk(walkc chan (*WalkResult), stop *int32, root []byte, batch [][]byte, ibatch, height int, wg *sync.WaitGroup) error { + if len(root) == 0 || atomic.LoadInt32(stop) != 0 { + // The sub tree is empty or stop walking + return nil + } + // Fetch the children of the node + batch, ibatch, lnode, rnode, isShortcut, err := s.loadChildren(root, height, ibatch, batch) + if err != nil { + return err + } + if isShortcut { + wg.Add(1) + walkc <- &WalkResult{Value: rnode[:HashLength], Key: lnode[:HashLength]} + return nil + } + // Go left + if err := s.walk(walkc, stop, lnode, batch, 2*ibatch+1, height-1, wg); err != nil { + return err + } + // Go Right + if err := s.walk(walkc, stop, rnode, batch, 2*ibatch+2, height-1, wg); err != nil { + return err + } + return nil +} + +// TrieRootExists returns true if the root exists in Database. +func (s *Trie) TrieRootExists(root []byte) bool { + s.db.lock.RLock() + dbval := s.db.Store.Get(root) + s.db.lock.RUnlock() + if len(dbval) != 0 { + return true + } + return false +} + +// Commit stores the updated nodes to disk. +// Commit should be called for every block otherwise past tries +// are not recorded and it is not possible to revert to them +// (except if AtomicUpdate is used, which records every state). +func (s *Trie) Commit() error { + if s.db.Store == nil { + return fmt.Errorf("DB not connected to trie") + } + // NOTE The tx interface doesnt handle ErrTxnTooBig + txn := s.db.Store.NewTx().(DbTx) + s.StageUpdates(txn) + txn.(db.Transaction).Commit() + return nil +} + +// StageUpdates requires a database transaction as input +// Unlike Commit(), it doesnt commit the transaction +// the database transaction MUST be commited otherwise the +// state ROOT will not exist. +func (s *Trie) StageUpdates(txn DbTx) { + s.lock.Lock() + defer s.lock.Unlock() + // Commit the new nodes to database, clear updatedNodes and store the Root in pastTries for reverts. + if !s.atomicUpdate { + // if previously AtomicUpdate was called, then past tries is already updated + s.updatePastTries() + } + s.db.commit(&txn) + + s.db.updatedNodes = make(map[Hash][][]byte) + s.prevRoot = s.Root +} + +// Stash rolls back the changes made by previous updates +// and loads the cache from before the rollback. +func (s *Trie) Stash(rollbackCache bool) error { + s.lock.Lock() + defer s.lock.Unlock() + s.Root = s.prevRoot + if rollbackCache { + // Making a temporary liveCache requires it to be copied, so it's quicker + // to just load the cache from DB if a block state root was incorrect. + s.db.liveCache = make(map[Hash][][]byte) + ch := make(chan error, 1) + s.loadCache(s.Root, nil, 0, s.TrieHeight, ch) + err := <-ch + if err != nil { + return err + } + } else { + s.db.liveCache = make(map[Hash][][]byte) + } + s.db.updatedNodes = make(map[Hash][][]byte) + // also stash past tries created by Atomic update + for i := len(s.pastTries) - 1; i >= 0; i-- { + if bytes.Equal(s.pastTries[i], s.Root) { + break + } else { + // remove from past tries + s.pastTries = s.pastTries[:len(s.pastTries)-1] + } + } + return nil +} diff --git a/util.go b/util.go new file mode 100644 index 0000000..7c93b39 --- /dev/null +++ b/util.go @@ -0,0 +1,42 @@ +/** + * @file + * @copyright defined in aergo/LICENSE.txt + */ + +package trie + +import ( + "bytes" +) + +var ( + // Trie default value : [byte(0)] + DefaultLeaf = []byte{0} +) + +const ( + HashLength = 32 + maxPastTries = 300 +) + +type Hash [HashLength]byte + +func bitIsSet(bits []byte, i int) bool { + return bits[i/8]&(1<