mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
Capella beacon state (#11141)
* fork
* types
* cloners
* getters
* remove CapellaBlind from fork
* hasher
* setters
* spec params, config tests
* generate ssz
* executionPayloadHeaderCapella
* proto state
* BeaconStateCapella SSZ
* saving state
* configfork
* BUILD files
* fix RealPosition
* fix hasher
* SetLatestExecutionPayloadHeaderCapella
* fix error message
* reduce complexity of saveStatesEfficientInternal
* add latestExecutionPayloadHeaderCapella to minimal state
* halway done interface
* remove withdrawal methods
* merge setters
* change signatures for v1 and v2
* fixing errors pt. 1
* paylod_test fixes
* fix everything
* remove unused func
* fix tests
* state_trie_test improvements
* in progress...
* hasher test
* fix configs
* simplify hashing
* Revert "fix configs"
This reverts commit bcae2825fc.
* remove capella from config test
* unify locking
* review
* hashing
* fixes
Co-authored-by: terencechain <terence@prysmaticlabs.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
This commit is contained in:
@@ -17,6 +17,7 @@ go_library(
|
||||
"//crypto/hash:go_default_library",
|
||||
"//crypto/hash/htr:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"@com_github_minio_sha256_simd//:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
@@ -39,6 +40,8 @@ go_test(
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//crypto/hash:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//proto/engine/v1:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
|
||||
@@ -111,6 +111,16 @@ func (cf *VersionedUnmarshaler) UnmarshalBeaconState(marshaled []byte) (s state.
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to init state trie from state, detected fork=%s", forkName)
|
||||
}
|
||||
case version.Capella:
|
||||
st := ðpb.BeaconStateCapella{}
|
||||
err = st.UnmarshalSSZ(marshaled)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to unmarshal state, detected fork=%s", forkName)
|
||||
}
|
||||
s, err = state_native.InitializeFromProtoUnsafeCapella(st)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to init state trie from state, detected fork=%s", forkName)
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("unable to initialize BeaconState for fork version=%s", forkName)
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ func TestByState(t *testing.T) {
|
||||
}()
|
||||
bc := params.BeaconConfig()
|
||||
altairSlot, err := slots.EpochStart(bc.AltairForkEpoch)
|
||||
require.NoError(t, err)
|
||||
bellaSlot, err := slots.EpochStart(bc.BellatrixForkEpoch)
|
||||
require.NoError(t, err)
|
||||
cases := []struct {
|
||||
@@ -109,8 +110,10 @@ func stateForVersion(v int) (state.BeaconState, error) {
|
||||
return util.NewBeaconStateAltair()
|
||||
case version.Bellatrix:
|
||||
return util.NewBeaconStateBellatrix()
|
||||
case version.Capella:
|
||||
return util.NewBeaconStateCapella()
|
||||
default:
|
||||
return nil, fmt.Errorf("unrecognoized version %d", v)
|
||||
return nil, fmt.Errorf("unrecognized version %d", v)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v3/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v3/crypto/hash"
|
||||
"github.com/prysmaticlabs/prysm/v3/encoding/bytesutil"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
@@ -117,6 +118,31 @@ func TransactionsRoot(txs [][]byte) ([32]byte, error) {
|
||||
return MixInLength(bytesRoot, bytesRootBufRoot), nil
|
||||
}
|
||||
|
||||
// WithdrawalSliceRoot computes the HTR of a slice of withdrawals.
|
||||
// The limit parameter is used as input to the bitwise merkleization algorithm.
|
||||
func WithdrawalSliceRoot(hasher HashFn, withdrawals []*enginev1.Withdrawal, limit uint64) ([32]byte, error) {
|
||||
roots := make([][32]byte, len(withdrawals))
|
||||
for i := 0; i < len(withdrawals); i++ {
|
||||
r, err := withdrawalRoot(hasher, withdrawals[i])
|
||||
if err != nil {
|
||||
return [32]byte{}, err
|
||||
}
|
||||
roots[i] = r
|
||||
}
|
||||
|
||||
bytesRoot, err := BitwiseMerkleize(hasher, roots, uint64(len(roots)), limit)
|
||||
if err != nil {
|
||||
return [32]byte{}, errors.Wrap(err, "could not compute merkleization")
|
||||
}
|
||||
bytesRootBuf := new(bytes.Buffer)
|
||||
if err := binary.Write(bytesRootBuf, binary.LittleEndian, uint64(len(withdrawals))); err != nil {
|
||||
return [32]byte{}, errors.Wrap(err, "could not marshal length")
|
||||
}
|
||||
bytesRootBufRoot := make([]byte, 32)
|
||||
copy(bytesRootBufRoot, bytesRootBuf.Bytes())
|
||||
return MixInLength(bytesRoot, bytesRootBufRoot), nil
|
||||
}
|
||||
|
||||
func transactionRoot(tx []byte) ([32]byte, error) {
|
||||
hasher := hash.CustomSHA256Hasher()
|
||||
chunkedRoots, err := PackByChunk([][]byte{tx})
|
||||
@@ -137,3 +163,17 @@ func transactionRoot(tx []byte) ([32]byte, error) {
|
||||
copy(bytesRootBufRoot, bytesRootBuf.Bytes())
|
||||
return MixInLength(bytesRoot, bytesRootBufRoot), nil
|
||||
}
|
||||
|
||||
func withdrawalRoot(hasher HashFn, w *enginev1.Withdrawal) ([32]byte, error) {
|
||||
fieldRoots := make([][32]byte, 3)
|
||||
if w != nil {
|
||||
indexBuf := make([]byte, 32)
|
||||
binary.LittleEndian.PutUint64(indexBuf, w.WithdrawalIndex)
|
||||
fieldRoots[0] = bytesutil.ToBytes32(indexBuf)
|
||||
fieldRoots[1] = bytesutil.ToBytes32(w.ExecutionAddress)
|
||||
amountBuf := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(amountBuf, w.Amount)
|
||||
fieldRoots[2] = bytesutil.ToBytes32(amountBuf)
|
||||
}
|
||||
return BitwiseMerkleize(hasher, fieldRoots, uint64(len(fieldRoots)), uint64(len(fieldRoots)))
|
||||
}
|
||||
|
||||
@@ -2,11 +2,14 @@ package ssz_test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v3/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v3/crypto/hash"
|
||||
"github.com/prysmaticlabs/prysm/v3/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v3/encoding/ssz"
|
||||
enginev1 "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v3/testing/require"
|
||||
@@ -123,6 +126,78 @@ func TestTransactionsRoot(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithdrawalQueueRoot(t *testing.T) {
|
||||
const limit = 16
|
||||
tests := []struct {
|
||||
name string
|
||||
ws []*enginev1.Withdrawal
|
||||
want [32]byte
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "nil",
|
||||
ws: nil,
|
||||
want: [32]byte{121, 41, 48, 187, 213, 186, 172, 67, 188, 199, 152, 238, 73, 170, 129, 133, 239, 118, 187, 59, 68, 186, 98, 185, 29, 134, 174, 86, 158, 75, 181, 53},
|
||||
},
|
||||
{
|
||||
name: "empty",
|
||||
ws: []*enginev1.Withdrawal{},
|
||||
want: [32]byte{121, 41, 48, 187, 213, 186, 172, 67, 188, 199, 152, 238, 73, 170, 129, 133, 239, 118, 187, 59, 68, 186, 98, 185, 29, 134, 174, 86, 158, 75, 181, 53},
|
||||
},
|
||||
{
|
||||
name: "one",
|
||||
ws: []*enginev1.Withdrawal{{
|
||||
WithdrawalIndex: 123,
|
||||
ExecutionAddress: bytesutil.PadTo([]byte("address"), 20),
|
||||
Amount: 123,
|
||||
}},
|
||||
want: [32]byte{242, 16, 137, 49, 219, 35, 236, 39, 191, 96, 52, 104, 35, 98, 250, 177, 189, 65, 113, 185, 51, 107, 115, 26, 229, 168, 40, 189, 200, 152, 225, 24},
|
||||
},
|
||||
{
|
||||
name: "max withdrawals",
|
||||
ws: func() []*enginev1.Withdrawal {
|
||||
var ws []*enginev1.Withdrawal
|
||||
for i := 0; i < limit; i++ {
|
||||
ws = append(ws, &enginev1.Withdrawal{
|
||||
WithdrawalIndex: uint64(i),
|
||||
ExecutionAddress: bytesutil.PadTo([]byte("address"+strconv.Itoa(i)), 20),
|
||||
Amount: uint64(i),
|
||||
})
|
||||
}
|
||||
return ws
|
||||
}(),
|
||||
want: [32]byte{252, 43, 118, 69, 222, 73, 222, 196, 52, 234, 247, 49, 98, 54, 19, 146, 204, 246, 12, 139, 179, 167, 117, 216, 77, 159, 84, 154, 9, 103, 28, 226},
|
||||
},
|
||||
{
|
||||
name: "exceed max withdrawals",
|
||||
ws: func() []*enginev1.Withdrawal {
|
||||
var ws []*enginev1.Withdrawal
|
||||
for i := 0; i < limit+1; i++ {
|
||||
ws = append(ws, &enginev1.Withdrawal{
|
||||
WithdrawalIndex: uint64(i),
|
||||
ExecutionAddress: bytesutil.PadTo([]byte("address"+strconv.Itoa(i)), 20),
|
||||
Amount: uint64(i),
|
||||
})
|
||||
}
|
||||
return ws
|
||||
}(),
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := ssz.WithdrawalSliceRoot(hash.CustomSHA256Hasher(), tt.ws, limit)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("error = %v, wantErr = %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("got = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPackByChunk_SingleList(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
Reference in New Issue
Block a user