diff --git a/consensus/beacon/validator_status.go b/consensus/beacon/validator_status.go new file mode 100644 index 0000000..f7f20e9 --- /dev/null +++ b/consensus/beacon/validator_status.go @@ -0,0 +1,55 @@ +// description: +// @author renshiwei +// Date: 2023/6/30 + +package beacon + +import ( + "context" + consensusApi "github.com/attestantio/go-eth2-client/api/v1" + "github.com/attestantio/go-eth2-client/spec/phase0" + "github.com/duktig666/ethsuper/eth1" + "github.com/pkg/errors" + "math/big" + "strconv" +) + +// ValidatorIsFullExited Whether the validator has completed the lifecycle of the exit +func ValidatorIsFullExited(validator *consensusApi.Validator) bool { + return validator.Status == consensusApi.ValidatorStateWithdrawalDone +} + +// ValidatorIsRequestExiting Whether the validator request the exit +func ValidatorIsRequestExiting(validator *consensusApi.Validator) bool { + return validator.Status == consensusApi.ValidatorStateActiveExiting || + validator.Status == consensusApi.ValidatorStateActiveSlashed || + validator.Status == consensusApi.ValidatorStateExitedUnslashed || + validator.Status == consensusApi.ValidatorStateExitedSlashed || + validator.Status == consensusApi.ValidatorStateWithdrawalPossible || + validator.Status == consensusApi.ValidatorStateWithdrawalDone +} + +// ValidatorSlashedAmount 32ETh - ValidatorWithdrawAbleBalance +func (b *BeaconService) ValidatorSlashedAmount(ctx context.Context, validator *consensusApi.Validator) (*big.Int, error) { + if !validator.Validator.Slashed { + return nil, errors.New("validator not slashed.") + } + + pubkey := validator.Validator.PublicKey.String() + + withdrawAbleSlot := epochToSlot(validator.Validator.WithdrawableEpoch) + pubkeys := make([]string, 1) + pubkeys[0] = pubkey + slashedValidator, err := b.ValidatorsByPubKey(ctx, strconv.FormatInt(int64(withdrawAbleSlot), 10), pubkeys) + if err != nil { + return nil, errors.Wrap(err, "Failed to get validators info.") + } + + slashAmount := new(big.Int).Sub(eth1.ETH32().BigInt(), eth1.GweiToWei(slashedValidator[pubkey].Balance)) + + return slashAmount, nil +} + +func epochToSlot(epoch phase0.Epoch) phase0.Slot { + return phase0.Slot(uint64(epoch) * 12) +} diff --git a/consensus/chaintime/service.go b/consensus/chaintime/service.go index a1e3248..96b0c5c 100644 --- a/consensus/chaintime/service.go +++ b/consensus/chaintime/service.go @@ -42,6 +42,8 @@ type Service interface { CurrentSyncCommitteePeriod() uint64 // SlotToEpoch provides the epoch of the given slot. SlotToEpoch(slot phase0.Slot) phase0.Epoch + // EpochToSlot provides the slot of the given epoch. + EpochToSlot(epoch phase0.Epoch) phase0.Slot // SlotToSyncCommitteePeriod provides the sync committee period of the given slot. SlotToSyncCommitteePeriod(slot phase0.Slot) uint64 // FirstSlotOfEpoch provides the first slot of the given epoch. diff --git a/consensus/chaintime/standard/service.go b/consensus/chaintime/standard/service.go index 7c8b5c9..07c091a 100644 --- a/consensus/chaintime/standard/service.go +++ b/consensus/chaintime/standard/service.go @@ -168,6 +168,11 @@ func (s *Service) SlotToEpoch(slot phase0.Slot) phase0.Epoch { return phase0.Epoch(uint64(slot) / s.slotsPerEpoch) } +// EpochToSlot provides the slot of the given epoch. +func (s *Service) EpochToSlot(epoch phase0.Epoch) phase0.Slot { + return phase0.Slot(uint64(epoch) * s.slotsPerEpoch) +} + // SlotToSyncCommitteePeriod provides the sync committee period of the given slot. func (s *Service) SlotToSyncCommitteePeriod(slot phase0.Slot) uint64 { return uint64(s.SlotToEpoch(slot)) / s.epochsPerSyncCommitteePeriod diff --git a/eth1/constants.go b/eth1/constants.go index 1d3f6b4..a62e1af 100644 --- a/eth1/constants.go +++ b/eth1/constants.go @@ -18,6 +18,7 @@ package eth1 import ( + "github.com/attestantio/go-eth2-client/spec/phase0" "github.com/ethereum/go-ethereum/params" "github.com/shopspring/decimal" "math/big" @@ -42,3 +43,11 @@ func ETH32() decimal.Decimal { eth32, _ := decimal.NewFromString("32000000000000000000") return eth32 } + +func GweiToWei(gwei phase0.Gwei) *big.Int { + return new(big.Int).Mul(big.NewInt(int64(gwei)), big.NewInt(params.GWei)) +} + +func ETH(eth int64) *big.Int { + return new(big.Int).Mul(big.NewInt(params.Ether), big.NewInt(eth)) +}