mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 03:30:37 +00:00
Added separate Withdrawal data type to Caplin (#8474)
Reason: JSON formatting
This commit is contained in:
parent
9db82fee5b
commit
54ce971084
@ -103,3 +103,7 @@ func (*KZGCommitment) Clone() clonable.Clonable {
|
||||
func (*Eth1Header) Clone() clonable.Clonable {
|
||||
return &Eth1Header{}
|
||||
}
|
||||
|
||||
func (*Withdrawal) Clone() clonable.Clonable {
|
||||
return &Withdrawal{}
|
||||
}
|
||||
|
@ -29,11 +29,11 @@ type Eth1Block struct {
|
||||
Extra *solid.ExtraData `json:"extra_data"`
|
||||
BaseFeePerGas libcommon.Hash `json:"base_fee_per_gas"`
|
||||
// Extra fields
|
||||
BlockHash libcommon.Hash `json:"block_hash"`
|
||||
Transactions *solid.TransactionsSSZ `json:"transactions"`
|
||||
Withdrawals *solid.ListSSZ[*types.Withdrawal] `json:"withdrawals,omitempty"`
|
||||
BlobGasUsed uint64 `json:"blob_gas_used,omitempty"`
|
||||
ExcessBlobGas uint64 `json:"excess_blob_gas,omitempty"`
|
||||
BlockHash libcommon.Hash `json:"block_hash"`
|
||||
Transactions *solid.TransactionsSSZ `json:"transactions"`
|
||||
Withdrawals *solid.ListSSZ[*Withdrawal] `json:"withdrawals,omitempty"`
|
||||
BlobGasUsed uint64 `json:"blob_gas_used,omitempty"`
|
||||
ExcessBlobGas uint64 `json:"excess_blob_gas,omitempty"`
|
||||
// internals
|
||||
version clparams.StateVersion
|
||||
beaconCfg *clparams.BeaconChainConfig
|
||||
@ -70,7 +70,7 @@ func NewEth1BlockFromHeaderAndBody(header *types.Header, body *types.RawBody, be
|
||||
BaseFeePerGas: baseFee32,
|
||||
BlockHash: header.Hash(),
|
||||
Transactions: solid.NewTransactionsSSZFromTransactions(body.Transactions),
|
||||
Withdrawals: solid.NewStaticListSSZFromList(body.Withdrawals, int(beaconCfg.MaxWithdrawalsPerPayload), 44),
|
||||
Withdrawals: solid.NewStaticListSSZFromList(convertExecutionWithdrawalsToConsensusWithdrawals(body.Withdrawals), int(beaconCfg.MaxWithdrawalsPerPayload), 44),
|
||||
beaconCfg: beaconCfg,
|
||||
}
|
||||
|
||||
@ -145,7 +145,7 @@ func (b *Eth1Block) EncodingSizeSSZ() (size int) {
|
||||
|
||||
if b.version >= clparams.CapellaVersion {
|
||||
if b.Withdrawals == nil {
|
||||
b.Withdrawals = solid.NewStaticListSSZ[*types.Withdrawal](int(b.beaconCfg.MaxWithdrawalsPerPayload), 44)
|
||||
b.Withdrawals = solid.NewStaticListSSZ[*Withdrawal](int(b.beaconCfg.MaxWithdrawalsPerPayload), 44)
|
||||
}
|
||||
size += b.Withdrawals.EncodingSizeSSZ() + 4
|
||||
}
|
||||
@ -161,7 +161,7 @@ func (b *Eth1Block) EncodingSizeSSZ() (size int) {
|
||||
func (b *Eth1Block) DecodeSSZ(buf []byte, version int) error {
|
||||
b.Extra = solid.NewExtraData()
|
||||
b.Transactions = &solid.TransactionsSSZ{}
|
||||
b.Withdrawals = solid.NewStaticListSSZ[*types.Withdrawal](int(b.beaconCfg.MaxWithdrawalsPerPayload), 44)
|
||||
b.Withdrawals = solid.NewStaticListSSZ[*Withdrawal](int(b.beaconCfg.MaxWithdrawalsPerPayload), 44)
|
||||
b.version = clparams.StateVersion(version)
|
||||
return ssz2.UnmarshalSSZ(buf, version, b.getSchema()...)
|
||||
}
|
||||
@ -202,8 +202,8 @@ func (b *Eth1Block) RlpHeader() (*types.Header, error) {
|
||||
withdrawalsHash = new(libcommon.Hash)
|
||||
// extract all withdrawals from itearable list
|
||||
withdrawals := make([]*types.Withdrawal, b.Withdrawals.Len())
|
||||
b.Withdrawals.Range(func(idx int, w *types.Withdrawal, _ int) bool {
|
||||
withdrawals[idx] = w
|
||||
b.Withdrawals.Range(func(idx int, w *Withdrawal, _ int) bool {
|
||||
withdrawals[idx] = convertConsensusWithdrawalToExecutionWithdrawal(w)
|
||||
return true
|
||||
})
|
||||
*withdrawalsHash = types.DeriveSha(types.Withdrawals(withdrawals))
|
||||
@ -251,8 +251,8 @@ func (b *Eth1Block) Version() clparams.StateVersion {
|
||||
// Body returns the equivalent raw body (only eth1 body section).
|
||||
func (b *Eth1Block) Body() *types.RawBody {
|
||||
withdrawals := make([]*types.Withdrawal, b.Withdrawals.Len())
|
||||
b.Withdrawals.Range(func(idx int, w *types.Withdrawal, _ int) bool {
|
||||
withdrawals[idx] = w
|
||||
b.Withdrawals.Range(func(idx int, w *Withdrawal, _ int) bool {
|
||||
withdrawals[idx] = convertConsensusWithdrawalToExecutionWithdrawal(w)
|
||||
return true
|
||||
})
|
||||
return &types.RawBody{
|
||||
|
72
cl/cltypes/withdrawal.go
Normal file
72
cl/cltypes/withdrawal.go
Normal file
@ -0,0 +1,72 @@
|
||||
package cltypes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||
"github.com/ledgerwatch/erigon-lib/common/length"
|
||||
"github.com/ledgerwatch/erigon-lib/types/ssz"
|
||||
"github.com/ledgerwatch/erigon/cl/merkle_tree"
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
)
|
||||
|
||||
type Withdrawal struct {
|
||||
Index uint64 `json:"index"` // monotonically increasing identifier issued by consensus layer
|
||||
Validator uint64 `json:"validatorIndex"` // index of validator associated with withdrawal
|
||||
Address libcommon.Address `json:"address"` // target address for withdrawn ether
|
||||
Amount uint64 `json:"amount"` // value of withdrawal in GWei
|
||||
}
|
||||
|
||||
func (obj *Withdrawal) EncodeSSZ(buf []byte) ([]byte, error) {
|
||||
buf = append(buf, ssz.Uint64SSZ(obj.Index)...)
|
||||
buf = append(buf, ssz.Uint64SSZ(obj.Validator)...)
|
||||
buf = append(buf, obj.Address[:]...)
|
||||
buf = append(buf, ssz.Uint64SSZ(obj.Amount)...)
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func (obj *Withdrawal) DecodeSSZ(buf []byte, _ int) error {
|
||||
if len(buf) < obj.EncodingSizeSSZ() {
|
||||
return fmt.Errorf("[Withdrawal] err: %s", ssz.ErrLowBufferSize)
|
||||
}
|
||||
obj.Index = ssz.UnmarshalUint64SSZ(buf)
|
||||
obj.Validator = ssz.UnmarshalUint64SSZ(buf[8:])
|
||||
copy(obj.Address[:], buf[16:])
|
||||
obj.Amount = ssz.UnmarshalUint64SSZ(buf[36:])
|
||||
return nil
|
||||
}
|
||||
|
||||
func (obj *Withdrawal) EncodingSizeSSZ() int {
|
||||
// Validator Index (8 bytes) + Index (8 bytes) + Amount (8 bytes) + address length
|
||||
return 24 + length.Addr
|
||||
}
|
||||
|
||||
func (obj *Withdrawal) HashSSZ() ([32]byte, error) { // the [32]byte is temporary
|
||||
return merkle_tree.HashTreeRoot(obj.Index, obj.Validator, obj.Address[:], obj.Amount)
|
||||
}
|
||||
|
||||
func convertExecutionWithdrawalToConsensusWithdrawal(executionWithdrawal *types.Withdrawal) *Withdrawal {
|
||||
return &Withdrawal{
|
||||
Index: executionWithdrawal.Index,
|
||||
Validator: executionWithdrawal.Validator,
|
||||
Address: executionWithdrawal.Address,
|
||||
Amount: executionWithdrawal.Amount,
|
||||
}
|
||||
}
|
||||
|
||||
func convertConsensusWithdrawalToExecutionWithdrawal(consensusWithdrawal *Withdrawal) *types.Withdrawal {
|
||||
return &types.Withdrawal{
|
||||
Index: consensusWithdrawal.Index,
|
||||
Validator: consensusWithdrawal.Validator,
|
||||
Address: consensusWithdrawal.Address,
|
||||
Amount: consensusWithdrawal.Amount,
|
||||
}
|
||||
}
|
||||
|
||||
func convertExecutionWithdrawalsToConsensusWithdrawals(executionWithdrawal []*types.Withdrawal) []*Withdrawal {
|
||||
ret := make([]*Withdrawal, len(executionWithdrawal))
|
||||
for i, w := range executionWithdrawal {
|
||||
ret[i] = convertExecutionWithdrawalToConsensusWithdrawal(w)
|
||||
}
|
||||
return ret
|
||||
}
|
@ -12,7 +12,6 @@ import (
|
||||
"github.com/ledgerwatch/erigon/cl/cltypes/solid"
|
||||
"github.com/ledgerwatch/erigon/cl/fork"
|
||||
"github.com/ledgerwatch/erigon/cl/utils"
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
)
|
||||
|
||||
const PreAllocatedRewardsAndPenalties = 8192
|
||||
@ -192,7 +191,7 @@ func ComputeTimestampAtSlot(b abstract.BeaconState, slot uint64) uint64 {
|
||||
}
|
||||
|
||||
// ExpectedWithdrawals calculates the expected withdrawals that can be made by validators in the current epoch
|
||||
func ExpectedWithdrawals(b abstract.BeaconState) []*types.Withdrawal {
|
||||
func ExpectedWithdrawals(b abstract.BeaconState) []*cltypes.Withdrawal {
|
||||
// Get the current epoch, the next withdrawal index, and the next withdrawal validator index
|
||||
currentEpoch := Epoch(b)
|
||||
nextWithdrawalIndex := b.NextWithdrawalIndex()
|
||||
@ -202,7 +201,7 @@ func ExpectedWithdrawals(b abstract.BeaconState) []*types.Withdrawal {
|
||||
maxValidators := uint64(b.ValidatorLength())
|
||||
maxValidatorsPerWithdrawalsSweep := b.BeaconConfig().MaxValidatorsPerWithdrawalsSweep
|
||||
bound := utils.Min64(maxValidators, maxValidatorsPerWithdrawalsSweep)
|
||||
withdrawals := make([]*types.Withdrawal, 0, bound)
|
||||
withdrawals := make([]*cltypes.Withdrawal, 0, bound)
|
||||
|
||||
// Loop through the validators to calculate expected withdrawals
|
||||
for validatorCount := uint64(0); validatorCount < bound && len(withdrawals) != int(b.BeaconConfig().MaxWithdrawalsPerPayload); validatorCount++ {
|
||||
@ -214,7 +213,7 @@ func ExpectedWithdrawals(b abstract.BeaconState) []*types.Withdrawal {
|
||||
// Check if the validator is fully withdrawable
|
||||
if isFullyWithdrawableValidator(b.BeaconConfig(), currentValidator, currentBalance, currentEpoch) {
|
||||
// Add a new withdrawal with the validator's withdrawal credentials and balance
|
||||
newWithdrawal := &types.Withdrawal{
|
||||
newWithdrawal := &cltypes.Withdrawal{
|
||||
Index: nextWithdrawalIndex,
|
||||
Validator: nextWithdrawalValidatorIndex,
|
||||
Address: libcommon.BytesToAddress(wd[12:]),
|
||||
@ -224,7 +223,7 @@ func ExpectedWithdrawals(b abstract.BeaconState) []*types.Withdrawal {
|
||||
nextWithdrawalIndex++
|
||||
} else if isPartiallyWithdrawableValidator(b.BeaconConfig(), currentValidator, currentBalance) { // Check if the validator is partially withdrawable
|
||||
// Add a new withdrawal with the validator's withdrawal credentials and balance minus the maximum effective balance
|
||||
newWithdrawal := &types.Withdrawal{
|
||||
newWithdrawal := &cltypes.Withdrawal{
|
||||
Index: nextWithdrawalIndex,
|
||||
Validator: nextWithdrawalValidatorIndex,
|
||||
Address: libcommon.BytesToAddress(wd[12:]),
|
||||
|
@ -234,7 +234,7 @@ func (I *impl) ProcessVoluntaryExit(s abstract.BeaconState, signedVoluntaryExit
|
||||
|
||||
// ProcessWithdrawals processes withdrawals by decreasing the balance of each validator
|
||||
// and updating the next withdrawal index and validator index.
|
||||
func (I *impl) ProcessWithdrawals(s abstract.BeaconState, withdrawals *solid.ListSSZ[*types.Withdrawal]) error {
|
||||
func (I *impl) ProcessWithdrawals(s abstract.BeaconState, withdrawals *solid.ListSSZ[*cltypes.Withdrawal]) error {
|
||||
// Get the list of withdrawals, the expected withdrawals (if performing full validation),
|
||||
// and the beacon configuration.
|
||||
beaconConfig := s.BeaconConfig()
|
||||
@ -246,8 +246,8 @@ func (I *impl) ProcessWithdrawals(s abstract.BeaconState, withdrawals *solid.Lis
|
||||
if len(expectedWithdrawals) != withdrawals.Len() {
|
||||
return fmt.Errorf("ProcessWithdrawals: expected %d withdrawals, but got %d", len(expectedWithdrawals), withdrawals.Len())
|
||||
}
|
||||
if err := solid.RangeErr[*types.Withdrawal](withdrawals, func(i int, w *types.Withdrawal, _ int) error {
|
||||
if !expectedWithdrawals[i].Equal(w) {
|
||||
if err := solid.RangeErr[*cltypes.Withdrawal](withdrawals, func(i int, w *cltypes.Withdrawal, _ int) error {
|
||||
if *expectedWithdrawals[i] != *w {
|
||||
return fmt.Errorf("ProcessWithdrawals: withdrawal %d does not match expected withdrawal", i)
|
||||
}
|
||||
return nil
|
||||
@ -256,7 +256,7 @@ func (I *impl) ProcessWithdrawals(s abstract.BeaconState, withdrawals *solid.Lis
|
||||
}
|
||||
}
|
||||
|
||||
if err := solid.RangeErr[*types.Withdrawal](withdrawals, func(_ int, w *types.Withdrawal, _ int) error {
|
||||
if err := solid.RangeErr[*cltypes.Withdrawal](withdrawals, func(_ int, w *cltypes.Withdrawal, _ int) error {
|
||||
if err := state.DecreaseBalance(s, w.Validator, w.Amount); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"github.com/ledgerwatch/erigon/cl/cltypes"
|
||||
"github.com/ledgerwatch/erigon/cl/cltypes/solid"
|
||||
"github.com/ledgerwatch/erigon/cl/transition/machine"
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
)
|
||||
|
||||
var _ machine.Interface = (*Impl)(nil)
|
||||
@ -15,7 +14,7 @@ type Impl struct {
|
||||
FnVerifyTransition func(s abstract.BeaconState, block *cltypes.BeaconBlock) error
|
||||
FnProcessSlots func(s abstract.BeaconState, slot uint64) error
|
||||
FnProcessBlockHeader func(s abstract.BeaconState, block *cltypes.BeaconBlock) error
|
||||
FnProcessWithdrawals func(s abstract.BeaconState, withdrawals *solid.ListSSZ[*types.Withdrawal]) error
|
||||
FnProcessWithdrawals func(s abstract.BeaconState, withdrawals *solid.ListSSZ[*cltypes.Withdrawal]) error
|
||||
FnProcessExecutionPayload func(s abstract.BeaconState, payload *cltypes.Eth1Block) error
|
||||
FnProcessRandao func(s abstract.BeaconState, randao [96]byte, proposerIndex uint64) error
|
||||
FnProcessEth1Data func(state abstract.BeaconState, eth1Data *cltypes.Eth1Data) error
|
||||
@ -41,7 +40,7 @@ func (i Impl) ProcessBlockHeader(s abstract.BeaconState, block *cltypes.BeaconBl
|
||||
return i.FnProcessBlockHeader(s, block)
|
||||
}
|
||||
|
||||
func (i Impl) ProcessWithdrawals(s abstract.BeaconState, withdrawals *solid.ListSSZ[*types.Withdrawal]) error {
|
||||
func (i Impl) ProcessWithdrawals(s abstract.BeaconState, withdrawals *solid.ListSSZ[*cltypes.Withdrawal]) error {
|
||||
return i.FnProcessWithdrawals(s, withdrawals)
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"github.com/ledgerwatch/erigon/cl/abstract"
|
||||
"github.com/ledgerwatch/erigon/cl/cltypes"
|
||||
"github.com/ledgerwatch/erigon/cl/cltypes/solid"
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
@ -30,7 +29,7 @@ type SlotProcessor interface {
|
||||
|
||||
type BlockHeaderProcessor interface {
|
||||
ProcessBlockHeader(s abstract.BeaconState, block *cltypes.BeaconBlock) error
|
||||
ProcessWithdrawals(s abstract.BeaconState, withdrawals *solid.ListSSZ[*types.Withdrawal]) error
|
||||
ProcessWithdrawals(s abstract.BeaconState, withdrawals *solid.ListSSZ[*cltypes.Withdrawal]) error
|
||||
ProcessExecutionPayload(s abstract.BeaconState, payload *cltypes.Eth1Block) error
|
||||
ProcessRandao(s abstract.BeaconState, randao [96]byte, proposerIndex uint64) error
|
||||
ProcessEth1Data(state abstract.BeaconState, eth1Data *cltypes.Eth1Data) error
|
||||
|
@ -22,11 +22,8 @@ import (
|
||||
"io"
|
||||
|
||||
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||
"github.com/ledgerwatch/erigon-lib/common/length"
|
||||
"github.com/ledgerwatch/erigon-lib/types/clonable"
|
||||
"github.com/ledgerwatch/erigon-lib/types/ssz"
|
||||
|
||||
"github.com/ledgerwatch/erigon/cl/merkle_tree"
|
||||
"github.com/ledgerwatch/erigon/common/hexutil"
|
||||
"github.com/ledgerwatch/erigon/rlp"
|
||||
)
|
||||
@ -42,11 +39,6 @@ type Withdrawal struct {
|
||||
Amount uint64 `json:"amount"` // value of withdrawal in GWei
|
||||
}
|
||||
|
||||
func (obj *Withdrawal) Equal(other *Withdrawal) bool {
|
||||
return obj.Index == other.Index && obj.Validator == other.Validator &&
|
||||
obj.Address == other.Address && obj.Amount == other.Amount
|
||||
}
|
||||
|
||||
func (obj *Withdrawal) EncodingSize() int {
|
||||
encodingSize := 21 /* Address */
|
||||
encodingSize++
|
||||
@ -84,34 +76,6 @@ func (obj *Withdrawal) EncodeRLP(w io.Writer) error {
|
||||
return rlp.EncodeInt(obj.Amount, w, b[:])
|
||||
}
|
||||
|
||||
func (obj *Withdrawal) EncodeSSZ(buf []byte) ([]byte, error) {
|
||||
buf = append(buf, ssz.Uint64SSZ(obj.Index)...)
|
||||
buf = append(buf, ssz.Uint64SSZ(obj.Validator)...)
|
||||
buf = append(buf, obj.Address[:]...)
|
||||
buf = append(buf, ssz.Uint64SSZ(obj.Amount)...)
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func (obj *Withdrawal) DecodeSSZ(buf []byte, _ int) error {
|
||||
if len(buf) < obj.EncodingSizeSSZ() {
|
||||
return fmt.Errorf("[Withdrawal] err: %s", ssz.ErrLowBufferSize)
|
||||
}
|
||||
obj.Index = ssz.UnmarshalUint64SSZ(buf)
|
||||
obj.Validator = ssz.UnmarshalUint64SSZ(buf[8:])
|
||||
copy(obj.Address[:], buf[16:])
|
||||
obj.Amount = ssz.UnmarshalUint64SSZ(buf[36:])
|
||||
return nil
|
||||
}
|
||||
|
||||
func (obj *Withdrawal) EncodingSizeSSZ() int {
|
||||
// Validator Index (8 bytes) + Index (8 bytes) + Amount (8 bytes) + address length
|
||||
return 24 + length.Addr
|
||||
}
|
||||
|
||||
func (obj *Withdrawal) HashSSZ() ([32]byte, error) { // the [32]byte is temporary
|
||||
return merkle_tree.HashTreeRoot(obj.Index, obj.Validator, obj.Address[:], obj.Amount)
|
||||
}
|
||||
|
||||
func (obj *Withdrawal) DecodeRLP(s *rlp.Stream) error {
|
||||
_, err := s.List()
|
||||
if err != nil {
|
||||
|
@ -5,9 +5,6 @@ import (
|
||||
|
||||
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/ledgerwatch/erigon/common"
|
||||
)
|
||||
|
||||
func TestWithdrawalsHash(t *testing.T) {
|
||||
@ -23,24 +20,3 @@ func TestWithdrawalsHash(t *testing.T) {
|
||||
// Its Keccak should be returned, not the node itself.
|
||||
assert.Equal(t, libcommon.HexToHash("82cc6fbe74c41496b382fcdf25216c5af7bdbb5a3929e8f2e61bd6445ab66436"), hash)
|
||||
}
|
||||
|
||||
// Test taken from: https://github.com/ethereum/consensus-spec-tests/tree/master/tests/mainnet/capella/ssz_static/Withdrawal/ssz_random/case_1
|
||||
var testWithdrawalEncodedSSZ = common.Hex2Bytes("09b99ded9629457f21c3c177a3cf80dedbbcbcbeee17b2395d5d3f839fc1ba3559d1a73ef53b8a5325e25ad2")
|
||||
var testWithdrawalsSSZHash = libcommon.HexToHash("c1ec17957781f09ab3d8dbfcdfaa6c3b40a1679d3d124588f77a2da5ebb3555f")
|
||||
var testWithdrawal = &Withdrawal{
|
||||
Index: 9170781944418253065,
|
||||
Validator: 16033042974434771745,
|
||||
Address: libcommon.HexToAddress("0xdbbcbcbeee17b2395d5d3f839fc1ba3559d1a73e"),
|
||||
Amount: 15157676145812061173,
|
||||
}
|
||||
|
||||
func TestWithdrawalSSZ(t *testing.T) {
|
||||
withdrawal := &Withdrawal{}
|
||||
require.NoError(t, withdrawal.DecodeSSZ(testWithdrawalEncodedSSZ, 0))
|
||||
require.Equal(t, withdrawal, testWithdrawal)
|
||||
a, _ := withdrawal.EncodeSSZ(nil)
|
||||
require.Equal(t, a, testWithdrawalEncodedSSZ)
|
||||
hashSSZ, err := withdrawal.HashSSZ()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, libcommon.Hash(hashSSZ), testWithdrawalsSSZHash)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user