@@ -9,40 +9,50 @@ import (
9
9
fmt "fmt"
10
10
)
11
11
12
- func ApplyOps (ops []* ProofOp , args ... []byte ) ([]byte , error ) {
13
- first , rem := ops [0 ], ops [1 :]
14
- res , err := ApplyOp (first , args ... )
12
+ // Calculate determines the root hash that matches the given proof.
13
+ // You must validate the result is what you have in a header.
14
+ // Returns error if the calculations cannot be performed.
15
+ func (p * ExistanceProof ) Calculate () ([]byte , error ) {
16
+ if len (p .Steps ) == 0 {
17
+ return nil , fmt .Errorf ("Existence Proof needs at least one step" )
18
+ }
19
+
20
+ first , rem := p .Steps [0 ], p .Steps [1 :]
21
+ // first step takes the key and value as input
22
+ res , err := first .Apply (p .Key , p .Value )
15
23
if err != nil {
16
24
return nil , err
17
25
}
26
+
27
+ // the rest just take the output of the last step (reducing it)
18
28
for _ , step := range rem {
19
- res , err = ApplyOp ( step , res )
29
+ res , err = step . Apply ( res )
20
30
if err != nil {
21
31
return nil , err
22
32
}
23
33
}
24
34
return res , nil
25
35
}
26
36
27
- func ApplyOp (op * ProofOp , args ... []byte ) ([]byte , error ) {
37
+ func (op * ProofOp ) Apply ( args ... []byte ) ([]byte , error ) {
28
38
o := op .Op
29
39
switch o .(type ) {
30
40
case * ProofOp_Leaf :
31
41
if len (args ) != 2 {
32
42
return nil , fmt .Errorf ("Need key and value args, got %d" , len (args ))
33
43
}
34
- return ApplyLeafOp ( op .GetLeaf (), args [0 ], args [1 ])
44
+ return op .GetLeaf (). Apply ( args [0 ], args [1 ])
35
45
case * ProofOp_Inner :
36
46
if len (args ) != 1 {
37
47
return nil , fmt .Errorf ("Need one child hash, got %d" , len (args ))
38
48
}
39
- return ApplyInnerOp ( op .GetInner (), args [0 ])
49
+ return op .GetInner (). Apply ( args [0 ])
40
50
default :
41
51
panic ("Unknown proof op" )
42
52
}
43
53
}
44
54
45
- func ApplyLeafOp (op * LeafOp , key []byte , value []byte ) ([]byte , error ) {
55
+ func (op * LeafOp ) Apply ( key []byte , value []byte ) ([]byte , error ) {
46
56
if len (key ) == 0 {
47
57
return nil , fmt .Errorf ("Leaf op needs key" )
48
58
}
@@ -62,6 +72,15 @@ func ApplyLeafOp(op *LeafOp, key []byte, value []byte) ([]byte, error) {
62
72
return doHash (op .Hash , data )
63
73
}
64
74
75
+ func (op * InnerOp ) Apply (child []byte ) ([]byte , error ) {
76
+ if len (child ) == 0 {
77
+ return nil , fmt .Errorf ("Inner op needs child value" )
78
+ }
79
+ preimage := append (op .Prefix , child ... )
80
+ preimage = append (preimage , op .Suffix ... )
81
+ return doHash (op .Hash , preimage )
82
+ }
83
+
65
84
func prepareLeafData (hashOp HashOp , lengthOp LengthOp , data []byte ) ([]byte , error ) {
66
85
// TODO: lengthop before or after hash ???
67
86
hdata , err := doHashOrNoop (hashOp , data )
@@ -72,15 +91,6 @@ func prepareLeafData(hashOp HashOp, lengthOp LengthOp, data []byte) ([]byte, err
72
91
return ldata , err
73
92
}
74
93
75
- func ApplyInnerOp (op * InnerOp , child []byte ) ([]byte , error ) {
76
- if len (child ) == 0 {
77
- return nil , fmt .Errorf ("Inner op needs child value" )
78
- }
79
- preimage := append (op .Prefix , child ... )
80
- preimage = append (preimage , op .Suffix ... )
81
- return doHash (op .Hash , preimage )
82
- }
83
-
84
94
// doHashOrNoop will return the preimage untouched if hashOp == NONE,
85
95
// otherwise, perform doHash
86
96
func doHashOrNoop (hashOp HashOp , preimage []byte ) ([]byte , error ) {
0 commit comments