mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-31 23:41:22 +00:00
5dc5f1d1c8
* using little endian and tests for encoding dep inputs * use decode value and timestamp method in state * updated comments to match serialization format * latest compiled contract, abi, bytecode, and bindings * to little endian everywhere * fix all tests except for contract tests * include contract changes * address broken build * compile with vyper v8 * update readme * fix pkg name * add skip chainstart delay * skip chainstart delay tests pass * to little endian timestamp
126 lines
3.1 KiB
Go
126 lines
3.1 KiB
Go
// Package trieutil contains definitions for building a Merkle trie for validator deposits
|
|
// as defined in the Ethereum Serenity specification, as well as utilities to generate
|
|
// and verify Merkle proofs.
|
|
package trieutil
|
|
|
|
import (
|
|
"encoding/binary"
|
|
|
|
"github.com/prysmaticlabs/prysm/shared/hashutil"
|
|
"github.com/prysmaticlabs/prysm/shared/params"
|
|
)
|
|
|
|
// DepositTrie represents a Merkle trie tracking deposits on the ETH 1.0
|
|
// PoW chain contract created in Vyper.
|
|
type DepositTrie struct {
|
|
depositCount uint64
|
|
branch [32][32]byte
|
|
zeroHashes [32][32]byte
|
|
}
|
|
|
|
// NewDepositTrie creates a new struct instance representing a Merkle trie for deposits
|
|
// and tracking an initial deposit count of 0.
|
|
func NewDepositTrie() *DepositTrie {
|
|
var zeroHashes [32][32]byte
|
|
var branch [32][32]byte
|
|
|
|
zeroHashes[0] = params.BeaconConfig().ZeroHash
|
|
branch[0] = params.BeaconConfig().ZeroHash
|
|
|
|
for i := 0; i < 31; i++ {
|
|
zeroHashes[i+1] = hashutil.Hash(append(zeroHashes[i][:], zeroHashes[i][:]...))
|
|
branch[i+1] = zeroHashes[i+1]
|
|
}
|
|
return &DepositTrie{
|
|
depositCount: 0,
|
|
zeroHashes: zeroHashes,
|
|
branch: branch,
|
|
}
|
|
}
|
|
|
|
// UpdateDepositTrie updates the Merkle trie representing deposits on
|
|
// the ETH 1.0 PoW chain contract.
|
|
func (d *DepositTrie) UpdateDepositTrie(depositData []byte) {
|
|
index := d.depositCount
|
|
i := 0
|
|
powerOf2 := uint64(2)
|
|
|
|
for j := 0; j < 32; j++ {
|
|
if (index+1)%powerOf2 != 0 {
|
|
break
|
|
}
|
|
|
|
i++
|
|
powerOf2 *= 2
|
|
}
|
|
hashedData := hashutil.Hash(depositData)
|
|
|
|
for k := 0; k < 32; k++ {
|
|
if k < i {
|
|
hashedData = hashutil.Hash(append(d.branch[k][:], hashedData[:]...))
|
|
}
|
|
}
|
|
d.branch[i] = hashedData
|
|
d.depositCount++
|
|
}
|
|
|
|
// Root returns the Merkle root of the calculated deposit trie.
|
|
func (d *DepositTrie) Root() [32]byte {
|
|
root := params.BeaconConfig().ZeroHash
|
|
size := d.depositCount
|
|
|
|
for i := 0; i < 32; i++ {
|
|
|
|
if size%2 == 1 {
|
|
root = hashutil.Hash(append(d.branch[i][:], root[:]...))
|
|
} else {
|
|
root = hashutil.Hash(append(root[:], d.zeroHashes[i][:]...))
|
|
}
|
|
|
|
size /= 2
|
|
}
|
|
return root
|
|
}
|
|
|
|
// Branch returns the merkle branch of the left most leaf of the trie.
|
|
func (d *DepositTrie) Branch() [][]byte {
|
|
nBranch := make([][]byte, 32)
|
|
for i := range nBranch {
|
|
nBranch[i] = d.branch[i][:]
|
|
}
|
|
return nBranch
|
|
}
|
|
|
|
// VerifyMerkleBranch verifies a Merkle path in a trie
|
|
// by checking the aggregated hash of contiguous leaves along a path
|
|
// eventually equals the root hash of the Merkle trie.
|
|
func VerifyMerkleBranch(branch [][]byte, root [32]byte, merkleTreeIndex []byte) bool {
|
|
computedRoot := params.BeaconConfig().ZeroHash
|
|
index := binary.LittleEndian.Uint64(merkleTreeIndex)
|
|
size := index + 1
|
|
zHashes := zeroHashes()
|
|
|
|
for i := 0; i < 32; i++ {
|
|
|
|
if size%2 == 1 {
|
|
computedRoot = hashutil.Hash(append(branch[i][:], computedRoot[:]...))
|
|
} else {
|
|
computedRoot = hashutil.Hash(append(computedRoot[:], zHashes[i][:]...))
|
|
}
|
|
|
|
size /= 2
|
|
}
|
|
|
|
return computedRoot == root
|
|
}
|
|
|
|
func zeroHashes() [32][32]byte {
|
|
var zeroHashes [32][32]byte
|
|
|
|
zeroHashes[0] = params.BeaconConfig().ZeroHash
|
|
for i := 0; i < 31; i++ {
|
|
zeroHashes[i+1] = hashutil.Hash(append(zeroHashes[i][:], zeroHashes[i][:]...))
|
|
}
|
|
return zeroHashes
|
|
}
|