Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(ssz): Optimize pad chunks to re-use buffer #1500

Merged
merged 14 commits into from
Jun 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions beacond/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ replace (
cosmossdk.io/core => cosmossdk.io/core v0.12.1-0.20240530104414-90cbb022d5f6
cosmossdk.io/x/auth => cosmossdk.io/x/auth v0.0.0-20240530104414-90cbb022d5f6
cosmossdk.io/x/staking => cosmossdk.io/x/staking v0.0.0-20240530104414-90cbb022d5f6
github.com/berachain/beacon-kit/mod/cli => ../mod/cli
github.com/berachain/beacon-kit/mod/config => ../mod/config
github.com/cosmos/cosmos-sdk => github.com/berachain/cosmos-sdk v0.46.0-beta2.0.20240529213909-58c32d695e1a
)

Expand Down
4 changes: 4 additions & 0 deletions beacond/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ github.com/berachain/beacon-kit/mod/async v0.0.0-20240614154006-a5defa6198f5 h1:
github.com/berachain/beacon-kit/mod/async v0.0.0-20240614154006-a5defa6198f5/go.mod h1:ycwqumRG49gb8qg87cc6kVgPeiUDaFMajjLko54Ey+I=
github.com/berachain/beacon-kit/mod/beacon v0.0.0-20240614154006-a5defa6198f5 h1:/Qf4EKw83NxwgE9zmF0+y4ec+x+7OX1H9saWrKal2zk=
github.com/berachain/beacon-kit/mod/beacon v0.0.0-20240614154006-a5defa6198f5/go.mod h1:S5ydAEdBDSv4P0NcZCGJaEJiljPgNiah3P6EeWDo4Zk=
github.com/berachain/beacon-kit/mod/cli v0.0.0-20240614154006-a5defa6198f5 h1:WdcB+EL2WGWD6QySPdsf6ZW7RvACwkdIz5lpFR89THg=
github.com/berachain/beacon-kit/mod/cli v0.0.0-20240614154006-a5defa6198f5/go.mod h1:KBIgO+aFAQkLpFJ+27DFRmrGPlpBjr/7gdQYSy9UnA4=
github.com/berachain/beacon-kit/mod/config v0.0.0-20240614154006-a5defa6198f5 h1:KqQcNurpXlZYZ3r/+WR3j50+KjMWu2iZ1DDk1MdbrWk=
github.com/berachain/beacon-kit/mod/config v0.0.0-20240614154006-a5defa6198f5/go.mod h1:rBTpMivjYpzaQk/tKsp1pqj3jev4YJ5PPfUHhcpowCc=
github.com/berachain/beacon-kit/mod/consensus-types v0.0.0-20240614154006-a5defa6198f5 h1:tF5zeC+OzfoVuE86LcE2Z9xyJSkBiMjEhejBKTRw6jE=
github.com/berachain/beacon-kit/mod/consensus-types v0.0.0-20240614154006-a5defa6198f5/go.mod h1:rreW3jRRBVZNjrqDRTBik3oSYrxyQ/gKmni/OaHnfxc=
github.com/berachain/beacon-kit/mod/da v0.0.0-20240614154006-a5defa6198f5 h1:rpEZNxSXhMh2d0Tlb1m6ioxxXeoPOkWir0algjJ7QKY=
Expand Down
3 changes: 0 additions & 3 deletions mod/node-core/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ go 1.22.4
replace (
// The following are required to build with the latest version of the cosmos-sdk main branch:
cosmossdk.io/api => cosmossdk.io/api v0.7.3-0.20240530104414-90cbb022d5f6
// this is a bad dep for node-core
github.com/berachain/beacon-kit/mod/cli => ../cli
github.com/berachain/beacon-kit/mod/config => ../config
github.com/cosmos/cosmos-sdk => github.com/berachain/cosmos-sdk v0.46.0-beta2.0.20240529213909-58c32d695e1a
)

