Skip to content

Commit 600efdb

Browse files
authored
Merge pull request #369 from attestantio/vouch-combined-att
Add combinedmajority attestation strategy
2 parents 7266818 + cd32064 commit 600efdb

File tree

14 files changed

+1257
-52
lines changed

14 files changed

+1257
-52
lines changed

.github/workflows/release.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,6 @@ jobs:
6464
sudo apt-mark hold grub-efi-amd64-signed grub-efi-amd64-bin
6565
sudo apt-get update
6666
sudo apt-get upgrade
67-
echo "================================================================================"
68-
go version
69-
echo "================================================================================"
7067
go build -tags osusergo,netgo -v -ldflags="-X github.com/${{ github.repository }}/cmd.ReleaseVersion=${{ needs.env_vars.outputs.release_version }} -extldflags -static"
7168
tar zcf ${{ needs.env_vars.outputs.binary }}-${{ needs.env_vars.outputs.release_version }}-linux-amd64.tar.gz ${{ needs.env_vars.outputs.binary }}
7269
sha256sum ${{ needs.env_vars.outputs.binary }}-${{ needs.env_vars.outputs.release_version }}-linux-amd64.tar.gz | sed -e 's/ .*//' >${{ needs.env_vars.outputs.binary }}-${{ needs.env_vars.outputs.release_version }}-linux-amd64.tar.gz.sha256

.golangci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,11 @@ linters:
9191
- gochecknoglobals
9292
- gocognit
9393
- goconst
94+
- godoclint
9495
- iface
9596
- ireturn
9697
- lll
98+
- modernize
9799
- mnd
98100
- nestif
99101
- nilnil

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
dev:
22
- update majordomo to v1.1.2
3+
- add combinedmajority attestationdata strategy
34

45
1.12.0:
56
- import fulu container specs from go-eth2-client

