diff --git a/app/obolapi/exit_model.go b/app/obolapi/exit_model.go index a66b0bde0..0ab032c42 100644 --- a/app/obolapi/exit_model.go +++ b/app/obolapi/exit_model.go @@ -10,6 +10,10 @@ import ( eth2p0 "github.com/attestantio/go-eth2-client/spec/phase0" ssz "github.com/ferranbt/fastssz" + dynssz "github.com/pk910/dynamic-ssz" + "github.com/pk910/dynamic-ssz/hasher" + "github.com/pk910/dynamic-ssz/sszutils" + "github.com/pk910/dynamic-ssz/treeproof" "github.com/obolnetwork/charon/app/errors" "github.com/obolnetwork/charon/app/z" @@ -76,8 +80,8 @@ type UnsignedPartialExitRequest struct { ShareIdx uint64 `json:"share_idx,omitempty"` } -func (p UnsignedPartialExitRequest) GetTree() (*ssz.Node, error) { - node, err := ssz.ProofTree(p) +func (p UnsignedPartialExitRequest) GetTree() (*treeproof.Node, error) { + node, err := dynssz.GetGlobalDynSsz().GetTree(p) if err != nil { return nil, errors.Wrap(err, "proof tree") } @@ -85,16 +89,18 @@ func (p UnsignedPartialExitRequest) GetTree() (*ssz.Node, error) { return node, nil } -func (p UnsignedPartialExitRequest) HashTreeRoot() ([32]byte, error) { - hash, err := ssz.HashWithDefaultHasher(p) - if err != nil { - return [32]byte{}, errors.Wrap(err, "hash with default hasher") - } - - return hash, nil +func (p UnsignedPartialExitRequest) HashTreeRoot() (root [32]byte, err error) { + err = hasher.WithDefaultHasher(func(hh sszutils.HashWalker) (err error) { + err = p.HashTreeRootWith(hh) + if err == nil { + root, err = hh.HashRoot() + } + return + }) + return } -func (p UnsignedPartialExitRequest) HashTreeRootWith(hh ssz.HashWalker) error { +func (p UnsignedPartialExitRequest) HashTreeRootWith(hh sszutils.HashWalker) error { indx := hh.Index() if err := p.PartialExits.HashTreeRootWith(hh); err != nil { @@ -111,25 +117,27 @@ func (p UnsignedPartialExitRequest) HashTreeRootWith(hh ssz.HashWalker) error { // PartialExits is an array of ExitMessage that have been signed with a partial key. type PartialExits []ExitBlob -func (p PartialExits) GetTree() (*ssz.Node, error) { - hash, err := ssz.ProofTree(p) +func (p PartialExits) GetTree() (*treeproof.Node, error) { + node, err := dynssz.GetGlobalDynSsz().GetTree(p) if err != nil { return nil, errors.Wrap(err, "proof tree") } - return hash, nil + return node, nil } -func (p PartialExits) HashTreeRoot() ([32]byte, error) { - hash, err := ssz.HashWithDefaultHasher(p) - if err != nil { - return [32]byte{}, errors.Wrap(err, "hash with default hasher") - } - - return hash, nil +func (p PartialExits) HashTreeRoot() (root [32]byte, err error) { + err = hasher.WithDefaultHasher(func(hh sszutils.HashWalker) (err error) { + err = p.HashTreeRootWith(hh) + if err == nil { + root, err = hh.HashRoot() + } + return + }) + return } -func (p PartialExits) HashTreeRootWith(hh ssz.HashWalker) error { +func (p PartialExits) HashTreeRootWith(hh sszutils.HashWalker) error { indx := hh.Index() num := uint64(len(p)) @@ -200,8 +208,8 @@ type ExitBlob struct { SignedExitMessage eth2p0.SignedVoluntaryExit `json:"signed_exit_message"` } -func (e ExitBlob) GetTree() (*ssz.Node, error) { - node, err := ssz.ProofTree(e) +func (e ExitBlob) GetTree() (*treeproof.Node, error) { + node, err := dynssz.GetGlobalDynSsz().GetTree(e) if err != nil { return nil, errors.Wrap(err, "proof tree") } @@ -209,16 +217,18 @@ func (e ExitBlob) GetTree() (*ssz.Node, error) { return node, nil } -func (e ExitBlob) HashTreeRoot() ([32]byte, error) { - hash, err := ssz.HashWithDefaultHasher(e) - if err != nil { - return [32]byte{}, errors.Wrap(err, "hash with default hasher") - } - - return hash, nil +func (e ExitBlob) HashTreeRoot() (root [32]byte, err error) { + err = hasher.WithDefaultHasher(func(hh sszutils.HashWalker) (err error) { + err = e.HashTreeRootWith(hh) + if err == nil { + root, err = hh.HashRoot() + } + return + }) + return } -func (e ExitBlob) HashTreeRootWith(hh ssz.HashWalker) error { +func (e ExitBlob) HashTreeRootWith(hh sszutils.HashWalker) error { indx := hh.Index() pkBytes, err := from0x(e.PublicKey, 48) // public key is 48 bytes long diff --git a/app/obolapi/exit_model_test.go b/app/obolapi/exit_model_test.go index c8eaea1df..6d7ccee81 100644 --- a/app/obolapi/exit_model_test.go +++ b/app/obolapi/exit_model_test.go @@ -5,7 +5,6 @@ package obolapi_test import ( "testing" - ssz "github.com/ferranbt/fastssz" "github.com/stretchr/testify/require" "github.com/obolnetwork/charon/app/obolapi" @@ -43,7 +42,7 @@ func Test_PartialExitRequest(t *testing.T) { require.NoError(t, err) require.Equal(t, other, pr) - err = pr.HashTreeRootWith(ssz.DefaultHasherPool.Get()) + _, err = pr.HashTreeRoot() require.NoError(t, err) require.NotEmpty(t, htr) } @@ -67,7 +66,7 @@ func Test_UnsignedPartialExitRequest(t *testing.T) { require.NoError(t, err) require.NotNil(t, node) - err = pr.HashTreeRootWith(ssz.DefaultHasherPool.Get()) + _, err = pr.HashTreeRoot() require.NoError(t, err) require.NotEmpty(t, htr) } @@ -92,7 +91,7 @@ func Test_PartialExits(t *testing.T) { require.NoError(t, err) require.NotNil(t, node) - err = pr.HashTreeRootWith(ssz.DefaultHasherPool.Get()) + _, err = pr.HashTreeRoot() require.NoError(t, err) require.NotEmpty(t, htr) } @@ -115,7 +114,7 @@ func Test_FullExitAuthBlob(t *testing.T) { require.NoError(t, err) require.NotNil(t, node) - err = pr.HashTreeRootWith(ssz.DefaultHasherPool.Get()) + _, err = pr.HashTreeRoot() require.NoError(t, err) require.NotEmpty(t, htr) } @@ -134,7 +133,7 @@ func Test_ExitBlob(t *testing.T) { require.NoError(t, err) require.NotNil(t, node) - err = pr.HashTreeRootWith(ssz.DefaultHasherPool.Get()) + _, err = pr.HashTreeRoot() require.NoError(t, err) require.NotEmpty(t, htr) } diff --git a/core/validatorapi/validatorapi.go b/core/validatorapi/validatorapi.go index 2443987e2..a7103da4f 100644 --- a/core/validatorapi/validatorapi.go +++ b/core/validatorapi/validatorapi.go @@ -17,7 +17,7 @@ import ( eth2spec "github.com/attestantio/go-eth2-client/spec" "github.com/attestantio/go-eth2-client/spec/altair" eth2p0 "github.com/attestantio/go-eth2-client/spec/phase0" - ssz "github.com/ferranbt/fastssz" + "github.com/pk910/dynamic-ssz/sszutils" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" @@ -502,7 +502,7 @@ func propDataMatchesDuty(opts *eth2api.SubmitProposalOpts, prop *eth2api.Version ) } - checkHashes := func(d1, d2 ssz.HashRoot) error { + checkHashes := func(d1, d2 sszutils.FastsszHashRoot) error { ddb, err := d1.HashTreeRoot() if err != nil { return errors.Wrap(err, "hash tree root dutydb") diff --git a/go.mod b/go.mod index c2c394157..a7ccbf030 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,7 @@ require ( github.com/libp2p/go-libp2p v0.47.0 github.com/libp2p/go-msgio v0.3.0 github.com/multiformats/go-multiaddr v0.16.1 + github.com/pk910/dynamic-ssz v1.2.2 github.com/prometheus/client_golang v1.23.2 github.com/prometheus/client_model v0.6.2 github.com/protolambda/eth2-shuffle v1.1.0 @@ -85,6 +86,7 @@ require ( github.com/bufbuild/buf v1.58.0 // indirect github.com/bufbuild/protocompile v0.14.1 // indirect github.com/bufbuild/protoplugin v0.0.0-20250218205857-750e09ce93e1 // indirect + github.com/casbin/govaluate v1.8.0 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chigopher/pathlib v0.19.1 // indirect @@ -153,7 +155,7 @@ require ( github.com/jinzhu/copier v0.4.0 // indirect github.com/kilic/bls12-381 v0.1.0 // indirect github.com/klauspost/compress v1.18.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.10 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/klauspost/pgzip v1.2.6 // indirect github.com/koron/go-ssdp v0.0.6 // indirect github.com/kr/pretty v0.3.1 // indirect @@ -218,7 +220,7 @@ require ( github.com/pion/transport/v4 v4.0.1 // indirect github.com/pion/turn/v4 v4.0.2 // indirect github.com/pion/webrtc/v4 v4.1.2 // indirect - github.com/pk910/dynamic-ssz v0.0.6 // indirect + github.com/pk910/hashtree-bindings v0.0.1 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect @@ -275,7 +277,6 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect google.golang.org/grpc v1.79.2 // indirect - gopkg.in/Knetic/govaluate.v3 v3.0.0 // indirect gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect @@ -287,7 +288,10 @@ require ( replace github.com/coinbase/kryptology => github.com/ObolNetwork/kryptology v0.1.0 // We're replacing go-eth2-client with a branch off our fork. The branch is kept up to date with the latest attestantio versions. -replace github.com/attestantio/go-eth2-client => github.com/ObolNetwork/go-eth2-client v0.28.0-obol.1 //nolint +replace github.com/attestantio/go-eth2-client => github.com/ObolNetwork/go-eth2-client v0.28.0-obol.2-gloas-v1.7.0-alpha2 //nolint + +// We're replacing temporarily go-builder-client with a branch off our fork. This is to be removed once go-builder-client includes dynamic-ssz. +replace github.com/attestantio/go-builder-client => github.com/ObolNetwork/go-builder-client v0.0.0-20260319131832-9f3465599f38 //nolint tool ( github.com/bufbuild/buf/cmd/buf diff --git a/go.sum b/go.sum index a82166e81..be036d6ca 100644 --- a/go.sum +++ b/go.sum @@ -34,8 +34,10 @@ github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE= github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/ObolNetwork/go-eth2-client v0.28.0-obol.1 h1:72NAvJRe09mKHiKfB30r9nO7JZnV/5bPx5J1qxZ5Yow= -github.com/ObolNetwork/go-eth2-client v0.28.0-obol.1/go.mod h1:PO9sHFCq+1RiG+Eh3eOR2GYvYV64Qzg7idM3kLgCs5k= +github.com/ObolNetwork/go-builder-client v0.0.0-20260319131832-9f3465599f38 h1:gbo1se2O0jKnVrr6Lt4euc3bjhGU0PPV20oiu7XEj80= +github.com/ObolNetwork/go-builder-client v0.0.0-20260319131832-9f3465599f38/go.mod h1:cQ7jj82IUs5w/DTP9mDz6Vp2rP5mXqNXs8UN1KXGfVU= +github.com/ObolNetwork/go-eth2-client v0.28.0-obol.2-gloas-v1.7.0-alpha2 h1:l4/QrxMR9RskJ/to2u3PwpIO6PyFG15GEayvwpPE7uY= +github.com/ObolNetwork/go-eth2-client v0.28.0-obol.2-gloas-v1.7.0-alpha2/go.mod h1:lwj0l8l51hIjqdQpODPea01JfE33nyM++1VGjBZau08= github.com/ObolNetwork/kryptology v0.1.0 h1:AhoG4My70+xMhEJSpVaJay/t+T/vIUNHQYLjsDJHulI= github.com/ObolNetwork/kryptology v0.1.0/go.mod h1:/Wl7Js2f676GyXZDTaojf/O+l0fxFPWudbyjdFhkpSA= github.com/OffchainLabs/go-bitfield v0.0.0-20251031151322-f427d04d8506 h1:d/SJkN8/9Ca+1YmuDiUJxAiV4w/a9S8NcsG7GMQSrVI= @@ -51,8 +53,6 @@ github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYW github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= -github.com/attestantio/go-builder-client v0.7.2 h1:bOrtysEIZd9bEM+mAeT6OtAo6LSAft/qylBLwFoFwZ0= -github.com/attestantio/go-builder-client v0.7.2/go.mod h1:+NADxbaknI5yxl+0mCkMa/VciVsesxRMGNP/poDfV08= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -66,6 +66,8 @@ github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/ github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= github.com/bufbuild/protoplugin v0.0.0-20250218205857-750e09ce93e1 h1:V1xulAoqLqVg44rY97xOR+mQpD2N+GzhMHVwJ030WEU= github.com/bufbuild/protoplugin v0.0.0-20250218205857-750e09ce93e1/go.mod h1:c5D8gWRIZ2HLWO3gXYTtUfw/hbJyD8xikv2ooPxnklQ= +github.com/casbin/govaluate v1.8.0 h1:1dUaV/I0LFP2tcY1uNQEb6wBCbp8GMTcC/zhwQDWvZo= +github.com/casbin/govaluate v1.8.0/go.mod h1:G/UnbIjZk/0uMNaLwZZmFQrR72tYRZWQkO70si/iR7A= github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= @@ -283,8 +285,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= -github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= -github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/koron/go-ssdp v0.0.6 h1:Jb0h04599eq/CY7rB5YEqPS83HmRfHP2azkxMN2rFtU= @@ -461,8 +463,10 @@ github.com/pion/turn/v4 v4.0.2 h1:ZqgQ3+MjP32ug30xAbD6Mn+/K4Sxi3SdNOTFf+7mpps= github.com/pion/turn/v4 v4.0.2/go.mod h1:pMMKP/ieNAG/fN5cZiN4SDuyKsXtNTr0ccN7IToA1zs= github.com/pion/webrtc/v4 v4.1.2 h1:mpuUo/EJ1zMNKGE79fAdYNFZBX790KE7kQQpLMjjR54= github.com/pion/webrtc/v4 v4.1.2/go.mod h1:xsCXiNAmMEjIdFxAYU0MbB3RwRieJsegSB2JZsGN+8U= -github.com/pk910/dynamic-ssz v0.0.6 h1:Tu97LSc2TtCyqRfoSbhG9XuR/FbA7CkKeAnlkgUydFY= -github.com/pk910/dynamic-ssz v0.0.6/go.mod h1:b6CrLaB2X7pYA+OSEEbkgXDEcRnjLOZIxZTsMuO/Y9c= +github.com/pk910/dynamic-ssz v1.2.2 h1:dyvewnBFKGJQUVQjGhS0+LdX95xhFRh7+d7hIq3OnvQ= +github.com/pk910/dynamic-ssz v1.2.2/go.mod h1:HXRWLNcgj3DL65Kznrb+RdL3DEKw2JBZ/6crooqGoII= +github.com/pk910/hashtree-bindings v0.0.1 h1:Sw+UlPlrBle4LUg04kqLFybVQcfmamwKL1QsrR3GU0g= +github.com/pk910/hashtree-bindings v0.0.1/go.mod h1:eayIpxMFkWzMsydESu/5bV8wglZzSE/c9mq6DQdn204= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -768,8 +772,6 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= -gopkg.in/Knetic/govaluate.v3 v3.0.0 h1:18mUyIt4ZlRlFZAAfVetz4/rzlJs9yhN+U02F4u1AOc= -gopkg.in/Knetic/govaluate.v3 v3.0.0/go.mod h1:csKLBORsPbafmSCGTEh3U7Ozmsuq8ZSIlKk1bcqph0E= gopkg.in/cenkalti/backoff.v1 v1.1.0 h1:Arh75ttbsvlpVA7WtVpH4u9h6Zl46xuptxqLxPiSo4Y= gopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UDAkHu8BrjI= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=