Expand Down
4 changes: 4 additions & 0 deletions mod/node-core/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ github.com/berachain/beacon-kit/mod/async v0.0.0-20240614154006-a5defa6198f5 h1:
github.com/berachain/beacon-kit/mod/async v0.0.0-20240614154006-a5defa6198f5/go.mod h1:ycwqumRG49gb8qg87cc6kVgPeiUDaFMajjLko54Ey+I=
github.com/berachain/beacon-kit/mod/beacon v0.0.0-20240614154006-a5defa6198f5 h1:/Qf4EKw83NxwgE9zmF0+y4ec+x+7OX1H9saWrKal2zk=
github.com/berachain/beacon-kit/mod/beacon v0.0.0-20240614154006-a5defa6198f5/go.mod h1:S5ydAEdBDSv4P0NcZCGJaEJiljPgNiah3P6EeWDo4Zk=
github.com/berachain/beacon-kit/mod/cli v0.0.0-20240614154006-a5defa6198f5 h1:WdcB+EL2WGWD6QySPdsf6ZW7RvACwkdIz5lpFR89THg=
github.com/berachain/beacon-kit/mod/cli v0.0.0-20240614154006-a5defa6198f5/go.mod h1:KBIgO+aFAQkLpFJ+27DFRmrGPlpBjr/7gdQYSy9UnA4=
github.com/berachain/beacon-kit/mod/config v0.0.0-20240614154006-a5defa6198f5 h1:KqQcNurpXlZYZ3r/+WR3j50+KjMWu2iZ1DDk1MdbrWk=
github.com/berachain/beacon-kit/mod/config v0.0.0-20240614154006-a5defa6198f5/go.mod h1:rBTpMivjYpzaQk/tKsp1pqj3jev4YJ5PPfUHhcpowCc=
github.com/berachain/beacon-kit/mod/consensus-types v0.0.0-20240614154006-a5defa6198f5 h1:tF5zeC+OzfoVuE86LcE2Z9xyJSkBiMjEhejBKTRw6jE=
github.com/berachain/beacon-kit/mod/consensus-types v0.0.0-20240614154006-a5defa6198f5/go.mod h1:rreW3jRRBVZNjrqDRTBik3oSYrxyQ/gKmni/OaHnfxc=
github.com/berachain/beacon-kit/mod/da v0.0.0-20240614154006-a5defa6198f5 h1:rpEZNxSXhMh2d0Tlb1m6ioxxXeoPOkWir0algjJ7QKY=
Expand Down
80 changes: 80 additions & 0 deletions mod/primitives/pkg/crypto/sha256/sha256.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// SPDX-License-Identifier: BUSL-1.1
//
// Copyright (C) 2024, Berachain Foundation. All rights reserved.
// Use of this software is governed by the Business Source License included
// in the LICENSE file of this repository and at www.mariadb.com/bsl11.
//
// ANY USE OF THE LICENSED WORK IN VIOLATION OF THIS LICENSE WILL AUTOMATICALLY
// TERMINATE YOUR RIGHTS UNDER THIS LICENSE FOR THE CURRENT AND ALL OTHER
// VERSIONS OF THE LICENSED WORK.
//
// THIS LICENSE DOES NOT GRANT YOU ANY RIGHT IN ANY TRADEMARK OR LOGO OF
// LICENSOR OR ITS AFFILIATES (PROVIDED THAT YOU MAY USE A TRADEMARK OR LOGO OF
// LICENSOR AS EXPRESSLY REQUIRED BY THIS LICENSE).
//
// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
// AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
// TITLE.

package sha256

import (
"hash"
"sync"

"github.com/minio/sha256-simd"
)

// sha256Pool is a pool of sha256 hash functions.
//
//nolint:gochecknoglobals // needed for pool.
var sha256Pool = sync.Pool{New: func() interface{} {
return sha256.New()
}}

// Sum256 defines a function that returns the sha256 checksum of the data passed
// in.
// https://github.com/ethereum/consensus-specs/blob/v0.9.3/specs/core/0_beacon-chain.md#hash
//
//nolint:lll // url.
func Sum256(data []byte) [32]byte {
h, ok := sha256Pool.Get().(hash.Hash)
if !ok {
h = sha256.New()
}
defer sha256Pool.Put(h)
h.Reset()

var b [32]byte
//#nosec:G104 bet
h.Write(data)
h.Sum(b[:0])
return b
}

