github.com/annchain/OG@v0.0.9/trie/proof.go (about)

     1  // Copyright 2015 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package trie
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"github.com/annchain/OG/arefactor/og/types"
    23  	ogcrypto2 "github.com/annchain/OG/deprecated/ogcrypto"
    24  	"github.com/annchain/OG/ogdb"
    25  	log "github.com/sirupsen/logrus"
    26  )
    27  
    28  // Prove constructs a merkle proof for key. The result contains all encoded nodes
    29  // on the path to the value at key. The value itself is also included in the last
    30  // node and can be retrieved by verifying the proof.
    31  //
    32  // If the trie does not contain a value for key, the returned proof contains all
    33  // nodes of the longest existing prefix of the key (at least the root node), ending
    34  // with the node that proves the absence of the key.
    35  func (t *Trie) Prove(key []byte, fromLevel uint, proofDb ogdb.Putter) error {
    36  	// Collect all nodes on the path to key.
    37  	key = keybytesToHex(key)
    38  	nodes := []Node{}
    39  	tn := t.root
    40  	for len(key) > 0 && tn != nil {
    41  		switch n := tn.(type) {
    42  		case *ShortNode:
    43  			if len(key) < len(n.Key) || !bytes.Equal(n.Key, key[:len(n.Key)]) {
    44  				// The trie doesn't contain the key.
    45  				tn = nil
    46  			} else {
    47  				tn = n.Val
    48  				key = key[len(n.Key):]
    49  			}
    50  			nodes = append(nodes, n)
    51  		case *FullNode:
    52  			tn = n.Children[key[0]]
    53  			key = key[1:]
    54  			nodes = append(nodes, n)
    55  		case HashNode:
    56  			var err error
    57  			tn, err = t.resolveHash(n, nil)
    58  			if err != nil {
    59  				log.Error(fmt.Sprintf("Unhandled trie error: %v", err))
    60  				return err
    61  			}
    62  		default:
    63  			panic(fmt.Sprintf("%T: invalid node: %v", tn, tn))
    64  		}
    65  	}
    66  	hasher := newHasher(0, 0, nil)
    67  	for i, n := range nodes {
    68  		// Don't bother checking for errors here since hasher panics
    69  		// if encoding doesn't work and we're not writing to any database.
    70  		n, _, _ = hasher.hashChildren(n, nil, false)
    71  		hn, _ := hasher.store(n, nil, false, false)
    72  		if hash, ok := hn.(HashNode); ok || i == 0 {
    73  			// If the node's database encoding is a hash (or is the
    74  			// root node), it becomes a proof element.
    75  			if fromLevel > 0 {
    76  				fromLevel--
    77  			} else {
    78  				enc := n.encodeNode()
    79  				// TODO
    80  				// delete this line later
    81  				// enc, _ := rlp.EncodeToBytes(n)
    82  				if !ok {
    83  					hash = ogcrypto2.Keccak256(enc)
    84  				}
    85  				proofDb.Put(hash, enc)
    86  			}
    87  		}
    88  	}
    89  	return nil
    90  }
    91  
    92  // Prove constructs a merkle proof for key. The result contains all encoded nodes
    93  // on the path to the value at key. The value itself is also included in the last
    94  // node and can be retrieved by verifying the proof.
    95  //
    96  // If the trie does not contain a value for key, the returned proof contains all
    97  // nodes of the longest existing prefix of the key (at least the root node), ending
    98  // with the node that proves the absence of the key.
    99  func (t *SecureTrie) Prove(key []byte, fromLevel uint, proofDb ogdb.Putter) error {
   100  	return t.trie.Prove(key, fromLevel, proofDb)
   101  }
   102  
   103  // VerifyProof checks merkle proofs. The given proof must contain the value for
   104  // key in a trie with the given root hash. VerifyProof returns an error if the
   105  // proof contains invalid trie nodes or the wrong value.
   106  func VerifyProof(rootHash types.Hash, key []byte, proofDb DatabaseReader) (value []byte, nodes int, err error) {
   107  	key = keybytesToHex(key)
   108  	wantHash := rootHash
   109  	for i := 0; ; i++ {
   110  		buf, _ := proofDb.Get(wantHash.ToBytes())
   111  		if buf == nil {
   112  			return nil, i, fmt.Errorf("proof node %d (hash %064x) missing", i, wantHash)
   113  		}
   114  		n, err := decodeNode(wantHash.ToBytes(), buf, 0)
   115  		if err != nil {
   116  			return nil, i, fmt.Errorf("bad proof node %d: %v", i, err)
   117  		}
   118  		keyrest, cld := get(n, key)
   119  		switch cld := cld.(type) {
   120  		case nil:
   121  			// The trie doesn't contain the key.
   122  			return nil, i, nil
   123  		case HashNode:
   124  			key = keyrest
   125  			copy(wantHash.ToBytes(), cld)
   126  		case ValueNode:
   127  			return cld, i + 1, nil
   128  		}
   129  	}
   130  }
   131  
   132  func get(tn Node, key []byte) ([]byte, Node) {
   133  	for {
   134  		switch n := tn.(type) {
   135  		case *ShortNode:
   136  			if len(key) < len(n.Key) || !bytes.Equal(n.Key, key[:len(n.Key)]) {
   137  				return nil, nil
   138  			}
   139  			tn = n.Val
   140  			key = key[len(n.Key):]
   141  		case *FullNode:
   142  			tn = n.Children[key[0]]
   143  			key = key[1:]
   144  		case HashNode:
   145  			return key, n
   146  		case nil:
   147  			return key, nil
   148  		case ValueNode:
   149  			return nil, n
   150  		default:
   151  			panic(fmt.Sprintf("%T: invalid node: %v", tn, tn))
   152  		}
   153  	}
   154  }