From 967e21634f4163f31970f41bb146fee90a52b5e9 Mon Sep 17 00:00:00 2001 From: kaleofduty <59616916+kaleofduty@users.noreply.github.com> Date: Mon, 7 Apr 2025 20:52:22 +0200 Subject: [PATCH] Improvements: - Upgrade to go 1.23 - Upgrade to go-ethereum v1.15.6 - ragep2p: Introduce PeerKeyring abstraction for digital signatures - Prep work for OCR 3.1 Based on f4ecd7113e8e1d2ce77a4bb34d66140a7708dd57 --- go.mod | 48 +-- go.sum | 144 +++---- .../ed25519_sanity_check.go | 2 +- .../peer_keyring_with_private_key.go | 36 ++ networking/peer_v2.go | 34 +- networking/ragedisco/announcement.go | 12 +- networking/ragedisco/discovery_protocol.go | 14 +- networking/ragedisco/ragep2p_discoverer.go | 5 +- .../internal/managed/limits/ocr3_limits.go | 2 +- .../internal/ocr3/protocol/message.go | 15 +- .../ocr3/protocol/outcome_generation.go | 2 - .../protocol/outcome_generation_follower.go | 28 +- .../protocol/outcome_generation_leader.go | 56 ++- .../ocr3/protocol/report_attestation.go | 60 +-- .../internal/ocr3/protocol/signed_data.go | 106 ++++- .../offchainreporting3_messages.pb.go | 366 ++++++++++-------- .../ocr3/serialization/serialization.go | 8 + ragep2p/internal/knock/knock.go | 9 +- ragep2p/internal/mtls/common.go | 47 +-- .../internal/mtls/crypto_signer_adapter.go | 32 ++ ragep2p/ragep2p.go | 35 +- ragep2p/types/types.go | 54 ++- 22 files changed, 710 insertions(+), 405 deletions(-) rename {networking => internal/peerkeyringhelper}/ed25519_sanity_check.go (96%) create mode 100644 internal/peerkeyringhelper/peer_keyring_with_private_key.go create mode 100644 ragep2p/internal/mtls/crypto_signer_adapter.go diff --git a/go.mod b/go.mod index 0d51e2ea..75b65517 100644 --- a/go.mod +++ b/go.mod @@ -1,17 +1,17 @@ module github.com/smartcontractkit/libocr -go 1.22 +go 1.23.0 -toolchain go1.23.2 +toolchain go1.23.6 require ( - github.com/ethereum/go-ethereum v1.14.11 - github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a + github.com/ethereum/go-ethereum v1.15.6 + github.com/leanovate/gopter v0.2.11 github.com/mr-tron/base58 v1.2.0 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.14.0 github.com/sirupsen/logrus v1.9.3 - golang.org/x/crypto v0.29.0 + golang.org/x/crypto v0.35.0 google.golang.org/protobuf v1.34.2 ) @@ -22,9 +22,7 @@ require ( github.com/VictoriaMetrics/fastcache v1.12.2 // indirect github.com/allegro/bigcache v1.2.1 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.15.0 // indirect - github.com/btcsuite/btcd v0.22.0-beta // indirect - github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect + github.com/bits-and-blooms/bitset v1.17.0 // indirect github.com/cespare/cp v1.1.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cockroachdb/errors v1.11.3 // indirect @@ -34,8 +32,8 @@ require ( github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/consensys/bavard v0.1.22 // indirect - github.com/consensys/gnark-crypto v0.13.0 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/consensys/gnark-crypto v0.14.0 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect github.com/crate-crypto/go-kzg-4844 v1.1.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -51,7 +49,7 @@ require ( github.com/go-ole/go-ole v1.3.0 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + github.com/golang-jwt/jwt/v4 v4.5.1 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/go-cmp v0.6.0 // indirect @@ -61,7 +59,7 @@ require ( github.com/hashicorp/go-bexpr v0.1.10 // indirect github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect - github.com/holiman/uint256 v1.3.1 // indirect + github.com/holiman/uint256 v1.3.2 // indirect github.com/huin/goupnp v1.3.0 // indirect github.com/influxdata/influxdb-client-go/v2 v2.4.0 // indirect github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c // indirect @@ -84,6 +82,11 @@ require ( github.com/onsi/gomega v1.10.3 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 // indirect + github.com/pion/dtls/v2 v2.2.7 // indirect + github.com/pion/logging v0.2.2 // indirect + github.com/pion/stun/v2 v2.0.0 // indirect + github.com/pion/transport/v2 v2.2.1 // indirect + github.com/pion/transport/v3 v3.0.1 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.39.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect @@ -92,21 +95,22 @@ require ( github.com/rs/cors v1.7.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect - github.com/status-im/keycard-go v0.2.0 // indirect - github.com/supranational/blst v0.3.13 // indirect + github.com/supranational/blst v0.3.14 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect - github.com/tyler-smith/go-bip39 v1.1.0 // indirect - github.com/urfave/cli/v2 v2.25.7 // indirect - github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + github.com/urfave/cli/v2 v2.27.5 // indirect + github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect - golang.org/x/net v0.25.0 // indirect - golang.org/x/sync v0.9.0 // indirect - golang.org/x/sys v0.27.0 // indirect - golang.org/x/text v0.20.0 // indirect - golang.org/x/time v0.5.0 // indirect + golang.org/x/net v0.36.0 // indirect + golang.org/x/sync v0.11.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/text v0.22.0 // indirect + golang.org/x/time v0.9.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) + +replace github.com/leanovate/gopter => github.com/leanovate/gopter v0.2.10-0.20210127095200-9abe2343507a diff --git a/go.sum b/go.sum index 962c3a4a..84039d59 100644 --- a/go.sum +++ b/go.sum @@ -6,29 +6,13 @@ github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDO github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= -github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bits-and-blooms/bitset v1.15.0 h1:DiCRMscZsGyYePE9AR3sVhKqUXCt5IZvkX5AfAc5xLQ= -github.com/bits-and-blooms/bitset v1.15.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrfdnWo= -github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA= -github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= -github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= -github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= -github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= -github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= -github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= -github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= -github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= -github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/bits-and-blooms/bitset v1.17.0 h1:1X2TS7aHz1ELcC0yU1y2stUs/0ig5oMU6STFZGrhvHI= +github.com/bits-and-blooms/bitset v1.17.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -50,17 +34,16 @@ github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAK github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/consensys/bavard v0.1.22 h1:Uw2CGvbXSZWhqK59X0VG/zOjpTFuOMcPLStrp1ihI0A= github.com/consensys/bavard v0.1.22/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs= -github.com/consensys/gnark-crypto v0.13.0 h1:VPULb/v6bbYELAPTDFINEVaMTTybV5GLxDdcjnS+4oc= -github.com/consensys/gnark-crypto v0.13.0/go.mod h1:wKqwsieaKPThcFkHe0d0zMsbHEUWFmZcG7KBCse210o= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/consensys/gnark-crypto v0.14.0 h1:DDBdl4HaBtdQsq/wfMwJvZNE80sHidrK3Nfrefatm0E= +github.com/consensys/gnark-crypto v0.14.0/go.mod h1:CU4UijNPsHawiVGNxe9co07FkzCeWHHrb1li/n1XoU0= +github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= +github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg= github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM= github.com/crate-crypto/go-kzg-4844 v1.1.0 h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4= github.com/crate-crypto/go-kzg-4844 v1.1.0/go.mod h1:JolLjpSff1tCCJKaJx4psrlEdlXuJEC996PL3tTAFks= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= -github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -70,15 +53,14 @@ github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5il github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= -github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= github.com/deepmap/oapi-codegen v1.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU= github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/ethereum/c-kzg-4844 v1.0.3 h1:IEnbOHwjixW2cTvKRUlAAUOeleV7nNM/umJR+qy4WDs= github.com/ethereum/c-kzg-4844 v1.0.3/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= -github.com/ethereum/go-ethereum v1.14.11 h1:8nFDCUUE67rPc6AKxFj7JKaOa2W/W1Rse3oS6LvvxEY= -github.com/ethereum/go-ethereum v1.14.11/go.mod h1:+l/fr42Mma+xBnhefL/+z11/hcmJ2egl+ScIVPjhc7E= +github.com/ethereum/go-ethereum v1.15.6 h1:jgLoUM6/pNjp0uEnXyWcWikDwa4j1wZlcqkX8Pm8A+I= +github.com/ethereum/go-ethereum v1.15.6/go.mod h1:+S9k+jFzlyVTNcYGvqFhzN/SFhI6vA+aOY4T5tLSPL0= github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8= github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= github.com/ferranbt/fastssz v0.1.2 h1:Dky6dXlngF6Qjc+EfDipAkE83N5I5DE68bY6O0VLNPk= @@ -106,8 +88,8 @@ github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= -github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= +github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -143,8 +125,8 @@ github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6w github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs= -github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA= +github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= @@ -157,12 +139,8 @@ github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 h1:vilfsD github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= @@ -217,13 +195,10 @@ github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4= github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA= @@ -235,6 +210,16 @@ github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQm github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= +github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= +github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= +github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= +github.com/pion/stun/v2 v2.0.0 h1:A5+wXKLAypxQri59+tmQKVs7+l6mMM+3d+eER9ifRU0= +github.com/pion/stun/v2 v2.0.0/go.mod h1:22qRSh08fSEttYUmJZGlriq9+03jtVmXNODgLccj8GQ= +github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c= +github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= +github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM= +github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -264,49 +249,53 @@ github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1 github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= -github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 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/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk= -github.com/supranational/blst v0.3.13/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/supranational/blst v0.3.14 h1:xNMoHRJOTwMn63ip6qoWJ2Ymgvj7E2b9jY2FAwY+qRo= +github.com/supranational/blst v0.3.14/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= -github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= -github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= -github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= -github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= +github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= +golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -317,16 +306,24 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/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-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= +golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-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-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= -golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/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= @@ -346,33 +343,49 @@ golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= +golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= 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/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -395,7 +408,6 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -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.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/networking/ed25519_sanity_check.go b/internal/peerkeyringhelper/ed25519_sanity_check.go similarity index 96% rename from networking/ed25519_sanity_check.go rename to internal/peerkeyringhelper/ed25519_sanity_check.go index 9986ed2f..f39aa54d 100644 --- a/networking/ed25519_sanity_check.go +++ b/internal/peerkeyringhelper/ed25519_sanity_check.go @@ -1,4 +1,4 @@ -package networking +package peerkeyringhelper import ( "bytes" diff --git a/internal/peerkeyringhelper/peer_keyring_with_private_key.go b/internal/peerkeyringhelper/peer_keyring_with_private_key.go new file mode 100644 index 00000000..42910bf1 --- /dev/null +++ b/internal/peerkeyringhelper/peer_keyring_with_private_key.go @@ -0,0 +1,36 @@ +package peerkeyringhelper + +import ( + "crypto/ed25519" + "fmt" + + ragetypes "github.com/smartcontractkit/libocr/ragep2p/types" +) + +type PeerKeyringWithPrivateKey struct { + privateKey ed25519.PrivateKey + peerPublicKey ragetypes.PeerPublicKey +} + +var _ ragetypes.PeerKeyring = &PeerKeyringWithPrivateKey{} + +func NewPeerKeyringWithPrivateKey(privateKey ed25519.PrivateKey) (*PeerKeyringWithPrivateKey, error) { + if err := ed25519SanityCheck(privateKey); err != nil { + return nil, fmt.Errorf("ed25519 sanity check failed: %w", err) + } + peerPublicKey, err := ragetypes.PeerPublicKeyFromGenericPublicKey(privateKey.Public()) + if err != nil { + return nil, fmt.Errorf("StaticallySizedEd25519PublicKey failed even though sanity check succeeded: %w", err) + } + return &PeerKeyringWithPrivateKey{privateKey, peerPublicKey}, nil +} + +// PublicKey implements ragetypes.PeerKeyring. +func (s *PeerKeyringWithPrivateKey) PublicKey() ragetypes.PeerPublicKey { + return s.peerPublicKey +} + +// Sign implements ragetypes.PeerKeyring. +func (s *PeerKeyringWithPrivateKey) Sign(msg []byte) (signature []byte, err error) { + return ed25519.Sign(s.privateKey, msg), nil +} diff --git a/networking/peer_v2.go b/networking/peer_v2.go index e124b92c..8908e0dc 100644 --- a/networking/peer_v2.go +++ b/networking/peer_v2.go @@ -11,6 +11,7 @@ import ( "github.com/smartcontractkit/libocr/commontypes" "github.com/smartcontractkit/libocr/internal/loghelper" "github.com/smartcontractkit/libocr/internal/metricshelper" + "github.com/smartcontractkit/libocr/internal/peerkeyringhelper" "github.com/smartcontractkit/libocr/networking/ragedisco" "github.com/smartcontractkit/libocr/networking/rageping" nettypes "github.com/smartcontractkit/libocr/networking/types" @@ -19,9 +20,17 @@ import ( ragetypes "github.com/smartcontractkit/libocr/ragep2p/types" ) +// Exactly one of PrivKey (deprecated) or PeerKeyring must be provided. type PeerConfig struct { + // Exactly one of PrivKey (deprecated) or PeerKeyring must be provided. + // + // Deprecated: Use PeerKeyring instead. This field is maintained for + // backwards compatibility and will be removed in a future release. PrivKey ed25519.PrivateKey - Logger commontypes.Logger + // Exactly one of PrivKey (deprecated) or PeerKeyring must be provided. + PeerKeyring ragetypes.PeerKeyring + + Logger commontypes.Logger // V2ListenAddresses contains the addresses the peer will listen to on the network in : form as // accepted by net.Listen. @@ -47,6 +56,17 @@ type PeerConfig struct { LatencyMetricsServiceConfigs []*rageping.LatencyMetricsServiceConfig } +func (c *PeerConfig) keyring() (ragetypes.PeerKeyring, error) { + switch { + case c.PeerKeyring != nil && c.PrivKey == nil: + return c.PeerKeyring, nil + case c.PrivKey != nil && c.PeerKeyring == nil: + return peerkeyringhelper.NewPeerKeyringWithPrivateKey(c.PrivKey) + default: + return nil, fmt.Errorf("exactly one of PrivKey (deprecated) or PeerKeyring must be provided") + } +} + // concretePeerV2 represents a ragep2p peer with one peer ID listening on one port type concretePeerV2 struct { peerID ragetypes.PeerID @@ -61,15 +81,13 @@ type concretePeerV2 struct { // Users are expected to create (using the OCR*Factory() methods) and close endpoints and bootstrappers before calling // Close() on the peer itself. func NewPeer(c PeerConfig) (*concretePeerV2, error) { - if err := ed25519SanityCheck(c.PrivKey); err != nil { - return nil, fmt.Errorf("ed25519 sanity check failed: %w", err) - } - - peerID, err := ragetypes.PeerIDFromPrivateKey(c.PrivKey) + keyring, err := c.keyring() if err != nil { - return nil, fmt.Errorf("error extracting v2 peer ID from private key: %w", err) + return nil, fmt.Errorf("failed to instantiate keyring: %w", err) } + peerID := ragetypes.PeerIDFromKeyring(keyring) + logger := loghelper.MakeRootLoggerWithContext(c.Logger).MakeChild(commontypes.LogFields{ "id": "PeerV2", "peerID": peerID.String(), @@ -85,7 +103,7 @@ func NewPeer(c PeerConfig) (*concretePeerV2, error) { discoverer := ragedisco.NewRagep2pDiscoverer(c.V2DeltaReconcile, announceAddresses, c.V2DiscovererDatabase, metricsRegistererWrapper) host, err := ragep2p.NewHost( ragep2p.HostConfig{c.V2DeltaDial}, - c.PrivKey, + keyring, c.V2ListenAddresses, discoverer, c.Logger, diff --git a/networking/ragedisco/announcement.go b/networking/ragedisco/announcement.go index 98c4af83..8355f1d1 100644 --- a/networking/ragedisco/announcement.go +++ b/networking/ragedisco/announcement.go @@ -193,19 +193,19 @@ func (uann unsignedAnnouncement) digest() ([]byte, error) { return hasher.Sum(nil), nil } -func (uann unsignedAnnouncement) sign(sk ed25519.PrivateKey) (Announcement, error) { +func (uann unsignedAnnouncement) sign(keyring ragetypes.PeerKeyring) (Announcement, error) { digest, err := uann.digest() if err != nil { return Announcement{}, err } - sig := ed25519.Sign(sk, digest) - - epk, ok := sk.Public().(ed25519.PublicKey) - if !ok { - return Announcement{}, fmt.Errorf("public key is not ed25519 public key") + sig, err := keyring.Sign(digest) + if err != nil { + return Announcement{}, fmt.Errorf("keyring Sign failed: %w", err) } + epk := ragetypes.Ed25519PublicKeyFromPeerPublicKey(keyring.PublicKey()) + return Announcement{ uann, epk, diff --git a/networking/ragedisco/discovery_protocol.go b/networking/ragedisco/discovery_protocol.go index 9bd9c971..0218834b 100644 --- a/networking/ragedisco/discovery_protocol.go +++ b/networking/ragedisco/discovery_protocol.go @@ -2,7 +2,6 @@ package ragedisco import ( "context" - "crypto/ed25519" "encoding/hex" "errors" "fmt" @@ -62,7 +61,7 @@ type discoveryProtocol struct { chOutgoingMessages chan<- outgoingMessage chConnectivity chan<- connectivityMsg chInternalBump chan Announcement - privKey ed25519.PrivateKey + keyring ragetypes.PeerKeyring ownID ragetypes.PeerID ownAddrs []ragetypes.Address @@ -91,16 +90,13 @@ func newDiscoveryProtocol( chIncomingMessages <-chan incomingMessage, chOutgoingMessages chan<- outgoingMessage, chConnectivity chan<- connectivityMsg, - privKey ed25519.PrivateKey, + keyring ragetypes.PeerKeyring, ownAddrs []ragetypes.Address, db nettypes.DiscovererDatabase, logger loghelper.LoggerWithContext, metricsRegisterer prometheus.Registerer, ) (*discoveryProtocol, error) { - ownID, err := ragetypes.PeerIDFromPrivateKey(privKey) - if err != nil { - return nil, fmt.Errorf("failed to obtain peer id from private key: %w", err) - } + ownID := ragetypes.PeerIDFromKeyring(keyring) ctx, ctxCancel := context.WithCancel(context.Background()) return &discoveryProtocol{ @@ -111,7 +107,7 @@ func newDiscoveryProtocol( chOutgoingMessages, chConnectivity, make(chan Announcement), - privKey, + keyring, ownID, ownAddrs, sync.RWMutex{}, @@ -662,7 +658,7 @@ func (p *discoveryProtocol) lockedBumpOwnAnnouncement() (*Announcement, bool, er if newctr > announcementVersionWarnThreshold { logger.Warn("New announcement version too big!", commontypes.LogFields{"announcement": newann}) } - sann, err := newann.sign(p.privKey) + sann, err := newann.sign(p.keyring) if err != nil { return nil, false, fmt.Errorf("failed to sign own announcement: %w", err) } diff --git a/networking/ragedisco/ragep2p_discoverer.go b/networking/ragedisco/ragep2p_discoverer.go index 4e0493c4..e3f91a1e 100644 --- a/networking/ragedisco/ragep2p_discoverer.go +++ b/networking/ragedisco/ragep2p_discoverer.go @@ -2,7 +2,6 @@ package ragedisco import ( "context" - "crypto/ed25519" "fmt" "sync" "time" @@ -78,7 +77,7 @@ func NewRagep2pDiscoverer( } } -func (r *Ragep2pDiscoverer) Start(host *ragep2p.Host, privKey ed25519.PrivateKey, logger loghelper.LoggerWithContext) error { +func (r *Ragep2pDiscoverer) Start(host *ragep2p.Host, keyring ragetypes.PeerKeyring, logger loghelper.LoggerWithContext) error { succeeded := false defer func() { if !succeeded { @@ -103,7 +102,7 @@ func (r *Ragep2pDiscoverer) Start(host *ragep2p.Host, privKey ed25519.PrivateKey r.chIncomingMessages, r.chOutgoingMessages, r.chConnectivity, - privKey, + keyring, announceAddresses, r.db, logger, diff --git a/offchainreporting2plus/internal/managed/limits/ocr3_limits.go b/offchainreporting2plus/internal/managed/limits/ocr3_limits.go index 9bdf7a06..db8c5be4 100644 --- a/offchainreporting2plus/internal/managed/limits/ocr3_limits.go +++ b/offchainreporting2plus/internal/managed/limits/ocr3_limits.go @@ -60,7 +60,7 @@ func ocr3limits(cfg ocr3config.PublicConfig, pluginLimits ocr3types.ReportingPlu maxLenMsgNewEpoch := overhead maxLenMsgEpochStartRequest := add(maxLenCertifiedPrepareOrCommit, overhead) - maxLenMsgEpochStart := add(maxLenCertifiedPrepareOrCommit, mul(ed25519.SignatureSize+sigOverhead, cfg.ByzQuorumSize()), overhead) + maxLenMsgEpochStart := add(maxLenCertifiedPrepareOrCommit, mul(2*(ed25519.SignatureSize+sigOverhead), cfg.ByzQuorumSize()), overhead) maxLenMsgRoundStart := add(pluginLimits.MaxQueryLength, overhead) maxLenMsgObservation := add(pluginLimits.MaxObservationLength, overhead) maxLenMsgProposal := add(mul(add(pluginLimits.MaxObservationLength, ed25519.SignatureSize+sigOverhead), cfg.N()), overhead) diff --git a/offchainreporting2plus/internal/ocr3/protocol/message.go b/offchainreporting2plus/internal/ocr3/protocol/message.go index aead5fcc..287d872a 100644 --- a/offchainreporting2plus/internal/ocr3/protocol/message.go +++ b/offchainreporting2plus/internal/ocr3/protocol/message.go @@ -194,7 +194,10 @@ func (msg MessageEpochStartRequest[RI]) CheckSize(n int, f int, limits ocr3types if !msg.HighestCertified.CheckSize(n, f, limits, maxReportSigLen) { return false } - if len(msg.SignedHighestCertifiedTimestamp.Signature) != ed25519.SignatureSize { + if len(msg.SignedHighestCertifiedTimestamp.Signature) > ed25519.SignatureSize { + return false + } + if len(msg.SignedHighestCertifiedTimestamp.Signature31) > ed25519.SignatureSize { return false } return true @@ -218,6 +221,7 @@ func (msg MessageEpochStartRequest[RI]) epoch() uint64 { type MessageEpochStart[RI any] struct { Epoch uint64 EpochStartProof EpochStartProof + Signature31 EpochStartSignature31 } var _ MessageToOutcomeGeneration[struct{}] = (*MessageEpochStart[struct{}])(nil) @@ -230,10 +234,17 @@ func (msg MessageEpochStart[RI]) CheckSize(n int, f int, limits ocr3types.Report return false } for _, ashct := range msg.EpochStartProof.HighestCertifiedProof { - if len(ashct.SignedHighestCertifiedTimestamp.Signature) != ed25519.SignatureSize { + if len(ashct.SignedHighestCertifiedTimestamp.Signature) > ed25519.SignatureSize { + return false + } + if len(ashct.SignedHighestCertifiedTimestamp.Signature31) > ed25519.SignatureSize { return false } } + //nolint:gosimple + if len(msg.Signature31) > ed25519.SignatureSize { + return false + } return true } diff --git a/offchainreporting2plus/internal/ocr3/protocol/outcome_generation.go b/offchainreporting2plus/internal/ocr3/protocol/outcome_generation.go index b54b3628..f1fba0e9 100644 --- a/offchainreporting2plus/internal/ocr3/protocol/outcome_generation.go +++ b/offchainreporting2plus/internal/ocr3/protocol/outcome_generation.go @@ -146,7 +146,6 @@ type sharedState struct { firstSeqNrOfEpoch uint64 seqNr uint64 - observationQuorum *int committedSeqNr uint64 committedOutcome ocr3types.Outcome } @@ -189,7 +188,6 @@ func (outgen *outcomeGenerationState[RI]) run(restoredCert CertifiedPrepareOrCom 0, 0, - nil, 0, nil, } diff --git a/offchainreporting2plus/internal/ocr3/protocol/outcome_generation_follower.go b/offchainreporting2plus/internal/ocr3/protocol/outcome_generation_follower.go index 24c198a7..40f92f51 100644 --- a/offchainreporting2plus/internal/ocr3/protocol/outcome_generation_follower.go +++ b/offchainreporting2plus/internal/ocr3/protocol/outcome_generation_follower.go @@ -84,7 +84,7 @@ func (outgen *outcomeGenerationState[RI]) messageEpochStart(msg MessageEpochStar } else { // We're dealing with a re-proposal from a failed epoch - prepareQc, ok := msg.EpochStartProof.HighestCertified.(*CertifiedPrepare) + prepareQC, ok := msg.EpochStartProof.HighestCertified.(*CertifiedPrepare) if !ok { outgen.logger.Critical("cast to CertifiedPrepare failed while processing MessageEpochStart", commontypes.LogFields{ "seqNr": outgen.sharedState.seqNr, @@ -96,11 +96,11 @@ func (outgen *outcomeGenerationState[RI]) messageEpochStart(msg MessageEpochStar // in case of a re-proposal. outcomeInputsDigest := OutcomeInputsDigest{} - outcomeDigest := MakeOutcomeDigest(prepareQc.Outcome) + outcomeDigest := MakeOutcomeDigest(prepareQC.Outcome) prepareSignature, err := MakePrepareSignature( outgen.ID(), - prepareQc.SeqNr, + prepareQC.SeqNr, outcomeInputsDigest, outcomeDigest, outgen.offchainKeyring.OffchainSign, @@ -113,13 +113,12 @@ func (outgen *outcomeGenerationState[RI]) messageEpochStart(msg MessageEpochStar return } - outgen.sharedState.firstSeqNrOfEpoch = prepareQc.SeqNr + 1 - outgen.sharedState.seqNr = prepareQc.SeqNr - outgen.sharedState.observationQuorum = nil + outgen.sharedState.firstSeqNrOfEpoch = prepareQC.SeqNr + 1 + outgen.sharedState.seqNr = prepareQC.SeqNr outgen.followerState.phase = outgenFollowerPhaseSentPrepare outgen.followerState.outcome = outcomeAndDigests{ - prepareQc.Outcome, + prepareQC.Outcome, outcomeInputsDigest, outcomeDigest, } @@ -128,7 +127,7 @@ func (outgen *outcomeGenerationState[RI]) messageEpochStart(msg MessageEpochStar }) outgen.netSender.Broadcast(MessagePrepare[RI]{ outgen.sharedState.e, - prepareQc.SeqNr, + prepareQC.SeqNr, prepareSignature, }) } @@ -136,7 +135,6 @@ func (outgen *outcomeGenerationState[RI]) messageEpochStart(msg MessageEpochStar func (outgen *outcomeGenerationState[RI]) startSubsequentFollowerRound() { outgen.sharedState.seqNr = outgen.sharedState.committedSeqNr + 1 - outgen.sharedState.observationQuorum = nil outgen.followerState.phase = outgenFollowerPhaseNewRound outgen.followerState.query = nil @@ -264,7 +262,7 @@ func (outgen *outcomeGenerationState[RI]) backgroundObservation( func (outgen *outcomeGenerationState[RI]) eventComputedObservation(ev EventComputedObservation[RI]) { if ev.Epoch != outgen.sharedState.e || ev.SeqNr != outgen.sharedState.seqNr { - outgen.logger.Debug("discarding EventComputedObservation from old round", commontypes.LogFields{ + outgen.logger.Debug("dropping EventComputedObservation from old round", commontypes.LogFields{ "seqNr": outgen.sharedState.seqNr, "evEpoch": ev.Epoch, "evSeqNr": ev.SeqNr, @@ -273,7 +271,7 @@ func (outgen *outcomeGenerationState[RI]) eventComputedObservation(ev EventCompu } if outgen.followerState.phase != outgenFollowerPhaseBackgroundObservation { - outgen.logger.Debug("discarding EventComputedObservation, wrong phase", commontypes.LogFields{ + outgen.logger.Debug("dropping EventComputedObservation, wrong phase", commontypes.LogFields{ "seqNr": outgen.sharedState.seqNr, "phase": outgen.followerState.phase, }) @@ -536,7 +534,7 @@ func (outgen *outcomeGenerationState[RI]) backgroundProposalOutcome( func (outgen *outcomeGenerationState[RI]) eventComputedProposalOutcome(ev EventComputedProposalOutcome[RI]) { if ev.Epoch != outgen.sharedState.e || ev.SeqNr != outgen.sharedState.seqNr { - outgen.logger.Debug("discarding EventComputedProposalOutcome from old round", commontypes.LogFields{ + outgen.logger.Debug("dropping EventComputedProposalOutcome from old round", commontypes.LogFields{ "seqNr": outgen.sharedState.seqNr, "evEpoch": ev.Epoch, "evSeqNr": ev.SeqNr, @@ -545,7 +543,7 @@ func (outgen *outcomeGenerationState[RI]) eventComputedProposalOutcome(ev EventC } if outgen.followerState.phase != outgenFollowerPhaseBackgroundProposalOutcome { - outgen.logger.Debug("discarding EventComputedProposalOutcome, wrong phase", commontypes.LogFields{ + outgen.logger.Debug("dropping EventComputedProposalOutcome, wrong phase", commontypes.LogFields{ "seqNr": outgen.sharedState.seqNr, "phase": outgen.followerState.phase, }) @@ -836,7 +834,7 @@ func (outgen *outcomeGenerationState[RI]) commit(commit CertifiedCommit) { if commit.SeqNr <= outgen.sharedState.committedSeqNr { outgen.logger.Debug("skipping commit of already committed outcome", commontypes.LogFields{ - "commitSeqNr ": commit.SeqNr, + "commitSeqNr": commit.SeqNr, "committedSeqNr": outgen.sharedState.committedSeqNr, }) } else { @@ -868,7 +866,7 @@ func (outgen *outcomeGenerationState[RI]) commit(commit CertifiedCommit) { // Updates and persists cert if it is greater than the current cert. // Returns false if the cert could not be persisted, in which case the round should be aborted. func (outgen *outcomeGenerationState[RI]) persistAndUpdateCertIfGreater(cert CertifiedPrepareOrCommit) (ok bool) { - if outgen.followerState.cert.Timestamp().Less(cert.Timestamp()) { + if outgen.followerState.cert.Timestamp().Less31(cert.Timestamp()) { ctx, cancel := context.WithTimeout(outgen.ctx, outgen.localConfig.DatabaseTimeout) defer cancel() if err := outgen.database.WriteCert(ctx, outgen.config.ConfigDigest, cert); err != nil { diff --git a/offchainreporting2plus/internal/ocr3/protocol/outcome_generation_leader.go b/offchainreporting2plus/internal/ocr3/protocol/outcome_generation_leader.go index 6ef1541d..5104b99b 100644 --- a/offchainreporting2plus/internal/ocr3/protocol/outcome_generation_leader.go +++ b/offchainreporting2plus/internal/ocr3/protocol/outcome_generation_leader.go @@ -79,27 +79,33 @@ func (outgen *outcomeGenerationState[RI]) messageEpochStartRequest(msg MessageEp return } - goodCount := 0 - var maxSender *commontypes.OracleID - for sender, epochStartRequest := range outgen.leaderState.epochStartRequests { + notBadCount := 0 // Note: just because a request is not bad does not mean it's good. Tertium datur! + for _, epochStartRequest := range outgen.leaderState.epochStartRequests { if epochStartRequest.bad { continue } - goodCount++ - - if maxSender == nil || outgen.leaderState.epochStartRequests[*maxSender].message.SignedHighestCertifiedTimestamp.HighestCertifiedTimestamp.Less(epochStartRequest.message.SignedHighestCertifiedTimestamp.HighestCertifiedTimestamp) { - sender := sender - maxSender = &sender - } + notBadCount++ } - if maxSender == nil || goodCount < outgen.config.ByzQuorumSize() { + if notBadCount < outgen.config.ByzQuorumSize() { return } + var maxSender *commontypes.OracleID + for sender, epochStartRequest := range outgen.leaderState.epochStartRequests { + if maxSender != nil { + maxTimestamp := outgen.leaderState.epochStartRequests[*maxSender].message.HighestCertified.Timestamp() + if !maxTimestamp.Less31(epochStartRequest.message.HighestCertified.Timestamp()) { + continue + } + } + + maxSender = &sender + } + maxRequest := outgen.leaderState.epochStartRequests[*maxSender] - if maxRequest.message.HighestCertified.Timestamp() != maxRequest.message.SignedHighestCertifiedTimestamp.HighestCertifiedTimestamp { + if !maxRequest.message.HighestCertified.Timestamp().Equal(maxRequest.message.SignedHighestCertifiedTimestamp.HighestCertifiedTimestamp) { maxRequest.bad = true outgen.logger.Warn("timestamp mismatch in MessageEpochStartRequest", commontypes.LogFields{ "sender": *maxSender, @@ -159,9 +165,23 @@ func (outgen *outcomeGenerationState[RI]) messageEpochStartRequest(msg MessageEp "contributors": contributors, }) + epochStartSignature31, err := MakeEpochStartSignature31( + outgen.ID(), + epochStartProof, + outgen.offchainKeyring.OffchainSign, + ) + + if err != nil { + outgen.logger.Error("MakeEpochStartSignature31 returned error", commontypes.LogFields{ + "error": err, + }) + return + } + outgen.netSender.Broadcast(MessageEpochStart[RI]{ outgen.sharedState.e, epochStartProof, + epochStartSignature31, }) if epochStartProof.HighestCertified.IsGenesis() { @@ -172,12 +192,12 @@ func (outgen *outcomeGenerationState[RI]) messageEpochStartRequest(msg MessageEp outgen.sharedState.firstSeqNrOfEpoch = outgen.sharedState.committedSeqNr + 1 outgen.startSubsequentLeaderRound() } else { - prepareQc, ok := epochStartProof.HighestCertified.(*CertifiedPrepare) + prepareQC, ok := epochStartProof.HighestCertified.(*CertifiedPrepare) if !ok { outgen.logger.Critical("cast to CertifiedPrepare failed while processing MessageEpochStartRequest", nil) return } - outgen.sharedState.firstSeqNrOfEpoch = prepareQc.SeqNr + 1 + outgen.sharedState.firstSeqNrOfEpoch = prepareQC.SeqNr + 1 // We're dealing with a re-proposal from a failed epoch based on a // prepare qc. // We don't want to send MessageRoundStart. @@ -241,7 +261,7 @@ func (outgen *outcomeGenerationState[RI]) backgroundQuery( func (outgen *outcomeGenerationState[RI]) eventComputedQuery(ev EventComputedQuery[RI]) { if ev.Epoch != outgen.sharedState.e || ev.SeqNr != outgen.sharedState.committedSeqNr+1 { - outgen.logger.Debug("discarding EventComputedQuery from old round", commontypes.LogFields{ + outgen.logger.Debug("dropping EventComputedQuery from old round", commontypes.LogFields{ "seqNr": outgen.sharedState.seqNr, "committedSeqNr": outgen.sharedState.committedSeqNr, "evEpoch": ev.Epoch, @@ -392,7 +412,7 @@ func (outgen *outcomeGenerationState[RI]) backgroundVerifyValidateObservation( func (outgen *outcomeGenerationState[RI]) eventComputedValidateVerifyObservation(ev EventComputedValidateVerifyObservation[RI]) { if ev.Epoch != outgen.sharedState.e || ev.SeqNr != outgen.sharedState.seqNr { - outgen.logger.Debug("discarding EventComputedValidateVerifyObservation from old round", commontypes.LogFields{ + outgen.logger.Debug("dropping EventComputedValidateVerifyObservation from old round", commontypes.LogFields{ "seqNr": outgen.sharedState.seqNr, "evEpoch": ev.Epoch, "evSeqNr": ev.SeqNr, @@ -401,7 +421,7 @@ func (outgen *outcomeGenerationState[RI]) eventComputedValidateVerifyObservation } if outgen.leaderState.phase != outgenLeaderPhaseSentRoundStart && outgen.leaderState.phase != outgenLeaderPhaseGrace { - outgen.logger.Debug("discarding EventComputedValidateVerifyObservation, wrong phase", commontypes.LogFields{ + outgen.logger.Debug("dropping EventComputedValidateVerifyObservation, wrong phase", commontypes.LogFields{ "seqNr": outgen.sharedState.seqNr, "phase": outgen.leaderState.phase, }) @@ -484,7 +504,7 @@ func (outgen *outcomeGenerationState[RI]) backgroundObservationQuorum( func (outgen *outcomeGenerationState[RI]) eventComputedObservationQuorumSuccess(ev EventComputedObservationQuorumSuccess[RI]) { if ev.Epoch != outgen.sharedState.e || ev.SeqNr != outgen.sharedState.seqNr { - outgen.logger.Debug("discarding EventComputedObservationQuorumSuccess from old round", commontypes.LogFields{ + outgen.logger.Debug("dropping EventComputedObservationQuorumSuccess from old round", commontypes.LogFields{ "seqNr": outgen.sharedState.seqNr, "evEpoch": ev.Epoch, "evSeqNr": ev.SeqNr, @@ -493,7 +513,7 @@ func (outgen *outcomeGenerationState[RI]) eventComputedObservationQuorumSuccess( } if outgen.leaderState.phase != outgenLeaderPhaseSentRoundStart { - outgen.logger.Debug("discarding EventComputedObservationQuorumSuccess, wrong phase", commontypes.LogFields{ + outgen.logger.Debug("dropping EventComputedObservationQuorumSuccess, wrong phase", commontypes.LogFields{ "seqNr": outgen.sharedState.seqNr, "phase": outgen.leaderState.phase, }) diff --git a/offchainreporting2plus/internal/ocr3/protocol/report_attestation.go b/offchainreporting2plus/internal/ocr3/protocol/report_attestation.go index 7d67bb7c..a1f712c6 100644 --- a/offchainreporting2plus/internal/ocr3/protocol/report_attestation.go +++ b/offchainreporting2plus/internal/ocr3/protocol/report_attestation.go @@ -130,17 +130,17 @@ func (repatt *reportAttestationState[RI]) messageReportSignatures( repatt.tryReap(msg.SeqNr, sender) if repatt.isBeyondExpiry(msg.SeqNr) { - repatt.logger.Debug("ignoring MessageReportSignatures for expired seqNr", commontypes.LogFields{ - "seqNr": msg.SeqNr, - "sender": sender, + repatt.logger.Debug("dropping MessageReportSignatures for expired seqNr", commontypes.LogFields{ + "msgSeqNr": msg.SeqNr, + "sender": sender, }) return } if repatt.isBeyondLookahead(msg.SeqNr) { - repatt.logger.Debug("ignoring MessageReportSignatures for seqNr beyond lookahead", commontypes.LogFields{ - "seqNr": msg.SeqNr, - "sender": sender, + repatt.logger.Debug("dropping MessageReportSignatures for seqNr beyond lookahead", commontypes.LogFields{ + "msgSeqNr": msg.SeqNr, + "sender": sender, }) return } @@ -159,9 +159,9 @@ func (repatt *reportAttestationState[RI]) messageReportSignatures( } if len(repatt.rounds[msg.SeqNr].oracles[sender].signatures) != 0 { - repatt.logger.Debug("ignoring MessageReportSignatures with duplicate signature", commontypes.LogFields{ - "seqNr": msg.SeqNr, - "sender": sender, + repatt.logger.Debug("dropping MessageReportSignatures with duplicate signature", commontypes.LogFields{ + "msgSeqNr": msg.SeqNr, + "sender": sender, }) return } @@ -174,7 +174,7 @@ func (repatt *reportAttestationState[RI]) messageReportSignatures( func (repatt *reportAttestationState[RI]) eventMissingOutcome(ev EventMissingOutcome[RI]) { if repatt.rounds[ev.SeqNr].verifiedCertifiedCommit != nil { repatt.logger.Debug("dropping EventMissingOutcome, already have Outcome", commontypes.LogFields{ - "seqNr": ev.SeqNr, + "evSeqNr": ev.SeqNr, }) return } @@ -185,16 +185,16 @@ func (repatt *reportAttestationState[RI]) eventMissingOutcome(ev EventMissingOut func (repatt *reportAttestationState[RI]) messageCertifiedCommitRequest(msg MessageCertifiedCommitRequest[RI], sender commontypes.OracleID) { if repatt.rounds[msg.SeqNr] == nil || repatt.rounds[msg.SeqNr].verifiedCertifiedCommit == nil { repatt.logger.Debug("dropping MessageCertifiedCommitRequest for outcome with unknown certified commit", commontypes.LogFields{ - "seqNr": msg.SeqNr, - "sender": sender, + "msgSeqNr": msg.SeqNr, + "sender": sender, }) return } if repatt.rounds[msg.SeqNr].oracles[sender].weServiced { repatt.logger.Warn("dropping duplicate MessageCertifiedCommitRequest", commontypes.LogFields{ - "seqNr": msg.SeqNr, - "sender": sender, + "msgSeqNr": msg.SeqNr, + "sender": sender, }) return } @@ -202,8 +202,8 @@ func (repatt *reportAttestationState[RI]) messageCertifiedCommitRequest(msg Mess repatt.rounds[msg.SeqNr].oracles[sender].weServiced = true repatt.logger.Debug("sending MessageCertifiedCommit", commontypes.LogFields{ - "seqNr": msg.SeqNr, - "to": sender, + "msgSeqNr": msg.SeqNr, + "to": sender, }) repatt.netSender.SendTo(MessageCertifiedCommit[RI]{*repatt.rounds[msg.SeqNr].verifiedCertifiedCommit}, sender) } @@ -211,8 +211,8 @@ func (repatt *reportAttestationState[RI]) messageCertifiedCommitRequest(msg Mess func (repatt *reportAttestationState[RI]) messageCertifiedCommit(msg MessageCertifiedCommit[RI], sender commontypes.OracleID) { if repatt.rounds[msg.CertifiedCommit.SeqNr] == nil { repatt.logger.Warn("dropping MessageCertifiedCommit for unknown seqNr", commontypes.LogFields{ - "seqNr": msg.CertifiedCommit.SeqNr, - "sender": sender, + "msgSeqNr": msg.CertifiedCommit.SeqNr, + "sender": sender, }) return } @@ -220,7 +220,7 @@ func (repatt *reportAttestationState[RI]) messageCertifiedCommit(msg MessageCert oracle := &repatt.rounds[msg.CertifiedCommit.SeqNr].oracles[sender] if !(oracle.weRequested && !oracle.theyServiced) { repatt.logger.Warn("dropping unexpected MessageCertifiedCommit", commontypes.LogFields{ - "seqNr": msg.CertifiedCommit.SeqNr, + "msgSeqNr": msg.CertifiedCommit.SeqNr, "sender": sender, "weRequested": oracle.weRequested, "theyServiced": oracle.theyServiced, @@ -232,23 +232,23 @@ func (repatt *reportAttestationState[RI]) messageCertifiedCommit(msg MessageCert if repatt.rounds[msg.CertifiedCommit.SeqNr].verifiedCertifiedCommit != nil { repatt.logger.Debug("dropping redundant MessageCertifiedCommit", commontypes.LogFields{ - "seqNr": msg.CertifiedCommit.SeqNr, - "sender": sender, + "msgSeqNr": msg.CertifiedCommit.SeqNr, + "sender": sender, }) return } if err := msg.CertifiedCommit.Verify(repatt.config.ConfigDigest, repatt.config.OracleIdentities, repatt.config.ByzQuorumSize()); err != nil { repatt.logger.Warn("dropping MessageCertifiedCommit with invalid certified commit", commontypes.LogFields{ - "seqNr": msg.CertifiedCommit.SeqNr, - "sender": sender, + "msgSeqNr": msg.CertifiedCommit.SeqNr, + "sender": sender, }) return } repatt.logger.Debug("received valid MessageCertifiedCommit", commontypes.LogFields{ - "seqNr": msg.CertifiedCommit.SeqNr, - "sender": sender, + "msgSeqNr": msg.CertifiedCommit.SeqNr, + "sender": sender, }) repatt.receivedVerifiedCertifiedCommit(msg.CertifiedCommit) @@ -507,7 +507,7 @@ func (repatt *reportAttestationState[RI]) backgroundComputeReports(ctx context.C func (repatt *reportAttestationState[RI]) eventComputedReports(ev EventComputedReports[RI]) { if repatt.rounds[ev.SeqNr] == nil { - repatt.logger.Debug("discarding EventComputedReports from old round", commontypes.LogFields{ + repatt.logger.Debug("dropping EventComputedReports from old round", commontypes.LogFields{ "evSeqNr": ev.SeqNr, "highWaterMark": repatt.highWaterMark, "expiryRounds": repatt.expiryRounds(), @@ -522,9 +522,9 @@ func (repatt *reportAttestationState[RI]) eventComputedReports(ev EventComputedR sig, err := repatt.onchainKeyring.Sign(repatt.config.ConfigDigest, ev.SeqNr, reportPlus.ReportWithInfo) if err != nil { repatt.logger.Error("error while signing report", commontypes.LogFields{ - "seqNr": ev.SeqNr, - "index": i, - "error": err, + "evSeqNr": ev.SeqNr, + "index": i, + "error": err, }) return } @@ -532,7 +532,7 @@ func (repatt *reportAttestationState[RI]) eventComputedReports(ev EventComputedR } repatt.logger.Debug("broadcasting MessageReportSignatures", commontypes.LogFields{ - "seqNr": ev.SeqNr, + "evSeqNr": ev.SeqNr, }) repatt.netSender.Broadcast(MessageReportSignatures[RI]{ diff --git a/offchainreporting2plus/internal/ocr3/protocol/signed_data.go b/offchainreporting2plus/internal/ocr3/protocol/signed_data.go index e20e89ea..f969f264 100644 --- a/offchainreporting2plus/internal/ocr3/protocol/signed_data.go +++ b/offchainreporting2plus/internal/ocr3/protocol/signed_data.go @@ -265,17 +265,29 @@ type AttributedCommitSignature struct { type HighestCertifiedTimestamp struct { SeqNr uint64 CommittedElsePrepared bool + Epoch uint64 } func (t HighestCertifiedTimestamp) Less(t2 HighestCertifiedTimestamp) bool { return t.SeqNr < t2.SeqNr || t.SeqNr == t2.SeqNr && !t.CommittedElsePrepared && t2.CommittedElsePrepared } +func (t HighestCertifiedTimestamp) Less31(t2 HighestCertifiedTimestamp) bool { + return t.SeqNr < t2.SeqNr || + t.SeqNr == t2.SeqNr && !t.CommittedElsePrepared && t2.CommittedElsePrepared || + t.SeqNr == t2.SeqNr && t.CommittedElsePrepared == t2.CommittedElsePrepared && t.Epoch < t2.Epoch +} + +func (t HighestCertifiedTimestamp) Equal(t2 HighestCertifiedTimestamp) bool { + return t.SeqNr == t2.SeqNr && t.CommittedElsePrepared == t2.CommittedElsePrepared +} + const signedHighestCertifiedTimestampDomainSeparator = "ocr3 SignedHighestCertifiedTimestamp" type SignedHighestCertifiedTimestamp struct { HighestCertifiedTimestamp HighestCertifiedTimestamp Signature []byte + Signature31 []byte } func MakeSignedHighestCertifiedTimestamp( @@ -288,9 +300,15 @@ func MakeSignedHighestCertifiedTimestamp( return SignedHighestCertifiedTimestamp{}, err } + sig31, err := signer(signedHighestCertifiedTimestamp31Msg(ogid, highestCertifiedTimestamp)) + if err != nil { + return SignedHighestCertifiedTimestamp{}, err + } + return SignedHighestCertifiedTimestamp{ highestCertifiedTimestamp, sig, + sig31, }, nil } @@ -302,6 +320,7 @@ func (shct *SignedHighestCertifiedTimestamp) Verify(ogid OutcomeGenerationID, pu } ok := ed25519.Verify(pk, signedHighestCertifiedTimestampMsg(ogid, shct.HighestCertifiedTimestamp), shct.Signature) + if !ok { return fmt.Errorf("SignedHighestCertifiedTimestamp signature failed to verify") } @@ -333,6 +352,32 @@ func signedHighestCertifiedTimestampMsg( return ocr3DomainSeparatedSum(h) } +func signedHighestCertifiedTimestamp31Msg( + ogid OutcomeGenerationID, + highestCertifiedTimestamp HighestCertifiedTimestamp, +) []byte { + h := sha256.New() + + _, _ = h.Write([]byte(signedHighestCertifiedTimestampDomainSeparator)) + + _, _ = h.Write(ogid.ConfigDigest[:]) + _ = binary.Write(h, binary.BigEndian, ogid.Epoch) + + _ = binary.Write(h, binary.BigEndian, highestCertifiedTimestamp.SeqNr) + + var committedElsePreparedByte uint8 + if highestCertifiedTimestamp.CommittedElsePrepared { + committedElsePreparedByte = 1 + } else { + committedElsePreparedByte = 0 + } + _, _ = h.Write([]byte{byte(committedElsePreparedByte)}) + + _ = binary.Write(h, binary.BigEndian, highestCertifiedTimestamp.Epoch) + + return ocr3DomainSeparatedSum(h) +} + type AttributedSignedHighestCertifiedTimestamp struct { SignedHighestCertifiedTimestamp SignedHighestCertifiedTimestamp Signer commontypes.OracleID @@ -372,7 +417,7 @@ func (qc *EpochStartProof) Verify( } } - if qc.HighestCertified.Timestamp() != maximumTimestamp { + if !qc.HighestCertified.Timestamp().Equal(maximumTimestamp) { return fmt.Errorf("mismatch between timestamp of HighestCertified (%v) and the max from HighestCertifiedProof (%v)", qc.HighestCertified.Timestamp(), maximumTimestamp) } @@ -394,6 +439,7 @@ type CertifiedPrepareOrCommit interface { byzQuorumSize int, ) error CheckSize(n int, f int, limits ocr3types.ReportingPluginLimits, maxReportSigLen int) bool + SignatureMsg(ogid OutcomeGenerationID) []byte } var _ CertifiedPrepareOrCommit = &CertifiedPrepare{} @@ -416,6 +462,7 @@ func (hc *CertifiedPrepare) Timestamp() HighestCertifiedTimestamp { return HighestCertifiedTimestamp{ hc.SeqNr, false, + hc.PrepareEpoch, } } @@ -468,6 +515,10 @@ func (hc *CertifiedPrepare) CheckSize(n int, f int, limits ocr3types.ReportingPl return true } +func (hc *CertifiedPrepare) SignatureMsg(ogid OutcomeGenerationID) []byte { + return prepareSignatureMsg(ogid, hc.SeqNr, hc.OutcomeInputsDigest, MakeOutcomeDigest(hc.Outcome)) +} + var _ CertifiedPrepareOrCommit = &CertifiedCommit{} // The empty CertifiedCommit{} is the genesis value @@ -488,6 +539,7 @@ func (hc *CertifiedCommit) Timestamp() HighestCertifiedTimestamp { return HighestCertifiedTimestamp{ hc.SeqNr, true, + hc.CommitEpoch, } } @@ -549,3 +601,55 @@ func (hc *CertifiedCommit) CheckSize(n int, f int, limits ocr3types.ReportingPlu } return true } + +func (hc *CertifiedCommit) SignatureMsg(ogid OutcomeGenerationID) []byte { + return commitSignatureMsg(ogid, hc.SeqNr, MakeOutcomeDigest(hc.Outcome)) +} + +const epochStartProofSignatureDomainSeparator = "ocr3 EpochStartProofSignature" + +func epochStartProofSignatureMsg(ogid OutcomeGenerationID, esp EpochStartProof) []byte { + h := sha256.New() + + _, _ = h.Write([]byte(epochStartProofSignatureDomainSeparator)) + + _, _ = h.Write(ogid.ConfigDigest[:]) + _ = binary.Write(h, binary.BigEndian, ogid.Epoch) + + highestCertifiedEnc := esp.HighestCertified.SignatureMsg(ogid) + _ = binary.Write(h, binary.BigEndian, uint64(len(highestCertifiedEnc))) + _, _ = h.Write(highestCertifiedEnc) + + _ = binary.Write(h, binary.BigEndian, uint64(len(esp.HighestCertifiedProof))) + for _, ashct := range esp.HighestCertifiedProof { + + _ = binary.Write(h, binary.BigEndian, ashct.SignedHighestCertifiedTimestamp.HighestCertifiedTimestamp.SeqNr) + + var committedElsePreparedByte uint8 + if ashct.SignedHighestCertifiedTimestamp.HighestCertifiedTimestamp.CommittedElsePrepared { + committedElsePreparedByte = 1 + } else { + committedElsePreparedByte = 0 + } + _, _ = h.Write([]byte{byte(committedElsePreparedByte)}) + + _ = binary.Write(h, binary.BigEndian, ashct.SignedHighestCertifiedTimestamp.HighestCertifiedTimestamp.Epoch) + + _ = binary.Write(h, binary.BigEndian, uint64(len(ashct.SignedHighestCertifiedTimestamp.Signature31))) + _, _ = h.Write(ashct.SignedHighestCertifiedTimestamp.Signature31) + + _ = binary.Write(h, binary.BigEndian, uint64(ashct.Signer)) + } + + return ocr3DomainSeparatedSum(h) +} + +type EpochStartSignature31 []byte + +func MakeEpochStartSignature31( + ogid OutcomeGenerationID, + epochStartProof EpochStartProof, + signer func(msg []byte) ([]byte, error), +) (EpochStartSignature31, error) { + return signer(epochStartProofSignatureMsg(ogid, epochStartProof)) +} diff --git a/offchainreporting2plus/internal/ocr3/serialization/offchainreporting3_messages.pb.go b/offchainreporting2plus/internal/ocr3/serialization/offchainreporting3_messages.pb.go index f1bde480..f4f7ae3e 100644 --- a/offchainreporting2plus/internal/ocr3/serialization/offchainreporting3_messages.pb.go +++ b/offchainreporting2plus/internal/ocr3/serialization/offchainreporting3_messages.pb.go @@ -344,6 +344,7 @@ type MessageEpochStart struct { Epoch uint64 `protobuf:"varint,1,opt,name=epoch,proto3" json:"epoch,omitempty"` EpochStartProof *EpochStartProof `protobuf:"bytes,2,opt,name=epoch_start_proof,json=epochStartProof,proto3" json:"epoch_start_proof,omitempty"` + Signature31 []byte `protobuf:"bytes,3,opt,name=signature31,proto3" json:"signature31,omitempty"` } func (x *MessageEpochStart) Reset() { @@ -392,6 +393,13 @@ func (x *MessageEpochStart) GetEpochStartProof() *EpochStartProof { return nil } +func (x *MessageEpochStart) GetSignature31() []byte { + if x != nil { + return x.Signature31 + } + return nil +} + type MessageRoundStart struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1149,6 +1157,7 @@ type HighestCertifiedTimestamp struct { SeqNr uint64 `protobuf:"varint,1,opt,name=seq_nr,json=seqNr,proto3" json:"seq_nr,omitempty"` CommittedElsePrepared bool `protobuf:"varint,2,opt,name=committed_else_prepared,json=committedElsePrepared,proto3" json:"committed_else_prepared,omitempty"` + Epoch uint64 `protobuf:"varint,3,opt,name=epoch,proto3" json:"epoch,omitempty"` } func (x *HighestCertifiedTimestamp) Reset() { @@ -1197,6 +1206,13 @@ func (x *HighestCertifiedTimestamp) GetCommittedElsePrepared() bool { return false } +func (x *HighestCertifiedTimestamp) GetEpoch() uint64 { + if x != nil { + return x.Epoch + } + return 0 +} + type AttributedSignedHighestCertifiedTimestamp struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1259,6 +1275,7 @@ type SignedHighestCertifiedTimestamp struct { HighestCertifiedTimestamp *HighestCertifiedTimestamp `protobuf:"bytes,1,opt,name=highest_certified_timestamp,json=highestCertifiedTimestamp,proto3" json:"highest_certified_timestamp,omitempty"` Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` + Signature31 []byte `protobuf:"bytes,3,opt,name=signature31,proto3" json:"signature31,omitempty"` } func (x *SignedHighestCertifiedTimestamp) Reset() { @@ -1307,6 +1324,13 @@ func (x *SignedHighestCertifiedTimestamp) GetSignature() []byte { return nil } +func (x *SignedHighestCertifiedTimestamp) GetSignature31() []byte { + if x != nil { + return x.Signature31 + } + return nil +} + type AttributedSignedObservation struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1621,181 +1645,187 @@ var file_offchainreporting3_messages_proto_rawDesc = []byte{ 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x1f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x48, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x7a, 0x0a, 0x11, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x45, 0x70, 0x6f, 0x63, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x9c, 0x01, 0x0a, 0x11, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, + 0x70, 0x6f, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, + 0x68, 0x12, 0x4f, 0x0a, 0x11, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6f, + 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, + 0x33, 0x2e, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x6f, + 0x66, 0x52, 0x0f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74, 0x50, 0x72, 0x6f, + 0x6f, 0x66, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x33, + 0x31, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x33, 0x31, 0x22, 0x56, 0x0a, 0x11, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, 0x6f, + 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, + 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x97, 0x01, 0x0a, + 0x12, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, + 0x5f, 0x6e, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, + 0x12, 0x54, 0x0a, 0x12, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x6f, 0x62, 0x73, 0x65, 0x72, + 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, + 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, + 0x33, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, + 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb5, 0x01, 0x0a, 0x0f, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, - 0x12, 0x4f, 0x0a, 0x11, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, - 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6f, 0x66, - 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, - 0x2e, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, - 0x52, 0x0f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x6f, - 0x66, 0x22, 0x56, 0x0a, 0x11, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x6f, 0x75, 0x6e, - 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x15, 0x0a, 0x06, - 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, - 0x71, 0x4e, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x97, 0x01, 0x0a, 0x12, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x75, 0x0a, 0x1e, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x6f, 0x62, 0x73, + 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x2f, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x69, 0x6e, 0x67, 0x33, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x53, + 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x1c, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, + 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x5b, + 0x0a, 0x0e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x54, 0x0a, - 0x12, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x66, 0x66, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x2e, 0x53, - 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x11, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x22, 0xb5, 0x01, 0x0a, 0x0f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, - 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x61, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x15, 0x0a, - 0x06, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, - 0x65, 0x71, 0x4e, 0x72, 0x12, 0x75, 0x0a, 0x1e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x64, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x6f, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x1c, 0x0a, + 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x5a, 0x0a, 0x0d, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x65, 0x70, 0x6f, + 0x63, 0x68, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x5d, 0x0a, 0x17, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x2b, 0x0a, 0x11, 0x72, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0c, 0x52, 0x10, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x22, 0x36, 0x0a, 0x1d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x6e, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x22, 0x68, + 0x0a, 0x16, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x4e, 0x0a, 0x10, 0x63, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, + 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x0f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x22, 0xe3, 0x01, 0x0a, 0x0f, 0x45, 0x70, 0x6f, + 0x63, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x59, 0x0a, 0x11, + 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x2e, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x4f, 0x72, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x10, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x75, 0x0a, 0x17, 0x68, 0x69, 0x67, 0x68, 0x65, + 0x73, 0x74, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x6f, + 0x6f, 0x66, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x2e, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x48, 0x69, + 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x15, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0xb0, + 0x01, 0x0a, 0x18, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x50, 0x72, 0x65, 0x70, + 0x61, 0x72, 0x65, 0x4f, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x40, 0x0a, 0x07, 0x70, + 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, - 0x33, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, - 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x1c, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, - 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x5b, 0x0a, 0x0e, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x65, 0x70, - 0x6f, 0x63, 0x68, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x5a, 0x0a, 0x0d, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, 0x6f, - 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, - 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x22, 0x5d, 0x0a, 0x17, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, + 0x33, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x50, 0x72, 0x65, 0x70, 0x61, + 0x72, 0x65, 0x48, 0x00, 0x52, 0x07, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x12, 0x3d, 0x0a, + 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, + 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, + 0x67, 0x33, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x48, 0x00, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x42, 0x13, 0x0a, 0x11, + 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x5f, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x22, 0x8a, 0x02, 0x0a, 0x10, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x50, + 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, + 0x65, 0x5f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x70, + 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x15, 0x0a, 0x06, 0x73, + 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, + 0x4e, 0x72, 0x12, 0x32, 0x0a, 0x15, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x5f, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x73, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x13, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, + 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, + 0x12, 0x6c, 0x0a, 0x1a, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x5f, 0x71, 0x75, 0x6f, 0x72, + 0x75, 0x6d, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, + 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x64, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x52, 0x18, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x51, 0x75, 0x6f, + 0x72, 0x75, 0x6d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x22, 0xd0, + 0x01, 0x0a, 0x0f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x65, 0x70, 0x6f, + 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x45, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x18, 0x0a, 0x07, + 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6f, + 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x12, 0x69, 0x0a, 0x19, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x5f, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x6f, 0x66, 0x66, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x2e, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x17, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x22, 0x80, 0x01, 0x0a, 0x19, 0x48, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x2b, 0x0a, 0x11, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0c, 0x52, 0x10, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x73, 0x22, 0x36, 0x0a, 0x1d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x65, - 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x22, 0x68, 0x0a, 0x16, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x4e, 0x0a, 0x10, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x23, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x69, 0x6e, 0x67, 0x33, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x0f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x22, 0xe3, 0x01, 0x0a, 0x0f, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x53, - 0x74, 0x61, 0x72, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x59, 0x0a, 0x11, 0x68, 0x69, 0x67, - 0x68, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, - 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, - 0x69, 0x65, 0x64, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x4f, 0x72, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x52, 0x10, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x65, 0x64, 0x12, 0x75, 0x0a, 0x17, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x5f, - 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x48, 0x69, 0x67, 0x68, 0x65, + 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x36, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x74, 0x65, 0x64, 0x5f, 0x65, 0x6c, 0x73, 0x65, 0x5f, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, + 0x65, 0x64, 0x45, 0x6c, 0x73, 0x65, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x12, 0x14, + 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x65, + 0x70, 0x6f, 0x63, 0x68, 0x22, 0xc6, 0x01, 0x0a, 0x29, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x48, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x12, 0x80, 0x01, 0x0a, 0x22, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x68, 0x69, + 0x67, 0x68, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x33, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x69, 0x6e, 0x67, 0x33, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x48, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x52, 0x15, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, - 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0xb0, 0x01, 0x0a, 0x18, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, - 0x4f, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x40, 0x0a, 0x07, 0x70, 0x72, 0x65, 0x70, - 0x61, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6f, 0x66, 0x66, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x2e, 0x43, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x48, - 0x00, 0x52, 0x07, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x12, 0x3d, 0x0a, 0x06, 0x63, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6f, 0x66, 0x66, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x2e, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x48, - 0x00, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x42, 0x13, 0x0a, 0x11, 0x70, 0x72, 0x65, - 0x70, 0x61, 0x72, 0x65, 0x5f, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x22, 0x8a, - 0x02, 0x0a, 0x10, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x50, 0x72, 0x65, 0x70, - 0x61, 0x72, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x5f, 0x65, - 0x70, 0x6f, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x70, 0x72, 0x65, 0x70, - 0x61, 0x72, 0x65, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, - 0x6e, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, - 0x32, 0x0a, 0x15, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, - 0x73, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, - 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x44, 0x69, 0x67, - 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6f, 0x75, 0x74, 0x63, 0x6f, 0x6d, 0x65, 0x12, 0x6c, 0x0a, - 0x1a, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x5f, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x5f, - 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x2e, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x64, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x52, 0x18, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x22, 0xd0, 0x01, 0x0a, 0x0f, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, - 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x45, 0x70, 0x6f, - 0x63, 0x68, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, 0x4e, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x75, 0x74, - 0x63, 0x6f, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6f, 0x75, 0x74, 0x63, - 0x6f, 0x6d, 0x65, 0x12, 0x69, 0x0a, 0x19, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x71, 0x75, - 0x6f, 0x72, 0x75, 0x6d, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x2e, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x17, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, - 0x72, 0x75, 0x6d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x22, 0x6a, - 0x0a, 0x19, 0x48, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x15, 0x0a, 0x06, 0x73, - 0x65, 0x71, 0x5f, 0x6e, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x65, 0x71, - 0x4e, 0x72, 0x12, 0x36, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x5f, - 0x65, 0x6c, 0x73, 0x65, 0x5f, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x15, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x45, 0x6c, - 0x73, 0x65, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x22, 0xc6, 0x01, 0x0a, 0x29, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x48, - 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x80, 0x01, 0x0a, 0x22, 0x73, 0x69, 0x67, - 0x6e, 0x65, 0x64, 0x5f, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, - 0x64, 0x48, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, - 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x1f, 0x73, 0x69, 0x67, 0x6e, - 0x65, 0x64, 0x48, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x73, - 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x69, 0x67, - 0x6e, 0x65, 0x72, 0x22, 0xae, 0x01, 0x0a, 0x1f, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x48, 0x69, - 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x6d, 0x0a, 0x1b, 0x68, 0x69, 0x67, 0x68, 0x65, - 0x73, 0x74, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x6f, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x1f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x48, 0x69, 0x67, 0x68, + 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x22, 0xd0, 0x01, + 0x0a, 0x1f, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x48, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x12, 0x6d, 0x0a, 0x1b, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x33, 0x2e, 0x48, 0x69, 0x67, 0x68, + 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x19, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x33, 0x31, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x33, 0x31, + 0x22, 0x8f, 0x01, 0x0a, 0x1b, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x53, + 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x54, 0x0a, 0x12, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x6f, 0x62, 0x73, 0x65, 0x72, + 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6e, 0x67, - 0x33, 0x2e, 0x48, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x19, 0x68, 0x69, 0x67, - 0x68, 0x65, 0x73, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x22, 0x8f, 0x01, 0x0a, 0x1b, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x54, 0x0a, 0x12, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x6f, - 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x25, 0x2e, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, - 0x74, 0x69, 0x6e, 0x67, 0x33, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, - 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, - 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x62, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x6f, 0x62, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x53, 0x0a, 0x11, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, - 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x6f, - 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x0b, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, - 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x52, 0x0a, 0x1a, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, - 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, - 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, - 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x22, - 0x51, 0x0a, 0x19, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1c, 0x0a, 0x09, - 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, - 0x67, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, - 0x65, 0x72, 0x42, 0x11, 0x5a, 0x0f, 0x2e, 0x3b, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x33, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, 0x72, + 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x22, 0x53, 0x0a, 0x11, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4f, 0x62, 0x73, 0x65, + 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x6f, 0x62, 0x73, 0x65, 0x72, + 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x6f, 0x62, + 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x52, 0x0a, 0x1a, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x64, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x53, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x22, 0x51, 0x0a, 0x19, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x42, 0x11, + 0x5a, 0x0f, 0x2e, 0x3b, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/offchainreporting2plus/internal/ocr3/serialization/serialization.go b/offchainreporting2plus/internal/ocr3/serialization/serialization.go index 49b084da..95eea53f 100644 --- a/offchainreporting2plus/internal/ocr3/serialization/serialization.go +++ b/offchainreporting2plus/internal/ocr3/serialization/serialization.go @@ -129,6 +129,7 @@ func (tpm *toProtoMessage[RI]) messageWrapper(m protocol.Message[RI]) (*MessageW // fields uint64(v.Epoch), tpm.epochStartProof(v.EpochStartProof), + v.Signature31, } msgWrapper.Msg = &MessageWrapper_MessageEpochStart{pm} case protocol.MessageRoundStart[RI]: @@ -332,6 +333,7 @@ func (tpm *toProtoMessage[RI]) signedHighestCertifiedTimestamp(shct protocol.Sig // fields tpm.highestCertifiedTimestamp(shct.HighestCertifiedTimestamp), shct.Signature, + shct.Signature31, } } @@ -344,6 +346,7 @@ func (tpm *toProtoMessage[RI]) highestCertifiedTimestamp(hct protocol.HighestCer // fields hct.SeqNr, hct.CommittedElsePrepared, + hct.Epoch, } } @@ -463,6 +466,7 @@ func (fpm *fromProtoMessage[RI]) messageEpochStart(m *MessageEpochStart) (protoc return protocol.MessageEpochStart[RI]{ m.Epoch, srqc, + m.Signature31, }, nil } @@ -586,6 +590,7 @@ func (fpm *fromProtoMessage[RI]) signedHighestCertifiedTimestamp(m *SignedHighes return protocol.SignedHighestCertifiedTimestamp{ hct, m.Signature, + m.Signature31, }, nil } @@ -596,6 +601,7 @@ func (fpm *fromProtoMessage[RI]) highestCertifiedTimestamp(m *HighestCertifiedTi return protocol.HighestCertifiedTimestamp{ m.SeqNr, m.CommittedElsePrepared, + m.Epoch, }, nil } @@ -618,8 +624,10 @@ func (fpm *fromProtoMessage[RI]) epochStartProof(m *EpochStartProof) (protocol.E protocol.HighestCertifiedTimestamp{ ashct.GetSignedHighestCertifiedTimestamp().GetHighestCertifiedTimestamp().GetSeqNr(), ashct.GetSignedHighestCertifiedTimestamp().GetHighestCertifiedTimestamp().GetCommittedElsePrepared(), + ashct.GetSignedHighestCertifiedTimestamp().GetHighestCertifiedTimestamp().GetEpoch(), }, ashct.GetSignedHighestCertifiedTimestamp().GetSignature(), + ashct.GetSignedHighestCertifiedTimestamp().GetSignature31(), }, signer, }) diff --git a/ragep2p/internal/knock/knock.go b/ragep2p/internal/knock/knock.go index f4b8d83d..b9e08f93 100644 --- a/ragep2p/internal/knock/knock.go +++ b/ragep2p/internal/knock/knock.go @@ -25,15 +25,18 @@ func messageToSign(peerID types.PeerID) []byte { // message and must correspond to self. // // Returns a knock message exactly KnockSize bytes long. -func BuildKnock(other types.PeerID, self types.PeerID, secretKey ed25519.PrivateKey) []byte { +func BuildKnock(other types.PeerID, self types.PeerID, keyring types.PeerKeyring) ([]byte, error) { msg := messageToSign(other) - sig := ed25519.Sign(secretKey, msg) + sig, err := keyring.Sign(msg) + if err != nil { + return nil, fmt.Errorf("keyring failed to sign knock message: %w", err) + } knock := make([]byte, 0, KnockSize) knock = append(knock, version) knock = append(knock, self[:]...) knock = append(knock, sig...) - return knock + return knock, nil } var ( diff --git a/ragep2p/internal/mtls/common.go b/ragep2p/internal/mtls/common.go index a7097e64..14c9f67f 100644 --- a/ragep2p/internal/mtls/common.go +++ b/ragep2p/internal/mtls/common.go @@ -2,24 +2,29 @@ package mtls import ( "crypto" - "crypto/ed25519" "crypto/rand" "crypto/tls" "crypto/x509" "fmt" "math/big" + + "github.com/smartcontractkit/libocr/ragep2p/types" ) // Generates a minimal certificate (that wouldn't be considered valid outside this telemetry networking protocol) -// from an Ed25519 private key. -func NewMinimalX509CertFromPrivateKey(sk ed25519.PrivateKey) tls.Certificate { +// from a PeerKeyring. +func NewMinimalX509CertFromKeyring(keyring types.PeerKeyring) (tls.Certificate, error) { template := x509.Certificate{ SerialNumber: big.NewInt(0), // serial number must be set, so we set it to 0 } - encodedCert, err := x509.CreateCertificate(rand.Reader, &template, &template, sk.Public(), sk) + // x509 args are of type any, even though crypto.Signer is required + var signer crypto.Signer //nolint:gosimple + signer = &peerKeyringCryptoSignerAdapter{keyring} + + encodedCert, err := x509.CreateCertificate(rand.Reader, &template, &template, signer.Public(), signer) if err != nil { - panic(err) + return tls.Certificate{}, fmt.Errorf("x509.CreateCertificate: %w", err) } // Uncomment this if you want to get an encoded cert you can feed into openssl x509 etc... @@ -28,14 +33,14 @@ func NewMinimalX509CertFromPrivateKey(sk ed25519.PrivateKey) tls.Certificate { // if err := pem.Encode(&buf, &pem.Block{Type: "CERTIFICATE", Bytes: encodedCert}); err != nil { // log.Fatalf("Failed to encode cert into pem format: %v", err) // } - // fmt.Printf("pubkey: %x\nencodedCert: %v\n", sk.Public(), buf.String()) + // fmt.Printf("pubkey: %x\nencodedCert: %v\n", signer.Public(), buf.String()) return tls.Certificate{ Certificate: [][]byte{encodedCert}, - PrivateKey: sk, + PrivateKey: signer, SupportedSignatureAlgorithms: []tls.SignatureScheme{tls.Ed25519}, - } + }, nil } func VerifyCertMatchesPubKey(publicKey [32]byte) func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { @@ -60,31 +65,9 @@ func VerifyCertMatchesPubKey(publicKey [32]byte) func(rawCerts [][]byte, verifie } } -func PubKeyFromCert(cert *x509.Certificate) (pk [ed25519.PublicKeySize]byte, err error) { +func PubKeyFromCert(cert *x509.Certificate) (pk types.PeerPublicKey, err error) { if cert.PublicKeyAlgorithm != x509.Ed25519 { return pk, fmt.Errorf("require ed25519 public key") } - return StaticallySizedEd25519PublicKey(cert.PublicKey) -} - -func StaticallySizedEd25519PublicKey(publickey crypto.PublicKey) ([ed25519.PublicKeySize]byte, error) { - var result [ed25519.PublicKeySize]byte - - pkslice, ok := publickey.(ed25519.PublicKey) - if !ok { - return result, fmt.Errorf("invalid ed25519 public key") - } - if ed25519.PublicKeySize != len(pkslice) { - return result, fmt.Errorf("invalid key size (expected %d, actual %d)", ed25519.PublicKeySize, len(pkslice)) - } - copy(result[:], pkslice) - return result, nil -} - -func MustStaticallySizedEd25519PublicKey(publickey crypto.PublicKey) [ed25519.PublicKeySize]byte { - result, err := StaticallySizedEd25519PublicKey(publickey) - if err != nil { - panic(err) - } - return result + return types.PeerPublicKeyFromGenericPublicKey(cert.PublicKey) } diff --git a/ragep2p/internal/mtls/crypto_signer_adapter.go b/ragep2p/internal/mtls/crypto_signer_adapter.go new file mode 100644 index 00000000..92ec306d --- /dev/null +++ b/ragep2p/internal/mtls/crypto_signer_adapter.go @@ -0,0 +1,32 @@ +package mtls + +import ( + "crypto" + "crypto/ed25519" + "fmt" + "io" + + "github.com/smartcontractkit/libocr/ragep2p/types" +) + +type peerKeyringCryptoSignerAdapter struct { + keyring types.PeerKeyring +} + +// Public implements crypto.Signer. +func (p *peerKeyringCryptoSignerAdapter) Public() crypto.PublicKey { + pk := p.keyring.PublicKey() + return ed25519.PublicKey(pk[:]) +} + +// Sign implements crypto.Signer. +func (p *peerKeyringCryptoSignerAdapter) Sign(_ io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) { + // We can safely ignore the io.Reader providing randomness, since we use + // deterministic Ed25519 here. + if opts != crypto.Hash(0) { + return nil, fmt.Errorf("unexpected SignerOpts for Ed25519: %v", opts) + } + return p.keyring.Sign(digest) +} + +var _ crypto.Signer = &peerKeyringCryptoSignerAdapter{} diff --git a/ragep2p/ragep2p.go b/ragep2p/ragep2p.go index a1cccb35..30787f44 100644 --- a/ragep2p/ragep2p.go +++ b/ragep2p/ragep2p.go @@ -2,7 +2,6 @@ package ragep2p import ( "context" - "crypto/ed25519" "crypto/tls" "encoding/hex" "fmt" @@ -150,7 +149,7 @@ type HostConfig struct { type Host struct { // Constructor args config HostConfig - secretKey ed25519.PrivateKey + keyring types.PeerKeyring listenAddresses []string discoverer Discoverer logger loghelper.LoggerWithContext @@ -158,7 +157,7 @@ type Host struct { hostMetrics *hostMetrics - // Derived from secretKey + // Derived from keyring id types.PeerID tlsCert tls.Certificate @@ -181,7 +180,7 @@ type Host struct { // discovering addresses of peers. func NewHost( config HostConfig, - secretKey ed25519.PrivateKey, + keyring types.PeerKeyring, listenAddresses []string, discoverer Discoverer, logger commontypes.Logger, @@ -191,25 +190,27 @@ func NewHost( return nil, fmt.Errorf("no listen addresses provided") } - id, err := mtls.StaticallySizedEd25519PublicKey(secretKey.Public()) + id := types.PeerIDFromKeyring(keyring) + + tlsCert, err := mtls.NewMinimalX509CertFromKeyring(keyring) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to create certificate from keyring for host: %w", err) } ctx, cancel := context.WithCancel(context.Background()) return &Host{ config, - secretKey, + keyring, listenAddresses, discoverer, // peerID might already be set to the same value if we are managed, but we don't take any chances - loghelper.MakeRootLoggerWithContext(logger).MakeChild(commontypes.LogFields{"id": "ragep2p", "peerID": types.PeerID(id)}), + loghelper.MakeRootLoggerWithContext(logger).MakeChild(commontypes.LogFields{"id": "ragep2p", "peerID": id}), metricsRegisterer, - newHostMetrics(metricsRegisterer, logger, types.PeerID(id)), + newHostMetrics(metricsRegisterer, logger, id), id, - mtls.NewMinimalX509CertFromPrivateKey(secretKey), + tlsCert, sync.Mutex{}, hostStatePending, @@ -253,7 +254,7 @@ func (ho *Host) Start() error { }) } - err := ho.discoverer.Start(ho, ho.secretKey, ho.logger) + err := ho.discoverer.Start(ho, ho.keyring, ho.logger) if err != nil { return fmt.Errorf("failed to start discoverer: %w", err) } @@ -689,7 +690,11 @@ func (ho *Host) handleOutgoingConnection(conn net.Conn, other types.PeerID, logg } }() - knck := knock.BuildKnock(other, ho.id, ho.secretKey) + knck, err := knock.BuildKnock(other, ho.id, ho.keyring) + if err != nil { + logger.Warn("Error while building knock", commontypes.LogFields{"error": err}) + return + } if err := conn.SetWriteDeadline(time.Now().Add(netTimeout)); err != nil { logger.Warn("Closing connection, error during SetWriteDeadline", commontypes.LogFields{"error": err}) return @@ -810,10 +815,10 @@ func (ho *Host) handleConnection(incoming bool, rlConn *ratelimitedconn.RateLimi logger.Warn("Closing connection, error getting public key", commontypes.LogFields{"error": err}) return } - if peer.other != pubKey { + if peer.other != types.PeerIDFromPeerPublicKey(pubKey) { logger.Warn("TLS handshake PeerID mismatch", commontypes.LogFields{ "expected": peer.other, - "actual": types.PeerID(pubKey), + "actual": types.PeerIDFromPeerPublicKey(pubKey), }) return } @@ -1527,7 +1532,7 @@ func incomingConnsRateLimit(durationBetweenDials time.Duration) ratelimit.Millit // Discoverer is responsible for discovering the addresses of peers on the network. type Discoverer interface { - Start(host *Host, privKey ed25519.PrivateKey, logger loghelper.LoggerWithContext) error + Start(host *Host, keyring types.PeerKeyring, logger loghelper.LoggerWithContext) error Close() error FindPeer(peer types.PeerID) ([]types.Address, error) } diff --git a/ragep2p/types/types.go b/ragep2p/types/types.go index 528463f8..11ed6732 100644 --- a/ragep2p/types/types.go +++ b/ragep2p/types/types.go @@ -2,12 +2,12 @@ package types import ( "bytes" + "crypto" "crypto/ed25519" "encoding" "fmt" "github.com/mr-tron/base58" - "github.com/smartcontractkit/libocr/ragep2p/internal/mtls" ) // Address represents a network address & port such as "192.168.1.2:8080". It @@ -15,7 +15,7 @@ import ( type Address string // PeerID represents a unique identifier for another peer. -type PeerID [32]byte +type PeerID [ed25519.PublicKeySize]byte var ( _ fmt.Stringer = PeerID{} @@ -72,15 +72,63 @@ func (p *PeerID) UnmarshalBinary(data []byte) error { return nil } +func PeerPublicKeyFromGenericPublicKey(publickey crypto.PublicKey) (PeerPublicKey, error) { + var result PeerPublicKey + + pkslice, ok := publickey.(ed25519.PublicKey) + if !ok { + return result, fmt.Errorf("invalid ed25519 public key") + } + if ed25519.PublicKeySize != len(pkslice) { + return result, fmt.Errorf("invalid key size (expected %d, actual %d)", ed25519.PublicKeySize, len(pkslice)) + } + copy(result[:], pkslice) + return result, nil +} + +func MustPeerPublicKeyFromGenericPublicKey(publickey crypto.PublicKey) PeerPublicKey { + result, err := PeerPublicKeyFromGenericPublicKey(publickey) + if err != nil { + panic(err) + } + return result +} + +func PeerIDFromPeerPublicKey(pk PeerPublicKey) PeerID { + return PeerID(pk) +} + func PeerIDFromPublicKey(pk ed25519.PublicKey) (PeerID, error) { - return mtls.StaticallySizedEd25519PublicKey(pk) + peerPublicKey, err := PeerPublicKeyFromGenericPublicKey(pk) + return PeerIDFromPeerPublicKey(peerPublicKey), err } func PeerIDFromPrivateKey(sk ed25519.PrivateKey) (PeerID, error) { return PeerIDFromPublicKey(sk.Public().(ed25519.PublicKey)) } +func PeerIDFromKeyring(keyring PeerKeyring) PeerID { + return PeerIDFromPeerPublicKey(keyring.PublicKey()) +} + type PeerInfo struct { ID PeerID Addrs []Address } + +// PeerPublicKey is the public key used to cryptographically identify an +// oracle in p2p related communications and peer discovery. +type PeerPublicKey [ed25519.PublicKeySize]byte + +func Ed25519PublicKeyFromPeerPublicKey(pk PeerPublicKey) ed25519.PublicKey { + return pk[:] +} + +type PeerKeyring interface { + // Sign returns an EdDSA-Ed25519 signature on msg produced using the + // standard library's ed25519.Sign function. Must be fast. + Sign(msg []byte) (signature []byte, err error) + + // PublicKey returns the public component of the keypair used in Sign. + PublicKey() PeerPublicKey +}