Compare commits

...

1 Commits

Author SHA1 Message Date
nisdas
c1270b6b81 try it out 2023-05-11 21:04:48 +08:00
8 changed files with 53 additions and 43 deletions

View File

@@ -20,7 +20,7 @@ var (
type FieldTrie struct { type FieldTrie struct {
*sync.RWMutex *sync.RWMutex
reference *stateutil.Reference reference *stateutil.Reference
fieldLayers [][]*[32]byte fieldLayers [][]byte
field types.FieldIndex field types.FieldIndex
dataType types.DataType dataType types.DataType
length uint64 length uint64
@@ -162,9 +162,9 @@ func (f *FieldTrie) CopyTrie() *FieldTrie {
numOfElems: f.numOfElems, numOfElems: f.numOfElems,
} }
} }
dstFieldTrie := make([][]*[32]byte, len(f.fieldLayers)) dstFieldTrie := make([][]byte, len(f.fieldLayers))
for i, layer := range f.fieldLayers { for i, layer := range f.fieldLayers {
dstFieldTrie[i] = make([]*[32]byte, len(layer)) dstFieldTrie[i] = make([]byte, len(layer))
copy(dstFieldTrie[i], layer) copy(dstFieldTrie[i], layer)
} }
return &FieldTrie{ return &FieldTrie{
@@ -252,6 +252,6 @@ func (f *FieldTrie) Empty() bool {
// InsertFieldLayer manually inserts a field layer. This method // InsertFieldLayer manually inserts a field layer. This method
// bypasses the normal method of field computation, it is only // bypasses the normal method of field computation, it is only
// meant to be used in tests. // meant to be used in tests.
func (f *FieldTrie) InsertFieldLayer(layer [][]*[32]byte) { func (f *FieldTrie) InsertFieldLayer(layer [][]byte) {
f.fieldLayers = layer f.fieldLayers = layer
} }

View File

@@ -56,7 +56,7 @@ func optimizedValidatorRoots(validators []*ethpb.Validator) ([][32]byte, error)
if len(validators) == 0 { if len(validators) == 0 {
return [][32]byte{}, nil return [][32]byte{}, nil
} }
roots := make([][32]byte, 0, len(validators)*validatorFieldRoots) roots := make([]byte, 0, len(validators)*validatorFieldRoots)
for i := 0; i < len(validators); i++ { for i := 0; i < len(validators); i++ {
fRoots, err := ValidatorFieldRoots(validators[i]) fRoots, err := ValidatorFieldRoots(validators[i])
if err != nil { if err != nil {

View File

@@ -43,53 +43,52 @@ func ReturnTrieLayer(elements [][32]byte, length uint64) ([][]*[32]byte, error)
// ReturnTrieLayerVariable returns the representation of a merkle trie when // ReturnTrieLayerVariable returns the representation of a merkle trie when
// provided with the elements of a variable sized trie and the corresponding depth of // provided with the elements of a variable sized trie and the corresponding depth of
// it. // it.
func ReturnTrieLayerVariable(elements [][32]byte, length uint64) [][]*[32]byte { func ReturnTrieLayerVariable(elements [][32]byte, length uint64) [][]byte {
depth := ssz.Depth(length) depth := ssz.Depth(length)
layers := make([][]*[32]byte, depth+1) layers := make([][]byte, depth+1)
// Return zerohash at depth // Return zerohash at depth
if len(elements) == 0 { if len(elements) == 0 {
zerohash := trie.ZeroHashes[depth] zerohash := trie.ZeroHashes[depth]
layers[len(layers)-1] = []*[32]byte{&zerohash} layers[len(layers)-1] = zerohash[:]
return layers return layers
} }
transformedLeaves := make([]*[32]byte, len(elements)) transformedLeaves := make([]byte, len(elements)*32)
for i := range elements { for i := range elements {
arr := elements[i] copy(transformedLeaves[i*32:(i+1)*32], elements[i][:])
transformedLeaves[i] = &arr
} }
layers[0] = transformedLeaves layers[0] = transformedLeaves
buffer := bytes.NewBuffer([]byte{}) buffer := bytes.NewBuffer([]byte{})
buffer.Grow(64) buffer.Grow(64)
for i := uint8(0); i < depth; i++ { for i := uint8(0); i < depth; i++ {
layerLen := len(layers[i]) numOfChunks := len(layers[i]) / 32
oddNodeLength := layerLen%2 == 1 oddNodeLength := numOfChunks%2 == 1
if oddNodeLength { if oddNodeLength {
zerohash := trie.ZeroHashes[i] zerohash := trie.ZeroHashes[i]
elements = append(elements, zerohash) elements = append(elements, zerohash)
layerLen++ numOfChunks++
} }
layers[i+1] = make([]*[32]byte, layerLen/2) layers[i+1] = make([]byte, (numOfChunks/2)*32)
newElems := make([][32]byte, layerLen/2) newElems := make([][32]byte, numOfChunks/2)
htr.VectorizedSha256(elements, newElems) htr.VectorizedSha256(elements, newElems)
elements = newElems elements = newElems
for j := range elements { for j := range elements {
layers[i+1][j] = &elements[j] copy(layers[i+1][j*32:(j+1)*32], elements[j][:])
} }
} }
return layers return layers
} }
// RecomputeFromLayer recomputes specific branches of a fixed sized trie depending on the provided changed indexes. // RecomputeFromLayer recomputes specific branches of a fixed sized trie depending on the provided changed indexes.
func RecomputeFromLayer(changedLeaves [][32]byte, changedIdx []uint64, layer [][]*[32]byte) ([32]byte, [][]*[32]byte, error) { func RecomputeFromLayer(changedLeaves [][32]byte, changedIdx []uint64, layer [][]byte) ([32]byte, [][]byte, error) {
hasher := hash.CustomSHA256Hasher() hasher := hash.CustomSHA256Hasher()
for i, idx := range changedIdx { for i, idx := range changedIdx {
layer[0][idx] = &changedLeaves[i] copy(layer[0][idx*32:(idx+1)*32], changedLeaves[i][:])
} }
if len(changedIdx) == 0 { if len(changedIdx) == 0 {
return *layer[0][0], layer, nil return *(*[32]byte)(layer[0][:32]), layer, nil
} }
leaves := layer[0] leaves := layer[0]
@@ -102,7 +101,7 @@ func RecomputeFromLayer(changedLeaves [][32]byte, changedIdx []uint64, layer [][
changedIdx = append(changedIdx, maxChangedIndex+1) changedIdx = append(changedIdx, maxChangedIndex+1)
} }
root := *layer[0][0] root := *(*[32]byte)(layer[0][:32])
for _, idx := range changedIdx { for _, idx := range changedIdx {
ii, err := math.Int(idx) ii, err := math.Int(idx)
@@ -118,12 +117,12 @@ func RecomputeFromLayer(changedLeaves [][32]byte, changedIdx []uint64, layer [][
} }
// RecomputeFromLayerVariable recomputes specific branches of a variable sized trie depending on the provided changed indexes. // RecomputeFromLayerVariable recomputes specific branches of a variable sized trie depending on the provided changed indexes.
func RecomputeFromLayerVariable(changedLeaves [][32]byte, changedIdx []uint64, layer [][]*[32]byte) ([32]byte, [][]*[32]byte, error) { func RecomputeFromLayerVariable(changedLeaves [][32]byte, changedIdx []uint64, layer [][]byte) ([32]byte, [][]byte, error) {
hasher := hash.CustomSHA256Hasher() hasher := hash.CustomSHA256Hasher()
if len(changedIdx) == 0 { if len(changedIdx) == 0 {
return *layer[0][0], layer, nil return *(*[32]byte)(layer[0][:32]), layer, nil
} }
root := *layer[len(layer)-1][0] root := *(*[32]byte)(layer[len(layer)-1][:32])
for i, idx := range changedIdx { for i, idx := range changedIdx {
ii, err := math.Int(idx) ii, err := math.Int(idx)
@@ -140,9 +139,9 @@ func RecomputeFromLayerVariable(changedLeaves [][32]byte, changedIdx []uint64, l
// this method assumes that the provided trie already has all its elements included // this method assumes that the provided trie already has all its elements included
// in the base depth. // in the base depth.
func recomputeRootFromLayer(idx int, layers [][]*[32]byte, chunks []*[32]byte, func recomputeRootFromLayer(idx int, layers [][]byte, chunks []byte,
hasher func([]byte) [32]byte) ([32]byte, [][]*[32]byte, error) { hasher func([]byte) [32]byte) ([32]byte, [][]byte, error) {
root := *chunks[idx] root := *(*[32]byte)(chunks[idx*32 : (idx+1)*32])
layers[0] = chunks layers[0] = chunks
// The merkle tree structure looks as follows: // The merkle tree structure looks as follows:
// [[r1, r2, r3, r4], [parent1, parent2], [root]] // [[r1, r2, r3, r4], [parent1, parent2], [root]]
@@ -157,7 +156,7 @@ func recomputeRootFromLayer(idx int, layers [][]*[32]byte, chunks []*[32]byte,
var neighbor [32]byte var neighbor [32]byte
if layers[i] != nil && len(layers[i]) != 0 && neighborIdx < len(layers[i]) { if layers[i] != nil && len(layers[i]) != 0 && neighborIdx < len(layers[i]) {
neighbor = *layers[i][neighborIdx] neighbor = *(*[32]byte)(layers[i][neighborIdx*32 : (neighborIdx+1)*32])
} }
if isLeft { if isLeft {
copy(combinedChunks[:32], root[:]) copy(combinedChunks[:32], root[:])
@@ -174,15 +173,15 @@ func recomputeRootFromLayer(idx int, layers [][]*[32]byte, chunks []*[32]byte,
// Update the cached layers at the parent index. // Update the cached layers at the parent index.
rootVal := root rootVal := root
if len(layers[i+1]) == 0 { if len(layers[i+1]) == 0 {
layers[i+1] = append(layers[i+1], &rootVal) layers[i+1] = append(layers[i+1], rootVal[:]...)
} else { } else {
layers[i+1][parentIdx] = &rootVal copy(layers[i+1][parentIdx*32:(parentIdx+1)*32], rootVal[:])
} }
currentIndex = parentIdx currentIndex = parentIdx
} }
// If there is only a single leaf, we return it (the identity element). // If there is only a single leaf, we return it (the identity element).
if len(layers[0]) == 1 { if len(layers[0]) == 1 {
return *layers[0][0], layers, nil return *(*[32]byte)(layers[0][:32]), layers, nil
} }
return root, layers, nil return root, layers, nil
} }
@@ -190,13 +189,13 @@ func recomputeRootFromLayer(idx int, layers [][]*[32]byte, chunks []*[32]byte,
// this method assumes that the base branch does not consist of all leaves of the // this method assumes that the base branch does not consist of all leaves of the
// trie. Instead missing leaves are assumed to be zerohashes, following the structure // trie. Instead missing leaves are assumed to be zerohashes, following the structure
// of a sparse merkle trie. // of a sparse merkle trie.
func recomputeRootFromLayerVariable(idx int, item [32]byte, layers [][]*[32]byte, func recomputeRootFromLayerVariable(idx int, item [32]byte, layers [][]byte,
hasher func([]byte) [32]byte) ([32]byte, [][]*[32]byte, error) { hasher func([]byte) [32]byte) ([32]byte, [][]byte, error) {
for idx >= len(layers[0]) { for idx >= len(layers[0]) {
zerohash := trie.ZeroHashes[0] zerohash := trie.ZeroHashes[0]
layers[0] = append(layers[0], &zerohash) layers[0] = append(layers[0], zerohash[:]...)
} }
layers[0][idx] = &item copy(layers[0][idx*32:(idx+1):32], item[:])
currentIndex := idx currentIndex := idx
root := item root := item
@@ -211,7 +210,7 @@ func recomputeRootFromLayerVariable(idx int, item [32]byte, layers [][]*[32]byte
if neighborIdx >= len(layers[i]) { if neighborIdx >= len(layers[i]) {
neighbor = trie.ZeroHashes[i] neighbor = trie.ZeroHashes[i]
} else { } else {
neighbor = *layers[i][neighborIdx] neighbor = *(*[32]byte)(layers[i][(neighborIdx * 32) : (neighborIdx+1)*32])
} }
if isLeft { if isLeft {
copy(combinedChunks[:32], root[:]) copy(combinedChunks[:32], root[:])
@@ -227,10 +226,10 @@ func recomputeRootFromLayerVariable(idx int, item [32]byte, layers [][]*[32]byte
parentIdx := currentIndex / 2 parentIdx := currentIndex / 2
if len(layers[i+1]) == 0 || parentIdx >= len(layers[i+1]) { if len(layers[i+1]) == 0 || parentIdx >= len(layers[i+1]) {
newItem := root newItem := root
layers[i+1] = append(layers[i+1], &newItem) layers[i+1] = append(layers[i+1], newItem[:]...)
} else { } else {
newItem := root newItem := root
layers[i+1][parentIdx] = &newItem copy(layers[i+1][parentIdx*32:(parentIdx+1)*32], newItem[:])
} }
currentIndex = parentIdx currentIndex = parentIdx
} }

View File

@@ -9,7 +9,14 @@ import (
// hardware configuration, using this routine can lead to a significant // hardware configuration, using this routine can lead to a significant
// performance improvement compared to the default method of hashing // performance improvement compared to the default method of hashing
// lists. // lists.
func VectorizedSha256(inputList [][32]byte, outputList [][32]byte) { func VectorizedSha256(inputList []byte, outputList []byte) {
err := gohashtree.HashByteSlice(outputList, inputList)
if err != nil {
panic(err)
}
}
func VectorizedSha256Chunks(inputList [][32]byte, outputList [][32]byte) {
err := gohashtree.Hash(outputList, inputList) err := gohashtree.Hash(outputList, inputList)
if err != nil { if err != nil {
panic(err) panic(err)

View File

@@ -3303,8 +3303,8 @@ def prysm_deps():
go_repository( go_repository(
name = "com_github_prysmaticlabs_gohashtree", name = "com_github_prysmaticlabs_gohashtree",
importpath = "github.com/prysmaticlabs/gohashtree", importpath = "github.com/prysmaticlabs/gohashtree",
sum = "h1:1EVinCWdb3Lorq7xn8DYQHf48nCcdAM3Vb18KsFlRWY=", sum = "h1:po9GKr5APkGj8blcsaPYj/EBlZbvCmoKE/oGLZE+PNI=",
version = "v0.0.3-alpha", version = "v0.0.3-alpha.0.20230510131438-bf992328364a",
) )
go_repository( go_repository(

View File

@@ -214,7 +214,7 @@ func MerkleizeVector(elements [][32]byte, length uint64) [32]byte {
elements = append(elements, zerohash) elements = append(elements, zerohash)
} }
outputLen := len(elements) / 2 outputLen := len(elements) / 2
htr.VectorizedSha256(elements, elements) htr.VectorizedSha256Chunks(elements, elements)
elements = elements[:outputLen] elements = elements[:outputLen]
} }
return elements[0] return elements[0]

2
go.mod
View File

@@ -248,7 +248,7 @@ require (
github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-playground/validator/v10 v10.11.1 github.com/go-playground/validator/v10 v10.11.1
github.com/peterh/liner v1.2.0 // indirect github.com/peterh/liner v1.2.0 // indirect
github.com/prysmaticlabs/gohashtree v0.0.3-alpha github.com/prysmaticlabs/gohashtree v0.0.3-alpha.0.20230510131438-bf992328364a
golang.org/x/sys v0.7.0 // indirect golang.org/x/sys v0.7.0 // indirect
google.golang.org/api v0.34.0 // indirect google.golang.org/api v0.34.0 // indirect
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect

4
go.sum
View File

@@ -1066,8 +1066,12 @@ github.com/prysmaticlabs/fastssz v0.0.0-20220628121656-93dfe28febab/go.mod h1:MA
github.com/prysmaticlabs/go-bitfield v0.0.0-20210108222456-8e92c3709aa0/go.mod h1:hCwmef+4qXWjv0jLDbQdWnL0Ol7cS7/lCSS26WR+u6s= github.com/prysmaticlabs/go-bitfield v0.0.0-20210108222456-8e92c3709aa0/go.mod h1:hCwmef+4qXWjv0jLDbQdWnL0Ol7cS7/lCSS26WR+u6s=
github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 h1:0tVE4tdWQK9ZpYygoV7+vS6QkDvQVySboMVEIxBJmXw= github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 h1:0tVE4tdWQK9ZpYygoV7+vS6QkDvQVySboMVEIxBJmXw=
github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7/go.mod h1:wmuf/mdK4VMD+jA9ThwcUKjg3a2XWM9cVfFYjDyY4j4= github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7/go.mod h1:wmuf/mdK4VMD+jA9ThwcUKjg3a2XWM9cVfFYjDyY4j4=
github.com/prysmaticlabs/gohashtree v0.0.1-alpha.0.20220714111606-acbb2962fb48 h1:cSo6/vk8YpvkLbk9v3FO97cakNmUoxwi2KMP8hd5WIw=
github.com/prysmaticlabs/gohashtree v0.0.1-alpha.0.20220714111606-acbb2962fb48/go.mod h1:4pWaT30XoEx1j8KNJf3TV+E3mQkaufn7mf+jRNb/Fuk=
github.com/prysmaticlabs/gohashtree v0.0.3-alpha h1:1EVinCWdb3Lorq7xn8DYQHf48nCcdAM3Vb18KsFlRWY= github.com/prysmaticlabs/gohashtree v0.0.3-alpha h1:1EVinCWdb3Lorq7xn8DYQHf48nCcdAM3Vb18KsFlRWY=
github.com/prysmaticlabs/gohashtree v0.0.3-alpha/go.mod h1:4pWaT30XoEx1j8KNJf3TV+E3mQkaufn7mf+jRNb/Fuk= github.com/prysmaticlabs/gohashtree v0.0.3-alpha/go.mod h1:4pWaT30XoEx1j8KNJf3TV+E3mQkaufn7mf+jRNb/Fuk=
github.com/prysmaticlabs/gohashtree v0.0.3-alpha.0.20230510131438-bf992328364a h1:po9GKr5APkGj8blcsaPYj/EBlZbvCmoKE/oGLZE+PNI=
github.com/prysmaticlabs/gohashtree v0.0.3-alpha.0.20230510131438-bf992328364a/go.mod h1:4pWaT30XoEx1j8KNJf3TV+E3mQkaufn7mf+jRNb/Fuk=
github.com/prysmaticlabs/grpc-gateway/v2 v2.3.1-0.20230315201114-09284ba20446 h1:4wctORg/1TkgLgXejv9yOSAm3cDBJxoTzl/RNuZmX28= github.com/prysmaticlabs/grpc-gateway/v2 v2.3.1-0.20230315201114-09284ba20446 h1:4wctORg/1TkgLgXejv9yOSAm3cDBJxoTzl/RNuZmX28=
github.com/prysmaticlabs/grpc-gateway/v2 v2.3.1-0.20230315201114-09284ba20446/go.mod h1:IOyTYjcIO0rkmnGBfJTL0NJ11exy/Tc2QEuv7hCXp24= github.com/prysmaticlabs/grpc-gateway/v2 v2.3.1-0.20230315201114-09284ba20446/go.mod h1:IOyTYjcIO0rkmnGBfJTL0NJ11exy/Tc2QEuv7hCXp24=
github.com/prysmaticlabs/prombbolt v0.0.0-20210126082820-9b7adba6db7c h1:9PHRCuO/VN0s9k+RmLykho7AjDxblNYI5bYKed16NPU= github.com/prysmaticlabs/prombbolt v0.0.0-20210126082820-9b7adba6db7c h1:9PHRCuO/VN0s9k+RmLykho7AjDxblNYI5bYKed16NPU=