mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 07:58:22 -05:00
General indices helpers (#3575)
* Implemented Power of 2 helpers * Test for power of 2 helpers * Gazelle * Fmt * Implemented MerkleTree * Test for MerkleTree * Fixed tests * Implemented ConcatGeneralizedIndices and GeneralizedIndexLength * Tests for the above * Benchmarked copy, it's faster * Implemented rest of the indices helpers * Tests for indices helpers * Delete
This commit is contained in:
committed by
Nishant Das
parent
7c9ddfeb58
commit
6c892dc376
@@ -1,6 +1,8 @@
|
||||
package trieutil
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/shared/hashutil"
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
)
|
||||
@@ -77,3 +79,77 @@ func MerkleTree(leaves [][]byte) [][]byte {
|
||||
|
||||
return merkleTree
|
||||
}
|
||||
|
||||
// ConcatGeneralizedIndices concats the generalized indices together.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def concat_generalized_indices(*indices: GeneralizedIndex) -> GeneralizedIndex:
|
||||
// """
|
||||
// Given generalized indices i1 for A -> B, i2 for B -> C .... i_n for Y -> Z, returns
|
||||
// the generalized index for A -> Z.
|
||||
// """
|
||||
// o = GeneralizedIndex(1)
|
||||
// for i in indices:
|
||||
// o = GeneralizedIndex(o * get_previous_power_of_two(i) + (i - get_previous_power_of_two(i)))
|
||||
// return o
|
||||
func ConcatGeneralizedIndices(indices []int) int {
|
||||
index := 1
|
||||
for _, i := range indices {
|
||||
index = index*PrevPowerOf2(i) + (i - PrevPowerOf2(i))
|
||||
}
|
||||
return index
|
||||
}
|
||||
|
||||
// GeneralizedIndexLength returns the generalized index length from a given index.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def get_generalized_index_length(index: GeneralizedIndex) -> int:
|
||||
// """
|
||||
// Return the length of a path represented by a generalized index.
|
||||
// """
|
||||
// return int(log2(index))
|
||||
func GeneralizedIndexLength(index int) int {
|
||||
return int(math.Log2(float64(index)))
|
||||
}
|
||||
|
||||
// GeneralizedIndexBit returns the given bit of a generalized index.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def get_generalized_index_bit(index: GeneralizedIndex, position: int) -> bool:
|
||||
// """
|
||||
// Return the given bit of a generalized index.
|
||||
// """
|
||||
// return (index & (1 << position)) > 0
|
||||
func GeneralizedIndexBit(index uint64, pos uint64) bool {
|
||||
return (index & (1 << pos)) > 0
|
||||
}
|
||||
|
||||
// GeneralizedIndexSibling returns the sibling of a generalized index.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def generalized_index_sibling(index: GeneralizedIndex) -> GeneralizedIndex:
|
||||
// return GeneralizedIndex(index ^ 1)
|
||||
func GeneralizedIndexSibling(index int) int {
|
||||
return index ^ 1
|
||||
}
|
||||
|
||||
// GeneralizedIndexChild returns the child of a generalized index.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def generalized_index_child(index: GeneralizedIndex, right_side: bool) -> GeneralizedIndex:
|
||||
// return GeneralizedIndex(index * 2 + right_side)
|
||||
func GeneralizedIndexChild(index int, rightSide bool) int {
|
||||
if rightSide {
|
||||
return index*2 + 1
|
||||
}
|
||||
return index * 2
|
||||
}
|
||||
|
||||
// GeneralizedIndexParent returns the parent of a generalized index.
|
||||
//
|
||||
// Spec pseudocode definition:
|
||||
// def generalized_index_parent(index: GeneralizedIndex) -> GeneralizedIndex:
|
||||
// return GeneralizedIndex(index // 2)
|
||||
func GeneralizedIndexParent(index int) int {
|
||||
return index / 2
|
||||
}
|
||||
|
||||
@@ -7,40 +7,40 @@ import (
|
||||
|
||||
func TestNextPowerOf2(t *testing.T) {
|
||||
tests := []struct {
|
||||
input int
|
||||
want int
|
||||
input int
|
||||
result int
|
||||
}{
|
||||
{input: 0, want: 0},
|
||||
{input: 1, want: 1},
|
||||
{input: 2, want: 2},
|
||||
{input: 3, want: 4},
|
||||
{input: 5, want: 8},
|
||||
{input: 9, want: 16},
|
||||
{input: 20, want: 32},
|
||||
{input: 0, result: 0},
|
||||
{input: 1, result: 1},
|
||||
{input: 2, result: 2},
|
||||
{input: 3, result: 4},
|
||||
{input: 5, result: 8},
|
||||
{input: 9, result: 16},
|
||||
{input: 20, result: 32},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if got := NextPowerOf2(tt.input); got != tt.want {
|
||||
t.Errorf("NextPowerOf2() = %v, want %v", got, tt.want)
|
||||
if got := NextPowerOf2(tt.input); got != tt.result {
|
||||
t.Errorf("NextPowerOf2() = %d, result %d", got, tt.result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrevPowerOf2(t *testing.T) {
|
||||
tests := []struct {
|
||||
input int
|
||||
want int
|
||||
input int
|
||||
result int
|
||||
}{
|
||||
{input: 0, want: 0},
|
||||
{input: 1, want: 1},
|
||||
{input: 2, want: 2},
|
||||
{input: 3, want: 2},
|
||||
{input: 5, want: 4},
|
||||
{input: 9, want: 8},
|
||||
{input: 20, want: 16},
|
||||
{input: 0, result: 0},
|
||||
{input: 1, result: 1},
|
||||
{input: 2, result: 2},
|
||||
{input: 3, result: 2},
|
||||
{input: 5, result: 4},
|
||||
{input: 9, result: 8},
|
||||
{input: 20, result: 16},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if got := PrevPowerOf2(tt.input); got != tt.want {
|
||||
t.Errorf("PrevPowerOf2() = %v, want %v", got, tt.want)
|
||||
if got := PrevPowerOf2(tt.input); got != tt.result {
|
||||
t.Errorf("PrevPowerOf2() = %d, result %d", got, tt.result)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,117 @@ func TestMerkleTreeLength(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if got := MerkleTree(tt.leaves); len(got) != tt.length {
|
||||
t.Errorf("len(MerkleTree()) = %v, want %v", got, tt.length)
|
||||
t.Errorf("len(MerkleTree()) = %d, result %d", got, tt.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConcatGeneralizedIndices(t *testing.T) {
|
||||
tests := []struct {
|
||||
indices []int
|
||||
result int
|
||||
}{
|
||||
{[]int{1, 2}, 2},
|
||||
{[]int{1, 3, 6}, 14},
|
||||
{[]int{1, 2, 4, 8}, 64},
|
||||
{[]int{1, 2, 5, 10}, 74},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if got := ConcatGeneralizedIndices(tt.indices); got != tt.result {
|
||||
t.Errorf("ConcatGeneralizedIndices() = %d, result %d", got, tt.result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGeneralizedIndexLength(t *testing.T) {
|
||||
tests := []struct {
|
||||
index int
|
||||
result int
|
||||
}{
|
||||
{index: 20, result: 4},
|
||||
{index: 200, result: 7},
|
||||
{index: 1987, result: 10},
|
||||
{index: 34989843, result: 25},
|
||||
{index: 97282, result: 16},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
result := GeneralizedIndexLength(tt.index)
|
||||
if tt.result != result {
|
||||
t.Errorf("GeneralizedIndexLength() = %d, result %d", tt.result, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGeneralizedIndexBit(t *testing.T) {
|
||||
tests := []struct {
|
||||
index uint64
|
||||
pos uint64
|
||||
result bool
|
||||
}{
|
||||
{index: 7, pos: 2, result: true},
|
||||
{index: 7, pos: 3, result: false},
|
||||
{index: 10, pos: 2, result: false},
|
||||
{index: 10, pos: 3, result: true},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
result := GeneralizedIndexBit(tt.index, tt.pos)
|
||||
if result != tt.result {
|
||||
t.Errorf("GeneralizedIndexBit() = %v, result %v", tt.result, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGeneralizedIndexChild(t *testing.T) {
|
||||
tests := []struct {
|
||||
index int
|
||||
right bool
|
||||
result int
|
||||
}{
|
||||
{index: 5, right: true, result: 11},
|
||||
{index: 10, right: false, result: 20},
|
||||
{index: 1000, right: true, result: 2001},
|
||||
{index: 9999, right: false, result: 19998},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
result := GeneralizedIndexChild(tt.index, tt.right)
|
||||
if result != tt.result {
|
||||
t.Errorf("GeneralizedIndexChild() = %v, result %v", tt.result, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGeneralizedIndexSibling(t *testing.T) {
|
||||
tests := []struct {
|
||||
index int
|
||||
result int
|
||||
}{
|
||||
{index: 5, result: 4},
|
||||
{index: 10, result: 11},
|
||||
{index: 1000, result: 1001},
|
||||
{index: 9999, result: 9998},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
result := GeneralizedIndexSibling(tt.index)
|
||||
if result != tt.result {
|
||||
t.Errorf("GeneralizedIndexSibling() = %v, result %v", tt.result, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGeneralizedIndexParent(t *testing.T) {
|
||||
tests := []struct {
|
||||
index int
|
||||
result int
|
||||
}{
|
||||
{index: 5, result: 2},
|
||||
{index: 10, result: 5},
|
||||
{index: 1000, result: 500},
|
||||
{index: 9999, result: 4999},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
result := GeneralizedIndexParent(tt.index)
|
||||
if result != tt.result {
|
||||
t.Errorf("GeneralizedIndexParent() = %v, result %v", tt.result, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user