// CustomSHA256Hasher provides a hash function utilizing
// an internal hasher. It is not thread-safe as the same
// hasher instance is reused.
//
// Note: This method is more efficient only if the callback
// is invoked more than 5 times.
func CustomSHA256Hasher() func([]byte) [32]byte {
hasher, ok := sha256Pool.Get().(hash.Hash)
if !ok {
hasher = sha256.New()
} else {
hasher.Reset()
}
var h [32]byte

return func(data []byte) [32]byte {
//#nosec:G104 // bet
hasher.Write(data)
hasher.Sum(h[:0])
hasher.Reset()

return h
}
}
2 changes: 1 addition & 1 deletion mod/primitives/pkg/eip4844/kzg_commitment.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (

"github.com/berachain/beacon-kit/mod/primitives/pkg/bytes"
"github.com/berachain/beacon-kit/mod/primitives/pkg/constants"
sha256 "github.com/minio/sha256-simd"
"github.com/berachain/beacon-kit/mod/primitives/pkg/crypto/sha256"
"github.com/prysmaticlabs/gohashtree"
)

Expand Down
15 changes: 11 additions & 4 deletions mod/primitives/pkg/eip4844/kzg_commitment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,13 @@ func TestKZGCommitmentHashTreeRoot(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
hashTreeRoot, err := tt.input.HashTreeRoot()
require.NoError(t, err)
require.Equal(t, tt.expected, hashTreeRoot, "Hash tree root does not "+
"match expected for test: "+tt.name)
require.Equal(
t,
tt.expected,
hashTreeRoot,
"Hash tree root does not "+
"match expected for test: "+tt.name,
)
})
}
}
Expand All @@ -117,8 +122,10 @@ func TestKZGCommitmentUnmarshalJSON(t *testing.T) {
`abcdef0123456789abcdef0123456789abcdef"`,
expected: func() eip4844.KZGCommitment {
var c eip4844.KZGCommitment
data, _ := hex.DecodeString("0123456789abcdef0123456789abcdef0" +
"123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")
data, _ := hex.DecodeString(
"0123456789abcdef0123456789abcdef0" +
"123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
)
copy(c[:], data)
return c
}(),
Expand Down
19 changes: 15 additions & 4 deletions mod/primitives/pkg/merkle/proof.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
package merkle

import (
sha256 "github.com/minio/sha256-simd"
"github.com/berachain/beacon-kit/mod/primitives/pkg/crypto/sha256"
)

// VerifyProof given a tree root, a leaf, the generalized merkle index
Expand Down Expand Up @@ -72,8 +72,19 @@ func RootFromBranch[RootT, BranchT ~[32]byte](
depth uint8,
index uint64,
) RootT {
merkleRoot := leaf
var hashInput [64]byte
var (
hashInput [64]byte
hashFn func([]byte) [32]byte
merkleRoot = leaf
)

//nolint:mnd // 5 as defined by the library.
if depth > 5 {
hashFn = sha256.CustomSHA256Hasher()
} else {
hashFn = sha256.Sum256
}

for i := range depth {
//nolint:mnd // from spec.
ithBit := (index >> i) & 0x01
Expand All @@ -84,7 +95,7 @@ func RootFromBranch[RootT, BranchT ~[32]byte](
copy(hashInput[:32], merkleRoot[:])
copy(hashInput[32:], branch[i][:])
}
merkleRoot = sha256.Sum256(hashInput[:])
merkleRoot = hashFn(hashInput[:])
}
return merkleRoot
}
24 changes: 18 additions & 6 deletions mod/primitives/pkg/merkle/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ import (
"fmt"

"github.com/berachain/beacon-kit/mod/errors"
"github.com/berachain/beacon-kit/mod/primitives/pkg/crypto/sha256"
"github.com/berachain/beacon-kit/mod/primitives/pkg/math"
"github.com/berachain/beacon-kit/mod/primitives/pkg/merkle/zero"
sha256 "github.com/minio/sha256-simd"
"github.com/prysmaticlabs/gohashtree"
)

Expand Down Expand Up @@ -113,10 +113,22 @@ func (m *Tree[LeafT, RootT]) Insert(item [32]byte, index int) error {
} else {
m.leaves[index] = item
}
neighbor := [32]byte{}
input := [64]byte{}
currentIndex := index
root := item

var (
hashFn func([]byte) [32]byte
neighbor = [32]byte{}
input = [64]byte{}
currentIndex = index
root = item
)

//nolint:mnd // 5 as defined by the library.
if m.depth > 5 {
hashFn = sha256.CustomSHA256Hasher()
} else {
hashFn = sha256.Sum256
}

for i := range m.depth {
if neighborIdx := currentIndex ^ 1; neighborIdx >= len(m.branches[i]) {
neighbor = zero.Hashes[i]
Expand All @@ -132,7 +144,7 @@ func (m *Tree[LeafT, RootT]) Insert(item [32]byte, index int) error {
copy(input[0:32], neighbor[:])
copy(input[32:64], root[:])
}
root = sha256.Sum256(input[:])
root = hashFn(input[:])

//nolint:mnd // 2 is allowed.
parentIdx := currentIndex / 2
Expand Down
2 changes: 1 addition & 1 deletion mod/primitives/pkg/merkle/zero/zero.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

package zero

import sha256 "github.com/minio/sha256-simd"
import "github.com/berachain/beacon-kit/mod/primitives/pkg/crypto/sha256"

// NumZeroHashes is the number of pre-computed zero-hashes.
const NumZeroHashes = 64
Expand Down
15 changes: 8 additions & 7 deletions mod/primitives/pkg/ssz/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,15 +131,16 @@ func ChunkCountContainer[SpecT any, RootT ~[32]byte, C Container[SpecT, RootT]](
// PadTo function to pad the chunks to the effective limit with zeroed chunks.
func PadTo[U64T ~uint64, ChunkT ~[32]byte](
chunks []ChunkT,
effectiveLimit U64T,
size U64T,
) []ChunkT {
paddedChunks := make([]ChunkT, effectiveLimit)
copy(paddedChunks, chunks)
//#nosec:G701 // This is a safe operation.
for i := uint64(len(chunks)); i < uint64(effectiveLimit); i++ {
paddedChunks[i] = ChunkT{}
switch numChunks := U64T(len(chunks)); {
case numChunks == size:
return chunks
case numChunks > size:
return chunks[:size]
default:
return append(chunks, make([]ChunkT, size-numChunks)...)
}
return paddedChunks
}

// Pack packs a list of SSZ-marshallable elements into a single byte slice.
Expand Down
2 changes: 1 addition & 1 deletion mod/primitives/pkg/ssz/merkle/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import (
"sort"

"github.com/berachain/beacon-kit/mod/errors"
"github.com/berachain/beacon-kit/mod/primitives/pkg/crypto/sha256"
"github.com/berachain/beacon-kit/mod/primitives/pkg/math"
sha256 "github.com/minio/sha256-simd"
)

type (
Expand Down
2 changes: 1 addition & 1 deletion mod/primitives/pkg/ssz/merkleize_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ package ssz_test
import (
"testing"

"github.com/berachain/beacon-kit/mod/primitives/pkg/crypto/sha256"
"github.com/berachain/beacon-kit/mod/primitives/pkg/math"
"github.com/berachain/beacon-kit/mod/primitives/pkg/ssz"
sha256 "github.com/minio/sha256-simd"
"github.com/stretchr/testify/require"
)

Expand Down
73 changes: 63 additions & 10 deletions mod/primitives/pkg/ssz/serialization_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,13 +327,32 @@ func TestMarshalBitList(t *testing.T) {
expOutput: []byte{0b11010101},
},
{
name: "eight elements input",
input: []bool{true, false, true, false, true, false, true, false},
name: "eight elements input",
input: []bool{
true,
false,
true,
false,
true,
false,
true,
false,
},
expOutput: []byte{0b01010101, 0b00000001},
},
{
name: "nine elements input",
input: []bool{true, false, true, false, true, false, true, false, false},
name: "nine elements input",
input: []bool{
true,
false,
true,
false,
true,
false,
true,
false,
false,
},
expOutput: []byte{0b01010101, 0b00000010},
},
{
Expand Down Expand Up @@ -530,19 +549,53 @@ func TestMarshalUnmarshalBitList(t *testing.T) {
expOutput: []byte{0b11010101},
},
{
name: "eight elements input",
input: []bool{true, false, true, false, true, false, true, false},
name: "eight elements input",
input: []bool{
true,
false,
true,
false,
true,
false,
true,
false,
},
expOutput: []byte{0b01010101, 0b00000001},
},
{
name: "nine elements input",
input: []bool{true, false, true, false, true, false, true, false, false},
name: "nine elements input",
input: []bool{
true,
false,
true,
false,
true,
false,
true,
false,
false,
},
expOutput: []byte{0b01010101, 0b00000010},
},
{
name: "fifteen elements input",
input: []bool{true, false, true, false, true, false, true, false, true,
true, true, true, true, true, true},
input: []bool{
true,
false,
true,
false,
true,
false,
true,
false,
true,
true,
true,
true,
true,
true,
true,
},
expOutput: []byte{0b01010101, 0b11111111},
},
{
Expand Down
Loading
Loading