mirror of https://github.com/certusone/vouch.git
Merge branch 'eth2client'
This commit is contained in:
commit
b8d26c7470
63
go.mod
63
go.mod
|
@ -3,57 +3,46 @@ module github.com/attestantio/vouch
|
|||
go 1.14
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.69.1 // indirect
|
||||
cloud.google.com/go v0.72.0 // indirect
|
||||
github.com/OneOfOne/xxhash v1.2.5 // indirect
|
||||
github.com/attestantio/dirk v0.9.0
|
||||
github.com/attestantio/go-eth2-client v0.6.8
|
||||
github.com/aws/aws-sdk-go v1.35.9
|
||||
github.com/ferranbt/fastssz v0.0.0-20201016163051-9c5a44b9b68d
|
||||
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||
github.com/google/uuid v1.1.2 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.15.2 // indirect
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20201015064056-ab4d637175e8
|
||||
github.com/magiconair/properties v1.8.4 // indirect
|
||||
github.com/minio/highwayhash v1.0.1 // indirect
|
||||
github.com/attestantio/dirk v0.9.3
|
||||
github.com/attestantio/go-eth2-client v0.6.10
|
||||
github.com/aws/aws-sdk-go v1.35.28
|
||||
github.com/ferranbt/fastssz v0.0.0-20201030134205-9b9624098321
|
||||
github.com/goccy/go-yaml v1.8.4 // indirect
|
||||
github.com/google/go-cmp v0.5.3 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20201104034342-d782bdf735de
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/opentracing/opentracing-go v1.2.0
|
||||
github.com/pelletier/go-toml v1.8.1 // indirect
|
||||
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.8.0
|
||||
github.com/prometheus/common v0.14.0 // indirect
|
||||
github.com/prometheus/procfs v0.2.0 // indirect
|
||||
github.com/prysmaticlabs/ethereumapis v0.0.0-20201003171600-a72e5f77d233
|
||||
github.com/prometheus/common v0.15.0 // indirect
|
||||
github.com/prysmaticlabs/ethereumapis v0.0.0-20201020182719-7f66dae2bbba
|
||||
github.com/prysmaticlabs/go-bitfield v0.0.0-20200618145306-2ae0807bef65
|
||||
github.com/rs/zerolog v1.20.0
|
||||
github.com/sasha-s/go-deadlock v0.2.0
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/spf13/afero v1.4.1 // indirect
|
||||
github.com/spf13/cast v1.3.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/sirupsen/logrus v1.6.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/spf13/viper v1.7.1
|
||||
github.com/stretchr/testify v1.6.1
|
||||
github.com/uber/jaeger-client-go v2.25.0+incompatible
|
||||
github.com/uber/jaeger-lib v2.4.0+incompatible // indirect
|
||||
github.com/wealdtech/go-bytesutil v1.1.1
|
||||
github.com/wealdtech/go-eth2-types/v2 v2.5.0
|
||||
github.com/wealdtech/go-eth2-wallet v1.14.1
|
||||
github.com/wealdtech/go-eth2-wallet-dirk v1.0.4
|
||||
github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.1
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.5.1
|
||||
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.16.1
|
||||
github.com/wealdtech/go-eth2-wallet-store-scratch v1.6.0
|
||||
github.com/wealdtech/go-eth2-wallet-types/v2 v2.8.0
|
||||
github.com/wealdtech/go-eth2-types/v2 v2.5.1
|
||||
github.com/wealdtech/go-eth2-wallet v1.14.3
|
||||
github.com/wealdtech/go-eth2-wallet-dirk v1.1.4
|
||||
github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.2
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.5.3
|
||||
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.16.13
|
||||
github.com/wealdtech/go-eth2-wallet-store-scratch v1.6.1
|
||||
github.com/wealdtech/go-eth2-wallet-types/v2 v2.8.1
|
||||
github.com/wealdtech/go-majordomo v1.0.1
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 // indirect
|
||||
golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0 // indirect
|
||||
golang.org/x/sync v0.0.0-20201008141435-b3e1573b7520
|
||||
golang.org/x/sys v0.0.0-20201017003518-b09fb700fbb7 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20201015140912-32ed001d685c // indirect
|
||||
google.golang.org/grpc v1.33.0
|
||||
gopkg.in/ini.v1 v1.62.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58 // indirect
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
|
||||
golang.org/x/sys v0.0.0-20201113233024-12cec1faf1ba // indirect
|
||||
google.golang.org/genproto v0.0.0-20201113130914-ce600e9a6f9e // indirect
|
||||
google.golang.org/grpc v1.33.2
|
||||
gotest.tools v2.2.0+incompatible
|
||||
)
|
||||
|
|
354
go.sum
354
go.sum
|
@ -11,14 +11,13 @@ cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6
|
|||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0 h1:RmDygqvj27Zf3fCQjQRtLyC7KwFcHkeJitcO0OoGOcA=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go v0.66.0 h1:DZeAkuQGQqnm9Xv36SbMJEU8aFBz4wL04UpMWPWwjzg=
|
||||
cloud.google.com/go v0.66.0/go.mod h1:dgqGAjKCDxyhGTtC9dAREQGUJpkceNm1yt590Qno0Ko=
|
||||
cloud.google.com/go v0.68.0/go.mod h1:91NO4SCDjUfe1zeC0f4/dpckkUNpuNEyqm4X2KLrzNQ=
|
||||
cloud.google.com/go v0.69.1 h1:01WAtK12Fes1PhlpkgDf6iifgXbrdczf+6Cec2S+Aa8=
|
||||
cloud.google.com/go v0.69.1/go.mod h1:nBQK+D2Y4slKAj03c6wkILB3imWdzebeEZgWHEmGREE=
|
||||
cloud.google.com/go v0.70.0 h1:ujhG1RejZYi+HYfJNlgBh3j/bVKD8DewM7AkJ5UPyBc=
|
||||
cloud.google.com/go v0.70.0/go.mod h1:/UTKYRQTWjVnSe7nGvoSzxEFUELzSI/yAYd0JQT6cRo=
|
||||
cloud.google.com/go v0.72.0 h1:eWRCuwubtDrCJG0oSUMgnsbD4CmPFQF2ei4OFbXvwww=
|
||||
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
|
@ -38,15 +37,14 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
|
|||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||
github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ=
|
||||
github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||
github.com/HdrHistogram/hdrhistogram-go v0.9.0 h1:dpujRju0R4M/QZzcnR1LH1qm+TVG3UzkWdp5tH1WMcg=
|
||||
github.com/HdrHistogram/hdrhistogram-go v0.9.0/go.mod h1:nxrse8/Tzg2tg3DZcZjm6qEclQKK70g0KxO61gFFZD4=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/OneOfOne/xxhash v1.2.5 h1:zl/OfRA6nftbBK9qTohYBJ5xvw6C/oNKizR7cZGl3cI=
|
||||
github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
|
||||
|
@ -68,34 +66,25 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5
|
|||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
||||
github.com/attestantio/dirk v0.8.0 h1:N3/djI47sKkXV6BWbhwxfbiO2E4TjA3f3NqTayWXyNE=
|
||||
github.com/attestantio/dirk v0.9.0 h1:duHmWzjJDALFTu8Fay5nKZ9IXhVf2o6ufE08G7vb1zw=
|
||||
github.com/attestantio/dirk v0.9.0/go.mod h1:oWsyIb/OXdx9pvDQqS3hdFBB1eFaYnrNjuvLtVwo69w=
|
||||
github.com/attestantio/go-eth2-client v0.6.4 h1:EfnOCWlPrmLXBxMyctXUOEIcn61/QnYvnIBz5aIH8Bg=
|
||||
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/attestantio/go-eth2-client v0.6.7 h1:QphgX2XL8HMxZ3wo7RSyBhBJr9eKHNJU0GLWtVmxYG8=
|
||||
github.com/attestantio/go-eth2-client v0.6.7/go.mod h1:lYEayGHzZma9HMUJgyxFIzDWRck8n2IedP7KTkIwe0g=
|
||||
github.com/attestantio/go-eth2-client v0.6.8 h1:Lsjx5P0pB8ruZBfJUbqy5hpevD4Zt8Z0Lg4V5m2s53E=
|
||||
github.com/attestantio/go-eth2-client v0.6.8/go.mod h1:lYEayGHzZma9HMUJgyxFIzDWRck8n2IedP7KTkIwe0g=
|
||||
github.com/attestantio/dirk v0.9.1 h1:oof1Xm0uI4a2T9vhQB+f3Wjlngd2rnfsKi8aj1wqNh0=
|
||||
github.com/attestantio/dirk v0.9.1/go.mod h1:oWsyIb/OXdx9pvDQqS3hdFBB1eFaYnrNjuvLtVwo69w=
|
||||
github.com/attestantio/dirk v0.9.3/go.mod h1:EfppeT+VjQXnE9Ti5/vxa6ptZJAN2vMXO6KZojvSOXA=
|
||||
github.com/attestantio/go-eth2-client v0.6.9/go.mod h1:ODAZ4yS1YYYew/EsgGsVb/siNEoa505CrGsvlVFdkfo=
|
||||
github.com/attestantio/go-eth2-client v0.6.10 h1:PMNBMLk6xfMEUqhaUnsI0/HZRrstZF18Gt6Dm5GelW4=
|
||||
github.com/attestantio/go-eth2-client v0.6.10/go.mod h1:ODAZ4yS1YYYew/EsgGsVb/siNEoa505CrGsvlVFdkfo=
|
||||
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=
|
||||
github.com/aws/aws-sdk-go v1.33.17 h1:vngPRchZs603qLtJH7lh2pBCDqiFxA9+9nDWJ5WYJ5A=
|
||||
github.com/aws/aws-sdk-go v1.33.17/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
|
||||
github.com/aws/aws-sdk-go v1.34.31 h1:408wh5EHKzxyby8JpYfnn1w3fsF26AIU0o1kbJoRy7E=
|
||||
github.com/aws/aws-sdk-go v1.34.31/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
|
||||
github.com/aws/aws-sdk-go v1.35.7/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k=
|
||||
github.com/aws/aws-sdk-go v1.35.8 h1:+S3BTWePYImKLh7DUJxMVm+/FQUnmHADsMzo/psHFr4=
|
||||
github.com/aws/aws-sdk-go v1.35.8/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k=
|
||||
github.com/aws/aws-sdk-go v1.35.9 h1:b1HiUpdkFLJyoOQ7zas36YHzjNHH0ivHx/G5lWBeg+U=
|
||||
github.com/aws/aws-sdk-go v1.35.9/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k=
|
||||
github.com/aws/aws-sdk-go v1.35.14 h1:nucVVXXjAr9UkmYCBWxQWRuYa5KOlaXjuJGg2ulW0K0=
|
||||
github.com/aws/aws-sdk-go v1.35.14/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k=
|
||||
github.com/aws/aws-sdk-go v1.35.26 h1:MawRvDpAp/Ai859dPC1xo1fdU/BIkijoHj0DwXLXXkI=
|
||||
github.com/aws/aws-sdk-go v1.35.26/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k=
|
||||
github.com/aws/aws-sdk-go v1.35.28 h1:S2LuRnfC8X05zgZLC8gy/Sb82TGv2Cpytzbzz7tkeHc=
|
||||
github.com/aws/aws-sdk-go v1.35.28/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k=
|
||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
|
@ -119,16 +108,13 @@ github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T
|
|||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/etcd v3.3.13+incompatible h1:8F3hqu9fGYLBifCmRCJsicFqDx/D68Rt3q1JMazcgBQ=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
|
@ -142,9 +128,7 @@ github.com/dgraph-io/ristretto v0.0.1/go.mod h1:T40EBc7CJke8TkpiYfGGKAeFjSaxuFXh
|
|||
github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
|
||||
github.com/dgraph-io/ristretto v0.0.3 h1:jh22xisGBjrEVnRZ1DVTpBVQm0Xndu8sMl0CWDzSIBI=
|
||||
github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=
|
||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y=
|
||||
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||
|
@ -161,17 +145,19 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
|
|||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/ferranbt/fastssz v0.0.0-20200514094935-99fccaf93472 h1:maoKvILdMk6CSWHanFcUdxXIZGKD9YpWIaVbUQ/4kfg=
|
||||
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
|
||||
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/ferranbt/fastssz v0.0.0-20200514094935-99fccaf93472/go.mod h1:LlFXPmgrgVYsuoFDwV8rDJ9tvt1pLQdjKvU1b5IRES0=
|
||||
github.com/ferranbt/fastssz v0.0.0-20200728110133-0b6e349af87a/go.mod h1:DyEu2iuLBnb/T51BlsiO3yLYdJC6UbGMrIkqK1KmQxM=
|
||||
github.com/ferranbt/fastssz v0.0.0-20200826142241-3a913c5a1313 h1:8DS7uDmUkGF6UKNU1HivEsjrTusxLPb05KUr/D8ONWQ=
|
||||
github.com/ferranbt/fastssz v0.0.0-20200826142241-3a913c5a1313/go.mod h1:DyEu2iuLBnb/T51BlsiO3yLYdJC6UbGMrIkqK1KmQxM=
|
||||
github.com/ferranbt/fastssz v0.0.0-20201016163051-9c5a44b9b68d h1:gHW6nLqM4iq3m9sHAkWWFvpeSoEfRhzv3HZG4jcm/J8=
|
||||
github.com/ferranbt/fastssz v0.0.0-20201016163051-9c5a44b9b68d/go.mod h1:DyEu2iuLBnb/T51BlsiO3yLYdJC6UbGMrIkqK1KmQxM=
|
||||
github.com/ferranbt/fastssz v0.0.0-20201020132831-68dc48984fd3 h1:FnpkCo1TAj/eq0ETLPhAplYYB4KlFQy3kVb8cLludAc=
|
||||
github.com/ferranbt/fastssz v0.0.0-20201020132831-68dc48984fd3/go.mod h1:DyEu2iuLBnb/T51BlsiO3yLYdJC6UbGMrIkqK1KmQxM=
|
||||
github.com/ferranbt/fastssz v0.0.0-20201030134205-9b9624098321 h1:9Pkbf8HgETu3xKpz12Sj5clUrVFp2O+ymK7pBsTPYRM=
|
||||
github.com/ferranbt/fastssz v0.0.0-20201030134205-9b9624098321/go.mod h1:DyEu2iuLBnb/T51BlsiO3yLYdJC6UbGMrIkqK1KmQxM=
|
||||
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
||||
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
|
@ -185,9 +171,17 @@ github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgO
|
|||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/goccy/go-yaml v1.8.3 h1:VGzw2KWSUyQX0yXai02S0nttBc+Oa4Kvh6RCFoxt8SE=
|
||||
github.com/goccy/go-yaml v1.8.3/go.mod h1:wS4gNoLalDSJxo/SpngzPQ2BN4uuZVLCmbM4S3vd4+Y=
|
||||
github.com/goccy/go-yaml v1.8.4 h1:AOEdR7aQgbgwHznGe3BLkDQVujxCPUpHOZZcQcp8Y3M=
|
||||
github.com/goccy/go-yaml v1.8.4/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA=
|
||||
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
|
@ -220,7 +214,6 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU
|
|||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
|
@ -233,20 +226,19 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ
|
|||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
|
@ -256,9 +248,9 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf
|
|||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200905233945-acf8798be1f7/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20201009210932-67992a1a5a35/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
|
@ -272,7 +264,6 @@ github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z
|
|||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2 h1:FlFbCRLd5Jr4iYXZufAvgWN6Ao0JrI5chLINnUXDDr0=
|
||||
|
@ -280,14 +271,11 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaD
|
|||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.13.0 h1:sBDQoHXrOlfPobnKw69FIKa1wg9qsLLvvQ/Y19WtFgI=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.14.7 h1:Nk5kuHrnWUTf/0GL1a/vchH/om9Ap2/HnVna+jYZgTY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.14.7/go.mod h1:oYZKL012gGh6LMyg/xA7Q2yq6j8bu0wa+9w14EEthWU=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.15.0 h1:ntPNC9TD/6l2XDenJZe6T5lSMg95thpV9sGAqHX4WU8=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.15.0/go.mod h1:vO11I9oWA+KsxmfFQPhLnnIb1VDE24M+pdxZFiuZcA8=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.15.2 h1:HC+hWRWf+v5zTMPyoaYTKIJih+4sd4XRWmj0qlG87Co=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.15.2/go.mod h1:vO11I9oWA+KsxmfFQPhLnnIb1VDE24M+pdxZFiuZcA8=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
|
||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
|
@ -312,34 +300,28 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
|
|||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20200706085701-832d8c2c0f7d h1:P8yaFmLwc5ZlUx2sHuawcdQvpv5/0GM+WEGJ07ljN3g=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20200706085701-832d8c2c0f7d/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20200722032157-41fc56eba7b4 h1:TfBVK1MJ9vhrMXWVHu5p/MlVHZTeCGgDAEu5RykVZeI=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20200722032157-41fc56eba7b4/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20200923072303-32b29e5d8cbf h1:Lw7EOMVxu3O+7Ro5bqn9M20a7GwuCqZQsmdXNzmcKE4=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20200923072303-32b29e5d8cbf/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20201008062400-71567a52ad65/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20201015064056-ab4d637175e8 h1:zkPatN5r+w/I0dO/ivQL3OOHEqSVqoUy2BLbF95uf40=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20201015064056-ab4d637175e8/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20201019012252-4b463a10c225 h1:S7pKW74AvYc89WawL6IxGSnJRxF4TkE1GITYqKFyYy4=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20201019012252-4b463a10c225/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20201104034342-d782bdf735de h1:qLlwYGvpvAx/nDBnPt2KpZTXGli0oHBGddyYxJHTOds=
|
||||
github.com/herumi/bls-eth-go-binary v0.0.0-20201104034342-d782bdf735de/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||
github.com/jackc/puddle v1.1.1 h1:PJAw7H/9hoWC4Kf3J8iNmL1SwA6E8vfsLqBiL+F6CtI=
|
||||
github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.1.2 h1:mpQEXihFnWGDy6X98EOTh81JYuxn7txby8ilJ3iIPGM=
|
||||
github.com/jackc/puddle v1.1.2/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
|
||||
github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
|
@ -354,32 +336,40 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
|
|||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
|
||||
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.4 h1:8KGKTcQQGm0Kv7vEbKFErAoAOFyyacLStRtQSeYtvkY=
|
||||
github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=
|
||||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/minio/highwayhash v1.0.0 h1:iMSDhgUILCr0TNm8LWlSjF8N0ZIj2qbO8WHp6Q/J2BA=
|
||||
github.com/minio/highwayhash v1.0.0/go.mod h1:xQboMTeM9nY9v/LlAOxFctujiv5+Aq2hR5dxBpaMbdc=
|
||||
github.com/minio/highwayhash v1.0.1 h1:dZ6IIu8Z14VlC0VpfKofAhCy74wu/Qb5gcn52yWoz/0=
|
||||
github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
|
||||
|
@ -393,17 +383,13 @@ github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eI
|
|||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg=
|
||||
github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8=
|
||||
github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
|
@ -435,10 +421,7 @@ github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh
|
|||
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.8.0 h1:Keo9qb7iRJs2voHvunFtuuYFsbWeOBh8/P9v/kVMFtw=
|
||||
github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs=
|
||||
github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
|
||||
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
||||
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||
|
@ -457,40 +440,34 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
|||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8=
|
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
|
||||
github.com/prometheus/client_golang v1.7.1 h1:NTGy1Ja9pByO+xAeH/qiWnLrKtr3hJPNjaVUwnjpdpA=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.8.0 h1:zvJNkoCFAnYFNC24FV8nW4JdRJ3GIFcLbg65lL/JDcw=
|
||||
github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.13.0 h1:vJlpe9wPgDRM1Z+7Wj3zUUjY1nr6/1jNKyl7llliccg=
|
||||
github.com/prometheus/common v0.13.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
github.com/prometheus/common v0.14.0 h1:RHRyE8UocrbjU+6UvRzwi6HjiDfxrrBU91TtbKzkGp4=
|
||||
github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
github.com/prometheus/common v0.15.0 h1:4fgOnadei3EZvgRwxJ7RMpG1k1pOZth5Pc13tyspaKM=
|
||||
github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4=
|
||||
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
|
@ -498,28 +475,23 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T
|
|||
github.com/protolambda/zssz v0.1.3/go.mod h1:a4iwOX5FE7/JkKA+J/PH0Mjo9oXftN6P8NZyL28gpag=
|
||||
github.com/protolambda/zssz v0.1.5 h1:7fjJjissZIIaa2QcvmhS/pZISMX21zVITt49sW1ouek=
|
||||
github.com/protolambda/zssz v0.1.5/go.mod h1:a4iwOX5FE7/JkKA+J/PH0Mjo9oXftN6P8NZyL28gpag=
|
||||
github.com/prysmaticlabs/ethereumapis v0.0.0-20200812153649-a842fc47c2c3 h1:0f++UXRfp4/Mrmlfj3UaCnYj2lPr6El0gWWTBb9MD2Y=
|
||||
github.com/prysmaticlabs/ethereumapis v0.0.0-20200812153649-a842fc47c2c3/go.mod h1:k7b2dxy6RppCG6kmOJkNOXzRpEoTdsPygc2aQhsUsZk=
|
||||
github.com/prysmaticlabs/ethereumapis v0.0.0-20200826112054-b9e8bd145725 h1:ui38FW8BoWEXQ8VnDGI+4LTrQvRncyojGP7ZCrclIcM=
|
||||
github.com/prysmaticlabs/ethereumapis v0.0.0-20200826112054-b9e8bd145725/go.mod h1:k7b2dxy6RppCG6kmOJkNOXzRpEoTdsPygc2aQhsUsZk=
|
||||
github.com/prysmaticlabs/ethereumapis v0.0.0-20200923224139-64c46fb1b0fa h1:UuO9ndtrESi7kHJZZ17aXqpdwA6VDSqgfoQXWKI3dco=
|
||||
github.com/prysmaticlabs/ethereumapis v0.0.0-20200923224139-64c46fb1b0fa/go.mod h1:k7b2dxy6RppCG6kmOJkNOXzRpEoTdsPygc2aQhsUsZk=
|
||||
github.com/prysmaticlabs/ethereumapis v0.0.0-20201003171600-a72e5f77d233 h1:dGeuKeaXxCepTbwsz7kYSfP1yazw1uRMn58CqNCcPP4=
|
||||
github.com/prysmaticlabs/ethereumapis v0.0.0-20201003171600-a72e5f77d233/go.mod h1:k7b2dxy6RppCG6kmOJkNOXzRpEoTdsPygc2aQhsUsZk=
|
||||
github.com/prysmaticlabs/ethereumapis v0.0.0-20201020182719-7f66dae2bbba h1:ItW6tq3B45Gws8dO0cIuU1Srlgf4qomZnWkc0sDCln0=
|
||||
github.com/prysmaticlabs/ethereumapis v0.0.0-20201020182719-7f66dae2bbba/go.mod h1:k7b2dxy6RppCG6kmOJkNOXzRpEoTdsPygc2aQhsUsZk=
|
||||
github.com/prysmaticlabs/go-bitfield v0.0.0-20191017011753-53b773adde52/go.mod h1:hCwmef+4qXWjv0jLDbQdWnL0Ol7cS7/lCSS26WR+u6s=
|
||||
github.com/prysmaticlabs/go-bitfield v0.0.0-20200322041314-62c2aee71669 h1:cX6YRZnZ9sgMqM5U14llxUiXVNJ3u07Res1IIjTOgtI=
|
||||
github.com/prysmaticlabs/go-bitfield v0.0.0-20200322041314-62c2aee71669/go.mod h1:hCwmef+4qXWjv0jLDbQdWnL0Ol7cS7/lCSS26WR+u6s=
|
||||
github.com/prysmaticlabs/go-bitfield v0.0.0-20200618145306-2ae0807bef65 h1:hJfAWrlxx7SKpn4S/h2JGl2HHwA1a2wSS3HAzzZ0F+U=
|
||||
github.com/prysmaticlabs/go-bitfield v0.0.0-20200618145306-2ae0807bef65/go.mod h1:hCwmef+4qXWjv0jLDbQdWnL0Ol7cS7/lCSS26WR+u6s=
|
||||
github.com/prysmaticlabs/go-ssz v0.0.0-20200101200214-e24db4d9e963/go.mod h1:VecIJZrewdAuhVckySLFt2wAAHRME934bSDurP8ftkc=
|
||||
github.com/prysmaticlabs/go-ssz v0.0.0-20200612203617-6d5c9aa213ae h1:7qd0Af1ozWKBU3c93YW2RH+/09hJns9+ftqWUZyts9c=
|
||||
github.com/prysmaticlabs/go-ssz v0.0.0-20200612203617-6d5c9aa213ae/go.mod h1:VecIJZrewdAuhVckySLFt2wAAHRME934bSDurP8ftkc=
|
||||
github.com/r3labs/sse/v2 v2.3.0 h1:R/UMa0ML6AYKQ8irQNHhY+204lz1LytDIdKhCxSVAd8=
|
||||
github.com/r3labs/sse/v2 v2.3.0/go.mod h1:hUrYMKfu9WquG9MyI0r6TKiNH+6Sw/QPKm2YbNbU5g8=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/zerolog v1.19.0 h1:hYz4ZVdUgjXTBUmrkrw55j1nHx68LfOKIQk5IYtyScg=
|
||||
github.com/rs/zerolog v1.19.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo=
|
||||
github.com/rs/zerolog v1.20.0 h1:38k9hgtUBdxFwE34yS8rTHmHBa4eN16E4DJlv177LNs=
|
||||
github.com/rs/zerolog v1.20.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo=
|
||||
|
@ -535,38 +507,30 @@ github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0/go.mod h1:7Awj
|
|||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8=
|
||||
github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
|
||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/afero v1.3.4 h1:8q6vk3hthlpb2SouZcnBVKboxWQWMDNF38bwholZrJc=
|
||||
github.com/spf13/afero v1.3.4/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||
github.com/spf13/afero v1.4.0 h1:jsLTaI1zwYO3vjrzHalkVcIHXTNmdQFepW4OI8H3+x8=
|
||||
github.com/spf13/afero v1.4.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||
github.com/spf13/afero v1.4.1 h1:asw9sl74539yqavKaglDM5hFpdJVK0Y5Dr/JOgQ89nQ=
|
||||
github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
|
@ -582,28 +546,20 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
|||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/uber/jaeger-client-go v2.25.0+incompatible h1:IxcNZ7WRY1Y3G4poYlx24szfsn/3LvK9QHCq9oQw8+U=
|
||||
github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-lib v2.2.0+incompatible h1:MxZXOiR2JuoANZ3J6DE/U0kSFv/eJ/GfSYVCjK7dyaw=
|
||||
github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||
github.com/uber/jaeger-lib v2.3.0+incompatible h1:B/kUIXcj6kIU3WSXgeJ7/uYj94I/r0LDa//JKgN/Sf0=
|
||||
github.com/uber/jaeger-lib v2.3.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||
github.com/uber/jaeger-lib v2.4.0+incompatible h1:fY7QsGQWiCt8pajv4r7JEvmATdCVaWxXbjwyYwsNaLQ=
|
||||
github.com/uber/jaeger-lib v2.4.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/wealdtech/eth2-signer-api v1.5.2 h1:3jw8MW0r7KlX9bme0q6j+QMa8osRhEnKLkgkECH6xcU=
|
||||
github.com/wealdtech/eth2-signer-api v1.5.2/go.mod h1:5wlLQ7NO7nbXo3znJOwIWHN8S4C3xHcZ0uOg9Ue4mvg=
|
||||
github.com/wealdtech/eth2-signer-api v1.6.0 h1:YgQ35qS6sm1N4SGp3gcP6SHSDx7OvghstzpDQ9zvLZY=
|
||||
github.com/wealdtech/eth2-signer-api v1.6.0/go.mod h1:5wlLQ7NO7nbXo3znJOwIWHN8S4C3xHcZ0uOg9Ue4mvg=
|
||||
github.com/wealdtech/go-bytesutil v1.0.1/go.mod h1:jENeMqeTEU8FNZyDFRVc7KqBdRKSnJ9CCh26TcuNb9s=
|
||||
|
@ -611,54 +567,71 @@ github.com/wealdtech/go-bytesutil v1.1.1 h1:ocEg3Ke2GkZ4vQw5lp46rmO+pfqCCTgq35gq
|
|||
github.com/wealdtech/go-bytesutil v1.1.1/go.mod h1:jENeMqeTEU8FNZyDFRVc7KqBdRKSnJ9CCh26TcuNb9s=
|
||||
github.com/wealdtech/go-ecodec v1.1.0 h1:yggrTSckcPJRaxxOxQF7FPm21kgE8WA6+f5jdq5Kr8o=
|
||||
github.com/wealdtech/go-ecodec v1.1.0/go.mod h1:PSdBFEB6cltdT7V4E1jbboufMZTZXcQOKG/2PeEjKK4=
|
||||
github.com/wealdtech/go-ecodec v1.1.1 h1:Lti3l4r/tHxviU4GzYMkkLWPuY/pJeG+QURE8KJObYk=
|
||||
github.com/wealdtech/go-ecodec v1.1.1/go.mod h1:PSdBFEB6cltdT7V4E1jbboufMZTZXcQOKG/2PeEjKK4=
|
||||
github.com/wealdtech/go-eth2-types/v2 v2.5.0 h1:L8sl3yoICAbn3134CBLNUt0o5h2voe0Es2KD5O9r8YQ=
|
||||
github.com/wealdtech/go-eth2-types/v2 v2.5.0/go.mod h1:321w9X26lAnNa/lQJi2A6Lap5IsNORoLwFPoJ1i8QvY=
|
||||
github.com/wealdtech/go-eth2-util v1.5.0/go.mod h1:0PGWeWWc6qjky/aNjdPdguJdZ2HSEHHCA+3cTjvT+Hk=
|
||||
github.com/wealdtech/go-eth2-types/v2 v2.5.1 h1:59VZuwgqRaTjBu3b3CCaxG05XTmANtuTKA8hy3C6IFQ=
|
||||
github.com/wealdtech/go-eth2-types/v2 v2.5.1/go.mod h1:UUtEgRum8HkPvImpu5+hFYRanMUjP0k6KWqHlYkOGbk=
|
||||
github.com/wealdtech/go-eth2-util v1.6.0 h1:l2OR0SqfYdEnb1I1Ggnk0w+B9/LA5aHdQ2KK2FPnGkY=
|
||||
github.com/wealdtech/go-eth2-util v1.6.0/go.mod h1:0PGWeWWc6qjky/aNjdPdguJdZ2HSEHHCA+3cTjvT+Hk=
|
||||
github.com/wealdtech/go-eth2-wallet v1.12.0/go.mod h1:ouV+YSMbzk2dyecmofm8jhaMKdSigdIPMSnSqmWEfW8=
|
||||
github.com/wealdtech/go-eth2-wallet v1.14.0 h1:eZjopWDMlCHCE9SLydAXBr0Cqtm2HWL3O56ELfeGK9c=
|
||||
github.com/wealdtech/go-eth2-wallet v1.14.0/go.mod h1:HrJ4hLcTPZPjhdkZKZd07OFxA+r7d3i+7XKjYJbxdxk=
|
||||
github.com/wealdtech/go-eth2-util v1.6.1 h1:gYW2s6iea/6NoSuSbisMqETpcnQYfqQnpmGLPYc0XHY=
|
||||
github.com/wealdtech/go-eth2-util v1.6.1/go.mod h1:0hCjncDU0yi6dzGgrCgWAj6grdvJ6loEKCGpCMfxo9c=
|
||||
github.com/wealdtech/go-eth2-util v1.6.2 h1:Gk7xVTG/bY1IUw/8wxOf97DuPbLTGGoZ0k5dNayudhk=
|
||||
github.com/wealdtech/go-eth2-util v1.6.2/go.mod h1:0hCjncDU0yi6dzGgrCgWAj6grdvJ6loEKCGpCMfxo9c=
|
||||
github.com/wealdtech/go-eth2-wallet v1.14.1 h1:0XQ6Bc2vZQCvDMg4qD6usObsXEVUPaNdv31qpwHpm0g=
|
||||
github.com/wealdtech/go-eth2-wallet v1.14.1/go.mod h1:MfQZSlMPfUlvh8EAnlHan/ZQSr+lSWA1zD4QTl4116w=
|
||||
github.com/wealdtech/go-eth2-wallet-dirk v1.0.2 h1:ZxAdF6iTOzYHtQlWd1nzVevZ+HtXS/LLn580t+NXT3A=
|
||||
github.com/wealdtech/go-eth2-wallet-dirk v1.0.2/go.mod h1:5jK/aEAjYAVRBKKjYAvJWSmOWxiECs4asYXHwloNI+w=
|
||||
github.com/wealdtech/go-eth2-wallet-dirk v1.0.3 h1:NWwxzYjFG3k7S9mzVOvj02A5S9QOak4uh+MJF2Ae37w=
|
||||
github.com/wealdtech/go-eth2-wallet-dirk v1.0.3/go.mod h1:WIy6Xx0FgTNG5bP7IytxsEt8y1Yl46HbsWVFbE4Yc94=
|
||||
github.com/wealdtech/go-eth2-wallet-dirk v1.0.4 h1:BOESKDQ2n8EsaeyD+wsTk71zx6VY1mpPe8ADjRqGMoE=
|
||||
github.com/wealdtech/go-eth2-wallet-dirk v1.0.4/go.mod h1:ezepVp6m3sNGsZwFzcA6kjgljGek9ZGYh5AdC5PndPo=
|
||||
github.com/wealdtech/go-eth2-wallet-distributed v1.1.0 h1:OZjjuxcIYo+EhAfph7lYP1z+VeNs9ruOI32kqtYe1Jg=
|
||||
github.com/wealdtech/go-eth2-wallet-distributed v1.1.0/go.mod h1:8r06Vpg/315/7Hl9CXq0ShQP8/cgUrBGzKKo6ywA4yQ=
|
||||
github.com/wealdtech/go-eth2-wallet v1.14.2 h1:pk6JGQdeEafVmZw5JYg2gk/8IeZjf0mY8gjufdTfYo8=
|
||||
github.com/wealdtech/go-eth2-wallet v1.14.2/go.mod h1:irzlGFMyRCWlvGgdI7IjS+/Oyr3Y+Dkkh5kxo0VCRDg=
|
||||
github.com/wealdtech/go-eth2-wallet v1.14.3 h1:VskYm62CSMPm9pc/93E2mO3p1GcYUg8HHUSW/rgXPks=
|
||||
github.com/wealdtech/go-eth2-wallet v1.14.3/go.mod h1:cGFCLvyUua84+WQ9e9ETnXjx9hnlZgjRRYYltn+RfOE=
|
||||
github.com/wealdtech/go-eth2-wallet-dirk v1.1.1 h1:lACHi/+nCQlxDEgMAwl4HE05+RN79NndqDNKTP7iAsk=
|
||||
github.com/wealdtech/go-eth2-wallet-dirk v1.1.1/go.mod h1:qG4tbznw2pO80tMm3x42uPqOAO+LUhQosWApbL0enqY=
|
||||
github.com/wealdtech/go-eth2-wallet-dirk v1.1.2 h1:HSF3j/RY5bl46cPgskNNz9k7NEeVRrZq+qKWDKRWqP8=
|
||||
github.com/wealdtech/go-eth2-wallet-dirk v1.1.2/go.mod h1:WQ0YW8E+A8r+SjMYX8ZwouZNAHEQPvoxy4Q3OtC0KqU=
|
||||
github.com/wealdtech/go-eth2-wallet-dirk v1.1.4 h1:huJwlmQDNGjjBi6B/yEDLYFUcx+xbldhoJfkVGLBJYY=
|
||||
github.com/wealdtech/go-eth2-wallet-dirk v1.1.4/go.mod h1:CEQyNdk+egD2UbvnVn4qGeSBkvR09dmknCA293WiCVk=
|
||||
github.com/wealdtech/go-eth2-wallet-distributed v1.1.1 h1:KSaNQbtj5XXjttTVHe1oy+LgvHmi4NHNfLl+jaTM8fU=
|
||||
github.com/wealdtech/go-eth2-wallet-distributed v1.1.1/go.mod h1:Ik8JPsQQiMengG+dVUaLbFmGug1z9UOWqBDHkF1tGro=
|
||||
github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.0 h1:CWb82xeNaZQt1Z829RyDALUy7UZbc6VOfTS+82jRdEQ=
|
||||
github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.0/go.mod h1:JelKMM10UzDJNXdIcojMj6SCIsHC8NYn4c1S2FFk7OQ=
|
||||
github.com/wealdtech/go-eth2-wallet-distributed v1.1.2 h1:ABE1tyxGfXAPPphQ32dval7+9aP61BsIdtvuOJr3azY=
|
||||
github.com/wealdtech/go-eth2-wallet-distributed v1.1.2/go.mod h1:BRl33Vt9urhVuNHGiBfrf0gRs+U+gKSWCV2kmzD5xTw=
|
||||
github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.1 h1:PYwMOCt92iWEHXdnsBaAk1/xygPfuBMkrXEgO8WtFdw=
|
||||
github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.1/go.mod h1:JelKMM10UzDJNXdIcojMj6SCIsHC8NYn4c1S2FFk7OQ=
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.3.0/go.mod h1:Kc/8WcqMTczfH2xy5mDfCRd0NI/ca/j2jXmqJ7gz8yk=
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.5.0 h1:OhJm7hn6vlO+dazs5S1EBrZu/ZVQUQcaNw1ncfy0/xI=
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.5.0/go.mod h1:LfgcOnQeBcqBEoHd4VNqwZhwqzz0Xh1DqnDmjHWONGs=
|
||||
github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.2 h1:JRZGHJWTX9iEYNg1jKSuO5WBrLVwMLExkJg04esRgss=
|
||||
github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.2/go.mod h1:q+Ng4rNBsD7nMk6s07BpAa2V6Se1aH1dua2jk5orjc0=
|
||||
github.com/wealdtech/go-eth2-wallet-encryptor-unencrypted v1.0.0/go.mod h1:49K88T/4LNQpB8ghVcjTKeRRi/bZHeYjN8Ef5S23yps=
|
||||
github.com/wealdtech/go-eth2-wallet-encryptor-unencrypted v1.0.1 h1:x6bq8cVgRgfhwtSQSYo/9AqJ8qEeaS6af28cW0cVj5U=
|
||||
github.com/wealdtech/go-eth2-wallet-encryptor-unencrypted v1.0.1/go.mod h1:49K88T/4LNQpB8ghVcjTKeRRi/bZHeYjN8Ef5S23yps=
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.5.1 h1:QoIyyVQ/vaztkeG88L1vOZKkKMM43Wo8hutH+qn8jA4=
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.5.1/go.mod h1:smW8Ca0x7JO41urG0sgrlJALb1mGTSagnqaapMWiHfk=
|
||||
github.com/wealdtech/go-eth2-wallet-nd/v2 v2.3.0 h1:L1aPK9nc+8Ctcw+8I05vM6408weFc4a5RtLQDUeS0eE=
|
||||
github.com/wealdtech/go-eth2-wallet-nd/v2 v2.3.0/go.mod h1:e2q2uuEdq5+B3GE7jk+Mi9oz9V5nPPKXcXRg1XYavsU=
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.5.2 h1:3EYbuUrs4cCId+WxFAtx+H/uQXRRlBLzosMRSijpwps=
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.5.2/go.mod h1:hmDme779S5sqxN+W+zmHpS0K8n13fGekHM3gUUB1Ip0=
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.5.3 h1:9Gt/UGrg3wWkZEFuXOdmm5Ih/wOJPP/p8l9v3MIPPzc=
|
||||
github.com/wealdtech/go-eth2-wallet-hd/v2 v2.5.3/go.mod h1:UzS7JsWmOGjaSky+NTSjriTpdv+Vww1pWemb+3+GRk8=
|
||||
github.com/wealdtech/go-eth2-wallet-nd/v2 v2.3.1 h1:inSu0xN3LQN9/nEXTri5IbGLfhsvHwyrXiCI3rAHTzc=
|
||||
github.com/wealdtech/go-eth2-wallet-nd/v2 v2.3.1/go.mod h1:72HjvN+bANNgv/YCZ4Rjwgn6wesg24aHSQlHzrbPFWo=
|
||||
github.com/wealdtech/go-eth2-wallet-nd/v2 v2.3.2 h1:NwJV/Ll90WhqxhCcYCdHYWIURGXDt/GRPNFOvu4kzbg=
|
||||
github.com/wealdtech/go-eth2-wallet-nd/v2 v2.3.2/go.mod h1:WyFAmQHBIUN4hd9hAZQ9Py+N7c+mmlpDSTgiNxvICCM=
|
||||
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.16.1 h1:l9YV6OBqcxp5fjscK63lzuCUIye8ANACjJdpm5ULGS8=
|
||||
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.16.1/go.mod h1:Zxhj/4i8nRpk4LTTqFKbfI2KyvO3uqLMerNXqKZKDK0=
|
||||
github.com/wealdtech/go-eth2-wallet-store-s3 v1.8.0/go.mod h1:OxYD+d79StAOHigNaI5bWuvjhanEyrD4MqTj8hIvt2Y=
|
||||
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.16.13 h1:zVV0kL6TZ1fW/Od9BW9e7W5UJB78gNbcbRQK+HeJOL8=
|
||||
github.com/wealdtech/go-eth2-wallet-store-filesystem v1.16.13/go.mod h1:x6sKafiDSvsUeiYZq7TE/ZWIWeAToXLIqgb7KCehgjU=
|
||||
github.com/wealdtech/go-eth2-wallet-store-s3 v1.9.0 h1:O5211UskLbK1WDecTXwugUlINDBQ26MqtiFn6u66fmA=
|
||||
github.com/wealdtech/go-eth2-wallet-store-s3 v1.9.0/go.mod h1:dcQPLsRRYDiMV0DFYzTX6HRpP9WP+gWreAX5SLBOJ0I=
|
||||
github.com/wealdtech/go-eth2-wallet-store-s3 v1.9.1 h1:YGw5YanOepPGalSyvDKwCEdwvAmG9E3pwo7v6jR/7IM=
|
||||
github.com/wealdtech/go-eth2-wallet-store-s3 v1.9.1/go.mod h1:FR+mhCaoZN4d+EEBSV2QT2cO4szdKvDLTHRygMrH6fk=
|
||||
github.com/wealdtech/go-eth2-wallet-store-s3 v1.9.2 h1:HFT1w+8icvHj5Yb1qDZUjzIQYnFbau1ahYwB08kwwJM=
|
||||
github.com/wealdtech/go-eth2-wallet-store-s3 v1.9.2/go.mod h1:oKDDrc/BMDotY8/zT9TfmnELt+QMaPCiWwTiBmjlwTw=
|
||||
github.com/wealdtech/go-eth2-wallet-store-scratch v1.6.0 h1:41H6hnVsI/csBx20UHpI2pY922N7Vhcro35DFS+slj0=
|
||||
github.com/wealdtech/go-eth2-wallet-store-scratch v1.6.0/go.mod h1:XtXHbl4OV/XenQsvGmXbh+bVXaGS788oa30DB7kDInA=
|
||||
github.com/wealdtech/go-eth2-wallet-types/v2 v2.5.0 h1:J29mbkSCUMl2xdu8Lg6U+JptFGfmli6xl04DAHtq9aM=
|
||||
github.com/wealdtech/go-eth2-wallet-store-scratch v1.6.1 h1:vv9lR8K76FUSNbzUU25MN4HNhZIBBI1kJBNfHq2WjRY=
|
||||
github.com/wealdtech/go-eth2-wallet-store-scratch v1.6.1/go.mod h1:qnI6/VRpFyKGV+DhzdC1zmx2sA7mRRanCFlk4RYzoYs=
|
||||
github.com/wealdtech/go-eth2-wallet-types/v2 v2.5.0/go.mod h1:X9kYUH/E5YMqFMZ4xL6MJanABUkJGaH/yPZRT2o+yYA=
|
||||
github.com/wealdtech/go-eth2-wallet-types/v2 v2.6.0 h1:vBrH5icPPSeb14cdShA7/P2PBZOgZscJ2IhBlTIaFrA=
|
||||
github.com/wealdtech/go-eth2-wallet-types/v2 v2.6.0/go.mod h1:X9kYUH/E5YMqFMZ4xL6MJanABUkJGaH/yPZRT2o+yYA=
|
||||
github.com/wealdtech/go-eth2-wallet-types/v2 v2.7.0 h1:pquFQdIWEiSYrpIpFuvsRuialI8t9KhFsPvbIBPnzic=
|
||||
github.com/wealdtech/go-eth2-wallet-types/v2 v2.7.0/go.mod h1:X9kYUH/E5YMqFMZ4xL6MJanABUkJGaH/yPZRT2o+yYA=
|
||||
github.com/wealdtech/go-eth2-wallet-types/v2 v2.8.0 h1:30sYrHQBchcOv+N2yIB2APnqf1RjwAbgXK+IzmXS6cw=
|
||||
github.com/wealdtech/go-eth2-wallet-types/v2 v2.8.0/go.mod h1:X9kYUH/E5YMqFMZ4xL6MJanABUkJGaH/yPZRT2o+yYA=
|
||||
github.com/wealdtech/go-eth2-wallet-types/v2 v2.8.1 h1:pcvljXdc/CqXl/JAXXtd6Ey5SqfOq9MvQutvM+5wvHQ=
|
||||
github.com/wealdtech/go-eth2-wallet-types/v2 v2.8.1/go.mod h1:PWvCKqRknUmOdkXmMLpyW7wBVaAEP5BWSWRph4iWy98=
|
||||
github.com/wealdtech/go-indexer v1.0.0 h1:/S4rfWQbSOnnYmwnvuTVatDibZ8o1s9bmTCHO16XINg=
|
||||
github.com/wealdtech/go-indexer v1.0.0/go.mod h1:u1cjsbsOXsm5jzJDyLmZY7GsrdX8KYXKBXkZcAmk3Zg=
|
||||
github.com/wealdtech/go-majordomo v1.0.1 h1:wo4e0hZmCquhz/l8T/PHLr6hF9+hPY65BM1uRdFXtc8=
|
||||
|
@ -678,16 +651,12 @@ go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
|||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0=
|
||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
|
@ -705,15 +674,14 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U
|
|||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191105034135-c7e5f84aec59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 h1:vEg9joUBmeBcK9iSJftGNf3coIG4HqZElCPehJsfAYM=
|
||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 h1:DZhuSZLsGlFL4CmhA8BcRA0mnthyA/nZ00AqCUo7vHg=
|
||||
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee h1:4yd7jl+vXjalO5ztz6Vc1VADv+S/80LGJmyl1ROJ2AI=
|
||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9 h1:umElSU9WZirRdgu2yFHY0ayQkEnKiOC1TtM3fWXFnoU=
|
||||
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
|
@ -736,7 +704,6 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHl
|
|||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
|
@ -745,7 +712,6 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
|||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -767,8 +733,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0 h1:2mqDk8w/o6UmeUCu5Qiq2y7iMf6anbx+YA8d1JFoFrs=
|
||||
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191116160921-f9c825593386/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
|
@ -781,42 +747,38 @@ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/
|
|||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200528225125-3c3fba18258b h1:IYiJPiJfzktmDAO1HQiwjMjwjlYKHAL7KzeD544RJPs=
|
||||
golang.org/x/net v0.0.0-20200528225125-3c3fba18258b/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc h1:zK/HqS5bZxDptfPJNq8v7vJfXtkU7r9TLIoSr1bXaP4=
|
||||
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200925080053-05aa5d4ee321 h1:lleNcKRbcaC8MqgLwghIkzZ2JBQAb7QQ9MiwRt1BisA=
|
||||
golang.org/x/net v0.0.0-20200925080053-05aa5d4ee321/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200927032502-5d4f70055728/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb h1:mUVeFHoDKis5nxCAzoAi7E8Ghb86EXh/RK6wtvJIqRY=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0 h1:5kGOVHlq0euqwzgTC9Vu15p6fV1Wi0ArVi8da2urnVg=
|
||||
golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201024042810-be3efd7ff127/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201026091529-146b70c837a4 h1:awiuzyrRjJDb+OXi9ceHO3SDxVoN3JER57mhtqkdQBs=
|
||||
golang.org/x/net v0.0.0-20201026091529-146b70c837a4/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 h1:ld7aEMNHoBnnDAX15v1T6z31v8HwR2A9FYOuAhWqkwc=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58 h1:Mj83v+wSRNEar42a/MQgxk9X42TdEmrOl9i+y8WbxLo=
|
||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201008141435-b3e1573b7520 h1:Bx6FllMpG4NWDOfhMBz1VR2QYNp/SAOHPIAsaVmxfPo=
|
||||
golang.org/x/sync v0.0.0-20201008141435-b3e1573b7520/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -828,24 +790,27 @@ golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -859,31 +824,29 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200722175500-76b94024e4b6 h1:X9xIZ1YU8bLZA3l6gqDUHSFiD0GFI9S548h6C8nDtOY=
|
||||
golang.org/x/sys v0.0.0-20200722175500-76b94024e4b6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200819171115-d785dc25833f h1:KJuwZVtZBVzDmEDtB2zro9CXkD9O0dpCv4o2LHbQIAw=
|
||||
golang.org/x/sys v0.0.0-20200819171115-d785dc25833f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d h1:L/IKR6COd7ubZrs2oTnTi73IhgqJ71c9s80WsQnh0Es=
|
||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201013132646-2da7054afaeb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201014080544-cc95f250f6bc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211 h1:9UQO31fZ+0aKQOFldThf7BKPMJTiBfWycGh/u3UoO88=
|
||||
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201017003518-b09fb700fbb7 h1:XtNJkfEjb4zR3q20BBBcYUykVOEMgZeIUOpBPfNYgxg=
|
||||
golang.org/x/sys v0.0.0-20201017003518-b09fb700fbb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201024232916-9f70ab9862d5 h1:iCaAy5bMeEvwANu3YnJfWwI0kWAGkEa2RXPdweI/ysk=
|
||||
golang.org/x/sys v0.0.0-20201024232916-9f70ab9862d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1 h1:a/mKvvZr9Jcc8oKfcmgzyp7OwF73JPWsQLvH1z2Kxck=
|
||||
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd h1:5CtCZbICpIOFdgO940moixOPjc0178IU44m4EjOO5IY=
|
||||
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201113233024-12cec1faf1ba h1:xmhUJGQGbxlod18iJGqVEp9cHIPLl7QiX2aA3to708s=
|
||||
golang.org/x/sys v0.0.0-20201113233024-12cec1faf1ba/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
@ -910,7 +873,6 @@ golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn
|
|||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc h1:NCy3Ohtk6Iny5V/reW2Ktypo4zIpWBdRJ1uFMjBxdg8=
|
||||
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
|
@ -935,26 +897,23 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY
|
|||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7 h1:LHW24ah7B+uV/OePwNP0p/t889F3QSyLvY8Sg/bK0SY=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200828161849-5deb26317202/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||
golang.org/x/tools v0.0.0-20200915173823-2db8f0ff891c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20201013201025-64a9e34f3752/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20201017001424-6003fad69a88/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0 h1:Q3Ui3V3/CVinFWFiW39Iw0kMuVrRzYX0wN6OPFp0lTA=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
|
@ -965,21 +924,19 @@ google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/
|
|||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0 h1:BaiDisFir8O4IJxvAabCGGkQ6yCJegNQqSVoYUNAnbk=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/api v0.31.0/go.mod h1:CL+9IBCa2WWU6gRuBWaKqGWLFFwbEUXkfeMkHLQWYWo=
|
||||
google.golang.org/api v0.32.0 h1:Le77IccnTqEa8ryp9wIpX5W3zYm7Gf9LhOp9PHcwFts=
|
||||
google.golang.org/api v0.32.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||
google.golang.org/api v0.33.0 h1:+gL0XvACeMIvpwLZ5rQZzLn5cwOsgg8dIcfJ2SYfBVw=
|
||||
google.golang.org/api v0.33.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||
google.golang.org/api v0.35.0 h1:TBCmTTxUrRDA1iTctnK/fIeitxIZ+TQuaf0j29fmCGo=
|
||||
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
|
@ -1012,27 +969,23 @@ google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfG
|
|||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200528191852-705c0b31589b h1:nl5tymnV+50ACFZUDAP+xFCe3Zh3SWdMDx+ernZSKNA=
|
||||
google.golang.org/genproto v0.0.0-20200528191852-705c0b31589b/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200722002428-88e341933a54 h1:ASrBgpl9XvkNTP0m39/j18mid7aoF21npu2ioIBxYnY=
|
||||
google.golang.org/genproto v0.0.0-20200722002428-88e341933a54/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200731012542-8145dea6a485/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200815001618-f69a88009b70 h1:wboULUXGF3c5qdUnKp+6gLAccE6PRpa/czkYvQ4UXv8=
|
||||
google.golang.org/genproto v0.0.0-20200815001618-f69a88009b70/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200831141814-d751682dd103/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200914193844-75d14daec038/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200925023002-c2d885f95484 h1:Rr9EZdYRq2WLckzJQVtN3ISKoP7dvgwi7jbglILNZ34=
|
||||
google.golang.org/genproto v0.0.0-20200925023002-c2d885f95484/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201002142447-3860012362da/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201013134114-7f9ee70cb474/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201014134559-03b6142f0dc9/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201015140912-32ed001d685c h1:FM0/YezufKHjM3Y9gndHmhytJuCHW0bExs92Pu3LTQ0=
|
||||
google.golang.org/genproto v0.0.0-20201015140912-32ed001d685c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201022181438-0ff5f38871d5 h1:YejJbGvoWsTXHab4OKNrzk27Dr7s4lPLnewbHue1+gM=
|
||||
google.golang.org/genproto v0.0.0-20201022181438-0ff5f38871d5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201111145450-ac7456db90a6 h1:iRN4+t0lvZX/l9gH14ARF9i58tsVa5a97k6aH95rC3Y=
|
||||
google.golang.org/genproto v0.0.0-20201111145450-ac7456db90a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201113130914-ce600e9a6f9e h1:jRAe+6EDD0LNrVzmjx7FxBivivOZTKnXMbH5lvmxLP8=
|
||||
google.golang.org/genproto v0.0.0-20201113130914-ce600e9a6f9e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
||||
|
@ -1048,17 +1001,17 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
|
|||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.30.0 h1:M5a8xTlYTxwMn5ZFkwhRabsygDY5G8TYLyQDBxJNAxE=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0 h1:T7P4R73V3SSDPhH7WW7ATbfViLtmamH0DKrP3f9AuDI=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.32.0 h1:zWTV+LMdc3kaiJMSTOFz2UgSBgx8RNQoTGiZu3fR9S0=
|
||||
google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.33.0 h1:IBKSUNL2uBS2DkJBncPP+TwT0sp9tgA8A75NjHt6umg=
|
||||
google.golang.org/grpc v1.33.0/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/grpc v1.33.1 h1:DGeFlSan2f+WEtCERJ4J9GJWk15TxUi8QGagfI87Xyc=
|
||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
@ -1067,11 +1020,12 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
|
|||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/cenkalti/backoff.v1 v1.1.0 h1:Arh75ttbsvlpVA7WtVpH4u9h6Zl46xuptxqLxPiSo4Y=
|
||||
gopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UDAkHu8BrjI=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
|
@ -1080,12 +1034,9 @@ gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qS
|
|||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||
gopkg.in/go-playground/validator.v9 v9.30.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.60.0 h1:P5ZzC7RJO04094NJYlEnBdFK2wwmnCAy/+7sAzvWs60=
|
||||
gopkg.in/ini.v1 v1.60.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.61.0 h1:LBCdW4FmFYL4s/vDZD1RQYX7oAR6IjujCYgMdbHBR10=
|
||||
gopkg.in/ini.v1 v1.61.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
|
||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
|
||||
|
@ -1096,7 +1047,6 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl
|
|||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
|
26
main.go
26
main.go
|
@ -265,13 +265,13 @@ func startServices(ctx context.Context, majordomo majordomo.Service) error {
|
|||
}
|
||||
|
||||
log.Trace().Msg("Selecting submitter strategy")
|
||||
submitterStrategy, err := selectSubmitterStrategy(ctx, eth2Client)
|
||||
submitterStrategy, err := selectSubmitterStrategy(ctx, monitor, eth2Client)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to select submitter")
|
||||
}
|
||||
|
||||
log.Trace().Msg("Starting graffiti provider")
|
||||
graffitiProvider, err := startGraffitiProvider(ctx, monitor, majordomo)
|
||||
graffitiProvider, err := startGraffitiProvider(ctx, majordomo)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to start graffiti provider")
|
||||
}
|
||||
|
@ -310,11 +310,17 @@ func startServices(ctx context.Context, majordomo majordomo.Service) error {
|
|||
}
|
||||
|
||||
log.Trace().Msg("Starting beacon attestation aggregator")
|
||||
var aggregationAttester standardattestationaggregator.Parameter
|
||||
if provider, isProvider := eth2Client.(eth2client.AggregateAttestationProvider); isProvider {
|
||||
aggregationAttester = standardattestationaggregator.WithAggregateAttestationDataProvider(provider)
|
||||
} else {
|
||||
aggregationAttester = standardattestationaggregator.WithPrysmAggregateAttestationDataProvider(eth2Client.(eth2client.PrysmAggregateAttestationProvider))
|
||||
}
|
||||
attestationAggregator, err := standardattestationaggregator.New(ctx,
|
||||
standardattestationaggregator.WithLogLevel(logLevel(viper.GetString("attestationaggregator.log-level"))),
|
||||
standardattestationaggregator.WithTargetAggregatorsPerCommitteeProvider(eth2Client.(eth2client.TargetAggregatorsPerCommitteeProvider)),
|
||||
standardattestationaggregator.WithAggregateAttestationDataProvider(eth2Client.(eth2client.NonSpecAggregateAttestationProvider)),
|
||||
standardattestationaggregator.WithAggregateAttestationsSubmitter(submitterStrategy.(submitter.AggregateAttestationsSubmitter)),
|
||||
aggregationAttester,
|
||||
standardattestationaggregator.WithAggregateAttestationsSubmitter(eth2Client.(eth2client.AggregateAttestationsSubmitter)),
|
||||
standardattestationaggregator.WithMonitor(monitor.(metrics.AttestationAggregationMonitor)),
|
||||
standardattestationaggregator.WithValidatingAccountsProvider(accountManager.(accountmanager.ValidatingAccountsProvider)),
|
||||
)
|
||||
|
@ -344,7 +350,7 @@ func startServices(ctx context.Context, majordomo majordomo.Service) error {
|
|||
standardcontroller.WithChainTimeService(chainTime),
|
||||
standardcontroller.WithProposerDutiesProvider(eth2Client.(eth2client.ProposerDutiesProvider)),
|
||||
standardcontroller.WithAttesterDutiesProvider(eth2Client.(eth2client.AttesterDutiesProvider)),
|
||||
standardcontroller.WithBeaconChainHeadUpdatedSource(eth2Client.(eth2client.BeaconChainHeadUpdatedSource)),
|
||||
standardcontroller.WithEventsProvider(eth2Client.(eth2client.EventsProvider)),
|
||||
standardcontroller.WithScheduler(scheduler),
|
||||
standardcontroller.WithValidatingAccountsProvider(accountManager.(accountmanager.ValidatingAccountsProvider)),
|
||||
standardcontroller.WithAttester(attester),
|
||||
|
@ -474,7 +480,7 @@ func startMonitor(ctx context.Context) (metrics.Service, error) {
|
|||
return monitor, nil
|
||||
}
|
||||
|
||||
func startGraffitiProvider(ctx context.Context, monitor metrics.Service, majordomo majordomo.Service) (graffitiprovider.Service, error) {
|
||||
func startGraffitiProvider(ctx context.Context, majordomo majordomo.Service) (graffitiprovider.Service, error) {
|
||||
switch {
|
||||
case viper.Get("graffiti.dynamic") != nil:
|
||||
log.Info().Msg("Starting dynamic graffiti provider")
|
||||
|
@ -524,7 +530,7 @@ func startAccountManager(ctx context.Context, monitor metrics.Service, eth2Clien
|
|||
dirkaccountmanager.WithRANDAODomainProvider(eth2Client.(eth2client.RANDAODomainProvider)),
|
||||
dirkaccountmanager.WithSelectionProofDomainProvider(eth2Client.(eth2client.SelectionProofDomainProvider)),
|
||||
dirkaccountmanager.WithAggregateAndProofDomainProvider(eth2Client.(eth2client.AggregateAndProofDomainProvider)),
|
||||
dirkaccountmanager.WithSignatureDomainProvider(eth2Client.(eth2client.SignatureDomainProvider)),
|
||||
dirkaccountmanager.WithDomainProvider(eth2Client.(eth2client.DomainProvider)),
|
||||
dirkaccountmanager.WithClientCert(certPEMBlock),
|
||||
dirkaccountmanager.WithClientKey(keyPEMBlock),
|
||||
dirkaccountmanager.WithCACert(caPEMBlock),
|
||||
|
@ -563,7 +569,7 @@ func startAccountManager(ctx context.Context, monitor metrics.Service, eth2Clien
|
|||
walletaccountmanager.WithRANDAODomainProvider(eth2Client.(eth2client.RANDAODomainProvider)),
|
||||
walletaccountmanager.WithSelectionProofDomainProvider(eth2Client.(eth2client.SelectionProofDomainProvider)),
|
||||
walletaccountmanager.WithAggregateAndProofDomainProvider(eth2Client.(eth2client.AggregateAndProofDomainProvider)),
|
||||
walletaccountmanager.WithSignatureDomainProvider(eth2Client.(eth2client.SignatureDomainProvider)),
|
||||
walletaccountmanager.WithDomainProvider(eth2Client.(eth2client.DomainProvider)),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to start wallet account manager service")
|
||||
|
@ -626,7 +632,7 @@ func selectBeaconBlockProposalProvider(ctx context.Context,
|
|||
return beaconBlockProposalProvider, nil
|
||||
}
|
||||
|
||||
func selectSubmitterStrategy(ctx context.Context, eth2Client eth2client.Service) (submitter.Service, error) {
|
||||
func selectSubmitterStrategy(ctx context.Context, monitor metrics.Service, eth2Client eth2client.Service) (submitter.Service, error) {
|
||||
var submitter submitter.Service
|
||||
var err error
|
||||
switch viper.GetString("submitter.style") {
|
||||
|
@ -647,6 +653,7 @@ func selectSubmitterStrategy(ctx context.Context, eth2Client eth2client.Service)
|
|||
beaconCommitteeSubscriptionsSubmitters[address] = client.(eth2client.BeaconCommitteeSubscriptionsSubmitter)
|
||||
}
|
||||
submitter, err = multinodesubmitter.New(ctx,
|
||||
multinodesubmitter.WithClientMonitor(monitor.(metrics.ClientMonitor)),
|
||||
multinodesubmitter.WithProcessConcurrency(viper.GetInt64("process-concurrency")),
|
||||
multinodesubmitter.WithLogLevel(logLevel(viper.GetString("submitter.log-level"))),
|
||||
multinodesubmitter.WithBeaconBlockSubmitters(beaconBlockSubmitters),
|
||||
|
@ -658,6 +665,7 @@ func selectSubmitterStrategy(ctx context.Context, eth2Client eth2client.Service)
|
|||
log.Info().Msg("Starting standard submitter strategy")
|
||||
submitter, err = immediatesubmitter.New(ctx,
|
||||
immediatesubmitter.WithLogLevel(logLevel(viper.GetString("submitter.log-level"))),
|
||||
immediatesubmitter.WithClientMonitor(monitor.(metrics.ClientMonitor)),
|
||||
immediatesubmitter.WithBeaconBlockSubmitter(eth2Client.(eth2client.BeaconBlockSubmitter)),
|
||||
immediatesubmitter.WithAttestationSubmitter(eth2Client.(eth2client.AttestationSubmitter)),
|
||||
immediatesubmitter.WithBeaconCommitteeSubscriptionsSubmitter(eth2Client.(eth2client.BeaconCommitteeSubscriptionsSubmitter)),
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"strings"
|
||||
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/attestantio/vouch/services/accountmanager"
|
||||
"github.com/herumi/bls-eth-go-binary/bls"
|
||||
"github.com/pkg/errors"
|
||||
|
@ -32,12 +33,14 @@ type validatingAccount struct {
|
|||
key *bls.SecretKey
|
||||
}
|
||||
|
||||
func (a *validatingAccount) PubKey(ctx context.Context) ([]byte, error) {
|
||||
return a.key.GetPublicKey().Serialize(), nil
|
||||
func (a *validatingAccount) PubKey(ctx context.Context) (spec.BLSPubKey, error) {
|
||||
var res spec.BLSPubKey
|
||||
copy(res[:], a.key.GetPublicKey().Serialize())
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (a *validatingAccount) Index(ctx context.Context) (uint64, error) {
|
||||
return a.index, nil
|
||||
func (a *validatingAccount) Index(ctx context.Context) (spec.ValidatorIndex, error) {
|
||||
return spec.ValidatorIndex(a.index), nil
|
||||
}
|
||||
|
||||
func (a *validatingAccount) State() api.ValidatorState {
|
||||
|
@ -175,8 +178,8 @@ func (m *ValidatingAccountsProvider) Accounts(ctx context.Context) ([]accountman
|
|||
}
|
||||
|
||||
// AccountsByIndex returns accounts.
|
||||
func (m *ValidatingAccountsProvider) AccountsByIndex(ctx context.Context, indices []uint64) ([]accountmanager.ValidatingAccount, error) {
|
||||
indexMap := make(map[uint64]bool)
|
||||
func (m *ValidatingAccountsProvider) AccountsByIndex(ctx context.Context, indices []spec.ValidatorIndex) ([]accountmanager.ValidatingAccount, error) {
|
||||
indexMap := make(map[spec.ValidatorIndex]bool)
|
||||
for _, index := range indices {
|
||||
indexMap[index] = true
|
||||
}
|
||||
|
@ -195,7 +198,7 @@ func (m *ValidatingAccountsProvider) AccountsByIndex(ctx context.Context, indice
|
|||
}
|
||||
|
||||
// AccountsByPubKey returns accounts.
|
||||
func (m *ValidatingAccountsProvider) AccountsByPubKey(ctx context.Context, pubKeys [][]byte) ([]accountmanager.ValidatingAccount, error) {
|
||||
func (m *ValidatingAccountsProvider) AccountsByPubKey(ctx context.Context, pubKeys []spec.BLSPubKey) ([]accountmanager.ValidatingAccount, error) {
|
||||
keyMap := make(map[string]bool)
|
||||
for _, pubKey := range pubKeys {
|
||||
keyMap[fmt.Sprintf("%x", pubKey)] = true
|
||||
|
|
|
@ -177,7 +177,7 @@ func NewBeaconCommitteeSubscriptionsSubmitter() eth2client.BeaconCommitteeSubscr
|
|||
}
|
||||
|
||||
// SubmitBeaconCommitteeSubscriptions is a mock.
|
||||
func (m *BeaconCommitteeSubscriptionsSubmitter) SubmitBeaconCommitteeSubscriptions(ctx context.Context, subscriptions []*eth2client.BeaconCommitteeSubscription) error {
|
||||
func (m *BeaconCommitteeSubscriptionsSubmitter) SubmitBeaconCommitteeSubscriptions(ctx context.Context, subscriptions []*api.BeaconCommitteeSubscription) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -190,7 +190,7 @@ func NewErroringBeaconCommitteeSubscriptionsSubmitter() eth2client.BeaconCommitt
|
|||
}
|
||||
|
||||
// SubmitBeaconCommitteeSubscriptions is a mock.
|
||||
func (m *ErroringBeaconCommitteeSubscriptionsSubmitter) SubmitBeaconCommitteeSubscriptions(ctx context.Context, subscriptions []*eth2client.BeaconCommitteeSubscription) error {
|
||||
func (m *ErroringBeaconCommitteeSubscriptionsSubmitter) SubmitBeaconCommitteeSubscriptions(ctx context.Context, subscriptions []*api.BeaconCommitteeSubscription) error {
|
||||
return errors.New("error")
|
||||
}
|
||||
|
||||
|
@ -203,7 +203,7 @@ func NewBeaconBlockProposalProvider() eth2client.BeaconBlockProposalProvider {
|
|||
}
|
||||
|
||||
// BeaconBlockProposal is a mock.
|
||||
func (m *BeaconBlockProposalProvider) BeaconBlockProposal(ctx context.Context, slot uint64, randaoReveal []byte, graffiti []byte) (*spec.BeaconBlock, error) {
|
||||
func (m *BeaconBlockProposalProvider) BeaconBlockProposal(ctx context.Context, slot spec.Slot, randaoReveal spec.BLSSignature, graffiti []byte) (*spec.BeaconBlock, error) {
|
||||
// Graffiti should be 32 bytes.
|
||||
fixedGraffiti := make([]byte, 32)
|
||||
copy(fixedGraffiti, graffiti)
|
||||
|
@ -219,55 +219,55 @@ func (m *BeaconBlockProposalProvider) BeaconBlockProposal(ctx context.Context, s
|
|||
AggregationBits: aggregationBits,
|
||||
Data: &spec.AttestationData{
|
||||
Slot: slot - 1,
|
||||
Index: i,
|
||||
BeaconBlockRoot: []byte{
|
||||
Index: spec.CommitteeIndex(i),
|
||||
BeaconBlockRoot: spec.Root([32]byte{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
},
|
||||
}),
|
||||
Source: &spec.Checkpoint{
|
||||
Epoch: 0,
|
||||
Root: []byte{
|
||||
Root: spec.Root([32]byte{
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
},
|
||||
}),
|
||||
},
|
||||
Target: &spec.Checkpoint{
|
||||
Epoch: 1,
|
||||
Root: []byte{
|
||||
Root: spec.Root([32]byte{
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
Signature: []byte{
|
||||
Signature: spec.BLSSignature([96]byte{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
},
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
block := &spec.BeaconBlock{
|
||||
Slot: slot,
|
||||
ProposerIndex: 1,
|
||||
ParentRoot: []byte{
|
||||
ParentRoot: spec.Root([32]byte{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
},
|
||||
StateRoot: []byte{
|
||||
}),
|
||||
StateRoot: spec.Root([32]byte{
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
},
|
||||
}),
|
||||
Body: &spec.BeaconBlockBody{
|
||||
RANDAOReveal: randaoReveal,
|
||||
ETH1Data: &spec.ETH1Data{
|
||||
DepositRoot: []byte{
|
||||
DepositRoot: spec.Root([32]byte{
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
},
|
||||
}),
|
||||
DepositCount: 16384,
|
||||
BlockHash: []byte{
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
|
@ -295,8 +295,8 @@ func NewBeaconProposerDomainProvider() eth2client.BeaconProposerDomainProvider {
|
|||
}
|
||||
|
||||
// BeaconProposerDomain is a mock.
|
||||
func (m *BeaconProposerDomainProvider) BeaconProposerDomain(ctx context.Context) ([]byte, error) {
|
||||
return []byte{0x00, 0x00, 0x00, 0x00}, nil
|
||||
func (m *BeaconProposerDomainProvider) BeaconProposerDomain(ctx context.Context) (spec.DomainType, error) {
|
||||
return spec.DomainType{0x00, 0x00, 0x00, 0x00}, nil
|
||||
}
|
||||
|
||||
// ErroringBeaconProposerDomainProvider is a mock for eth2client.BeaconProposerDomainProvider.
|
||||
|
@ -308,8 +308,8 @@ func NewErroringBeaconProposerDomainProvider() eth2client.BeaconProposerDomainPr
|
|||
}
|
||||
|
||||
// BeaconProposerDomain is a mock.
|
||||
func (m *ErroringBeaconProposerDomainProvider) BeaconProposerDomain(ctx context.Context) ([]byte, error) {
|
||||
return nil, errors.New("error")
|
||||
func (m *ErroringBeaconProposerDomainProvider) BeaconProposerDomain(ctx context.Context) (spec.DomainType, error) {
|
||||
return spec.DomainType{}, errors.New("error")
|
||||
}
|
||||
|
||||
// BeaconAttesterDomainProvider is a mock for eth2client.BeaconAttesterDomainProvider.
|
||||
|
@ -321,8 +321,8 @@ func NewBeaconAttesterDomainProvider() eth2client.BeaconAttesterDomainProvider {
|
|||
}
|
||||
|
||||
// BeaconAttesterDomain is a mock.
|
||||
func (m *BeaconAttesterDomainProvider) BeaconAttesterDomain(ctx context.Context) ([]byte, error) {
|
||||
return []byte{0x01, 0x00, 0x00, 0x00}, nil
|
||||
func (m *BeaconAttesterDomainProvider) BeaconAttesterDomain(ctx context.Context) (spec.DomainType, error) {
|
||||
return spec.DomainType{0x01, 0x00, 0x00, 0x00}, nil
|
||||
}
|
||||
|
||||
// ErroringBeaconAttesterDomainProvider is a mock for eth2client.BeaconAttesterDomainProvider.
|
||||
|
@ -334,8 +334,8 @@ func NewErroringBeaconAttesterDomainProvider() eth2client.BeaconAttesterDomainPr
|
|||
}
|
||||
|
||||
// BeaconAttesterDomain is a mock.
|
||||
func (m *ErroringBeaconAttesterDomainProvider) BeaconAttesterDomain(ctx context.Context) ([]byte, error) {
|
||||
return nil, errors.New("error")
|
||||
func (m *ErroringBeaconAttesterDomainProvider) BeaconAttesterDomain(ctx context.Context) (spec.DomainType, error) {
|
||||
return spec.DomainType{}, errors.New("error")
|
||||
}
|
||||
|
||||
// RANDAODomainProvider is a mock for eth2client.RANDAODomainProvider.
|
||||
|
@ -347,8 +347,8 @@ func NewRANDAODomainProvider() eth2client.RANDAODomainProvider {
|
|||
}
|
||||
|
||||
// RANDAODomain is a mock.
|
||||
func (m *RANDAODomainProvider) RANDAODomain(ctx context.Context) ([]byte, error) {
|
||||
return []byte{0x02, 0x00, 0x00, 0x00}, nil
|
||||
func (m *RANDAODomainProvider) RANDAODomain(ctx context.Context) (spec.DomainType, error) {
|
||||
return spec.DomainType{0x02, 0x00, 0x00, 0x00}, nil
|
||||
}
|
||||
|
||||
// ErroringRANDAODomainProvider is a mock for eth2client.RANDAODomainProvider.
|
||||
|
@ -360,8 +360,8 @@ func NewErroringRANDAODomainProvider() eth2client.RANDAODomainProvider {
|
|||
}
|
||||
|
||||
// RANDAODomain is a mock.
|
||||
func (m *ErroringRANDAODomainProvider) RANDAODomain(ctx context.Context) ([]byte, error) {
|
||||
return nil, errors.New("error")
|
||||
func (m *ErroringRANDAODomainProvider) RANDAODomain(ctx context.Context) (spec.DomainType, error) {
|
||||
return spec.DomainType{}, errors.New("error")
|
||||
}
|
||||
|
||||
// DepositDomainProvider is a mock for eth2client.DepositDomainProvider.
|
||||
|
@ -373,8 +373,8 @@ func NewDepositDomainProvider() eth2client.DepositDomainProvider {
|
|||
}
|
||||
|
||||
// DepositDomain is a mock.
|
||||
func (m *DepositDomainProvider) DepositDomain(ctx context.Context) ([]byte, error) {
|
||||
return []byte{0x03, 0x00, 0x00, 0x00}, nil
|
||||
func (m *DepositDomainProvider) DepositDomain(ctx context.Context) (spec.DomainType, error) {
|
||||
return spec.DomainType{0x03, 0x00, 0x00, 0x00}, nil
|
||||
}
|
||||
|
||||
// ErroringDepositDomainProvider is a mock for eth2client.DepositDomainProvider.
|
||||
|
@ -386,8 +386,8 @@ func NewErroringDepositDomainProvider() eth2client.DepositDomainProvider {
|
|||
}
|
||||
|
||||
// DepositDomain is a mock.
|
||||
func (m *ErroringDepositDomainProvider) DepositDomain(ctx context.Context) ([]byte, error) {
|
||||
return nil, errors.New("error")
|
||||
func (m *ErroringDepositDomainProvider) DepositDomain(ctx context.Context) (spec.DomainType, error) {
|
||||
return spec.DomainType{}, errors.New("error")
|
||||
}
|
||||
|
||||
// VoluntaryExitDomainProvider is a mock for eth2client.VoluntaryExitDomainProvider.
|
||||
|
@ -399,8 +399,8 @@ func NewVoluntaryExitDomainProvider() eth2client.VoluntaryExitDomainProvider {
|
|||
}
|
||||
|
||||
// VoluntaryExitDomain is a mock.
|
||||
func (m *VoluntaryExitDomainProvider) VoluntaryExitDomain(ctx context.Context) ([]byte, error) {
|
||||
return []byte{0x04, 0x00, 0x00, 0x00}, nil
|
||||
func (m *VoluntaryExitDomainProvider) VoluntaryExitDomain(ctx context.Context) (spec.DomainType, error) {
|
||||
return spec.DomainType{0x04, 0x00, 0x00, 0x00}, nil
|
||||
}
|
||||
|
||||
// ErroringVoluntaryExitDomainProvider is a mock for eth2client.VoluntaryExitDomainProvider.
|
||||
|
@ -412,8 +412,8 @@ func NewErroringVoluntaryExitDomainProvider() eth2client.VoluntaryExitDomainProv
|
|||
}
|
||||
|
||||
// VoluntaryExitDomain is a mock.
|
||||
func (m *ErroringVoluntaryExitDomainProvider) VoluntaryExitDomain(ctx context.Context) ([]byte, error) {
|
||||
return nil, errors.New("error")
|
||||
func (m *ErroringVoluntaryExitDomainProvider) VoluntaryExitDomain(ctx context.Context) (spec.DomainType, error) {
|
||||
return spec.DomainType{}, errors.New("error")
|
||||
}
|
||||
|
||||
// SelectionProofDomainProvider is a mock for eth2client.SelectionProofDomainProvider.
|
||||
|
@ -425,8 +425,8 @@ func NewSelectionProofDomainProvider() eth2client.SelectionProofDomainProvider {
|
|||
}
|
||||
|
||||
// SelectionProofDomain is a mock.
|
||||
func (m *SelectionProofDomainProvider) SelectionProofDomain(ctx context.Context) ([]byte, error) {
|
||||
return []byte{0x05, 0x00, 0x00, 0x00}, nil
|
||||
func (m *SelectionProofDomainProvider) SelectionProofDomain(ctx context.Context) (spec.DomainType, error) {
|
||||
return spec.DomainType{0x05, 0x00, 0x00, 0x00}, nil
|
||||
}
|
||||
|
||||
// ErroringSelectionProofDomainProvider is a mock for eth2client.SelectionProofDomainProvider.
|
||||
|
@ -438,8 +438,8 @@ func NewErroringSelectionProofDomainProvider() eth2client.SelectionProofDomainPr
|
|||
}
|
||||
|
||||
// SelectionProofDomain is a mock.
|
||||
func (m *ErroringSelectionProofDomainProvider) SelectionProofDomain(ctx context.Context) ([]byte, error) {
|
||||
return nil, errors.New("error")
|
||||
func (m *ErroringSelectionProofDomainProvider) SelectionProofDomain(ctx context.Context) (spec.DomainType, error) {
|
||||
return spec.DomainType{}, errors.New("error")
|
||||
}
|
||||
|
||||
// AggregateAndProofDomainProvider is a mock for eth2client.AggregateAndProofDomainProvider.
|
||||
|
@ -451,8 +451,8 @@ func NewAggregateAndProofDomainProvider() eth2client.AggregateAndProofDomainProv
|
|||
}
|
||||
|
||||
// AggregateAndProofDomain is a mock.
|
||||
func (m *AggregateAndProofDomainProvider) AggregateAndProofDomain(ctx context.Context) ([]byte, error) {
|
||||
return []byte{0x06, 0x00, 0x00, 0x00}, nil
|
||||
func (m *AggregateAndProofDomainProvider) AggregateAndProofDomain(ctx context.Context) (spec.DomainType, error) {
|
||||
return spec.DomainType{0x06, 0x00, 0x00, 0x00}, nil
|
||||
}
|
||||
|
||||
// ErroringAggregateAndProofDomainProvider is a mock for eth2client.AggregateAndProofDomainProvider.
|
||||
|
@ -464,38 +464,38 @@ func NewErroringAggregateAndProofDomainProvider() eth2client.AggregateAndProofDo
|
|||
}
|
||||
|
||||
// AggregateAndProofDomain is a mock.
|
||||
func (m *ErroringAggregateAndProofDomainProvider) AggregateAndProofDomain(ctx context.Context) ([]byte, error) {
|
||||
return nil, errors.New("error")
|
||||
func (m *ErroringAggregateAndProofDomainProvider) AggregateAndProofDomain(ctx context.Context) (spec.DomainType, error) {
|
||||
return spec.DomainType{}, errors.New("error")
|
||||
}
|
||||
|
||||
// SignatureDomainProvider is a mock for eth2client.SignatureDomainProvider.
|
||||
type SignatureDomainProvider struct{}
|
||||
// DomainProvider is a mock for eth2client.DomainProvider.
|
||||
type DomainProvider struct{}
|
||||
|
||||
// NewSignatureDomainProvider returns a mock signature domain provider.
|
||||
func NewSignatureDomainProvider() eth2client.SignatureDomainProvider {
|
||||
return &SignatureDomainProvider{}
|
||||
// NewDomainProvider returns a mock domain provider.
|
||||
func NewDomainProvider() eth2client.DomainProvider {
|
||||
return &DomainProvider{}
|
||||
}
|
||||
|
||||
// SignatureDomain is a mock.
|
||||
func (m *SignatureDomainProvider) SignatureDomain(ctx context.Context, domain []byte, epoch uint64) ([]byte, error) {
|
||||
var signatureDomain [32]byte
|
||||
// Put the domain in the first four bytes, to differentiate signatures.
|
||||
copy(signatureDomain[:], domain)
|
||||
// Domain is a mock.
|
||||
func (m *DomainProvider) Domain(ctx context.Context, domainType spec.DomainType, epoch spec.Epoch) (spec.Domain, error) {
|
||||
var domain spec.Domain
|
||||
// Put the domain type in the first four bytes, to differentiate signatures.
|
||||
copy(domain[:], domainType[:])
|
||||
|
||||
return signatureDomain[:], nil
|
||||
return domain, nil
|
||||
}
|
||||
|
||||
// ErroringSignatureDomainProvider is a mock for eth2client.SignatureDomainProvider.
|
||||
type ErroringSignatureDomainProvider struct{}
|
||||
// ErroringDomainProvider is a mock for eth2client.DomainProvider.
|
||||
type ErroringDomainProvider struct{}
|
||||
|
||||
// NewErroringSignatureDomainProvider returns a mock signature domain provider that errors.
|
||||
func NewErroringSignatureDomainProvider() eth2client.SignatureDomainProvider {
|
||||
return &SignatureDomainProvider{}
|
||||
// NewErroringDomainProvider returns a mock signature domain provider that errors.
|
||||
func NewErroringDomainProvider() eth2client.DomainProvider {
|
||||
return &ErroringDomainProvider{}
|
||||
}
|
||||
|
||||
// SignatureDomain is a mock.
|
||||
func (m *ErroringSignatureDomainProvider) SignatureDomain(ctx context.Context, domain []byte, epoch uint64) ([]byte, error) {
|
||||
return nil, errors.New("error")
|
||||
// Domain is a mock.
|
||||
func (m *ErroringDomainProvider) Domain(ctx context.Context, domainType spec.DomainType, epoch spec.Epoch) (spec.Domain, error) {
|
||||
return spec.Domain{}, errors.New("error")
|
||||
}
|
||||
|
||||
// ValidatorsProvider is a mock for eth2client.ValidatorsProvider.
|
||||
|
@ -511,13 +511,20 @@ func _byte(input string) []byte {
|
|||
return res
|
||||
}
|
||||
|
||||
func _epochValidator(index uint64, pubKey string, withdrwalCredentials string) *api.Validator {
|
||||
func _blsPubKey(input string) spec.BLSPubKey {
|
||||
tmp, _ := hex.DecodeString(strings.TrimPrefix(input, "0x"))
|
||||
var res spec.BLSPubKey
|
||||
copy(res[:], tmp)
|
||||
return res
|
||||
}
|
||||
|
||||
func _epochValidator(index spec.ValidatorIndex, pubKey string, withdrwalCredentials string) *api.Validator {
|
||||
return &api.Validator{
|
||||
Index: index,
|
||||
Balance: 32000000000,
|
||||
State: api.ValidatorStateActiveOngoing,
|
||||
Status: api.ValidatorStateActiveOngoing,
|
||||
Validator: &spec.Validator{
|
||||
PublicKey: _byte(pubKey),
|
||||
PublicKey: _blsPubKey(pubKey),
|
||||
WithdrawalCredentials: _byte(withdrwalCredentials),
|
||||
EffectiveBalance: 32000000,
|
||||
Slashed: false,
|
||||
|
@ -530,8 +537,110 @@ func _epochValidator(index uint64, pubKey string, withdrwalCredentials string) *
|
|||
}
|
||||
|
||||
// Validators is a mock.
|
||||
func (m *ValidatorsProvider) Validators(ctx context.Context, stateID string, validators []eth2client.ValidatorIDProvider) (map[uint64]*api.Validator, error) {
|
||||
return map[uint64]*api.Validator{
|
||||
func (m *ValidatorsProvider) Validators(ctx context.Context, stateID string, validators []spec.ValidatorIndex) (map[spec.ValidatorIndex]*api.Validator, error) {
|
||||
return map[spec.ValidatorIndex]*api.Validator{
|
||||
0: _epochValidator(0,
|
||||
"0xa99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c",
|
||||
"0x00fad2a6bfb0e7f1f0f45460944fbd8dfa7f37da06a4d13b3983cc90bb46963b"),
|
||||
1: _epochValidator(1,
|
||||
"0xb89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b",
|
||||
"0x00ec7ef7780c9d151597924036262dd28dc60e1228f4da6fecf9d402cb3f3594"),
|
||||
2: _epochValidator(2,
|
||||
"0xa3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b",
|
||||
"0x0036085c6c608e6d048505b04402568c36cce1e025722de44f9c3685a5c80fa6"),
|
||||
3: _epochValidator(3,
|
||||
"0x88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e",
|
||||
"0x005a7de495bcec04d3b5e74ae09ffe493a9dd06d7dcbf18c78455571e87d901a"),
|
||||
4: _epochValidator(4,
|
||||
"0x81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e",
|
||||
"0x004a28c193c65c91b7ebb5b5d14ffa7f75dc48ad4bc66de82f70fc55a2df1215"),
|
||||
5: _epochValidator(5,
|
||||
"0xab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34",
|
||||
"0x005856ab195b61df2ff5d6ab2fa36f30dab45e42cfa1aaef3ffd899f29bd8641"),
|
||||
6: _epochValidator(6,
|
||||
"0x9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373",
|
||||
"0x001c5d9bedbad1b7aff3b80e887e65b3357a695b70b6ee0625c2b2f6f86449f8"),
|
||||
7: _epochValidator(7,
|
||||
"0xa8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac",
|
||||
"0x001414bfc6dacca55f974ec910893c8617f9c99da897534c637b50e9fc695323"),
|
||||
8: _epochValidator(8,
|
||||
"0xa6d310dbbfab9a22450f59993f87a4ce5db6223f3b5f1f30d2c4ec718922d400e0b3c7741de8e59960f72411a0ee10a7",
|
||||
"0x00ed09b6181e6f97365e221e70aeebcb2604011d8c4326f3b98ce8d79b031ae8"),
|
||||
9: _epochValidator(9,
|
||||
"0x9893413c00283a3f9ed9fd9845dda1cea38228d22567f9541dccc357e54a2d6a6e204103c92564cbc05f4905ac7c493a",
|
||||
"0x001fe05baa70dd29ce85f694898bb6de3bcde158a825db56906b54141b2a728d"),
|
||||
10: _epochValidator(10,
|
||||
"0x876dd4705157eb66dc71bc2e07fb151ea53e1a62a0bb980a7ce72d15f58944a8a3752d754f52f4a60dbfc7b18169f268",
|
||||
"0x00aa2cfedd0160868d0901664e9d2eac1275dd658e109fabe11c7ad87a07fc0c"),
|
||||
11: _epochValidator(11,
|
||||
"0xaec922bd7a9b7b1dc21993133b586b0c3041c1e2e04b513e862227b9d7aecaf9444222f7e78282a449622ffc6278915d",
|
||||
"0x0076f08e6f40cf14992b7e4f524ea0cf7e1c6fd7dd5200b564c96fc099d601aa"),
|
||||
12: _epochValidator(12,
|
||||
"0x9314c6de0386635e2799af798884c2ea09c63b9f079e572acc00b06a7faccce501ea4dfc0b1a23b8603680a5e3481327",
|
||||
"0x004a581b2ef2b79652a19d3332f6574b0213ddbd179480edbf7ff490823fd5c7"),
|
||||
13: _epochValidator(13,
|
||||
"0x903e2989e7442ee0a8958d020507a8bd985d3974f5e8273093be00db3935f0500e141b252bd09e3728892c7a8443863c",
|
||||
"0x0040c37a4dafa560a7665394aa7502e113ecfbdb72c1ef92826db24601889b87"),
|
||||
14: _epochValidator(14,
|
||||
"0x84398f539a64cbe01cfcd8c485ea51cd6657b94df93ee9b5dc61e1f18f69da6ca9d4dba63c956a81c68d5d4d4277a60f",
|
||||
"0x0047381e2716b14a79e1f102669c615eb3542e9230ed7712b21f305ecc1a43d5"),
|
||||
15: _epochValidator(15,
|
||||
"0x872c61b4a7f8510ec809e5b023f5fdda2105d024c470ddbbeca4bc74e8280af0d178d749853e8f6a841083ac1b4db98f",
|
||||
"0x0020dd5f2223831fce8d1c8fd4148943c9917e1d3a92191651892dc56448451c"),
|
||||
16: _epochValidator(16,
|
||||
"0x8f467e5723deac7659e1ca273e28410cbaa6d495ab66ae77014f4cd21c64b6b5ab9987c9b5537fe0279bd063fe609be7",
|
||||
"0x00b24fc624e56a5ed42a9639691e27e34b783c7237030367bd17cbef65fa6ccf"),
|
||||
17: _epochValidator(17,
|
||||
"0x8dde8306920812b32def3b663f7c540b49180345d3bcb8d3770790b7dc80030ebc06497feebd1bcf017d918f00bfa88f",
|
||||
"0x0018e4071970526ed149970747c6b858307be8b60aa7440ad93c1f351af62923"),
|
||||
18: _epochValidator(18,
|
||||
"0xab8d3a9bcc160e518fac0756d3e192c74789588ed4a2b1debf0c78f78479ca8edb05b12ce21103076df6af4eb8756ff9",
|
||||
"0x00bb019106332edfed624b40e410561513e9fb9e285cbc56a450d499a2b13769"),
|
||||
19: _epochValidator(19,
|
||||
"0x8d5d3672a233db513df7ad1e8beafeae99a9f0199ed4d949bbedbb6f394030c0416bd99b910e14f73c65b6a11fe6b62e",
|
||||
"0x004218c29533321c9aae659d8b2148b87693d6b1eee8e119805e5298f8bf0a33"),
|
||||
20: _epochValidator(20,
|
||||
"0xa1c76af1545d7901214bb6be06be5d9e458f8e989c19373a920f0018327c83982f6a2ac138260b8def732cb366411ddc",
|
||||
"0x0004e3d99964ee8b0b6ed11833ba55fbf7bf80fe8f4e45c4d00a3d4ff6d73c0c"),
|
||||
21: _epochValidator(21,
|
||||
"0x8dd74e1bb5228fc1fca274fda02b971c1003a4f409bbdfbcfec6426bf2f52addcbbebccdbf45eee6ae11eb5b5ee7244d",
|
||||
"0x00037233059d7c629c79ddb7d94b0ef1275ebe55ed20fb80a414548be9ec890a"),
|
||||
22: _epochValidator(22,
|
||||
"0x954eb88ed1207f891dc3c28fa6cfdf8f53bf0ed3d838f3476c0900a61314d22d4f0a300da3cd010444dd5183e35a593c",
|
||||
"0x0056a7b95fd200d2997155b525eacda73baae3f3196a48fb9a513ddd1e7247c3"),
|
||||
23: _epochValidator(23,
|
||||
"0xaf344fce60dbd5fb850070e6e76a065e1a32485245ef4f413135a86ae703da88407c5d01c71f6bb06a151ff96cca7191",
|
||||
"0x005bdba6a856b0df016f8cbad0f9c02a517e2ff2f5db19187e6d1ba155d4b2e5"),
|
||||
24: _epochValidator(24,
|
||||
"0xae241af60691fda1cf8ca44d49573c55818c53b6141800cca2d488b9a3fba71c0f869179fff50c084657831fbeb42bf4",
|
||||
"0x000cc62d0bf911cfba5320da6e1d7407ff744427f74e855fc2444357788d6830"),
|
||||
25: _epochValidator(25,
|
||||
"0x96746aaba64dc87835ba709332f4d5d7837ada092b439c49d251aecf92aab5dc132e917bf6f59799bc093f976a7bc021",
|
||||
"0x006badd5d911c8565362da6e00dde8d2dda73fb9127d5ba26849ae0a0636172b"),
|
||||
26: _epochValidator(26,
|
||||
"0xb9d1d914df3d4565465c3fd52b5b96e637f9980570cabf5b5d4aadf5a329ac36ad672819d997e735f5052e28b1f0c104",
|
||||
"0x00f53dc973d5288e8070cf79ac0168443f3a2703e83f600e6197067aa02ca662"),
|
||||
27: _epochValidator(27,
|
||||
"0x963528adb5322c2e2c54dc296ffddd2861bb103cbf64646781dfa8a3c2d8a8eda7079d2b3e95600028c44365afbf8879",
|
||||
"0x00fa4e26953e907b1ed8032bdd02c9869dbbf521f3cb7bac1c8112ccf45c1d3a"),
|
||||
28: _epochValidator(28,
|
||||
"0xb245d63d3f9d8ea1807a629fcb1b328cb4d542f35a3d5bc478be0df389dddd712fc4c816ba3fede9a96320ae6b24a7d8",
|
||||
"0x00a68cdbfc1e865255d8e436d7bc7fc63c87b5c9c247c9e5de34d4fc26a1adc9"),
|
||||
29: _epochValidator(29,
|
||||
"0xa98ed496c2f464226500a6ce04602ff9ef133ed6316f372f6c744aee165149f7e578b12780e0eacec307ae6907351d99",
|
||||
"0x002f6d1f79f89a308365af4dbb8a850918db7844165b36e43c64e1a35b4af0b2"),
|
||||
30: _epochValidator(30,
|
||||
"0xae00fc3de831b09661a0ac02873c45c84cb2b58cffb6430a3f607e4c3fa1e0932397f11307cd169cdc6f79c463527260",
|
||||
"0x00e6ef2894304bc790c9e6b3a75815f10ceea391d8ebb9a27e07bf54360e9b3d"),
|
||||
31: _epochValidator(31,
|
||||
"0xa4855c83d868f772a579133d9f23818008417b743e8447e235d8eb78b1d8f8a9f63f98c551beb7de254400f89592314d",
|
||||
"0x0077c6a139204cbdaae840e0beb43b384c35182aabbc1104207b6a5a626fe75b"),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ValidatorsByPubKey is a mock.
|
||||
func (m *ValidatorsProvider) ValidatorsByPubKey(ctx context.Context, stateID string, validators []spec.BLSPubKey) (map[spec.ValidatorIndex]*api.Validator, error) {
|
||||
return map[spec.ValidatorIndex]*api.Validator{
|
||||
0: _epochValidator(0,
|
||||
"0xa99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c",
|
||||
"0x00fad2a6bfb0e7f1f0f45460944fbd8dfa7f37da06a4d13b3983cc90bb46963b"),
|
||||
|
@ -640,8 +749,110 @@ func NewValidatorsWithoutBalanceProvider() eth2client.ValidatorsProvider {
|
|||
}
|
||||
|
||||
// Validators is a mock.
|
||||
func (m *ValidatorsWithoutBalanceProvider) Validators(ctx context.Context, stateID string, validators []eth2client.ValidatorIDProvider) (map[uint64]*api.Validator, error) {
|
||||
return map[uint64]*api.Validator{
|
||||
func (m *ValidatorsWithoutBalanceProvider) Validators(ctx context.Context, stateID string, validators []spec.ValidatorIndex) (map[spec.ValidatorIndex]*api.Validator, error) {
|
||||
return map[spec.ValidatorIndex]*api.Validator{
|
||||
0: _epochValidator(0,
|
||||
"0xa99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c",
|
||||
"0x00fad2a6bfb0e7f1f0f45460944fbd8dfa7f37da06a4d13b3983cc90bb46963b"),
|
||||
1: _epochValidator(1,
|
||||
"0xb89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b",
|
||||
"0x00ec7ef7780c9d151597924036262dd28dc60e1228f4da6fecf9d402cb3f3594"),
|
||||
2: _epochValidator(2,
|
||||
"0xa3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b",
|
||||
"0x0036085c6c608e6d048505b04402568c36cce1e025722de44f9c3685a5c80fa6"),
|
||||
3: _epochValidator(3,
|
||||
"0x88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e",
|
||||
"0x005a7de495bcec04d3b5e74ae09ffe493a9dd06d7dcbf18c78455571e87d901a"),
|
||||
4: _epochValidator(4,
|
||||
"0x81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e",
|
||||
"0x004a28c193c65c91b7ebb5b5d14ffa7f75dc48ad4bc66de82f70fc55a2df1215"),
|
||||
5: _epochValidator(5,
|
||||
"0xab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34",
|
||||
"0x005856ab195b61df2ff5d6ab2fa36f30dab45e42cfa1aaef3ffd899f29bd8641"),
|
||||
6: _epochValidator(6,
|
||||
"0x9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373",
|
||||
"0x001c5d9bedbad1b7aff3b80e887e65b3357a695b70b6ee0625c2b2f6f86449f8"),
|
||||
7: _epochValidator(7,
|
||||
"0xa8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac",
|
||||
"0x001414bfc6dacca55f974ec910893c8617f9c99da897534c637b50e9fc695323"),
|
||||
8: _epochValidator(8,
|
||||
"0xa6d310dbbfab9a22450f59993f87a4ce5db6223f3b5f1f30d2c4ec718922d400e0b3c7741de8e59960f72411a0ee10a7",
|
||||
"0x00ed09b6181e6f97365e221e70aeebcb2604011d8c4326f3b98ce8d79b031ae8"),
|
||||
9: _epochValidator(9,
|
||||
"0x9893413c00283a3f9ed9fd9845dda1cea38228d22567f9541dccc357e54a2d6a6e204103c92564cbc05f4905ac7c493a",
|
||||
"0x001fe05baa70dd29ce85f694898bb6de3bcde158a825db56906b54141b2a728d"),
|
||||
10: _epochValidator(10,
|
||||
"0x876dd4705157eb66dc71bc2e07fb151ea53e1a62a0bb980a7ce72d15f58944a8a3752d754f52f4a60dbfc7b18169f268",
|
||||
"0x00aa2cfedd0160868d0901664e9d2eac1275dd658e109fabe11c7ad87a07fc0c"),
|
||||
11: _epochValidator(11,
|
||||
"0xaec922bd7a9b7b1dc21993133b586b0c3041c1e2e04b513e862227b9d7aecaf9444222f7e78282a449622ffc6278915d",
|
||||
"0x0076f08e6f40cf14992b7e4f524ea0cf7e1c6fd7dd5200b564c96fc099d601aa"),
|
||||
12: _epochValidator(12,
|
||||
"0x9314c6de0386635e2799af798884c2ea09c63b9f079e572acc00b06a7faccce501ea4dfc0b1a23b8603680a5e3481327",
|
||||
"0x004a581b2ef2b79652a19d3332f6574b0213ddbd179480edbf7ff490823fd5c7"),
|
||||
13: _epochValidator(13,
|
||||
"0x903e2989e7442ee0a8958d020507a8bd985d3974f5e8273093be00db3935f0500e141b252bd09e3728892c7a8443863c",
|
||||
"0x0040c37a4dafa560a7665394aa7502e113ecfbdb72c1ef92826db24601889b87"),
|
||||
14: _epochValidator(14,
|
||||
"0x84398f539a64cbe01cfcd8c485ea51cd6657b94df93ee9b5dc61e1f18f69da6ca9d4dba63c956a81c68d5d4d4277a60f",
|
||||
"0x0047381e2716b14a79e1f102669c615eb3542e9230ed7712b21f305ecc1a43d5"),
|
||||
15: _epochValidator(15,
|
||||
"0x872c61b4a7f8510ec809e5b023f5fdda2105d024c470ddbbeca4bc74e8280af0d178d749853e8f6a841083ac1b4db98f",
|
||||
"0x0020dd5f2223831fce8d1c8fd4148943c9917e1d3a92191651892dc56448451c"),
|
||||
16: _epochValidator(16,
|
||||
"0x8f467e5723deac7659e1ca273e28410cbaa6d495ab66ae77014f4cd21c64b6b5ab9987c9b5537fe0279bd063fe609be7",
|
||||
"0x00b24fc624e56a5ed42a9639691e27e34b783c7237030367bd17cbef65fa6ccf"),
|
||||
17: _epochValidator(17,
|
||||
"0x8dde8306920812b32def3b663f7c540b49180345d3bcb8d3770790b7dc80030ebc06497feebd1bcf017d918f00bfa88f",
|
||||
"0x0018e4071970526ed149970747c6b858307be8b60aa7440ad93c1f351af62923"),
|
||||
18: _epochValidator(18,
|
||||
"0xab8d3a9bcc160e518fac0756d3e192c74789588ed4a2b1debf0c78f78479ca8edb05b12ce21103076df6af4eb8756ff9",
|
||||
"0x00bb019106332edfed624b40e410561513e9fb9e285cbc56a450d499a2b13769"),
|
||||
19: _epochValidator(19,
|
||||
"0x8d5d3672a233db513df7ad1e8beafeae99a9f0199ed4d949bbedbb6f394030c0416bd99b910e14f73c65b6a11fe6b62e",
|
||||
"0x004218c29533321c9aae659d8b2148b87693d6b1eee8e119805e5298f8bf0a33"),
|
||||
20: _epochValidator(20,
|
||||
"0xa1c76af1545d7901214bb6be06be5d9e458f8e989c19373a920f0018327c83982f6a2ac138260b8def732cb366411ddc",
|
||||
"0x0004e3d99964ee8b0b6ed11833ba55fbf7bf80fe8f4e45c4d00a3d4ff6d73c0c"),
|
||||
21: _epochValidator(21,
|
||||
"0x8dd74e1bb5228fc1fca274fda02b971c1003a4f409bbdfbcfec6426bf2f52addcbbebccdbf45eee6ae11eb5b5ee7244d",
|
||||
"0x00037233059d7c629c79ddb7d94b0ef1275ebe55ed20fb80a414548be9ec890a"),
|
||||
22: _epochValidator(22,
|
||||
"0x954eb88ed1207f891dc3c28fa6cfdf8f53bf0ed3d838f3476c0900a61314d22d4f0a300da3cd010444dd5183e35a593c",
|
||||
"0x0056a7b95fd200d2997155b525eacda73baae3f3196a48fb9a513ddd1e7247c3"),
|
||||
23: _epochValidator(23,
|
||||
"0xaf344fce60dbd5fb850070e6e76a065e1a32485245ef4f413135a86ae703da88407c5d01c71f6bb06a151ff96cca7191",
|
||||
"0x005bdba6a856b0df016f8cbad0f9c02a517e2ff2f5db19187e6d1ba155d4b2e5"),
|
||||
24: _epochValidator(24,
|
||||
"0xae241af60691fda1cf8ca44d49573c55818c53b6141800cca2d488b9a3fba71c0f869179fff50c084657831fbeb42bf4",
|
||||
"0x000cc62d0bf911cfba5320da6e1d7407ff744427f74e855fc2444357788d6830"),
|
||||
25: _epochValidator(25,
|
||||
"0x96746aaba64dc87835ba709332f4d5d7837ada092b439c49d251aecf92aab5dc132e917bf6f59799bc093f976a7bc021",
|
||||
"0x006badd5d911c8565362da6e00dde8d2dda73fb9127d5ba26849ae0a0636172b"),
|
||||
26: _epochValidator(26,
|
||||
"0xb9d1d914df3d4565465c3fd52b5b96e637f9980570cabf5b5d4aadf5a329ac36ad672819d997e735f5052e28b1f0c104",
|
||||
"0x00f53dc973d5288e8070cf79ac0168443f3a2703e83f600e6197067aa02ca662"),
|
||||
27: _epochValidator(27,
|
||||
"0x963528adb5322c2e2c54dc296ffddd2861bb103cbf64646781dfa8a3c2d8a8eda7079d2b3e95600028c44365afbf8879",
|
||||
"0x00fa4e26953e907b1ed8032bdd02c9869dbbf521f3cb7bac1c8112ccf45c1d3a"),
|
||||
28: _epochValidator(28,
|
||||
"0xb245d63d3f9d8ea1807a629fcb1b328cb4d542f35a3d5bc478be0df389dddd712fc4c816ba3fede9a96320ae6b24a7d8",
|
||||
"0x00a68cdbfc1e865255d8e436d7bc7fc63c87b5c9c247c9e5de34d4fc26a1adc9"),
|
||||
29: _epochValidator(29,
|
||||
"0xa98ed496c2f464226500a6ce04602ff9ef133ed6316f372f6c744aee165149f7e578b12780e0eacec307ae6907351d99",
|
||||
"0x002f6d1f79f89a308365af4dbb8a850918db7844165b36e43c64e1a35b4af0b2"),
|
||||
30: _epochValidator(30,
|
||||
"0xae00fc3de831b09661a0ac02873c45c84cb2b58cffb6430a3f607e4c3fa1e0932397f11307cd169cdc6f79c463527260",
|
||||
"0x00e6ef2894304bc790c9e6b3a75815f10ceea391d8ebb9a27e07bf54360e9b3d"),
|
||||
31: _epochValidator(31,
|
||||
"0xa4855c83d868f772a579133d9f23818008417b743e8447e235d8eb78b1d8f8a9f63f98c551beb7de254400f89592314d",
|
||||
"0x0077c6a139204cbdaae840e0beb43b384c35182aabbc1104207b6a5a626fe75b"),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ValidatorsByPubKey is a mock.
|
||||
func (m *ValidatorsWithoutBalanceProvider) ValidatorsByPubKey(ctx context.Context, stateID string, validators []spec.BLSPubKey) (map[spec.ValidatorIndex]*api.Validator, error) {
|
||||
return map[spec.ValidatorIndex]*api.Validator{
|
||||
0: _epochValidator(0,
|
||||
"0xa99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c",
|
||||
"0x00fad2a6bfb0e7f1f0f45460944fbd8dfa7f37da06a4d13b3983cc90bb46963b"),
|
||||
|
@ -742,14 +953,109 @@ func (m *ValidatorsWithoutBalanceProvider) Validators(ctx context.Context, state
|
|||
}
|
||||
|
||||
// ValidatorsWithoutBalance is a mock.
|
||||
func (m *ValidatorsWithoutBalanceProvider) ValidatorsWithoutBalance(ctx context.Context, stateID string, validators []eth2client.ValidatorIDProvider) (map[uint64]*api.Validator, error) {
|
||||
res, err := m.Validators(ctx, stateID, validators)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func (m *ValidatorsWithoutBalanceProvider) ValidatorsWithoutBalance(ctx context.Context, stateID string, validators []spec.ValidatorIndex) (map[spec.ValidatorIndex]*api.Validator, error) {
|
||||
res := map[spec.ValidatorIndex]*api.Validator{
|
||||
0: _epochValidator(0,
|
||||
"0xa99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c",
|
||||
"0x00fad2a6bfb0e7f1f0f45460944fbd8dfa7f37da06a4d13b3983cc90bb46963b"),
|
||||
1: _epochValidator(1,
|
||||
"0xb89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b",
|
||||
"0x00ec7ef7780c9d151597924036262dd28dc60e1228f4da6fecf9d402cb3f3594"),
|
||||
2: _epochValidator(2,
|
||||
"0xa3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b",
|
||||
"0x0036085c6c608e6d048505b04402568c36cce1e025722de44f9c3685a5c80fa6"),
|
||||
3: _epochValidator(3,
|
||||
"0x88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e",
|
||||
"0x005a7de495bcec04d3b5e74ae09ffe493a9dd06d7dcbf18c78455571e87d901a"),
|
||||
4: _epochValidator(4,
|
||||
"0x81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e",
|
||||
"0x004a28c193c65c91b7ebb5b5d14ffa7f75dc48ad4bc66de82f70fc55a2df1215"),
|
||||
5: _epochValidator(5,
|
||||
"0xab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34",
|
||||
"0x005856ab195b61df2ff5d6ab2fa36f30dab45e42cfa1aaef3ffd899f29bd8641"),
|
||||
6: _epochValidator(6,
|
||||
"0x9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373",
|
||||
"0x001c5d9bedbad1b7aff3b80e887e65b3357a695b70b6ee0625c2b2f6f86449f8"),
|
||||
7: _epochValidator(7,
|
||||
"0xa8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac",
|
||||
"0x001414bfc6dacca55f974ec910893c8617f9c99da897534c637b50e9fc695323"),
|
||||
8: _epochValidator(8,
|
||||
"0xa6d310dbbfab9a22450f59993f87a4ce5db6223f3b5f1f30d2c4ec718922d400e0b3c7741de8e59960f72411a0ee10a7",
|
||||
"0x00ed09b6181e6f97365e221e70aeebcb2604011d8c4326f3b98ce8d79b031ae8"),
|
||||
9: _epochValidator(9,
|
||||
"0x9893413c00283a3f9ed9fd9845dda1cea38228d22567f9541dccc357e54a2d6a6e204103c92564cbc05f4905ac7c493a",
|
||||
"0x001fe05baa70dd29ce85f694898bb6de3bcde158a825db56906b54141b2a728d"),
|
||||
10: _epochValidator(10,
|
||||
"0x876dd4705157eb66dc71bc2e07fb151ea53e1a62a0bb980a7ce72d15f58944a8a3752d754f52f4a60dbfc7b18169f268",
|
||||
"0x00aa2cfedd0160868d0901664e9d2eac1275dd658e109fabe11c7ad87a07fc0c"),
|
||||
11: _epochValidator(11,
|
||||
"0xaec922bd7a9b7b1dc21993133b586b0c3041c1e2e04b513e862227b9d7aecaf9444222f7e78282a449622ffc6278915d",
|
||||
"0x0076f08e6f40cf14992b7e4f524ea0cf7e1c6fd7dd5200b564c96fc099d601aa"),
|
||||
12: _epochValidator(12,
|
||||
"0x9314c6de0386635e2799af798884c2ea09c63b9f079e572acc00b06a7faccce501ea4dfc0b1a23b8603680a5e3481327",
|
||||
"0x004a581b2ef2b79652a19d3332f6574b0213ddbd179480edbf7ff490823fd5c7"),
|
||||
13: _epochValidator(13,
|
||||
"0x903e2989e7442ee0a8958d020507a8bd985d3974f5e8273093be00db3935f0500e141b252bd09e3728892c7a8443863c",
|
||||
"0x0040c37a4dafa560a7665394aa7502e113ecfbdb72c1ef92826db24601889b87"),
|
||||
14: _epochValidator(14,
|
||||
"0x84398f539a64cbe01cfcd8c485ea51cd6657b94df93ee9b5dc61e1f18f69da6ca9d4dba63c956a81c68d5d4d4277a60f",
|
||||
"0x0047381e2716b14a79e1f102669c615eb3542e9230ed7712b21f305ecc1a43d5"),
|
||||
15: _epochValidator(15,
|
||||
"0x872c61b4a7f8510ec809e5b023f5fdda2105d024c470ddbbeca4bc74e8280af0d178d749853e8f6a841083ac1b4db98f",
|
||||
"0x0020dd5f2223831fce8d1c8fd4148943c9917e1d3a92191651892dc56448451c"),
|
||||
16: _epochValidator(16,
|
||||
"0x8f467e5723deac7659e1ca273e28410cbaa6d495ab66ae77014f4cd21c64b6b5ab9987c9b5537fe0279bd063fe609be7",
|
||||
"0x00b24fc624e56a5ed42a9639691e27e34b783c7237030367bd17cbef65fa6ccf"),
|
||||
17: _epochValidator(17,
|
||||
"0x8dde8306920812b32def3b663f7c540b49180345d3bcb8d3770790b7dc80030ebc06497feebd1bcf017d918f00bfa88f",
|
||||
"0x0018e4071970526ed149970747c6b858307be8b60aa7440ad93c1f351af62923"),
|
||||
18: _epochValidator(18,
|
||||
"0xab8d3a9bcc160e518fac0756d3e192c74789588ed4a2b1debf0c78f78479ca8edb05b12ce21103076df6af4eb8756ff9",
|
||||
"0x00bb019106332edfed624b40e410561513e9fb9e285cbc56a450d499a2b13769"),
|
||||
19: _epochValidator(19,
|
||||
"0x8d5d3672a233db513df7ad1e8beafeae99a9f0199ed4d949bbedbb6f394030c0416bd99b910e14f73c65b6a11fe6b62e",
|
||||
"0x004218c29533321c9aae659d8b2148b87693d6b1eee8e119805e5298f8bf0a33"),
|
||||
20: _epochValidator(20,
|
||||
"0xa1c76af1545d7901214bb6be06be5d9e458f8e989c19373a920f0018327c83982f6a2ac138260b8def732cb366411ddc",
|
||||
"0x0004e3d99964ee8b0b6ed11833ba55fbf7bf80fe8f4e45c4d00a3d4ff6d73c0c"),
|
||||
21: _epochValidator(21,
|
||||
"0x8dd74e1bb5228fc1fca274fda02b971c1003a4f409bbdfbcfec6426bf2f52addcbbebccdbf45eee6ae11eb5b5ee7244d",
|
||||
"0x00037233059d7c629c79ddb7d94b0ef1275ebe55ed20fb80a414548be9ec890a"),
|
||||
22: _epochValidator(22,
|
||||
"0x954eb88ed1207f891dc3c28fa6cfdf8f53bf0ed3d838f3476c0900a61314d22d4f0a300da3cd010444dd5183e35a593c",
|
||||
"0x0056a7b95fd200d2997155b525eacda73baae3f3196a48fb9a513ddd1e7247c3"),
|
||||
23: _epochValidator(23,
|
||||
"0xaf344fce60dbd5fb850070e6e76a065e1a32485245ef4f413135a86ae703da88407c5d01c71f6bb06a151ff96cca7191",
|
||||
"0x005bdba6a856b0df016f8cbad0f9c02a517e2ff2f5db19187e6d1ba155d4b2e5"),
|
||||
24: _epochValidator(24,
|
||||
"0xae241af60691fda1cf8ca44d49573c55818c53b6141800cca2d488b9a3fba71c0f869179fff50c084657831fbeb42bf4",
|
||||
"0x000cc62d0bf911cfba5320da6e1d7407ff744427f74e855fc2444357788d6830"),
|
||||
25: _epochValidator(25,
|
||||
"0x96746aaba64dc87835ba709332f4d5d7837ada092b439c49d251aecf92aab5dc132e917bf6f59799bc093f976a7bc021",
|
||||
"0x006badd5d911c8565362da6e00dde8d2dda73fb9127d5ba26849ae0a0636172b"),
|
||||
26: _epochValidator(26,
|
||||
"0xb9d1d914df3d4565465c3fd52b5b96e637f9980570cabf5b5d4aadf5a329ac36ad672819d997e735f5052e28b1f0c104",
|
||||
"0x00f53dc973d5288e8070cf79ac0168443f3a2703e83f600e6197067aa02ca662"),
|
||||
27: _epochValidator(27,
|
||||
"0x963528adb5322c2e2c54dc296ffddd2861bb103cbf64646781dfa8a3c2d8a8eda7079d2b3e95600028c44365afbf8879",
|
||||
"0x00fa4e26953e907b1ed8032bdd02c9869dbbf521f3cb7bac1c8112ccf45c1d3a"),
|
||||
28: _epochValidator(28,
|
||||
"0xb245d63d3f9d8ea1807a629fcb1b328cb4d542f35a3d5bc478be0df389dddd712fc4c816ba3fede9a96320ae6b24a7d8",
|
||||
"0x00a68cdbfc1e865255d8e436d7bc7fc63c87b5c9c247c9e5de34d4fc26a1adc9"),
|
||||
29: _epochValidator(29,
|
||||
"0xa98ed496c2f464226500a6ce04602ff9ef133ed6316f372f6c744aee165149f7e578b12780e0eacec307ae6907351d99",
|
||||
"0x002f6d1f79f89a308365af4dbb8a850918db7844165b36e43c64e1a35b4af0b2"),
|
||||
30: _epochValidator(30,
|
||||
"0xae00fc3de831b09661a0ac02873c45c84cb2b58cffb6430a3f607e4c3fa1e0932397f11307cd169cdc6f79c463527260",
|
||||
"0x00e6ef2894304bc790c9e6b3a75815f10ceea391d8ebb9a27e07bf54360e9b3d"),
|
||||
31: _epochValidator(31,
|
||||
"0xa4855c83d868f772a579133d9f23818008417b743e8447e235d8eb78b1d8f8a9f63f98c551beb7de254400f89592314d",
|
||||
"0x0077c6a139204cbdaae840e0beb43b384c35182aabbc1104207b6a5a626fe75b"),
|
||||
}
|
||||
|
||||
for _, validator := range res {
|
||||
validator.Balance = 0
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ type parameters struct {
|
|||
randaoDomainProvider eth2client.RANDAODomainProvider
|
||||
selectionProofDomainProvider eth2client.SelectionProofDomainProvider
|
||||
aggregateAndProofDomainProvider eth2client.AggregateAndProofDomainProvider
|
||||
signatureDomainProvider eth2client.SignatureDomainProvider
|
||||
domainProvider eth2client.DomainProvider
|
||||
validatorsProvider eth2client.ValidatorsProvider
|
||||
}
|
||||
|
||||
|
@ -158,10 +158,10 @@ func WithAggregateAndProofDomainProvider(provider eth2client.AggregateAndProofDo
|
|||
})
|
||||
}
|
||||
|
||||
// WithSignatureDomainProvider sets the signature domain provider.
|
||||
func WithSignatureDomainProvider(provider eth2client.SignatureDomainProvider) Parameter {
|
||||
// WithDomainProvider sets the signature domain provider.
|
||||
func WithDomainProvider(provider eth2client.DomainProvider) Parameter {
|
||||
return parameterFunc(func(p *parameters) {
|
||||
p.signatureDomainProvider = provider
|
||||
p.domainProvider = provider
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -217,8 +217,8 @@ func parseAndCheckParameters(params ...Parameter) (*parameters, error) {
|
|||
if parameters.aggregateAndProofDomainProvider == nil {
|
||||
return nil, errors.New("no aggregate and proof domain provider specified")
|
||||
}
|
||||
if parameters.signatureDomainProvider == nil {
|
||||
return nil, errors.New("no signature domain provider specified")
|
||||
if parameters.domainProvider == nil {
|
||||
return nil, errors.New("no domain provider specified")
|
||||
}
|
||||
|
||||
return ¶meters, nil
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
|
||||
eth2client "github.com/attestantio/go-eth2-client"
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/attestantio/vouch/services/accountmanager"
|
||||
"github.com/attestantio/vouch/services/metrics"
|
||||
"github.com/pkg/errors"
|
||||
|
@ -39,21 +40,21 @@ import (
|
|||
|
||||
// Service is the manager for dirk accounts.
|
||||
type Service struct {
|
||||
mutex sync.RWMutex
|
||||
monitor metrics.AccountManagerMonitor
|
||||
clientMonitor metrics.ClientMonitor
|
||||
endpoints []*dirk.Endpoint
|
||||
accountPaths []string
|
||||
credentials credentials.TransportCredentials
|
||||
accounts map[[48]byte]*ValidatingAccount
|
||||
validatorsProvider eth2client.ValidatorsProvider
|
||||
slotsPerEpoch uint64
|
||||
beaconProposerDomain []byte
|
||||
beaconAttesterDomain []byte
|
||||
randaoDomain []byte
|
||||
selectionProofDomain []byte
|
||||
aggregateAndProofDomain []byte
|
||||
signatureDomainProvider eth2client.SignatureDomainProvider
|
||||
mutex sync.RWMutex
|
||||
monitor metrics.AccountManagerMonitor
|
||||
clientMonitor metrics.ClientMonitor
|
||||
endpoints []*dirk.Endpoint
|
||||
accountPaths []string
|
||||
credentials credentials.TransportCredentials
|
||||
accounts map[spec.BLSPubKey]*ValidatingAccount
|
||||
validatorsProvider eth2client.ValidatorsProvider
|
||||
slotsPerEpoch spec.Slot
|
||||
beaconProposerDomainType spec.DomainType
|
||||
beaconAttesterDomainType spec.DomainType
|
||||
randaoDomainType spec.DomainType
|
||||
selectionProofDomainType spec.DomainType
|
||||
aggregateAndProofDomainType spec.DomainType
|
||||
domainProvider eth2client.DomainProvider
|
||||
}
|
||||
|
||||
// module-wide log.
|
||||
|
@ -103,41 +104,41 @@ func New(ctx context.Context, params ...Parameter) (*Service, error) {
|
|||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain slots per epoch")
|
||||
}
|
||||
beaconAttesterDomain, err := parameters.beaconAttesterDomainProvider.BeaconAttesterDomain(ctx)
|
||||
beaconAttesterDomainType, err := parameters.beaconAttesterDomainProvider.BeaconAttesterDomain(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain beacon attester domain")
|
||||
}
|
||||
beaconProposerDomain, err := parameters.beaconProposerDomainProvider.BeaconProposerDomain(ctx)
|
||||
beaconProposerDomainType, err := parameters.beaconProposerDomainProvider.BeaconProposerDomain(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain beacon proposer domain")
|
||||
}
|
||||
randaoDomain, err := parameters.randaoDomainProvider.RANDAODomain(ctx)
|
||||
randaoDomainType, err := parameters.randaoDomainProvider.RANDAODomain(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain RANDAO domain")
|
||||
}
|
||||
selectionProofDomain, err := parameters.selectionProofDomainProvider.SelectionProofDomain(ctx)
|
||||
selectionProofDomainType, err := parameters.selectionProofDomainProvider.SelectionProofDomain(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain selection proof domain")
|
||||
}
|
||||
aggregateAndProofDomain, err := parameters.aggregateAndProofDomainProvider.AggregateAndProofDomain(ctx)
|
||||
aggregateAndProofDomainType, err := parameters.aggregateAndProofDomainProvider.AggregateAndProofDomain(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain aggregate and proof domain")
|
||||
}
|
||||
|
||||
s := &Service{
|
||||
monitor: parameters.monitor,
|
||||
clientMonitor: parameters.clientMonitor,
|
||||
endpoints: endpoints,
|
||||
accountPaths: parameters.accountPaths,
|
||||
credentials: credentials,
|
||||
slotsPerEpoch: slotsPerEpoch,
|
||||
beaconAttesterDomain: beaconAttesterDomain,
|
||||
beaconProposerDomain: beaconProposerDomain,
|
||||
randaoDomain: randaoDomain,
|
||||
selectionProofDomain: selectionProofDomain,
|
||||
aggregateAndProofDomain: aggregateAndProofDomain,
|
||||
signatureDomainProvider: parameters.signatureDomainProvider,
|
||||
validatorsProvider: parameters.validatorsProvider,
|
||||
monitor: parameters.monitor,
|
||||
clientMonitor: parameters.clientMonitor,
|
||||
endpoints: endpoints,
|
||||
accountPaths: parameters.accountPaths,
|
||||
credentials: credentials,
|
||||
slotsPerEpoch: spec.Slot(slotsPerEpoch),
|
||||
beaconAttesterDomainType: beaconAttesterDomainType,
|
||||
beaconProposerDomainType: beaconProposerDomainType,
|
||||
randaoDomainType: randaoDomainType,
|
||||
selectionProofDomainType: selectionProofDomainType,
|
||||
aggregateAndProofDomainType: aggregateAndProofDomainType,
|
||||
domainProvider: parameters.domainProvider,
|
||||
validatorsProvider: parameters.validatorsProvider,
|
||||
}
|
||||
|
||||
if err := s.RefreshAccounts(ctx); err != nil {
|
||||
|
@ -150,23 +151,24 @@ func New(ctx context.Context, params ...Parameter) (*Service, error) {
|
|||
// UpdateAccountsState updates account state with the latest information from the beacon chain.
|
||||
// This should be run at the beginning of each epoch to ensure that any newly-activated accounts are registered.
|
||||
func (s *Service) UpdateAccountsState(ctx context.Context) error {
|
||||
validatorIDs := make([]eth2client.ValidatorIDProvider, 0, len(s.accounts))
|
||||
validatorIDProviders := make([]eth2client.ValidatorIDProvider, 0, len(s.accounts))
|
||||
for _, account := range s.accounts {
|
||||
if !account.state.HasActivated() {
|
||||
validatorIDs = append(validatorIDs, account)
|
||||
validatorIDProviders = append(validatorIDProviders, account)
|
||||
}
|
||||
}
|
||||
if len(validatorIDs) == 0 {
|
||||
if len(validatorIDProviders) == 0 {
|
||||
// Nothing to do.
|
||||
log.Trace().Msg("No unactivated keys")
|
||||
return nil
|
||||
}
|
||||
log.Trace().Int("total", len(s.accounts)).Int("unactivated", len(validatorIDs)).Msg("Updating state of unactivated keys")
|
||||
var validators map[uint64]*api.Validator
|
||||
// TODO unactivated validators can have an index of 0, so cannot send via an API call that is by index. Need to use bypubkeys.
|
||||
log.Trace().Int("total", len(s.accounts)).Int("unactivated", len(validatorIDProviders)).Msg("Updating state of unactivated keys")
|
||||
var validators map[spec.ValidatorIndex]*api.Validator
|
||||
var err error
|
||||
if validatorsWithoutBalanceProvider, isProvider := s.validatorsProvider.(eth2client.ValidatorsWithoutBalanceProvider); isProvider {
|
||||
started := time.Now()
|
||||
validators, err = validatorsWithoutBalanceProvider.ValidatorsWithoutBalance(ctx, "head", validatorIDs)
|
||||
validators, err = validatorsWithoutBalanceProvider.ValidatorsWithoutBalance(ctx, "head", validatorIDProviders)
|
||||
if service, isService := s.validatorsProvider.(eth2client.Service); isService {
|
||||
s.clientMonitor.ClientOperation(service.Address(), "validators without balance", err == nil, time.Since(started))
|
||||
} else {
|
||||
|
@ -177,6 +179,16 @@ func (s *Service) UpdateAccountsState(ctx context.Context) error {
|
|||
}
|
||||
} else {
|
||||
started := time.Now()
|
||||
validatorIDs := make([]spec.ValidatorIndex, 0, len(s.accounts))
|
||||
for _, account := range s.accounts {
|
||||
if !account.state.HasActivated() {
|
||||
index, err := account.Index(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to obtain account index")
|
||||
}
|
||||
validatorIDs = append(validatorIDs, index)
|
||||
}
|
||||
}
|
||||
validators, err = s.validatorsProvider.Validators(ctx, "head", validatorIDs)
|
||||
if service, isService := s.validatorsProvider.(eth2client.Service); isService {
|
||||
s.clientMonitor.ClientOperation(service.Address(), "validators", err == nil, time.Since(started))
|
||||
|
@ -220,7 +232,7 @@ func (s *Service) RefreshAccounts(ctx context.Context) error {
|
|||
|
||||
verificationRegexes := accountPathsToVerificationRegexes(s.accountPaths)
|
||||
// Fetch accounts for each wallet.
|
||||
accounts := make(map[[48]byte]*ValidatingAccount)
|
||||
accounts := make(map[spec.BLSPubKey]*ValidatingAccount)
|
||||
for _, wallet := range wallets {
|
||||
// if _, isProvider := wallet.(e2wtypes.WalletAccountsByPathProvider); isProvider {
|
||||
// fmt.Printf("TODO: fetch accounts by path")
|
||||
|
@ -229,32 +241,44 @@ func (s *Service) RefreshAccounts(ctx context.Context) error {
|
|||
//}
|
||||
}
|
||||
|
||||
validatorIDs := make([]eth2client.ValidatorIDProvider, 0, len(accounts))
|
||||
// Update indices for accounts.
|
||||
pubKeys := make([]spec.BLSPubKey, 0, len(accounts))
|
||||
for _, account := range accounts {
|
||||
if !account.state.IsAttesting() {
|
||||
validatorIDs = append(validatorIDs, account)
|
||||
pubKey, err := account.PubKey(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to obtain public key")
|
||||
}
|
||||
pubKeys = append(pubKeys, pubKey)
|
||||
}
|
||||
log.Trace().Int("keys", len(accounts)).Msg("Keys obtained")
|
||||
if len(validatorIDs) == 0 {
|
||||
log.Warn().Msg("No accounts obtained")
|
||||
return nil
|
||||
validators, err := s.validatorsProvider.ValidatorsByPubKey(ctx, "head", pubKeys)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to obtain validators")
|
||||
}
|
||||
|
||||
log.Trace().Int("accounts", len(validatorIDs)).Msg("Obtaining validator state of accounts")
|
||||
var validators map[uint64]*api.Validator
|
||||
var err error
|
||||
if validatorsWithoutBalanceProvider, isProvider := s.validatorsProvider.(eth2client.ValidatorsWithoutBalanceProvider); isProvider {
|
||||
validators, err = validatorsWithoutBalanceProvider.ValidatorsWithoutBalance(ctx, "head", validatorIDs)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to obtain validators without balances")
|
||||
}
|
||||
} else {
|
||||
validators, err = s.validatorsProvider.Validators(ctx, "head", validatorIDs)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to obtain validators")
|
||||
}
|
||||
}
|
||||
// log.Trace().Int("accounts", len(validatorIDProviders)).Msg("Obtaining validator state of accounts")
|
||||
// var validators map[uint64]*api.Validator
|
||||
// var err error
|
||||
// if validatorsWithoutBalanceProvider, isProvider := s.validatorsProvider.(eth2client.ValidatorsWithoutBalanceProvider); isProvider {
|
||||
// validators, err = validatorsWithoutBalanceProvider.ValidatorsWithoutBalance(ctx, "head", validatorIDProviders)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(err, "failed to obtain validators without balances")
|
||||
// }
|
||||
// } else {
|
||||
// validatorIDs := make([]uint64, 0, len(s.accounts))
|
||||
// for _, account := range s.accounts {
|
||||
// if !account.state.IsAttesting() {
|
||||
// index, err := account.Index(ctx)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(err, "failed to obtain account index")
|
||||
// }
|
||||
// validatorIDs = append(validatorIDs, index)
|
||||
// }
|
||||
// }
|
||||
// validators, err = s.validatorsProvider.Validators(ctx, "head", validatorIDs)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(err, "failed to obtain validators")
|
||||
// }
|
||||
// }
|
||||
log.Trace().Int("received", len(validators)).Msg("Received state of accounts")
|
||||
|
||||
s.updateAccountStates(ctx, accounts, validators)
|
||||
|
@ -304,8 +328,8 @@ func (s *Service) Accounts(ctx context.Context) ([]accountmanager.ValidatingAcco
|
|||
}
|
||||
|
||||
// AccountsByIndex returns attesting accounts.
|
||||
func (s *Service) AccountsByIndex(ctx context.Context, indices []uint64) ([]accountmanager.ValidatingAccount, error) {
|
||||
indexMap := make(map[uint64]bool)
|
||||
func (s *Service) AccountsByIndex(ctx context.Context, indices []spec.ValidatorIndex) ([]accountmanager.ValidatingAccount, error) {
|
||||
indexMap := make(map[spec.ValidatorIndex]bool)
|
||||
for _, index := range indices {
|
||||
indexMap[index] = true
|
||||
}
|
||||
|
@ -333,12 +357,10 @@ func (s *Service) AccountsByIndex(ctx context.Context, indices []uint64) ([]acco
|
|||
}
|
||||
|
||||
// AccountsByPubKey returns validating accounts.
|
||||
func (s *Service) AccountsByPubKey(ctx context.Context, pubKeys [][]byte) ([]accountmanager.ValidatingAccount, error) {
|
||||
pubKeyMap := make(map[[48]byte]bool)
|
||||
func (s *Service) AccountsByPubKey(ctx context.Context, pubKeys []spec.BLSPubKey) ([]accountmanager.ValidatingAccount, error) {
|
||||
pubKeyMap := make(map[spec.BLSPubKey]bool)
|
||||
for _, pubKey := range pubKeys {
|
||||
var mapKey [48]byte
|
||||
copy(mapKey[:], pubKey)
|
||||
pubKeyMap[mapKey] = true
|
||||
pubKeyMap[pubKey] = true
|
||||
}
|
||||
|
||||
s.mutex.RLock()
|
||||
|
@ -388,19 +410,17 @@ func accountPathsToVerificationRegexes(paths []string) []*regexp.Regexp {
|
|||
return regexes
|
||||
}
|
||||
|
||||
func (s *Service) updateAccountStates(ctx context.Context, accounts map[[48]byte]*ValidatingAccount, validators map[uint64]*api.Validator) {
|
||||
func (s *Service) updateAccountStates(ctx context.Context, accounts map[spec.BLSPubKey]*ValidatingAccount, validators map[spec.ValidatorIndex]*api.Validator) {
|
||||
validatorsByPubKey := make(map[[48]byte]*api.Validator, len(validators))
|
||||
for _, validator := range validators {
|
||||
var pubKey [48]byte
|
||||
copy(pubKey[:], validator.Validator.PublicKey)
|
||||
validatorsByPubKey[pubKey] = validator
|
||||
validatorsByPubKey[validator.Validator.PublicKey] = validator
|
||||
}
|
||||
|
||||
validatorStateCounts := make(map[string]uint64)
|
||||
for pubKey, account := range accounts {
|
||||
if validator, exists := validatorsByPubKey[pubKey]; exists {
|
||||
account.index = validator.Index
|
||||
account.state = validator.State
|
||||
account.state = validator.Status
|
||||
}
|
||||
validatorStateCounts[strings.ToLower(account.state.String())]++
|
||||
}
|
||||
|
@ -419,7 +439,7 @@ func (s *Service) updateAccountStates(ctx context.Context, accounts map[[48]byte
|
|||
}
|
||||
}
|
||||
|
||||
func (s *Service) fetchAccountsForWallet(ctx context.Context, wallet e2wtypes.Wallet, accounts map[[48]byte]*ValidatingAccount, verificationRegexes []*regexp.Regexp) {
|
||||
func (s *Service) fetchAccountsForWallet(ctx context.Context, wallet e2wtypes.Wallet, accounts map[spec.BLSPubKey]*ValidatingAccount, verificationRegexes []*regexp.Regexp) {
|
||||
for account := range wallet.Accounts(ctx) {
|
||||
// Ensure the name matches one of our account paths.
|
||||
name := fmt.Sprintf("%s/%s", wallet.Name(), account.Name())
|
||||
|
@ -444,9 +464,9 @@ func (s *Service) fetchAccountsForWallet(ctx context.Context, wallet e2wtypes.Wa
|
|||
|
||||
// Set up account as unknown to beacon chain.
|
||||
accounts[bytesutil.ToBytes48(pubKey)] = &ValidatingAccount{
|
||||
account: account,
|
||||
accountManager: s,
|
||||
signatureDomainProvider: s.signatureDomainProvider,
|
||||
account: account,
|
||||
accountManager: s,
|
||||
domainProvider: s.domainProvider,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
|
||||
"github.com/attestantio/dirk/testing/daemon"
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/attestantio/vouch/mock"
|
||||
nullmetrics "github.com/attestantio/vouch/services/metrics/null"
|
||||
"github.com/attestantio/vouch/testing/logger"
|
||||
|
@ -57,9 +58,9 @@ func TestFetchAccountsForWallet(t *testing.T) {
|
|||
// Test with wallet regex.
|
||||
s, err := setupService(ctx, t, []string{"localhost:12345"}, []string{"wallet1", "wallet2"})
|
||||
require.NoError(t, err)
|
||||
validatingAccounts := make(map[[48]byte]*ValidatingAccount)
|
||||
validatingAccounts := make(map[spec.BLSPubKey]*ValidatingAccount)
|
||||
for account := range wallets[0].Accounts(ctx) {
|
||||
var key [48]byte
|
||||
var key spec.BLSPubKey
|
||||
copy(key[:], account.PublicKey().Marshal())
|
||||
validatingAccounts[key] = &ValidatingAccount{
|
||||
account: account,
|
||||
|
@ -76,9 +77,9 @@ func TestFetchAccountsForWallet(t *testing.T) {
|
|||
capture := logger.NewLogCapture()
|
||||
s, err = setupService(ctx, t, []string{"localhost:12345"}, []string{"wallet1", "wallet2"})
|
||||
require.NoError(t, err)
|
||||
validatingAccounts = make(map[[48]byte]*ValidatingAccount)
|
||||
validatingAccounts = make(map[spec.BLSPubKey]*ValidatingAccount)
|
||||
for account := range wallets[0].Accounts(ctx) {
|
||||
var key [48]byte
|
||||
var key spec.BLSPubKey
|
||||
copy(key[:], account.PublicKey().Marshal())
|
||||
validatingAccounts[key] = &ValidatingAccount{
|
||||
account: account,
|
||||
|
@ -180,7 +181,7 @@ func TestAccountPathsToVerificationRegexes(t *testing.T) {
|
|||
func TestAccounts(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
accounts map[[48]byte]*ValidatingAccount
|
||||
accounts map[spec.BLSPubKey]*ValidatingAccount
|
||||
expected int
|
||||
}{
|
||||
{
|
||||
|
@ -260,7 +261,7 @@ func TestUpdateAccountsStateWithoutBalances(t *testing.T) {
|
|||
WithRANDAODomainProvider(mock.NewRANDAODomainProvider()),
|
||||
WithSelectionProofDomainProvider(mock.NewSelectionProofDomainProvider()),
|
||||
WithAggregateAndProofDomainProvider(mock.NewAggregateAndProofDomainProvider()),
|
||||
WithSignatureDomainProvider(mock.NewSignatureDomainProvider()),
|
||||
WithDomainProvider(mock.NewDomainProvider()),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
accounts, err := s.Accounts(ctx)
|
||||
|
@ -301,7 +302,7 @@ func setupService(ctx context.Context, t *testing.T, endpoints []string, account
|
|||
WithRANDAODomainProvider(mock.NewRANDAODomainProvider()),
|
||||
WithSelectionProofDomainProvider(mock.NewSelectionProofDomainProvider()),
|
||||
WithAggregateAndProofDomainProvider(mock.NewAggregateAndProofDomainProvider()),
|
||||
WithSignatureDomainProvider(mock.NewSignatureDomainProvider()),
|
||||
WithDomainProvider(mock.NewDomainProvider()),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -23,11 +23,13 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/attestantio/dirk/testing/daemon"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/attestantio/vouch/mock"
|
||||
"github.com/attestantio/vouch/services/accountmanager/dirk"
|
||||
nullmetrics "github.com/attestantio/vouch/services/metrics/null"
|
||||
"github.com/attestantio/vouch/testing/logger"
|
||||
"github.com/attestantio/vouch/testing/resources"
|
||||
"github.com/attestantio/vouch/testutil"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
@ -37,6 +39,36 @@ func _byte(input string) []byte {
|
|||
return res
|
||||
}
|
||||
|
||||
func _root(input string) spec.Root {
|
||||
res, err := hex.DecodeString(strings.TrimPrefix(input, "0x"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var root spec.Root
|
||||
copy(root[:], res)
|
||||
return root
|
||||
}
|
||||
|
||||
func _sig(input string) spec.BLSSignature {
|
||||
res, err := hex.DecodeString(strings.TrimPrefix(input, "0x"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var sig spec.BLSSignature
|
||||
copy(sig[:], res)
|
||||
return sig
|
||||
}
|
||||
|
||||
func _pubKey(input string) spec.BLSPubKey {
|
||||
res, err := hex.DecodeString(strings.TrimPrefix(input, "0x"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var pubKey spec.BLSPubKey
|
||||
copy(pubKey[:], res)
|
||||
return pubKey
|
||||
}
|
||||
|
||||
func TestService(t *testing.T) {
|
||||
slotsPerEpochProvider := mock.NewSlotsPerEpochProvider(32)
|
||||
beaconProposerDomainProvider := mock.NewBeaconProposerDomainProvider()
|
||||
|
@ -44,7 +76,7 @@ func TestService(t *testing.T) {
|
|||
randaoDomainProvider := mock.NewRANDAODomainProvider()
|
||||
selectionProofDomainProvider := mock.NewSelectionProofDomainProvider()
|
||||
aggregateAndProofDomainProvider := mock.NewAggregateAndProofDomainProvider()
|
||||
signatureDomainProvider := mock.NewSignatureDomainProvider()
|
||||
domainProvider := mock.NewDomainProvider()
|
||||
validatorsProvider := mock.NewValidatorsProvider()
|
||||
|
||||
tests := []struct {
|
||||
|
@ -71,7 +103,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "problem with parameters: no monitor specified",
|
||||
},
|
||||
|
@ -93,7 +125,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "problem with parameters: no client monitor specified",
|
||||
},
|
||||
|
@ -114,7 +146,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "problem with parameters: no endpoints specified",
|
||||
},
|
||||
|
@ -136,7 +168,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "problem with parameters: no endpoints specified",
|
||||
},
|
||||
|
@ -158,7 +190,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "no valid endpoints specified",
|
||||
logEntry: "Malformed endpoint",
|
||||
|
@ -181,7 +213,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "no valid endpoints specified",
|
||||
logEntry: "Malformed port",
|
||||
|
@ -204,7 +236,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "no valid endpoints specified",
|
||||
logEntry: "Invalid port",
|
||||
|
@ -226,7 +258,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "problem with parameters: no account paths specified",
|
||||
},
|
||||
|
@ -248,7 +280,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "problem with parameters: no account paths specified",
|
||||
},
|
||||
|
@ -269,7 +301,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "problem with parameters: no client certificate specified",
|
||||
},
|
||||
|
@ -290,7 +322,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "problem with parameters: no client key specified",
|
||||
},
|
||||
|
@ -312,7 +344,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "failed to build credentials: failed to load client keypair: tls: private key does not match public key",
|
||||
},
|
||||
|
@ -333,7 +365,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "problem with parameters: no validators provider specified",
|
||||
},
|
||||
|
@ -354,7 +386,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "problem with parameters: no slots per epoch provider specified",
|
||||
},
|
||||
|
@ -376,7 +408,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "failed to obtain slots per epoch: error",
|
||||
},
|
||||
|
@ -397,7 +429,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "problem with parameters: no beacon proposer domain provider specified",
|
||||
},
|
||||
|
@ -419,7 +451,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "failed to obtain beacon proposer domain: error",
|
||||
},
|
||||
|
@ -440,7 +472,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "problem with parameters: no beacon attester domain provider specified",
|
||||
},
|
||||
|
@ -462,7 +494,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "failed to obtain beacon attester domain: error",
|
||||
},
|
||||
|
@ -483,7 +515,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithBeaconAttesterDomainProvider(beaconAttesterDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "problem with parameters: no RANDAO domain provider specified",
|
||||
},
|
||||
|
@ -505,7 +537,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(mock.NewErroringRANDAODomainProvider()),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "failed to obtain RANDAO domain: error",
|
||||
},
|
||||
|
@ -526,7 +558,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithBeaconAttesterDomainProvider(beaconAttesterDomainProvider),
|
||||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "problem with parameters: no selection proof domain provider specified",
|
||||
},
|
||||
|
@ -548,7 +580,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(mock.NewErroringSelectionProofDomainProvider()),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "failed to obtain selection proof domain: error",
|
||||
},
|
||||
|
@ -569,7 +601,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithBeaconAttesterDomainProvider(beaconAttesterDomainProvider),
|
||||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "problem with parameters: no aggregate and proof domain provider specified",
|
||||
},
|
||||
|
@ -591,12 +623,12 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(mock.NewErroringAggregateAndProofDomainProvider()),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
err: "failed to obtain aggregate and proof domain: error",
|
||||
},
|
||||
{
|
||||
name: "SignatureDomainProviderMissing",
|
||||
name: "DomainProviderMissing",
|
||||
params: []dirk.Parameter{
|
||||
dirk.WithLogLevel(zerolog.TraceLevel),
|
||||
dirk.WithMonitor(nullmetrics.New(context.Background())),
|
||||
|
@ -614,7 +646,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
},
|
||||
err: "problem with parameters: no signature domain provider specified",
|
||||
err: "problem with parameters: no domain provider specified",
|
||||
},
|
||||
{
|
||||
name: "Good",
|
||||
|
@ -634,7 +666,7 @@ func TestService(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(randaoDomainProvider),
|
||||
dirk.WithSelectionProofDomainProvider(selectionProofDomainProvider),
|
||||
dirk.WithAggregateAndProofDomainProvider(aggregateAndProofDomainProvider),
|
||||
dirk.WithSignatureDomainProvider(signatureDomainProvider),
|
||||
dirk.WithDomainProvider(domainProvider),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -705,7 +737,7 @@ func TestAccounts(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(mock.NewRANDAODomainProvider()),
|
||||
dirk.WithSelectionProofDomainProvider(mock.NewSelectionProofDomainProvider()),
|
||||
dirk.WithAggregateAndProofDomainProvider(mock.NewAggregateAndProofDomainProvider()),
|
||||
dirk.WithSignatureDomainProvider(mock.NewSignatureDomainProvider()),
|
||||
dirk.WithDomainProvider(mock.NewDomainProvider()),
|
||||
)
|
||||
require.Nil(t, err)
|
||||
|
||||
|
@ -728,7 +760,7 @@ func TestAccountsByIndex(t *testing.T) {
|
|||
|
||||
tests := []struct {
|
||||
name string
|
||||
indices []uint64
|
||||
indices []spec.ValidatorIndex
|
||||
accounts int
|
||||
}{
|
||||
{
|
||||
|
@ -737,17 +769,17 @@ func TestAccountsByIndex(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "Empty",
|
||||
indices: []uint64{},
|
||||
indices: []spec.ValidatorIndex{},
|
||||
accounts: 0,
|
||||
},
|
||||
{
|
||||
name: "All",
|
||||
indices: []uint64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
||||
indices: []spec.ValidatorIndex{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
||||
accounts: 16,
|
||||
},
|
||||
{
|
||||
name: "Missing",
|
||||
indices: []uint64{15, 16},
|
||||
indices: []spec.ValidatorIndex{15, 16},
|
||||
accounts: 1,
|
||||
},
|
||||
}
|
||||
|
@ -770,7 +802,7 @@ func TestAccountsByIndex(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(mock.NewRANDAODomainProvider()),
|
||||
dirk.WithSelectionProofDomainProvider(mock.NewSelectionProofDomainProvider()),
|
||||
dirk.WithAggregateAndProofDomainProvider(mock.NewAggregateAndProofDomainProvider()),
|
||||
dirk.WithSignatureDomainProvider(mock.NewSignatureDomainProvider()),
|
||||
dirk.WithDomainProvider(mock.NewDomainProvider()),
|
||||
)
|
||||
require.Nil(t, err)
|
||||
|
||||
|
@ -793,7 +825,7 @@ func TestAccountsByPubKey(t *testing.T) {
|
|||
|
||||
tests := []struct {
|
||||
name string
|
||||
pubKeys [][]byte
|
||||
pubKeys []spec.BLSPubKey
|
||||
accounts int
|
||||
}{
|
||||
{
|
||||
|
@ -802,38 +834,38 @@ func TestAccountsByPubKey(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "Empty",
|
||||
pubKeys: [][]byte{
|
||||
_byte(""),
|
||||
pubKeys: []spec.BLSPubKey{
|
||||
{},
|
||||
},
|
||||
accounts: 0,
|
||||
},
|
||||
{
|
||||
name: "All",
|
||||
pubKeys: [][]byte{
|
||||
_byte("0xa99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c"),
|
||||
_byte("0xb89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b"),
|
||||
_byte("0xa3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b"),
|
||||
_byte("0x88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e"),
|
||||
_byte("0x81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e"),
|
||||
_byte("0xab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34"),
|
||||
_byte("0x9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373"),
|
||||
_byte("0xa8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac"),
|
||||
_byte("0xa6d310dbbfab9a22450f59993f87a4ce5db6223f3b5f1f30d2c4ec718922d400e0b3c7741de8e59960f72411a0ee10a7"),
|
||||
_byte("0x9893413c00283a3f9ed9fd9845dda1cea38228d22567f9541dccc357e54a2d6a6e204103c92564cbc05f4905ac7c493a"),
|
||||
_byte("0x876dd4705157eb66dc71bc2e07fb151ea53e1a62a0bb980a7ce72d15f58944a8a3752d754f52f4a60dbfc7b18169f268"),
|
||||
_byte("0xaec922bd7a9b7b1dc21993133b586b0c3041c1e2e04b513e862227b9d7aecaf9444222f7e78282a449622ffc6278915d"),
|
||||
_byte("0x9314c6de0386635e2799af798884c2ea09c63b9f079e572acc00b06a7faccce501ea4dfc0b1a23b8603680a5e3481327"),
|
||||
_byte("0x903e2989e7442ee0a8958d020507a8bd985d3974f5e8273093be00db3935f0500e141b252bd09e3728892c7a8443863c"),
|
||||
_byte("0x84398f539a64cbe01cfcd8c485ea51cd6657b94df93ee9b5dc61e1f18f69da6ca9d4dba63c956a81c68d5d4d4277a60f"),
|
||||
_byte("0x872c61b4a7f8510ec809e5b023f5fdda2105d024c470ddbbeca4bc74e8280af0d178d749853e8f6a841083ac1b4db98f"),
|
||||
pubKeys: []spec.BLSPubKey{
|
||||
testutil.HexToPubKey("0xa99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c"),
|
||||
testutil.HexToPubKey("0xb89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b"),
|
||||
testutil.HexToPubKey("0xa3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b"),
|
||||
testutil.HexToPubKey("0x88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e"),
|
||||
testutil.HexToPubKey("0x81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e"),
|
||||
testutil.HexToPubKey("0xab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34"),
|
||||
testutil.HexToPubKey("0x9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373"),
|
||||
testutil.HexToPubKey("0xa8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac"),
|
||||
testutil.HexToPubKey("0xa6d310dbbfab9a22450f59993f87a4ce5db6223f3b5f1f30d2c4ec718922d400e0b3c7741de8e59960f72411a0ee10a7"),
|
||||
testutil.HexToPubKey("0x9893413c00283a3f9ed9fd9845dda1cea38228d22567f9541dccc357e54a2d6a6e204103c92564cbc05f4905ac7c493a"),
|
||||
testutil.HexToPubKey("0x876dd4705157eb66dc71bc2e07fb151ea53e1a62a0bb980a7ce72d15f58944a8a3752d754f52f4a60dbfc7b18169f268"),
|
||||
testutil.HexToPubKey("0xaec922bd7a9b7b1dc21993133b586b0c3041c1e2e04b513e862227b9d7aecaf9444222f7e78282a449622ffc6278915d"),
|
||||
testutil.HexToPubKey("0x9314c6de0386635e2799af798884c2ea09c63b9f079e572acc00b06a7faccce501ea4dfc0b1a23b8603680a5e3481327"),
|
||||
testutil.HexToPubKey("0x903e2989e7442ee0a8958d020507a8bd985d3974f5e8273093be00db3935f0500e141b252bd09e3728892c7a8443863c"),
|
||||
testutil.HexToPubKey("0x84398f539a64cbe01cfcd8c485ea51cd6657b94df93ee9b5dc61e1f18f69da6ca9d4dba63c956a81c68d5d4d4277a60f"),
|
||||
testutil.HexToPubKey("0x872c61b4a7f8510ec809e5b023f5fdda2105d024c470ddbbeca4bc74e8280af0d178d749853e8f6a841083ac1b4db98f"),
|
||||
},
|
||||
accounts: 16,
|
||||
},
|
||||
{
|
||||
name: "Missing",
|
||||
pubKeys: [][]byte{
|
||||
_byte("0x872c61b4a7f8510ec809e5b023f5fdda2105d024c470ddbbeca4bc74e8280af0d178d749853e8f6a841083ac1b4db98f"),
|
||||
_byte("0x8f467e5723deac7659e1ca273e28410cbaa6d495ab66ae77014f4cd21c64b6b5ab9987c9b5537fe0279bd063fe609be7"),
|
||||
pubKeys: []spec.BLSPubKey{
|
||||
testutil.HexToPubKey("0x872c61b4a7f8510ec809e5b023f5fdda2105d024c470ddbbeca4bc74e8280af0d178d749853e8f6a841083ac1b4db98f"),
|
||||
testutil.HexToPubKey("0x8f467e5723deac7659e1ca273e28410cbaa6d495ab66ae77014f4cd21c64b6b5ab9987c9b5537fe0279bd063fe609be7"),
|
||||
},
|
||||
accounts: 1,
|
||||
},
|
||||
|
@ -857,7 +889,7 @@ func TestAccountsByPubKey(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(mock.NewRANDAODomainProvider()),
|
||||
dirk.WithSelectionProofDomainProvider(mock.NewSelectionProofDomainProvider()),
|
||||
dirk.WithAggregateAndProofDomainProvider(mock.NewAggregateAndProofDomainProvider()),
|
||||
dirk.WithSignatureDomainProvider(mock.NewSignatureDomainProvider()),
|
||||
dirk.WithDomainProvider(mock.NewDomainProvider()),
|
||||
)
|
||||
require.Nil(t, err)
|
||||
|
||||
|
|
|
@ -19,30 +19,33 @@ import (
|
|||
|
||||
eth2client "github.com/attestantio/go-eth2-client"
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
"github.com/opentracing/opentracing-go"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/pkg/errors"
|
||||
e2wtypes "github.com/wealdtech/go-eth2-wallet-types/v2"
|
||||
)
|
||||
|
||||
// ValidatingAccount is a wrapper around the dirk account that implements ValidatingAccount.
|
||||
type ValidatingAccount struct {
|
||||
account e2wtypes.Account
|
||||
index uint64
|
||||
state api.ValidatorState
|
||||
accountManager *Service
|
||||
signatureDomainProvider eth2client.SignatureDomainProvider
|
||||
account e2wtypes.Account
|
||||
index spec.ValidatorIndex
|
||||
state api.ValidatorState
|
||||
accountManager *Service
|
||||
domainProvider eth2client.DomainProvider
|
||||
}
|
||||
|
||||
// PubKey returns the public key of the validating account.
|
||||
func (d *ValidatingAccount) PubKey(ctx context.Context) ([]byte, error) {
|
||||
func (d *ValidatingAccount) PubKey(ctx context.Context) (spec.BLSPubKey, error) {
|
||||
var pubKey spec.BLSPubKey
|
||||
if provider, isProvider := d.account.(e2wtypes.AccountCompositePublicKeyProvider); isProvider {
|
||||
return provider.CompositePublicKey().Marshal(), nil
|
||||
copy(pubKey[:], provider.CompositePublicKey().Marshal())
|
||||
} else {
|
||||
copy(pubKey[:], d.account.PublicKey().Marshal())
|
||||
}
|
||||
return d.account.PublicKey().Marshal(), nil
|
||||
return pubKey, nil
|
||||
}
|
||||
|
||||
// Index returns the index of the validating account.
|
||||
func (d *ValidatingAccount) Index(ctx context.Context) (uint64, error) {
|
||||
func (d *ValidatingAccount) Index(ctx context.Context) (spec.ValidatorIndex, error) {
|
||||
return d.index, nil
|
||||
}
|
||||
|
||||
|
@ -53,133 +56,142 @@ func (d *ValidatingAccount) State() api.ValidatorState {
|
|||
|
||||
// SignSlotSelection returns a slot selection signature.
|
||||
// This signs a slot with the "selection proof" domain.
|
||||
func (d *ValidatingAccount) SignSlotSelection(ctx context.Context, slot uint64) ([]byte, error) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "dirk.SignSlotSelection")
|
||||
defer span.Finish()
|
||||
func (d *ValidatingAccount) SignSlotSelection(ctx context.Context, slot spec.Slot) (spec.BLSSignature, error) {
|
||||
var messageRoot spec.Root
|
||||
binary.LittleEndian.PutUint64(messageRoot[:], uint64(slot))
|
||||
|
||||
// Calculate the signature domain.
|
||||
signatureDomain, err := d.signatureDomainProvider.SignatureDomain(ctx,
|
||||
d.accountManager.selectionProofDomain,
|
||||
slot/d.accountManager.slotsPerEpoch)
|
||||
// Calculate the domain.
|
||||
domain, err := d.domainProvider.Domain(ctx,
|
||||
d.accountManager.selectionProofDomainType,
|
||||
spec.Epoch(slot/d.accountManager.slotsPerEpoch))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain signature domain for selection proof")
|
||||
return spec.BLSSignature{}, errors.Wrap(err, "failed to obtain signature domain for selection proof")
|
||||
}
|
||||
|
||||
slotBytes := make([]byte, 32)
|
||||
binary.LittleEndian.PutUint64(slotBytes, slot)
|
||||
binary.LittleEndian.PutUint64(slotBytes, uint64(slot))
|
||||
|
||||
sig, err := d.account.(e2wtypes.AccountProtectingSigner).SignGeneric(ctx, slotBytes, signatureDomain)
|
||||
sig, err := d.account.(e2wtypes.AccountProtectingSigner).SignGeneric(ctx, slotBytes, domain[:])
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to sign slot")
|
||||
return spec.BLSSignature{}, errors.Wrap(err, "failed to sign slot")
|
||||
}
|
||||
return sig.Marshal(), nil
|
||||
|
||||
var signature spec.BLSSignature
|
||||
copy(signature[:], sig.Marshal())
|
||||
return signature, nil
|
||||
}
|
||||
|
||||
// SignRANDAOReveal returns a RANDAO reveal signature.
|
||||
// This signs an epoch with the "RANDAO reveal" domain.
|
||||
// N.B. This passes in a slot, not an epoch.
|
||||
func (d *ValidatingAccount) SignRANDAOReveal(ctx context.Context, slot uint64) ([]byte, error) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "dirk.SignRANDAOReveal")
|
||||
defer span.Finish()
|
||||
func (d *ValidatingAccount) SignRANDAOReveal(ctx context.Context, slot spec.Slot) (spec.BLSSignature, error) {
|
||||
var messageRoot spec.Root
|
||||
epoch := spec.Epoch(slot / d.accountManager.slotsPerEpoch)
|
||||
binary.LittleEndian.PutUint64(messageRoot[:], uint64(epoch))
|
||||
|
||||
epoch := slot / d.accountManager.slotsPerEpoch
|
||||
// Obtain the RANDAO reveal signature domain.
|
||||
signatureDomain, err := d.signatureDomainProvider.SignatureDomain(ctx,
|
||||
d.accountManager.randaoDomain,
|
||||
domain, err := d.domainProvider.Domain(ctx,
|
||||
d.accountManager.randaoDomainType,
|
||||
epoch)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain signature domain for RANDAO reveal")
|
||||
return spec.BLSSignature{}, errors.Wrap(err, "failed to obtain signature domain for RANDAO reveal")
|
||||
}
|
||||
|
||||
epochBytes := make([]byte, 32)
|
||||
binary.LittleEndian.PutUint64(epochBytes, epoch)
|
||||
binary.LittleEndian.PutUint64(epochBytes, uint64(epoch))
|
||||
|
||||
sig, err := d.account.(e2wtypes.AccountProtectingSigner).SignGeneric(ctx, epochBytes, signatureDomain)
|
||||
sig, err := d.account.(e2wtypes.AccountProtectingSigner).SignGeneric(ctx, epochBytes, domain[:])
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to sign RANDO reveal")
|
||||
return spec.BLSSignature{}, errors.Wrap(err, "failed to sign RANDO reveal")
|
||||
}
|
||||
return sig.Marshal(), nil
|
||||
|
||||
var signature spec.BLSSignature
|
||||
copy(signature[:], sig.Marshal())
|
||||
return signature, nil
|
||||
}
|
||||
|
||||
// SignBeaconBlockProposal signs a beacon block proposal item.
|
||||
func (d *ValidatingAccount) SignBeaconBlockProposal(ctx context.Context,
|
||||
slot uint64,
|
||||
proposerIndex uint64,
|
||||
parentRoot []byte,
|
||||
stateRoot []byte,
|
||||
bodyRoot []byte) ([]byte, error) {
|
||||
slot spec.Slot,
|
||||
proposerIndex spec.ValidatorIndex,
|
||||
parentRoot spec.Root,
|
||||
stateRoot spec.Root,
|
||||
bodyRoot spec.Root) (spec.BLSSignature, error) {
|
||||
|
||||
// Fetch the signature domain.
|
||||
signatureDomain, err := d.signatureDomainProvider.SignatureDomain(ctx,
|
||||
d.accountManager.beaconProposerDomain,
|
||||
slot/d.accountManager.slotsPerEpoch)
|
||||
// Fetch the domain.
|
||||
domain, err := d.domainProvider.Domain(ctx,
|
||||
d.accountManager.beaconProposerDomainType,
|
||||
spec.Epoch(slot/d.accountManager.slotsPerEpoch))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain signature domain for beacon proposal")
|
||||
return spec.BLSSignature{}, errors.Wrap(err, "failed to obtain signature domain for beacon proposal")
|
||||
}
|
||||
|
||||
sig, err := d.account.(e2wtypes.AccountProtectingSigner).SignBeaconProposal(ctx,
|
||||
slot,
|
||||
proposerIndex,
|
||||
parentRoot,
|
||||
stateRoot,
|
||||
bodyRoot,
|
||||
signatureDomain)
|
||||
uint64(slot),
|
||||
uint64(proposerIndex),
|
||||
parentRoot[:],
|
||||
stateRoot[:],
|
||||
bodyRoot[:],
|
||||
domain[:])
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to sign beacon block proposal")
|
||||
return spec.BLSSignature{}, errors.Wrap(err, "failed to sign beacon block proposal")
|
||||
}
|
||||
return sig.Marshal(), nil
|
||||
|
||||
var signature spec.BLSSignature
|
||||
copy(signature[:], sig.Marshal())
|
||||
return signature, nil
|
||||
}
|
||||
|
||||
// SignBeaconAttestation signs a beacon attestation item.
|
||||
func (d *ValidatingAccount) SignBeaconAttestation(ctx context.Context,
|
||||
slot uint64,
|
||||
committeeIndex uint64,
|
||||
blockRoot []byte,
|
||||
sourceEpoch uint64,
|
||||
sourceRoot []byte,
|
||||
targetEpoch uint64,
|
||||
targetRoot []byte) ([]byte, error) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "dirk.SignBeaconAttestation")
|
||||
defer span.Finish()
|
||||
slot spec.Slot,
|
||||
committeeIndex spec.CommitteeIndex,
|
||||
blockRoot spec.Root,
|
||||
sourceEpoch spec.Epoch,
|
||||
sourceRoot spec.Root,
|
||||
targetEpoch spec.Epoch,
|
||||
targetRoot spec.Root) (spec.BLSSignature, error) {
|
||||
|
||||
signatureDomain, err := d.signatureDomainProvider.SignatureDomain(ctx,
|
||||
d.accountManager.beaconAttesterDomain,
|
||||
slot/d.accountManager.slotsPerEpoch)
|
||||
domain, err := d.domainProvider.Domain(ctx,
|
||||
d.accountManager.beaconAttesterDomainType,
|
||||
spec.Epoch(slot/d.accountManager.slotsPerEpoch))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain signature domain for beacon attestation")
|
||||
return spec.BLSSignature{}, errors.Wrap(err, "failed to obtain signature domain for beacon attestation")
|
||||
}
|
||||
|
||||
sig, err := d.account.(e2wtypes.AccountProtectingSigner).SignBeaconAttestation(ctx,
|
||||
slot,
|
||||
committeeIndex,
|
||||
blockRoot,
|
||||
sourceEpoch,
|
||||
sourceRoot,
|
||||
targetEpoch,
|
||||
targetRoot,
|
||||
signatureDomain)
|
||||
uint64(slot),
|
||||
uint64(committeeIndex),
|
||||
blockRoot[:],
|
||||
uint64(sourceEpoch),
|
||||
sourceRoot[:],
|
||||
uint64(targetEpoch),
|
||||
targetRoot[:],
|
||||
domain[:])
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to sign beacon attestation")
|
||||
return spec.BLSSignature{}, errors.Wrap(err, "failed to sign beacon attestation")
|
||||
}
|
||||
return sig.Marshal(), nil
|
||||
|
||||
var signature spec.BLSSignature
|
||||
copy(signature[:], sig.Marshal())
|
||||
return signature, nil
|
||||
}
|
||||
|
||||
// SignAggregateAndProof signs an aggregate and proof item.
|
||||
func (d *ValidatingAccount) SignAggregateAndProof(ctx context.Context, slot uint64, aggregateAndProofRoot []byte) ([]byte, error) {
|
||||
span, ctx := opentracing.StartSpanFromContext(ctx, "dirk.SignAggregateAndProof")
|
||||
defer span.Finish()
|
||||
|
||||
// Fetch the signature domain.
|
||||
signatureDomain, err := d.signatureDomainProvider.SignatureDomain(ctx,
|
||||
d.accountManager.aggregateAndProofDomain,
|
||||
slot)
|
||||
func (d *ValidatingAccount) SignAggregateAndProof(ctx context.Context, slot spec.Slot, aggregateAndProofRoot spec.Root) (spec.BLSSignature, error) {
|
||||
// Fetch the domain.
|
||||
domain, err := d.domainProvider.Domain(ctx,
|
||||
d.accountManager.aggregateAndProofDomainType,
|
||||
spec.Epoch(slot/d.accountManager.slotsPerEpoch))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain signature domain for beacon aggregate and proof")
|
||||
return spec.BLSSignature{}, errors.Wrap(err, "failed to obtain signature domain for beacon aggregate and proof")
|
||||
}
|
||||
|
||||
sig, err := d.account.(e2wtypes.AccountProtectingSigner).SignGeneric(ctx, aggregateAndProofRoot, signatureDomain)
|
||||
sig, err := d.account.(e2wtypes.AccountProtectingSigner).SignGeneric(ctx, aggregateAndProofRoot[:], domain[:])
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to aggregate and proof")
|
||||
return spec.BLSSignature{}, errors.Wrap(err, "failed to aggregate and proof")
|
||||
}
|
||||
return sig.Marshal(), nil
|
||||
|
||||
var signature spec.BLSSignature
|
||||
copy(signature[:], sig.Marshal())
|
||||
return signature, nil
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
|
||||
"github.com/attestantio/dirk/testing/daemon"
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/attestantio/vouch/mock"
|
||||
"github.com/attestantio/vouch/services/accountmanager"
|
||||
"github.com/attestantio/vouch/services/accountmanager/dirk"
|
||||
|
@ -57,30 +58,30 @@ func TestPubKey(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(mock.NewRANDAODomainProvider()),
|
||||
dirk.WithSelectionProofDomainProvider(mock.NewSelectionProofDomainProvider()),
|
||||
dirk.WithAggregateAndProofDomainProvider(mock.NewAggregateAndProofDomainProvider()),
|
||||
dirk.WithSignatureDomainProvider(mock.NewSignatureDomainProvider()),
|
||||
dirk.WithDomainProvider(mock.NewDomainProvider()),
|
||||
)
|
||||
require.Nil(t, err)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
index uint64
|
||||
expected []byte
|
||||
index spec.ValidatorIndex
|
||||
expected spec.BLSPubKey
|
||||
}{
|
||||
{
|
||||
name: "0",
|
||||
index: 0,
|
||||
expected: _byte("0xa99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c"),
|
||||
expected: _pubKey("0xa99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c"),
|
||||
},
|
||||
{
|
||||
name: "1",
|
||||
index: 1,
|
||||
expected: _byte("0xb89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b"),
|
||||
expected: _pubKey("0xb89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
accounts, err := s.AccountsByIndex(ctx, []uint64{test.index})
|
||||
accounts, err := s.AccountsByIndex(ctx, []spec.ValidatorIndex{test.index})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(accounts))
|
||||
account := accounts[0]
|
||||
|
@ -120,13 +121,13 @@ func TestState(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(mock.NewRANDAODomainProvider()),
|
||||
dirk.WithSelectionProofDomainProvider(mock.NewSelectionProofDomainProvider()),
|
||||
dirk.WithAggregateAndProofDomainProvider(mock.NewAggregateAndProofDomainProvider()),
|
||||
dirk.WithSignatureDomainProvider(mock.NewSignatureDomainProvider()),
|
||||
dirk.WithDomainProvider(mock.NewDomainProvider()),
|
||||
)
|
||||
require.Nil(t, err)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
index uint64
|
||||
index spec.ValidatorIndex
|
||||
expected api.ValidatorState
|
||||
}{
|
||||
{
|
||||
|
@ -143,7 +144,7 @@ func TestState(t *testing.T) {
|
|||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
accounts, err := s.AccountsByIndex(ctx, []uint64{test.index})
|
||||
accounts, err := s.AccountsByIndex(ctx, []spec.ValidatorIndex{test.index})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(accounts))
|
||||
account := accounts[0]
|
||||
|
@ -182,30 +183,30 @@ func TestSignSlotSelection(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(mock.NewRANDAODomainProvider()),
|
||||
dirk.WithSelectionProofDomainProvider(mock.NewSelectionProofDomainProvider()),
|
||||
dirk.WithAggregateAndProofDomainProvider(mock.NewAggregateAndProofDomainProvider()),
|
||||
dirk.WithSignatureDomainProvider(mock.NewSignatureDomainProvider()),
|
||||
dirk.WithDomainProvider(mock.NewDomainProvider()),
|
||||
)
|
||||
require.Nil(t, err)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
index uint64
|
||||
expected []byte
|
||||
index spec.ValidatorIndex
|
||||
expected spec.BLSSignature
|
||||
}{
|
||||
{
|
||||
name: "0",
|
||||
index: 0,
|
||||
expected: _byte("0xa207bbed7d1e43585e5d42e3f09a5179f21a12a33b66ac9af47132c20f9b7b7caaa162420e095664ca3318fe365776e80bd0f9ef1e3b07a2e5340d0c07152234bf18f7596c8d94d72e11961ad8455f08c4417b0019246e24f570a166f86de2c5"),
|
||||
expected: _sig("0xa207bbed7d1e43585e5d42e3f09a5179f21a12a33b66ac9af47132c20f9b7b7caaa162420e095664ca3318fe365776e80bd0f9ef1e3b07a2e5340d0c07152234bf18f7596c8d94d72e11961ad8455f08c4417b0019246e24f570a166f86de2c5"),
|
||||
},
|
||||
{
|
||||
name: "1",
|
||||
index: 1,
|
||||
expected: _byte("0xa17b1a6decb1503b5b8eacb4ca48e2f1665e43c587088995bb7e2da0738268ad0e1f28519ed79fbb318b9b98c6e8b65805a005bca4c98656fefb9ec6753df29ad6ef92da5e3074c027caaaf738d37fd09e08d8d8f86531bd80cf4152709240f9"),
|
||||
expected: _sig("0xa17b1a6decb1503b5b8eacb4ca48e2f1665e43c587088995bb7e2da0738268ad0e1f28519ed79fbb318b9b98c6e8b65805a005bca4c98656fefb9ec6753df29ad6ef92da5e3074c027caaaf738d37fd09e08d8d8f86531bd80cf4152709240f9"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
accounts, err := s.AccountsByIndex(ctx, []uint64{test.index})
|
||||
accounts, err := s.AccountsByIndex(ctx, []spec.ValidatorIndex{test.index})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(accounts))
|
||||
account := accounts[0]
|
||||
|
@ -245,30 +246,30 @@ func TestSignRANDAOReveal(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(mock.NewRANDAODomainProvider()),
|
||||
dirk.WithSelectionProofDomainProvider(mock.NewSelectionProofDomainProvider()),
|
||||
dirk.WithAggregateAndProofDomainProvider(mock.NewAggregateAndProofDomainProvider()),
|
||||
dirk.WithSignatureDomainProvider(mock.NewSignatureDomainProvider()),
|
||||
dirk.WithDomainProvider(mock.NewDomainProvider()),
|
||||
)
|
||||
require.Nil(t, err)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
index uint64
|
||||
expected []byte
|
||||
index spec.ValidatorIndex
|
||||
expected spec.BLSSignature
|
||||
}{
|
||||
{
|
||||
name: "0",
|
||||
index: 0,
|
||||
expected: _byte("0xb990eeca35dadda689f5561ac39bba9a27a0c41c40bd1ce584595ba2a44782a89e2630ced7b1fc348b2408d15fa6746c177c5227625e39031e6be1536387ae33e21ec3de6d1d0b46bada1b99b621f8d40eab81882400c028716b22d31999b177"),
|
||||
expected: _sig("0xb990eeca35dadda689f5561ac39bba9a27a0c41c40bd1ce584595ba2a44782a89e2630ced7b1fc348b2408d15fa6746c177c5227625e39031e6be1536387ae33e21ec3de6d1d0b46bada1b99b621f8d40eab81882400c028716b22d31999b177"),
|
||||
},
|
||||
{
|
||||
name: "1",
|
||||
index: 1,
|
||||
expected: _byte("0x840c144974632f09084b91ec7be5044c3fe9dd0dc7ce1031c0c78911807e264f36cb4fee0ddccf0ca93bada5d102cfb7118e6b75b5ecc5e18648a29f21f70727f3587b8d34bc7474d926fab4fb30eae4436153c336e6eb290d3d1cdd88ee9a58"),
|
||||
expected: _sig("0x840c144974632f09084b91ec7be5044c3fe9dd0dc7ce1031c0c78911807e264f36cb4fee0ddccf0ca93bada5d102cfb7118e6b75b5ecc5e18648a29f21f70727f3587b8d34bc7474d926fab4fb30eae4436153c336e6eb290d3d1cdd88ee9a58"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
accounts, err := s.AccountsByIndex(ctx, []uint64{test.index})
|
||||
accounts, err := s.AccountsByIndex(ctx, []spec.ValidatorIndex{test.index})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(accounts))
|
||||
account := accounts[0]
|
||||
|
@ -308,30 +309,30 @@ func TestSignBeaconBlockProposal(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(mock.NewRANDAODomainProvider()),
|
||||
dirk.WithSelectionProofDomainProvider(mock.NewSelectionProofDomainProvider()),
|
||||
dirk.WithAggregateAndProofDomainProvider(mock.NewAggregateAndProofDomainProvider()),
|
||||
dirk.WithSignatureDomainProvider(mock.NewSignatureDomainProvider()),
|
||||
dirk.WithDomainProvider(mock.NewDomainProvider()),
|
||||
)
|
||||
require.Nil(t, err)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
index uint64
|
||||
expected []byte
|
||||
index spec.ValidatorIndex
|
||||
expected spec.BLSSignature
|
||||
}{
|
||||
{
|
||||
name: "0",
|
||||
index: 0,
|
||||
expected: _byte("0x83d91f4fe6dd962493f212a94dc62c81358ffbdb6c3f8567d96fbe31c5ab505db1a3d37b8c3d653225621bb34918d30b069bbc02daeea9e1b2e62166014563f271fdfbe9aad37f0d155754f63eb368dd853c0bf723ad64af371a04b7778e891a"),
|
||||
expected: _sig("0x83d91f4fe6dd962493f212a94dc62c81358ffbdb6c3f8567d96fbe31c5ab505db1a3d37b8c3d653225621bb34918d30b069bbc02daeea9e1b2e62166014563f271fdfbe9aad37f0d155754f63eb368dd853c0bf723ad64af371a04b7778e891a"),
|
||||
},
|
||||
{
|
||||
name: "1",
|
||||
index: 1,
|
||||
expected: _byte("0x9176ac06d426beb74bfb3969a619d364a5e214f0da511433b56f8dca47b93725c4ddd225c1cb81dd5a26fc321801a1d70b1c28c6cf705c010fadf9c4f139c044224680d8c60e425c9d6e6b8e8af21f12cffab38b393a9b7529527b92cf20e80a"),
|
||||
expected: _sig("0x9176ac06d426beb74bfb3969a619d364a5e214f0da511433b56f8dca47b93725c4ddd225c1cb81dd5a26fc321801a1d70b1c28c6cf705c010fadf9c4f139c044224680d8c60e425c9d6e6b8e8af21f12cffab38b393a9b7529527b92cf20e80a"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
accounts, err := s.AccountsByIndex(ctx, []uint64{test.index})
|
||||
accounts, err := s.AccountsByIndex(ctx, []spec.ValidatorIndex{test.index})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(accounts))
|
||||
account := accounts[0]
|
||||
|
@ -341,9 +342,9 @@ func TestSignBeaconBlockProposal(t *testing.T) {
|
|||
res, err := signer.SignBeaconBlockProposal(ctx,
|
||||
1,
|
||||
1,
|
||||
_byte("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
_byte("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
_byte("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
_root("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
_root("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
_root("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, test.expected, res)
|
||||
|
@ -377,30 +378,30 @@ func TestBeaconAttestationsSigner(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(mock.NewRANDAODomainProvider()),
|
||||
dirk.WithSelectionProofDomainProvider(mock.NewSelectionProofDomainProvider()),
|
||||
dirk.WithAggregateAndProofDomainProvider(mock.NewAggregateAndProofDomainProvider()),
|
||||
dirk.WithSignatureDomainProvider(mock.NewSignatureDomainProvider()),
|
||||
dirk.WithDomainProvider(mock.NewDomainProvider()),
|
||||
)
|
||||
require.Nil(t, err)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
index uint64
|
||||
expected []byte
|
||||
index spec.ValidatorIndex
|
||||
expected spec.BLSSignature
|
||||
}{
|
||||
{
|
||||
name: "0",
|
||||
index: 0,
|
||||
expected: _byte("0x974fb6782c196c8e523b74ea3dbdfe7b122c6a18590992f2cb789358dcea6c28498ffa6cac68629bf83175cb55bb0d3910919eab48d2934c3a81655dcc27c91a996ca4a9880ffde7864f6aba3cd7c40111e3317c817032776d077d8d6a348bb2"),
|
||||
expected: _sig("0x974fb6782c196c8e523b74ea3dbdfe7b122c6a18590992f2cb789358dcea6c28498ffa6cac68629bf83175cb55bb0d3910919eab48d2934c3a81655dcc27c91a996ca4a9880ffde7864f6aba3cd7c40111e3317c817032776d077d8d6a348bb2"),
|
||||
},
|
||||
{
|
||||
name: "1",
|
||||
index: 1,
|
||||
expected: _byte("0x84a1c3c50d093901ea1b027b18598e4b9cf0f848f6bd49f2807a3f6ea37c0cbf3794556705863de0ae8ea7dd2da4d4d91436e2ca96fa1eb045a22fb7704cedf8a842fa881a416eaa02444454d9f7f8040b84fc3cd3d42817f6992c3c29e16007"),
|
||||
expected: _sig("0x84a1c3c50d093901ea1b027b18598e4b9cf0f848f6bd49f2807a3f6ea37c0cbf3794556705863de0ae8ea7dd2da4d4d91436e2ca96fa1eb045a22fb7704cedf8a842fa881a416eaa02444454d9f7f8040b84fc3cd3d42817f6992c3c29e16007"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
accounts, err := s.AccountsByIndex(ctx, []uint64{test.index})
|
||||
accounts, err := s.AccountsByIndex(ctx, []spec.ValidatorIndex{test.index})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(accounts))
|
||||
account := accounts[0]
|
||||
|
@ -410,11 +411,11 @@ func TestBeaconAttestationsSigner(t *testing.T) {
|
|||
res, err := signer.SignBeaconAttestation(ctx,
|
||||
1,
|
||||
1,
|
||||
_byte("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
_root("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
0,
|
||||
_byte("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
_root("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
1,
|
||||
_byte("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
_root("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, test.expected, res)
|
||||
|
@ -448,30 +449,30 @@ func TestAggregateAndProofsigner(t *testing.T) {
|
|||
dirk.WithRANDAODomainProvider(mock.NewRANDAODomainProvider()),
|
||||
dirk.WithSelectionProofDomainProvider(mock.NewSelectionProofDomainProvider()),
|
||||
dirk.WithAggregateAndProofDomainProvider(mock.NewAggregateAndProofDomainProvider()),
|
||||
dirk.WithSignatureDomainProvider(mock.NewSignatureDomainProvider()),
|
||||
dirk.WithDomainProvider(mock.NewDomainProvider()),
|
||||
)
|
||||
require.Nil(t, err)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
index uint64
|
||||
expected []byte
|
||||
index spec.ValidatorIndex
|
||||
expected spec.BLSSignature
|
||||
}{
|
||||
{
|
||||
name: "0",
|
||||
index: 0,
|
||||
expected: _byte("0xafd6b2ed80506b63e964820aba6523735d6156d4f2e3d53c88075f22b2a48447d6f083952e7d6c315a96dfde35b6959616591ac9d8b2d7f1c423b7f257e6f5eb4406b97b55270a9101cca809e76c7759aaf1235b028aa23da118697dfb9c34c5"),
|
||||
expected: _sig("0xafd6b2ed80506b63e964820aba6523735d6156d4f2e3d53c88075f22b2a48447d6f083952e7d6c315a96dfde35b6959616591ac9d8b2d7f1c423b7f257e6f5eb4406b97b55270a9101cca809e76c7759aaf1235b028aa23da118697dfb9c34c5"),
|
||||
},
|
||||
{
|
||||
name: "1",
|
||||
index: 1,
|
||||
expected: _byte("0xa006085be92bb0ee2cf2bba3da0d5e21630efb7e32a5e4fa7ca742ea0bd273f76a6336ef3a9817200bddbc0b4a6dbecf1303d9804806fa38ee05b7d5cfbba6e851c37ca587d66df935c296e6210db69f8b4c96f5e590cb83c7f82c06aee1d4c3"),
|
||||
expected: _sig("0xa006085be92bb0ee2cf2bba3da0d5e21630efb7e32a5e4fa7ca742ea0bd273f76a6336ef3a9817200bddbc0b4a6dbecf1303d9804806fa38ee05b7d5cfbba6e851c37ca587d66df935c296e6210db69f8b4c96f5e590cb83c7f82c06aee1d4c3"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
accounts, err := s.AccountsByIndex(ctx, []uint64{test.index})
|
||||
accounts, err := s.AccountsByIndex(ctx, []spec.ValidatorIndex{test.index})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(accounts))
|
||||
account := accounts[0]
|
||||
|
@ -480,7 +481,7 @@ func TestAggregateAndProofsigner(t *testing.T) {
|
|||
require.True(t, isSigner)
|
||||
res, err := signer.SignAggregateAndProof(ctx,
|
||||
1,
|
||||
_byte("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
_root("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, test.expected, res)
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"context"
|
||||
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
)
|
||||
|
||||
// Service is the generic accountmanager service.
|
||||
|
@ -29,23 +30,23 @@ type ValidatingAccountsProvider interface {
|
|||
Accounts(ctx context.Context) ([]ValidatingAccount, error)
|
||||
|
||||
// AccountsByIndex provides information about the specific accounts that are configured to validate through this instance.
|
||||
AccountsByIndex(ctx context.Context, indices []uint64) ([]ValidatingAccount, error)
|
||||
AccountsByIndex(ctx context.Context, indices []spec.ValidatorIndex) ([]ValidatingAccount, error)
|
||||
|
||||
// AccountsByPubKey provides information about the specific accounts that are configured to validate through this instance.
|
||||
AccountsByPubKey(ctx context.Context, pubKeys [][]byte) ([]ValidatingAccount, error)
|
||||
AccountsByPubKey(ctx context.Context, pubKeys []spec.BLSPubKey) ([]ValidatingAccount, error)
|
||||
}
|
||||
|
||||
// ValidatingAccountPubKeyProvider provides methods for obtaining public keys from accounts.
|
||||
type ValidatingAccountPubKeyProvider interface {
|
||||
// PubKey() provides the public key for this account.
|
||||
PubKey(ctx context.Context) ([]byte, error)
|
||||
PubKey(ctx context.Context) (spec.BLSPubKey, error)
|
||||
}
|
||||
|
||||
// ValidatingAccountIndexProvider provides methods for obtaining indices from accounts.
|
||||
type ValidatingAccountIndexProvider interface {
|
||||
// Index() provides the validator index for this account.
|
||||
// Returns an error if there is no index for this validator.
|
||||
Index(ctx context.Context) (uint64, error)
|
||||
Index(ctx context.Context) (spec.ValidatorIndex, error)
|
||||
}
|
||||
|
||||
// ValidatingAccountStateProvider provides methods for obtaining state from accounts.
|
||||
|
@ -81,45 +82,44 @@ type IsAggregatorProvider interface {
|
|||
type RANDAORevealSigner interface {
|
||||
// SignRANDAOReveal returns a RANDAO signature.
|
||||
// This signs an epoch with the "RANDAO" domain.
|
||||
// N.B. This passes in a slot, not an epoch.
|
||||
SignRANDAOReveal(ctx context.Context, slot uint64) ([]byte, error)
|
||||
SignRANDAOReveal(ctx context.Context, slot spec.Slot) (spec.BLSSignature, error)
|
||||
}
|
||||
|
||||
// SlotSelectionSigner provides methods to sign slot selections.
|
||||
type SlotSelectionSigner interface {
|
||||
// SignSlotSelection returns a slot selection signature.
|
||||
// This signs a slot with the "selection proof" domain.
|
||||
SignSlotSelection(ctx context.Context, slot uint64) ([]byte, error)
|
||||
SignSlotSelection(ctx context.Context, slot spec.Slot) (spec.BLSSignature, error)
|
||||
}
|
||||
|
||||
// BeaconBlockSigner provides methods to sign beacon blocks.
|
||||
type BeaconBlockSigner interface {
|
||||
// SignBeaconBlockProposal signs a beacon block proposal.
|
||||
SignBeaconBlockProposal(ctx context.Context,
|
||||
slot uint64,
|
||||
proposerIndex uint64,
|
||||
parentRoot []byte,
|
||||
stateRoot []byte,
|
||||
bodyRoot []byte) ([]byte, error)
|
||||
slot spec.Slot,
|
||||
proposerIndex spec.ValidatorIndex,
|
||||
parentRoot spec.Root,
|
||||
stateRoot spec.Root,
|
||||
bodyRoot spec.Root) (spec.BLSSignature, error)
|
||||
}
|
||||
|
||||
// BeaconAttestationSigner provides methods to sign beacon attestations.
|
||||
type BeaconAttestationSigner interface {
|
||||
// SignBeaconAttestation signs a beacon attestation.
|
||||
SignBeaconAttestation(ctx context.Context,
|
||||
slot uint64,
|
||||
committeeIndex uint64,
|
||||
blockRoot []byte,
|
||||
sourceEpoch uint64,
|
||||
sourceRoot []byte,
|
||||
targetEpoch uint64,
|
||||
targetRoot []byte) ([]byte, error)
|
||||
slot spec.Slot,
|
||||
committeeIndex spec.CommitteeIndex,
|
||||
blockRoot spec.Root,
|
||||
sourceEpoch spec.Epoch,
|
||||
sourceRoot spec.Root,
|
||||
targetEpoch spec.Epoch,
|
||||
targetRoot spec.Root) (spec.BLSSignature, error)
|
||||
}
|
||||
|
||||
// AggregateAndProofSigner provides methods to sign aggregate and proofs.
|
||||
type AggregateAndProofSigner interface {
|
||||
// SignAggregateAndProof signs an aggregate attestation for given slot and root.
|
||||
SignAggregateAndProof(ctx context.Context, slot uint64, root []byte) ([]byte, error)
|
||||
SignAggregateAndProof(ctx context.Context, slot spec.Slot, root spec.Root) (spec.BLSSignature, error)
|
||||
}
|
||||
|
||||
// Signer is a composite interface for all signer operations.
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
// Copyright © 2020 Attestant Limited.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package wallet
|
||||
|
||||
// Need to `go get github.com/ferranbt/fastssz/sszgen` for this to work.
|
||||
//go:generate sszgen --path . --objs SigningContainer
|
|
@ -33,7 +33,7 @@ type parameters struct {
|
|||
randaoDomainProvider eth2client.RANDAODomainProvider
|
||||
selectionProofDomainProvider eth2client.SelectionProofDomainProvider
|
||||
aggregateAndProofDomainProvider eth2client.AggregateAndProofDomainProvider
|
||||
signatureDomainProvider eth2client.SignatureDomainProvider
|
||||
domainProvider eth2client.DomainProvider
|
||||
}
|
||||
|
||||
// Parameter is the interface for service parameters.
|
||||
|
@ -131,10 +131,10 @@ func WithAggregateAndProofDomainProvider(provider eth2client.AggregateAndProofDo
|
|||
})
|
||||
}
|
||||
|
||||
// WithSignatureDomainProvider sets the signature domain provider.
|
||||
func WithSignatureDomainProvider(provider eth2client.SignatureDomainProvider) Parameter {
|
||||
// WithDomainProvider sets the domain provider.
|
||||
func WithDomainProvider(provider eth2client.DomainProvider) Parameter {
|
||||
return parameterFunc(func(p *parameters) {
|
||||
p.signatureDomainProvider = provider
|
||||
p.domainProvider = provider
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -179,8 +179,8 @@ func parseAndCheckParameters(params ...Parameter) (*parameters, error) {
|
|||
if parameters.aggregateAndProofDomainProvider == nil {
|
||||
return nil, errors.New("no aggregate and proof domain provider specified")
|
||||
}
|
||||
if parameters.signatureDomainProvider == nil {
|
||||
return nil, errors.New("no signature domain provider specified")
|
||||
if parameters.domainProvider == nil {
|
||||
return nil, errors.New("no domain provider specified")
|
||||
}
|
||||
|
||||
return ¶meters, nil
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
|
||||
eth2client "github.com/attestantio/go-eth2-client"
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/attestantio/vouch/services/accountmanager"
|
||||
"github.com/attestantio/vouch/services/metrics"
|
||||
"github.com/pkg/errors"
|
||||
|
@ -40,15 +41,15 @@ type Service struct {
|
|||
stores []e2wtypes.Store
|
||||
accountPaths []string
|
||||
passphrases [][]byte
|
||||
accounts map[[48]byte]*ValidatingAccount
|
||||
accounts map[spec.BLSPubKey]*ValidatingAccount
|
||||
validatorsProvider eth2client.ValidatorsProvider
|
||||
slotsPerEpoch uint64
|
||||
beaconProposerDomain []byte
|
||||
beaconAttesterDomain []byte
|
||||
randaoDomain []byte
|
||||
selectionProofDomain []byte
|
||||
aggregateAndProofDomain []byte
|
||||
signatureDomainProvider eth2client.SignatureDomainProvider
|
||||
slotsPerEpoch spec.Slot
|
||||
beaconProposerDomain spec.DomainType
|
||||
beaconAttesterDomain spec.DomainType
|
||||
randaoDomain spec.DomainType
|
||||
selectionProofDomain spec.DomainType
|
||||
aggregateAndProofDomain spec.DomainType
|
||||
domainProvider eth2client.DomainProvider
|
||||
}
|
||||
|
||||
// module-wide log.
|
||||
|
@ -81,23 +82,23 @@ func New(ctx context.Context, params ...Parameter) (*Service, error) {
|
|||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain slots per epoch")
|
||||
}
|
||||
beaconAttesterDomain, err := parameters.beaconAttesterDomainProvider.BeaconAttesterDomain(ctx)
|
||||
beaconAttesterDomainType, err := parameters.beaconAttesterDomainProvider.BeaconAttesterDomain(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain beacon attester domain")
|
||||
}
|
||||
beaconProposerDomain, err := parameters.beaconProposerDomainProvider.BeaconProposerDomain(ctx)
|
||||
beaconProposerDomainType, err := parameters.beaconProposerDomainProvider.BeaconProposerDomain(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain beacon proposer domain")
|
||||
}
|
||||
randaoDomain, err := parameters.randaoDomainProvider.RANDAODomain(ctx)
|
||||
randaoDomainType, err := parameters.randaoDomainProvider.RANDAODomain(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain RANDAO domain")
|
||||
}
|
||||
selectionProofDomain, err := parameters.selectionProofDomainProvider.SelectionProofDomain(ctx)
|
||||
selectionProofDomainType, err := parameters.selectionProofDomainProvider.SelectionProofDomain(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain selection proof domain")
|
||||
}
|
||||
aggregateAndProofDomain, err := parameters.aggregateAndProofDomainProvider.AggregateAndProofDomain(ctx)
|
||||
aggregateAndProofDomainType, err := parameters.aggregateAndProofDomainProvider.AggregateAndProofDomain(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain aggregate and proof domain")
|
||||
}
|
||||
|
@ -107,13 +108,13 @@ func New(ctx context.Context, params ...Parameter) (*Service, error) {
|
|||
accountPaths: parameters.accountPaths,
|
||||
passphrases: parameters.passphrases,
|
||||
validatorsProvider: parameters.validatorsProvider,
|
||||
slotsPerEpoch: slotsPerEpoch,
|
||||
beaconAttesterDomain: beaconAttesterDomain,
|
||||
beaconProposerDomain: beaconProposerDomain,
|
||||
randaoDomain: randaoDomain,
|
||||
selectionProofDomain: selectionProofDomain,
|
||||
aggregateAndProofDomain: aggregateAndProofDomain,
|
||||
signatureDomainProvider: parameters.signatureDomainProvider,
|
||||
slotsPerEpoch: spec.Slot(slotsPerEpoch),
|
||||
beaconAttesterDomain: beaconAttesterDomainType,
|
||||
beaconProposerDomain: beaconProposerDomainType,
|
||||
randaoDomain: randaoDomainType,
|
||||
selectionProofDomain: selectionProofDomainType,
|
||||
aggregateAndProofDomain: aggregateAndProofDomainType,
|
||||
domainProvider: parameters.domainProvider,
|
||||
}
|
||||
|
||||
if err := s.RefreshAccounts(ctx); err != nil {
|
||||
|
@ -126,18 +127,22 @@ func New(ctx context.Context, params ...Parameter) (*Service, error) {
|
|||
// UpdateAccountsState updates account state with the latest information from the beacon chain.
|
||||
// This should be run at the beginning of each epoch to ensure that any newly-activated accounts are registered.
|
||||
func (s *Service) UpdateAccountsState(ctx context.Context) error {
|
||||
validatorIDs := make([]eth2client.ValidatorIDProvider, 0, len(s.accounts))
|
||||
validatorIndices := make([]spec.ValidatorIndex, 0, len(s.accounts))
|
||||
for _, account := range s.accounts {
|
||||
if !account.state.IsAttesting() {
|
||||
validatorIDs = append(validatorIDs, account)
|
||||
index, err := account.Index(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to obtain account index")
|
||||
}
|
||||
validatorIndices = append(validatorIndices, index)
|
||||
}
|
||||
}
|
||||
if len(validatorIDs) == 0 {
|
||||
if len(validatorIndices) == 0 {
|
||||
// Nothing to do.
|
||||
log.Trace().Msg("No unactivated keys")
|
||||
return nil
|
||||
}
|
||||
validators, err := s.validatorsProvider.Validators(ctx, "head", validatorIDs)
|
||||
validators, err := s.validatorsProvider.Validators(ctx, "head", validatorIndices)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to obtain validators")
|
||||
}
|
||||
|
@ -180,7 +185,7 @@ func (s *Service) RefreshAccounts(ctx context.Context) error {
|
|||
|
||||
verificationRegexes := accountPathsToVerificationRegexes(s.accountPaths)
|
||||
// Fetch accounts for each wallet.
|
||||
accounts := make(map[[48]byte]*ValidatingAccount)
|
||||
accounts := make(map[spec.BLSPubKey]*ValidatingAccount)
|
||||
for _, wallet := range wallets {
|
||||
// if _, isProvider := wallet.(e2wtypes.WalletAccountsByPathProvider); isProvider {
|
||||
// fmt.Printf("TODO: fetch accounts by path")
|
||||
|
@ -189,22 +194,26 @@ func (s *Service) RefreshAccounts(ctx context.Context) error {
|
|||
//}
|
||||
}
|
||||
|
||||
validatorIDs := make([]eth2client.ValidatorIDProvider, 0, len(accounts))
|
||||
// Update indices for accounts.
|
||||
pubKeys := make([]spec.BLSPubKey, 0, len(accounts))
|
||||
for _, account := range accounts {
|
||||
if !account.state.IsAttesting() {
|
||||
validatorIDs = append(validatorIDs, account)
|
||||
pubKey, err := account.PubKey(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to obtain public key")
|
||||
}
|
||||
pubKeys = append(pubKeys, pubKey)
|
||||
}
|
||||
validators, err := s.validatorsProvider.ValidatorsByPubKey(ctx, "head", pubKeys)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to obtain validators")
|
||||
}
|
||||
|
||||
log.Trace().Int("keys", len(accounts)).Msg("Keys obtained")
|
||||
if len(validatorIDs) == 0 {
|
||||
if len(pubKeys) == 0 {
|
||||
log.Warn().Msg("No accounts obtained")
|
||||
return nil
|
||||
}
|
||||
|
||||
validators, err := s.validatorsProvider.Validators(ctx, "head", validatorIDs)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to obtain validators")
|
||||
}
|
||||
s.updateAccountStates(ctx, accounts, validators)
|
||||
|
||||
s.mutex.Lock()
|
||||
|
@ -230,9 +239,9 @@ func (s *Service) Accounts(ctx context.Context) ([]accountmanager.ValidatingAcco
|
|||
}
|
||||
|
||||
// AccountsByIndex returns attesting accounts.
|
||||
func (s *Service) AccountsByIndex(ctx context.Context, indices []uint64) ([]accountmanager.ValidatingAccount, error) {
|
||||
indexMap := make(map[uint64]bool)
|
||||
for _, index := range indices {
|
||||
func (s *Service) AccountsByIndex(ctx context.Context, validatorIndices []spec.ValidatorIndex) ([]accountmanager.ValidatingAccount, error) {
|
||||
indexMap := make(map[spec.ValidatorIndex]bool)
|
||||
for _, index := range validatorIndices {
|
||||
indexMap[index] = true
|
||||
}
|
||||
|
||||
|
@ -246,7 +255,7 @@ func (s *Service) AccountsByIndex(ctx context.Context, indices []uint64) ([]acco
|
|||
}
|
||||
index, err := account.Index(ctx)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("No index for account")
|
||||
log.Error().Err(err).Msg("Failed to obtain account index")
|
||||
continue
|
||||
}
|
||||
if _, exists := indexMap[index]; exists {
|
||||
|
@ -259,12 +268,10 @@ func (s *Service) AccountsByIndex(ctx context.Context, indices []uint64) ([]acco
|
|||
}
|
||||
|
||||
// AccountsByPubKey returns validating accounts.
|
||||
func (s *Service) AccountsByPubKey(ctx context.Context, pubKeys [][]byte) ([]accountmanager.ValidatingAccount, error) {
|
||||
pubKeyMap := make(map[[48]byte]bool)
|
||||
func (s *Service) AccountsByPubKey(ctx context.Context, pubKeys []spec.BLSPubKey) ([]accountmanager.ValidatingAccount, error) {
|
||||
pubKeyMap := make(map[spec.BLSPubKey]bool)
|
||||
for _, pubKey := range pubKeys {
|
||||
var mapKey [48]byte
|
||||
copy(mapKey[:], pubKey)
|
||||
pubKeyMap[mapKey] = true
|
||||
pubKeyMap[pubKey] = true
|
||||
}
|
||||
|
||||
s.mutex.RLock()
|
||||
|
@ -313,12 +320,10 @@ func accountPathsToVerificationRegexes(paths []string) []*regexp.Regexp {
|
|||
return regexes
|
||||
}
|
||||
|
||||
func (s *Service) updateAccountStates(ctx context.Context, accounts map[[48]byte]*ValidatingAccount, validators map[uint64]*api.Validator) {
|
||||
validatorsByPubKey := make(map[[48]byte]*api.Validator, len(validators))
|
||||
func (s *Service) updateAccountStates(ctx context.Context, accounts map[spec.BLSPubKey]*ValidatingAccount, validators map[spec.ValidatorIndex]*api.Validator) {
|
||||
validatorsByPubKey := make(map[spec.BLSPubKey]*api.Validator, len(validators))
|
||||
for _, validator := range validators {
|
||||
var pubKey [48]byte
|
||||
copy(pubKey[:], validator.Validator.PublicKey)
|
||||
validatorsByPubKey[pubKey] = validator
|
||||
validatorsByPubKey[validator.Validator.PublicKey] = validator
|
||||
}
|
||||
|
||||
validatorStateCounts := make(map[string]uint64)
|
||||
|
@ -326,7 +331,7 @@ func (s *Service) updateAccountStates(ctx context.Context, accounts map[[48]byte
|
|||
validator, exists := validatorsByPubKey[pubKey]
|
||||
if exists {
|
||||
account.index = validator.Index
|
||||
account.state = validator.State
|
||||
account.state = validator.Status
|
||||
}
|
||||
validatorStateCounts[strings.ToLower(account.state.String())]++
|
||||
}
|
||||
|
@ -345,7 +350,7 @@ func (s *Service) updateAccountStates(ctx context.Context, accounts map[[48]byte
|
|||
}
|
||||
}
|
||||
|
||||
func (s *Service) fetchAccountsForWallet(ctx context.Context, wallet e2wtypes.Wallet, accounts map[[48]byte]*ValidatingAccount, verificationRegexes []*regexp.Regexp) {
|
||||
func (s *Service) fetchAccountsForWallet(ctx context.Context, wallet e2wtypes.Wallet, accounts map[spec.BLSPubKey]*ValidatingAccount, verificationRegexes []*regexp.Regexp) {
|
||||
for account := range wallet.Accounts(ctx) {
|
||||
// Ensure the name matches one of our account paths.
|
||||
name := fmt.Sprintf("%s/%s", wallet.Name(), account.Name())
|
||||
|
@ -385,9 +390,9 @@ func (s *Service) fetchAccountsForWallet(ctx context.Context, wallet e2wtypes.Wa
|
|||
|
||||
// Set up account as unknown to beacon chain.
|
||||
accounts[bytesutil.ToBytes48(pubKey)] = &ValidatingAccount{
|
||||
account: account,
|
||||
accountManager: s,
|
||||
signatureDomainProvider: s.signatureDomainProvider,
|
||||
account: account,
|
||||
accountManager: s,
|
||||
domainProvider: s.domainProvider,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
// Copyright © 2020 Attestant Limited.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package wallet
|
||||
|
||||
// SigningContainer is the container for signing roots with a domain.
|
||||
type SigningContainer struct {
|
||||
Root []byte `ssz-size:"32"`
|
||||
Domain []byte `ssz-size:"32"`
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
// Code generated by fastssz. DO NOT EDIT.
|
||||
package wallet
|
||||
|
||||
import (
|
||||
ssz "github.com/ferranbt/fastssz"
|
||||
)
|
||||
|
||||
// MarshalSSZ ssz marshals the SigningContainer object
|
||||
func (s *SigningContainer) MarshalSSZ() ([]byte, error) {
|
||||
return ssz.MarshalSSZ(s)
|
||||
}
|
||||
|
||||
// MarshalSSZTo ssz marshals the SigningContainer object to a target array
|
||||
func (s *SigningContainer) MarshalSSZTo(buf []byte) (dst []byte, err error) {
|
||||
dst = buf
|
||||
|
||||
// Field (0) 'Root'
|
||||
if len(s.Root) != 32 {
|
||||
err = ssz.ErrBytesLength
|
||||
return
|
||||
}
|
||||
dst = append(dst, s.Root...)
|
||||
|
||||
// Field (1) 'Domain'
|
||||
if len(s.Domain) != 32 {
|
||||
err = ssz.ErrBytesLength
|
||||
return
|
||||
}
|
||||
dst = append(dst, s.Domain...)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// UnmarshalSSZ ssz unmarshals the SigningContainer object
|
||||
func (s *SigningContainer) UnmarshalSSZ(buf []byte) error {
|
||||
var err error
|
||||
size := uint64(len(buf))
|
||||
if size != 64 {
|
||||
return ssz.ErrSize
|
||||
}
|
||||
|
||||
// Field (0) 'Root'
|
||||
if cap(s.Root) == 0 {
|
||||
s.Root = make([]byte, 0, len(buf[0:32]))
|
||||
}
|
||||
s.Root = append(s.Root, buf[0:32]...)
|
||||
|
||||
// Field (1) 'Domain'
|
||||
if cap(s.Domain) == 0 {
|
||||
s.Domain = make([]byte, 0, len(buf[32:64]))
|
||||
}
|
||||
s.Domain = append(s.Domain, buf[32:64]...)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// SizeSSZ returns the ssz encoded size in bytes for the SigningContainer object
|
||||
func (s *SigningContainer) SizeSSZ() (size int) {
|
||||
size = 64
|
||||
return
|
||||
}
|
||||
|
||||
// HashTreeRoot ssz hashes the SigningContainer object
|
||||
func (s *SigningContainer) HashTreeRoot() ([32]byte, error) {
|
||||
return ssz.HashWithDefaultHasher(s)
|
||||
}
|
||||
|
||||
// HashTreeRootWith ssz hashes the SigningContainer object with a hasher
|
||||
func (s *SigningContainer) HashTreeRootWith(hh *ssz.Hasher) (err error) {
|
||||
indx := hh.Index()
|
||||
|
||||
// Field (0) 'Root'
|
||||
if len(s.Root) != 32 {
|
||||
err = ssz.ErrBytesLength
|
||||
return
|
||||
}
|
||||
hh.PutBytes(s.Root)
|
||||
|
||||
// Field (1) 'Domain'
|
||||
if len(s.Domain) != 32 {
|
||||
err = ssz.ErrBytesLength
|
||||
return
|
||||
}
|
||||
hh.PutBytes(s.Domain)
|
||||
|
||||
hh.Merkleize(indx)
|
||||
return
|
||||
}
|
|
@ -21,28 +21,32 @@ import (
|
|||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/pkg/errors"
|
||||
e2types "github.com/wealdtech/go-eth2-types/v2"
|
||||
e2wtypes "github.com/wealdtech/go-eth2-wallet-types/v2"
|
||||
)
|
||||
|
||||
// ValidatingAccount is a wrapper around the wallet account that implements ValidatingAccount.
|
||||
type ValidatingAccount struct {
|
||||
account e2wtypes.Account
|
||||
index uint64
|
||||
state api.ValidatorState
|
||||
accountManager *Service
|
||||
signatureDomainProvider eth2client.SignatureDomainProvider
|
||||
account e2wtypes.Account
|
||||
index spec.ValidatorIndex
|
||||
state api.ValidatorState
|
||||
accountManager *Service
|
||||
domainProvider eth2client.DomainProvider
|
||||
}
|
||||
|
||||
// PubKey returns the public key of the validating account.
|
||||
func (d *ValidatingAccount) PubKey(ctx context.Context) ([]byte, error) {
|
||||
func (d *ValidatingAccount) PubKey(ctx context.Context) (spec.BLSPubKey, error) {
|
||||
var pubKey spec.BLSPubKey
|
||||
if provider, isProvider := d.account.(e2wtypes.AccountCompositePublicKeyProvider); isProvider {
|
||||
return provider.CompositePublicKey().Marshal(), nil
|
||||
copy(pubKey[:], provider.CompositePublicKey().Marshal())
|
||||
} else {
|
||||
copy(pubKey[:], d.account.PublicKey().Marshal())
|
||||
}
|
||||
return d.account.PublicKey().Marshal(), nil
|
||||
return pubKey, nil
|
||||
}
|
||||
|
||||
// Index returns the index of the validating account.
|
||||
func (d *ValidatingAccount) Index(ctx context.Context) (uint64, error) {
|
||||
func (d *ValidatingAccount) Index(ctx context.Context) (spec.ValidatorIndex, error) {
|
||||
return d.index, nil
|
||||
}
|
||||
|
||||
|
@ -53,16 +57,16 @@ func (d *ValidatingAccount) State() api.ValidatorState {
|
|||
|
||||
// SignSlotSelection returns a slot selection signature.
|
||||
// This signs a slot with the "selection proof" domain.
|
||||
func (d *ValidatingAccount) SignSlotSelection(ctx context.Context, slot uint64) ([]byte, error) {
|
||||
messageRoot := make([]byte, 32)
|
||||
binary.LittleEndian.PutUint64(messageRoot, slot)
|
||||
func (d *ValidatingAccount) SignSlotSelection(ctx context.Context, slot spec.Slot) (spec.BLSSignature, error) {
|
||||
var messageRoot spec.Root
|
||||
binary.LittleEndian.PutUint64(messageRoot[:], uint64(slot))
|
||||
|
||||
// Calculate the signature domain.
|
||||
domain, err := d.signatureDomainProvider.SignatureDomain(ctx,
|
||||
// Calculate the domain.
|
||||
domain, err := d.domainProvider.Domain(ctx,
|
||||
d.accountManager.selectionProofDomain,
|
||||
slot/d.accountManager.slotsPerEpoch)
|
||||
spec.Epoch(slot/d.accountManager.slotsPerEpoch))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain signature domain for selection proof")
|
||||
return spec.BLSSignature{}, errors.Wrap(err, "failed to obtain domain for selection proof")
|
||||
}
|
||||
|
||||
return d.sign(ctx, messageRoot, domain)
|
||||
|
@ -70,30 +74,32 @@ func (d *ValidatingAccount) SignSlotSelection(ctx context.Context, slot uint64)
|
|||
|
||||
// SignRANDAOReveal returns a RANDAO reveal signature.
|
||||
// This signs an epoch with the "RANDAO reveal" domain.
|
||||
// N.B. This passes in a slot, not an epoch.
|
||||
func (d *ValidatingAccount) SignRANDAOReveal(ctx context.Context, slot uint64) ([]byte, error) {
|
||||
messageRoot := make([]byte, 32)
|
||||
epoch := slot / d.accountManager.slotsPerEpoch
|
||||
binary.LittleEndian.PutUint64(messageRoot, epoch)
|
||||
func (d *ValidatingAccount) SignRANDAOReveal(ctx context.Context, slot spec.Slot) (spec.BLSSignature, error) {
|
||||
var messageRoot spec.Root
|
||||
epoch := spec.Epoch(slot / d.accountManager.slotsPerEpoch)
|
||||
binary.LittleEndian.PutUint64(messageRoot[:], uint64(epoch))
|
||||
|
||||
// Obtain the RANDAO reveal signature domain.
|
||||
domain, err := d.signatureDomainProvider.SignatureDomain(ctx,
|
||||
domain, err := d.domainProvider.Domain(ctx,
|
||||
d.accountManager.randaoDomain,
|
||||
epoch)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain signature domain for RANDAO reveal")
|
||||
return spec.BLSSignature{}, errors.Wrap(err, "failed to obtain signature domain for RANDAO reveal")
|
||||
}
|
||||
|
||||
return d.sign(ctx, messageRoot, domain)
|
||||
var epochBytes spec.Root
|
||||
binary.LittleEndian.PutUint64(epochBytes[:], uint64(epoch))
|
||||
|
||||
return d.sign(ctx, epochBytes, domain)
|
||||
}
|
||||
|
||||
// SignBeaconBlockProposal signs a beacon block proposal item.
|
||||
func (d *ValidatingAccount) SignBeaconBlockProposal(ctx context.Context,
|
||||
slot uint64,
|
||||
proposerIndex uint64,
|
||||
parentRoot []byte,
|
||||
stateRoot []byte,
|
||||
bodyRoot []byte) ([]byte, error) {
|
||||
slot spec.Slot,
|
||||
proposerIndex spec.ValidatorIndex,
|
||||
parentRoot spec.Root,
|
||||
stateRoot spec.Root,
|
||||
bodyRoot spec.Root) (spec.BLSSignature, error) {
|
||||
|
||||
message := &spec.BeaconBlockHeader{
|
||||
Slot: slot,
|
||||
|
@ -104,29 +110,29 @@ func (d *ValidatingAccount) SignBeaconBlockProposal(ctx context.Context,
|
|||
}
|
||||
messageRoot, err := message.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain hash tree root of block")
|
||||
return spec.BLSSignature{}, errors.Wrap(err, "failed to obtain hash tree root of block")
|
||||
}
|
||||
|
||||
// Obtain the signature domain.
|
||||
domain, err := d.signatureDomainProvider.SignatureDomain(ctx,
|
||||
// Fetch the domain.
|
||||
domain, err := d.domainProvider.Domain(ctx,
|
||||
d.accountManager.beaconProposerDomain,
|
||||
slot/d.accountManager.slotsPerEpoch)
|
||||
spec.Epoch(slot/d.accountManager.slotsPerEpoch))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain signature domain for beacon proposal")
|
||||
return spec.BLSSignature{}, errors.Wrap(err, "failed to obtain signature domain for beacon proposal")
|
||||
}
|
||||
|
||||
return d.sign(ctx, messageRoot[:], domain)
|
||||
return d.sign(ctx, messageRoot, domain)
|
||||
}
|
||||
|
||||
// SignBeaconAttestation signs a beacon attestation item.
|
||||
func (d *ValidatingAccount) SignBeaconAttestation(ctx context.Context,
|
||||
slot uint64,
|
||||
committeeIndex uint64,
|
||||
blockRoot []byte,
|
||||
sourceEpoch uint64,
|
||||
sourceRoot []byte,
|
||||
targetEpoch uint64,
|
||||
targetRoot []byte) ([]byte, error) {
|
||||
slot spec.Slot,
|
||||
committeeIndex spec.CommitteeIndex,
|
||||
blockRoot spec.Root,
|
||||
sourceEpoch spec.Epoch,
|
||||
sourceRoot spec.Root,
|
||||
targetEpoch spec.Epoch,
|
||||
targetRoot spec.Root) (spec.BLSSignature, error) {
|
||||
|
||||
message := &spec.AttestationData{
|
||||
Slot: slot,
|
||||
|
@ -143,46 +149,56 @@ func (d *ValidatingAccount) SignBeaconAttestation(ctx context.Context,
|
|||
}
|
||||
messageRoot, err := message.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain hash tree root of attestation data")
|
||||
return spec.BLSSignature{}, errors.Wrap(err, "failed to obtain hash tree root of attestation data")
|
||||
}
|
||||
|
||||
domain, err := d.signatureDomainProvider.SignatureDomain(ctx,
|
||||
domain, err := d.domainProvider.Domain(ctx,
|
||||
d.accountManager.beaconAttesterDomain,
|
||||
slot/d.accountManager.slotsPerEpoch)
|
||||
spec.Epoch(slot/d.accountManager.slotsPerEpoch))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain signature domain for beacon attestation")
|
||||
return spec.BLSSignature{}, errors.Wrap(err, "failed to obtain signature domain for beacon attestation")
|
||||
}
|
||||
|
||||
return d.sign(ctx, messageRoot[:], domain)
|
||||
return d.sign(ctx, messageRoot, domain)
|
||||
}
|
||||
|
||||
// SignAggregateAndProof signs an aggregate and proof item.
|
||||
func (d *ValidatingAccount) SignAggregateAndProof(ctx context.Context, slot uint64, aggregateAndProofRoot []byte) ([]byte, error) {
|
||||
|
||||
func (d *ValidatingAccount) SignAggregateAndProof(ctx context.Context, slot spec.Slot, aggregateAndProofRoot spec.Root) (spec.BLSSignature, error) {
|
||||
// Fetch the signature domain.
|
||||
domain, err := d.signatureDomainProvider.SignatureDomain(ctx,
|
||||
domain, err := d.domainProvider.Domain(ctx,
|
||||
d.accountManager.aggregateAndProofDomain,
|
||||
slot)
|
||||
spec.Epoch(slot/d.accountManager.slotsPerEpoch))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain signature domain for beacon aggregate and proof")
|
||||
return spec.BLSSignature{}, errors.Wrap(err, "failed to obtain signature domain for beacon aggregate and proof")
|
||||
}
|
||||
|
||||
return d.sign(ctx, aggregateAndProofRoot, domain)
|
||||
}
|
||||
|
||||
func (d *ValidatingAccount) sign(ctx context.Context, messageRoot []byte, domain []byte) ([]byte, error) {
|
||||
container := &SigningContainer{
|
||||
Root: messageRoot,
|
||||
Domain: domain,
|
||||
func (d *ValidatingAccount) sign(ctx context.Context, message spec.Root, domain spec.Domain) (spec.BLSSignature, error) {
|
||||
var sig e2types.Signature
|
||||
var err error
|
||||
if protectingSigner, isProtectingSigner := d.account.(e2wtypes.AccountProtectingSigner); isProtectingSigner {
|
||||
sig, err = protectingSigner.SignGeneric(ctx, message[:], domain[:])
|
||||
} else {
|
||||
// Create the root manually.
|
||||
container := &spec.SigningData{
|
||||
ObjectRoot: message,
|
||||
Domain: domain,
|
||||
}
|
||||
var signingRoot spec.Root
|
||||
signingRoot, err = container.HashTreeRoot()
|
||||
if err != nil {
|
||||
return spec.BLSSignature{}, errors.Wrap(err, "failed to generate hash tree root for signing container")
|
||||
}
|
||||
|
||||
sig, err = d.account.(e2wtypes.AccountSigner).Sign(ctx, signingRoot[:])
|
||||
}
|
||||
signingRoot, err := container.HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to generate hash tree root for signing container")
|
||||
return spec.BLSSignature{}, errors.Wrap(err, "failed to sign")
|
||||
}
|
||||
|
||||
sig, err := d.account.(e2wtypes.AccountSigner).Sign(ctx, signingRoot[:])
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to sign beacon block proposal")
|
||||
}
|
||||
return sig.Marshal(), nil
|
||||
var signature spec.BLSSignature
|
||||
copy(signature[:], sig.Marshal())
|
||||
return signature, nil
|
||||
}
|
||||
|
|
|
@ -21,56 +21,20 @@ import (
|
|||
|
||||
// Duty contains information about an attestation aggregation duty.
|
||||
type Duty struct {
|
||||
validatorIndex uint64
|
||||
validatorPubKey []byte
|
||||
slotSignature []byte
|
||||
attestation *spec.Attestation
|
||||
}
|
||||
|
||||
// NewDuty creates a new attestation aggregation duty.
|
||||
func NewDuty(ctx context.Context, validatorIndex uint64, validatorPubKey []byte, attestation *spec.Attestation, slotSignature []byte) (*Duty, error) {
|
||||
return &Duty{
|
||||
validatorIndex: validatorIndex,
|
||||
validatorPubKey: validatorPubKey,
|
||||
slotSignature: slotSignature,
|
||||
attestation: attestation,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Slot provides the slot for the attestaton aggregation.
|
||||
func (d *Duty) Slot() uint64 {
|
||||
return d.attestation.Data.Slot
|
||||
}
|
||||
|
||||
// CommitteeIndex provides the committee index for the attestaton aggregation.
|
||||
func (d *Duty) CommitteeIndex() uint64 {
|
||||
return d.attestation.Data.Index
|
||||
}
|
||||
|
||||
// ValidatorIndex provides the index of the validator carrying out the attestation aggregation.
|
||||
func (d *Duty) ValidatorIndex() uint64 {
|
||||
return d.validatorIndex
|
||||
}
|
||||
|
||||
// ValidatorPubKey provides the public key of the validator carrying out the attestation aggregation.
|
||||
func (d *Duty) ValidatorPubKey() []byte {
|
||||
return d.validatorPubKey
|
||||
}
|
||||
|
||||
// Attestation provides the attestation of the validator carrying out the attestation aggregation.
|
||||
func (d *Duty) Attestation() *spec.Attestation {
|
||||
return d.attestation
|
||||
}
|
||||
|
||||
// SlotSignature provides the slot signature of the validator carrying out the attestation aggregation.
|
||||
func (d *Duty) SlotSignature() []byte {
|
||||
return d.slotSignature
|
||||
// Slot is the slot of the attestation aggregation; required for obtaining the aggregate.
|
||||
Slot spec.Slot
|
||||
// Attestation data root is the root of the attestation to be aggregated; required for obtaining the aggregate.
|
||||
AttestationDataRoot spec.Root
|
||||
// ValidatorIndex is the index of the validator carrying out the aggregation; reuqired for submitting the aggregate.
|
||||
ValidatorIndex spec.ValidatorIndex
|
||||
// SlotSignature is the signature of the slot by the validator carrying out the aggregation; reuqired for submitting the aggregate.
|
||||
SlotSignature spec.BLSSignature
|
||||
}
|
||||
|
||||
// IsAggregatorProvider provides information about if a validator is an aggregator.
|
||||
type IsAggregatorProvider interface {
|
||||
// IsAggregator returns true if the given validator is an aggregator for the given committee at the given slot.
|
||||
IsAggregator(ctx context.Context, validatorIndex uint64, committeeIndex uint64, slot uint64, committeeSize uint64) (bool, []byte, error)
|
||||
IsAggregator(ctx context.Context, validatorIndex spec.ValidatorIndex, committeeIndex spec.CommitteeIndex, slot spec.Slot, committeeSize uint64) (bool, spec.BLSSignature, error)
|
||||
}
|
||||
|
||||
// Service is the attestation aggregation service.
|
||||
|
|
|
@ -27,7 +27,8 @@ type parameters struct {
|
|||
monitor metrics.AttestationAggregationMonitor
|
||||
targetAggregatorsPerCommitteeProvider eth2client.TargetAggregatorsPerCommitteeProvider
|
||||
validatingAccountsProvider accountmanager.ValidatingAccountsProvider
|
||||
aggregateAttestationProvider eth2client.NonSpecAggregateAttestationProvider
|
||||
aggregateAttestationProvider eth2client.AggregateAttestationProvider
|
||||
prysmAggregateAttestationProvider eth2client.PrysmAggregateAttestationProvider
|
||||
aggregateAttestationsSubmitter submitter.AggregateAttestationsSubmitter
|
||||
}
|
||||
|
||||
|
@ -71,12 +72,19 @@ func WithValidatingAccountsProvider(provider accountmanager.ValidatingAccountsPr
|
|||
}
|
||||
|
||||
// WithAggregateAttestationDataProvider sets the aggregate attestation provider.
|
||||
func WithAggregateAttestationDataProvider(provider eth2client.NonSpecAggregateAttestationProvider) Parameter {
|
||||
func WithAggregateAttestationDataProvider(provider eth2client.AggregateAttestationProvider) Parameter {
|
||||
return parameterFunc(func(p *parameters) {
|
||||
p.aggregateAttestationProvider = provider
|
||||
})
|
||||
}
|
||||
|
||||
// WithPrysmAggregateAttestationDataProvider sets the non-spec aggregate attestation provider.
|
||||
func WithPrysmAggregateAttestationDataProvider(provider eth2client.PrysmAggregateAttestationProvider) Parameter {
|
||||
return parameterFunc(func(p *parameters) {
|
||||
p.prysmAggregateAttestationProvider = provider
|
||||
})
|
||||
}
|
||||
|
||||
// WithAggregateAttestationsSubmitter sets the aggregate attestation submitter.
|
||||
func WithAggregateAttestationsSubmitter(submitter submitter.AggregateAttestationsSubmitter) Parameter {
|
||||
return parameterFunc(func(p *parameters) {
|
||||
|
@ -104,7 +112,7 @@ func parseAndCheckParameters(params ...Parameter) (*parameters, error) {
|
|||
if parameters.validatingAccountsProvider == nil {
|
||||
return nil, errors.New("no validating accounts provider specified")
|
||||
}
|
||||
if parameters.aggregateAttestationProvider == nil {
|
||||
if parameters.aggregateAttestationProvider == nil && parameters.prysmAggregateAttestationProvider == nil {
|
||||
return nil, errors.New("no aggregate attestation provider specified")
|
||||
}
|
||||
if parameters.aggregateAttestationsSubmitter == nil {
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
eth2client "github.com/attestantio/go-eth2-client"
|
||||
|
@ -32,11 +33,12 @@ import (
|
|||
|
||||
// Service is an attestation aggregator.
|
||||
type Service struct {
|
||||
monitor metrics.AttestationAggregationMonitor
|
||||
targetAggregatorsPerCommittee uint64
|
||||
validatingAccountsProvider accountmanager.ValidatingAccountsProvider
|
||||
aggregateAttestationProvider eth2client.NonSpecAggregateAttestationProvider
|
||||
aggregateAttestationsSubmitter submitter.AggregateAttestationsSubmitter
|
||||
monitor metrics.AttestationAggregationMonitor
|
||||
targetAggregatorsPerCommittee uint64
|
||||
validatingAccountsProvider accountmanager.ValidatingAccountsProvider
|
||||
aggregateAttestationProvider eth2client.AggregateAttestationProvider
|
||||
prysmAggregateAttestationProvider eth2client.PrysmAggregateAttestationProvider
|
||||
aggregateAttestationsSubmitter submitter.AggregateAttestationsSubmitter
|
||||
}
|
||||
|
||||
// module-wide log.
|
||||
|
@ -61,11 +63,12 @@ func New(ctx context.Context, params ...Parameter) (*Service, error) {
|
|||
}
|
||||
|
||||
s := &Service{
|
||||
monitor: parameters.monitor,
|
||||
targetAggregatorsPerCommittee: targetAggregatorsPerCommittee,
|
||||
validatingAccountsProvider: parameters.validatingAccountsProvider,
|
||||
aggregateAttestationProvider: parameters.aggregateAttestationProvider,
|
||||
aggregateAttestationsSubmitter: parameters.aggregateAttestationsSubmitter,
|
||||
monitor: parameters.monitor,
|
||||
targetAggregatorsPerCommittee: targetAggregatorsPerCommittee,
|
||||
validatingAccountsProvider: parameters.validatingAccountsProvider,
|
||||
aggregateAttestationProvider: parameters.aggregateAttestationProvider,
|
||||
prysmAggregateAttestationProvider: parameters.prysmAggregateAttestationProvider,
|
||||
aggregateAttestationsSubmitter: parameters.aggregateAttestationsSubmitter,
|
||||
}
|
||||
|
||||
return s, nil
|
||||
|
@ -81,23 +84,32 @@ func (s *Service) Aggregate(ctx context.Context, data interface{}) {
|
|||
s.monitor.AttestationAggregationCompleted(started, "failed")
|
||||
return
|
||||
}
|
||||
log := log.With().Uint64("slot", duty.Slot()).Uint64("committee_index", duty.CommitteeIndex()).Logger()
|
||||
log := log.With().Uint64("slot", uint64(duty.Slot)).Str("attestation_data_root", fmt.Sprintf("%#x", duty.AttestationDataRoot)).Logger()
|
||||
log.Trace().Msg("Aggregating")
|
||||
|
||||
// Obtain the aggregate attestation.
|
||||
aggregateAttestation, err := s.aggregateAttestationProvider.NonSpecAggregateAttestation(ctx,
|
||||
duty.Attestation(),
|
||||
duty.ValidatorPubKey(),
|
||||
duty.SlotSignature())
|
||||
var aggregateAttestation *spec.Attestation
|
||||
var err error
|
||||
if s.aggregateAttestationProvider != nil {
|
||||
aggregateAttestation, err = s.aggregateAttestationProvider.AggregateAttestation(ctx, duty.Slot, duty.AttestationDataRoot)
|
||||
} else {
|
||||
// TODO
|
||||
log.Debug().Msg("Not aggregating for non-spec beacon node")
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to obtain aggregate attestation")
|
||||
s.monitor.AttestationAggregationCompleted(started, "failed")
|
||||
return
|
||||
}
|
||||
log.Trace().Dur("elapsed", time.Since(started)).Msg("Obtained aggregate attestation")
|
||||
if aggregateAttestation == nil {
|
||||
log.Debug().Msg("Obtained nil aggregate attestation")
|
||||
return
|
||||
}
|
||||
|
||||
// Fetch the validating account.
|
||||
accounts, err := s.validatingAccountsProvider.AccountsByPubKey(ctx, [][]byte{duty.ValidatorPubKey()})
|
||||
accounts, err := s.validatingAccountsProvider.AccountsByIndex(ctx, []spec.ValidatorIndex{duty.ValidatorIndex})
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to obtain proposing validator account")
|
||||
s.monitor.AttestationAggregationCompleted(started, "failed")
|
||||
|
@ -119,16 +131,16 @@ func (s *Service) Aggregate(ctx context.Context, data interface{}) {
|
|||
return
|
||||
}
|
||||
aggregateAndProof := &spec.AggregateAndProof{
|
||||
AggregatorIndex: duty.ValidatorIndex(),
|
||||
AggregatorIndex: duty.ValidatorIndex,
|
||||
Aggregate: aggregateAttestation,
|
||||
SelectionProof: duty.SlotSignature(),
|
||||
SelectionProof: duty.SlotSignature,
|
||||
}
|
||||
|
||||
aggregateAndProofRoot, err := aggregateAndProof.HashTreeRoot()
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to generate hash tree root of aggregate and proof")
|
||||
}
|
||||
sig, err := signer.SignAggregateAndProof(ctx, duty.Slot(), aggregateAndProofRoot[:])
|
||||
sig, err := signer.SignAggregateAndProof(ctx, duty.Slot, spec.Root(aggregateAndProofRoot))
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to sign aggregate and proof")
|
||||
s.monitor.AttestationAggregationCompleted(started, "failed")
|
||||
|
@ -157,7 +169,12 @@ func (s *Service) Aggregate(ctx context.Context, data interface{}) {
|
|||
}
|
||||
|
||||
// IsAggregator reports if we are an attestation aggregator for a given validator/committee/slot combination.
|
||||
func (s *Service) IsAggregator(ctx context.Context, validatorIndex uint64, committeeIndex uint64, slot uint64, committeeSize uint64) (bool, []byte, error) {
|
||||
func (s *Service) IsAggregator(ctx context.Context,
|
||||
validatorIndex spec.ValidatorIndex,
|
||||
committeeIndex spec.CommitteeIndex,
|
||||
slot spec.Slot,
|
||||
committeeSize uint64,
|
||||
) (bool, spec.BLSSignature, error) {
|
||||
modulo := committeeSize / s.targetAggregatorsPerCommittee
|
||||
if modulo == 0 {
|
||||
// Modulo must be at least 1.
|
||||
|
@ -165,34 +182,34 @@ func (s *Service) IsAggregator(ctx context.Context, validatorIndex uint64, commi
|
|||
}
|
||||
|
||||
// Fetch the validator from the account manager.
|
||||
accounts, err := s.validatingAccountsProvider.AccountsByIndex(ctx, []uint64{validatorIndex})
|
||||
accounts, err := s.validatingAccountsProvider.AccountsByIndex(ctx, []spec.ValidatorIndex{validatorIndex})
|
||||
if err != nil {
|
||||
return false, nil, errors.Wrap(err, "failed to obtain validator")
|
||||
return false, spec.BLSSignature{}, errors.Wrap(err, "failed to obtain validator")
|
||||
}
|
||||
if len(accounts) == 0 {
|
||||
return false, nil, errors.New("validator unknown")
|
||||
return false, spec.BLSSignature{}, errors.New("validator unknown")
|
||||
}
|
||||
account := accounts[0]
|
||||
|
||||
slotSelectionSigner, isSlotSelectionSigner := account.(accountmanager.SlotSelectionSigner)
|
||||
if !isSlotSelectionSigner {
|
||||
return false, nil, errors.New("validating account is not a slot selection signer")
|
||||
return false, spec.BLSSignature{}, errors.New("validating account is not a slot selection signer")
|
||||
}
|
||||
|
||||
// Sign the slot.
|
||||
signature, err := slotSelectionSigner.SignSlotSelection(ctx, slot)
|
||||
if err != nil {
|
||||
return false, nil, errors.Wrap(err, "failed to sign the slot")
|
||||
return false, spec.BLSSignature{}, errors.Wrap(err, "failed to sign the slot")
|
||||
}
|
||||
|
||||
// Hash the signature.
|
||||
sigHash := sha256.New()
|
||||
n, err := sigHash.Write(signature)
|
||||
n, err := sigHash.Write(signature[:])
|
||||
if err != nil {
|
||||
return false, nil, errors.Wrap(err, "failed to hash the slot signature")
|
||||
return false, spec.BLSSignature{}, errors.Wrap(err, "failed to hash the slot signature")
|
||||
}
|
||||
if n != len(signature) {
|
||||
return false, nil, errors.New("failed to write all bytes of the slot signature to the hash")
|
||||
return false, spec.BLSSignature{}, errors.New("failed to write all bytes of the slot signature to the hash")
|
||||
}
|
||||
hash := sigHash.Sum(nil)
|
||||
|
||||
|
|
|
@ -18,14 +18,21 @@ import (
|
|||
"sort"
|
||||
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
)
|
||||
|
||||
// MergeDuties merges attester duties given by an Ethereum 2 client into vouch's per-slot structure.
|
||||
func MergeDuties(ctx context.Context, attesterDuties []*api.AttesterDuty) ([]*Duty, error) {
|
||||
validatorIndices := make(map[uint64][]uint64)
|
||||
committeeIndices := make(map[uint64][]uint64)
|
||||
validatorCommitteeIndices := make(map[uint64][]uint64)
|
||||
committeeLengths := make(map[uint64]map[uint64]uint64)
|
||||
duties := make([]*Duty, 0, len(attesterDuties))
|
||||
if len(attesterDuties) == 0 {
|
||||
return duties, nil
|
||||
}
|
||||
|
||||
validatorIndices := make(map[spec.Slot][]spec.ValidatorIndex)
|
||||
committeeIndices := make(map[spec.Slot][]spec.CommitteeIndex)
|
||||
validatorCommitteeIndices := make(map[spec.Slot][]uint64)
|
||||
committeeLengths := make(map[spec.Slot]map[spec.CommitteeIndex]uint64)
|
||||
committeesAtSlots := make(map[spec.Slot]uint64)
|
||||
|
||||
// Set the base capacity for our arrays based on the number of attester duties.
|
||||
// This is much higher than we need, but is overall minimal and avoids reallocations.
|
||||
|
@ -56,9 +63,10 @@ func MergeDuties(ctx context.Context, attesterDuties []*api.AttesterDuty) ([]*Du
|
|||
|
||||
_, exists := validatorIndices[duty.Slot]
|
||||
if !exists {
|
||||
validatorIndices[duty.Slot] = make([]uint64, 0, arrayCap)
|
||||
committeeIndices[duty.Slot] = make([]uint64, 0, arrayCap)
|
||||
committeeLengths[duty.Slot] = make(map[uint64]uint64)
|
||||
validatorIndices[duty.Slot] = make([]spec.ValidatorIndex, 0, arrayCap)
|
||||
committeeIndices[duty.Slot] = make([]spec.CommitteeIndex, 0, arrayCap)
|
||||
committeeLengths[duty.Slot] = make(map[spec.CommitteeIndex]uint64)
|
||||
committeesAtSlots[duty.Slot] = duty.CommitteesAtSlot
|
||||
}
|
||||
validatorIndices[duty.Slot] = append(validatorIndices[duty.Slot], duty.ValidatorIndex)
|
||||
committeeIndices[duty.Slot] = append(committeeIndices[duty.Slot], duty.CommitteeIndex)
|
||||
|
@ -66,11 +74,11 @@ func MergeDuties(ctx context.Context, attesterDuties []*api.AttesterDuty) ([]*Du
|
|||
validatorCommitteeIndices[duty.Slot] = append(validatorCommitteeIndices[duty.Slot], duty.ValidatorCommitteeIndex)
|
||||
}
|
||||
|
||||
duties := make([]*Duty, 0, len(validatorIndices))
|
||||
for slot := range validatorIndices {
|
||||
if duty, err := NewDuty(
|
||||
ctx,
|
||||
slot,
|
||||
committeesAtSlots[slot],
|
||||
validatorIndices[slot],
|
||||
committeeIndices[slot],
|
||||
validatorCommitteeIndices[slot],
|
||||
|
|
|
@ -22,15 +22,23 @@ import (
|
|||
|
||||
// Duty contains information about a beacon block attester duty.
|
||||
type Duty struct {
|
||||
slot uint64
|
||||
validatorIndices []uint64
|
||||
committeeIndices []uint64
|
||||
slot spec.Slot
|
||||
committeesAtSlot uint64
|
||||
validatorIndices []spec.ValidatorIndex
|
||||
committeeIndices []spec.CommitteeIndex
|
||||
validatorCommitteeIndices []uint64
|
||||
committeeLengths map[uint64]uint64
|
||||
committeeLengths map[spec.CommitteeIndex]uint64
|
||||
}
|
||||
|
||||
// NewDuty creates a new beacon block attester duty.
|
||||
func NewDuty(ctx context.Context, slot uint64, validatorIndices []uint64, committeeIndices []uint64, validatorCommitteeIndices []uint64, committeeLengths map[uint64]uint64) (*Duty, error) {
|
||||
func NewDuty(ctx context.Context,
|
||||
slot spec.Slot,
|
||||
committeesAtSlot uint64,
|
||||
validatorIndices []spec.ValidatorIndex,
|
||||
committeeIndices []spec.CommitteeIndex,
|
||||
validatorCommitteeIndices []uint64,
|
||||
committeeLengths map[spec.CommitteeIndex]uint64,
|
||||
) (*Duty, error) {
|
||||
// Ensure there is a matching committee size for each committee index.
|
||||
for i := range committeeIndices {
|
||||
if _, exists := committeeLengths[committeeIndices[i]]; !exists {
|
||||
|
@ -40,6 +48,7 @@ func NewDuty(ctx context.Context, slot uint64, validatorIndices []uint64, commit
|
|||
|
||||
return &Duty{
|
||||
slot: slot,
|
||||
committeesAtSlot: committeesAtSlot,
|
||||
validatorIndices: validatorIndices,
|
||||
committeeIndices: committeeIndices,
|
||||
validatorCommitteeIndices: validatorCommitteeIndices,
|
||||
|
@ -48,17 +57,22 @@ func NewDuty(ctx context.Context, slot uint64, validatorIndices []uint64, commit
|
|||
}
|
||||
|
||||
// Slot provides the slot for the beacon block attester.
|
||||
func (d *Duty) Slot() uint64 {
|
||||
func (d *Duty) Slot() spec.Slot {
|
||||
return d.slot
|
||||
}
|
||||
|
||||
// CommitteesAtSlot provides the number of committees at the duty's slot.
|
||||
func (d *Duty) CommitteesAtSlot() uint64 {
|
||||
return d.committeesAtSlot
|
||||
}
|
||||
|
||||
// ValidatorIndices provides the validator indices for the beacon block attester.
|
||||
func (d *Duty) ValidatorIndices() []uint64 {
|
||||
func (d *Duty) ValidatorIndices() []spec.ValidatorIndex {
|
||||
return d.validatorIndices
|
||||
}
|
||||
|
||||
// CommitteeIndices provides the committee indices for the beacon block attester.
|
||||
func (d *Duty) CommitteeIndices() []uint64 {
|
||||
func (d *Duty) CommitteeIndices() []spec.CommitteeIndex {
|
||||
return d.committeeIndices
|
||||
}
|
||||
|
||||
|
@ -68,7 +82,7 @@ func (d *Duty) ValidatorCommitteeIndices() []uint64 {
|
|||
}
|
||||
|
||||
// CommitteeSize provides the committee size for a given index.
|
||||
func (d *Duty) CommitteeSize(committeeIndex uint64) uint64 {
|
||||
func (d *Duty) CommitteeSize(committeeIndex spec.CommitteeIndex) uint64 {
|
||||
return d.committeeLengths[committeeIndex]
|
||||
}
|
||||
|
||||
|
@ -77,6 +91,20 @@ func (d *Duty) String() string {
|
|||
return fmt.Sprintf("beacon block attester for slot %d with validators %v committee indices %v", d.slot, d.validatorIndices, d.committeeIndices)
|
||||
}
|
||||
|
||||
// Tuples returns a slice of (validator index, committee index, validator position in committee) strings.
|
||||
// Useful for logging the
|
||||
func (d *Duty) Tuples() []string {
|
||||
tuples := make([]string, len(d.committeeIndices))
|
||||
for i := range d.committeeIndices {
|
||||
tuples[i] = fmt.Sprintf("(%d,%d,%d)",
|
||||
d.validatorIndices[i],
|
||||
d.committeeIndices[i],
|
||||
d.validatorCommitteeIndices[i],
|
||||
)
|
||||
}
|
||||
return tuples
|
||||
}
|
||||
|
||||
// Service is the beacon block attester service.
|
||||
type Service interface {
|
||||
// Attest carries out attestations for a slot.
|
||||
|
|
|
@ -85,8 +85,8 @@ func (s *Service) Attest(ctx context.Context, data interface{}) ([]*spec.Attesta
|
|||
s.monitor.AttestationCompleted(started, "failed")
|
||||
return nil, errors.New("passed invalid data structure")
|
||||
}
|
||||
log := log.With().Uint64("slot", duty.Slot()).Logger()
|
||||
log.Trace().Uints64("validator_indices", duty.ValidatorIndices()).Msg("Attesting")
|
||||
log := log.With().Uint64("slot", uint64(duty.Slot())).Logger()
|
||||
log.Trace().Strs("duties", duty.Tuples()).Msg("Attesting")
|
||||
|
||||
attestations := make([]*spec.Attestation, 0, len(duty.ValidatorIndices()))
|
||||
var attestationsMutex sync.Mutex
|
||||
|
@ -110,10 +110,10 @@ func (s *Service) Attest(ctx context.Context, data interface{}) ([]*spec.Attesta
|
|||
s.monitor.AttestationCompleted(started, "failed")
|
||||
return nil, errors.New("failed to obtain attesting validator accounts")
|
||||
}
|
||||
log.Trace().Dur("elapsed", time.Since(started)).Uints64("validator_indices", duty.ValidatorIndices()).Msg("Obtained validating accounts")
|
||||
log.Trace().Dur("elapsed", time.Since(started)).Strs("tuples", duty.Tuples()).Msg("Obtained validating accounts")
|
||||
|
||||
// Run the attestations in parallel, up to a concurrency limit.
|
||||
validatorIndexToArrayIndexMap := make(map[uint64]int)
|
||||
validatorIndexToArrayIndexMap := make(map[spec.ValidatorIndex]int)
|
||||
for i := range duty.ValidatorIndices() {
|
||||
validatorIndexToArrayIndexMap[duty.ValidatorIndices()[i]] = i
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ func (s *Service) Attest(ctx context.Context, data interface{}) ([]*spec.Attesta
|
|||
log.Warn().Err(err).Msg("Failed to obtain validator index")
|
||||
return
|
||||
}
|
||||
log := log.With().Uint64("validator_index", validatorIndex).Logger()
|
||||
log := log.With().Uint64("validator_index", uint64(validatorIndex)).Logger()
|
||||
attestation, err := s.attest(ctx,
|
||||
duty.Slot(),
|
||||
duty.CommitteeIndices()[validatorIndexToArrayIndexMap[validatorIndex]],
|
||||
|
@ -163,8 +163,8 @@ func (s *Service) Attest(ctx context.Context, data interface{}) ([]*spec.Attesta
|
|||
|
||||
func (s *Service) attest(
|
||||
ctx context.Context,
|
||||
slot uint64,
|
||||
committeeIndex uint64,
|
||||
slot spec.Slot,
|
||||
committeeIndex spec.CommitteeIndex,
|
||||
validatorCommitteeIndex uint64,
|
||||
committeeSize uint64,
|
||||
account accountmanager.ValidatingAccount,
|
||||
|
|
|
@ -16,20 +16,26 @@ package beaconblockproposer
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/attestantio/vouch/services/accountmanager"
|
||||
)
|
||||
|
||||
// Duty contains information about a beacon block proposal duty.
|
||||
type Duty struct {
|
||||
// Details for the duty.
|
||||
slot uint64
|
||||
validatorIndex uint64
|
||||
slot spec.Slot
|
||||
validatorIndex spec.ValidatorIndex
|
||||
|
||||
// randaoReveal is required to be passed to the beacon node when proposing the block; can be pre-calculated.
|
||||
randaoReveal []byte
|
||||
randaoReveal spec.BLSSignature
|
||||
|
||||
// account is used to sign the proposal; can be pre-fetched.
|
||||
account accountmanager.ValidatingAccount
|
||||
}
|
||||
|
||||
// NewDuty creates a new beacon block proposer duty.
|
||||
func NewDuty(ctx context.Context, slot uint64, validatorIndex uint64) (*Duty, error) {
|
||||
func NewDuty(ctx context.Context, slot spec.Slot, validatorIndex spec.ValidatorIndex) (*Duty, error) {
|
||||
return &Duty{
|
||||
slot: slot,
|
||||
validatorIndex: validatorIndex,
|
||||
|
@ -37,12 +43,12 @@ func NewDuty(ctx context.Context, slot uint64, validatorIndex uint64) (*Duty, er
|
|||
}
|
||||
|
||||
// Slot provides the slot for the beacon block proposer.
|
||||
func (d *Duty) Slot() uint64 {
|
||||
func (d *Duty) Slot() spec.Slot {
|
||||
return d.slot
|
||||
}
|
||||
|
||||
// ValidatorIndex provides the validator index for the beacon block proposer.
|
||||
func (d *Duty) ValidatorIndex() uint64 {
|
||||
func (d *Duty) ValidatorIndex() spec.ValidatorIndex {
|
||||
return d.validatorIndex
|
||||
}
|
||||
|
||||
|
@ -52,15 +58,25 @@ func (d *Duty) String() string {
|
|||
}
|
||||
|
||||
// SetRandaoReveal sets the RANDAO reveal.
|
||||
func (d *Duty) SetRandaoReveal(randaoReveal []byte) {
|
||||
func (d *Duty) SetRandaoReveal(randaoReveal spec.BLSSignature) {
|
||||
d.randaoReveal = randaoReveal
|
||||
}
|
||||
|
||||
// RANDAOReveal provides the RANDAO reveal.
|
||||
func (d *Duty) RANDAOReveal() []byte {
|
||||
func (d *Duty) RANDAOReveal() spec.BLSSignature {
|
||||
return d.randaoReveal
|
||||
}
|
||||
|
||||
// SetAccount sets the account.
|
||||
func (d *Duty) SetAccount(account accountmanager.ValidatingAccount) {
|
||||
d.account = account
|
||||
}
|
||||
|
||||
// Account provides the account.
|
||||
func (d *Duty) Account() accountmanager.ValidatingAccount {
|
||||
return d.account
|
||||
}
|
||||
|
||||
// Service is the beacon block proposer service.
|
||||
type Service interface {
|
||||
// Prepare prepares the proposal for a slot.
|
||||
|
|
|
@ -26,7 +26,6 @@ import (
|
|||
"github.com/attestantio/vouch/services/metrics"
|
||||
"github.com/attestantio/vouch/services/submitter"
|
||||
"github.com/pkg/errors"
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"github.com/rs/zerolog"
|
||||
zerologger "github.com/rs/zerolog/log"
|
||||
)
|
||||
|
@ -76,11 +75,11 @@ func (s *Service) Prepare(ctx context.Context, data interface{}) error {
|
|||
if !ok {
|
||||
return errors.New("passed invalid data structure")
|
||||
}
|
||||
log := log.With().Uint64("slot", duty.Slot()).Uint64("validator_index", duty.ValidatorIndex()).Logger()
|
||||
log := log.With().Uint64("slot", uint64(duty.Slot())).Uint64("validator_index", uint64(duty.ValidatorIndex())).Logger()
|
||||
log.Trace().Msg("Preparing")
|
||||
|
||||
// Fetch the validating account.
|
||||
accounts, err := s.validatingAccountsProvider.AccountsByIndex(ctx, []uint64{duty.ValidatorIndex()})
|
||||
accounts, err := s.validatingAccountsProvider.AccountsByIndex(ctx, []spec.ValidatorIndex{duty.ValidatorIndex()})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to obtain proposing validator account")
|
||||
}
|
||||
|
@ -89,6 +88,7 @@ func (s *Service) Prepare(ctx context.Context, data interface{}) error {
|
|||
}
|
||||
account := accounts[0]
|
||||
log.Trace().Dur("elapsed", time.Since(started)).Msg("Obtained proposing account")
|
||||
duty.SetAccount(account)
|
||||
|
||||
revealSigner, isRevealSigner := account.(accountmanager.RANDAORevealSigner)
|
||||
if !isRevealSigner {
|
||||
|
@ -114,25 +114,11 @@ func (s *Service) Propose(ctx context.Context, data interface{}) {
|
|||
s.monitor.BeaconBlockProposalCompleted(started, "failed")
|
||||
return
|
||||
}
|
||||
log := log.With().Uint64("slot", duty.Slot()).Uint64("validator_index", duty.ValidatorIndex()).Logger()
|
||||
log := log.With().Uint64("slot", uint64(duty.Slot())).Uint64("validator_index", uint64(duty.ValidatorIndex())).Logger()
|
||||
log.Trace().Msg("Proposing")
|
||||
|
||||
// Fetch the validating account.
|
||||
accounts, err := s.validatingAccountsProvider.AccountsByIndex(ctx, []uint64{duty.ValidatorIndex()})
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to obtain proposing validator account")
|
||||
s.monitor.BeaconBlockProposalCompleted(started, "failed")
|
||||
return
|
||||
}
|
||||
if len(accounts) != 1 {
|
||||
log.Error().Err(err).Msg("Unknown proposing validator account")
|
||||
s.monitor.BeaconBlockProposalCompleted(started, "failed")
|
||||
return
|
||||
}
|
||||
account := accounts[0]
|
||||
log.Trace().Dur("elapsed", time.Since(started)).Msg("Obtained account")
|
||||
|
||||
var graffiti []byte
|
||||
var err error
|
||||
if s.graffitiProvider != nil {
|
||||
graffiti, err = s.graffitiProvider.Graffiti(ctx, duty.Slot(), duty.ValidatorIndex())
|
||||
if err != nil {
|
||||
|
@ -156,7 +142,7 @@ func (s *Service) Propose(ctx context.Context, data interface{}) {
|
|||
log.Trace().Dur("elapsed", time.Since(started)).Msg("Obtained proposal")
|
||||
|
||||
if proposal.Slot != duty.Slot() {
|
||||
log.Error().Uint64("proposal_slot", proposal.Slot).Msg("Proposal data for incorrect slot; not proceeding")
|
||||
log.Error().Uint64("proposal_slot", uint64(proposal.Slot)).Msg("Proposal data for incorrect slot; not proceeding")
|
||||
s.monitor.BeaconBlockProposalCompleted(started, "failed")
|
||||
return
|
||||
}
|
||||
|
@ -167,27 +153,20 @@ func (s *Service) Propose(ctx context.Context, data interface{}) {
|
|||
s.monitor.BeaconBlockProposalCompleted(started, "failed")
|
||||
return
|
||||
}
|
||||
proposalData := ðpb.BeaconBlockHeader{
|
||||
Slot: proposal.Slot,
|
||||
ProposerIndex: duty.ValidatorIndex(),
|
||||
ParentRoot: proposal.ParentRoot,
|
||||
StateRoot: proposal.StateRoot,
|
||||
BodyRoot: bodyRoot[:],
|
||||
}
|
||||
|
||||
// Sign the block.
|
||||
signer, isSigner := account.(accountmanager.BeaconBlockSigner)
|
||||
signer, isSigner := duty.Account().(accountmanager.BeaconBlockSigner)
|
||||
if !isSigner {
|
||||
log.Error().Msg("Account is not a beacon block signer")
|
||||
s.monitor.BeaconBlockProposalCompleted(started, "failed")
|
||||
return
|
||||
}
|
||||
sig, err := signer.SignBeaconBlockProposal(ctx,
|
||||
proposalData.Slot,
|
||||
proposalData.ProposerIndex,
|
||||
proposalData.ParentRoot,
|
||||
proposalData.StateRoot,
|
||||
proposalData.BodyRoot)
|
||||
proposal.Slot,
|
||||
duty.ValidatorIndex(),
|
||||
proposal.ParentRoot,
|
||||
proposal.StateRoot,
|
||||
bodyRoot)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to sign beacon block proposal")
|
||||
s.monitor.BeaconBlockProposalCompleted(started, "failed")
|
||||
|
|
|
@ -17,21 +17,21 @@ package beaconcommitteesubscriber
|
|||
import (
|
||||
"context"
|
||||
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/attestantio/vouch/services/accountmanager"
|
||||
)
|
||||
|
||||
// Subscription holds details of the committees to which we are subscribing.
|
||||
type Subscription struct {
|
||||
ValidatorIndex uint64
|
||||
ValidatorPubKey []byte
|
||||
CommitteeSize uint64
|
||||
Signature []byte
|
||||
Aggregate bool
|
||||
Duty *api.AttesterDuty
|
||||
IsAggregator bool
|
||||
// TODO is this in the correct place?
|
||||
Signature spec.BLSSignature
|
||||
}
|
||||
|
||||
// Service is the beacon committee subscriber service.
|
||||
type Service interface {
|
||||
// Subscribe subscribes to beacon committees for a given epoch.
|
||||
// It returns a map of slot => committee => subscription info.
|
||||
Subscribe(ctx context.Context, epoch uint64, accounts []accountmanager.ValidatingAccount) (map[uint64]map[uint64]*Subscription, error)
|
||||
Subscribe(ctx context.Context, epoch spec.Epoch, accounts []accountmanager.ValidatingAccount) (map[spec.Slot]map[spec.CommitteeIndex]*Subscription, error)
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ import (
|
|||
"time"
|
||||
|
||||
eth2client "github.com/attestantio/go-eth2-client"
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/attestantio/vouch/services/accountmanager"
|
||||
"github.com/attestantio/vouch/services/attestationaggregator"
|
||||
"github.com/attestantio/vouch/services/attester"
|
||||
|
@ -70,22 +72,29 @@ func New(ctx context.Context, params ...Parameter) (*Service, error) {
|
|||
|
||||
// Subscribe subscribes to beacon committees for a given epoch.
|
||||
// This returns data about the subnets to which we are subscribing.
|
||||
func (s *Service) Subscribe(ctx context.Context, epoch uint64, accounts []accountmanager.ValidatingAccount) (map[uint64]map[uint64]*beaconcommitteesubscriber.Subscription, error) {
|
||||
func (s *Service) Subscribe(ctx context.Context,
|
||||
epoch spec.Epoch,
|
||||
accounts []accountmanager.ValidatingAccount,
|
||||
) (map[spec.Slot]map[spec.CommitteeIndex]*beaconcommitteesubscriber.Subscription, error) {
|
||||
started := time.Now()
|
||||
|
||||
log := log.With().Uint64("epoch", epoch).Logger()
|
||||
log := log.With().Uint64("epoch", uint64(epoch)).Logger()
|
||||
log.Trace().Msg("Subscribing")
|
||||
|
||||
idProviders := make([]eth2client.ValidatorIDProvider, len(accounts))
|
||||
validatorIDs := make([]spec.ValidatorIndex, len(accounts))
|
||||
var err error
|
||||
for i, account := range accounts {
|
||||
idProviders[i] = account.(eth2client.ValidatorIDProvider)
|
||||
validatorIDs[i], err = account.Index(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to obtain account index")
|
||||
}
|
||||
}
|
||||
attesterDuties, err := s.attesterDutiesProvider.AttesterDuties(ctx, epoch, idProviders)
|
||||
attesterDuties, err := s.attesterDutiesProvider.AttesterDuties(ctx, epoch, validatorIDs)
|
||||
if err != nil {
|
||||
s.monitor.BeaconCommitteeSubscriptionCompleted(started, "failed")
|
||||
return nil, errors.Wrap(err, "failed to obtain attester duties")
|
||||
}
|
||||
log.Trace().Dur("elapsed", time.Since(started)).Int("accounts", len(idProviders)).Msg("Fetched attester duties")
|
||||
log.Trace().Dur("elapsed", time.Since(started)).Int("accounts", len(validatorIDs)).Msg("Fetched attester duties")
|
||||
duties, err := attester.MergeDuties(ctx, attesterDuties)
|
||||
if err != nil {
|
||||
s.monitor.BeaconCommitteeSubscriptionCompleted(started, "failed")
|
||||
|
@ -105,7 +114,7 @@ func (s *Service) Subscribe(ctx context.Context, epoch uint64, accounts []accoun
|
|||
for _, v := range subscriptionInfo {
|
||||
for _, v2 := range v {
|
||||
subscriptions++
|
||||
if v2.Aggregate {
|
||||
if v2.IsAggregator {
|
||||
aggregators++
|
||||
}
|
||||
}
|
||||
|
@ -116,17 +125,15 @@ func (s *Service) Subscribe(ctx context.Context, epoch uint64, accounts []accoun
|
|||
// Submit the subscription information.
|
||||
go func() {
|
||||
log.Trace().Msg("Submitting subscription")
|
||||
subscriptions := make([]*submitter.BeaconCommitteeSubscription, 0, len(duties))
|
||||
subscriptions := make([]*api.BeaconCommitteeSubscription, 0, len(duties))
|
||||
for slot, slotInfo := range subscriptionInfo {
|
||||
for committeeIndex, info := range slotInfo {
|
||||
subscriptions = append(subscriptions, &submitter.BeaconCommitteeSubscription{
|
||||
Slot: slot,
|
||||
CommitteeIndex: committeeIndex,
|
||||
CommitteeSize: info.CommitteeSize,
|
||||
ValidatorIndex: info.ValidatorIndex,
|
||||
ValidatorPubKey: info.ValidatorPubKey,
|
||||
Aggregate: info.Aggregate,
|
||||
Signature: info.Signature,
|
||||
subscriptions = append(subscriptions, &api.BeaconCommitteeSubscription{
|
||||
ValidatorIndex: info.Duty.ValidatorIndex,
|
||||
Slot: slot,
|
||||
CommitteeIndex: committeeIndex,
|
||||
CommitteesAtSlot: info.Duty.CommitteesAtSlot,
|
||||
IsAggregator: info.IsAggregator,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -146,17 +153,17 @@ func (s *Service) Subscribe(ctx context.Context, epoch uint64, accounts []accoun
|
|||
// calculateSubscriptionInfo calculates our beacon block attesation subnet requirements given a set of duties.
|
||||
// It returns a map of slot => committee => subscription information.
|
||||
func (s *Service) calculateSubscriptionInfo(ctx context.Context,
|
||||
epoch uint64,
|
||||
epoch spec.Epoch,
|
||||
accounts []accountmanager.ValidatingAccount,
|
||||
duties []*attester.Duty,
|
||||
) (map[uint64]map[uint64]*beaconcommitteesubscriber.Subscription, error) {
|
||||
) (map[spec.Slot]map[spec.CommitteeIndex]*beaconcommitteesubscriber.Subscription, error) {
|
||||
|
||||
// Map is slot => committee => info.
|
||||
subscriptionInfo := make(map[uint64]map[uint64]*beaconcommitteesubscriber.Subscription)
|
||||
subscriptionInfo := make(map[spec.Slot]map[spec.CommitteeIndex]*beaconcommitteesubscriber.Subscription)
|
||||
subscriptionInfoMutex := deadlock.RWMutex{}
|
||||
|
||||
// Map is validator ID => account.
|
||||
accountMap := make(map[uint64]accountmanager.ValidatingAccount, len(accounts))
|
||||
accountMap := make(map[spec.ValidatorIndex]accountmanager.ValidatingAccount, len(accounts))
|
||||
for _, account := range accounts {
|
||||
index, err := account.Index(ctx)
|
||||
if err != nil {
|
||||
|
@ -187,7 +194,7 @@ func (s *Service) calculateSubscriptionInfo(ctx context.Context,
|
|||
subscriptionInfoMutex.RLock()
|
||||
info, exists := subscriptionInfo[duty.Slot()][duty.CommitteeIndices()[i]]
|
||||
subscriptionInfoMutex.RUnlock()
|
||||
if exists && info.Aggregate {
|
||||
if exists && info.IsAggregator {
|
||||
// Already an aggregator for this slot/committee; don't need to go further.
|
||||
return
|
||||
}
|
||||
|
@ -201,26 +208,27 @@ func (s *Service) calculateSubscriptionInfo(ctx context.Context,
|
|||
log.Error().Err(err).Msg("Failed to calculate if validator is an aggregator")
|
||||
return
|
||||
}
|
||||
account, exists := accountMap[duty.ValidatorIndices()[i]]
|
||||
if !exists {
|
||||
log.Error().Uint64("validator_index", duty.ValidatorIndices()[i]).Msg("Failed to obtain validator account")
|
||||
pubKey, err := accountMap[duty.ValidatorIndices()[i]].PubKey(ctx)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to obtain validator's public key")
|
||||
return
|
||||
}
|
||||
subscriptionInfoMutex.Lock()
|
||||
if _, exists := subscriptionInfo[duty.Slot()]; !exists {
|
||||
subscriptionInfo[duty.Slot()] = make(map[uint64]*beaconcommitteesubscriber.Subscription)
|
||||
}
|
||||
pubKey, err := account.PubKey(ctx)
|
||||
if err != nil {
|
||||
log.Error().Uint64("validator_index", duty.ValidatorIndices()[i]).Err(err).Msg("Failed to obtain validator public key")
|
||||
return
|
||||
subscriptionInfo[duty.Slot()] = make(map[spec.CommitteeIndex]*beaconcommitteesubscriber.Subscription)
|
||||
}
|
||||
subscriptionInfo[duty.Slot()][duty.CommitteeIndices()[i]] = &beaconcommitteesubscriber.Subscription{
|
||||
ValidatorIndex: duty.ValidatorIndices()[i],
|
||||
ValidatorPubKey: pubKey,
|
||||
CommitteeSize: duty.CommitteeSize(duty.CommitteeIndices()[i]),
|
||||
Signature: signature,
|
||||
Aggregate: isAggregator,
|
||||
Duty: &api.AttesterDuty{
|
||||
PubKey: pubKey,
|
||||
Slot: duty.Slot(),
|
||||
ValidatorIndex: duty.ValidatorIndices()[i],
|
||||
CommitteeIndex: duty.CommitteeIndices()[i],
|
||||
CommitteeLength: duty.CommitteeSize(duty.CommitteeIndices()[i]),
|
||||
CommitteesAtSlot: duty.CommitteesAtSlot(),
|
||||
ValidatorCommitteeIndex: duty.ValidatorCommitteeIndices()[i],
|
||||
},
|
||||
IsAggregator: isAggregator,
|
||||
Signature: signature,
|
||||
}
|
||||
subscriptionInfoMutex.Unlock()
|
||||
}(ctx, sem, wg, duty, i)
|
||||
|
|
|
@ -13,22 +13,26 @@
|
|||
|
||||
package chaintime
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"time"
|
||||
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
)
|
||||
|
||||
// Service provides a number of functions for calculating chain-related times.
|
||||
type Service interface {
|
||||
// GenesisTime provides the time of the chain's genesis.
|
||||
GenesisTime() time.Time
|
||||
// StartOfSlot provides the time at which a given slot starts.
|
||||
StartOfSlot(slot uint64) time.Time
|
||||
StartOfSlot(slot spec.Slot) time.Time
|
||||
// StartOfEpoch provides the time at which a given epoch starts.
|
||||
StartOfEpoch(epoch uint64) time.Time
|
||||
StartOfEpoch(epoch spec.Epoch) time.Time
|
||||
// CurrentSlot provides the current slot.
|
||||
CurrentSlot() uint64
|
||||
CurrentSlot() spec.Slot
|
||||
// CurrentEpoch provides the current epoch.
|
||||
CurrentEpoch() uint64
|
||||
CurrentEpoch() spec.Epoch
|
||||
// SlotToEpoch provides the epoch of the given slot.
|
||||
SlotToEpoch(slot uint64) uint64
|
||||
SlotToEpoch(slot spec.Slot) spec.Epoch
|
||||
// FirstSlotOfEpoch provides the first slot of the given epoch.
|
||||
FirstSlotOfEpoch(epoch uint64) uint64
|
||||
FirstSlotOfEpoch(epoch spec.Epoch) spec.Slot
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
"context"
|
||||
"time"
|
||||
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog"
|
||||
zerologger "github.com/rs/zerolog/log"
|
||||
|
@ -78,37 +79,37 @@ func (s *Service) GenesisTime() time.Time {
|
|||
}
|
||||
|
||||
// StartOfSlot provides the time at which a given slot starts.
|
||||
func (s *Service) StartOfSlot(slot uint64) time.Time {
|
||||
func (s *Service) StartOfSlot(slot spec.Slot) time.Time {
|
||||
return s.genesisTime.Add(time.Duration(slot) * s.slotDuration)
|
||||
}
|
||||
|
||||
// StartOfEpoch provides the time at which a given epoch starts.
|
||||
func (s *Service) StartOfEpoch(epoch uint64) time.Time {
|
||||
return s.genesisTime.Add(time.Duration(epoch*s.slotsPerEpoch) * s.slotDuration)
|
||||
func (s *Service) StartOfEpoch(epoch spec.Epoch) time.Time {
|
||||
return s.genesisTime.Add(time.Duration(uint64(epoch)*s.slotsPerEpoch) * s.slotDuration)
|
||||
}
|
||||
|
||||
// CurrentSlot provides the current slot.
|
||||
func (s *Service) CurrentSlot() uint64 {
|
||||
func (s *Service) CurrentSlot() spec.Slot {
|
||||
if s.genesisTime.After(time.Now()) {
|
||||
return 0
|
||||
return spec.Slot(0)
|
||||
}
|
||||
return uint64(time.Since(s.genesisTime).Seconds()) / uint64(s.slotDuration.Seconds())
|
||||
return spec.Slot(uint64(time.Since(s.genesisTime).Seconds()) / uint64(s.slotDuration.Seconds()))
|
||||
}
|
||||
|
||||
// CurrentEpoch provides the current epoch.
|
||||
func (s *Service) CurrentEpoch() uint64 {
|
||||
func (s *Service) CurrentEpoch() spec.Epoch {
|
||||
if s.genesisTime.After(time.Now()) {
|
||||
return 0
|
||||
return spec.Epoch(0)
|
||||
}
|
||||
return uint64(time.Since(s.genesisTime).Seconds()) / (uint64(s.slotDuration.Seconds()) * s.slotsPerEpoch)
|
||||
return spec.Epoch(uint64(time.Since(s.genesisTime).Seconds()) / (uint64(s.slotDuration.Seconds()) * s.slotsPerEpoch))
|
||||
}
|
||||
|
||||
// SlotToEpoch provides the epoch of a given slot.
|
||||
func (s *Service) SlotToEpoch(slot uint64) uint64 {
|
||||
return slot / s.slotsPerEpoch
|
||||
func (s *Service) SlotToEpoch(slot spec.Slot) spec.Epoch {
|
||||
return spec.Epoch(uint64(slot) / s.slotsPerEpoch)
|
||||
}
|
||||
|
||||
// FirstSlotOfEpoch provides the first slot of the given epoch.
|
||||
func (s *Service) FirstSlotOfEpoch(epoch uint64) uint64 {
|
||||
return epoch * s.slotsPerEpoch
|
||||
func (s *Service) FirstSlotOfEpoch(epoch spec.Epoch) spec.Slot {
|
||||
return spec.Slot(uint64(epoch) * s.slotsPerEpoch)
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/attestantio/vouch/mock"
|
||||
"github.com/attestantio/vouch/services/chaintime"
|
||||
"github.com/attestantio/vouch/services/chaintime/standard"
|
||||
|
@ -143,7 +144,7 @@ func TestCurrentSlot(t *testing.T) {
|
|||
s, err := createMockService(slotDuration, slotsPerEpoch, genesisTime)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, uint64(5), s.CurrentSlot())
|
||||
require.Equal(t, spec.Slot(5), s.CurrentSlot())
|
||||
}
|
||||
|
||||
func TestCurrentSlotPreGenesis(t *testing.T) {
|
||||
|
@ -154,7 +155,7 @@ func TestCurrentSlotPreGenesis(t *testing.T) {
|
|||
s, err := createMockService(slotDuration, slotsPerEpoch, genesisTime)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, uint64(0), s.CurrentSlot())
|
||||
require.Equal(t, spec.Slot(0), s.CurrentSlot())
|
||||
}
|
||||
|
||||
func TestCurrentEpoch(t *testing.T) {
|
||||
|
@ -165,7 +166,7 @@ func TestCurrentEpoch(t *testing.T) {
|
|||
s, err := createMockService(slotDuration, slotsPerEpoch, genesisTime)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, uint64(2), s.CurrentEpoch())
|
||||
require.Equal(t, spec.Epoch(2), s.CurrentEpoch())
|
||||
}
|
||||
|
||||
func TestCurrentEpochPreGenesis(t *testing.T) {
|
||||
|
@ -176,14 +177,14 @@ func TestCurrentEpochPreGenesis(t *testing.T) {
|
|||
s, err := createMockService(slotDuration, slotsPerEpoch, genesisTime)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, uint64(0), s.CurrentEpoch())
|
||||
require.Equal(t, spec.Epoch(0), s.CurrentEpoch())
|
||||
}
|
||||
|
||||
func TestSlotToEpoch(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
slot uint64
|
||||
epoch uint64
|
||||
slot spec.Slot
|
||||
epoch spec.Epoch
|
||||
}{
|
||||
{
|
||||
name: "ZeroFirstSlot",
|
||||
|
@ -220,8 +221,8 @@ func TestSlotToEpoch(t *testing.T) {
|
|||
func TestFirstSlotOfEpoch(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
epoch uint64
|
||||
slot uint64
|
||||
epoch spec.Epoch
|
||||
slot spec.Slot
|
||||
}{
|
||||
{
|
||||
name: "Zero",
|
||||
|
|
|
@ -17,8 +17,8 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
eth2client "github.com/attestantio/go-eth2-client"
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/attestantio/vouch/services/accountmanager"
|
||||
"github.com/attestantio/vouch/services/attestationaggregator"
|
||||
"github.com/attestantio/vouch/services/attester"
|
||||
|
@ -26,16 +26,21 @@ import (
|
|||
|
||||
// createAttesterJobs creates attestation jobs for the given epoch provided accounts.
|
||||
func (s *Service) createAttesterJobs(ctx context.Context,
|
||||
epoch uint64,
|
||||
epoch spec.Epoch,
|
||||
accounts []accountmanager.ValidatingAccount,
|
||||
firstRun bool) {
|
||||
log.Trace().Msg("Creating attester jobs")
|
||||
|
||||
idProviders := make([]eth2client.ValidatorIDProvider, len(accounts))
|
||||
validatorIDs := make([]spec.ValidatorIndex, len(accounts))
|
||||
var err error
|
||||
for i, account := range accounts {
|
||||
idProviders[i] = account.(eth2client.ValidatorIDProvider)
|
||||
validatorIDs[i], err = account.Index(ctx)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to obtain account index")
|
||||
return
|
||||
}
|
||||
}
|
||||
resp, err := s.attesterDutiesProvider.AttesterDuties(ctx, epoch, idProviders)
|
||||
resp, err := s.attesterDutiesProvider.AttesterDuties(ctx, epoch, validatorIDs)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to obtain attester duties")
|
||||
return
|
||||
|
@ -43,11 +48,11 @@ func (s *Service) createAttesterJobs(ctx context.Context,
|
|||
|
||||
// Filter bad responses.
|
||||
filteredDuties := make([]*api.AttesterDuty, 0, len(resp))
|
||||
firstSlot := epoch * s.slotsPerEpoch
|
||||
lastSlot := (epoch+1)*s.slotsPerEpoch - 1
|
||||
firstSlot := spec.Slot(uint64(epoch) * s.slotsPerEpoch)
|
||||
lastSlot := spec.Slot((uint64(epoch)+1)*s.slotsPerEpoch - 1)
|
||||
for _, duty := range resp {
|
||||
if duty.Slot < firstSlot || duty.Slot > lastSlot {
|
||||
log.Warn().Uint64("epoch", epoch).Uint64("duty_slot", duty.Slot).Msg("Attester duty has invalid slot for requested epoch; ignoring")
|
||||
log.Warn().Uint64("epoch", uint64(epoch)).Uint64("duty_slot", uint64(duty.Slot)).Msg("Attester duty has invalid slot for requested epoch; ignoring")
|
||||
continue
|
||||
}
|
||||
filteredDuties = append(filteredDuties, duty)
|
||||
|
@ -59,24 +64,24 @@ func (s *Service) createAttesterJobs(ctx context.Context,
|
|||
return
|
||||
}
|
||||
|
||||
for _, duty := range duties {
|
||||
log.
|
||||
Trace().
|
||||
Uint64("slot", duty.Slot()).
|
||||
Uints64("committee_indices", duty.CommitteeIndices()).
|
||||
Uints64("validator_indices", duty.ValidatorCommitteeIndices()).
|
||||
Msg("Received attester duty")
|
||||
if e := log.Trace(); e.Enabled() {
|
||||
for _, duty := range duties {
|
||||
log.Trace().
|
||||
Uint64("slot", uint64(duty.Slot())).
|
||||
Strs("duties", duty.Tuples()).
|
||||
Msg("Received attester duties")
|
||||
}
|
||||
}
|
||||
|
||||
currentSlot := s.chainTimeService.CurrentSlot()
|
||||
for _, duty := range duties {
|
||||
// Do not schedule attestations for past slots (or the current slot if we've just started).
|
||||
if duty.Slot() < currentSlot {
|
||||
log.Debug().Uint64("attestation_slot", duty.Slot()).Uint64("current_slot", currentSlot).Msg("Attestation in the past; not scheduling")
|
||||
log.Debug().Uint64("attestation_slot", uint64(duty.Slot())).Uint64("current_slot", uint64(currentSlot)).Msg("Attestation for a past slot; not scheduling")
|
||||
continue
|
||||
}
|
||||
if firstRun && duty.Slot() == currentSlot {
|
||||
log.Debug().Uint64("attestation_slot", duty.Slot()).Uint64("current_slot", currentSlot).Msg("Attestation in the current slot and this is our first run; not scheduling")
|
||||
log.Debug().Uint64("attestation_slot", uint64(duty.Slot())).Uint64("current_slot", uint64(currentSlot)).Msg("Attestation for the current slot and this is our first run; not scheduling")
|
||||
continue
|
||||
}
|
||||
if err := s.scheduler.ScheduleJob(ctx,
|
||||
|
@ -110,38 +115,45 @@ func (s *Service) AttestAndScheduleAggregate(ctx context.Context, data interface
|
|||
return
|
||||
}
|
||||
|
||||
epoch := attestations[0].Data.Slot / s.slotsPerEpoch
|
||||
epoch := s.chainTimeService.SlotToEpoch(attestations[0].Data.Slot)
|
||||
s.subscriptionInfosMutex.Lock()
|
||||
subscriptionInfoMap, exists := s.subscriptionInfos[epoch]
|
||||
s.subscriptionInfosMutex.Unlock()
|
||||
if !exists {
|
||||
log.Warn().Msg("No subscription info for this epoch; cannot aggregate")
|
||||
log.Debug().Uint64("epoch", uint64(epoch)).Msg("No subscription info for this epoch; not aggregating")
|
||||
return
|
||||
}
|
||||
|
||||
for _, attestation := range attestations {
|
||||
log := log.With().Uint64("attestation_slot", uint64(attestation.Data.Slot)).Logger()
|
||||
slotInfoMap, exists := subscriptionInfoMap[attestation.Data.Slot]
|
||||
if !exists {
|
||||
log.Debug().Uint64("attestation_slot", attestation.Data.Slot).Msg("No slot info; cannot aggregate")
|
||||
log.Debug().Msg("No slot info; not aggregating")
|
||||
continue
|
||||
}
|
||||
// Do not schedule aggregations for past slots.
|
||||
if attestation.Data.Slot < s.chainTimeService.CurrentSlot() {
|
||||
log.Debug().Uint64("aggregation_slot", attestation.Data.Slot).Uint64("current_slot", s.chainTimeService.CurrentSlot()).Msg("Aggregation in the past; not scheduling")
|
||||
log.Debug().Uint64("current_slot", uint64(s.chainTimeService.CurrentSlot())).Msg("Aggregation in the past; not scheduling")
|
||||
continue
|
||||
}
|
||||
info, exists := slotInfoMap[attestation.Data.Index]
|
||||
if !exists {
|
||||
log.Debug().Uint64("attestation_slot", attestation.Data.Slot).Uint64("committee_index", attestation.Data.Index).Msg("No committee info; cannot aggregate")
|
||||
log.Debug().Uint64("committee_index", uint64(attestation.Data.Index)).Msg("No committee info; not aggregating")
|
||||
continue
|
||||
}
|
||||
if info.Aggregate {
|
||||
aggregatorDuty, err := attestationaggregator.NewDuty(ctx, info.ValidatorIndex, info.ValidatorPubKey, attestation, info.Signature)
|
||||
if info.IsAggregator {
|
||||
attestationDataRoot, err := attestation.Data.HashTreeRoot()
|
||||
if err != nil {
|
||||
// Don't return here; we want to try to set up as many aggregator jobs as possible.
|
||||
log.Error().Err(err).Msg("Failed to create beacon block attestation aggregation duty")
|
||||
log.Error().Err(err).Msg("Failed to obtain hash tree root of attestation")
|
||||
continue
|
||||
}
|
||||
aggregatorDuty := &attestationaggregator.Duty{
|
||||
Slot: info.Duty.Slot,
|
||||
AttestationDataRoot: attestationDataRoot,
|
||||
ValidatorIndex: info.Duty.ValidatorIndex,
|
||||
SlotSignature: info.Signature,
|
||||
}
|
||||
if err := s.scheduler.ScheduleJob(ctx,
|
||||
fmt.Sprintf("Beacon block attestation aggregation for slot %d committee %d", attestation.Data.Slot, attestation.Data.Index),
|
||||
s.chainTimeService.StartOfSlot(attestation.Data.Slot).Add(s.slotDuration*2/3),
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright © 2020 Attestant Limited.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package standard
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
)
|
||||
|
||||
// HandleHeadEvent handles the "head" events from the beacon node.
|
||||
func (s *Service) HandleHeadEvent(event *api.Event) {
|
||||
ctx := context.Background()
|
||||
data := event.Data.(*api.HeadEvent)
|
||||
log.Trace().Uint64("slot", uint64(data.Slot)).Msg("Received head event")
|
||||
|
||||
if data.Slot != s.chainTimeService.CurrentSlot() {
|
||||
return
|
||||
}
|
||||
s.monitor.BlockDelay(time.Since(s.chainTimeService.StartOfSlot(data.Slot)))
|
||||
|
||||
// Kick off attestations for the block's slot immediately.
|
||||
jobName := fmt.Sprintf("Beacon block attestations for slot %d", data.Slot)
|
||||
if s.scheduler.JobExists(ctx, jobName) {
|
||||
log.Trace().Uint64("slot", uint64(data.Slot)).Msg("Kicking off attestations for slot early due to receiving relevant block")
|
||||
if err := s.scheduler.RunJobIfExists(ctx, jobName); err != nil {
|
||||
log.Error().Str("job", jobName).Err(err).Msg("Failed to run attester job")
|
||||
}
|
||||
}
|
||||
|
||||
// If the head is in a new fork it may result in different attester duties.
|
||||
// TODO
|
||||
|
||||
// Remove old subscriptions if present.
|
||||
delete(s.subscriptionInfos, s.chainTimeService.SlotToEpoch(data.Slot)-2)
|
||||
}
|
|
@ -28,20 +28,20 @@ import (
|
|||
)
|
||||
|
||||
type parameters struct {
|
||||
logLevel zerolog.Level
|
||||
monitor metrics.ControllerMonitor
|
||||
slotDurationProvider eth2client.SlotDurationProvider
|
||||
slotsPerEpochProvider eth2client.SlotsPerEpochProvider
|
||||
chainTimeService chaintime.Service
|
||||
proposerDutiesProvider eth2client.ProposerDutiesProvider
|
||||
attesterDutiesProvider eth2client.AttesterDutiesProvider
|
||||
validatingAccountsProvider accountmanager.ValidatingAccountsProvider
|
||||
scheduler scheduler.Service
|
||||
beaconChainHeadUpdatedSource eth2client.BeaconChainHeadUpdatedSource
|
||||
attester attester.Service
|
||||
beaconBlockProposer beaconblockproposer.Service
|
||||
attestationAggregator attestationaggregator.Service
|
||||
beaconCommitteeSubscriber beaconcommitteesubscriber.Service
|
||||
logLevel zerolog.Level
|
||||
monitor metrics.ControllerMonitor
|
||||
slotDurationProvider eth2client.SlotDurationProvider
|
||||
slotsPerEpochProvider eth2client.SlotsPerEpochProvider
|
||||
chainTimeService chaintime.Service
|
||||
proposerDutiesProvider eth2client.ProposerDutiesProvider
|
||||
attesterDutiesProvider eth2client.AttesterDutiesProvider
|
||||
validatingAccountsProvider accountmanager.ValidatingAccountsProvider
|
||||
scheduler scheduler.Service
|
||||
eventsProvider eth2client.EventsProvider
|
||||
attester attester.Service
|
||||
beaconBlockProposer beaconblockproposer.Service
|
||||
attestationAggregator attestationaggregator.Service
|
||||
beaconCommitteeSubscriber beaconcommitteesubscriber.Service
|
||||
}
|
||||
|
||||
// Parameter is the interface for service parameters.
|
||||
|
@ -104,10 +104,10 @@ func WithAttesterDutiesProvider(provider eth2client.AttesterDutiesProvider) Para
|
|||
})
|
||||
}
|
||||
|
||||
// WithBeaconChainHeadUpdatedSource sets the source for an OnBeaconChainHeadUpdated request
|
||||
func WithBeaconChainHeadUpdatedSource(source eth2client.BeaconChainHeadUpdatedSource) Parameter {
|
||||
// WithEventsProvider sets the events provider.
|
||||
func WithEventsProvider(provider eth2client.EventsProvider) Parameter {
|
||||
return parameterFunc(func(p *parameters) {
|
||||
p.beaconChainHeadUpdatedSource = source
|
||||
p.eventsProvider = provider
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -182,8 +182,8 @@ func parseAndCheckParameters(params ...Parameter) (*parameters, error) {
|
|||
if parameters.attesterDutiesProvider == nil {
|
||||
return nil, errors.New("no attester duties provider specified")
|
||||
}
|
||||
if parameters.beaconChainHeadUpdatedSource == nil {
|
||||
return nil, errors.New("no beacon chain head updated source specified")
|
||||
if parameters.eventsProvider == nil {
|
||||
return nil, errors.New("no events provider specified")
|
||||
}
|
||||
if parameters.scheduler == nil {
|
||||
return nil, errors.New("no scheduler service specified")
|
||||
|
|
|
@ -17,22 +17,29 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
eth2client "github.com/attestantio/go-eth2-client"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/attestantio/vouch/services/accountmanager"
|
||||
"github.com/attestantio/vouch/services/beaconblockproposer"
|
||||
)
|
||||
|
||||
// createProposerJobs creates proposal jobs for the given epoch.
|
||||
func (s *Service) createProposerJobs(ctx context.Context,
|
||||
epoch uint64,
|
||||
epoch spec.Epoch,
|
||||
accounts []accountmanager.ValidatingAccount,
|
||||
firstRun bool) {
|
||||
validatorIDProviders := make([]eth2client.ValidatorIDProvider, len(accounts))
|
||||
log.Trace().Msg("Creating proposer jobs")
|
||||
|
||||
validatorIDs := make([]spec.ValidatorIndex, len(accounts))
|
||||
var err error
|
||||
for i, account := range accounts {
|
||||
validatorIDProviders[i] = account
|
||||
validatorIDs[i], err = account.Index(ctx)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to obtain account index")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := s.proposerDutiesProvider.ProposerDuties(ctx, epoch, validatorIDProviders)
|
||||
resp, err := s.proposerDutiesProvider.ProposerDuties(ctx, epoch, validatorIDs)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to obtain proposer duties")
|
||||
return
|
||||
|
@ -40,11 +47,11 @@ func (s *Service) createProposerJobs(ctx context.Context,
|
|||
|
||||
// Filter bad responses.
|
||||
duties := make([]*beaconblockproposer.Duty, 0, len(resp))
|
||||
firstSlot := epoch * s.slotsPerEpoch
|
||||
lastSlot := (epoch+1)*s.slotsPerEpoch - 1
|
||||
firstSlot := s.chainTimeService.FirstSlotOfEpoch(epoch)
|
||||
lastSlot := s.chainTimeService.FirstSlotOfEpoch(epoch+1) - 1
|
||||
for _, respDuty := range resp {
|
||||
if respDuty.Slot < firstSlot || respDuty.Slot > lastSlot {
|
||||
log.Warn().Uint64("epoch", epoch).Uint64("duty_slot", respDuty.Slot).Msg("Proposer duty has invalid slot for requested epoch; ignoring")
|
||||
log.Warn().Uint64("epoch", uint64(epoch)).Uint64("duty_slot", uint64(respDuty.Slot)).Msg("Proposer duty has invalid slot for requested epoch; ignoring")
|
||||
continue
|
||||
}
|
||||
duty, err := beaconblockproposer.NewDuty(ctx, respDuty.Slot, respDuty.ValidatorIndex)
|
||||
|
@ -59,12 +66,12 @@ func (s *Service) createProposerJobs(ctx context.Context,
|
|||
for _, duty := range duties {
|
||||
// Do not schedule proposals for past slots (or the current slot if we've just started).
|
||||
if duty.Slot() < currentSlot || firstRun && duty.Slot() == currentSlot {
|
||||
log.Debug().Uint64("proposal_slot", duty.Slot()).Uint64("current_slot", currentSlot).Msg("Proposal in the past; not scheduling")
|
||||
log.Debug().Uint64("proposal_slot", uint64(duty.Slot())).Uint64("current_slot", uint64(currentSlot)).Msg("Proposal in the past; not scheduling")
|
||||
continue
|
||||
}
|
||||
go func(duty *beaconblockproposer.Duty) {
|
||||
if err := s.beaconBlockProposer.Prepare(ctx, duty); err != nil {
|
||||
log.Error().Uint64("proposal_slot", duty.Slot()).Err(err).Msg("Failed to prepare proposal")
|
||||
log.Error().Uint64("proposal_slot", uint64(duty.Slot())).Err(err).Msg("Failed to prepare proposal")
|
||||
return
|
||||
}
|
||||
if err := s.scheduler.ScheduleJob(ctx,
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"time"
|
||||
|
||||
eth2client "github.com/attestantio/go-eth2-client"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/attestantio/vouch/services/accountmanager"
|
||||
"github.com/attestantio/vouch/services/attestationaggregator"
|
||||
"github.com/attestantio/vouch/services/attester"
|
||||
|
@ -50,9 +51,8 @@ type Service struct {
|
|||
attestationAggregator attestationaggregator.Service
|
||||
beaconCommitteeSubscriber beaconcommitteesubscriber.Service
|
||||
activeAccounts int
|
||||
// Epoch => slot => committee => subscription info cache.
|
||||
subscriptionInfos map[uint64]map[uint64]map[uint64]*beaconcommitteesubscriber.Subscription
|
||||
subscriptionInfosMutex sync.Mutex
|
||||
subscriptionInfos map[spec.Epoch]map[spec.Slot]map[spec.CommitteeIndex]*beaconcommitteesubscriber.Subscription
|
||||
subscriptionInfosMutex sync.Mutex
|
||||
}
|
||||
|
||||
// module-wide log.
|
||||
|
@ -94,12 +94,13 @@ func New(ctx context.Context, params ...Parameter) (*Service, error) {
|
|||
beaconBlockProposer: parameters.beaconBlockProposer,
|
||||
attestationAggregator: parameters.attestationAggregator,
|
||||
beaconCommitteeSubscriber: parameters.beaconCommitteeSubscriber,
|
||||
subscriptionInfos: make(map[uint64]map[uint64]map[uint64]*beaconcommitteesubscriber.Subscription),
|
||||
subscriptionInfos: make(map[spec.Epoch]map[spec.Slot]map[spec.CommitteeIndex]*beaconcommitteesubscriber.Subscription),
|
||||
}
|
||||
|
||||
log.Trace().Msg("Adding beacon chain head updated handler")
|
||||
if err := parameters.beaconChainHeadUpdatedSource.AddOnBeaconChainHeadUpdatedHandler(ctx, s); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to add beacon chain head updated handler")
|
||||
// Subscribe to head events. This allows us to go early for attestations if a block arrives, as well as
|
||||
// re-request duties if there is a change in beacon block.
|
||||
if err := parameters.eventsProvider.Events(ctx, []string{"head"}, s.HandleHeadEvent); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to add head event handler")
|
||||
}
|
||||
|
||||
// Subscriptions are usually updated one epoch in advance, but as we're
|
||||
|
@ -206,10 +207,10 @@ func (s *Service) epochTicker(ctx context.Context, data interface{}) {
|
|||
epochTickerData := data.(*epochTickerData)
|
||||
currentEpoch := s.chainTimeService.CurrentEpoch()
|
||||
firstRun := epochTickerData.latestEpochRan == -1
|
||||
log.Trace().Uint64("epoch", currentEpoch).Bool("first_run", firstRun).Msg("Starting per-epoch duties")
|
||||
log.Trace().Uint64("epoch", uint64(currentEpoch)).Bool("first_run", firstRun).Msg("Starting per-epoch duties")
|
||||
epochTickerData.mutex.Lock()
|
||||
if epochTickerData.latestEpochRan >= int64(currentEpoch) {
|
||||
log.Trace().Uint64("epoch", currentEpoch).Msg("Already ran for this epoch; skipping")
|
||||
log.Trace().Uint64("epoch", uint64(currentEpoch)).Msg("Already ran for this epoch; skipping")
|
||||
epochTickerData.mutex.Unlock()
|
||||
return
|
||||
}
|
||||
|
@ -263,21 +264,21 @@ func (s *Service) epochTicker(ctx context.Context, data interface{}) {
|
|||
epochTickerData.atGenesis = false
|
||||
}
|
||||
|
||||
// OnBeaconChainHeadUpdated runs attestations for a slot immediately, if the update is for the current slot.
|
||||
func (s *Service) OnBeaconChainHeadUpdated(ctx context.Context, slot uint64, stateRoot []byte, bodyRoot []byte, epochTransitioni bool) {
|
||||
if slot != s.chainTimeService.CurrentSlot() {
|
||||
return
|
||||
}
|
||||
s.monitor.BlockDelay(time.Since(s.chainTimeService.StartOfSlot(slot)))
|
||||
|
||||
jobName := fmt.Sprintf("Beacon block attestations for slot %d", slot)
|
||||
if s.scheduler.JobExists(ctx, jobName) {
|
||||
log.Trace().Uint64("slot", slot).Msg("Kicking off attestations for slot early due to receiving relevant block")
|
||||
if err := s.scheduler.RunJobIfExists(ctx, jobName); err != nil {
|
||||
log.Error().Str("job", jobName).Err(err).Msg("Failed to run attester job")
|
||||
}
|
||||
}
|
||||
|
||||
// Remove old subscriptions if present.
|
||||
delete(s.subscriptionInfos, s.chainTimeService.SlotToEpoch(slot)-2)
|
||||
}
|
||||
// // OnBeaconChainHeadUpdated runs attestations for a slot immediately, if the update is for the current slot.
|
||||
// func (s *Service) OnBeaconChainHeadUpdated(ctx context.Context, slot uint64, stateRoot []byte, bodyRoot []byte, epochTransitioni bool) {
|
||||
// if slot != s.chainTimeService.CurrentSlot() {
|
||||
// return
|
||||
// }
|
||||
// s.monitor.BlockDelay(time.Since(s.chainTimeService.StartOfSlot(slot)))
|
||||
//
|
||||
// jobName := fmt.Sprintf("Beacon block attestations for slot %d", slot)
|
||||
// if s.scheduler.JobExists(ctx, jobName) {
|
||||
// log.Trace().Uint64("slot", slot).Msg("Kicking off attestations for slot early due to receiving relevant block")
|
||||
// if err := s.scheduler.RunJobIfExists(ctx, jobName); err != nil {
|
||||
// log.Error().Str("job", jobName).Err(err).Msg("Failed to run attester job")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Remove old subscriptions if present.
|
||||
// delete(s.subscriptionInfos, s.chainTimeService.SlotToEpoch(slot)-2)
|
||||
// }
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog"
|
||||
zerologger "github.com/rs/zerolog/log"
|
||||
|
@ -60,7 +61,7 @@ func New(ctx context.Context, params ...Parameter) (*Service, error) {
|
|||
}
|
||||
|
||||
// Graffiti provides graffiti.
|
||||
func (s *Service) Graffiti(ctx context.Context, slot uint64, validatorIndex uint64) ([]byte, error) {
|
||||
func (s *Service) Graffiti(ctx context.Context, slot spec.Slot, validatorIndex spec.ValidatorIndex) ([]byte, error) {
|
||||
// Replace location parameters with values.
|
||||
location := strings.ReplaceAll(s.location, "{{SLOT}}", fmt.Sprintf("%d", slot))
|
||||
location = strings.ReplaceAll(location, "{{VALIDATORINDEX}}", fmt.Sprintf("%d", validatorIndex))
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/attestantio/vouch/services/graffitiprovider/dynamic"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -182,7 +183,7 @@ func TestReplacement(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
for validatorIndex := uint64(0); validatorIndex < 16; validatorIndex++ {
|
||||
for slot := uint64(0); slot < 16; slot++ {
|
||||
graffiti, err := svc.Graffiti(ctx, slot, validatorIndex)
|
||||
graffiti, err := svc.Graffiti(ctx, spec.Slot(slot), spec.ValidatorIndex(validatorIndex))
|
||||
require.NoError(t, err)
|
||||
delete(expectedGraffitis, string(graffiti))
|
||||
}
|
||||
|
@ -298,7 +299,7 @@ func TestMultiline(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
for validatorIndex := uint64(0); validatorIndex < 16; validatorIndex++ {
|
||||
for slot := uint64(0); slot < 16; slot++ {
|
||||
graffiti, err := svc.Graffiti(ctx, slot, validatorIndex)
|
||||
graffiti, err := svc.Graffiti(ctx, spec.Slot(slot), spec.ValidatorIndex(validatorIndex))
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, test.expectedGraffitis, string(graffiti))
|
||||
delete(obtainedGraffitis, string(graffiti))
|
||||
|
|
|
@ -16,10 +16,12 @@ package graffitiprovider
|
|||
|
||||
import (
|
||||
"context"
|
||||
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
)
|
||||
|
||||
// Service is the graffiti provider service.
|
||||
type Service interface {
|
||||
// Graffiti returns the graffiti for a given slot and validator.
|
||||
Graffiti(ctx context.Context, slot uint64, validatorIndex uint64) ([]byte, error)
|
||||
Graffiti(ctx context.Context, slot spec.Slot, validatorIndex spec.ValidatorIndex) ([]byte, error)
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ package static
|
|||
import (
|
||||
"context"
|
||||
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog"
|
||||
zerologger "github.com/rs/zerolog/log"
|
||||
|
@ -50,6 +51,6 @@ func New(ctx context.Context, params ...Parameter) (*Service, error) {
|
|||
}
|
||||
|
||||
// Graffiti provides graffiti.
|
||||
func (s *Service) Graffiti(ctx context.Context, slot uint64, validatorIndex uint64) ([]byte, error) {
|
||||
func (s *Service) Graffiti(ctx context.Context, slot spec.Slot, validatorIndex spec.ValidatorIndex) ([]byte, error) {
|
||||
return s.graffiti, nil
|
||||
}
|
||||
|
|
|
@ -15,13 +15,18 @@
|
|||
package immediate
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
eth2client "github.com/attestantio/go-eth2-client"
|
||||
"github.com/attestantio/vouch/services/metrics"
|
||||
nullmetrics "github.com/attestantio/vouch/services/metrics/null"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
type parameters struct {
|
||||
logLevel zerolog.Level
|
||||
clientMonitor metrics.ClientMonitor
|
||||
beaconBlockSubmitter eth2client.BeaconBlockSubmitter
|
||||
attestationSubmitter eth2client.AttestationSubmitter
|
||||
beaconCommitteeSubscriptionsSubmitter eth2client.BeaconCommitteeSubscriptionsSubmitter
|
||||
|
@ -46,14 +51,21 @@ func WithLogLevel(logLevel zerolog.Level) Parameter {
|
|||
})
|
||||
}
|
||||
|
||||
// WithBeaconBlockSubmitter sets the beacon block submitter
|
||||
// WithClientMonitor sets the client monitor.
|
||||
func WithClientMonitor(clientMonitor metrics.ClientMonitor) Parameter {
|
||||
return parameterFunc(func(p *parameters) {
|
||||
p.clientMonitor = clientMonitor
|
||||
})
|
||||
}
|
||||
|
||||
// WithBeaconBlockSubmitter sets the beacon block submitter.
|
||||
func WithBeaconBlockSubmitter(submitter eth2client.BeaconBlockSubmitter) Parameter {
|
||||
return parameterFunc(func(p *parameters) {
|
||||
p.beaconBlockSubmitter = submitter
|
||||
})
|
||||
}
|
||||
|
||||
// WithAttestationSubmitter sets the attestation submitter
|
||||
// WithAttestationSubmitter sets the attestation submitter.
|
||||
func WithAttestationSubmitter(submitter eth2client.AttestationSubmitter) Parameter {
|
||||
return parameterFunc(func(p *parameters) {
|
||||
p.attestationSubmitter = submitter
|
||||
|
@ -77,7 +89,8 @@ func WithAggregateAttestationsSubmitter(submitter eth2client.AggregateAttestatio
|
|||
// parseAndCheckParameters parses and checks parameters to ensure that mandatory parameters are present and correct.
|
||||
func parseAndCheckParameters(params ...Parameter) (*parameters, error) {
|
||||
parameters := parameters{
|
||||
logLevel: zerolog.GlobalLevel(),
|
||||
logLevel: zerolog.GlobalLevel(),
|
||||
clientMonitor: nullmetrics.New(context.Background()),
|
||||
}
|
||||
for _, p := range params {
|
||||
if params != nil {
|
||||
|
@ -85,6 +98,9 @@ func parseAndCheckParameters(params ...Parameter) (*parameters, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if parameters.clientMonitor == nil {
|
||||
return nil, errors.New("no client monitor specified")
|
||||
}
|
||||
if parameters.beaconBlockSubmitter == nil {
|
||||
return nil, errors.New("no beacon block submitter specified")
|
||||
}
|
||||
|
|
|
@ -16,10 +16,12 @@ package immediate
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
eth2client "github.com/attestantio/go-eth2-client"
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/attestantio/vouch/services/submitter"
|
||||
"github.com/attestantio/vouch/services/metrics"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog"
|
||||
zerologger "github.com/rs/zerolog/log"
|
||||
|
@ -27,6 +29,7 @@ import (
|
|||
|
||||
// Service is the submitter for signed items.
|
||||
type Service struct {
|
||||
clientMonitor metrics.ClientMonitor
|
||||
attestationSubmitter eth2client.AttestationSubmitter
|
||||
beaconBlockSubmitter eth2client.BeaconBlockSubmitter
|
||||
beaconCommitteeSubscriptionsSubmitter eth2client.BeaconCommitteeSubscriptionsSubmitter
|
||||
|
@ -50,6 +53,7 @@ func New(ctx context.Context, params ...Parameter) (*Service, error) {
|
|||
}
|
||||
|
||||
s := &Service{
|
||||
clientMonitor: parameters.clientMonitor,
|
||||
attestationSubmitter: parameters.attestationSubmitter,
|
||||
beaconBlockSubmitter: parameters.beaconBlockSubmitter,
|
||||
beaconCommitteeSubscriptionsSubmitter: parameters.beaconCommitteeSubscriptionsSubmitter,
|
||||
|
@ -65,7 +69,14 @@ func (s *Service) SubmitBeaconBlock(ctx context.Context, block *spec.SignedBeaco
|
|||
return errors.New("no beacon block supplied")
|
||||
}
|
||||
|
||||
if err := s.beaconBlockSubmitter.SubmitBeaconBlock(ctx, block); err != nil {
|
||||
started := time.Now()
|
||||
err := s.beaconBlockSubmitter.SubmitBeaconBlock(ctx, block)
|
||||
if service, isService := s.beaconBlockSubmitter.(eth2client.Service); isService {
|
||||
s.clientMonitor.ClientOperation(service.Address(), "submit beacon block", err == nil, time.Since(started))
|
||||
} else {
|
||||
s.clientMonitor.ClientOperation("<unknown>", "submit beacon block", err == nil, time.Since(started))
|
||||
}
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to submit beacon block")
|
||||
}
|
||||
|
||||
|
@ -85,7 +96,14 @@ func (s *Service) SubmitAttestation(ctx context.Context, attestation *spec.Attes
|
|||
return errors.New("no attestation supplied")
|
||||
}
|
||||
|
||||
if err := s.attestationSubmitter.SubmitAttestation(ctx, attestation); err != nil {
|
||||
started := time.Now()
|
||||
err := s.attestationSubmitter.SubmitAttestation(ctx, attestation)
|
||||
if service, isService := s.attestationSubmitter.(eth2client.Service); isService {
|
||||
s.clientMonitor.ClientOperation(service.Address(), "submit attestation", err == nil, time.Since(started))
|
||||
} else {
|
||||
s.clientMonitor.ClientOperation("<unknown>", "submit attestation", err == nil, time.Since(started))
|
||||
}
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to submit attestation")
|
||||
}
|
||||
|
||||
|
@ -100,24 +118,28 @@ func (s *Service) SubmitAttestation(ctx context.Context, attestation *spec.Attes
|
|||
}
|
||||
|
||||
// SubmitBeaconCommitteeSubscriptions submits a batch of beacon committee subscriptions.
|
||||
func (s *Service) SubmitBeaconCommitteeSubscriptions(ctx context.Context, subscriptions []*submitter.BeaconCommitteeSubscription) error {
|
||||
func (s *Service) SubmitBeaconCommitteeSubscriptions(ctx context.Context, subscriptions []*api.BeaconCommitteeSubscription) error {
|
||||
if len(subscriptions) == 0 {
|
||||
return errors.New("no beacon committee subscriptions supplied")
|
||||
}
|
||||
|
||||
subs := make([]*eth2client.BeaconCommitteeSubscription, len(subscriptions))
|
||||
subs := make([]*api.BeaconCommitteeSubscription, len(subscriptions))
|
||||
for i, subscription := range subscriptions {
|
||||
subs[i] = ð2client.BeaconCommitteeSubscription{
|
||||
Slot: subscription.Slot,
|
||||
CommitteeIndex: subscription.CommitteeIndex,
|
||||
CommitteeSize: subscription.CommitteeSize,
|
||||
ValidatorIndex: subscription.ValidatorIndex,
|
||||
ValidatorPubKey: subscription.ValidatorPubKey,
|
||||
Aggregate: subscription.Aggregate,
|
||||
SlotSelectionSignature: subscription.Signature,
|
||||
subs[i] = &api.BeaconCommitteeSubscription{
|
||||
Slot: subscription.Slot,
|
||||
CommitteeIndex: subscription.CommitteeIndex,
|
||||
CommitteesAtSlot: subscription.CommitteesAtSlot,
|
||||
IsAggregator: subscription.IsAggregator,
|
||||
}
|
||||
}
|
||||
if err := s.beaconCommitteeSubscriptionsSubmitter.SubmitBeaconCommitteeSubscriptions(ctx, subs); err != nil {
|
||||
started := time.Now()
|
||||
err := s.beaconCommitteeSubscriptionsSubmitter.SubmitBeaconCommitteeSubscriptions(ctx, subs)
|
||||
if service, isService := s.beaconCommitteeSubscriptionsSubmitter.(eth2client.Service); isService {
|
||||
s.clientMonitor.ClientOperation(service.Address(), "submit beacon committee subscription", err == nil, time.Since(started))
|
||||
} else {
|
||||
s.clientMonitor.ClientOperation("<unknown>", "submit beacon committee subscription", err == nil, time.Since(started))
|
||||
}
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to submit beacon committee subscriptions")
|
||||
}
|
||||
|
||||
|
@ -125,7 +147,7 @@ func (s *Service) SubmitBeaconCommitteeSubscriptions(ctx context.Context, subscr
|
|||
// Summary counts.
|
||||
aggregating := 0
|
||||
for i := range subscriptions {
|
||||
if subscriptions[i].Aggregate {
|
||||
if subscriptions[i].IsAggregator {
|
||||
aggregating++
|
||||
}
|
||||
}
|
||||
|
@ -145,7 +167,14 @@ func (s *Service) SubmitAggregateAttestations(ctx context.Context, aggregates []
|
|||
return errors.New("no aggregate attestations supplied")
|
||||
}
|
||||
|
||||
if err := s.aggregateAttestationsSubmitter.SubmitAggregateAttestations(ctx, aggregates); err != nil {
|
||||
started := time.Now()
|
||||
err := s.aggregateAttestationsSubmitter.SubmitAggregateAttestations(ctx, aggregates)
|
||||
if service, isService := s.aggregateAttestationsSubmitter.(eth2client.Service); isService {
|
||||
s.clientMonitor.ClientOperation(service.Address(), "submit aggregate attestation", err == nil, time.Since(started))
|
||||
} else {
|
||||
s.clientMonitor.ClientOperation("<unknown>", "submit aggregate attestation", err == nil, time.Since(started))
|
||||
}
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to submit aggregate attestation")
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
"context"
|
||||
"testing"
|
||||
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/attestantio/vouch/mock"
|
||||
"github.com/attestantio/vouch/services/submitter"
|
||||
|
@ -330,7 +331,7 @@ func TestSubmitBeaconCommitteeSubscriptions(t *testing.T) {
|
|||
tests := []struct {
|
||||
name string
|
||||
params []immediate.Parameter
|
||||
subscriptions []*submitter.BeaconCommitteeSubscription
|
||||
subscriptions []*api.BeaconCommitteeSubscription
|
||||
err string
|
||||
}{
|
||||
{
|
||||
|
@ -353,7 +354,7 @@ func TestSubmitBeaconCommitteeSubscriptions(t *testing.T) {
|
|||
immediate.WithBeaconCommitteeSubscriptionsSubmitter(mock.NewBeaconCommitteeSubscriptionsSubmitter()),
|
||||
immediate.WithAggregateAttestationsSubmitter(mock.NewAggregateAttestationsSubmitter()),
|
||||
},
|
||||
subscriptions: []*submitter.BeaconCommitteeSubscription{},
|
||||
subscriptions: []*api.BeaconCommitteeSubscription{},
|
||||
err: "no beacon committee subscriptions supplied",
|
||||
},
|
||||
{
|
||||
|
@ -365,7 +366,7 @@ func TestSubmitBeaconCommitteeSubscriptions(t *testing.T) {
|
|||
immediate.WithBeaconCommitteeSubscriptionsSubmitter(mock.NewErroringBeaconCommitteeSubscriptionsSubmitter()),
|
||||
immediate.WithAggregateAttestationsSubmitter(mock.NewAggregateAttestationsSubmitter()),
|
||||
},
|
||||
subscriptions: []*submitter.BeaconCommitteeSubscription{
|
||||
subscriptions: []*api.BeaconCommitteeSubscription{
|
||||
{},
|
||||
},
|
||||
err: "failed to submit beacon committee subscriptions: error",
|
||||
|
@ -379,7 +380,7 @@ func TestSubmitBeaconCommitteeSubscriptions(t *testing.T) {
|
|||
immediate.WithBeaconCommitteeSubscriptionsSubmitter(mock.NewBeaconCommitteeSubscriptionsSubmitter()),
|
||||
immediate.WithAggregateAttestationsSubmitter(mock.NewAggregateAttestationsSubmitter()),
|
||||
},
|
||||
subscriptions: []*submitter.BeaconCommitteeSubscription{
|
||||
subscriptions: []*api.BeaconCommitteeSubscription{
|
||||
{},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -16,13 +16,18 @@
|
|||
package multinode
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
eth2client "github.com/attestantio/go-eth2-client"
|
||||
"github.com/attestantio/vouch/services/metrics"
|
||||
nullmetrics "github.com/attestantio/vouch/services/metrics/null"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
type parameters struct {
|
||||
logLevel zerolog.Level
|
||||
clientMonitor metrics.ClientMonitor
|
||||
processConcurrency int64
|
||||
beaconBlockSubmitters map[string]eth2client.BeaconBlockSubmitter
|
||||
attestationSubmitters map[string]eth2client.AttestationSubmitter
|
||||
|
@ -48,6 +53,13 @@ func WithLogLevel(logLevel zerolog.Level) Parameter {
|
|||
})
|
||||
}
|
||||
|
||||
// WithClientMonitor sets the client monitor.
|
||||
func WithClientMonitor(clientMonitor metrics.ClientMonitor) Parameter {
|
||||
return parameterFunc(func(p *parameters) {
|
||||
p.clientMonitor = clientMonitor
|
||||
})
|
||||
}
|
||||
|
||||
// WithProcessConcurrency sets the concurrency for the service.
|
||||
func WithProcessConcurrency(concurrency int64) Parameter {
|
||||
return parameterFunc(func(p *parameters) {
|
||||
|
@ -86,7 +98,8 @@ func WithBeaconCommitteeSubscriptionsSubmitters(submitters map[string]eth2client
|
|||
// parseAndCheckParameters parses and checks parameters to ensure that mandatory parameters are present and correct.
|
||||
func parseAndCheckParameters(params ...Parameter) (*parameters, error) {
|
||||
parameters := parameters{
|
||||
logLevel: zerolog.GlobalLevel(),
|
||||
logLevel: zerolog.GlobalLevel(),
|
||||
clientMonitor: nullmetrics.New(context.Background()),
|
||||
}
|
||||
for _, p := range params {
|
||||
if params != nil {
|
||||
|
@ -94,6 +107,9 @@ func parseAndCheckParameters(params ...Parameter) (*parameters, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if parameters.clientMonitor == nil {
|
||||
return nil, errors.New("no client monitor specified")
|
||||
}
|
||||
if parameters.processConcurrency == 0 {
|
||||
return nil, errors.New("no process concurrency specified")
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
"context"
|
||||
|
||||
eth2client "github.com/attestantio/go-eth2-client"
|
||||
"github.com/attestantio/vouch/services/metrics"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog"
|
||||
zerologger "github.com/rs/zerolog/log"
|
||||
|
@ -24,6 +25,7 @@ import (
|
|||
|
||||
// Service is the provider for beacon block proposals.
|
||||
type Service struct {
|
||||
clientMonitor metrics.ClientMonitor
|
||||
processConcurrency int64
|
||||
beaconBlockSubmitters map[string]eth2client.BeaconBlockSubmitter
|
||||
attestationSubmitters map[string]eth2client.AttestationSubmitter
|
||||
|
@ -48,6 +50,7 @@ func New(ctx context.Context, params ...Parameter) (*Service, error) {
|
|||
}
|
||||
|
||||
s := &Service{
|
||||
clientMonitor: parameters.clientMonitor,
|
||||
processConcurrency: parameters.processConcurrency,
|
||||
beaconBlockSubmitters: parameters.beaconBlockSubmitters,
|
||||
attestationSubmitters: parameters.attestationSubmitters,
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
eth2client "github.com/attestantio/go-eth2-client"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
|
@ -41,14 +42,21 @@ func (s *Service) SubmitAggregateAttestations(ctx context.Context, aggregates []
|
|||
submitter eth2client.AggregateAttestationsSubmitter,
|
||||
) {
|
||||
defer wg.Done()
|
||||
log := log.With().Str("beacon_node_address", name).Uint64("slot", aggregates[0].Message.Aggregate.Data.Slot).Logger()
|
||||
log := log.With().Str("beacon_node_address", name).Uint64("slot", uint64(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, aggregates); err != nil {
|
||||
started := time.Now()
|
||||
err := submitter.SubmitAggregateAttestations(ctx, aggregates)
|
||||
if service, isService := submitter.(eth2client.Service); isService {
|
||||
s.clientMonitor.ClientOperation(service.Address(), "submit aggregate attestation", err == nil, time.Since(started))
|
||||
} else {
|
||||
s.clientMonitor.ClientOperation("<unknown>", "submit aggregate attestation", err == nil, time.Since(started))
|
||||
}
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Failed to submit aggregate attestations")
|
||||
return
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"encoding/json"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
eth2client "github.com/attestantio/go-eth2-client"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
|
@ -42,14 +43,21 @@ func (s *Service) SubmitAttestation(ctx context.Context, attestation *spec.Attes
|
|||
submitter eth2client.AttestationSubmitter,
|
||||
) {
|
||||
defer wg.Done()
|
||||
log := log.With().Str("beacon_node_address", name).Uint64("slot", attestation.Data.Slot).Logger()
|
||||
log := log.With().Str("beacon_node_address", name).Uint64("slot", uint64(attestation.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.SubmitAttestation(ctx, attestation); err != nil {
|
||||
started := time.Now()
|
||||
err := submitter.SubmitAttestation(ctx, attestation)
|
||||
if service, isService := submitter.(eth2client.Service); isService {
|
||||
s.clientMonitor.ClientOperation(service.Address(), "submit attestation", err == nil, time.Since(started))
|
||||
} else {
|
||||
s.clientMonitor.ClientOperation("<unknown>", "submit attestation", err == nil, time.Since(started))
|
||||
}
|
||||
if err != nil {
|
||||
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.
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
eth2client "github.com/attestantio/go-eth2-client"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
|
@ -41,14 +42,21 @@ func (s *Service) SubmitBeaconBlock(ctx context.Context, block *spec.SignedBeaco
|
|||
submitter eth2client.BeaconBlockSubmitter,
|
||||
) {
|
||||
defer wg.Done()
|
||||
log := log.With().Str("beacon_node_address", name).Uint64("slot", block.Message.Slot).Logger()
|
||||
log := log.With().Str("beacon_node_address", name).Uint64("slot", uint64(block.Message.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.SubmitBeaconBlock(ctx, block); err != nil {
|
||||
started := time.Now()
|
||||
err := submitter.SubmitBeaconBlock(ctx, block)
|
||||
if service, isService := submitter.(eth2client.Service); isService {
|
||||
s.clientMonitor.ClientOperation(service.Address(), "submit beacon block", err == nil, time.Since(started))
|
||||
} else {
|
||||
s.clientMonitor.ClientOperation("<unknown>", "submit beacon block", err == nil, time.Since(started))
|
||||
}
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Failed to submit beacon block")
|
||||
return
|
||||
}
|
||||
|
|
|
@ -17,32 +17,20 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
eth2client "github.com/attestantio/go-eth2-client"
|
||||
"github.com/attestantio/vouch/services/submitter"
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sync/semaphore"
|
||||
)
|
||||
|
||||
// SubmitBeaconCommitteeSubscriptions submits a batch of beacon committee subscriptions.
|
||||
func (s *Service) SubmitBeaconCommitteeSubscriptions(ctx context.Context, subscriptions []*submitter.BeaconCommitteeSubscription) error {
|
||||
func (s *Service) SubmitBeaconCommitteeSubscriptions(ctx context.Context, subscriptions []*api.BeaconCommitteeSubscription) error {
|
||||
if subscriptions == nil {
|
||||
return errors.New("no subscriptions supplied")
|
||||
}
|
||||
|
||||
subs := make([]*eth2client.BeaconCommitteeSubscription, len(subscriptions))
|
||||
for i, subscription := range subscriptions {
|
||||
subs[i] = ð2client.BeaconCommitteeSubscription{
|
||||
Slot: subscription.Slot,
|
||||
CommitteeIndex: subscription.CommitteeIndex,
|
||||
CommitteeSize: subscription.CommitteeSize,
|
||||
ValidatorIndex: subscription.ValidatorIndex,
|
||||
ValidatorPubKey: subscription.ValidatorPubKey,
|
||||
Aggregate: subscription.Aggregate,
|
||||
SlotSelectionSignature: subscription.Signature,
|
||||
}
|
||||
}
|
||||
|
||||
sem := semaphore.NewWeighted(s.processConcurrency)
|
||||
var wg sync.WaitGroup
|
||||
for name, submitter := range s.beaconCommitteeSubscriptionSubmitters {
|
||||
|
@ -54,14 +42,21 @@ func (s *Service) SubmitBeaconCommitteeSubscriptions(ctx context.Context, subscr
|
|||
submitter eth2client.BeaconCommitteeSubscriptionsSubmitter,
|
||||
) {
|
||||
defer wg.Done()
|
||||
log := log.With().Str("beacon_node_address", name).Int("subscriptions", len(subs)).Logger()
|
||||
log := log.With().Str("beacon_node_address", name).Int("subscriptions", len(subscriptions)).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.SubmitBeaconCommitteeSubscriptions(ctx, subs); err != nil {
|
||||
started := time.Now()
|
||||
err := submitter.SubmitBeaconCommitteeSubscriptions(ctx, subscriptions)
|
||||
if service, isService := submitter.(eth2client.Service); isService {
|
||||
s.clientMonitor.ClientOperation(service.Address(), "submit beacon committee subscription", err == nil, time.Since(started))
|
||||
} else {
|
||||
s.clientMonitor.ClientOperation("<unknown>", "submit beacon committee subscription", err == nil, time.Since(started))
|
||||
}
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("Failed to submit beacon committee subscription")
|
||||
return
|
||||
}
|
||||
|
@ -74,7 +69,7 @@ func (s *Service) SubmitBeaconCommitteeSubscriptions(ctx context.Context, subscr
|
|||
// Summary counts.
|
||||
aggregating := 0
|
||||
for i := range subscriptions {
|
||||
if subscriptions[i].Aggregate {
|
||||
if subscriptions[i].IsAggregator {
|
||||
aggregating++
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,8 +17,8 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/attestantio/vouch/services/submitter"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog"
|
||||
zerologger "github.com/rs/zerolog/log"
|
||||
|
@ -81,7 +81,7 @@ func (s *Service) SubmitAttestation(ctx context.Context, attestation *spec.Attes
|
|||
}
|
||||
|
||||
// SubmitBeaconCommitteeSubscriptions submits a batch of beacon committee subscriptions.
|
||||
func (s *Service) SubmitBeaconCommitteeSubscriptions(ctx context.Context, subscriptions []*submitter.BeaconCommitteeSubscription) error {
|
||||
func (s *Service) SubmitBeaconCommitteeSubscriptions(ctx context.Context, subscriptions []*api.BeaconCommitteeSubscription) error {
|
||||
if subscriptions == nil {
|
||||
return errors.New("no subscriptions supplied")
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ func (s *Service) SubmitBeaconCommitteeSubscriptions(ctx context.Context, subscr
|
|||
// Summary counts.
|
||||
aggregating := 0
|
||||
for i := range subscriptions {
|
||||
if subscriptions[i].Aggregate {
|
||||
if subscriptions[i].IsAggregator {
|
||||
aggregating++
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ package submitter
|
|||
import (
|
||||
"context"
|
||||
|
||||
api "github.com/attestantio/go-eth2-client/api/v1"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
)
|
||||
|
||||
|
@ -34,21 +35,10 @@ type BeaconBlockSubmitter interface {
|
|||
SubmitBeaconBlock(ctx context.Context, block *spec.SignedBeaconBlock) error
|
||||
}
|
||||
|
||||
// BeaconCommitteeSubscription is a subscription for a particular beacon committee at a given time.
|
||||
type BeaconCommitteeSubscription struct {
|
||||
Slot uint64
|
||||
CommitteeIndex uint64
|
||||
CommitteeSize uint64
|
||||
ValidatorIndex uint64
|
||||
ValidatorPubKey []byte
|
||||
Aggregate bool
|
||||
Signature []byte
|
||||
}
|
||||
|
||||
// BeaconCommitteeSubscriptionsSubmitter is the interface for a submitter of beacon committee subscriptions.
|
||||
type BeaconCommitteeSubscriptionsSubmitter interface {
|
||||
// SubmitBeaconCommitteeSubscription submits a batch of beacon committee subscriptions.
|
||||
SubmitBeaconCommitteeSubscriptions(ctx context.Context, subscriptions []*BeaconCommitteeSubscription) error
|
||||
SubmitBeaconCommitteeSubscriptions(ctx context.Context, subscriptions []*api.BeaconCommitteeSubscription) error
|
||||
}
|
||||
|
||||
// AggregateAttestationsSubmitter is the interface for a submitter of aggregate attestations.
|
||||
|
|
|
@ -23,12 +23,13 @@ import (
|
|||
"golang.org/x/sync/semaphore"
|
||||
)
|
||||
|
||||
// BeaconBlockProposal provies the best beacon block proposal from a number of beacon nodes.
|
||||
func (s *Service) BeaconBlockProposal(ctx context.Context, slot uint64, randaoReveal []byte, graffiti []byte) (*spec.BeaconBlock, error) {
|
||||
// BeaconBlockProposal provides the best beacon block proposal from a number of beacon nodes.
|
||||
func (s *Service) BeaconBlockProposal(ctx context.Context, slot spec.Slot, randaoReveal spec.BLSSignature, graffiti []byte) (*spec.BeaconBlock, error) {
|
||||
var mu sync.Mutex
|
||||
bestScore := float64(0)
|
||||
var bestProposal *spec.BeaconBlock
|
||||
|
||||
started := time.Now()
|
||||
sem := semaphore.NewWeighted(s.processConcurrency)
|
||||
var wg sync.WaitGroup
|
||||
for name, provider := range s.beaconBlockProposalProviders {
|
||||
|
@ -41,10 +42,10 @@ func (s *Service) BeaconBlockProposal(ctx context.Context, slot uint64, randaoRe
|
|||
return
|
||||
}
|
||||
defer sem.Release(1)
|
||||
log := log.With().Str("provider", name).Uint64("slot", slot).Logger()
|
||||
log := log.With().Str("provider", name).Uint64("slot", uint64(slot)).Logger()
|
||||
log.Trace().Dur("elapsed", time.Since(started)).Msg("Obtained semaphore")
|
||||
|
||||
opCtx, cancel := context.WithTimeout(ctx, s.timeout)
|
||||
started := time.Now()
|
||||
proposal, err := provider.BeaconBlockProposal(opCtx, slot, randaoReveal, graffiti)
|
||||
s.clientMonitor.ClientOperation(name, "beacon block proposal", err == nil, time.Since(started))
|
||||
if err != nil {
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"testing"
|
||||
|
||||
eth2client "github.com/attestantio/go-eth2-client"
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
"github.com/attestantio/vouch/mock"
|
||||
"github.com/attestantio/vouch/services/metrics/null"
|
||||
"github.com/attestantio/vouch/strategies/beaconblockproposal/best"
|
||||
|
@ -42,10 +43,14 @@ func TestBeaconBlockProposal(t *testing.T) {
|
|||
|
||||
block, err := service.BeaconBlockProposal(ctx,
|
||||
12345,
|
||||
[]byte{
|
||||
spec.BLSSignature([96]byte{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
},
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
||||
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
}),
|
||||
nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -35,11 +35,11 @@ func scoreBeaconBlockProposal(ctx context.Context, name string, blockProposal *s
|
|||
|
||||
// We need to avoid duplicates in attestations.
|
||||
// Map is slot -> committee index -> validator committee index -> attested.
|
||||
attested := make(map[uint64]map[uint64]map[uint64]bool)
|
||||
attested := make(map[spec.Slot]map[spec.CommitteeIndex]map[uint64]bool)
|
||||
for _, attestation := range blockProposal.Body.Attestations {
|
||||
slotAttested, exists := attested[attestation.Data.Slot]
|
||||
if !exists {
|
||||
slotAttested = make(map[uint64]map[uint64]bool)
|
||||
slotAttested = make(map[spec.CommitteeIndex]map[uint64]bool)
|
||||
attested[attestation.Data.Slot] = slotAttested
|
||||
}
|
||||
committeeAttested, exists := slotAttested[attestation.Data.Index]
|
||||
|
@ -84,7 +84,7 @@ func scoreBeaconBlockProposal(ctx context.Context, name string, blockProposal *s
|
|||
attesterSlashingScore := slashingWeight * float64(indicesSlashed)
|
||||
|
||||
log.Trace().
|
||||
Uint64("slot", blockProposal.Slot).
|
||||
Uint64("slot", uint64(blockProposal.Slot)).
|
||||
Str("provider", name).
|
||||
Float64("immediate_attestations", immediateAttestationScore).
|
||||
Float64("attestations", attestationScore).
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright © 2020 Attestant Limited.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// Licensed )junder the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
|
@ -57,8 +57,8 @@ func New(ctx context.Context, params ...Parameter) (*Service, error) {
|
|||
return s, nil
|
||||
}
|
||||
|
||||
// BeaconBlockProposal provies the first beacon block proposal from a number of beacon nodes.
|
||||
func (s *Service) BeaconBlockProposal(ctx context.Context, slot uint64, randaoReveal []byte, graffiti []byte) (*spec.BeaconBlock, error) {
|
||||
// BeaconBlockProposal provides the first beacon block proposal from a number of beacon nodes.
|
||||
func (s *Service) BeaconBlockProposal(ctx context.Context, slot spec.Slot, randaoReveal spec.BLSSignature, graffiti []byte) (*spec.BeaconBlock, error) {
|
||||
// We create a cancelable context with a timeout. As soon as the first provider has responded we
|
||||
// cancel the context to cancel the other requests.
|
||||
ctx, cancel := context.WithTimeout(ctx, s.timeout)
|
||||
|
@ -66,7 +66,7 @@ func (s *Service) BeaconBlockProposal(ctx context.Context, slot uint64, randaoRe
|
|||
proposalCh := make(chan *spec.BeaconBlock, 1)
|
||||
for name, provider := range s.beaconBlockProposalProviders {
|
||||
go func(ctx context.Context, name string, provider eth2client.BeaconBlockProposalProvider, ch chan *spec.BeaconBlock) {
|
||||
log := log.With().Str("provider", name).Uint64("slot", slot).Logger()
|
||||
log := log.With().Str("provider", name).Uint64("slot", uint64(slot)).Logger()
|
||||
|
||||
started := time.Now()
|
||||
proposal, err := provider.BeaconBlockProposal(ctx, slot, randaoReveal, graffiti)
|
||||
|
|
|
@ -506,6 +506,24 @@ XDCQeaEUOuLjokRojHrN27ghz3wJoUJzTdjtHZ+yE9s2cW9VXRUxkun0aLcQd/iY
|
|||
xvXEII1qCvhI4mmWvbcepvtswQmTEeOroM/27/IIEAOvTyqd6rDi2A==
|
||||
-----END RSA PRIVATE KEY-----`
|
||||
|
||||
// SignerCerts gives access to signer certificates by ID.
|
||||
var SignerCerts = map[uint64][]byte{
|
||||
1: []byte(SignerTest01Crt),
|
||||
2: []byte(SignerTest02Crt),
|
||||
3: []byte(SignerTest03Crt),
|
||||
4: []byte(SignerTest04Crt),
|
||||
5: []byte(SignerTest05Crt),
|
||||
}
|
||||
|
||||
// SignerKeys gives access to signer keys by ID.
|
||||
var SignerKeys = map[uint64][]byte{
|
||||
1: []byte(SignerTest01Key),
|
||||
2: []byte(SignerTest02Key),
|
||||
3: []byte(SignerTest03Key),
|
||||
4: []byte(SignerTest04Key),
|
||||
5: []byte(SignerTest05Key),
|
||||
}
|
||||
|
||||
// SetupCerts sets up a number of certificates on-disk in the provided location.
|
||||
func SetupCerts(base string) error {
|
||||
if err := ioutil.WriteFile(filepath.Join(base, "ca.crt"), []byte(CACrt), 0600); err != nil {
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
// Copyright © 2020 Attestant Limited
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"strings"
|
||||
|
||||
spec "github.com/attestantio/go-eth2-client/spec/phase0"
|
||||
)
|
||||
|
||||
// HexToBytes converts a hex string to a byte array.
|
||||
// This should only be used for pre-defined test strings; it will panic if the input is invalid.
|
||||
func HexToBytes(input string) []byte {
|
||||
res, err := hex.DecodeString(strings.TrimPrefix(input, "0x"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// HexToPubKey converts a hex string to a spec public key.
|
||||
// This should only be used for pre-defined test strings; it will panic if the input is invalid.
|
||||
func HexToPubKey(input string) spec.BLSPubKey {
|
||||
data := HexToBytes(input)
|
||||
var res spec.BLSPubKey
|
||||
copy(res[:], data)
|
||||
return res
|
||||
}
|
||||
|
||||
// HexToSignature converts a hex string to a spec signature.
|
||||
// This should only be used for pre-defined test strings; it will panic if the input is invalid.
|
||||
func HexToSignature(input string) spec.BLSSignature {
|
||||
data := HexToBytes(input)
|
||||
var res spec.BLSSignature
|
||||
copy(res[:], data)
|
||||
return res
|
||||
}
|
||||
|
||||
// HexToDomainType converts a hex string to a spec domain type.
|
||||
// This should only be used for pre-defined test strings; it will panic if the input is invalid.
|
||||
func HexToDomainType(input string) spec.DomainType {
|
||||
data := HexToBytes(input)
|
||||
var res spec.DomainType
|
||||
copy(res[:], data)
|
||||
return res
|
||||
}
|
||||
|
||||
// HexToDomain converts a hex string to a spec domain.
|
||||
// This should only be used for pre-defined test strings; it will panic if the input is invalid.
|
||||
func HexToDomain(input string) spec.Domain {
|
||||
data := HexToBytes(input)
|
||||
var res spec.Domain
|
||||
copy(res[:], data)
|
||||
return res
|
||||
}
|
||||
|
||||
// HexToVersion converts a hex string to a spec version.
|
||||
// This should only be used for pre-defined test strings; it will panic if the input is invalid.
|
||||
func HexToVersion(input string) spec.Version {
|
||||
data := HexToBytes(input)
|
||||
var res spec.Version
|
||||
copy(res[:], data)
|
||||
return res
|
||||
}
|
||||
|
||||
// HexToRoot converts a hex string to a spec root.
|
||||
// This should only be used for pre-defined test strings; it will panic if the input is invalid.
|
||||
func HexToRoot(input string) spec.Root {
|
||||
data := HexToBytes(input)
|
||||
var res spec.Root
|
||||
copy(res[:], data)
|
||||
return res
|
||||
}
|
Loading…
Reference in New Issue