From 05531dc00c3d942df1ceb258ff92f05b1a1b3684 Mon Sep 17 00:00:00 2001 From: Nikita Kryuchkov Date: Fri, 9 Feb 2024 17:59:33 +0400 Subject: [PATCH 1/5] Change network to interface in SimpleSigner --- signer/far_future_protection.go | 6 ++---- signer/validator_signer.go | 9 +++++++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/signer/far_future_protection.go b/signer/far_future_protection.go index 328f524a..36ef7fdd 100644 --- a/signer/far_future_protection.go +++ b/signer/far_future_protection.go @@ -4,8 +4,6 @@ import ( "time" "github.com/attestantio/go-eth2-client/spec/phase0" - - "github.com/bloxapp/eth2-key-manager/core" ) // FarFutureMaxValidEpoch is the max epoch of far future signing @@ -13,13 +11,13 @@ var FarFutureMaxValidEpoch = int64(time.Minute.Seconds() * 20) // IsValidFarFutureEpoch prevents far into the future signing request, verify a slot is within the current epoch // https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/validator.md#protection-best-practices -func IsValidFarFutureEpoch(network core.Network, epoch phase0.Epoch) bool { +func IsValidFarFutureEpoch(network network, epoch phase0.Epoch) bool { maxValidEpoch := network.EstimatedEpochAtSlot(network.EstimatedSlotAtTime(time.Now().Unix() + FarFutureMaxValidEpoch)) return epoch <= maxValidEpoch } // IsValidFarFutureSlot returns true if the given slot is valid -func IsValidFarFutureSlot(network core.Network, slot phase0.Slot) bool { +func IsValidFarFutureSlot(network network, slot phase0.Slot) bool { maxValidSlot := network.EstimatedSlotAtTime(time.Now().Unix() + FarFutureMaxValidEpoch) return slot <= maxValidSlot } diff --git a/signer/validator_signer.go b/signer/validator_signer.go index a4e12b9c..19e1d4ba 100644 --- a/signer/validator_signer.go +++ b/signer/validator_signer.go @@ -30,17 +30,22 @@ type ValidatorSigner interface { SignBLSToExecutionChange(blsToExecutionChange *capella.BLSToExecutionChange, domain phase0.Domain, pubKey []byte) (sig []byte, root []byte, err error) } +type network interface { + EstimatedEpochAtSlot(slot phase0.Slot) phase0.Epoch + EstimatedSlotAtTime(time int64) phase0.Slot +} + // SimpleSigner implements ValidatorSigner interface type SimpleSigner struct { wallet core.Wallet slashingProtector core.SlashingProtector - network core.Network + network network signLocks map[string]*sync.RWMutex mapLock *sync.RWMutex } // NewSimpleSigner is the constructor of SimpleSigner -func NewSimpleSigner(wallet core.Wallet, slashingProtector core.SlashingProtector, network core.Network) *SimpleSigner { +func NewSimpleSigner(wallet core.Wallet, slashingProtector core.SlashingProtector, network network) *SimpleSigner { return &SimpleSigner{ wallet: wallet, slashingProtector: slashingProtector, From 62dfd67eb8841354eb63ea8f316c6e4e5fced013 Mon Sep 17 00:00:00 2001 From: y0sher Date: Mon, 10 Mar 2025 13:09:38 +0200 Subject: [PATCH 2/5] add stacktrace to logs --- core/networks.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/core/networks.go b/core/networks.go index 83d8417d..d93dd98a 100644 --- a/core/networks.go +++ b/core/networks.go @@ -2,12 +2,22 @@ package core import ( "encoding/hex" + "runtime/debug" "time" "github.com/attestantio/go-eth2-client/spec/phase0" "github.com/sirupsen/logrus" ) +// logFatalWithStack logs a fatal message with a stack trace +func logFatalWithStack(field string, value interface{}, message string) { + stackTrace := string(debug.Stack()) + logrus.WithFields(logrus.Fields{ + field: value, + "stacktrace": stackTrace, + }).Fatal(message) +} + // Network represents the network. type Network string @@ -39,7 +49,7 @@ func (n Network) GenesisForkVersion() phase0.Version { case MainNetwork: return phase0.Version{0, 0, 0, 0} default: - logrus.WithField("network", n).Fatal("undefined network") + logFatalWithStack("network", n, "undefined network") return phase0.Version{} } } @@ -58,7 +68,7 @@ func (n Network) GenesisValidatorsRoot() phase0.Root { rootBytes, _ := hex.DecodeString("4b363db94e286120d76eb905340fdd4e54bfe9f06bf33ff6cf5ad27f511bfe95") copy(genValidatorsRoot[:], rootBytes) default: - logrus.WithField("network", n).Fatal("undefined network") + logFatalWithStack("network", n, "undefined network") } return genValidatorsRoot } @@ -75,7 +85,7 @@ func (n Network) DepositContractAddress() string { case MainNetwork: return "0x00000000219ab540356cBB839Cbe05303d7705Fa" default: - logrus.WithField("network", n).Fatal("undefined network") + logFatalWithStack("network", n, "undefined network") return "" } } @@ -97,7 +107,7 @@ func (n Network) MinGenesisTime() uint64 { case MainNetwork: return 1606824023 default: - logrus.WithField("network", n).Fatal("undefined network") + logFatalWithStack("network", n, "undefined network") return 0 } } From 9e9491cefa514f5233a89495052574c48df7f998 Mon Sep 17 00:00:00 2001 From: y0sher Date: Mon, 10 Mar 2025 13:23:22 +0200 Subject: [PATCH 3/5] change uint64 time to time.Time --- signer/validator_signer.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/signer/validator_signer.go b/signer/validator_signer.go index 63e4977c..67438b11 100644 --- a/signer/validator_signer.go +++ b/signer/validator_signer.go @@ -2,6 +2,7 @@ package signer import ( "sync" + "time" "github.com/attestantio/go-eth2-client/api" "github.com/attestantio/go-eth2-client/spec" @@ -32,7 +33,7 @@ type ValidatorSigner interface { type network interface { EstimatedEpochAtSlot(slot phase0.Slot) phase0.Epoch - EstimatedSlotAtTime(time int64) phase0.Slot + EstimatedSlotAtTime(time time.Time) phase0.Slot } // SimpleSigner implements ValidatorSigner interface From 87548a6e18ae07c54f47aa0783bbad400d69e73f Mon Sep 17 00:00:00 2001 From: y0sher Date: Mon, 10 Mar 2025 13:40:12 +0200 Subject: [PATCH 4/5] align iface usage --- signer/far_future_protection.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/signer/far_future_protection.go b/signer/far_future_protection.go index 36ef7fdd..d22e9c27 100644 --- a/signer/far_future_protection.go +++ b/signer/far_future_protection.go @@ -7,17 +7,17 @@ import ( ) // FarFutureMaxValidEpoch is the max epoch of far future signing -var FarFutureMaxValidEpoch = int64(time.Minute.Seconds() * 20) +var FarFutureMaxValidEpoch = time.Minute * 20 // IsValidFarFutureEpoch prevents far into the future signing request, verify a slot is within the current epoch // https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/validator.md#protection-best-practices func IsValidFarFutureEpoch(network network, epoch phase0.Epoch) bool { - maxValidEpoch := network.EstimatedEpochAtSlot(network.EstimatedSlotAtTime(time.Now().Unix() + FarFutureMaxValidEpoch)) + maxValidEpoch := network.EstimatedEpochAtSlot(network.EstimatedSlotAtTime(time.Now().Add(FarFutureMaxValidEpoch))) return epoch <= maxValidEpoch } // IsValidFarFutureSlot returns true if the given slot is valid func IsValidFarFutureSlot(network network, slot phase0.Slot) bool { - maxValidSlot := network.EstimatedSlotAtTime(time.Now().Unix() + FarFutureMaxValidEpoch) + maxValidSlot := network.EstimatedSlotAtTime(time.Now().Add(FarFutureMaxValidEpoch)) return slot <= maxValidSlot } From f7145d182b6edd22af46246a693954c25aeb85dc Mon Sep 17 00:00:00 2001 From: y0sher Date: Thu, 17 Apr 2025 17:40:33 +0300 Subject: [PATCH 5/5] Fix lint errors by updating EstimatedSlotAtTime to use time.Time and addressing other code quality issues. --- cli/util/printer/standard.go | 6 +++--- core/networks.go | 9 +++++---- core/networks_test.go | 2 +- signer/sign_attestation_test.go | 2 +- signer/sign_beacon_block_test.go | 2 +- stores/inmemory/marshalable.go | 7 ++++--- stores/inmemory/store_test.go | 4 ++-- 7 files changed, 17 insertions(+), 15 deletions(-) diff --git a/cli/util/printer/standard.go b/cli/util/printer/standard.go index 4f9187c9..5ba96396 100644 --- a/cli/util/printer/standard.go +++ b/cli/util/printer/standard.go @@ -33,7 +33,7 @@ func New(out io.Writer) Printer { // Text implements Printer interface. func (p *StandardPrinter) Text(text string) { - fmt.Fprintln(p.out, text) + _, _ = fmt.Fprintln(p.out, text) } // JSON implements Printer interface. @@ -47,9 +47,9 @@ func (p *StandardPrinter) JSON(obj interface{}) error { return nil } -// JSON implements Printer interface. +// Error implements Printer interface. func (p *StandardPrinter) Error(err error) { if err != nil { - fmt.Fprintln(p.out, "Error:", err.Error()) + _, _ = fmt.Fprintln(p.out, "Error:", err.Error()) } } diff --git a/core/networks.go b/core/networks.go index d93dd98a..472bc02d 100644 --- a/core/networks.go +++ b/core/networks.go @@ -124,16 +124,17 @@ func (n Network) SlotsPerEpoch() uint64 { // EstimatedCurrentSlot returns the estimation of the current slot func (n Network) EstimatedCurrentSlot() phase0.Slot { - return n.EstimatedSlotAtTime(time.Now().Unix()) + return n.EstimatedSlotAtTime(time.Now()) } // EstimatedSlotAtTime estimates slot at the given time -func (n Network) EstimatedSlotAtTime(time int64) phase0.Slot { +func (n Network) EstimatedSlotAtTime(t time.Time) phase0.Slot { + timeUnix := t.Unix() genesis := int64(n.MinGenesisTime()) - if time < genesis { + if timeUnix < genesis { return 0 } - return phase0.Slot(uint64(time-genesis) / uint64(n.SlotDurationSec().Seconds())) + return phase0.Slot(uint64(timeUnix-genesis) / uint64(n.SlotDurationSec().Seconds())) } // EstimatedCurrentEpoch estimates the current epoch diff --git a/core/networks_test.go b/core/networks_test.go index beef15f0..997b402f 100644 --- a/core/networks_test.go +++ b/core/networks_test.go @@ -14,6 +14,6 @@ func TestNetworkMainnet(t *testing.T) { secondsPassedSinceGenesis := time.Now().Unix() - 1606824023 require.EqualValues(t, phase0.Epoch(secondsPassedSinceGenesis/(12*32)), net.EstimatedCurrentEpoch()) require.EqualValues(t, phase0.Epoch(secondsPassedSinceGenesis/12), net.EstimatedCurrentSlot()) - require.EqualValues(t, phase0.Epoch(secondsPassedSinceGenesis/12), net.EstimatedSlotAtTime(time.Now().Unix())) + require.EqualValues(t, phase0.Epoch(secondsPassedSinceGenesis/12), net.EstimatedSlotAtTime(time.Now())) require.EqualValues(t, phase0.Epoch(101010/32), net.EstimatedEpochAtSlot(phase0.Slot(101010))) } diff --git a/signer/sign_attestation_test.go b/signer/sign_attestation_test.go index e5859d36..4659a283 100644 --- a/signer/sign_attestation_test.go +++ b/signer/sign_attestation_test.go @@ -682,7 +682,7 @@ func TestAttestationSignatures(t *testing.T) { func TestFarFutureAttestationSignature(t *testing.T) { seed := _byteArray("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fff") network := core.PraterNetwork - maxValidEpoch := network.EstimatedEpochAtSlot(network.EstimatedSlotAtTime(time.Now().Unix() + FarFutureMaxValidEpoch)) + maxValidEpoch := network.EstimatedEpochAtSlot(network.EstimatedSlotAtTime(time.Now().Add(FarFutureMaxValidEpoch))) t.Run("max valid source", func(tt *testing.T) { signer, err := setupWithSlashingProtection(t, seed, true, true) diff --git a/signer/sign_beacon_block_test.go b/signer/sign_beacon_block_test.go index 9b2d144d..d383f1c4 100644 --- a/signer/sign_beacon_block_test.go +++ b/signer/sign_beacon_block_test.go @@ -341,7 +341,7 @@ func TestProposalSlashingSignatures(t *testing.T) { func TestFarFutureProposalSignature(t *testing.T) { seed := _byteArray("0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fff") network := core.PraterNetwork - maxValidSlot := network.EstimatedSlotAtTime(time.Now().Unix() + FarFutureMaxValidEpoch) + maxValidSlot := network.EstimatedSlotAtTime(time.Now().Add(FarFutureMaxValidEpoch)) t.Run("max valid source", func(tt *testing.T) { signer, err := setupWithSlashingProtection(t, seed, true, true) diff --git a/stores/inmemory/marshalable.go b/stores/inmemory/marshalable.go index 75d2ce36..04b6556e 100644 --- a/stores/inmemory/marshalable.go +++ b/stores/inmemory/marshalable.go @@ -75,21 +75,22 @@ func (store *InMemStore) UnmarshalJSON(data []byte) error { return err } - if walletType == core.HDWallet { + switch walletType { + case core.HDWallet: hd := &hd2.Wallet{} err = json.Unmarshal(byts, &hd) if err != nil { return err } store.wallet = hd - } else if walletType == core.NDWallet { + case core.NDWallet: nd := &nd.Wallet{} err = json.Unmarshal(byts, &nd) if err != nil { return err } store.wallet = nd - } else { + default: return errors.Errorf("unknown wallet type %s", walletType) } } else { diff --git a/stores/inmemory/store_test.go b/stores/inmemory/store_test.go index 7f79085e..6e8aa598 100644 --- a/stores/inmemory/store_test.go +++ b/stores/inmemory/store_test.go @@ -287,7 +287,7 @@ func TestWalletStorage(t *testing.T) { err = storage.SaveWallet(wallet) if err != nil { if test.error != nil { - require.Equal(t, test.error.Error(), err.Error()) + require.Equal(t, test.error, err) } else { t.Error(err) } @@ -298,7 +298,7 @@ func TestWalletStorage(t *testing.T) { fetched, err := storage.OpenWallet() if err != nil { if test.error != nil { - require.Equal(t, test.error.Error(), err.Error()) + require.Equal(t, test.error, err) } else { t.Error(err) }