Update documentation for accountmanager.

Add configuration for multinode submitter.
This commit is contained in:
Jim McDonald 2020-09-30 09:56:44 +01:00
parent b279c097df
commit 6142a292b5
No known key found for this signature in database
GPG Key ID: 89CEB61B2AD2A5E7
10 changed files with 47 additions and 23 deletions

View File

@ -1,4 +1,7 @@
Development:
- update documentation for account managers, explaining the difference between Dirk and wallet
- add submitter configuration to documentation
- use latest version of go-eth2-client to enable timeouts
- if Vouch fails to obtain an updated list of validators continue with what it has
- block proposal calculation counts slashed indices rather than slashing entries
0.6.0:

View File

@ -1,7 +1,9 @@
# Account managers
Account managers are the interface between Vouch and the accounts for which it validates. Account managers provide the list of validating accounts and carry out signing operations.
Vouch currently supports two account managers: Dirk and wallet.
Vouch currently supports two account managers: Dirk and wallet. Dirk is a remote keymanager that provides additional features such as distributed key generation, threshold signing, and slashing protection. Wallet is a local keymanager that is quick and easy to set up.
**It is recommended that Dirk be used for all production installations, due to the additional protections it provides. Although Vouch attempts to avoid requesting signatures that could cause a slashing event, it does not have in-built slashing protection and relies on Dirk for this functionality.**
## `dirk`
The `dirk` account manager obtains account information from [Dirk](https://github.com/attestantio/dirk), and uses Dirk for remote signing. It is important to understand that this account manager never holds the private keys, instead it sends the data to sign to the Dirk server, which carries out signing as well as slashing prevention.
@ -70,13 +72,13 @@ Each item is explained in more detail below.
If no locations are supplied, the [default location for wallets](https://github.com/wealdtech/go-eth2-wallet-store-filesystem#usage) will be used.
### accounts
`accounts` is the list of accounts that Vouch will request from Dirk. This is an account specifier, and can be supplied in various forms for example:
`accounts` is the list of accounts that Vouch will request locally. This is an account specifier, and can be supplied in various forms for example:
- **`wallet`** will return all accounts in _wallet_
- **`wallet/Validator.*`** will return all accounts in _wallet_ starting with _Validator_
- **`wallet/Validator.*[02468]`** will return all accounts in _wallet_ starting with _Validator_ and ending in an even number
At least one account specifier is required for the Dirk account manager.
At least one account specifier is required for the wallet account manager.
### passphrases
`passphrases` is a list of passphrases that will be used to unlock the accounts. Each item in the list is a [Majordomo](https://github.com/wealdtech/go-majordomo) URL.

View File

@ -32,6 +32,16 @@ graffiti:
static:
value: My graffiti
# submitter submits data to beacon nodes. If not present the nodes in beacon-node-address above will be used.
submitter:
# style can currently only be 'all'
style: all
# beacon-node-addresses is the list of addresses to which submit. Submissions run in parallel
beacon-node-addresses:
- localhost:4000
- localhost:5051
- localhost:5052
# strategies provide advanced strategies for dealing with multiple beacon nodes
strategies:
beaconblockproposal:
@ -71,7 +81,7 @@ Modules levels are used for each module, overriding the global log level. The a
- **graffiti** provision of graffiti for proposed blocks
- **majordomo** accesss to secrets
- **scheduler** starting internal jobs such as proposing a block at the appropriate time
- **strategies.submitter** decisions on how to submit information to multiple beacon nodes
- **strategies.beaconblockproposer** decisions on how to obtain information from multiple beacon nodes
- **submitter** decisions on how to submit information to multiple beacon nodes
This can be configured using the environment variables `VOUCH_<MODULE>_LOG_LEVEL` or the configuration option `<module>.log-level`. For example, the controller module logging could be configured using the environment variable `VOUCH_CONTROLLER_LOG_LEVEL` or the configuration option `controller.log-level`.

2
go.mod
View File

@ -5,7 +5,7 @@ go 1.14
require (
cloud.google.com/go v0.66.0 // indirect
github.com/OneOfOne/xxhash v1.2.5 // indirect
github.com/attestantio/go-eth2-client v0.6.5
github.com/attestantio/go-eth2-client v0.6.6
github.com/aws/aws-sdk-go v1.34.31
github.com/ferranbt/fastssz v0.0.0-20200826142241-3a913c5a1313
github.com/fsnotify/fsnotify v1.4.9 // indirect

2
go.sum
View File

@ -64,6 +64,8 @@ github.com/attestantio/go-eth2-client v0.6.4 h1:EfnOCWlPrmLXBxMyctXUOEIcn61/QnYv
github.com/attestantio/go-eth2-client v0.6.4/go.mod h1:lYEayGHzZma9HMUJgyxFIzDWRck8n2IedP7KTkIwe0g=
github.com/attestantio/go-eth2-client v0.6.5 h1:IaPJfxOTqHdkfmeuy6MntsuLEoJipf7V6m4njBE4F6w=
github.com/attestantio/go-eth2-client v0.6.5/go.mod h1:lYEayGHzZma9HMUJgyxFIzDWRck8n2IedP7KTkIwe0g=
github.com/attestantio/go-eth2-client v0.6.6 h1:rgqG4KDyLDw75vOqnFnJ/nAXzkp6EDFaOctMzPJYNWI=
github.com/attestantio/go-eth2-client v0.6.6/go.mod h1:lYEayGHzZma9HMUJgyxFIzDWRck8n2IedP7KTkIwe0g=
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.33.5/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=

View File

@ -608,14 +608,14 @@ func selectBeaconBlockProposalProvider(ctx context.Context,
func selectSubmitterStrategy(ctx context.Context, eth2Client eth2client.Service) (submitter.Service, error) {
var submitter submitter.Service
var err error
switch viper.GetString("strategies.submitter.style") {
switch viper.GetString("submitter.style") {
case "all":
log.Info().Msg("Starting multinode submitter strategy")
beaconBlockSubmitters := make(map[string]eth2client.BeaconBlockSubmitter)
attestationSubmitters := make(map[string]eth2client.AttestationSubmitter)
aggregateAttestationSubmitters := make(map[string]eth2client.AggregateAttestationsSubmitter)
beaconCommitteeSubscriptionsSubmitters := make(map[string]eth2client.BeaconCommitteeSubscriptionsSubmitter)
for _, address := range viper.GetStringSlice("strategies.submitter.all.beacon-node-addresses") {
for _, address := range viper.GetStringSlice("submitter.beacon-node-addresses") {
client, err := fetchClient(ctx, address)
if err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("failed to fetch client %q for submitter strategy", address))
@ -627,7 +627,7 @@ func selectSubmitterStrategy(ctx context.Context, eth2Client eth2client.Service)
}
submitter, err = multinodesubmitter.New(ctx,
multinodesubmitter.WithProcessConcurrency(viper.GetInt64("process-concurrency")),
multinodesubmitter.WithLogLevel(logLevel(viper.GetString("strategies.submitter.log-level"))),
multinodesubmitter.WithLogLevel(logLevel(viper.GetString("submitter.log-level"))),
multinodesubmitter.WithBeaconBlockSubmitters(beaconBlockSubmitters),
multinodesubmitter.WithAttestationSubmitters(attestationSubmitters),
multinodesubmitter.WithAggregateAttestationsSubmitters(aggregateAttestationSubmitters),
@ -636,7 +636,7 @@ func selectSubmitterStrategy(ctx context.Context, eth2Client eth2client.Service)
default:
log.Info().Msg("Starting standard submitter strategy")
submitter, err = immediatesubmitter.New(ctx,
immediatesubmitter.WithLogLevel(logLevel(viper.GetString("strategies.submitter.log-level"))),
immediatesubmitter.WithLogLevel(logLevel(viper.GetString("submitter.log-level"))),
immediatesubmitter.WithBeaconBlockSubmitter(eth2Client.(eth2client.BeaconBlockSubmitter)),
immediatesubmitter.WithAttestationSubmitter(eth2Client.(eth2client.AttestationSubmitter)),
immediatesubmitter.WithBeaconCommitteeSubscriptionsSubmitter(eth2Client.(eth2client.BeaconCommitteeSubscriptionsSubmitter)),

View File

@ -24,10 +24,10 @@ import (
"golang.org/x/sync/semaphore"
)
// SubmitAggregateAttestation submits an aggregate attestation.
func (s *Service) SubmitAggregateAttestation(ctx context.Context, aggregate *spec.SignedAggregateAndProof) error {
if aggregate == nil {
return errors.New("no aggregate attestation supplied")
// SubmitAggregateAttestations submits aggregate attestations.
func (s *Service) SubmitAggregateAttestations(ctx context.Context, aggregates []*spec.SignedAggregateAndProof) error {
if len(aggregates) == 0 {
return errors.New("no aggregate attestations supplied")
}
sem := semaphore.NewWeighted(s.processConcurrency)
@ -41,26 +41,26 @@ func (s *Service) SubmitAggregateAttestation(ctx context.Context, aggregate *spe
submitter eth2client.AggregateAttestationsSubmitter,
) {
defer wg.Done()
log := log.With().Str("submitter", name).Uint64("slot", aggregate.Message.Aggregate.Data.Slot).Logger()
log := log.With().Str("beacon_node_address", name).Uint64("slot", aggregates[0].Message.Aggregate.Data.Slot).Logger()
if err := sem.Acquire(ctx, 1); err != nil {
log.Error().Err(err).Msg("Failed to acquire semaphore")
return
}
defer sem.Release(1)
if err := submitter.SubmitAggregateAttestations(ctx, []*spec.SignedAggregateAndProof{aggregate}); err != nil {
log.Warn().Err(err).Msg("Failed to submit aggregate attestation")
if err := submitter.SubmitAggregateAttestations(ctx, aggregates); err != nil {
log.Warn().Err(err).Msg("Failed to submit aggregate attestations")
return
}
log.Trace().Msg("Submitted aggregate attestation")
log.Trace().Msg("Submitted aggregate attestations")
}(ctx, sem, &wg, name, submitter)
}
wg.Wait()
if e := log.Trace(); e.Enabled() {
data, err := json.Marshal(aggregate)
data, err := json.Marshal(aggregates)
if err == nil {
e.Str("attestation", string(data)).Msg("Submitted aggregate attestation")
e.Str("aggregate_attestations", string(data)).Msg("Submitted aggregate attestations")
}
}

View File

@ -16,6 +16,7 @@ package multinode
import (
"context"
"encoding/json"
"strings"
"sync"
eth2client "github.com/attestantio/go-eth2-client"
@ -41,7 +42,7 @@ func (s *Service) SubmitAttestation(ctx context.Context, attestation *spec.Attes
submitter eth2client.AttestationSubmitter,
) {
defer wg.Done()
log := log.With().Str("submitter", name).Uint64("slot", attestation.Data.Slot).Logger()
log := log.With().Str("beacon_node_address", name).Uint64("slot", attestation.Data.Slot).Logger()
if err := sem.Acquire(ctx, 1); err != nil {
log.Error().Err(err).Msg("Failed to acquire semaphore")
return
@ -49,7 +50,13 @@ func (s *Service) SubmitAttestation(ctx context.Context, attestation *spec.Attes
defer sem.Release(1)
if err := submitter.SubmitAttestation(ctx, attestation); err != nil {
log.Warn().Msg("Failed to submit attestation")
if strings.Contains(err.Error(), "PriorAttestationKnown") {
// Lighthouse rejects duplicate attestations. It is possible that an attestation we sent
// to another node already propagated to this node, so ignore the error.
log.Trace().Msg("Node already knows about attestation; ignored")
} else {
log.Warn().Err(err).Msg("Failed to submit attestation")
}
return
}
log.Trace().Msg("Submitted attestation")

View File

@ -41,7 +41,7 @@ func (s *Service) SubmitBeaconBlock(ctx context.Context, block *spec.SignedBeaco
submitter eth2client.BeaconBlockSubmitter,
) {
defer wg.Done()
log := log.With().Str("submitter", name).Uint64("slot", block.Message.Slot).Logger()
log := log.With().Str("beacon_node_address", name).Uint64("slot", block.Message.Slot).Logger()
if err := sem.Acquire(ctx, 1); err != nil {
log.Error().Err(err).Msg("Failed to acquire semaphore")
return

View File

@ -54,7 +54,7 @@ func (s *Service) SubmitBeaconCommitteeSubscriptions(ctx context.Context, subscr
submitter eth2client.BeaconCommitteeSubscriptionsSubmitter,
) {
defer wg.Done()
log := log.With().Str("submitter", name).Int("subscriptions", len(subs)).Logger()
log := log.With().Str("beacon_node_address", name).Int("subscriptions", len(subs)).Logger()
if err := sem.Acquire(ctx, 1); err != nil {
log.Error().Err(err).Msg("Failed to acquire semaphore")
return