Skip to content

Commit 60546fe

Browse files
committed
Refactored Apply to be methods on relevant protobuf objects
1 parent 27dba92 commit 60546fe

File tree

2 files changed

+30
-21
lines changed

2 files changed

+30
-21
lines changed

go/ops.go

+27-17
Original file line numberDiff line numberDiff line change
@@ -9,40 +9,50 @@ import (
99
fmt "fmt"
1010
)
1111

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)
1523
if err != nil {
1624
return nil, err
1725
}
26+
27+
// the rest just take the output of the last step (reducing it)
1828
for _, step := range rem {
19-
res, err = ApplyOp(step, res)
29+
res, err = step.Apply(res)
2030
if err != nil {
2131
return nil, err
2232
}
2333
}
2434
return res, nil
2535
}
2636

27-
func ApplyOp(op *ProofOp, args ...[]byte) ([]byte, error) {
37+
func (op *ProofOp) Apply(args ...[]byte) ([]byte, error) {
2838
o := op.Op
2939
switch o.(type) {
3040
case *ProofOp_Leaf:
3141
if len(args) != 2 {
3242
return nil, fmt.Errorf("Need key and value args, got %d", len(args))
3343
}
34-
return ApplyLeafOp(op.GetLeaf(), args[0], args[1])
44+
return op.GetLeaf().Apply(args[0], args[1])
3545
case *ProofOp_Inner:
3646
if len(args) != 1 {
3747
return nil, fmt.Errorf("Need one child hash, got %d", len(args))
3848
}
39-
return ApplyInnerOp(op.GetInner(), args[0])
49+
return op.GetInner().Apply(args[0])
4050
default:
4151
panic("Unknown proof op")
4252
}
4353
}
4454

45-
func ApplyLeafOp(op *LeafOp, key []byte, value []byte) ([]byte, error) {
55+
func (op *LeafOp) Apply(key []byte, value []byte) ([]byte, error) {
4656
if len(key) == 0 {
4757
return nil, fmt.Errorf("Leaf op needs key")
4858
}
@@ -62,6 +72,15 @@ func ApplyLeafOp(op *LeafOp, key []byte, value []byte) ([]byte, error) {
6272
return doHash(op.Hash, data)
6373
}
6474

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+
6584
func prepareLeafData(hashOp HashOp, lengthOp LengthOp, data []byte) ([]byte, error) {
6685
// TODO: lengthop before or after hash ???
6786
hdata, err := doHashOrNoop(hashOp, data)
@@ -72,15 +91,6 @@ func prepareLeafData(hashOp HashOp, lengthOp LengthOp, data []byte) ([]byte, err
7291
return ldata, err
7392
}
7493

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-
8494
// doHashOrNoop will return the preimage untouched if hashOp == NONE,
8595
// otherwise, perform doHash
8696
func doHashOrNoop(hashOp HashOp, preimage []byte) ([]byte, error) {

go/ops_test.go

+3-4
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func TestLeafOp(t *testing.T) {
6464
op: &LeafOp{
6565
Hash: HashOp_SHA256,
6666
Length: LengthOp_VAR_PROTO,
67-
// no prehash, no length prefix
67+
// no prehash
6868
},
6969
// echo -n food | xxs -ps
7070
// and manually compute length byte
@@ -78,7 +78,6 @@ func TestLeafOp(t *testing.T) {
7878
Hash: HashOp_SHA256,
7979
Length: LengthOp_VAR_PROTO,
8080
PrehashValue: HashOp_SHA256,
81-
// no prehash, no length prefix
8281
},
8382
key: []byte("food"), // 04666f6f64
8483
// TODO: this is hash, then length....
@@ -91,7 +90,7 @@ func TestLeafOp(t *testing.T) {
9190

9291
for name, tc := range cases {
9392
t.Run(name, func(t *testing.T) {
94-
res, err := ApplyLeafOp(tc.op, tc.key, tc.value)
93+
res, err := tc.op.Apply(tc.key, tc.value)
9594
// short-circuit with error case
9695
if tc.isErr {
9796
if err == nil {
@@ -157,7 +156,7 @@ func TestInnerOp(t *testing.T) {
157156

158157
for name, tc := range cases {
159158
t.Run(name, func(t *testing.T) {
160-
res, err := ApplyInnerOp(tc.op, tc.child)
159+
res, err := tc.op.Apply(tc.child)
161160
// short-circuit with error case
162161
if tc.isErr {
163162
if err == nil {

0 commit comments

Comments
 (0)