main.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ import (
8383
bestaggregateattestationstrategy "github.com/attestantio/vouch/strategies/aggregateattestation/best"
8484
firstaggregateattestationstrategy "github.com/attestantio/vouch/strategies/aggregateattestation/first"
8585
bestattestationdatastrategy "github.com/attestantio/vouch/strategies/attestationdata/best"
86+
combinedmajorityattestationdatastrategy "github.com/attestantio/vouch/strategies/attestationdata/combinedmajority"
8687
firstattestationdatastrategy "github.com/attestantio/vouch/strategies/attestationdata/first"
8788
majorityattestationdatastrategy "github.com/attestantio/vouch/strategies/attestationdata/majority"
8889
combinedattestationpoolstrategy "github.com/attestantio/vouch/strategies/attestationpool/combined"
@@ -115,7 +116,7 @@ import (
115116
)
116117

117118
// ReleaseVersion is the release version for the code.
118-
var ReleaseVersion = "1.13.0-dev"
119+
var ReleaseVersion = "1.13.0-alpha.1"
119120

120121
func main() {
121122
exitCode := main2()
@@ -1249,6 +1250,30 @@ func selectAttestationDataProvider(ctx context.Context,
12491250
if err != nil {
12501251
return nil, errors.Wrap(err, "failed to start majority attestation data strategy")
12511252
}
1253+
case "combinedmajority":
1254+
log.Info().Msg("Starting combinedmajority attestation data strategy")
1255+
attestationDataProviders := make(map[string]eth2client.AttestationDataProvider)
1256+
for _, address := range util.BeaconNodeAddresses("strategies.attestationdata.combinedmajority") {
1257+
client, err := fetchClient(ctx, monitor, address)
1258+
if err != nil {
1259+
return nil, errors.Wrap(err, fmt.Sprintf("failed to fetch client %s for combinedmajority attestation data strategy", address))
1260+
}
1261+
attestationDataProviders[address] = client.(eth2client.AttestationDataProvider)
1262+
}
1263+
attestationDataProvider, err = combinedmajorityattestationdatastrategy.New(ctx,
1264+
combinedmajorityattestationdatastrategy.WithClientMonitor(monitor.(metrics.ClientMonitor)),
1265+
combinedmajorityattestationdatastrategy.WithProcessConcurrency(util.ProcessConcurrency("strategies.attestationdata.combinedmajority")),
1266+
combinedmajorityattestationdatastrategy.WithLogLevel(util.LogLevel("strategies.attestationdata.combinedmajority")),
1267+
combinedmajorityattestationdatastrategy.WithAttestationDataProviders(attestationDataProviders),
1268+
combinedmajorityattestationdatastrategy.WithTimeout(util.Timeout("strategies.attestationdata.combinedmajority")),
1269+
combinedmajorityattestationdatastrategy.WithChainTime(chainTime),
1270+
combinedmajorityattestationdatastrategy.WithBlockRootToSlotCache(cacheSvc.(cache.BlockRootToSlotProvider)),
1271+
combinedmajorityattestationdatastrategy.WithThreshold(viper.GetInt("strategies.attestationdata.combinedmajority.threshold")),
1272+
)
1273+
if err != nil {
1274+
return nil, errors.Wrap(err, "failed to start combinedmajority attestation data strategy")
1275+
}
1276+
12521277
case "first":
12531278
log.Info().Msg("Starting first attestation data strategy")
12541279
attestationDataProviders := make(map[string]eth2client.AttestationDataProvider)

mock/eth2client.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,84 @@ func (*AttestationDataProvider) AttestationData(_ context.Context,
985985
}, nil
986986
}
987987

988+
// CustomAttestationDataProvider is a mock for eth2client.AttestationDataProvider.
989+
type CustomAttestationDataProvider struct {
990+
changeSlot int
991+
changeRoot bool
992+
}
993+
994+
// NewFuzzingAttestationDataProvider returns a mock attestation data provider.
995+
// changeSlot: how much to add to the slot, 0 for no change, positive for later, negative for earlier.
996+
// changeRoot: whether to change the root based on the slot.
997+
func NewCustomAttestationDataProvider(changeSlot int, changeRoot bool) eth2client.AttestationDataProvider {
998+
return &CustomAttestationDataProvider{changeSlot: changeSlot, changeRoot: changeRoot}
999+
}
1000+
1001+
// AttestationData is a mock.
1002+
func (m *CustomAttestationDataProvider) AttestationData(_ context.Context,
1003+
opts *api.AttestationDataOpts,
1004+
) (
1005+
*api.Response[*phase0.AttestationData],
1006+
error,
1007+
) {
1008+
slot := opts.Slot + phase0.Slot(m.changeSlot)
1009+
// Generate a fixed block root according to the slot.
1010+
firstByte := byte(opts.Slot & 0xff)
1011+
if m.changeRoot {
1012+
firstByte = byte(slot & 0xff)
1013+
}
1014+
beaconBlockRoot := phase0.Root([32]byte{
1015+
firstByte, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
1016+
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
1017+
})
1018+
source := &phase0.Checkpoint{
1019+
Epoch: phase0.Epoch(slot/32 - 1),
1020+
Root: phase0.Root([32]byte{
1021+
firstByte, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
1022+
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
1023+
}),
1024+
}
1025+
target := &phase0.Checkpoint{
1026+
Epoch: phase0.Epoch(slot / 32),
1027+
Root: phase0.Root([32]byte{
1028+
firstByte, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
1029+
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
1030+
}),
1031+
}
1032+
1033+
return &api.Response[*phase0.AttestationData]{
1034+
Data: &phase0.AttestationData{
1035+
Slot: slot,
1036+
Index: opts.CommitteeIndex,
1037+
BeaconBlockRoot: beaconBlockRoot,
1038+
Source: source,
1039+
Target: target,
1040+
},
1041+
Metadata: make(map[string]any),
1042+
}, nil
1043+
}
1044+
1045+
// EmptyAttestationDataProvider is a mock for eth2client.AttestationDataProvider.
1046+
type EmptyAttestationDataProvider struct{}
1047+
1048+
// NewEmptyAttestationDataProvider returns a mock attestation data provider.
1049+
func NewEmptyAttestationDataProvider() eth2client.AttestationDataProvider {
1050+
return &EmptyAttestationDataProvider{}
1051+
}
1052+
1053+
// AttestationData is a mock.
1054+
func (*EmptyAttestationDataProvider) AttestationData(_ context.Context,
1055+
opts *api.AttestationDataOpts,
1056+
) (
1057+
*api.Response[*phase0.AttestationData],
1058+
error,
1059+
) {
1060+
return &api.Response[*phase0.AttestationData]{
1061+
Data: &phase0.AttestationData{Slot: opts.Slot},
1062+
Metadata: make(map[string]any),
1063+
}, nil
1064+
}
1065+
9881066
// ErroringAttestationDataProvider is a mock for eth2client.AttestationDataProvider.
9891067
type ErroringAttestationDataProvider struct{}
9901068

strategies/attestationdata/best/attestationdata.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ func (s *Service) AttestationData(ctx context.Context,
174174
Msg("Results")
175175

176176
if bestAttestationData == nil {
177-
return nil, errors.New("no attestations received")
177+
return nil, errors.New("no attestation data received")
178178
}
179179
log.Trace().Str("provider", bestProvider).Stringer("attestation_data", bestAttestationData).Float64("score", bestScore).Msg("Selected best attestation")
180180
if bestProvider != "" {

strategies/attestationdata/best/attestationdata_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ func TestAttestationData(t *testing.T) {
8181
},
8282
slot: 12345,
8383
committeeIndex: 3,
84-
err: "no attestations received",
84+
err: "no attestation data received",
8585
},
8686
{
8787
name: "GoodMixed",

0 commit comments

Comments
 (0)