Skip to content

Commit 0fc4621

Browse files
committed
feat: add build root children from proof
1 parent df8aefa commit 0fc4621

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

internal/merkle/builder.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,29 @@ func (proof *Proof) BuildRoot() common.Hash {
5050
return rootHash
5151
}
5252

53+
func (proof *Proof) BuildRootChildren() (common.Hash, common.Hash) {
54+
two := big.NewInt(2)
55+
height := len(proof.Siblings)
56+
childHash := proof.Node
57+
58+
for i, s := range proof.Siblings[:height-1] {
59+
60+
// ((pos >> i) % 2) == 0
61+
if new(big.Int).Rem(new(big.Int).Rsh(proof.Pos, uint(i)), two).Cmp(zero) == 0 {
62+
childHash = crypto.Keccak256Hash(childHash[:], s[:])
63+
} else {
64+
childHash = crypto.Keccak256Hash(s[:], childHash[:])
65+
}
66+
}
67+
68+
// ((pos >> (height-1)) % 2) == 0
69+
if new(big.Int).Rem(new(big.Int).Rsh(proof.Pos, uint(height-1)), two).Cmp(zero) == 0 {
70+
return childHash, proof.Siblings[height-1]
71+
} else {
72+
return proof.Siblings[height-1], childHash
73+
}
74+
}
75+
5376
func (proof *Proof) VerifyRoot(other common.Hash) bool {
5477
return proof.BuildRoot() == other
5578
}

internal/merkle/builder_test.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"testing"
99

1010
"github.com/ethereum/go-ethereum/common"
11+
"github.com/ethereum/go-ethereum/crypto"
1112
"github.com/stretchr/testify/assert"
1213
)
1314

@@ -129,6 +130,51 @@ func TestAppendAndRepeated(t *testing.T) {
129130
assert.Equal(t, tree1, tree2)
130131
}
131132

133+
func TestBuildRootChildren1(t *testing.T) {
134+
p := Proof{
135+
Pos: big.NewInt(1),
136+
Node: common.HexToHash("0x01"),
137+
Siblings: []common.Hash{
138+
common.HexToHash("0x02"),
139+
},
140+
}
141+
rootHash := p.BuildRoot()
142+
lhs, rhs := p.BuildRootChildren()
143+
144+
assert.Equal(t, rootHash, crypto.Keccak256Hash(lhs[:], rhs[:]))
145+
}
146+
147+
func TestBuildRootChildren2(t *testing.T) {
148+
p := Proof{
149+
Pos: big.NewInt(1),
150+
Node: common.HexToHash("0x01"),
151+
Siblings: []common.Hash{
152+
common.HexToHash("0x02"),
153+
common.HexToHash("0x03"),
154+
},
155+
}
156+
rootHash := p.BuildRoot()
157+
lhs, rhs := p.BuildRootChildren()
158+
159+
assert.Equal(t, rootHash, crypto.Keccak256Hash(lhs[:], rhs[:]))
160+
}
161+
162+
func TestBuildRootChildren3(t *testing.T) {
163+
p := Proof{
164+
Pos: big.NewInt(1),
165+
Node: common.HexToHash("0x01"),
166+
Siblings: []common.Hash{
167+
common.HexToHash("0x02"),
168+
common.HexToHash("0x03"),
169+
common.HexToHash("0x04"),
170+
},
171+
}
172+
rootHash := p.BuildRoot()
173+
lhs, rhs := p.BuildRootChildren()
174+
175+
assert.Equal(t, rootHash, crypto.Keccak256Hash(lhs[:], rhs[:]))
176+
}
177+
132178
// repanicked
133179
//func TestBuildNotPow2(t *testing.T) {
134180
// defer recover()

0 commit comments

Comments
 (0)