From 56fda787d5ca392d73c130362e6b36ed3f92b462 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Wed, 10 Dec 2025 18:27:56 +0100 Subject: [PATCH 01/53] buf plugin draft --- buf.gen.yaml | 8 ++ go.work.sum | 23 ++++- sei-tendermint/cmd/buf_plugin/main.go | 104 ++++++++++++++++++++ sei-tendermint/proto/tendermint/utils.proto | 14 +++ 4 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 sei-tendermint/cmd/buf_plugin/main.go create mode 100644 sei-tendermint/proto/tendermint/utils.proto diff --git a/buf.gen.yaml b/buf.gen.yaml index dfe4a5e848..275dbdc31b 100644 --- a/buf.gen.yaml +++ b/buf.gen.yaml @@ -42,3 +42,11 @@ plugins: - Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types - Mgoogle/protobuf/duration.proto=github.com/golang/protobuf/ptypes/duration - plugins=grpc + - local: + - go + - run + - ./cmd/protoc-gen-seiplugin + out: ./build/proto/sei-plugin + opt: + - annotation=sei.custom.plugin + - fail_on_deprecated=false diff --git a/go.work.sum b/go.work.sum index 409bf514e4..9fec94cdea 100644 --- a/go.work.sum +++ b/go.work.sum @@ -619,6 +619,7 @@ github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43 h1:nFBQlGtkbPzp/NjZL github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37 h1:JRVhO25+r3ar2mKGP7E0LDl8K9/G36gjlqca5iQbaqc= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45 h1:hze8YsjSh8Wl1rYa1CJpRmXP21BvOBuc76YhW0HsuQ4= github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.8.1 h1:w/fPGB0t5rWwA43mux4e9ozFSH5zF1moQemlA131PWc= +github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.8.1/go.mod h1:CM+19rL1+4dFWnOQKwDc7H1KwXTz+h61oUSHyhV0b3o= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.37 h1:WWZA/I2K4ptBS1kg0kV1JbBtG/umed0vwHRrmcr9z7k= github.com/aws/aws-sdk-go-v2/service/route53 v1.30.2 h1:/RPQNjh1sDIezpXaFIkZb7MlXnSyAqjVdAwcJuGYTqg= github.com/aws/aws-sdk-go-v2/service/sso v1.15.2 h1:JuPGc7IkOP4AaqcZSIcyqLpFSqBWK32rM9+a1g6u73k= @@ -647,7 +648,9 @@ github.com/btcsuite/winsvc v1.0.0 h1:J9B4L7e3oqhXOcm+2IuNApwzQec85lE+QaikUcCs+dk github.com/c2h5oh/datasize v0.0.0-20220606134207-859f65c6625b h1:6+ZFm0flnudZzdSE0JxlhR2hKnGPcNB35BjQf4RYQDY= github.com/c2h5oh/datasize v0.0.0-20220606134207-859f65c6625b/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M= github.com/casbin/casbin/v2 v2.37.0 h1:/poEwPSovi4bTOcP752/CsTQiRz2xycyVKFG7GUhbDw= +github.com/casbin/casbin/v2 v2.37.0/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg= github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ= +github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= github.com/checkpoint-restore/go-criu/v5 v5.0.0 h1:TW8f/UvntYoVDMN1K2HlT82qH1rb0sOjpGw3m6Ym+i4= github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927 h1:SKI1/fuSdodxmNNyVBR8d7X/HuLnRpvvFO0AgyQk764= @@ -658,6 +661,7 @@ github.com/cilium/ebpf v0.6.2 h1:iHsfF/t4aW4heW2YKfeHrVPGdtYTL4C4KocpM8KTSnI= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible h1:C29Ae4G5GtYyYMm1aztcyj/J5ckgJm2zwdDajFbx1NY= github.com/circonus-labs/circonusllhist v0.1.3 h1:TJH+oke8D16535+jHExHj4nQvzlZrj7ug5D7I/orNUA= github.com/clbanning/mxj v1.8.4 h1:HuhwZtbyvyOw+3Z1AowPkU87JkJUSv751ELWaiTpj8I= +github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec h1:EdRZT3IeKQmfCSrgo8SZ8V3MEnskuJP0wCYNpe+aiXo= github.com/cloudflare/cloudflare-go v0.114.0 h1:ucoti4/7Exo0XQ+rzpn1H+IfVVe++zgiM+tyKtf0HUA= github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe h1:QQ3GSy+MqSHxm/d8nCtnAiZdYFd45cYZPs8vOOIYKfk= @@ -758,12 +762,12 @@ github.com/go-redis/redis v6.15.8+incompatible h1:BKZuG6mCnRj5AOaWJXoCgf6rqTYnYJ github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-zookeeper/zk v1.0.2 h1:4mx0EYENAdX/B/rbunjlt5+4RTA/a9SMHBRuSKdGxPM= +github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= github.com/gogo/status v1.1.0 h1:+eIkrewn5q6b30y+g/BJINVVdi2xH7je5MPJ3ZPK3JA= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= -github.com/golang/mock v1.7.0-rc.1/go.mod h1:s42URUywIqd+OcERslBJvOjepvNymP31m3q8d/GkuRs= github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38 h1:y0Wmhvml7cGnzPa9nocn/fMraMH/lMDdeG+rkx4VgYY= github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/gonum/blas v0.0.0-20181208220705-f22b278b28ac h1:Q0Jsdxl5jbxouNs1TQYt0gxesYMU4VXRbsTlgDloZ50= @@ -836,6 +840,7 @@ github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/hudl/fargo v1.4.0 h1:ZDDILMbB37UlAVLlWcJ2Iz1XuahZZTDZfdCKeclfq2s= +github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo= github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/hydrogen18/memlistener v1.0.0 h1:JR7eDj8HD6eXrc5fWLbSUnfcQFL06PYvCc0DKQnWfaU= github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= @@ -948,6 +953,7 @@ github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517 h1:zpIH83+oKzcpryru8c github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/microcosm-cc/bluemonday v1.0.23 h1:SMZe2IGa0NuHvnVNAZ+6B38gsTbi5e4sViiWJyDDqFY= github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg= +github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/miekg/pkcs11 v1.0.3 h1:iMwmD7I5225wv84WxIG/bmxz9AXjWvTWIbM/TYHvWtw= github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94= github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= @@ -958,6 +964,7 @@ github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo github.com/mitchellh/cli v1.1.0 h1:tEElEatulEHDeedTxwckzyYMA5c86fbmNIUL1hBIiTg= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= +github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/gox v0.4.0 h1:lfGJxY7ToLJQjHHwi0EX6uYBdK78egf954SQl13PQJc= @@ -992,6 +999,7 @@ github.com/oklog/oklog v0.3.2 h1:wVfs8F+in6nTBMkA7CbRw+zZMIB7nNM825cM1wuzoTk= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid/v2 v2.0.2 h1:r4fFzBm+bv0wNKNh5eXTwU7i85y5x+uwkxCUTNVQqLc= +github.com/oklog/ulid/v2 v2.0.2/go.mod h1:mtBL0Qe/0HAx6/a4Z30qxVIAL1eQDweXq5lxOEiwQ68= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 h1:3snG66yBm59tKhhSPQrQ/0bCrv1LQbKt40LnUPiUxdc= github.com/opencontainers/selinux v1.8.2 h1:c4ca10UMgRcvZ6h0K4HtS15UaVSBEaE+iln2LVpAuGc= @@ -1001,6 +1009,7 @@ github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+ github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5 h1:ZCnq+JUrvXcDVhX/xRolRBZifmabN1HcS1wrPSvxhrU= github.com/openzipkin/zipkin-go v0.2.5 h1:UwtQQx2pyPIgWYHRg+epgdx1/HnBQTgN3/oIYEJTQzU= +github.com/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa4YDFlwRYAMyE= github.com/otiai10/curr v1.0.0 h1:TJIWdbX0B+kpNagQrjgq8bCMrbhiuX73M2XwgtDMoOI= github.com/otiai10/mint v1.3.1 h1:BCmzIS3n71sGfHB5NMNDB3lHYPz8fWSkCAErHed//qc= github.com/pact-foundation/pact-go v1.0.4 h1:OYkFijGHoZAYbOIb1LWXrwKQbMMRUv1oQ89blD2Mh2Q= @@ -1009,6 +1018,7 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhM github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= github.com/performancecopilot/speed v3.0.0+incompatible h1:2WnRzIquHa5QxaJKShDkLM+sc0JPuwhXzK8OYOyt3Vg= github.com/performancecopilot/speed/v4 v4.0.0 h1:VxEDCmdkfbQYDlcr/GC9YoN9PQ6p8ulk9xVsepYy9ZY= +github.com/performancecopilot/speed/v4 v4.0.0/go.mod h1:qxrSyuDGrTOWfV+uKRFhfxw6h/4HXRGUiZiufxo49BM= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQmzR3rNLYGGz4g/UgFcjb28p/viDM= github.com/phpdave11/gofpdf v1.4.2 h1:KPKiIbfwbvC/wOncwhrpRdXVj2CZTCFlw4wnoyjtHfQ= @@ -1078,8 +1088,11 @@ github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqn github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/go-dbus v0.0.0-20121104212943-b7232d34b1d5 h1:CvqZS4QYHBRvx7AeFdimd16HCbLlYsvQMcKDACpJW/c= +github.com/remyoudompheng/go-dbus v0.0.0-20121104212943-b7232d34b1d5/go.mod h1:+u151txRmLpwxBmpYn9z3d1sdJdjRPQpsXuYeY9jNls= github.com/remyoudompheng/go-liblzma v0.0.0-20190506200333-81bf2d431b96 h1:J8J/cgLDRuqXJnwIrRDBvtl+LLsdg7De74znW/BRRq4= +github.com/remyoudompheng/go-liblzma v0.0.0-20190506200333-81bf2d431b96/go.mod h1:90HvCY7+oHHUKkbeMCiHt1WuFR2/hPJ9QrljDG+v6ls= github.com/remyoudompheng/go-misc v0.0.0-20190427085024-2d6ac652a50e h1:eTWZyPUnHcuGRDiryS/l2I7FfKjbU3IBx3IjqHPxuKU= +github.com/remyoudompheng/go-misc v0.0.0-20190427085024-2d6ac652a50e/go.mod h1:80FQABjoFzZ2M5uEa6FUaJYEmqU2UOKojlFVak1UAwI= github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= @@ -1091,6 +1104,7 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f h1:UFr9zpz4xgTn github.com/ryanuber/columnize v2.1.0+incompatible h1:j1Wcmh8OrK4Q7GXY+V7SVSY8nUWQxHW5TkBe7YUl+2s= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sagikazarmark/crypt v0.6.0 h1:REOEXCs/NFY/1jOCEouMuT4zEniE5YoXbvpC5X/TLF8= +github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da h1:p3Vo3i64TCLY7gIfzeQaUJ+kppEO5WQG3cL8iE8tGHU= github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo= github.com/schollz/closestmatch v2.1.0+incompatible h1:Uel2GXEpJqOWBrlyI+oY9LTiyyjYS17cCYRqP13/SHk= @@ -1115,7 +1129,9 @@ github.com/sony/gobreaker v0.4.1 h1:oMnRNZXX5j85zso6xCPRNPtmAycat+WcoKbklScLDgQ= github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/streadway/amqp v1.0.0 h1:kuuDrUJFZL1QYL9hUNuCxNObNzB0bV/ZG5jV3RWAQgo= +github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20200128134331-0f66f006fb2e h1:mOtuXaRAbVZsxAHVdPR3IjfmN8T1h2iczJLynhLybf8= +github.com/streadway/handy v0.0.0-20200128134331-0f66f006fb2e/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI= github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502 h1:34icjjmqJ2HPjrSuJYEkdZ+0ItmGQAQ75cRHIiftIyE= @@ -1140,6 +1156,7 @@ github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQ github.com/valyala/histogram v1.2.0 h1:wyYGAZZt3CpwUiIb9AU/Zbllg1llXyrtApRS815OLoQ= github.com/valyala/histogram v1.2.0/go.mod h1:Hb4kBwb4UxsaNbbbh+RRz8ZR6pdodR57tzWUS3BUzXY= github.com/valyala/quicktemplate v1.7.0 h1:LUPTJmlVcb46OOUY3IeD9DojFpAVbsG+5WFTcjMJzCM= +github.com/valyala/quicktemplate v1.7.0/go.mod h1:sqKJnoaOF88V07vkO+9FL8fb9uZg/VPSJnLYn+LmLk8= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= github.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8 h1:EVObHAr8DqpoJCVv6KYTle8FEImKhtkfcZetNqxDoJQ= @@ -1172,9 +1189,13 @@ go.einride.tech/aip v0.68.0 h1:4seM66oLzTpz50u4K1zlJyOXQ3tCzcJN7I22tKkjipw= go.einride.tech/aip v0.68.0/go.mod h1:7y9FF8VtPWqpxuAxl0KQWqaULxW4zFIesD6zF5RIHHg= go.etcd.io/etcd v0.0.0-20200513171258-e048e166ab9c h1:/RwRVN9EdXAVtdHxP7Ndn/tfmM9/goiwU0QTnLBgS4w= go.etcd.io/etcd/api/v3 v3.5.4 h1:OHVyt3TopwtUQ2GKdd5wu3PmmipR4FTwCqoEjSyRdIc= +go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= go.etcd.io/etcd/client/pkg/v3 v3.5.4 h1:lrneYvz923dvC14R54XcA7FXoZ3mlGZAgmwhfm7HqOg= +go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.4 h1:Dcx3/MYyfKcPNLpR4VVQUP5KgYrBeJtktBwEKkw08Ao= +go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU= go.etcd.io/etcd/client/v3 v3.5.4 h1:p83BUL3tAYS0OT/r0qglgc3M1JjhM0diV8DSWAhVXv4= +go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= go.etcd.io/gofail v0.1.0 h1:XItAMIhOojXFQMgrxjnd2EIIHun/d5qL0Pf7FzVTkFg= go.mozilla.org/mozlog v0.0.0-20170222151521-4bb13139d403 h1:rKyWXYDfrVOpMFBion4Pmx5sJbQreQNXycHvm4KwJSg= go.opentelemetry.io/contrib/detectors/gcp v1.29.0 h1:TiaiXB4DpGD3sdzNlYQxruQngn5Apwzi1X0DRhuGvDQ= diff --git a/sei-tendermint/cmd/buf_plugin/main.go b/sei-tendermint/cmd/buf_plugin/main.go new file mode 100644 index 0000000000..46869cce19 --- /dev/null +++ b/sei-tendermint/cmd/buf_plugin/main.go @@ -0,0 +1,104 @@ +package main + +import ( + "fmt" + "iter" + + "google.golang.org/protobuf/compiler/protogen" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/types/descriptorpb" + "google.golang.org/protobuf/types/dynamicpb" +) + +type md struct { protoreflect.MessageDescriptor } +type mds = map[protoreflect.FullName]md + +func getExtType(p *protogen.Plugin, name protoreflect.FullName) (protoreflect.ExtensionType, bool) { + for _, file := range p.Files { + es := file.Desc.Extensions() + for i := range es.Len() { + if e := es.Get(i); e.FullName() == name { + return dynamicpb.NewExtensionType(e),true + } + } + } + return nil, false +} + +func (d md) walk(yield func(md) bool) bool { + if !yield(d) { return false } + descs := d.Messages() + for i := range descs.Len() { + if !(md{descs.Get(i)}).walk(yield) { + return false + } + } + return true +} + +func allMDs(plugin *protogen.Plugin) iter.Seq[md] { + return func(yield func(md) bool) { + for _, file := range plugin.Files { + descs := file.Desc.Messages() + for i := range descs.Len() { + if !(md{descs.Get(i)}).walk(yield) { + return + } + } + } + } +} + +func (d md) GetBoolOption(opt protoreflect.ExtensionType) bool { + options, ok := d.Options().(*descriptorpb.MessageOptions) + if !ok || !proto.HasExtension(options, opt) { + return false + } + has,ok := proto.GetExtension(options, opt).(bool) + return ok && has +} + +// run reads the proto descriptors and checks that the can_hash messages satisfy the following constraints: +// * all can_hash messages have to use proto3 syntax +// * message fields of can_hash messages have to be can_hash as well +// * fields of can_hash messages have to be repeated/optional (explicit presence) +// * fields of can_hash messages cannot be maps +func run(p *protogen.Plugin) error { + canHashName := protoreflect.FullName("tendermint.utils.can_hash") + canHashOpt,ok := getExtType(p,canHashName) + if !ok { + return fmt.Errorf("extension %q not found",canHashName) + } + descs := mds{} + for d := range allMDs(p) { + if d.GetBoolOption(canHashOpt) { + descs[d.FullName()] = d + } + } + for _,d := range descs { + if d.Syntax()!=protoreflect.Proto3 { + return fmt.Errorf("%q: can_hash messages have to be in proto3 syntax",d.FullName()) + } + fields := d.Fields() + for i := 0; i < fields.Len(); i++ { + f := fields.Get(i) + if f.IsMap() { + return fmt.Errorf("%q: maps are not allowed in can_hash messages",f.FullName()) + } + if !f.IsList() && !f.HasPresence() { + return fmt.Errorf("%q: all fields of can_hash messages should be optional or repeated",f.FullName()) + } + if f.Kind() == protoreflect.MessageKind { + if _,ok := descs[f.Message().FullName()]; !ok { + return fmt.Errorf("%q: message fields of can_hash messages have to be can_hash",f.FullName()) + } + } + } + } + return nil +} + +func main() { + protogen.Options{}.Run(run) +} diff --git a/sei-tendermint/proto/tendermint/utils.proto b/sei-tendermint/proto/tendermint/utils.proto new file mode 100644 index 0000000000..451f609eb7 --- /dev/null +++ b/sei-tendermint/proto/tendermint/utils.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package tendermint.utils; + +import "google/protobuf/descriptor.proto"; + +option go_package = "github.com/tendermint/tendermint/proto/tendermint/utils"; + +// can_hash marks messages whose fields participate in the custom hashing logic +// enforced by the Sei buf plugin. When set to true, every message-typed field +// (recursively) must also opt in. +extend google.protobuf.MessageOptions { + bool can_hash = 51001; +} From 9e34cae7fcee8d8a19fab9aa5f031424f54748c4 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Wed, 10 Dec 2025 18:51:09 +0100 Subject: [PATCH 02/53] plugin has been placed --- buf.gen.yaml | 15 +++++++-------- sei-tendermint/cmd/buf_plugin/main.go | 5 ++++- sei-tendermint/proto/tendermint/utils.proto | 5 ++--- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/buf.gen.yaml b/buf.gen.yaml index 275dbdc31b..e94d6af339 100644 --- a/buf.gen.yaml +++ b/buf.gen.yaml @@ -6,6 +6,13 @@ inputs: - directory: sei-tendermint/proto - directory: sei-wasmd/proto plugins: + - local: + - go + - run + - ./sei-tendermint/cmd/buf_plugin + opt: + - Mgoogle/protobuf/any.proto=github.com/cosmos/cosmos-sdk/codec/types + out: ./build/proto/validation - local: - ./build/proto/gocosmos/protoc-gen-gocosmos opt: @@ -42,11 +49,3 @@ plugins: - Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types - Mgoogle/protobuf/duration.proto=github.com/golang/protobuf/ptypes/duration - plugins=grpc - - local: - - go - - run - - ./cmd/protoc-gen-seiplugin - out: ./build/proto/sei-plugin - opt: - - annotation=sei.custom.plugin - - fail_on_deprecated=false diff --git a/sei-tendermint/cmd/buf_plugin/main.go b/sei-tendermint/cmd/buf_plugin/main.go index 46869cce19..0ed3866434 100644 --- a/sei-tendermint/cmd/buf_plugin/main.go +++ b/sei-tendermint/cmd/buf_plugin/main.go @@ -3,6 +3,7 @@ package main import ( "fmt" "iter" + "log" "google.golang.org/protobuf/compiler/protogen" "google.golang.org/protobuf/proto" @@ -68,7 +69,8 @@ func run(p *protogen.Plugin) error { canHashName := protoreflect.FullName("tendermint.utils.can_hash") canHashOpt,ok := getExtType(p,canHashName) if !ok { - return fmt.Errorf("extension %q not found",canHashName) + // When the module being processed does not declare the extension we have nothing to validate. + return nil } descs := mds{} for d := range allMDs(p) { @@ -76,6 +78,7 @@ func run(p *protogen.Plugin) error { descs[d.FullName()] = d } } + log.Printf("buf_plugin: found can_hash option; %d message type(s) marked with it", len(descs)) for _,d := range descs { if d.Syntax()!=protoreflect.Proto3 { return fmt.Errorf("%q: can_hash messages have to be in proto3 syntax",d.FullName()) diff --git a/sei-tendermint/proto/tendermint/utils.proto b/sei-tendermint/proto/tendermint/utils.proto index 451f609eb7..3798f035d3 100644 --- a/sei-tendermint/proto/tendermint/utils.proto +++ b/sei-tendermint/proto/tendermint/utils.proto @@ -6,9 +6,8 @@ import "google/protobuf/descriptor.proto"; option go_package = "github.com/tendermint/tendermint/proto/tendermint/utils"; -// can_hash marks messages whose fields participate in the custom hashing logic -// enforced by the Sei buf plugin. When set to true, every message-typed field -// (recursively) must also opt in. +// can_hash marks messages which support canonical protobuf serialization and therefore +// are suitable for hashing. extend google.protobuf.MessageOptions { bool can_hash = 51001; } From e4ecde628b4e9f5c1051bce9533fb3d35cede520 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Thu, 11 Dec 2025 10:12:42 +0100 Subject: [PATCH 03/53] fmt --- sei-tendermint/cmd/buf_plugin/main.go | 30 ++++++++++++++------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/sei-tendermint/cmd/buf_plugin/main.go b/sei-tendermint/cmd/buf_plugin/main.go index 0ed3866434..2e20575748 100644 --- a/sei-tendermint/cmd/buf_plugin/main.go +++ b/sei-tendermint/cmd/buf_plugin/main.go @@ -12,7 +12,7 @@ import ( "google.golang.org/protobuf/types/dynamicpb" ) -type md struct { protoreflect.MessageDescriptor } +type md struct{ protoreflect.MessageDescriptor } type mds = map[protoreflect.FullName]md func getExtType(p *protogen.Plugin, name protoreflect.FullName) (protoreflect.ExtensionType, bool) { @@ -20,15 +20,17 @@ func getExtType(p *protogen.Plugin, name protoreflect.FullName) (protoreflect.Ex es := file.Desc.Extensions() for i := range es.Len() { if e := es.Get(i); e.FullName() == name { - return dynamicpb.NewExtensionType(e),true + return dynamicpb.NewExtensionType(e), true } - } + } } return nil, false } func (d md) walk(yield func(md) bool) bool { - if !yield(d) { return false } + if !yield(d) { + return false + } descs := d.Messages() for i := range descs.Len() { if !(md{descs.Get(i)}).walk(yield) { @@ -47,7 +49,7 @@ func allMDs(plugin *protogen.Plugin) iter.Seq[md] { return } } - } + } } } @@ -56,7 +58,7 @@ func (d md) GetBoolOption(opt protoreflect.ExtensionType) bool { if !ok || !proto.HasExtension(options, opt) { return false } - has,ok := proto.GetExtension(options, opt).(bool) + has, ok := proto.GetExtension(options, opt).(bool) return ok && has } @@ -67,7 +69,7 @@ func (d md) GetBoolOption(opt protoreflect.ExtensionType) bool { // * fields of can_hash messages cannot be maps func run(p *protogen.Plugin) error { canHashName := protoreflect.FullName("tendermint.utils.can_hash") - canHashOpt,ok := getExtType(p,canHashName) + canHashOpt, ok := getExtType(p, canHashName) if !ok { // When the module being processed does not declare the extension we have nothing to validate. return nil @@ -79,22 +81,22 @@ func run(p *protogen.Plugin) error { } } log.Printf("buf_plugin: found can_hash option; %d message type(s) marked with it", len(descs)) - for _,d := range descs { - if d.Syntax()!=protoreflect.Proto3 { - return fmt.Errorf("%q: can_hash messages have to be in proto3 syntax",d.FullName()) + for _, d := range descs { + if d.Syntax() != protoreflect.Proto3 { + return fmt.Errorf("%q: can_hash messages have to be in proto3 syntax", d.FullName()) } fields := d.Fields() for i := 0; i < fields.Len(); i++ { f := fields.Get(i) if f.IsMap() { - return fmt.Errorf("%q: maps are not allowed in can_hash messages",f.FullName()) + return fmt.Errorf("%q: maps are not allowed in can_hash messages", f.FullName()) } if !f.IsList() && !f.HasPresence() { - return fmt.Errorf("%q: all fields of can_hash messages should be optional or repeated",f.FullName()) + return fmt.Errorf("%q: all fields of can_hash messages should be optional or repeated", f.FullName()) } if f.Kind() == protoreflect.MessageKind { - if _,ok := descs[f.Message().FullName()]; !ok { - return fmt.Errorf("%q: message fields of can_hash messages have to be can_hash",f.FullName()) + if _, ok := descs[f.Message().FullName()]; !ok { + return fmt.Errorf("%q: message fields of can_hash messages have to be can_hash", f.FullName()) } } } From 29364aafbc5446a099435f66bcfb62967f072982 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Thu, 11 Dec 2025 18:47:14 +0100 Subject: [PATCH 04/53] WIP --- buf.gen.yaml | 1 + buf.yaml | 1 - sei-cosmos/x/staking/types/staking.pb.go | 1546 +++++++++-------- sei-tendermint/cmd/buf_plugin/main.go | 85 +- sei-tendermint/proto/hashable.proto | 14 + .../proto/tendermint/consensus/types.pb.go | 112 +- .../proto/tendermint/consensus/types.proto | 2 + .../proto/tendermint/types/types.pb.go | 1294 ++++++++++---- .../proto/tendermint/types/types.proto | 37 +- sei-tendermint/proto/tendermint/utils.proto | 13 - 10 files changed, 1865 insertions(+), 1240 deletions(-) create mode 100644 sei-tendermint/proto/hashable.proto delete mode 100644 sei-tendermint/proto/tendermint/utils.proto diff --git a/buf.gen.yaml b/buf.gen.yaml index e94d6af339..ae63227624 100644 --- a/buf.gen.yaml +++ b/buf.gen.yaml @@ -10,6 +10,7 @@ plugins: - go - run - ./sei-tendermint/cmd/buf_plugin + strategy: all opt: - Mgoogle/protobuf/any.proto=github.com/cosmos/cosmos-sdk/codec/types out: ./build/proto/validation diff --git a/buf.yaml b/buf.yaml index 31cb3d07db..c15a632022 100644 --- a/buf.yaml +++ b/buf.yaml @@ -29,4 +29,3 @@ breaking: use: - WIRE - WIRE_JSON - \ No newline at end of file diff --git a/sei-cosmos/x/staking/types/staking.pb.go b/sei-cosmos/x/staking/types/staking.pb.go index 49103fb7e4..fcda29b9d3 100644 --- a/sei-cosmos/x/staking/types/staking.pb.go +++ b/sei-cosmos/x/staking/types/staking.pb.go @@ -1273,776 +1273,790 @@ func (this *Pool) Description() (desc *github_com_gogo_protobuf_protoc_gen_gogo_ func StakingDescription() (desc *github_com_gogo_protobuf_protoc_gen_gogo_descriptor.FileDescriptorSet) { d := &github_com_gogo_protobuf_protoc_gen_gogo_descriptor.FileDescriptorSet{} var gzipped = []byte{ - // 12299 bytes of a gzipped FileDescriptorSet - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x7d, 0x94, 0x1b, 0xd7, - 0x75, 0x18, 0xbe, 0x83, 0x6f, 0xdc, 0xfd, 0x9a, 0x7d, 0xbb, 0x24, 0x41, 0x90, 0xdc, 0x5d, 0x8d, - 0x24, 0x8a, 0xa2, 0xc4, 0xa5, 0x48, 0x89, 0x14, 0xb9, 0x72, 0xac, 0x00, 0x0b, 0x70, 0x09, 0x6a, - 0xbf, 0x3c, 0xc0, 0x52, 0x92, 0xe3, 0xfc, 0xe6, 0xcc, 0x02, 0x6f, 0xb1, 0x23, 0x02, 0x33, 0x30, - 0x66, 0x40, 0x71, 0xe5, 0x24, 0x47, 0x76, 0xfc, 0xf3, 0x4f, 0x96, 0x7f, 0xfe, 0xc5, 0xfe, 0x39, - 0x27, 0x91, 0x9d, 0xd0, 0x91, 0xed, 0x34, 0x4e, 0x1d, 0xa7, 0x71, 0x12, 0x37, 0x6d, 0xda, 0x9e, - 0x93, 0xa4, 0xe7, 0xa4, 0x49, 0xdc, 0xa4, 0xc7, 0x6e, 0xd3, 0x36, 0xcd, 0x49, 0xe9, 0x56, 0xf1, - 0x89, 0x65, 0xc7, 0x6d, 0x1c, 0xc5, 0x6d, 0xd3, 0xe3, 0xa6, 0xee, 0x79, 0x5f, 0xf3, 0x05, 0x60, - 0x81, 0xa5, 0x28, 0x47, 0x69, 0xfa, 0x0f, 0xb9, 0xef, 0xbe, 0x7b, 0xef, 0xbb, 0xef, 0xbe, 0x7b, - 0xef, 0xbb, 0xef, 0x6b, 0x00, 0x7f, 0x65, 0xc0, 0x7c, 0xdd, 0xb2, 0xea, 0x0d, 0x7c, 0xba, 0xd5, - 0xb6, 0x1c, 0x6b, 0xab, 0xb3, 0x7d, 0xba, 0x86, 0xed, 0x6a, 0xdb, 0x68, 0x39, 0x56, 0x7b, 0x81, - 0xc2, 0xd0, 0x24, 0xc3, 0x58, 0x10, 0x18, 0xca, 0x17, 0x24, 0x98, 0xba, 0x64, 0x34, 0x70, 0xc1, - 0xc5, 0x2c, 0x63, 0x07, 0x5d, 0x80, 0xd8, 0xb6, 0xd1, 0xc0, 0x19, 0x69, 0x3e, 0x7a, 0x62, 0xf4, - 0xec, 0x3d, 0x0b, 0x21, 0xaa, 0x85, 0x20, 0xc5, 0x06, 0x01, 0xab, 0x94, 0xe2, 0xe4, 0xbb, 0x52, - 0xcf, 0x7f, 0xe3, 0x0b, 0xdf, 0x91, 0xe4, 0x77, 0x93, 0x7f, 0xb3, 0x4d, 0x74, 0x8d, 0x95, 0xd1, - 0x23, 0x0b, 0x84, 0xce, 0x27, 0xcf, 0xf5, 0x33, 0x04, 0xa2, 0x11, 0x22, 0xcd, 0x03, 0x6b, 0x36, - 0x76, 0x34, 0x7c, 0xc3, 0xc1, 0xa6, 0x6d, 0x58, 0x66, 0xf6, 0x54, 0x0f, 0xaa, 0x2e, 0x69, 0x8b, - 0x02, 0x5d, 0xf9, 0xcd, 0x38, 0x4c, 0xf7, 0x10, 0x0d, 0x21, 0x88, 0x99, 0x7a, 0x93, 0x74, 0x47, - 0x3a, 0x91, 0x56, 0xe9, 0xdf, 0x28, 0x03, 0xc9, 0x96, 0x5e, 0xbd, 0xa6, 0xd7, 0x71, 0x26, 0x42, - 0xc1, 0xa2, 0x88, 0x66, 0x01, 0x6a, 0xb8, 0x85, 0xcd, 0x1a, 0x36, 0xab, 0xbb, 0x99, 0xe8, 0x7c, - 0xf4, 0x44, 0x5a, 0xf5, 0x41, 0xd0, 0x03, 0x30, 0xd5, 0xea, 0x6c, 0x35, 0x8c, 0xaa, 0xe6, 0x43, - 0x83, 0xf9, 0xe8, 0x89, 0xb8, 0x2a, 0xb3, 0x8a, 0x82, 0x87, 0x7c, 0x1f, 0x4c, 0x3e, 0x8b, 0xf5, - 0x6b, 0x7e, 0xd4, 0x51, 0x8a, 0x3a, 0x41, 0xc0, 0x85, 0x00, 0x57, 0xab, 0xe5, 0x18, 0x96, 0xe9, - 0x47, 0x9d, 0xa4, 0x8d, 0xcb, 0xac, 0xc2, 0x87, 0xbc, 0x04, 0x63, 0x4d, 0x6c, 0xdb, 0x7a, 0x1d, - 0x6b, 0xce, 0x6e, 0x0b, 0x67, 0x62, 0x74, 0x9c, 0xe6, 0xbb, 0xc6, 0x29, 0x3c, 0x46, 0xa3, 0x9c, - 0xaa, 0xb2, 0xdb, 0xc2, 0x28, 0x07, 0x69, 0x6c, 0x76, 0x9a, 0x8c, 0x43, 0xbc, 0xcf, 0x48, 0x17, - 0xcd, 0x4e, 0x33, 0xcc, 0x25, 0x45, 0xc8, 0x38, 0x8b, 0xa4, 0x8d, 0xdb, 0xd7, 0x8d, 0x2a, 0xce, - 0x24, 0x28, 0x83, 0xfb, 0xba, 0x18, 0x94, 0x59, 0x7d, 0x98, 0x87, 0xa0, 0x43, 0x4b, 0x90, 0x76, - 0xc7, 0x3b, 0x93, 0xa4, 0x4c, 0xee, 0xed, 0x61, 0x6f, 0xb8, 0x51, 0x0b, 0xb3, 0xf0, 0xe8, 0xd0, - 0x79, 0x48, 0x32, 0x1d, 0xd9, 0x99, 0xd4, 0xbc, 0x74, 0x62, 0xf4, 0xec, 0xd1, 0x9e, 0x26, 0xbb, - 0xce, 0x70, 0x54, 0x81, 0x8c, 0x4a, 0x20, 0xdb, 0x56, 0xa7, 0x5d, 0xc5, 0x5a, 0xd5, 0xaa, 0x61, - 0xcd, 0x30, 0xb7, 0xad, 0x4c, 0x9a, 0x32, 0x98, 0xeb, 0xee, 0x08, 0x45, 0x5c, 0xb2, 0x6a, 0xb8, - 0x64, 0x6e, 0x5b, 0xea, 0x84, 0x1d, 0x28, 0xa3, 0x83, 0x90, 0xb0, 0x77, 0x4d, 0x47, 0xbf, 0x91, - 0x19, 0xa3, 0xe6, 0xc4, 0x4b, 0xe8, 0x2c, 0x24, 0x71, 0xcd, 0x20, 0xcd, 0x65, 0x26, 0xe6, 0xa5, - 0x13, 0x13, 0x67, 0x33, 0xdd, 0x3a, 0x66, 0xf5, 0xaa, 0x40, 0x54, 0xfe, 0x47, 0x02, 0x26, 0x87, - 0xb1, 0xe1, 0xc7, 0x20, 0xbe, 0x4d, 0x34, 0x93, 0x89, 0xec, 0x47, 0x6f, 0x8c, 0x26, 0xa8, 0xf8, - 0xc4, 0x6d, 0x2a, 0x3e, 0x07, 0xa3, 0x26, 0xb6, 0x1d, 0x5c, 0x63, 0x56, 0x14, 0x1d, 0xd2, 0x0e, - 0x81, 0x11, 0x75, 0x9b, 0x61, 0xec, 0xb6, 0xcc, 0xf0, 0x29, 0x98, 0x74, 0x45, 0xd2, 0xda, 0xba, - 0x59, 0x17, 0xf6, 0x7c, 0x7a, 0x90, 0x24, 0x0b, 0x6e, 0xf0, 0x50, 0x09, 0x99, 0x3a, 0x81, 0x03, - 0x65, 0x54, 0x00, 0xb0, 0x4c, 0x6c, 0x6d, 0x6b, 0x35, 0x5c, 0x6d, 0x64, 0x52, 0x7d, 0xb4, 0xb4, - 0x4e, 0x50, 0xba, 0xb4, 0x64, 0x31, 0x68, 0xb5, 0x81, 0x2e, 0x7a, 0xe6, 0x99, 0xec, 0x63, 0x5d, - 0xab, 0xcc, 0x31, 0xbb, 0x2c, 0x74, 0x13, 0x26, 0xda, 0x98, 0xf8, 0x0a, 0xae, 0xf1, 0x9e, 0xa5, - 0xa9, 0x10, 0x0b, 0x03, 0x7b, 0xa6, 0x72, 0x32, 0xd6, 0xb1, 0xf1, 0xb6, 0xbf, 0x88, 0xee, 0x06, - 0x17, 0xa0, 0x51, 0xb3, 0x02, 0x1a, 0x69, 0xc6, 0x04, 0x70, 0x8d, 0x98, 0x57, 0x0e, 0xe0, 0xba, - 0x61, 0x1b, 0x5b, 0x46, 0xc3, 0x70, 0x48, 0xd8, 0x22, 0xd6, 0x7b, 0x57, 0xb7, 0x5f, 0xec, 0x36, - 0xb7, 0xac, 0xc6, 0x55, 0x17, 0x51, 0xf5, 0x11, 0x65, 0x9f, 0x83, 0x89, 0xa0, 0x86, 0xd1, 0x0c, - 0xc4, 0x6d, 0x47, 0x6f, 0x3b, 0xd4, 0x90, 0xe3, 0x2a, 0x2b, 0x20, 0x19, 0xa2, 0xd8, 0xac, 0xd1, - 0x48, 0x1c, 0x57, 0xc9, 0x9f, 0xe8, 0x7b, 0x3d, 0x9d, 0x45, 0xa9, 0xce, 0x8e, 0x77, 0x1b, 0x45, - 0x80, 0x73, 0x58, 0x75, 0xd9, 0x47, 0x61, 0x3c, 0xa0, 0x83, 0x61, 0x9b, 0x56, 0x7e, 0x37, 0x06, - 0x07, 0x7a, 0xf2, 0x46, 0x4f, 0xc1, 0x4c, 0xc7, 0x34, 0x4c, 0x07, 0xb7, 0x5b, 0x6d, 0x4c, 0xac, - 0x9e, 0xb5, 0x95, 0xf9, 0x6a, 0xb2, 0x8f, 0xdd, 0x6e, 0xfa, 0xb1, 0x19, 0x17, 0x75, 0xba, 0xd3, - 0x0d, 0x44, 0x4f, 0xc3, 0x28, 0x31, 0x31, 0xbd, 0xad, 0x53, 0x86, 0xcc, 0xa1, 0xcf, 0x0e, 0xd7, - 0xe5, 0x85, 0x82, 0x47, 0x99, 0x8f, 0xbe, 0x20, 0x45, 0x54, 0x3f, 0x2f, 0xf4, 0x28, 0xa4, 0xb6, - 0xb1, 0xee, 0x74, 0xda, 0xd8, 0xce, 0x9c, 0xa5, 0xaa, 0x3c, 0xd2, 0xed, 0xe7, 0x0c, 0xa1, 0x8c, - 0x1d, 0xd5, 0x45, 0x46, 0x4d, 0x18, 0xbb, 0x8e, 0xdb, 0xc6, 0xb6, 0x51, 0x65, 0x42, 0x45, 0xa9, - 0x05, 0x5c, 0x18, 0x52, 0xa8, 0xab, 0x3e, 0xd2, 0xb2, 0xa3, 0x3b, 0x78, 0x11, 0x36, 0xd7, 0xae, - 0x16, 0xd5, 0xd2, 0xa5, 0x52, 0xb1, 0xc0, 0xc4, 0x0c, 0xb0, 0xcf, 0xfe, 0xa8, 0x04, 0xa3, 0xbe, - 0x9e, 0x90, 0x88, 0x6a, 0x76, 0x9a, 0x5b, 0xb8, 0xcd, 0xc7, 0x8b, 0x97, 0xd0, 0x11, 0x48, 0x6f, - 0x77, 0x1a, 0x0d, 0x66, 0xb7, 0x6c, 0xee, 0x4e, 0x11, 0x00, 0xb5, 0x59, 0x04, 0x31, 0x1e, 0x89, - 0x68, 0x98, 0x24, 0x7f, 0xa3, 0x2c, 0xa4, 0x84, 0x5d, 0x67, 0xe2, 0xf3, 0xd2, 0x89, 0x94, 0xea, - 0x96, 0x59, 0x5d, 0x0b, 0xeb, 0x0e, 0xae, 0x65, 0x12, 0xa2, 0x8e, 0x95, 0xaf, 0xc4, 0x52, 0x31, - 0x39, 0xae, 0x3c, 0x02, 0x53, 0x5d, 0x5d, 0x41, 0x93, 0x30, 0x5a, 0x28, 0x2e, 0xad, 0xe4, 0xd4, - 0x5c, 0xa5, 0xb4, 0xbe, 0x26, 0x8f, 0xa0, 0x09, 0xf0, 0xf5, 0x4e, 0x96, 0x4e, 0xa6, 0x53, 0xaf, - 0x26, 0xe5, 0xe7, 0x9f, 0x7f, 0xfe, 0xf9, 0x88, 0xf2, 0x1b, 0x09, 0x98, 0xe9, 0x15, 0x47, 0x7b, - 0x86, 0x74, 0xaf, 0xd3, 0xd1, 0x40, 0xa7, 0x73, 0x10, 0x6f, 0xe8, 0x5b, 0xb8, 0x91, 0x89, 0xd1, - 0x41, 0x78, 0x60, 0xa8, 0x48, 0xbd, 0xb0, 0x42, 0x48, 0x54, 0x46, 0x89, 0xde, 0xca, 0x55, 0x13, - 0xa7, 0x1c, 0x4e, 0x0e, 0xc7, 0x81, 0xc4, 0x57, 0xae, 0xc6, 0x23, 0x90, 0x26, 0xff, 0x33, 0xbd, - 0x27, 0x98, 0xde, 0x09, 0x80, 0xea, 0x3d, 0x0b, 0x29, 0x1a, 0x3a, 0x6b, 0xd8, 0x1d, 0x13, 0x51, - 0x26, 0xc1, 0xa6, 0x86, 0xb7, 0xf5, 0x4e, 0xc3, 0xd1, 0xae, 0xeb, 0x8d, 0x0e, 0xa6, 0x41, 0x30, - 0xad, 0x8e, 0x71, 0xe0, 0x55, 0x02, 0x43, 0x73, 0x30, 0xca, 0x22, 0xad, 0x61, 0xd6, 0xf0, 0x0d, - 0x3a, 0x0b, 0xc7, 0x55, 0x16, 0x7c, 0x4b, 0x04, 0x42, 0x9a, 0x7f, 0xc6, 0xb6, 0x4c, 0x11, 0xae, - 0x68, 0x13, 0x04, 0x40, 0x9b, 0x7f, 0x34, 0x9c, 0x00, 0x1c, 0xeb, 0xdd, 0xbd, 0xae, 0xf8, 0x7a, - 0x1f, 0x4c, 0x52, 0x8c, 0x87, 0xb9, 0x2b, 0xeb, 0x8d, 0xcc, 0x14, 0x35, 0x83, 0x09, 0x06, 0x5e, - 0xe7, 0x50, 0xe5, 0x57, 0x22, 0x10, 0xa3, 0x93, 0xcd, 0x24, 0x8c, 0x56, 0x9e, 0xde, 0x28, 0x6a, - 0x85, 0xf5, 0xcd, 0xfc, 0x4a, 0x51, 0x96, 0xc8, 0xd0, 0x53, 0xc0, 0xa5, 0x95, 0xf5, 0x5c, 0x45, - 0x8e, 0xb8, 0xe5, 0xd2, 0x5a, 0xe5, 0xfc, 0x23, 0x72, 0xd4, 0x25, 0xd8, 0x64, 0x80, 0x98, 0x1f, - 0xe1, 0xe1, 0xb3, 0x72, 0x1c, 0xc9, 0x30, 0xc6, 0x18, 0x94, 0x9e, 0x2a, 0x16, 0xce, 0x3f, 0x22, - 0x27, 0x82, 0x90, 0x87, 0xcf, 0xca, 0x49, 0x34, 0x0e, 0x69, 0x0a, 0xc9, 0xaf, 0xaf, 0xaf, 0xc8, - 0x29, 0x97, 0x67, 0xb9, 0xa2, 0x96, 0xd6, 0x96, 0xe5, 0xb4, 0xcb, 0x73, 0x59, 0x5d, 0xdf, 0xdc, - 0x90, 0xc1, 0xe5, 0xb0, 0x5a, 0x2c, 0x97, 0x73, 0xcb, 0x45, 0x79, 0xd4, 0xc5, 0xc8, 0x3f, 0x5d, - 0x29, 0x96, 0xe5, 0xb1, 0x80, 0x58, 0x0f, 0x9f, 0x95, 0xc7, 0xdd, 0x26, 0x8a, 0x6b, 0x9b, 0xab, - 0xf2, 0x04, 0x9a, 0x82, 0x71, 0xd6, 0x84, 0x10, 0x62, 0x32, 0x04, 0x3a, 0xff, 0x88, 0x2c, 0x7b, - 0x82, 0x30, 0x2e, 0x53, 0x01, 0xc0, 0xf9, 0x47, 0x64, 0xa4, 0x2c, 0x41, 0x9c, 0x9a, 0x21, 0x42, - 0x30, 0xb1, 0x92, 0xcb, 0x17, 0x57, 0xb4, 0xf5, 0x0d, 0xe2, 0x34, 0xb9, 0x15, 0x59, 0xf2, 0x60, - 0x6a, 0x71, 0xa3, 0x98, 0xab, 0x14, 0x0b, 0x72, 0xd4, 0x0f, 0x7b, 0xdb, 0x66, 0x49, 0x2d, 0x16, - 0xe4, 0x88, 0x52, 0x85, 0x99, 0x5e, 0x93, 0x6c, 0x4f, 0x17, 0xf2, 0xd9, 0x42, 0xa4, 0x8f, 0x2d, - 0x50, 0x5e, 0x61, 0x5b, 0x50, 0x7e, 0x26, 0x0a, 0xd3, 0x3d, 0x12, 0x8d, 0x9e, 0x8d, 0x3c, 0x0e, - 0x71, 0x66, 0xcb, 0x2c, 0x52, 0xdf, 0xdf, 0x33, 0x63, 0xa1, 0x96, 0xdd, 0x95, 0x7e, 0x51, 0x3a, - 0x7f, 0xca, 0x1a, 0xed, 0x93, 0xb2, 0x12, 0x16, 0x5d, 0x06, 0xfb, 0xfd, 0x5d, 0x09, 0x01, 0xcb, - 0x99, 0xce, 0x0f, 0x93, 0x33, 0x51, 0xd8, 0xfe, 0x12, 0x83, 0xf8, 0xc0, 0xc4, 0x20, 0x71, 0x3b, - 0x89, 0xc1, 0x63, 0x30, 0xd5, 0x25, 0xcb, 0xd0, 0x13, 0xf4, 0x0f, 0x4b, 0x90, 0xe9, 0xa7, 0xdf, - 0x01, 0x51, 0x35, 0x12, 0x88, 0xaa, 0x8f, 0x85, 0x07, 0xe1, 0xae, 0xfe, 0xe3, 0xd8, 0x65, 0x2e, - 0x9f, 0x96, 0xe0, 0x60, 0xef, 0xd5, 0x4d, 0x4f, 0x19, 0xde, 0x0a, 0x89, 0x26, 0x76, 0x76, 0x2c, - 0x91, 0xad, 0x1f, 0xef, 0x91, 0x03, 0x92, 0xea, 0xb0, 0xbd, 0x70, 0x2a, 0x7f, 0x12, 0x19, 0xed, - 0xb7, 0x44, 0x61, 0xd2, 0x74, 0x49, 0xfa, 0xfe, 0x08, 0x1c, 0xe8, 0xc9, 0xbc, 0xa7, 0xa0, 0xc7, - 0x00, 0x0c, 0xb3, 0xd5, 0x71, 0x58, 0x46, 0xce, 0x82, 0x79, 0x9a, 0x42, 0x68, 0xfc, 0x23, 0x81, - 0xba, 0xe3, 0xb8, 0xf5, 0x6c, 0xa2, 0x05, 0x06, 0xa2, 0x08, 0x17, 0x3c, 0x41, 0x63, 0x54, 0xd0, - 0xd9, 0x3e, 0x3d, 0xed, 0xb2, 0xed, 0x87, 0x40, 0xae, 0x36, 0x0c, 0x6c, 0x3a, 0x9a, 0xed, 0xb4, - 0xb1, 0xde, 0x34, 0xcc, 0x3a, 0x9b, 0xb0, 0x17, 0xe3, 0xdb, 0x7a, 0xc3, 0xc6, 0xea, 0x24, 0xab, - 0x2e, 0x8b, 0x5a, 0x42, 0x41, 0x0d, 0xa8, 0xed, 0xa3, 0x48, 0x04, 0x28, 0x58, 0xb5, 0x4b, 0xa1, - 0xfc, 0x7c, 0x1a, 0x46, 0x7d, 0x6b, 0x41, 0x74, 0x17, 0x8c, 0x3d, 0xa3, 0x5f, 0xd7, 0x35, 0xb1, - 0x19, 0xc0, 0x34, 0x31, 0x4a, 0x60, 0x1b, 0x7c, 0x43, 0xe0, 0x21, 0x98, 0xa1, 0x28, 0x56, 0xc7, - 0xc1, 0x6d, 0xad, 0xda, 0xd0, 0x6d, 0x9b, 0x2a, 0x2d, 0x45, 0x51, 0x11, 0xa9, 0x5b, 0x27, 0x55, - 0x4b, 0xa2, 0x06, 0x9d, 0x83, 0x69, 0x4a, 0xd1, 0xec, 0x34, 0x1c, 0xa3, 0xd5, 0xc0, 0x74, 0x9b, - 0xc3, 0xa6, 0xb3, 0x96, 0x2b, 0xd9, 0x14, 0xc1, 0x58, 0xe5, 0x08, 0x44, 0x22, 0x1b, 0x15, 0xe0, - 0x18, 0x25, 0xab, 0x63, 0x13, 0xb7, 0x75, 0x07, 0x6b, 0xf8, 0x9d, 0x1d, 0xbd, 0x61, 0x6b, 0xba, - 0x59, 0xd3, 0x76, 0x74, 0x7b, 0x27, 0x33, 0x43, 0x18, 0xe4, 0x23, 0x19, 0x49, 0x3d, 0x4c, 0x10, - 0x97, 0x39, 0x5e, 0x91, 0xa2, 0xe5, 0xcc, 0xda, 0x65, 0xdd, 0xde, 0x41, 0x8b, 0x70, 0x90, 0x72, - 0xb1, 0x9d, 0xb6, 0x61, 0xd6, 0xb5, 0xea, 0x0e, 0xae, 0x5e, 0xd3, 0x3a, 0xce, 0xf6, 0x85, 0xcc, - 0x11, 0x7f, 0xfb, 0x54, 0xc2, 0x32, 0xc5, 0x59, 0x22, 0x28, 0x9b, 0xce, 0xf6, 0x05, 0x54, 0x86, - 0x31, 0x32, 0x18, 0x4d, 0xe3, 0x39, 0xac, 0x6d, 0x5b, 0x6d, 0x3a, 0x0d, 0x4f, 0xf4, 0x88, 0x6e, - 0x3e, 0x0d, 0x2e, 0xac, 0x73, 0x82, 0x55, 0xab, 0x86, 0x17, 0xe3, 0xe5, 0x8d, 0x62, 0xb1, 0xa0, - 0x8e, 0x0a, 0x2e, 0x97, 0xac, 0x36, 0x31, 0xa8, 0xba, 0xe5, 0x2a, 0x78, 0x94, 0x19, 0x54, 0xdd, - 0x12, 0xea, 0x3d, 0x07, 0xd3, 0xd5, 0x2a, 0xeb, 0xb3, 0x51, 0xd5, 0xf8, 0xbe, 0x80, 0x9d, 0x91, - 0x03, 0xca, 0xaa, 0x56, 0x97, 0x19, 0x02, 0xb7, 0x71, 0x1b, 0x5d, 0x84, 0x03, 0x9e, 0xb2, 0xfc, - 0x84, 0x53, 0x5d, 0xbd, 0x0c, 0x93, 0x9e, 0x83, 0xe9, 0xd6, 0x6e, 0x37, 0x21, 0x0a, 0xb4, 0xd8, - 0xda, 0x0d, 0x93, 0xdd, 0x4b, 0x37, 0x86, 0xda, 0xb8, 0x4a, 0xb3, 0xc5, 0x43, 0x7e, 0x6c, 0x5f, - 0x05, 0x5a, 0x00, 0xb9, 0x5a, 0xd5, 0xb0, 0xa9, 0x6f, 0x35, 0xb0, 0xa6, 0xb7, 0xb1, 0xa9, 0xdb, - 0x99, 0x39, 0x8a, 0x1c, 0x73, 0xda, 0x1d, 0xac, 0x4e, 0x54, 0xab, 0x45, 0x5a, 0x99, 0xa3, 0x75, - 0xe8, 0x24, 0x4c, 0x59, 0x5b, 0xcf, 0x54, 0x99, 0x61, 0x69, 0xad, 0x36, 0xde, 0x36, 0x6e, 0x64, - 0xee, 0xa1, 0x5a, 0x9a, 0x24, 0x15, 0xd4, 0xac, 0x36, 0x28, 0x18, 0xdd, 0x0f, 0x72, 0xd5, 0xde, - 0xd1, 0xdb, 0x2d, 0x1a, 0x9c, 0xed, 0x96, 0x5e, 0xc5, 0x99, 0x7b, 0x19, 0x2a, 0x83, 0xaf, 0x09, - 0x30, 0x31, 0x6c, 0xfb, 0x59, 0x63, 0xdb, 0x11, 0x1c, 0xef, 0x63, 0x86, 0x4d, 0x61, 0x9c, 0xdb, - 0x09, 0x90, 0x5b, 0x3b, 0xad, 0x60, 0xc3, 0x27, 0x28, 0xda, 0x44, 0x6b, 0xa7, 0xe5, 0x6f, 0xf7, - 0x6e, 0x18, 0x27, 0x98, 0x5e, 0xa3, 0xf7, 0xb3, 0x14, 0xae, 0xb5, 0xe3, 0x6b, 0xf1, 0x11, 0x38, - 0x48, 0x90, 0x9a, 0xd8, 0xd1, 0x6b, 0xba, 0xa3, 0xfb, 0xb0, 0x1f, 0xa4, 0xd8, 0x33, 0xad, 0x9d, - 0xd6, 0x2a, 0xaf, 0x0c, 0xc8, 0xd9, 0xee, 0x6c, 0xed, 0xba, 0xf6, 0x71, 0x8a, 0xc9, 0x49, 0x60, - 0xc2, 0x42, 0x6e, 0x7b, 0x05, 0xf3, 0x86, 0xad, 0xd7, 0x94, 0x45, 0x18, 0xf3, 0xdb, 0x3d, 0x4a, - 0x03, 0xb3, 0x7c, 0x59, 0x22, 0x79, 0xd4, 0xd2, 0x7a, 0x81, 0x64, 0x40, 0x6f, 0x2f, 0xca, 0x11, - 0x92, 0x89, 0xad, 0x94, 0x2a, 0x45, 0x4d, 0xdd, 0x5c, 0xab, 0x94, 0x56, 0x8b, 0x72, 0xd4, 0xb7, - 0x36, 0xb8, 0x12, 0x4b, 0x9d, 0x94, 0x1f, 0xb8, 0x12, 0x4b, 0x1d, 0x97, 0xef, 0xa3, 0xea, 0xe9, - 0x32, 0x4a, 0xe5, 0x5b, 0x51, 0x98, 0x08, 0x6e, 0x0e, 0xa0, 0xb7, 0xc0, 0x21, 0xb1, 0xfb, 0x67, - 0x63, 0x47, 0x7b, 0xd6, 0x68, 0x53, 0x67, 0x6d, 0xea, 0x6c, 0xe2, 0x74, 0x8d, 0x72, 0x86, 0x63, - 0x95, 0xb1, 0xf3, 0xa4, 0xd1, 0x26, 0xae, 0xd8, 0xd4, 0x1d, 0xb4, 0x02, 0x73, 0xa6, 0xa5, 0xd9, - 0x8e, 0x6e, 0xd6, 0xf4, 0x76, 0xcd, 0xbf, 0xf7, 0xaa, 0x57, 0xab, 0xd8, 0xb6, 0x2d, 0x36, 0x49, - 0xba, 0x5c, 0x8e, 0x9a, 0x56, 0x99, 0x23, 0x7b, 0xb3, 0x47, 0x8e, 0xa3, 0x86, 0x7c, 0x22, 0xda, - 0xcf, 0x27, 0x8e, 0x40, 0xba, 0xa9, 0xb7, 0x34, 0x6c, 0x3a, 0xed, 0x5d, 0x9a, 0xfe, 0xa7, 0xd4, - 0x54, 0x53, 0x6f, 0x15, 0x49, 0x19, 0x5d, 0x85, 0xe3, 0x1e, 0xaa, 0xd6, 0xc0, 0x75, 0xbd, 0xba, - 0xab, 0xd1, 0x5c, 0x9f, 0xee, 0x54, 0x69, 0x55, 0xcb, 0xdc, 0x6e, 0x18, 0x55, 0xc7, 0xa6, 0xb1, - 0x83, 0xc5, 0x3f, 0xc5, 0xa3, 0x58, 0xa1, 0x04, 0x57, 0x6c, 0xcb, 0xa4, 0x29, 0xfe, 0x92, 0xc0, - 0x0e, 0x98, 0xcd, 0xd8, 0x9b, 0xc2, 0x6c, 0x82, 0x43, 0x1f, 0x93, 0xe3, 0x57, 0x62, 0xa9, 0xb8, - 0x9c, 0xb8, 0x12, 0x4b, 0x25, 0xe4, 0xe4, 0x95, 0x58, 0x2a, 0x25, 0xa7, 0xaf, 0xc4, 0x52, 0x69, - 0x19, 0x94, 0x9b, 0xe3, 0x30, 0xe6, 0x5f, 0xb1, 0x90, 0x05, 0x60, 0x95, 0x4e, 0xb8, 0x12, 0x0d, - 0xc9, 0x77, 0xef, 0xb9, 0xbe, 0x59, 0x58, 0x22, 0x33, 0xf1, 0x62, 0x82, 0x2d, 0x0f, 0x54, 0x46, - 0x49, 0xb2, 0x20, 0xe2, 0x64, 0x98, 0xe5, 0x52, 0x29, 0x95, 0x97, 0xd0, 0x32, 0x24, 0x9e, 0xb1, - 0x29, 0x6f, 0x96, 0xca, 0xdd, 0xb3, 0x37, 0xef, 0x2b, 0x65, 0xca, 0x3c, 0x7d, 0xa5, 0xac, 0xad, - 0xad, 0xab, 0xab, 0xb9, 0x15, 0x95, 0x93, 0xa3, 0xc3, 0x10, 0x6b, 0xe8, 0xcf, 0xed, 0x06, 0xe7, - 0x6c, 0x0a, 0x42, 0x0b, 0x30, 0xd9, 0x31, 0xd9, 0x72, 0x9f, 0x8c, 0x31, 0xc1, 0x9a, 0xf4, 0x63, - 0x4d, 0x78, 0xb5, 0x2b, 0x04, 0x7f, 0x48, 0xbb, 0x3a, 0x0c, 0xb1, 0x67, 0xb1, 0x7e, 0x2d, 0x38, - 0xb3, 0x52, 0x10, 0x3a, 0x01, 0x63, 0x35, 0xbc, 0xd5, 0xa9, 0x6b, 0x6d, 0x5c, 0xd3, 0xab, 0x4e, - 0x70, 0x3e, 0x19, 0xa5, 0x55, 0x2a, 0xad, 0x41, 0x4f, 0x40, 0x9a, 0x8c, 0x91, 0x49, 0xc7, 0x78, - 0x8a, 0xaa, 0xe0, 0xd4, 0xde, 0x2a, 0xe0, 0x43, 0x2c, 0x88, 0x54, 0x8f, 0x1e, 0x5d, 0x86, 0xa4, - 0xa3, 0xb7, 0xeb, 0xd8, 0xb1, 0x33, 0xd3, 0xf3, 0xd1, 0x13, 0x13, 0x3d, 0x76, 0xea, 0x7a, 0xb0, - 0xaa, 0x50, 0x12, 0xba, 0xd8, 0x16, 0xe4, 0xe8, 0x49, 0x90, 0xf9, 0x86, 0xb0, 0xc6, 0x57, 0xca, - 0x76, 0x66, 0x86, 0x1a, 0xe0, 0x83, 0x7b, 0xb3, 0xe4, 0xfb, 0xc9, 0x05, 0x46, 0xa4, 0x4e, 0xe2, - 0x40, 0x39, 0xe8, 0x17, 0x07, 0xf6, 0xe3, 0x17, 0x9b, 0x30, 0xc9, 0xff, 0xd6, 0xec, 0x4e, 0xab, - 0x65, 0xb5, 0x9d, 0xcc, 0x41, 0x4a, 0x3f, 0x40, 0x20, 0xc1, 0x8c, 0xd1, 0xa8, 0x13, 0xdb, 0x81, - 0xf2, 0x1b, 0xe7, 0x6e, 0xd9, 0xb7, 0xc3, 0x44, 0x50, 0x19, 0xfe, 0xed, 0xf8, 0xe8, 0x90, 0xdb, - 0xf1, 0x64, 0x59, 0x22, 0xd6, 0x7a, 0x64, 0x6a, 0x62, 0x85, 0xec, 0x8f, 0x45, 0x60, 0x22, 0xd8, - 0x31, 0xb4, 0x0c, 0x48, 0x8c, 0x98, 0x61, 0x3a, 0x6d, 0xab, 0xd6, 0xa9, 0xe2, 0x1a, 0x77, 0xd8, - 0xfe, 0xed, 0x4c, 0x71, 0x9a, 0x92, 0x4b, 0xe2, 0x67, 0xe4, 0xf3, 0x82, 0xc8, 0x90, 0x8c, 0x0a, - 0x9e, 0x7f, 0x9c, 0x86, 0x69, 0xc1, 0x80, 0x30, 0x7b, 0x56, 0x6f, 0x9b, 0x24, 0x45, 0x66, 0x49, - 0x3b, 0xf2, 0x55, 0x3d, 0xc9, 0x6a, 0x50, 0x0e, 0x84, 0xb9, 0x68, 0x6d, 0xdc, 0xb4, 0xae, 0xe3, - 0x1a, 0xdf, 0x71, 0xea, 0xdf, 0xec, 0x04, 0x27, 0x50, 0x19, 0xbe, 0x72, 0x1a, 0xe2, 0x34, 0xfc, - 0x20, 0x00, 0x1e, 0x80, 0xe4, 0x11, 0x94, 0x82, 0xd8, 0xd2, 0xba, 0x4a, 0xa6, 0x47, 0x19, 0xc6, - 0x18, 0x54, 0xdb, 0x28, 0x15, 0x97, 0x8a, 0x72, 0x44, 0x39, 0x07, 0x09, 0x16, 0x53, 0xc8, 0xd4, - 0xe9, 0x46, 0x15, 0x79, 0x84, 0x17, 0x39, 0x0f, 0x49, 0xd4, 0x6e, 0xae, 0xe6, 0x8b, 0xaa, 0x1c, - 0x51, 0x36, 0x61, 0x32, 0xe4, 0x87, 0xe8, 0x00, 0x4c, 0xa9, 0xc5, 0x4a, 0x71, 0xad, 0x52, 0x5a, - 0x5f, 0xd3, 0x36, 0xd7, 0x9e, 0x58, 0x5b, 0x7f, 0x72, 0x4d, 0x1e, 0x09, 0x82, 0xc5, 0x3c, 0x2c, - 0xa1, 0x19, 0x90, 0x3d, 0x70, 0x79, 0x7d, 0x53, 0xa5, 0xd2, 0xfc, 0xbf, 0x11, 0x90, 0xc3, 0x4e, - 0x89, 0x0e, 0xc1, 0x74, 0x25, 0xa7, 0x2e, 0x17, 0x2b, 0x1a, 0xdb, 0x33, 0x71, 0x59, 0xcf, 0x80, - 0xec, 0xaf, 0xb8, 0x54, 0xa2, 0x5b, 0x42, 0x73, 0x70, 0xc4, 0x0f, 0x2d, 0x3e, 0x55, 0x29, 0xae, - 0x95, 0x69, 0xe3, 0xb9, 0xb5, 0x65, 0x92, 0x14, 0x84, 0xf8, 0x89, 0x5d, 0x9a, 0x28, 0x11, 0x35, - 0xc8, 0xaf, 0xb8, 0x52, 0x90, 0x63, 0x61, 0xf0, 0xfa, 0x5a, 0x71, 0xfd, 0x92, 0x1c, 0x0f, 0xb7, - 0x4e, 0x77, 0x6e, 0x12, 0x28, 0x0b, 0x07, 0xc3, 0x50, 0xad, 0xb8, 0x56, 0x51, 0x9f, 0x96, 0x93, - 0xe1, 0x86, 0xcb, 0x45, 0xf5, 0x6a, 0x69, 0xa9, 0x28, 0xa7, 0xd0, 0x41, 0x40, 0x41, 0x89, 0x2a, - 0x97, 0xd7, 0x0b, 0x72, 0xba, 0xd7, 0x8c, 0x85, 0xe4, 0x69, 0xe5, 0xb3, 0x12, 0x8c, 0xf9, 0x77, - 0x51, 0x02, 0x41, 0x45, 0x7a, 0xb3, 0x4d, 0xb6, 0xca, 0x97, 0x22, 0x30, 0xea, 0xdb, 0x4e, 0x21, - 0x8b, 0x58, 0xbd, 0xd1, 0xb0, 0x9e, 0xd5, 0xf4, 0x86, 0xa1, 0xdb, 0x7c, 0x3e, 0x04, 0x0a, 0xca, - 0x11, 0xc8, 0xb0, 0xf3, 0xcf, 0xf0, 0xa9, 0x4b, 0xe2, 0xb6, 0x53, 0x97, 0xe4, 0x9b, 0x30, 0x75, - 0x89, 0xcb, 0x09, 0xe5, 0x0f, 0x22, 0x20, 0x87, 0x77, 0x47, 0x42, 0x7a, 0x93, 0xfa, 0xe9, 0xcd, - 0xdf, 0xbf, 0xc8, 0x7e, 0xfa, 0x17, 0x9e, 0xd5, 0xa3, 0x7d, 0x67, 0xf5, 0x1e, 0x93, 0x55, 0xec, - 0xcd, 0x3c, 0x59, 0xf9, 0xcd, 0xf5, 0x5f, 0x4b, 0x30, 0x11, 0xdc, 0xcc, 0x09, 0x68, 0x4c, 0xd9, - 0x8f, 0xc6, 0x82, 0x23, 0x72, 0x57, 0xbf, 0x11, 0xf9, 0xae, 0xf4, 0xeb, 0xa3, 0x51, 0x18, 0x0f, - 0xec, 0xfd, 0x0c, 0x2b, 0xdd, 0x3b, 0x61, 0xca, 0xa8, 0xe1, 0x66, 0xcb, 0x72, 0xb0, 0x59, 0xdd, - 0xd5, 0x1a, 0xf8, 0x3a, 0x6e, 0x50, 0x35, 0x4c, 0xf4, 0x38, 0xe3, 0x0d, 0xb4, 0xb0, 0x50, 0xf2, - 0xe8, 0x56, 0x08, 0xd9, 0xe2, 0x74, 0xa9, 0x50, 0x5c, 0xdd, 0x58, 0xaf, 0x14, 0xd7, 0x96, 0x9e, - 0x16, 0x91, 0x5c, 0x95, 0x8d, 0x10, 0x5a, 0x40, 0xe1, 0x77, 0xbf, 0x39, 0x16, 0x9d, 0x1b, 0x20, - 0x87, 0x7b, 0x43, 0x02, 0x7a, 0x8f, 0xfe, 0xc8, 0x23, 0x68, 0x1a, 0x26, 0xd7, 0xd6, 0xb5, 0x72, - 0xa9, 0x50, 0xd4, 0x8a, 0x97, 0x2e, 0x15, 0x97, 0x2a, 0x65, 0x76, 0x56, 0xe1, 0x62, 0x57, 0xe4, - 0x88, 0x7f, 0x6c, 0x3e, 0x16, 0x85, 0xe9, 0x1e, 0x92, 0xa0, 0x1c, 0xdf, 0x22, 0x64, 0xbb, 0x96, - 0xa7, 0x86, 0x91, 0x7e, 0x81, 0xac, 0xee, 0x37, 0xf4, 0xb6, 0xc3, 0x77, 0x14, 0xef, 0x07, 0xa2, - 0x5e, 0xd3, 0x21, 0xe9, 0x7d, 0x9b, 0x9f, 0x01, 0xb1, 0x14, 0x64, 0xd2, 0x83, 0xb3, 0x63, 0xa0, - 0x07, 0x01, 0xb5, 0x2c, 0xdb, 0x70, 0x8c, 0xeb, 0x98, 0xe4, 0x50, 0x1c, 0x99, 0x38, 0x6e, 0x4c, - 0x95, 0x45, 0x4d, 0xc9, 0x74, 0x5c, 0x6c, 0x13, 0xd7, 0xf5, 0x10, 0x36, 0x59, 0x7e, 0x44, 0x55, - 0x59, 0xd4, 0xb8, 0xd8, 0x77, 0xc1, 0x58, 0xcd, 0xea, 0x6c, 0x35, 0x30, 0xc7, 0x23, 0x21, 0x59, - 0x52, 0x47, 0x19, 0xcc, 0x45, 0xe1, 0xdb, 0x66, 0xde, 0x49, 0xd5, 0x98, 0x3a, 0xca, 0x60, 0x0c, - 0xe5, 0x3e, 0x98, 0xd4, 0xeb, 0xf5, 0x36, 0x61, 0x2e, 0x18, 0xb1, 0x8d, 0xc0, 0x09, 0x17, 0x4c, - 0x11, 0xb3, 0x57, 0x20, 0x25, 0xf4, 0x40, 0xd6, 0xbf, 0x44, 0x13, 0x5a, 0x8b, 0xed, 0x6e, 0x47, - 0x4e, 0xa4, 0xd5, 0x94, 0x29, 0x2a, 0xef, 0x82, 0x31, 0xc3, 0xf6, 0x6e, 0x3d, 0x65, 0x22, 0xf3, - 0x91, 0x13, 0x29, 0x75, 0xd4, 0xb0, 0xbd, 0x9b, 0x4d, 0xbf, 0x2a, 0x03, 0x78, 0xc6, 0x86, 0x3e, - 0x2c, 0xc1, 0x04, 0x9b, 0x60, 0x5a, 0x6d, 0x6c, 0x63, 0xb3, 0x2a, 0x96, 0x85, 0xf7, 0xef, 0x61, - 0xa2, 0x2c, 0xcc, 0x6d, 0x70, 0x82, 0xfc, 0xe3, 0x2f, 0x48, 0xd2, 0x4b, 0x52, 0xec, 0x25, 0x49, - 0xfa, 0xa4, 0x34, 0x8e, 0x52, 0xc5, 0xa7, 0x36, 0x56, 0x4a, 0x4b, 0xa5, 0x4a, 0xe6, 0xbd, 0x49, - 0x5a, 0x2e, 0xad, 0xf2, 0xf2, 0x57, 0x93, 0xc1, 0xfa, 0x57, 0x93, 0xbf, 0x24, 0x45, 0x53, 0xaf, - 0x26, 0xd5, 0xf1, 0x6d, 0x3f, 0x3f, 0xd4, 0xf0, 0xdf, 0xe3, 0x88, 0xf4, 0x5b, 0x48, 0x7a, 0xd2, - 0x14, 0xf9, 0xed, 0x8d, 0xfc, 0xfd, 0x54, 0x90, 0x04, 0x15, 0x64, 0x14, 0x25, 0x96, 0x56, 0xd6, - 0xcb, 0xc5, 0x02, 0x15, 0x23, 0x8d, 0x62, 0xeb, 0x1b, 0xc5, 0xb5, 0xcc, 0x57, 0x45, 0x93, 0xde, - 0x95, 0x8f, 0x97, 0x24, 0x38, 0x24, 0x0e, 0x6a, 0xf9, 0x5c, 0x8b, 0xcd, 0xaa, 0x55, 0x13, 0xd9, - 0xed, 0xc4, 0xd9, 0x33, 0x7b, 0x35, 0xae, 0x72, 0x52, 0xaa, 0x92, 0x22, 0x27, 0xcc, 0x9f, 0xea, - 0x52, 0x49, 0x6e, 0xad, 0xc0, 0x65, 0x19, 0x45, 0x89, 0x8d, 0xdc, 0xd2, 0x13, 0xc5, 0x82, 0x27, - 0xcd, 0x81, 0x76, 0x2f, 0x2e, 0xe8, 0x87, 0x60, 0xb2, 0xe3, 0x6c, 0x5f, 0x20, 0xb6, 0x61, 0xd4, - 0xd8, 0xc9, 0x79, 0xac, 0xdf, 0x91, 0xab, 0x27, 0xd1, 0xa6, 0xb3, 0x7d, 0xe1, 0xaa, 0x4b, 0xc1, - 0x95, 0xc2, 0x44, 0x49, 0xa3, 0xd8, 0xda, 0xfa, 0x5a, 0x51, 0x88, 0x41, 0x4f, 0x99, 0x9f, 0xf6, - 0xc4, 0x98, 0xe8, 0x04, 0x48, 0xd1, 0x0f, 0x81, 0x2c, 0xb6, 0x87, 0x5c, 0x95, 0xc4, 0xfb, 0x9d, - 0x1a, 0x7b, 0x02, 0xf0, 0x4d, 0x26, 0x57, 0x19, 0xc7, 0x7d, 0x12, 0xcc, 0xa0, 0xc9, 0x95, 0xe2, - 0xda, 0x72, 0xe5, 0xb2, 0xb6, 0xa1, 0x16, 0xe9, 0xe1, 0x5f, 0xe6, 0xbd, 0xa2, 0xf9, 0xc9, 0x66, - 0x90, 0x10, 0xbd, 0x47, 0x82, 0x51, 0x96, 0x02, 0xb1, 0x3d, 0x29, 0xb6, 0xa9, 0x70, 0x7c, 0xaf, - 0xb6, 0x69, 0x06, 0x44, 0xb1, 0xf3, 0x17, 0x69, 0xb3, 0x51, 0x61, 0x10, 0x87, 0x10, 0x5a, 0x29, - 0x2e, 0xe7, 0x96, 0x9e, 0xd6, 0xf2, 0xc5, 0x72, 0x85, 0x44, 0xb2, 0x75, 0x95, 0xd9, 0x28, 0xa0, - 0x78, 0x6e, 0x65, 0x65, 0xfd, 0x49, 0x4f, 0x11, 0xf0, 0x8c, 0xcb, 0x06, 0xfd, 0x9c, 0x04, 0x33, - 0xd8, 0xdc, 0xb6, 0xda, 0x55, 0x7a, 0x60, 0x4d, 0x3c, 0xda, 0x76, 0x76, 0x1b, 0xcc, 0xa3, 0x7b, - 0x2e, 0xca, 0xfd, 0x96, 0x49, 0xe9, 0xd6, 0x28, 0x59, 0x99, 0x50, 0xe5, 0x4b, 0x2f, 0x48, 0x91, - 0x97, 0x88, 0x60, 0x11, 0x2a, 0x5b, 0xec, 0x25, 0x29, 0x4e, 0x25, 0x4c, 0xbe, 0x24, 0xa5, 0x5e, - 0x92, 0xd2, 0x9f, 0x94, 0xa6, 0xd0, 0x58, 0xb9, 0xf2, 0xf4, 0x4a, 0x51, 0x63, 0xd2, 0x52, 0x09, - 0x27, 0x50, 0x9a, 0xc2, 0xce, 0x3e, 0x74, 0xf6, 0x91, 0xcc, 0xd7, 0xa8, 0x94, 0x5f, 0x4b, 0xaa, - 0x08, 0x77, 0xb1, 0x47, 0xbf, 0x2a, 0xc1, 0x61, 0x71, 0x44, 0x6e, 0xd3, 0x63, 0x33, 0xcd, 0x77, - 0xc0, 0x96, 0xa2, 0x22, 0x17, 0xf7, 0x12, 0xd9, 0x3b, 0x65, 0xe3, 0xc0, 0x05, 0xbe, 0xe0, 0x0d, - 0x1f, 0xc2, 0xe5, 0xcf, 0xb3, 0x9e, 0x7c, 0x52, 0x9a, 0x44, 0x50, 0x7c, 0x6a, 0x63, 0x5d, 0xad, - 0x68, 0xb9, 0x95, 0x15, 0x2a, 0xef, 0x01, 0x24, 0x73, 0x48, 0x65, 0x7d, 0x43, 0x5b, 0x29, 0x5e, - 0x2d, 0xae, 0x78, 0x62, 0x1f, 0xaa, 0xf5, 0x66, 0x98, 0xfd, 0x84, 0x04, 0x53, 0x5d, 0xcd, 0x2b, - 0xef, 0x96, 0xe0, 0x50, 0x1f, 0x11, 0xd0, 0xbd, 0x70, 0x57, 0xa1, 0x78, 0x29, 0xb7, 0xb9, 0x52, - 0xd1, 0xca, 0x4f, 0xaf, 0xe6, 0xd7, 0x57, 0xb4, 0xab, 0xa5, 0x72, 0x29, 0x5f, 0x5a, 0x29, 0x55, - 0xfc, 0x13, 0xd8, 0x04, 0xf8, 0x04, 0x64, 0xcb, 0xb5, 0xb0, 0x78, 0x72, 0x84, 0x2c, 0x0a, 0x57, - 0xd6, 0x97, 0x72, 0x2b, 0x14, 0x29, 0x2a, 0xd6, 0x9c, 0x4b, 0x15, 0x39, 0x76, 0x25, 0x95, 0x92, - 0xf8, 0xdc, 0xf6, 0x0e, 0x18, 0x0f, 0x04, 0x3f, 0xb2, 0x44, 0xa2, 0x4b, 0x2b, 0x62, 0xcf, 0xe5, - 0xe2, 0xda, 0x92, 0x7f, 0x49, 0x37, 0x06, 0x6e, 0xb0, 0x93, 0x25, 0x52, 0x12, 0xa1, 0x50, 0x8e, - 0x90, 0x49, 0x95, 0x9b, 0xa3, 0x7b, 0x38, 0x1d, 0x55, 0x1e, 0x85, 0x94, 0x08, 0x66, 0x64, 0xa1, - 0x46, 0xd7, 0x5b, 0xa1, 0x65, 0x62, 0x0a, 0x68, 0x24, 0x93, 0x25, 0x22, 0x20, 0x8b, 0x70, 0x72, - 0x44, 0xb9, 0x0a, 0x07, 0x7a, 0x06, 0x22, 0x74, 0x37, 0xcc, 0x89, 0x03, 0x71, 0xb6, 0x04, 0xd4, - 0x8a, 0x6b, 0x4b, 0xeb, 0x05, 0xb2, 0x68, 0xf6, 0x78, 0x02, 0xf0, 0x88, 0xc4, 0xa4, 0x14, 0xd1, - 0x4a, 0x8e, 0x28, 0x25, 0x98, 0x08, 0x86, 0x13, 0x74, 0x04, 0x0e, 0x6d, 0x56, 0x2e, 0x5d, 0xd0, - 0xae, 0xe6, 0x56, 0x4a, 0x85, 0x5c, 0x68, 0x79, 0x0c, 0xc0, 0x63, 0x8a, 0x1c, 0x21, 0x82, 0x92, - 0x58, 0x23, 0x47, 0x95, 0x58, 0x4a, 0x92, 0x25, 0xa5, 0x0c, 0x93, 0xa1, 0xc0, 0x80, 0x8e, 0x42, - 0x86, 0xaf, 0x57, 0x7b, 0x49, 0x45, 0x35, 0x14, 0x08, 0x15, 0x6c, 0xe5, 0x5e, 0x28, 0xae, 0x94, - 0x56, 0x4b, 0x15, 0x2a, 0xdf, 0x65, 0x00, 0xcf, 0xe3, 0x49, 0x06, 0x73, 0xa5, 0xbc, 0xbe, 0xa6, + // 12514 bytes of a gzipped FileDescriptorSet + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x6b, 0x94, 0x5b, 0xd7, + 0x75, 0x18, 0x3c, 0x17, 0x6f, 0xec, 0x79, 0xdd, 0x39, 0x33, 0x24, 0x41, 0xf0, 0x31, 0xd4, 0x95, + 0x44, 0x51, 0x94, 0x38, 0x14, 0x29, 0x91, 0x22, 0x47, 0x8e, 0x15, 0x60, 0x00, 0xce, 0x80, 0x9a, + 0x97, 0x2e, 0x30, 0x94, 0xe4, 0x38, 0xb9, 0xeb, 0x0e, 0x70, 0x06, 0x73, 0x45, 0xe0, 0x5e, 0x18, + 0xf7, 0x82, 0xe2, 0xc8, 0x49, 0x96, 0xec, 0xf8, 0xf3, 0x27, 0xcb, 0x9f, 0xbf, 0xd8, 0x9f, 0xf3, + 0x25, 0xb2, 0x13, 0x3a, 0xb2, 0x9d, 0xc6, 0xa9, 0xed, 0x34, 0x4e, 0xe2, 0xa6, 0x4d, 0x9b, 0xb5, + 0x92, 0x74, 0x2d, 0x37, 0x8e, 0x9b, 0x74, 0xc9, 0x69, 0xda, 0xa6, 0x59, 0x29, 0xdd, 0x2a, 0x5e, + 0xb1, 0xec, 0xb8, 0x8d, 0xa3, 0xb8, 0x6d, 0xba, 0xdc, 0xd4, 0x5d, 0xe7, 0x75, 0x5f, 0x00, 0x06, + 0x18, 0x8a, 0x4a, 0x94, 0xa6, 0x7f, 0xc8, 0x39, 0xfb, 0xec, 0xbd, 0xcf, 0x3e, 0xfb, 0xec, 0xbd, + 0xcf, 0x3e, 0xaf, 0x0b, 0xf8, 0x2b, 0x03, 0x8e, 0xd5, 0x2d, 0xab, 0xde, 0xc0, 0xa7, 0x5b, 0x6d, + 0xcb, 0xb1, 0x36, 0x3b, 0x5b, 0xa7, 0x6b, 0xd8, 0xae, 0xb6, 0x8d, 0x96, 0x63, 0xb5, 0xe7, 0x28, + 0x0c, 0x4d, 0x32, 0x8c, 0x39, 0x81, 0xa1, 0x7c, 0x49, 0x82, 0xa9, 0x4b, 0x46, 0x03, 0x17, 0x5c, + 0xcc, 0x32, 0x76, 0xd0, 0x05, 0x88, 0x6d, 0x19, 0x0d, 0x9c, 0x91, 0x8e, 0x45, 0x4f, 0x8c, 0x9e, + 0xbd, 0x6b, 0x2e, 0x44, 0x35, 0x17, 0xa4, 0x58, 0x27, 0x60, 0x95, 0x52, 0x9c, 0x7c, 0x67, 0xea, + 0xb9, 0x6f, 0x7e, 0xe9, 0xbb, 0x92, 0xfc, 0x2e, 0xf2, 0x6f, 0xb6, 0x89, 0xae, 0xb2, 0x32, 0x7a, + 0x68, 0x8e, 0xd0, 0xf9, 0xe4, 0xb9, 0x76, 0x86, 0x40, 0x34, 0x42, 0xa4, 0x79, 0x60, 0xcd, 0xc6, + 0x8e, 0x86, 0xaf, 0x3b, 0xd8, 0xb4, 0x0d, 0xcb, 0xcc, 0x9e, 0xea, 0x41, 0xd5, 0x25, 0x6d, 0x51, + 0xa0, 0x2b, 0x5f, 0x88, 0xc3, 0x74, 0x0f, 0xd1, 0x10, 0x82, 0x98, 0xa9, 0x37, 0x49, 0x77, 0xa4, + 0x13, 0x69, 0x95, 0xfe, 0x8d, 0x32, 0x90, 0x6c, 0xe9, 0xd5, 0xab, 0x7a, 0x1d, 0x67, 0x22, 0x14, + 0x2c, 0x8a, 0xe8, 0x28, 0x40, 0x0d, 0xb7, 0xb0, 0x59, 0xc3, 0x66, 0x75, 0x27, 0x13, 0x3d, 0x16, + 0x3d, 0x91, 0x56, 0x7d, 0x10, 0x74, 0x1f, 0x4c, 0xb5, 0x3a, 0x9b, 0x0d, 0xa3, 0xaa, 0xf9, 0xd0, + 0xe0, 0x58, 0xf4, 0x44, 0x5c, 0x95, 0x59, 0x45, 0xc1, 0x43, 0xbe, 0x07, 0x26, 0x9f, 0xc1, 0xfa, + 0x55, 0x3f, 0xea, 0x28, 0x45, 0x9d, 0x20, 0xe0, 0x42, 0x80, 0xab, 0xd5, 0x72, 0x0c, 0xcb, 0xf4, + 0xa3, 0x4e, 0xd2, 0xc6, 0x65, 0x56, 0xe1, 0x43, 0x5e, 0x80, 0xb1, 0x26, 0xb6, 0x6d, 0xbd, 0x8e, + 0x35, 0x67, 0xa7, 0x85, 0x33, 0x31, 0x3a, 0x4e, 0xc7, 0xba, 0xc6, 0x29, 0x3c, 0x46, 0xa3, 0x9c, + 0xaa, 0xb2, 0xd3, 0xc2, 0x28, 0x07, 0x69, 0x6c, 0x76, 0x9a, 0x8c, 0x43, 0xbc, 0xcf, 0x48, 0x17, + 0xcd, 0x4e, 0x33, 0xcc, 0x25, 0x45, 0xc8, 0x38, 0x8b, 0xa4, 0x8d, 0xdb, 0xd7, 0x8c, 0x2a, 0xce, + 0x24, 0x28, 0x83, 0x7b, 0xba, 0x18, 0x94, 0x59, 0x7d, 0x98, 0x87, 0xa0, 0x43, 0x0b, 0x90, 0x76, + 0xc7, 0x3b, 0x93, 0xa4, 0x4c, 0xee, 0xee, 0x61, 0x6f, 0xb8, 0x51, 0x0b, 0xb3, 0xf0, 0xe8, 0xd0, + 0x79, 0x48, 0x32, 0x1d, 0xd9, 0x99, 0xd4, 0x31, 0xe9, 0xc4, 0xe8, 0xd9, 0xc3, 0x3d, 0x4d, 0x76, + 0x8d, 0xe1, 0xa8, 0x02, 0x19, 0x95, 0x40, 0xb6, 0xad, 0x4e, 0xbb, 0x8a, 0xb5, 0xaa, 0x55, 0xc3, + 0x9a, 0x61, 0x6e, 0x59, 0x99, 0x34, 0x65, 0x30, 0xdb, 0xdd, 0x11, 0x8a, 0xb8, 0x60, 0xd5, 0x70, + 0xc9, 0xdc, 0xb2, 0xd4, 0x09, 0x3b, 0x50, 0x46, 0xfb, 0x21, 0x61, 0xef, 0x98, 0x8e, 0x7e, 0x3d, + 0x33, 0x46, 0xcd, 0x89, 0x97, 0xd0, 0x59, 0x48, 0xe2, 0x9a, 0x41, 0x9a, 0xcb, 0x4c, 0x1c, 0x93, + 0x4e, 0x4c, 0x9c, 0xcd, 0x74, 0xeb, 0x98, 0xd5, 0xab, 0x02, 0x51, 0xf9, 0x1f, 0x09, 0x98, 0x1c, + 0xc6, 0x86, 0x1f, 0x81, 0xf8, 0x16, 0xd1, 0x4c, 0x26, 0xb2, 0x17, 0xbd, 0x31, 0x9a, 0xa0, 0xe2, + 0x13, 0xb7, 0xa8, 0xf8, 0x1c, 0x8c, 0x9a, 0xd8, 0x76, 0x70, 0x8d, 0x59, 0x51, 0x74, 0x48, 0x3b, + 0x04, 0x46, 0xd4, 0x6d, 0x86, 0xb1, 0x5b, 0x32, 0xc3, 0x27, 0x61, 0xd2, 0x15, 0x49, 0x6b, 0xeb, + 0x66, 0x5d, 0xd8, 0xf3, 0xe9, 0x41, 0x92, 0xcc, 0xb9, 0xc1, 0x43, 0x25, 0x64, 0xea, 0x04, 0x0e, + 0x94, 0x51, 0x01, 0xc0, 0x32, 0xb1, 0xb5, 0xa5, 0xd5, 0x70, 0xb5, 0x91, 0x49, 0xf5, 0xd1, 0xd2, + 0x1a, 0x41, 0xe9, 0xd2, 0x92, 0xc5, 0xa0, 0xd5, 0x06, 0xba, 0xe8, 0x99, 0x67, 0xb2, 0x8f, 0x75, + 0xad, 0x30, 0xc7, 0xec, 0xb2, 0xd0, 0x0d, 0x98, 0x68, 0x63, 0xe2, 0x2b, 0xb8, 0xc6, 0x7b, 0x96, + 0xa6, 0x42, 0xcc, 0x0d, 0xec, 0x99, 0xca, 0xc9, 0x58, 0xc7, 0xc6, 0xdb, 0xfe, 0x22, 0xba, 0x13, + 0x5c, 0x80, 0x46, 0xcd, 0x0a, 0x68, 0xa4, 0x19, 0x13, 0xc0, 0x55, 0x62, 0x5e, 0x39, 0x80, 0x6b, + 0x86, 0x6d, 0x6c, 0x1a, 0x0d, 0xc3, 0x21, 0x61, 0x8b, 0x58, 0xef, 0x1d, 0xdd, 0x7e, 0xb1, 0xd3, + 0xdc, 0xb4, 0x1a, 0x57, 0x5c, 0x44, 0xd5, 0x47, 0x94, 0x7d, 0x16, 0x26, 0x82, 0x1a, 0x46, 0x33, + 0x10, 0xb7, 0x1d, 0xbd, 0xed, 0x50, 0x43, 0x8e, 0xab, 0xac, 0x80, 0x64, 0x88, 0x62, 0xb3, 0x46, + 0x23, 0x71, 0x5c, 0x25, 0x7f, 0xa2, 0xef, 0xf5, 0x74, 0x16, 0xa5, 0x3a, 0x3b, 0xde, 0x6d, 0x14, + 0x01, 0xce, 0x61, 0xd5, 0x65, 0x1f, 0x86, 0xf1, 0x80, 0x0e, 0x86, 0x6d, 0x5a, 0xf9, 0x9d, 0x18, + 0xec, 0xeb, 0xc9, 0x1b, 0x3d, 0x09, 0x33, 0x1d, 0xd3, 0x30, 0x1d, 0xdc, 0x6e, 0xb5, 0x31, 0xb1, + 0x7a, 0xd6, 0x56, 0xe6, 0x6b, 0xc9, 0x3e, 0x76, 0xbb, 0xe1, 0xc7, 0x66, 0x5c, 0xd4, 0xe9, 0x4e, + 0x37, 0x10, 0x3d, 0x05, 0xa3, 0xc4, 0xc4, 0xf4, 0xb6, 0x4e, 0x19, 0x32, 0x87, 0x3e, 0x3b, 0x5c, + 0x97, 0xe7, 0x0a, 0x1e, 0x65, 0x3e, 0xfa, 0xbc, 0x14, 0x51, 0xfd, 0xbc, 0xd0, 0xc3, 0x90, 0xda, + 0xc2, 0xba, 0xd3, 0x69, 0x63, 0x3b, 0x73, 0x96, 0xaa, 0xf2, 0x50, 0xb7, 0x9f, 0x33, 0x84, 0x32, + 0x76, 0x54, 0x17, 0x19, 0x35, 0x61, 0xec, 0x1a, 0x6e, 0x1b, 0x5b, 0x46, 0x95, 0x09, 0x15, 0xa5, + 0x16, 0x70, 0x61, 0x48, 0xa1, 0xae, 0xf8, 0x48, 0xcb, 0x8e, 0xee, 0xe0, 0x79, 0xd8, 0x58, 0xbd, + 0x52, 0x54, 0x4b, 0x97, 0x4a, 0xc5, 0x02, 0x13, 0x33, 0xc0, 0x3e, 0xfb, 0x63, 0x12, 0x8c, 0xfa, + 0x7a, 0x42, 0x22, 0xaa, 0xd9, 0x69, 0x6e, 0xe2, 0x36, 0x1f, 0x2f, 0x5e, 0x42, 0x87, 0x20, 0xbd, + 0xd5, 0x69, 0x34, 0x98, 0xdd, 0xb2, 0xb9, 0x3b, 0x45, 0x00, 0xd4, 0x66, 0x11, 0xc4, 0x78, 0x24, + 0xa2, 0x61, 0x92, 0xfc, 0x8d, 0xb2, 0x90, 0x12, 0x76, 0x9d, 0x89, 0x1f, 0x93, 0x4e, 0xa4, 0x54, + 0xb7, 0xcc, 0xea, 0x5a, 0x58, 0x77, 0x70, 0x2d, 0x93, 0x10, 0x75, 0xac, 0x7c, 0x39, 0x96, 0x8a, + 0xc9, 0x71, 0xe5, 0x21, 0x98, 0xea, 0xea, 0x0a, 0x9a, 0x84, 0xd1, 0x42, 0x71, 0x61, 0x39, 0xa7, + 0xe6, 0x2a, 0xa5, 0xb5, 0x55, 0x79, 0x04, 0x4d, 0x80, 0xaf, 0x77, 0xb2, 0x74, 0x32, 0x9d, 0x7a, + 0x35, 0x29, 0x3f, 0xf7, 0xdc, 0x73, 0xcf, 0x45, 0x94, 0xdf, 0x4c, 0xc0, 0x4c, 0xaf, 0x38, 0xda, + 0x33, 0xa4, 0x7b, 0x9d, 0x8e, 0x06, 0x3a, 0x9d, 0x83, 0x78, 0x43, 0xdf, 0xc4, 0x8d, 0x4c, 0x8c, + 0x0e, 0xc2, 0x7d, 0x43, 0x45, 0xea, 0xb9, 0x65, 0x42, 0xa2, 0x32, 0x4a, 0xf4, 0x56, 0xae, 0x9a, + 0x38, 0xe5, 0x70, 0x72, 0x38, 0x0e, 0x24, 0xbe, 0x72, 0x35, 0x1e, 0x82, 0x34, 0xf9, 0x9f, 0xe9, + 0x3d, 0xc1, 0xf4, 0x4e, 0x00, 0x54, 0xef, 0x59, 0x48, 0xd1, 0xd0, 0x59, 0xc3, 0xee, 0x98, 0x88, + 0x32, 0x09, 0x36, 0x35, 0xbc, 0xa5, 0x77, 0x1a, 0x8e, 0x76, 0x4d, 0x6f, 0x74, 0x30, 0x0d, 0x82, + 0x69, 0x75, 0x8c, 0x03, 0xaf, 0x10, 0x18, 0x9a, 0x85, 0x51, 0x16, 0x69, 0x0d, 0xb3, 0x86, 0xaf, + 0xd3, 0x59, 0x38, 0xae, 0xb2, 0xe0, 0x5b, 0x22, 0x10, 0xd2, 0xfc, 0xd3, 0xb6, 0x65, 0x8a, 0x70, + 0x45, 0x9b, 0x20, 0x00, 0xda, 0xfc, 0xc3, 0xe1, 0x04, 0xe0, 0x48, 0xef, 0xee, 0x75, 0xc5, 0xd7, + 0x7b, 0x60, 0x92, 0x62, 0x3c, 0xc8, 0x5d, 0x59, 0x6f, 0x64, 0xa6, 0xa8, 0x19, 0x4c, 0x30, 0xf0, + 0x1a, 0x87, 0x2a, 0xbf, 0x12, 0x81, 0x18, 0x9d, 0x6c, 0x26, 0x61, 0xb4, 0xf2, 0xd4, 0x7a, 0x51, + 0x2b, 0xac, 0x6d, 0xe4, 0x97, 0x8b, 0xb2, 0x44, 0x86, 0x9e, 0x02, 0x2e, 0x2d, 0xaf, 0xe5, 0x2a, + 0x72, 0xc4, 0x2d, 0x97, 0x56, 0x2b, 0xe7, 0x1f, 0x92, 0xa3, 0x2e, 0xc1, 0x06, 0x03, 0xc4, 0xfc, + 0x08, 0x0f, 0x9e, 0x95, 0xe3, 0x48, 0x86, 0x31, 0xc6, 0xa0, 0xf4, 0x64, 0xb1, 0x70, 0xfe, 0x21, + 0x39, 0x11, 0x84, 0x3c, 0x78, 0x56, 0x4e, 0xa2, 0x71, 0x48, 0x53, 0x48, 0x7e, 0x6d, 0x6d, 0x59, + 0x4e, 0xb9, 0x3c, 0xcb, 0x15, 0xb5, 0xb4, 0xba, 0x28, 0xa7, 0x5d, 0x9e, 0x8b, 0xea, 0xda, 0xc6, + 0xba, 0x0c, 0x2e, 0x87, 0x95, 0x62, 0xb9, 0x9c, 0x5b, 0x2c, 0xca, 0xa3, 0x2e, 0x46, 0xfe, 0xa9, + 0x4a, 0xb1, 0x2c, 0x8f, 0x05, 0xc4, 0x7a, 0xf0, 0xac, 0x3c, 0xee, 0x36, 0x51, 0x5c, 0xdd, 0x58, + 0x91, 0x27, 0xd0, 0x14, 0x8c, 0xb3, 0x26, 0x84, 0x10, 0x93, 0x21, 0xd0, 0xf9, 0x87, 0x64, 0xd9, + 0x13, 0x84, 0x71, 0x99, 0x0a, 0x00, 0xce, 0x3f, 0x24, 0x23, 0x65, 0x01, 0xe2, 0xd4, 0x0c, 0x11, + 0x82, 0x89, 0xe5, 0x5c, 0xbe, 0xb8, 0xac, 0xad, 0xad, 0x13, 0xa7, 0xc9, 0x2d, 0xcb, 0x92, 0x07, + 0x53, 0x8b, 0xeb, 0xc5, 0x5c, 0xa5, 0x58, 0x90, 0xa3, 0x7e, 0xd8, 0xe3, 0x1b, 0x25, 0xb5, 0x58, + 0x90, 0x23, 0x4a, 0x15, 0x66, 0x7a, 0x4d, 0xb2, 0x3d, 0x5d, 0xc8, 0x67, 0x0b, 0x91, 0x3e, 0xb6, + 0x40, 0x79, 0x85, 0x6d, 0x41, 0xf9, 0xd9, 0x28, 0x4c, 0xf7, 0x48, 0x34, 0x7a, 0x36, 0xf2, 0x28, + 0xc4, 0x99, 0x2d, 0xb3, 0x48, 0x7d, 0x6f, 0xcf, 0x8c, 0x85, 0x5a, 0x76, 0x57, 0xfa, 0x45, 0xe9, + 0xfc, 0x29, 0x6b, 0xb4, 0x4f, 0xca, 0x4a, 0x58, 0x74, 0x19, 0xec, 0xf7, 0x77, 0x25, 0x04, 0x2c, + 0x67, 0x3a, 0x3f, 0x4c, 0xce, 0x44, 0x61, 0x7b, 0x4b, 0x0c, 0xe2, 0x03, 0x13, 0x83, 0xc4, 0xad, + 0x24, 0x06, 0x8f, 0xc0, 0x54, 0x97, 0x2c, 0x43, 0x4f, 0xd0, 0x3f, 0x22, 0x41, 0xa6, 0x9f, 0x7e, + 0x07, 0x44, 0xd5, 0x48, 0x20, 0xaa, 0x3e, 0x12, 0x1e, 0x84, 0x3b, 0xfa, 0x8f, 0x63, 0x97, 0xb9, + 0x7c, 0x4a, 0x82, 0xfd, 0xbd, 0x57, 0x37, 0x3d, 0x65, 0x78, 0x2b, 0x24, 0x9a, 0xd8, 0xd9, 0xb6, + 0x44, 0xb6, 0x7e, 0xbc, 0x47, 0x0e, 0x48, 0xaa, 0xc3, 0xf6, 0xc2, 0xa9, 0xfc, 0x49, 0x64, 0xb4, + 0xdf, 0x12, 0x85, 0x49, 0xd3, 0x25, 0xe9, 0xfb, 0x22, 0xb0, 0xaf, 0x27, 0xf3, 0x9e, 0x82, 0x1e, + 0x01, 0x30, 0xcc, 0x56, 0xc7, 0x61, 0x19, 0x39, 0x0b, 0xe6, 0x69, 0x0a, 0xa1, 0xf1, 0x8f, 0x04, + 0xea, 0x8e, 0xe3, 0xd6, 0xb3, 0x89, 0x16, 0x18, 0x88, 0x22, 0x5c, 0xf0, 0x04, 0x8d, 0x51, 0x41, + 0x8f, 0xf6, 0xe9, 0x69, 0x97, 0x6d, 0x3f, 0x00, 0x72, 0xb5, 0x61, 0x60, 0xd3, 0xd1, 0x6c, 0xa7, + 0x8d, 0xf5, 0xa6, 0x61, 0xd6, 0xd9, 0x84, 0x3d, 0x1f, 0xdf, 0xd2, 0x1b, 0x36, 0x56, 0x27, 0x59, + 0x75, 0x59, 0xd4, 0x12, 0x0a, 0x6a, 0x40, 0x6d, 0x1f, 0x45, 0x22, 0x40, 0xc1, 0xaa, 0x5d, 0x0a, + 0xe5, 0xe7, 0xd3, 0x30, 0xea, 0x5b, 0x0b, 0xa2, 0x3b, 0x60, 0xec, 0x69, 0xfd, 0x9a, 0xae, 0x89, + 0xcd, 0x00, 0xa6, 0x89, 0x51, 0x02, 0x5b, 0xe7, 0x1b, 0x02, 0x0f, 0xc0, 0x0c, 0x45, 0xb1, 0x3a, + 0x0e, 0x6e, 0x6b, 0xd5, 0x86, 0x6e, 0xdb, 0x54, 0x69, 0x29, 0x8a, 0x8a, 0x48, 0xdd, 0x1a, 0xa9, + 0x5a, 0x10, 0x35, 0xe8, 0x1c, 0x4c, 0x53, 0x8a, 0x66, 0xa7, 0xe1, 0x18, 0xad, 0x06, 0xa6, 0xdb, + 0x1c, 0x36, 0x9d, 0xb5, 0x5c, 0xc9, 0xa6, 0x08, 0xc6, 0x0a, 0x47, 0x20, 0x12, 0xd9, 0xa8, 0x00, + 0x47, 0x28, 0x59, 0x1d, 0x9b, 0xb8, 0xad, 0x3b, 0x58, 0xc3, 0xef, 0xe8, 0xe8, 0x0d, 0x5b, 0xd3, + 0xcd, 0x9a, 0xb6, 0xad, 0xdb, 0xdb, 0x99, 0x19, 0xc2, 0x20, 0x1f, 0xc9, 0x48, 0xea, 0x41, 0x82, + 0xb8, 0xc8, 0xf1, 0x8a, 0x14, 0x2d, 0x67, 0xd6, 0x96, 0x74, 0x7b, 0x1b, 0xcd, 0xc3, 0x7e, 0xca, + 0xc5, 0x76, 0xda, 0x86, 0x59, 0xd7, 0xaa, 0xdb, 0xb8, 0x7a, 0x55, 0xeb, 0x38, 0x5b, 0x17, 0x32, + 0x87, 0xfc, 0xed, 0x53, 0x09, 0xcb, 0x14, 0x67, 0x81, 0xa0, 0x6c, 0x38, 0x5b, 0x17, 0x50, 0x19, + 0xc6, 0xc8, 0x60, 0x34, 0x8d, 0x67, 0xb1, 0xb6, 0x65, 0xb5, 0xe9, 0x34, 0x3c, 0xd1, 0x23, 0xba, + 0xf9, 0x34, 0x38, 0xb7, 0xc6, 0x09, 0x56, 0xac, 0x1a, 0x9e, 0x8f, 0x97, 0xd7, 0x8b, 0xc5, 0x82, + 0x3a, 0x2a, 0xb8, 0x5c, 0xb2, 0xda, 0xc4, 0xa0, 0xea, 0x96, 0xab, 0xe0, 0x51, 0x66, 0x50, 0x75, + 0x4b, 0xa8, 0xf7, 0x1c, 0x4c, 0x57, 0xab, 0xac, 0xcf, 0x46, 0x55, 0xe3, 0xfb, 0x02, 0x76, 0x46, + 0x0e, 0x28, 0xab, 0x5a, 0x5d, 0x64, 0x08, 0xdc, 0xc6, 0x6d, 0x74, 0x11, 0xf6, 0x79, 0xca, 0xf2, + 0x13, 0x4e, 0x75, 0xf5, 0x32, 0x4c, 0x7a, 0x0e, 0xa6, 0x5b, 0x3b, 0xdd, 0x84, 0x28, 0xd0, 0x62, + 0x6b, 0x27, 0x4c, 0x76, 0x37, 0xdd, 0x18, 0x6a, 0xe3, 0x2a, 0xcd, 0x16, 0x0f, 0xf8, 0xb1, 0x7d, + 0x15, 0x68, 0x0e, 0xe4, 0x6a, 0x55, 0xc3, 0xa6, 0xbe, 0xd9, 0xc0, 0x9a, 0xde, 0xc6, 0xa6, 0x6e, + 0x67, 0x66, 0x29, 0x72, 0xcc, 0x69, 0x77, 0xb0, 0x3a, 0x51, 0xad, 0x16, 0x69, 0x65, 0x8e, 0xd6, + 0xa1, 0x93, 0x30, 0x65, 0x6d, 0x3e, 0x5d, 0x65, 0x86, 0xa5, 0xb5, 0xda, 0x78, 0xcb, 0xb8, 0x9e, + 0xb9, 0x8b, 0x6a, 0x69, 0x92, 0x54, 0x50, 0xb3, 0x5a, 0xa7, 0x60, 0x74, 0x2f, 0xc8, 0x55, 0x7b, + 0x5b, 0x6f, 0xb7, 0x68, 0x70, 0xb6, 0x5b, 0x7a, 0x15, 0x67, 0xee, 0x66, 0xa8, 0x0c, 0xbe, 0x2a, + 0xc0, 0xc4, 0xb0, 0xed, 0x67, 0x8c, 0x2d, 0x47, 0x70, 0xbc, 0x87, 0x19, 0x36, 0x85, 0x71, 0x6e, + 0x27, 0x40, 0x6e, 0x6d, 0xb7, 0x82, 0x0d, 0x9f, 0xa0, 0x68, 0x13, 0xad, 0xed, 0x96, 0xbf, 0xdd, + 0x3b, 0x61, 0x9c, 0x60, 0x7a, 0x8d, 0xde, 0xcb, 0x52, 0xb8, 0xd6, 0xb6, 0xaf, 0xc5, 0x87, 0x60, + 0x3f, 0x41, 0x6a, 0x62, 0x47, 0xaf, 0xe9, 0x8e, 0xee, 0xc3, 0xbe, 0x9f, 0x62, 0xcf, 0xb4, 0xb6, + 0x5b, 0x2b, 0xbc, 0x32, 0x20, 0x67, 0xbb, 0xb3, 0xb9, 0xe3, 0xda, 0xc7, 0x29, 0x26, 0x27, 0x81, + 0x09, 0x0b, 0xb9, 0xe5, 0x15, 0xcc, 0x1b, 0xb6, 0x5e, 0x53, 0xe6, 0x61, 0xcc, 0x6f, 0xf7, 0x28, + 0x0d, 0xcc, 0xf2, 0x65, 0x89, 0xe4, 0x51, 0x0b, 0x6b, 0x05, 0x92, 0x01, 0xbd, 0xad, 0x28, 0x47, + 0x48, 0x26, 0xb6, 0x5c, 0xaa, 0x14, 0x35, 0x75, 0x63, 0xb5, 0x52, 0x5a, 0x29, 0xca, 0x51, 0xdf, + 0xda, 0xe0, 0x72, 0x2c, 0x75, 0x52, 0xbe, 0xef, 0x72, 0x2c, 0x75, 0x5c, 0xbe, 0x87, 0xaa, 0xa7, + 0xcb, 0x28, 0x95, 0x6f, 0x47, 0x61, 0x22, 0xb8, 0x39, 0x80, 0xde, 0x02, 0x07, 0xc4, 0xee, 0x9f, + 0x8d, 0x1d, 0xed, 0x19, 0xa3, 0x4d, 0x9d, 0xb5, 0xa9, 0xb3, 0x89, 0xd3, 0x35, 0xca, 0x19, 0x8e, + 0x55, 0xc6, 0xce, 0x13, 0x46, 0x9b, 0xb8, 0x62, 0x53, 0x77, 0xd0, 0x32, 0xcc, 0x9a, 0x96, 0x66, + 0x3b, 0xba, 0x59, 0xd3, 0xdb, 0x35, 0xff, 0xde, 0xab, 0x5e, 0xad, 0x62, 0xdb, 0xb6, 0xd8, 0x24, + 0xe9, 0x72, 0x39, 0x6c, 0x5a, 0x65, 0x8e, 0xec, 0xcd, 0x1e, 0x39, 0x8e, 0x1a, 0xf2, 0x89, 0x68, + 0x3f, 0x9f, 0x38, 0x04, 0xe9, 0xa6, 0xde, 0xd2, 0xb0, 0xe9, 0xb4, 0x77, 0x68, 0xfa, 0x9f, 0x52, + 0x53, 0x4d, 0xbd, 0x55, 0x24, 0x65, 0x74, 0x05, 0x8e, 0x7b, 0xa8, 0x5a, 0x03, 0xd7, 0xf5, 0xea, + 0x8e, 0x46, 0x73, 0x7d, 0xba, 0x53, 0xa5, 0x55, 0x2d, 0x73, 0xab, 0x61, 0x54, 0x1d, 0x9b, 0xc6, + 0x0e, 0x16, 0xff, 0x14, 0x8f, 0x62, 0x99, 0x12, 0x5c, 0xb6, 0x2d, 0x93, 0xa6, 0xf8, 0x0b, 0x02, + 0x3b, 0x60, 0x36, 0x63, 0x6f, 0x0a, 0xb3, 0x09, 0x0e, 0x7d, 0x4c, 0x8e, 0x5f, 0x8e, 0xa5, 0xe2, + 0x72, 0xe2, 0x72, 0x2c, 0x95, 0x90, 0x93, 0x97, 0x63, 0xa9, 0x94, 0x9c, 0xbe, 0x1c, 0x4b, 0xa5, + 0x65, 0x50, 0x6e, 0x8c, 0xc3, 0x98, 0x7f, 0xc5, 0x42, 0x16, 0x80, 0x55, 0x3a, 0xe1, 0x4a, 0x34, + 0x24, 0xdf, 0xb9, 0xeb, 0xfa, 0x66, 0x6e, 0x81, 0xcc, 0xc4, 0xf3, 0x09, 0xb6, 0x3c, 0x50, 0x19, + 0x25, 0xc9, 0x82, 0x88, 0x93, 0x61, 0x96, 0x4b, 0xa5, 0x54, 0x5e, 0x42, 0x8b, 0x90, 0x78, 0xda, + 0xa6, 0xbc, 0x59, 0x2a, 0x77, 0xd7, 0xee, 0xbc, 0x2f, 0x97, 0x29, 0xf3, 0xf4, 0xe5, 0xb2, 0xb6, + 0xba, 0xa6, 0xae, 0xe4, 0x96, 0x55, 0x4e, 0x8e, 0x0e, 0x42, 0xac, 0xa1, 0x3f, 0xbb, 0x13, 0x9c, + 0xb3, 0x29, 0x08, 0xcd, 0xc1, 0x64, 0xc7, 0x64, 0xcb, 0x7d, 0x32, 0xc6, 0x04, 0x6b, 0xd2, 0x8f, + 0x35, 0xe1, 0xd5, 0x2e, 0x13, 0xfc, 0x21, 0xed, 0xea, 0x20, 0xc4, 0x9e, 0xc1, 0xfa, 0xd5, 0xe0, + 0xcc, 0x4a, 0x41, 0xe8, 0x04, 0x8c, 0xd5, 0xf0, 0x66, 0xa7, 0xae, 0xb5, 0x71, 0x4d, 0xaf, 0x3a, + 0xc1, 0xf9, 0x64, 0x94, 0x56, 0xa9, 0xb4, 0x06, 0x3d, 0x06, 0x69, 0x32, 0x46, 0x26, 0x1d, 0xe3, + 0x29, 0xaa, 0x82, 0x53, 0xbb, 0xab, 0x80, 0x0f, 0xb1, 0x20, 0x52, 0x3d, 0x7a, 0xb4, 0x04, 0x49, + 0x47, 0x6f, 0xd7, 0xb1, 0x63, 0x67, 0xa6, 0x8f, 0x45, 0x4f, 0x4c, 0xf4, 0xd8, 0xa9, 0xeb, 0xc1, + 0xaa, 0x42, 0x49, 0xe8, 0x62, 0x5b, 0x90, 0xa3, 0x27, 0x40, 0xe6, 0x1b, 0xc2, 0x1a, 0x5f, 0x29, + 0xdb, 0x99, 0x19, 0x6a, 0x80, 0xf7, 0xef, 0xce, 0x92, 0xef, 0x27, 0x17, 0x18, 0x91, 0x3a, 0x89, + 0x03, 0xe5, 0xa0, 0x5f, 0xec, 0xdb, 0x8b, 0x5f, 0x6c, 0xc0, 0x24, 0xff, 0x5b, 0xb3, 0x3b, 0xad, + 0x96, 0xd5, 0x76, 0x32, 0xfb, 0x29, 0xfd, 0x00, 0x81, 0x04, 0x33, 0x46, 0xa3, 0x4e, 0x6c, 0x05, + 0xca, 0x6f, 0x9c, 0xbb, 0x65, 0xdf, 0x06, 0x13, 0x41, 0x65, 0xf8, 0xb7, 0xe3, 0xa3, 0x43, 0x6e, + 0xc7, 0x93, 0x65, 0x89, 0x58, 0xeb, 0x91, 0xa9, 0x89, 0x15, 0xb2, 0x3f, 0x1e, 0x81, 0x89, 0x60, + 0xc7, 0xd0, 0x22, 0x20, 0x31, 0x62, 0x86, 0xe9, 0xb4, 0xad, 0x5a, 0xa7, 0x8a, 0x6b, 0xdc, 0x61, + 0xfb, 0xb7, 0x33, 0xc5, 0x69, 0x4a, 0x2e, 0x89, 0x9f, 0x91, 0xcf, 0x0b, 0x22, 0x43, 0x32, 0x2a, + 0x78, 0xfe, 0x71, 0x1a, 0xa6, 0x05, 0x03, 0xc2, 0xec, 0x19, 0xbd, 0x6d, 0x92, 0x14, 0x99, 0x25, + 0xed, 0xc8, 0x57, 0xf5, 0x04, 0xab, 0x41, 0x39, 0x10, 0xe6, 0xa2, 0xb5, 0x71, 0xd3, 0xba, 0x86, + 0x6b, 0x7c, 0xc7, 0xa9, 0x7f, 0xb3, 0x13, 0x9c, 0x40, 0x65, 0xf8, 0xca, 0x69, 0x88, 0xd3, 0xf0, + 0x83, 0x00, 0x78, 0x00, 0x92, 0x47, 0x50, 0x0a, 0x62, 0x0b, 0x6b, 0x2a, 0x99, 0x1e, 0x65, 0x18, + 0x63, 0x50, 0x6d, 0xbd, 0x54, 0x5c, 0x28, 0xca, 0x11, 0xe5, 0x1c, 0x24, 0x58, 0x4c, 0x21, 0x53, + 0xa7, 0x1b, 0x55, 0xe4, 0x11, 0x5e, 0xe4, 0x3c, 0x24, 0x51, 0xbb, 0xb1, 0x92, 0x2f, 0xaa, 0x72, + 0x44, 0xd9, 0x80, 0xc9, 0x90, 0x1f, 0xa2, 0x7d, 0x30, 0xa5, 0x16, 0x2b, 0xc5, 0xd5, 0x4a, 0x69, + 0x6d, 0x55, 0xdb, 0x58, 0x7d, 0x6c, 0x75, 0xed, 0x89, 0x55, 0x79, 0x24, 0x08, 0x16, 0xf3, 0xb0, + 0x84, 0x66, 0x40, 0xf6, 0xc0, 0xe5, 0xb5, 0x0d, 0x95, 0x4a, 0xf3, 0xff, 0x44, 0x40, 0x0e, 0x3b, + 0x25, 0x3a, 0x00, 0xd3, 0x95, 0x9c, 0xba, 0x58, 0xac, 0x68, 0x6c, 0xcf, 0xc4, 0x65, 0x3d, 0x03, + 0xb2, 0xbf, 0xe2, 0x52, 0x89, 0x6e, 0x09, 0xcd, 0xc2, 0x21, 0x3f, 0xb4, 0xf8, 0x64, 0xa5, 0xb8, + 0x5a, 0xa6, 0x8d, 0xe7, 0x56, 0x17, 0x49, 0x52, 0x10, 0xe2, 0x27, 0x76, 0x69, 0xa2, 0x44, 0xd4, + 0x20, 0xbf, 0xe2, 0x72, 0x41, 0x8e, 0x85, 0xc1, 0x6b, 0xab, 0xc5, 0xb5, 0x4b, 0x72, 0x3c, 0xdc, + 0x3a, 0xdd, 0xb9, 0x49, 0xa0, 0x2c, 0xec, 0x0f, 0x43, 0xb5, 0xe2, 0x6a, 0x45, 0x7d, 0x4a, 0x4e, + 0x86, 0x1b, 0x2e, 0x17, 0xd5, 0x2b, 0xa5, 0x85, 0xa2, 0x9c, 0x42, 0xfb, 0x01, 0x05, 0x25, 0xaa, + 0x2c, 0xad, 0x15, 0xe4, 0x74, 0xaf, 0x19, 0x0b, 0xc9, 0xd3, 0xca, 0x67, 0x25, 0x18, 0xf3, 0xef, + 0xa2, 0x04, 0x82, 0x8a, 0xf4, 0x66, 0x9b, 0x6c, 0x95, 0x2f, 0x47, 0x60, 0xd4, 0xb7, 0x9d, 0x42, + 0x16, 0xb1, 0x7a, 0xa3, 0x61, 0x3d, 0xa3, 0xe9, 0x0d, 0x43, 0xb7, 0xf9, 0x7c, 0x08, 0x14, 0x94, + 0x23, 0x90, 0x61, 0xe7, 0x9f, 0xe1, 0x53, 0x97, 0xc4, 0x2d, 0xa7, 0x2e, 0xc9, 0x37, 0x61, 0xea, + 0x12, 0x97, 0x13, 0xca, 0x1f, 0x44, 0x40, 0x0e, 0xef, 0x8e, 0x84, 0xf4, 0x26, 0xf5, 0xd3, 0x9b, + 0xbf, 0x7f, 0x91, 0xbd, 0xf4, 0x2f, 0x3c, 0xab, 0x47, 0xfb, 0xce, 0xea, 0x3d, 0x26, 0xab, 0xd8, + 0x9b, 0x79, 0xb2, 0xf2, 0x9b, 0xeb, 0xbf, 0x96, 0x60, 0x22, 0xb8, 0x99, 0x13, 0xd0, 0x98, 0xb2, + 0x17, 0x8d, 0x05, 0x47, 0xe4, 0x8e, 0x7e, 0x23, 0xf2, 0xd7, 0xd2, 0xaf, 0x8f, 0x44, 0x61, 0x3c, + 0xb0, 0xf7, 0x33, 0xac, 0x74, 0xef, 0x80, 0x29, 0xa3, 0x86, 0x9b, 0x2d, 0xcb, 0xc1, 0x66, 0x75, + 0x47, 0x6b, 0xe0, 0x6b, 0xb8, 0x41, 0xd5, 0x30, 0xd1, 0xe3, 0x8c, 0x37, 0xd0, 0xc2, 0x5c, 0xc9, + 0xa3, 0x5b, 0x26, 0x64, 0xf3, 0xd3, 0xa5, 0x42, 0x71, 0x65, 0x7d, 0xad, 0x52, 0x5c, 0x5d, 0x78, + 0x4a, 0x44, 0x72, 0x55, 0x36, 0x42, 0x68, 0x01, 0x85, 0xdf, 0xf9, 0xe6, 0x58, 0x74, 0xae, 0x83, + 0x1c, 0xee, 0x0d, 0x09, 0xe8, 0x3d, 0xfa, 0x23, 0x8f, 0xa0, 0x69, 0x98, 0x5c, 0x5d, 0xd3, 0xca, + 0xa5, 0x42, 0x51, 0x2b, 0x5e, 0xba, 0x54, 0x5c, 0xa8, 0x94, 0xd9, 0x59, 0x85, 0x8b, 0x5d, 0x91, + 0x23, 0xfe, 0xb1, 0xf9, 0x68, 0x14, 0xa6, 0x7b, 0x48, 0x82, 0x72, 0x7c, 0x8b, 0x90, 0xed, 0x5a, + 0x9e, 0x1a, 0x46, 0xfa, 0x39, 0xb2, 0xba, 0x5f, 0xd7, 0xdb, 0x0e, 0xdf, 0x51, 0xbc, 0x17, 0x88, + 0x7a, 0x4d, 0x87, 0xa4, 0xf7, 0x6d, 0x7e, 0x06, 0xc4, 0x52, 0x90, 0x49, 0x0f, 0xce, 0x8e, 0x81, + 0xee, 0x07, 0xd4, 0xb2, 0x6c, 0xc3, 0x31, 0xae, 0x61, 0x92, 0x43, 0x71, 0x64, 0xe2, 0xb8, 0x31, + 0x55, 0x16, 0x35, 0x25, 0xd3, 0x71, 0xb1, 0x4d, 0x5c, 0xd7, 0x43, 0xd8, 0x64, 0xf9, 0x11, 0x55, + 0x65, 0x51, 0xe3, 0x62, 0xdf, 0x01, 0x63, 0x35, 0xab, 0xb3, 0xd9, 0xc0, 0x1c, 0x8f, 0x84, 0x64, + 0x49, 0x1d, 0x65, 0x30, 0x17, 0x85, 0x6f, 0x9b, 0x79, 0x27, 0x55, 0x63, 0xea, 0x28, 0x83, 0x31, + 0x94, 0x7b, 0x60, 0x52, 0xaf, 0xd7, 0xdb, 0x84, 0xb9, 0x60, 0xc4, 0x36, 0x02, 0x27, 0x5c, 0x30, + 0x45, 0xcc, 0x5e, 0x86, 0x94, 0xd0, 0x03, 0x59, 0xff, 0x12, 0x4d, 0x68, 0x2d, 0xb6, 0xbb, 0x1d, + 0x39, 0x91, 0x56, 0x53, 0xa6, 0xa8, 0xbc, 0x03, 0xc6, 0x0c, 0xdb, 0xbb, 0xf5, 0x94, 0x89, 0x1c, + 0x8b, 0x9c, 0x48, 0xa9, 0xa3, 0x86, 0xed, 0xdd, 0x6c, 0xfa, 0x55, 0x19, 0xc0, 0x33, 0x36, 0xf4, + 0x21, 0x09, 0x26, 0xd8, 0x04, 0xd3, 0x6a, 0x63, 0x1b, 0x9b, 0x55, 0xb1, 0x2c, 0xbc, 0x77, 0x17, + 0x13, 0x65, 0x61, 0x6e, 0x9d, 0x13, 0xe4, 0x1f, 0x7d, 0x5e, 0x92, 0x5e, 0x94, 0x62, 0x2f, 0x4a, + 0xd2, 0x27, 0xa4, 0x71, 0x94, 0x2a, 0x3e, 0xb9, 0xbe, 0x5c, 0x5a, 0x28, 0x55, 0x32, 0xef, 0x49, + 0xd2, 0x72, 0x69, 0x85, 0x97, 0xbf, 0x96, 0x0c, 0xd6, 0xbf, 0x9a, 0xfc, 0x25, 0x29, 0x9a, 0x7a, + 0x35, 0xa9, 0x8e, 0x6f, 0xf9, 0xf9, 0xa1, 0x86, 0xff, 0x1e, 0x47, 0xa4, 0xdf, 0x42, 0xd2, 0x93, + 0xa6, 0xc8, 0x6f, 0x6f, 0xe4, 0xef, 0xa5, 0x82, 0x24, 0xa8, 0x20, 0xa3, 0x28, 0xb1, 0xb0, 0xbc, + 0x56, 0x2e, 0x16, 0xa8, 0x18, 0x69, 0x14, 0x5b, 0x5b, 0x2f, 0xae, 0x66, 0xbe, 0x26, 0x9a, 0xf4, + 0xae, 0x7c, 0xbc, 0x28, 0xc1, 0x01, 0x71, 0x50, 0xcb, 0xe7, 0x5a, 0x6c, 0x56, 0xad, 0x9a, 0xc8, + 0x6e, 0x27, 0xce, 0x9e, 0xd9, 0xad, 0x71, 0x95, 0x93, 0x52, 0x95, 0x14, 0x39, 0x61, 0xfe, 0x54, + 0x97, 0x4a, 0x72, 0xab, 0x05, 0x2e, 0xcb, 0x28, 0x4a, 0xac, 0xe7, 0x16, 0x1e, 0x2b, 0x16, 0x3c, + 0x69, 0xf6, 0xb5, 0x7b, 0x71, 0x41, 0x3f, 0x0c, 0x93, 0x1d, 0x67, 0xeb, 0x02, 0xb1, 0x0d, 0xa3, + 0xc6, 0x4e, 0xce, 0x63, 0xfd, 0x8e, 0x5c, 0x3d, 0x89, 0x36, 0x9c, 0xad, 0x0b, 0x57, 0x5c, 0x0a, + 0xae, 0x14, 0x26, 0x4a, 0x1a, 0xc5, 0x56, 0xd7, 0x56, 0x8b, 0x42, 0x0c, 0x7a, 0xca, 0xfc, 0x94, + 0x27, 0xc6, 0x44, 0x27, 0x40, 0x8a, 0x7e, 0x18, 0x64, 0xb1, 0x3d, 0xe4, 0xaa, 0x24, 0xde, 0xef, + 0xd4, 0xd8, 0x13, 0x80, 0x6f, 0x32, 0xb9, 0xca, 0x38, 0xee, 0x93, 0x60, 0x06, 0x4d, 0x2e, 0x17, + 0x57, 0x17, 0x2b, 0x4b, 0xda, 0xba, 0x5a, 0xa4, 0x87, 0x7f, 0x99, 0xf7, 0x88, 0xe6, 0x27, 0x9b, + 0x41, 0x42, 0xf4, 0x6e, 0x09, 0x46, 0x59, 0x0a, 0xc4, 0xf6, 0xa4, 0xd8, 0xa6, 0xc2, 0xf1, 0xdd, + 0xda, 0xa6, 0x19, 0x10, 0xc5, 0xce, 0x5f, 0xa4, 0xcd, 0x46, 0x85, 0x41, 0x1c, 0x40, 0x68, 0xb9, + 0xb8, 0x98, 0x5b, 0x78, 0x4a, 0xcb, 0x17, 0xcb, 0x15, 0x12, 0xc9, 0xd6, 0x54, 0x66, 0xa3, 0x80, + 0xe2, 0xb9, 0xe5, 0xe5, 0xb5, 0x27, 0x3c, 0x45, 0xc0, 0xd3, 0x2e, 0x1b, 0xf4, 0x19, 0x09, 0x66, + 0xb0, 0xb9, 0x65, 0xb5, 0xab, 0xf4, 0xc0, 0x9a, 0x78, 0xb4, 0xed, 0xec, 0x34, 0x98, 0x47, 0xf7, + 0x5c, 0x94, 0xfb, 0x2d, 0x93, 0xd2, 0xad, 0x52, 0xb2, 0x32, 0xa1, 0xca, 0x97, 0x9e, 0x97, 0x22, + 0x2f, 0x12, 0xc1, 0x22, 0x54, 0xb6, 0xd8, 0x8b, 0x52, 0x9c, 0x4a, 0x98, 0x7c, 0x51, 0x4a, 0xbd, + 0x28, 0xa5, 0x3f, 0x21, 0x4d, 0xa1, 0xb1, 0x72, 0xe5, 0xa9, 0xe5, 0xa2, 0xc6, 0xa4, 0xa5, 0x12, + 0x4e, 0xa0, 0x34, 0x85, 0x9d, 0x7d, 0xe0, 0xec, 0x43, 0x99, 0xaf, 0x53, 0x29, 0xbf, 0x9e, 0x54, + 0x11, 0xee, 0x62, 0x8f, 0x7e, 0x55, 0x82, 0x83, 0xe2, 0x88, 0xdc, 0xa6, 0xc7, 0x66, 0x9a, 0xef, + 0x80, 0x2d, 0x45, 0x45, 0x2e, 0xee, 0x26, 0xb2, 0x77, 0xca, 0xc6, 0x81, 0x73, 0x7c, 0xc1, 0x1b, + 0x3e, 0x84, 0xcb, 0x9f, 0x67, 0x3d, 0xf9, 0x84, 0x34, 0x89, 0xa0, 0xf8, 0xe4, 0xfa, 0x9a, 0x5a, + 0xd1, 0x72, 0xcb, 0xcb, 0x54, 0xde, 0x7d, 0x48, 0xe6, 0x90, 0xca, 0xda, 0xba, 0xb6, 0x5c, 0xbc, + 0x52, 0x5c, 0xf6, 0xc4, 0x3e, 0x50, 0xeb, 0xcd, 0x30, 0xfb, 0x71, 0x09, 0xa6, 0xba, 0x9a, 0x57, + 0xde, 0x25, 0xc1, 0x81, 0x3e, 0x22, 0xa0, 0xbb, 0xe1, 0x8e, 0x42, 0xf1, 0x52, 0x6e, 0x63, 0xb9, + 0xa2, 0x95, 0x9f, 0x5a, 0xc9, 0xaf, 0x2d, 0x6b, 0x57, 0x4a, 0xe5, 0x52, 0xbe, 0xb4, 0x5c, 0xaa, + 0xf8, 0x27, 0xb0, 0x09, 0xf0, 0x09, 0xc8, 0x96, 0x6b, 0x61, 0xf1, 0xe4, 0x08, 0x59, 0x14, 0x2e, + 0xaf, 0x2d, 0xe4, 0x96, 0x29, 0x52, 0x54, 0xac, 0x39, 0x17, 0x2a, 0x72, 0xec, 0x72, 0x2a, 0x25, + 0xf1, 0xb9, 0xed, 0xed, 0x30, 0x1e, 0x08, 0x7e, 0x64, 0x89, 0x44, 0x97, 0x56, 0xc4, 0x9e, 0xcb, + 0xc5, 0xd5, 0x05, 0xff, 0x92, 0x6e, 0x0c, 0xdc, 0x60, 0x27, 0x4b, 0xa4, 0x24, 0x42, 0xa1, 0x1c, + 0x21, 0x93, 0x2a, 0x37, 0x47, 0xf7, 0x70, 0x3a, 0xaa, 0x3c, 0x0c, 0x29, 0x11, 0xcc, 0xc8, 0x42, + 0x8d, 0xae, 0xb7, 0x42, 0xcb, 0xc4, 0x14, 0xd0, 0x48, 0x26, 0x4b, 0x44, 0x40, 0x16, 0xe1, 0xe4, + 0x88, 0x72, 0x05, 0xf6, 0xf5, 0x0c, 0x44, 0xe8, 0x4e, 0x98, 0x15, 0x07, 0xe2, 0x6c, 0x09, 0xa8, + 0x15, 0x57, 0x17, 0xd6, 0x0a, 0x64, 0xd1, 0xec, 0xf1, 0x04, 0xe0, 0x11, 0x89, 0x49, 0x29, 0xa2, + 0x95, 0x1c, 0x51, 0x4a, 0x30, 0x11, 0x0c, 0x27, 0xe8, 0x10, 0x1c, 0xd8, 0xa8, 0x5c, 0xba, 0xa0, + 0x5d, 0xc9, 0x2d, 0x97, 0x0a, 0xb9, 0xd0, 0xf2, 0x18, 0x80, 0xc7, 0x14, 0x39, 0x42, 0x04, 0x25, + 0xb1, 0x46, 0x8e, 0x2a, 0xb1, 0x94, 0x24, 0x4b, 0x4a, 0x19, 0x26, 0x43, 0x81, 0x01, 0x1d, 0x86, + 0x0c, 0x5f, 0xaf, 0xf6, 0x92, 0x8a, 0x6a, 0x28, 0x10, 0x2a, 0xd8, 0xca, 0xbd, 0x50, 0x5c, 0x2e, + 0xad, 0x94, 0x2a, 0x54, 0xbe, 0x25, 0x00, 0xcf, 0xe3, 0x49, 0x06, 0x73, 0xb9, 0xbc, 0xb6, 0xaa, 0x5d, 0x22, 0xcb, 0xfe, 0x8a, 0x8f, 0x55, 0x1a, 0x98, 0x87, 0xcb, 0x12, 0x59, 0x9d, 0x76, 0x87, - 0x01, 0x39, 0xa2, 0x3c, 0x09, 0xa8, 0xdb, 0x5b, 0xd1, 0x3c, 0x1c, 0x2d, 0xae, 0x5d, 0x5a, 0x57, - 0x97, 0x8a, 0xda, 0x5a, 0x6e, 0x95, 0xc8, 0xc7, 0x7c, 0xd3, 0x63, 0x3d, 0x0e, 0x9e, 0x6b, 0x8a, - 0x3d, 0x09, 0xcf, 0x7b, 0xe5, 0xc8, 0xc9, 0xcf, 0x49, 0x24, 0x33, 0xfa, 0xc0, 0x5a, 0xf6, 0xd3, - 0x12, 0x3a, 0x96, 0x7a, 0x35, 0x89, 0x92, 0x0b, 0xad, 0xad, 0x85, 0x6a, 0xab, 0x95, 0x9d, 0x24, - 0x7f, 0x2c, 0xb5, 0x5a, 0x97, 0x44, 0xbe, 0x37, 0x97, 0xfa, 0x5a, 0x12, 0xa5, 0x08, 0xf4, 0x19, - 0xfd, 0xba, 0x9e, 0x95, 0xc9, 0x5f, 0x57, 0xf4, 0xeb, 0xba, 0x8b, 0x70, 0x24, 0xf5, 0xf5, 0x24, - 0x4a, 0x10, 0x70, 0xdd, 0xca, 0x4e, 0x90, 0xff, 0x97, 0x2d, 0xb7, 0xf2, 0xee, 0xd4, 0x9f, 0x26, - 0x11, 0x10, 0x60, 0x6b, 0xd7, 0xd9, 0xb1, 0xcc, 0x2c, 0x22, 0x7f, 0x6f, 0xd0, 0xbf, 0x7d, 0x48, - 0xef, 0x5b, 0xe3, 0x48, 0xc4, 0xf9, 0xcf, 0x70, 0x24, 0xfa, 0xb7, 0x40, 0x3a, 0x99, 0x48, 0x7d, - 0x60, 0x4d, 0xfe, 0xd0, 0xda, 0xc9, 0x44, 0xea, 0x43, 0x6b, 0xf2, 0x87, 0xd7, 0xae, 0x24, 0x52, - 0x5f, 0x4d, 0xca, 0xaf, 0x26, 0x95, 0x3f, 0x8b, 0x02, 0xf2, 0x42, 0x85, 0xbb, 0x0b, 0xf8, 0x14, - 0xa4, 0xdc, 0x6d, 0x45, 0x76, 0xcf, 0xfb, 0x2d, 0x7b, 0x44, 0x18, 0x41, 0xe6, 0x03, 0x85, 0xb6, - 0x19, 0x5d, 0x6e, 0x28, 0x07, 0x93, 0x4d, 0xc3, 0x34, 0x9a, 0x9d, 0xa6, 0x26, 0xf6, 0xda, 0x06, - 0xee, 0x21, 0x71, 0x02, 0x5e, 0xa6, 0x2c, 0xf4, 0x1b, 0x01, 0x16, 0xf1, 0x81, 0x2c, 0x18, 0x01, - 0x2f, 0x67, 0xff, 0x52, 0x82, 0x4c, 0x3f, 0x61, 0x6f, 0x6b, 0x1b, 0x70, 0x0d, 0x66, 0xac, 0xeb, - 0xb8, 0xdd, 0x36, 0x6a, 0xf4, 0x64, 0xcf, 0x5d, 0x1c, 0xc4, 0x06, 0x2f, 0x0e, 0xa6, 0x7d, 0x84, - 0xee, 0xa0, 0xe6, 0x49, 0x0e, 0x77, 0x83, 0xa4, 0x2f, 0x82, 0x53, 0x7c, 0x30, 0xa7, 0x71, 0x4a, - 0x22, 0x78, 0x5c, 0x21, 0x4e, 0x4a, 0xd6, 0xe3, 0x11, 0x39, 0xea, 0xad, 0x40, 0x94, 0x8f, 0x47, - 0x61, 0x22, 0x78, 0x5d, 0x19, 0x15, 0x20, 0xd5, 0xb0, 0xf8, 0x3d, 0x3e, 0x36, 0xda, 0x27, 0x06, - 0xdc, 0x70, 0x5e, 0x58, 0xe1, 0xf8, 0xaa, 0x4b, 0x99, 0xfd, 0x17, 0x12, 0xa4, 0x04, 0x18, 0x1d, - 0x84, 0x58, 0x4b, 0x77, 0x76, 0x28, 0xbb, 0x78, 0x3e, 0x22, 0x4b, 0x2a, 0x2d, 0x13, 0xb8, 0xdd, - 0xd2, 0xd9, 0x1d, 0x46, 0x0e, 0x27, 0x65, 0xb2, 0x0a, 0x68, 0x60, 0xbd, 0x46, 0xcf, 0xa4, 0xad, - 0x66, 0x13, 0x9b, 0x8e, 0x2d, 0x56, 0x01, 0x1c, 0xbe, 0xc4, 0xc1, 0xe8, 0x01, 0x98, 0x72, 0xda, - 0xba, 0xd1, 0x08, 0xe0, 0xc6, 0x28, 0xae, 0x2c, 0x2a, 0x5c, 0xe4, 0x45, 0x38, 0x2c, 0xf8, 0xd6, - 0xb0, 0xa3, 0x57, 0x77, 0x70, 0xcd, 0x23, 0x4a, 0xd0, 0xeb, 0x2b, 0x87, 0x38, 0x42, 0x81, 0xd7, - 0x0b, 0xda, 0x93, 0x9d, 0xc0, 0x73, 0x85, 0x3a, 0xc2, 0xfc, 0xb9, 0xc2, 0x99, 0x3e, 0xcf, 0x15, - 0xc2, 0xb7, 0xc5, 0x7d, 0x6f, 0x15, 0x4e, 0xf6, 0x20, 0x09, 0x6a, 0xd4, 0x4b, 0xe7, 0xbf, 0x18, - 0x81, 0x29, 0x71, 0x78, 0x5f, 0x73, 0xc7, 0x68, 0x15, 0x40, 0x37, 0x4d, 0xcb, 0xf1, 0x8f, 0x52, - 0xf7, 0x7a, 0xab, 0x8b, 0x6e, 0x21, 0xe7, 0x12, 0xa9, 0x3e, 0x06, 0xd9, 0x3f, 0x95, 0x00, 0xbc, - 0xaa, 0xbe, 0xc3, 0x35, 0x07, 0xa3, 0xbc, 0x57, 0xf4, 0xc9, 0x07, 0xdb, 0xe3, 0x06, 0x06, 0xba, - 0x64, 0x34, 0xe8, 0xad, 0x9c, 0x2d, 0x5c, 0x37, 0x4c, 0x7e, 0x23, 0x91, 0x15, 0xc4, 0xad, 0x9c, + 0x01, 0x39, 0xa2, 0x3c, 0x01, 0xa8, 0xdb, 0x5b, 0xd1, 0x31, 0x38, 0x5c, 0x5c, 0xbd, 0xb4, 0xa6, + 0x2e, 0x14, 0xb5, 0xd5, 0xdc, 0x0a, 0x91, 0x8f, 0xf9, 0xa6, 0xc7, 0x7a, 0x1c, 0x3c, 0xd7, 0x14, + 0x7b, 0x12, 0x9e, 0xf7, 0xca, 0x91, 0x93, 0x9f, 0x93, 0x48, 0x66, 0xf4, 0xfe, 0xd5, 0xec, 0xa7, + 0x24, 0x74, 0x24, 0xf5, 0x6a, 0x12, 0x25, 0xe7, 0x5a, 0x9b, 0x73, 0xd5, 0x56, 0x2b, 0x3b, 0x49, + 0xfe, 0x58, 0x68, 0xb5, 0x2e, 0x89, 0x7c, 0x6f, 0x36, 0xf5, 0xf5, 0x24, 0x4a, 0x11, 0xe8, 0xd3, + 0xfa, 0x35, 0x3d, 0x2b, 0x93, 0xbf, 0x2e, 0xeb, 0xd7, 0x74, 0x17, 0xe1, 0x50, 0xea, 0x1b, 0x49, + 0x94, 0x20, 0xe0, 0xba, 0x95, 0x9d, 0x20, 0xff, 0x2f, 0x5a, 0x6e, 0xe5, 0x9d, 0xa9, 0x3f, 0x4d, + 0x22, 0x20, 0xc0, 0xd6, 0x8e, 0xb3, 0x6d, 0x99, 0x59, 0x44, 0xfe, 0x5e, 0xa7, 0x7f, 0xfb, 0x90, + 0xde, 0xbb, 0xca, 0x91, 0x88, 0xf3, 0x9f, 0xe1, 0x48, 0xf4, 0x6f, 0x81, 0x74, 0x32, 0x91, 0x7a, + 0xff, 0xaa, 0xfc, 0xc1, 0xd5, 0x93, 0x89, 0xd4, 0x07, 0x57, 0xe5, 0x0f, 0xad, 0x5e, 0x4e, 0xa4, + 0xbe, 0x96, 0x94, 0x5f, 0x4d, 0x2a, 0x7f, 0x16, 0x05, 0xe4, 0x85, 0x0a, 0x77, 0x17, 0xf0, 0x49, + 0x48, 0xb9, 0xdb, 0x8a, 0xec, 0x9e, 0xf7, 0x5b, 0x76, 0x89, 0x30, 0x82, 0xcc, 0x07, 0x0a, 0x6d, + 0x33, 0xba, 0xdc, 0x50, 0x0e, 0x26, 0x9b, 0x86, 0x69, 0x34, 0x3b, 0x4d, 0x4d, 0xec, 0xb5, 0x0d, + 0xdc, 0x43, 0xe2, 0x04, 0xbc, 0x4c, 0x59, 0xe8, 0xd7, 0x03, 0x2c, 0xe2, 0x03, 0x59, 0x30, 0x02, + 0x5e, 0xce, 0xfe, 0xa5, 0x04, 0x99, 0x7e, 0xc2, 0xde, 0xd2, 0x36, 0xe0, 0x2a, 0xcc, 0x58, 0xd7, + 0x70, 0xbb, 0x6d, 0xd4, 0xe8, 0xc9, 0x9e, 0xbb, 0x38, 0x88, 0x0d, 0x5e, 0x1c, 0x4c, 0xfb, 0x08, + 0xdd, 0x41, 0xcd, 0x93, 0x1c, 0xee, 0x3a, 0x49, 0x5f, 0x04, 0xa7, 0xf8, 0x60, 0x4e, 0xe3, 0x94, + 0x44, 0xf0, 0xb8, 0x4c, 0x9c, 0x94, 0xac, 0xc7, 0x23, 0x72, 0xd4, 0x5b, 0x81, 0x28, 0x1f, 0x8b, + 0xc2, 0x44, 0xf0, 0xba, 0x32, 0x2a, 0x40, 0xaa, 0x61, 0xf1, 0x7b, 0x7c, 0x6c, 0xb4, 0x4f, 0x0c, + 0xb8, 0xe1, 0x3c, 0xb7, 0xcc, 0xf1, 0x55, 0x97, 0x32, 0xfb, 0x2f, 0x25, 0x48, 0x09, 0x30, 0xda, + 0x0f, 0xb1, 0x96, 0xee, 0x6c, 0x53, 0x76, 0xf1, 0x7c, 0x44, 0x96, 0x54, 0x5a, 0x26, 0x70, 0xbb, + 0xa5, 0xb3, 0x3b, 0x8c, 0x1c, 0x4e, 0xca, 0x64, 0x15, 0xd0, 0xc0, 0x7a, 0x8d, 0x9e, 0x49, 0x5b, + 0xcd, 0x26, 0x36, 0x1d, 0x5b, 0xac, 0x02, 0x38, 0x7c, 0x81, 0x83, 0xd1, 0x7d, 0x30, 0xe5, 0xb4, + 0x75, 0xa3, 0x11, 0xc0, 0x8d, 0x51, 0x5c, 0x59, 0x54, 0xb8, 0xc8, 0xf3, 0x70, 0x50, 0xf0, 0xad, + 0x61, 0x47, 0xaf, 0x6e, 0xe3, 0x9a, 0x47, 0x94, 0xa0, 0xd7, 0x57, 0x0e, 0x70, 0x84, 0x02, 0xaf, + 0x17, 0xb4, 0x27, 0x3b, 0x81, 0xe7, 0x0a, 0x75, 0x84, 0xf9, 0x73, 0x85, 0x33, 0x7d, 0x9e, 0x2b, + 0x84, 0x6f, 0x8b, 0xfb, 0xde, 0x2a, 0x9c, 0xec, 0x41, 0x12, 0xd4, 0xa8, 0x97, 0xce, 0xbf, 0x1c, + 0x81, 0x29, 0x71, 0x78, 0x5f, 0x73, 0xc7, 0x68, 0x05, 0x40, 0x37, 0x4d, 0xcb, 0xf1, 0x8f, 0x52, + 0xf7, 0x7a, 0xab, 0x8b, 0x6e, 0x2e, 0xe7, 0x12, 0xa9, 0x3e, 0x06, 0xd9, 0x3f, 0x95, 0x00, 0xbc, + 0xaa, 0xbe, 0xc3, 0x35, 0x0b, 0xa3, 0xbc, 0x57, 0xf4, 0xc9, 0x07, 0xdb, 0xe3, 0x06, 0x06, 0xba, + 0x64, 0x34, 0xe8, 0xad, 0x9c, 0x4d, 0x5c, 0x37, 0x4c, 0x7e, 0x23, 0x91, 0x15, 0xc4, 0xad, 0x9c, 0x98, 0x77, 0x63, 0x57, 0x85, 0x94, 0x8d, 0x9b, 0xba, 0xe9, 0x18, 0x55, 0xee, 0xac, 0xe7, 0xf7, - 0x25, 0xfc, 0x42, 0x99, 0x53, 0xab, 0x2e, 0x1f, 0xe5, 0x04, 0xa4, 0x04, 0xd4, 0x9d, 0x9a, 0x46, + 0x24, 0xfc, 0x5c, 0x99, 0x53, 0xab, 0x2e, 0x1f, 0xe5, 0x04, 0xa4, 0x04, 0xd4, 0x9d, 0x9a, 0x46, 0x50, 0x12, 0xa2, 0xe5, 0x22, 0x99, 0x9c, 0xe9, 0x0c, 0x51, 0xca, 0x95, 0xe5, 0xc8, 0xc9, 0x4f, - 0x47, 0x20, 0x29, 0xa2, 0xc7, 0x34, 0x4c, 0x16, 0x0b, 0xa5, 0xd0, 0x2c, 0x37, 0x0d, 0x13, 0x02, - 0xc8, 0xa3, 0xfc, 0x7b, 0x93, 0x7e, 0xe0, 0x86, 0xba, 0x5e, 0x59, 0x3f, 0x2b, 0xff, 0x49, 0x37, - 0xf0, 0x61, 0xf9, 0xab, 0x49, 0x34, 0x05, 0x63, 0x02, 0x78, 0xf6, 0xa1, 0xb3, 0x0f, 0xcb, 0xaf, - 0x86, 0x41, 0x8f, 0xc8, 0x5f, 0xa3, 0xdb, 0xab, 0x02, 0x74, 0x46, 0xab, 0x90, 0xa9, 0x6a, 0x7d, - 0x6d, 0xe5, 0x69, 0x59, 0xf2, 0x57, 0x9c, 0xf5, 0x55, 0x44, 0xd0, 0x31, 0x38, 0x24, 0x2a, 0x2e, - 0x5e, 0xbc, 0x78, 0xf1, 0x51, 0x5f, 0xe5, 0xcd, 0x0f, 0x26, 0xc2, 0xd5, 0x17, 0x7c, 0xd5, 0x1f, - 0xef, 0xae, 0xbe, 0xe8, 0xab, 0xfe, 0xa9, 0x0f, 0x26, 0xd0, 0x34, 0x8c, 0x8a, 0xea, 0xd5, 0xdc, - 0x53, 0xf2, 0x77, 0xbe, 0xf3, 0x9d, 0xef, 0x24, 0x4f, 0x6e, 0x82, 0xdc, 0x95, 0x92, 0xcd, 0x80, + 0x45, 0x20, 0x29, 0xa2, 0xc7, 0x34, 0x4c, 0x16, 0x0b, 0xa5, 0xd0, 0x2c, 0x37, 0x0d, 0x13, 0x02, + 0xc8, 0xa3, 0xfc, 0x7b, 0x92, 0x7e, 0xe0, 0xba, 0xba, 0x56, 0x59, 0x3b, 0x2b, 0xff, 0x49, 0x37, + 0xf0, 0x41, 0xf9, 0x6b, 0x49, 0x34, 0x05, 0x63, 0x02, 0x78, 0xf6, 0x81, 0xb3, 0x0f, 0xca, 0xaf, + 0x86, 0x41, 0x0f, 0xc9, 0x5f, 0xa7, 0xdb, 0xab, 0x02, 0x74, 0x46, 0xab, 0x90, 0xa9, 0x6a, 0x6d, + 0x75, 0xf9, 0x29, 0x59, 0xf2, 0x57, 0x9c, 0xf5, 0x55, 0x44, 0xd0, 0x11, 0x38, 0x20, 0x2a, 0x2e, + 0x5e, 0xbc, 0x78, 0xf1, 0x61, 0x5f, 0xe5, 0x8d, 0x0f, 0x24, 0xc2, 0xd5, 0x17, 0x7c, 0xd5, 0x1f, + 0xeb, 0xae, 0xbe, 0xe8, 0xab, 0xfe, 0xe9, 0x0f, 0x24, 0xd0, 0x34, 0x8c, 0x8a, 0xea, 0x95, 0xdc, + 0x93, 0xf2, 0x77, 0xbf, 0xfb, 0xdd, 0xef, 0x26, 0x4f, 0x6e, 0x80, 0xdc, 0x95, 0x92, 0xcd, 0x80, 0x1c, 0xc8, 0xc1, 0x88, 0x7a, 0x47, 0x42, 0x50, 0x9a, 0x66, 0xc9, 0x12, 0x49, 0x71, 0x7c, 0x50, - 0x96, 0x92, 0xc9, 0x91, 0xfc, 0x0f, 0xc1, 0x74, 0xd5, 0x6a, 0x86, 0x47, 0x3c, 0x2f, 0x87, 0xae, - 0x1c, 0xd9, 0x97, 0xa5, 0xb7, 0x9f, 0xe2, 0x48, 0x75, 0xab, 0xa1, 0x9b, 0xf5, 0x05, 0xab, 0x5d, - 0xf7, 0x9e, 0x2c, 0x91, 0xe5, 0xa3, 0xed, 0x7b, 0xb8, 0xd4, 0xda, 0xfa, 0x4b, 0x49, 0xfa, 0x64, - 0x24, 0xba, 0xbc, 0x91, 0xff, 0x4c, 0x24, 0xbb, 0xcc, 0x08, 0x37, 0x84, 0x3d, 0xa9, 0x78, 0xbb, - 0x81, 0xab, 0x64, 0xd0, 0xe1, 0xeb, 0x0f, 0xc0, 0x4c, 0xdd, 0xaa, 0x5b, 0x94, 0xd3, 0x69, 0xf2, - 0x17, 0x7f, 0xf3, 0x94, 0x76, 0xa1, 0xd9, 0x81, 0x0f, 0xa4, 0x16, 0xd7, 0x60, 0x9a, 0x23, 0x6b, - 0x74, 0x35, 0xcb, 0x6e, 0x45, 0xa0, 0x3d, 0x2f, 0xe7, 0x65, 0x7e, 0xf1, 0x2b, 0x74, 0x1b, 0x52, - 0x9d, 0xe2, 0xa4, 0xa4, 0x8e, 0x5d, 0x9c, 0x58, 0x54, 0xe1, 0x40, 0x80, 0x1f, 0xdb, 0x49, 0xc0, - 0xed, 0x01, 0x1c, 0x7f, 0x93, 0x73, 0x9c, 0xf6, 0x71, 0x2c, 0x73, 0xd2, 0xc5, 0x25, 0x18, 0xdf, - 0x0f, 0xaf, 0x7f, 0xc6, 0x79, 0x8d, 0x61, 0x3f, 0x93, 0x65, 0x98, 0xa4, 0x4c, 0xaa, 0x1d, 0xdb, - 0xb1, 0x9a, 0x74, 0x9b, 0x66, 0x6f, 0x36, 0xbf, 0xf5, 0x15, 0x16, 0xac, 0x27, 0x08, 0xd9, 0x92, - 0x4b, 0xb5, 0xb8, 0x08, 0x74, 0x55, 0x5e, 0xc3, 0xd5, 0xc6, 0x00, 0x0e, 0xbf, 0xcd, 0x05, 0x71, - 0xf1, 0x17, 0xaf, 0x92, 0x45, 0x5a, 0xa7, 0x49, 0x77, 0x51, 0xfc, 0x92, 0x0c, 0xbe, 0x86, 0x97, - 0xf9, 0xd2, 0x0f, 0xb3, 0xf9, 0x60, 0xda, 0x65, 0xe0, 0x93, 0xc9, 0x37, 0x8a, 0x75, 0xec, 0x38, - 0xb8, 0x6d, 0x6b, 0x7a, 0xa3, 0x97, 0x78, 0xbe, 0x7b, 0x4c, 0x99, 0x8f, 0x7e, 0x23, 0x38, 0x8a, - 0xcb, 0x8c, 0x32, 0xd7, 0x68, 0x2c, 0x6e, 0xc2, 0xa1, 0x1e, 0x56, 0x31, 0x04, 0xcf, 0x8f, 0x71, - 0x9e, 0x33, 0x5d, 0x96, 0x41, 0xd8, 0x6e, 0x80, 0x80, 0xbb, 0x63, 0x39, 0x04, 0xcf, 0x9f, 0xe0, - 0x3c, 0x11, 0xa7, 0x15, 0x43, 0x4a, 0x38, 0x5e, 0x81, 0xa9, 0xeb, 0xb8, 0xbd, 0x65, 0xd9, 0xfc, - 0xee, 0xd8, 0x10, 0xec, 0x7e, 0x92, 0xb3, 0x9b, 0xe4, 0x84, 0xf4, 0x32, 0x19, 0xe1, 0x75, 0x11, - 0x52, 0xdb, 0x7a, 0x15, 0x0f, 0xc1, 0xe2, 0x26, 0x67, 0x91, 0x24, 0xf8, 0x84, 0x34, 0x07, 0x63, - 0x75, 0x8b, 0x6f, 0xa4, 0x0d, 0x26, 0xff, 0x38, 0x27, 0x1f, 0x15, 0x34, 0x9c, 0x45, 0xcb, 0x6a, - 0x75, 0x1a, 0xba, 0x33, 0x8c, 0x04, 0x3f, 0x25, 0x58, 0x08, 0x1a, 0xce, 0x62, 0x1f, 0x6a, 0x7d, - 0x59, 0xb0, 0xb0, 0x7d, 0xfa, 0x7c, 0x1c, 0x46, 0x2d, 0xb3, 0xb1, 0x6b, 0x99, 0xc3, 0x08, 0xf1, - 0x09, 0xce, 0x01, 0x38, 0x09, 0x61, 0xf0, 0x18, 0xa4, 0x87, 0x1d, 0x88, 0xbf, 0xf3, 0x0d, 0xe1, - 0x1e, 0x62, 0x04, 0x96, 0x61, 0x52, 0x04, 0x28, 0xc3, 0x32, 0x87, 0x60, 0xf1, 0x33, 0x9c, 0xc5, - 0x84, 0x8f, 0x8c, 0x77, 0xc3, 0xc1, 0xb6, 0x53, 0xc7, 0xc3, 0x30, 0xf9, 0xb4, 0xe8, 0x06, 0x27, - 0xe1, 0xaa, 0xdc, 0xc2, 0x66, 0x75, 0x67, 0x38, 0x0e, 0x3f, 0x2b, 0x54, 0x29, 0x68, 0x08, 0x8b, - 0x25, 0x18, 0x6f, 0xea, 0x6d, 0x7b, 0x47, 0x6f, 0x0c, 0x35, 0x1c, 0x7f, 0x97, 0xf3, 0x18, 0x73, - 0x89, 0xb8, 0x46, 0x3a, 0xe6, 0x7e, 0xd8, 0x7c, 0x46, 0x68, 0xc4, 0x47, 0xc6, 0x5d, 0xcf, 0x76, - 0x68, 0x1e, 0xbf, 0x1f, 0x6e, 0x3f, 0x27, 0x5c, 0x8f, 0xd1, 0xae, 0xfa, 0x39, 0x3e, 0x06, 0x69, - 0xdb, 0x78, 0x6e, 0x28, 0x36, 0x9f, 0x15, 0x23, 0x4d, 0x09, 0x08, 0xf1, 0xd3, 0x70, 0xb8, 0xe7, - 0x34, 0x31, 0x04, 0xb3, 0x9f, 0xe7, 0xcc, 0x0e, 0xf6, 0x98, 0x2a, 0x78, 0x48, 0xd8, 0x2f, 0xcb, - 0xbf, 0x27, 0x42, 0x02, 0x0e, 0xf1, 0xda, 0x80, 0x99, 0x8e, 0x69, 0xeb, 0xdb, 0xfb, 0xd3, 0xda, - 0x2f, 0x08, 0xad, 0x31, 0xda, 0x80, 0xd6, 0x2a, 0x70, 0x90, 0x73, 0xdc, 0xdf, 0xb8, 0x7e, 0x4e, - 0x04, 0x56, 0x46, 0xbd, 0x19, 0x1c, 0xdd, 0xef, 0x83, 0xac, 0xab, 0x4e, 0x91, 0x74, 0xdb, 0x5a, - 0x53, 0x6f, 0x0d, 0xc1, 0xf9, 0x17, 0x39, 0x67, 0x11, 0xf1, 0xdd, 0xac, 0xdd, 0x5e, 0xd5, 0x5b, - 0x84, 0xf9, 0x53, 0x90, 0x11, 0xcc, 0x3b, 0x66, 0x1b, 0x57, 0xad, 0xba, 0x69, 0x3c, 0x87, 0x6b, - 0x43, 0xb0, 0xfe, 0xa5, 0xd0, 0x50, 0x6d, 0xfa, 0xc8, 0x09, 0xe7, 0x12, 0xc8, 0x6e, 0xae, 0xa2, - 0x19, 0x4d, 0x7a, 0xde, 0xb8, 0x37, 0xc7, 0x5f, 0x16, 0x23, 0xe5, 0xd2, 0x95, 0x28, 0xd9, 0x62, - 0x11, 0xd8, 0x03, 0x96, 0x61, 0x4d, 0xf2, 0xf3, 0x9c, 0xd1, 0xb8, 0x47, 0xc5, 0x03, 0x47, 0xd5, - 0x6a, 0xb6, 0xf4, 0xf6, 0x30, 0xf1, 0xef, 0xef, 0x8b, 0xc0, 0xc1, 0x49, 0x78, 0xe0, 0x20, 0x19, - 0x1d, 0x99, 0xed, 0x87, 0xe0, 0xf0, 0x2b, 0x22, 0x70, 0x08, 0x1a, 0xce, 0x42, 0x24, 0x0c, 0x43, - 0xb0, 0xf8, 0x07, 0x82, 0x85, 0xa0, 0x21, 0x2c, 0xde, 0xe6, 0x4d, 0xb4, 0x6d, 0x5c, 0x37, 0x6c, - 0x87, 0x3f, 0x31, 0xdb, 0x9b, 0xd5, 0x3f, 0xfc, 0x46, 0x30, 0x09, 0x53, 0x7d, 0xa4, 0x24, 0x12, - 0xf1, 0x8d, 0x6f, 0x7a, 0xb0, 0x33, 0x58, 0xb0, 0x5f, 0x15, 0x91, 0xc8, 0x47, 0x46, 0x64, 0xf3, - 0x65, 0x88, 0x44, 0xed, 0x55, 0xb2, 0x40, 0x1d, 0x82, 0xdd, 0x3f, 0x0a, 0x09, 0x57, 0x16, 0xb4, - 0x84, 0xa7, 0x2f, 0xff, 0xe9, 0x98, 0xd7, 0xf0, 0xee, 0x50, 0xd6, 0xf9, 0x8f, 0x43, 0xf9, 0xcf, - 0x26, 0xa3, 0x64, 0x31, 0x64, 0x32, 0x94, 0x4f, 0xa1, 0x41, 0x4f, 0x58, 0x33, 0xef, 0xfe, 0x16, - 0xef, 0x6f, 0x30, 0x9d, 0x5a, 0x5c, 0x21, 0x46, 0x1e, 0x4c, 0x7a, 0x06, 0x33, 0xfb, 0xe1, 0x6f, - 0xb9, 0x76, 0x1e, 0xc8, 0x79, 0x16, 0x2f, 0xc1, 0x78, 0x20, 0xe1, 0x19, 0xcc, 0xea, 0xbd, 0x9c, - 0xd5, 0x98, 0x3f, 0xdf, 0x59, 0x3c, 0x07, 0x31, 0x92, 0xbc, 0x0c, 0x26, 0xff, 0xbf, 0x39, 0x39, - 0x45, 0x5f, 0xfc, 0x1e, 0x48, 0x89, 0xa4, 0x65, 0x30, 0xe9, 0xfb, 0x38, 0xa9, 0x4b, 0x42, 0xc8, - 0x45, 0xc2, 0x32, 0x98, 0xfc, 0xff, 0x11, 0xe4, 0x82, 0x84, 0x90, 0x0f, 0xaf, 0xc2, 0x5f, 0xff, - 0x40, 0x8c, 0x4f, 0x3a, 0x42, 0x77, 0x8f, 0x41, 0x92, 0x67, 0x2a, 0x83, 0xa9, 0xdf, 0xcf, 0x1b, - 0x17, 0x14, 0x8b, 0x8f, 0x42, 0x7c, 0x48, 0x85, 0x7f, 0x90, 0x93, 0x32, 0xfc, 0xc5, 0x25, 0x18, - 0xf5, 0x65, 0x27, 0x83, 0xc9, 0xff, 0x3f, 0x4e, 0xee, 0xa7, 0x22, 0xa2, 0xf3, 0xec, 0x64, 0x30, - 0x83, 0x1f, 0x11, 0xa2, 0x73, 0x0a, 0xa2, 0x36, 0x91, 0x98, 0x0c, 0xa6, 0xfe, 0x90, 0xd0, 0xba, - 0x20, 0x59, 0x7c, 0x1c, 0xd2, 0xee, 0x64, 0x33, 0x98, 0xfe, 0xc3, 0x9c, 0xde, 0xa3, 0x21, 0x1a, - 0xf0, 0x4d, 0x76, 0x83, 0x59, 0xfc, 0xff, 0x42, 0x03, 0x3e, 0x2a, 0xe2, 0x46, 0xe1, 0x04, 0x66, - 0x30, 0xa7, 0x8f, 0x08, 0x37, 0x0a, 0xe5, 0x2f, 0x64, 0x34, 0x69, 0xcc, 0x1f, 0xcc, 0xe2, 0x47, - 0xc5, 0x68, 0x52, 0x7c, 0x22, 0x46, 0x38, 0x23, 0x18, 0xcc, 0xe3, 0xc7, 0x85, 0x18, 0xa1, 0x84, - 0x60, 0x71, 0x03, 0x50, 0x77, 0x36, 0x30, 0x98, 0xdf, 0x4b, 0x9c, 0xdf, 0x54, 0x57, 0x32, 0xb0, - 0xf8, 0x24, 0x1c, 0xec, 0x9d, 0x09, 0x0c, 0xe6, 0xfa, 0xd1, 0x6f, 0x85, 0xd6, 0x6e, 0xfe, 0x44, - 0x60, 0xb1, 0xe2, 0x4d, 0x29, 0xfe, 0x2c, 0x60, 0x30, 0xdb, 0x8f, 0x7d, 0x2b, 0x18, 0xb8, 0xfd, - 0x49, 0xc0, 0x62, 0x0e, 0xc0, 0x9b, 0x80, 0x07, 0xf3, 0xfa, 0x49, 0xce, 0xcb, 0x47, 0x44, 0x5c, - 0x83, 0xcf, 0xbf, 0x83, 0xe9, 0x6f, 0x0a, 0xd7, 0xe0, 0x14, 0xc4, 0x35, 0xc4, 0xd4, 0x3b, 0x98, - 0xfa, 0xe3, 0xc2, 0x35, 0x04, 0x09, 0xb1, 0x6c, 0xdf, 0xec, 0x36, 0x98, 0xc3, 0x27, 0x84, 0x65, - 0xfb, 0xa8, 0x16, 0xd7, 0x60, 0xaa, 0x6b, 0x42, 0x1c, 0xcc, 0xea, 0x93, 0x9c, 0x95, 0x1c, 0x9e, - 0x0f, 0xfd, 0x93, 0x17, 0x9f, 0x0c, 0x07, 0x73, 0xfb, 0x54, 0x68, 0xf2, 0xe2, 0x73, 0xe1, 0xe2, - 0x63, 0x90, 0x32, 0x3b, 0x8d, 0x06, 0x71, 0x1e, 0xb4, 0xf7, 0x13, 0xe3, 0xcc, 0xd7, 0xbe, 0xcd, - 0xb5, 0x23, 0x08, 0x16, 0xcf, 0x41, 0x1c, 0x37, 0xb7, 0x70, 0x6d, 0x10, 0xe5, 0xd7, 0xbf, 0x2d, - 0x02, 0x26, 0xc1, 0x5e, 0x7c, 0x1c, 0x80, 0x6d, 0x8d, 0xd0, 0x3b, 0xf6, 0x03, 0x68, 0xff, 0xf4, - 0xdb, 0xfc, 0x41, 0x9e, 0x47, 0xe2, 0x31, 0x60, 0xcf, 0xfb, 0xf6, 0x66, 0xf0, 0x8d, 0x20, 0x03, - 0x3a, 0x22, 0x17, 0x21, 0xf9, 0x8c, 0x6d, 0x99, 0x8e, 0x5e, 0x1f, 0x44, 0xfd, 0x9f, 0x38, 0xb5, - 0xc0, 0x27, 0x0a, 0x6b, 0x5a, 0x6d, 0xec, 0xe8, 0x75, 0x7b, 0x10, 0xed, 0x7f, 0xe6, 0xb4, 0x2e, - 0x01, 0x21, 0xae, 0xea, 0xb6, 0x33, 0x4c, 0xbf, 0xff, 0x4c, 0x10, 0x0b, 0x02, 0x22, 0x34, 0xf9, - 0xfb, 0x1a, 0xde, 0x1d, 0x44, 0xfb, 0x4d, 0x21, 0x34, 0xc7, 0x5f, 0xfc, 0x1e, 0x48, 0x93, 0x3f, - 0xd9, 0x43, 0xdd, 0x01, 0xc4, 0x7f, 0xce, 0x89, 0x3d, 0x0a, 0xd2, 0xb2, 0xed, 0xd4, 0x1c, 0x63, - 0xb0, 0xb2, 0x5f, 0xe3, 0x23, 0x2d, 0xf0, 0x17, 0x73, 0x30, 0x6a, 0x3b, 0xb5, 0x5a, 0x87, 0xe7, - 0xa7, 0x03, 0xc8, 0xff, 0xe2, 0xdb, 0xee, 0x96, 0x85, 0x4b, 0x43, 0x46, 0xfb, 0xd9, 0x6b, 0x4e, - 0xcb, 0xa2, 0xb7, 0xb2, 0x06, 0x71, 0xf8, 0x16, 0xe7, 0xe0, 0x23, 0x59, 0x5c, 0x82, 0x31, 0xd2, - 0x17, 0x71, 0xb9, 0x65, 0x10, 0x8b, 0xff, 0xc2, 0x15, 0x10, 0x20, 0xca, 0x7f, 0xff, 0x6f, 0xbf, - 0x32, 0x2b, 0x7d, 0xf1, 0x95, 0x59, 0xe9, 0x3f, 0xbc, 0x32, 0x2b, 0x7d, 0xe8, 0x8f, 0x67, 0x47, - 0xbe, 0xf8, 0xc7, 0xb3, 0x23, 0x7f, 0xf0, 0xc7, 0xb3, 0x23, 0xbd, 0x77, 0x89, 0x61, 0xd9, 0x5a, - 0xb6, 0xd8, 0xfe, 0xf0, 0xdb, 0x95, 0xba, 0xe1, 0xec, 0x74, 0xb6, 0x16, 0xaa, 0x56, 0x93, 0x6e, - 0xe3, 0x7a, 0xbb, 0xb5, 0xee, 0x22, 0x07, 0xde, 0x1b, 0x85, 0xd9, 0xaa, 0x65, 0x37, 0x2d, 0xfb, - 0xf4, 0x96, 0x6e, 0xe3, 0xd3, 0xd7, 0xcf, 0x6c, 0x61, 0x47, 0x3f, 0x73, 0xba, 0x6a, 0x19, 0x26, - 0xdf, 0xf6, 0x9d, 0x66, 0xf5, 0x0b, 0xa4, 0x7e, 0x81, 0xd7, 0x67, 0x7b, 0xee, 0x10, 0x2b, 0xcb, - 0x10, 0x5b, 0xb2, 0x0c, 0x7a, 0xd1, 0xbf, 0x86, 0x4d, 0xab, 0xc9, 0x1f, 0x81, 0xb2, 0x02, 0xba, - 0x1b, 0x12, 0x7a, 0xd3, 0xea, 0x98, 0x0e, 0x3b, 0x1b, 0xc9, 0x8f, 0xfe, 0xf6, 0xad, 0xb9, 0x91, - 0x3f, 0xbc, 0x35, 0x17, 0x2d, 0x99, 0x8e, 0xca, 0xab, 0x16, 0x63, 0xaf, 0xbe, 0x3c, 0x27, 0x29, - 0x57, 0x20, 0x59, 0xc0, 0xd5, 0xdb, 0xe1, 0x55, 0xc0, 0xd5, 0x10, 0xaf, 0xfb, 0x21, 0x55, 0x32, - 0x1d, 0xf6, 0x4c, 0xf7, 0x18, 0x44, 0x0d, 0x93, 0xbd, 0xee, 0x0a, 0xb5, 0x4f, 0xe0, 0x04, 0xb5, - 0x80, 0xab, 0x2e, 0x6a, 0x0d, 0x57, 0xc3, 0xa8, 0x84, 0x3d, 0x81, 0xe7, 0x0b, 0x7f, 0xf0, 0x1f, - 0x67, 0x47, 0x9e, 0x7f, 0x65, 0x76, 0xa4, 0xdf, 0xf8, 0x04, 0xd4, 0xcf, 0x55, 0xcc, 0xfe, 0x3b, - 0x65, 0xd7, 0xae, 0xb1, 0xed, 0xf9, 0xad, 0x04, 0xfb, 0x38, 0x02, 0xbc, 0x27, 0x0a, 0x87, 0x59, - 0xa5, 0xc6, 0x94, 0xca, 0x75, 0xce, 0x46, 0x60, 0xcc, 0x5f, 0x35, 0xc4, 0xde, 0xfb, 0x65, 0x98, - 0xa0, 0x16, 0x48, 0x77, 0x1d, 0xa9, 0xd3, 0x0f, 0x8c, 0xd3, 0xbf, 0xf3, 0x6f, 0xe2, 0x54, 0xbd, - 0xe3, 0x2e, 0x21, 0x7d, 0x9b, 0x54, 0x81, 0x19, 0xa3, 0xd9, 0x6a, 0x60, 0x7a, 0xc8, 0xa7, 0xb9, - 0x75, 0x83, 0xf9, 0x7d, 0x81, 0xf3, 0x9b, 0xf6, 0xc8, 0x4b, 0x82, 0x7a, 0x71, 0x05, 0xa6, 0xf4, - 0x6a, 0x15, 0xb7, 0x02, 0x2c, 0x07, 0x78, 0x87, 0x10, 0x50, 0xe6, 0x94, 0x2e, 0xb7, 0xfc, 0xe3, - 0x7d, 0x47, 0xe0, 0x5e, 0xdf, 0x08, 0xb4, 0x71, 0x1d, 0x9b, 0xa7, 0x4c, 0xec, 0x3c, 0x6b, 0xb5, - 0xaf, 0x89, 0x81, 0x60, 0x4d, 0x89, 0x41, 0xf8, 0xbd, 0x04, 0x28, 0x7c, 0xa0, 0x6c, 0x47, 0xbf, - 0x66, 0x98, 0x75, 0xd7, 0x1d, 0xf4, 0x8e, 0xb3, 0xf3, 0x1c, 0x1f, 0x8d, 0x83, 0x7c, 0x6c, 0x38, - 0x8e, 0xeb, 0x12, 0x03, 0xfc, 0x28, 0xdb, 0x7f, 0x80, 0xfb, 0x78, 0xd3, 0xef, 0x46, 0x01, 0x95, - 0x1d, 0xfd, 0x1a, 0xce, 0x75, 0x9c, 0x1d, 0xab, 0x6d, 0x3c, 0xc7, 0x62, 0x19, 0x06, 0x68, 0xea, - 0x37, 0x34, 0xc7, 0xba, 0x86, 0x4d, 0xf1, 0x44, 0xe0, 0xf0, 0x42, 0x0f, 0x27, 0x5d, 0x20, 0xfe, - 0x93, 0x7f, 0xe0, 0x33, 0x5f, 0x9e, 0xbb, 0x6f, 0xb0, 0x29, 0x52, 0x64, 0x92, 0x5c, 0xdf, 0xa8, - 0x50, 0xc6, 0xe8, 0x2a, 0xb0, 0x6b, 0xfc, 0x5a, 0xc3, 0xb0, 0x1d, 0x7e, 0xb7, 0xfc, 0xdc, 0x42, - 0xef, 0xbe, 0x2f, 0x74, 0x8b, 0xb9, 0xc0, 0x2f, 0xcd, 0x58, 0x6d, 0xfb, 0xf2, 0x88, 0x9a, 0xa6, - 0xac, 0x56, 0x0c, 0xdb, 0x41, 0x15, 0x48, 0xd7, 0xb0, 0xb9, 0xcb, 0xd8, 0x46, 0x5f, 0x1f, 0xdb, - 0x14, 0xe1, 0x44, 0xb9, 0x3e, 0x05, 0x48, 0xf7, 0xe3, 0x89, 0xaf, 0x60, 0xb1, 0xbb, 0x9c, 0x7d, - 0xd8, 0x07, 0x38, 0xd3, 0x37, 0x63, 0x53, 0x7a, 0x18, 0x94, 0x3d, 0x0e, 0xe0, 0xb5, 0x89, 0x32, - 0x90, 0xd4, 0x6b, 0xb5, 0x36, 0xb6, 0xd9, 0x5d, 0x8f, 0xb4, 0x2a, 0x8a, 0x8b, 0x53, 0xff, 0xf2, - 0xf3, 0xa7, 0xc6, 0x03, 0x1c, 0xf3, 0x63, 0x00, 0xd7, 0x5d, 0xd2, 0x93, 0x1f, 0x97, 0x60, 0xaa, - 0xab, 0x45, 0xa4, 0xc0, 0x6c, 0x6e, 0xb3, 0x72, 0x79, 0x5d, 0x2d, 0xbd, 0x9d, 0x5d, 0x27, 0xe2, - 0x17, 0x9e, 0xca, 0x1b, 0xc5, 0x25, 0xf6, 0x0d, 0x9c, 0x11, 0x34, 0x07, 0x47, 0x7a, 0xe0, 0x14, - 0x8a, 0x2b, 0xc5, 0xe5, 0x5c, 0xa5, 0x28, 0x4b, 0xe8, 0x2e, 0x38, 0xd6, 0x93, 0x89, 0x8b, 0x12, - 0xe9, 0x83, 0xa2, 0x16, 0x5d, 0x94, 0x68, 0xfe, 0x52, 0x5f, 0x47, 0x7a, 0x70, 0x4f, 0xfb, 0xb9, - 0xe1, 0xba, 0x4b, 0x30, 0xa8, 0xbd, 0x3b, 0x02, 0x87, 0xc3, 0xb1, 0x4a, 0x37, 0x77, 0xfb, 0x7c, - 0x41, 0xb1, 0x8f, 0x13, 0x5c, 0x86, 0x68, 0xce, 0xdc, 0x45, 0x87, 0x59, 0x3e, 0xad, 0x75, 0xda, - 0x0d, 0x3e, 0x11, 0x24, 0x49, 0x79, 0xb3, 0xdd, 0x08, 0xbe, 0x2a, 0x1b, 0xe3, 0xaf, 0xca, 0x16, - 0xe5, 0x97, 0x5e, 0x9e, 0x1b, 0xf9, 0xdc, 0xcb, 0x73, 0x23, 0xdf, 0xfc, 0xc4, 0xdc, 0xc8, 0xf3, - 0x7f, 0x34, 0x3f, 0x92, 0xbf, 0x16, 0xee, 0xde, 0xaf, 0x0f, 0x9c, 0x4d, 0x53, 0x39, 0x73, 0x97, - 0xce, 0x06, 0x1b, 0xd2, 0xdb, 0xe3, 0xb4, 0x73, 0xe2, 0x00, 0x75, 0x36, 0x7c, 0x80, 0xfa, 0x24, - 0x6e, 0x34, 0x9e, 0x30, 0xad, 0x67, 0xe9, 0xa8, 0x7a, 0x3a, 0xf8, 0x48, 0x04, 0x66, 0xbb, 0xe2, - 0x35, 0xcf, 0x30, 0xfa, 0x7d, 0x4a, 0x72, 0x11, 0x52, 0x05, 0x91, 0xb8, 0x64, 0x20, 0x69, 0xe3, - 0xaa, 0x65, 0xd6, 0x98, 0xa7, 0x47, 0x55, 0x51, 0x24, 0xdd, 0x36, 0x75, 0xd3, 0xb2, 0xf9, 0x97, - 0x38, 0x58, 0x21, 0xff, 0x13, 0xd2, 0xfe, 0xf2, 0x85, 0x71, 0xd1, 0x92, 0xe8, 0xe6, 0x99, 0x81, - 0x47, 0xca, 0xd7, 0x48, 0x2f, 0xdd, 0x4e, 0x04, 0x8e, 0x95, 0x87, 0xd5, 0xca, 0x8f, 0x47, 0x60, - 0x2e, 0xac, 0x15, 0x92, 0xb6, 0xd9, 0x8e, 0xde, 0x6c, 0xf5, 0x53, 0xcb, 0x63, 0x90, 0xae, 0x08, - 0x9c, 0x7d, 0xeb, 0xe5, 0xe6, 0x3e, 0xf5, 0x32, 0xe1, 0x36, 0x25, 0x14, 0x73, 0x76, 0x48, 0xc5, - 0xb8, 0xfd, 0xb8, 0x2d, 0xcd, 0x7c, 0x26, 0x06, 0xc7, 0xe8, 0xd7, 0x9e, 0xda, 0x4d, 0xc3, 0x74, - 0x4e, 0x57, 0xdb, 0xbb, 0x2d, 0x87, 0x26, 0x6e, 0xd6, 0x36, 0xd7, 0xcb, 0x94, 0x57, 0xbd, 0xc0, - 0xaa, 0xfb, 0x78, 0xce, 0x36, 0xc4, 0x37, 0x08, 0x1d, 0xd1, 0x88, 0x63, 0x39, 0x7a, 0x83, 0x6b, - 0x8a, 0x15, 0x08, 0x94, 0x7d, 0x21, 0x2a, 0xc2, 0xa0, 0x86, 0xf8, 0x38, 0x54, 0x03, 0xeb, 0xdb, - 0xec, 0x2b, 0x19, 0x51, 0xea, 0x50, 0x29, 0x02, 0xa0, 0x1f, 0xc4, 0x98, 0x81, 0xb8, 0xde, 0x61, - 0x37, 0x88, 0xa2, 0xc4, 0xd3, 0x68, 0x41, 0x79, 0x02, 0x92, 0xfc, 0x40, 0x19, 0xc9, 0x10, 0xbd, - 0x86, 0x77, 0x69, 0x3b, 0x63, 0x2a, 0xf9, 0x13, 0x2d, 0x40, 0x9c, 0x0a, 0xcf, 0x27, 0x90, 0xcc, - 0x42, 0x97, 0xf4, 0x0b, 0x54, 0x48, 0x95, 0xa1, 0x29, 0x57, 0x20, 0x55, 0xb0, 0x9a, 0x86, 0x69, - 0x05, 0xb9, 0xa5, 0x19, 0x37, 0x2a, 0x73, 0xab, 0xe3, 0x88, 0x07, 0xa4, 0xb4, 0x80, 0x0e, 0x42, - 0x82, 0x7d, 0x35, 0x85, 0xdf, 0x82, 0xe2, 0x25, 0x65, 0x09, 0x92, 0x94, 0xf7, 0x7a, 0xcb, 0xfd, - 0x9a, 0x99, 0xe4, 0xfb, 0x9a, 0x19, 0x67, 0x1f, 0xf1, 0x84, 0x45, 0x10, 0xab, 0xe9, 0x8e, 0xce, - 0xfb, 0x4d, 0xff, 0x56, 0xde, 0x0a, 0x29, 0xce, 0xc4, 0x46, 0x67, 0x21, 0x6a, 0xb5, 0xc4, 0x25, - 0xbf, 0x6c, 0xbf, 0xae, 0xac, 0xb7, 0xf2, 0x31, 0x92, 0x2e, 0xaa, 0x04, 0x39, 0xaf, 0xf6, 0x0d, - 0xaa, 0x17, 0x7c, 0x41, 0xd5, 0x37, 0xe4, 0xbe, 0x3f, 0xd9, 0x90, 0x76, 0x99, 0x83, 0x6b, 0x2c, - 0x7f, 0x25, 0xc1, 0xd1, 0x6e, 0x63, 0xb9, 0x86, 0x77, 0xed, 0xfd, 0xda, 0xca, 0x53, 0x90, 0xde, - 0xa0, 0x5f, 0x5c, 0x7d, 0x02, 0xef, 0xa2, 0x2c, 0x24, 0x71, 0xed, 0xec, 0xb9, 0x73, 0x67, 0x2e, - 0xb2, 0x91, 0xbc, 0x3c, 0xa2, 0x0a, 0xc0, 0x62, 0x8a, 0xa4, 0xd4, 0xaf, 0x7e, 0x62, 0x4e, 0xca, - 0xc7, 0x21, 0x6a, 0x77, 0x9a, 0xec, 0xca, 0xdc, 0x95, 0x58, 0x2a, 0x2a, 0xc7, 0xd4, 0xb4, 0x8d, - 0xab, 0xad, 0xb3, 0xe7, 0xce, 0x5f, 0x3b, 0xa3, 0x26, 0xed, 0x36, 0x25, 0x78, 0x43, 0xfb, 0xff, - 0xb1, 0x38, 0xcc, 0xfb, 0x29, 0xa9, 0x17, 0xba, 0x33, 0x2e, 0xd7, 0x81, 0xec, 0xd3, 0x01, 0xc5, - 0xe8, 0xad, 0x82, 0xec, 0x9e, 0x9a, 0x54, 0x7e, 0x49, 0x82, 0x31, 0x37, 0x0d, 0x28, 0x63, 0x07, - 0x3d, 0xe6, 0x9f, 0xdb, 0xb9, 0x49, 0x1c, 0x59, 0x08, 0xb7, 0xe5, 0xa5, 0x2b, 0xaa, 0x0f, 0x1d, - 0x3d, 0x0a, 0xa9, 0x56, 0xdb, 0x6a, 0x59, 0x36, 0xff, 0x90, 0xd2, 0x00, 0x52, 0x17, 0x19, 0x3d, - 0x08, 0x88, 0x7a, 0xaf, 0x76, 0xdd, 0x72, 0x0c, 0xb3, 0xae, 0xb5, 0xac, 0x67, 0xf9, 0x17, 0xee, - 0xa2, 0xaa, 0x4c, 0x6b, 0xae, 0xd2, 0x8a, 0x0d, 0x02, 0x27, 0x42, 0xa7, 0x5d, 0x2e, 0xc1, 0xd4, - 0x85, 0x18, 0xb8, 0x28, 0xa2, 0xc7, 0x20, 0xd9, 0xea, 0x6c, 0x69, 0xc2, 0x1b, 0x46, 0xcf, 0x1e, - 0xed, 0x65, 0xdb, 0xc2, 0x3e, 0xb8, 0x75, 0x27, 0x5a, 0x9d, 0x2d, 0x62, 0x2d, 0x77, 0xc1, 0x58, - 0x0f, 0x61, 0x46, 0xaf, 0x7b, 0x72, 0xd0, 0x0f, 0xfd, 0xf2, 0x1e, 0x68, 0xad, 0xb6, 0x61, 0xb5, - 0x0d, 0x67, 0x97, 0xe6, 0x66, 0x51, 0x55, 0x16, 0x15, 0x1b, 0x1c, 0xae, 0x5c, 0x83, 0xc9, 0x32, - 0x5d, 0x34, 0x78, 0x92, 0x9f, 0xf3, 0xe4, 0x93, 0x06, 0xcb, 0xd7, 0x57, 0xb2, 0x48, 0x97, 0x64, - 0xf9, 0xb7, 0xf5, 0xb5, 0xce, 0x47, 0xf7, 0x6f, 0x9d, 0xc1, 0xec, 0xe7, 0x15, 0x09, 0x66, 0x7d, - 0x95, 0xd7, 0x71, 0xdb, 0x36, 0x2c, 0x93, 0x27, 0xdb, 0xcc, 0x34, 0x91, 0xaf, 0x17, 0xbc, 0xbe, - 0x8f, 0x7f, 0x5e, 0x84, 0xf4, 0x92, 0x65, 0xda, 0xd8, 0xb4, 0x3b, 0x74, 0x86, 0xdb, 0x6a, 0x58, - 0xd5, 0x6b, 0x54, 0x19, 0x31, 0x95, 0x15, 0x48, 0x38, 0xd3, 0x5b, 0x2d, 0xda, 0xc9, 0x98, 0x4a, - 0xfe, 0x64, 0xcb, 0xdf, 0x7c, 0xb9, 0x6f, 0x17, 0x2f, 0xee, 0xbf, 0x8b, 0x5c, 0x4a, 0xb7, 0x93, - 0x2f, 0xde, 0x13, 0x88, 0x40, 0xcc, 0x03, 0xfd, 0x5d, 0x1c, 0xd6, 0xfb, 0x06, 0xa5, 0x03, 0xd9, - 0xbd, 0x67, 0xc5, 0xec, 0xc0, 0x38, 0x90, 0x1d, 0x30, 0x18, 0xca, 0x45, 0x18, 0xdf, 0xd0, 0xdb, - 0x4e, 0x19, 0x3b, 0x97, 0xb1, 0x5e, 0xc3, 0xed, 0xe0, 0xb4, 0x39, 0x2e, 0xa6, 0x4d, 0x04, 0x31, - 0x3a, 0x37, 0xb2, 0x69, 0x83, 0xfe, 0xad, 0xec, 0x40, 0x8c, 0xbe, 0x3f, 0x73, 0xa7, 0x54, 0x4e, - 0xc1, 0xa6, 0x54, 0x32, 0x5c, 0xbb, 0x0e, 0x7f, 0x9f, 0x3b, 0xa6, 0xb2, 0x02, 0x7a, 0x44, 0x4c, - 0x8c, 0xd1, 0xbd, 0x27, 0x46, 0xee, 0x6d, 0x7c, 0x7a, 0x6c, 0x40, 0x32, 0x4f, 0x46, 0xbb, 0x54, - 0x70, 0x05, 0x91, 0x3c, 0x41, 0xd0, 0x2a, 0x4c, 0xb6, 0xf4, 0xb6, 0x43, 0xbf, 0x66, 0xb3, 0x43, - 0x7b, 0xc1, 0x1d, 0x7a, 0xae, 0x3b, 0xbc, 0x04, 0x3a, 0xcb, 0x5b, 0x19, 0x6f, 0xf9, 0x81, 0xca, - 0x9f, 0xc4, 0x20, 0xc1, 0x95, 0xf1, 0x3d, 0x90, 0xe4, 0x4a, 0xe3, 0x2e, 0x78, 0x6c, 0xa1, 0xdb, - 0x78, 0x17, 0x5c, 0x1b, 0xe5, 0xfc, 0x04, 0x0d, 0x3a, 0x0e, 0xa9, 0xea, 0x8e, 0x6e, 0x98, 0x9a, - 0x51, 0x13, 0x1b, 0x36, 0xaf, 0xdc, 0x9a, 0x4b, 0x2e, 0x11, 0x58, 0xa9, 0xa0, 0x26, 0x69, 0x65, - 0xa9, 0x46, 0xa6, 0xf2, 0x1d, 0x6c, 0xd4, 0x77, 0x1c, 0x1e, 0x46, 0x78, 0x09, 0x5d, 0x80, 0x18, - 0x31, 0x08, 0x7e, 0x45, 0x3c, 0xdb, 0xb5, 0x55, 0xe0, 0x66, 0x6b, 0xf9, 0x14, 0x69, 0xf8, 0x43, - 0x5f, 0x9e, 0x93, 0x54, 0x4a, 0x81, 0x96, 0x60, 0xbc, 0xa1, 0xdb, 0x8e, 0x46, 0x9d, 0x84, 0x34, - 0x1f, 0xe7, 0x0b, 0xe6, 0x2e, 0x85, 0x70, 0xc5, 0x72, 0xd1, 0x47, 0x09, 0x15, 0x03, 0xd5, 0xd0, - 0x09, 0x90, 0x29, 0x93, 0xaa, 0xd5, 0x6c, 0x1a, 0x0e, 0x4b, 0x8e, 0x12, 0x54, 0xef, 0x13, 0x04, - 0xbe, 0x44, 0xc1, 0x34, 0x45, 0x3a, 0x02, 0x69, 0xfa, 0xc9, 0x26, 0x8a, 0xc2, 0x1e, 0x3d, 0xa6, - 0x08, 0x80, 0x56, 0xde, 0x07, 0x93, 0xde, 0x24, 0xc0, 0x50, 0x52, 0x8c, 0x8b, 0x07, 0xa6, 0x88, - 0x0f, 0xc1, 0x8c, 0x89, 0x6f, 0x38, 0x5a, 0x18, 0x3b, 0x4d, 0xb1, 0x11, 0xa9, 0xbb, 0x1a, 0xa4, - 0xb8, 0x17, 0x26, 0xaa, 0x42, 0xf9, 0x0c, 0x17, 0x28, 0xee, 0xb8, 0x0b, 0xa5, 0x68, 0x87, 0x21, - 0xa5, 0xb7, 0x5a, 0x0c, 0x61, 0x94, 0x4f, 0x02, 0xad, 0x16, 0xad, 0x3a, 0x09, 0x53, 0xb4, 0x8f, - 0x6d, 0x6c, 0x77, 0x1a, 0x0e, 0x67, 0x32, 0x46, 0x71, 0x26, 0x49, 0x85, 0xca, 0xe0, 0x14, 0xf7, - 0x6e, 0x18, 0xc7, 0xd7, 0x8d, 0x1a, 0x36, 0xab, 0x98, 0xe1, 0x8d, 0x53, 0xbc, 0x31, 0x01, 0xa4, - 0x48, 0xf7, 0x83, 0x1b, 0xdc, 0x35, 0x31, 0xf1, 0x4c, 0x30, 0x7e, 0x02, 0x9e, 0x63, 0x60, 0x25, - 0x03, 0xb1, 0x82, 0xee, 0xe8, 0x24, 0x86, 0x39, 0x37, 0xd8, 0x6c, 0x3a, 0xa6, 0x92, 0x3f, 0x95, - 0x59, 0x88, 0x57, 0x6e, 0x90, 0x60, 0x7e, 0x00, 0x12, 0xce, 0x0d, 0xcd, 0xcb, 0x2e, 0xe3, 0x0e, - 0x01, 0x2b, 0xbf, 0x16, 0x85, 0xd8, 0x55, 0xcb, 0xc1, 0xe8, 0x61, 0x5f, 0x86, 0x37, 0xd1, 0xcb, - 0xde, 0xcb, 0x46, 0xdd, 0xc4, 0xb5, 0x55, 0xbb, 0xee, 0xfb, 0x12, 0xab, 0x67, 0x6e, 0x91, 0x80, - 0xb9, 0xcd, 0x40, 0xbc, 0x6d, 0x75, 0xcc, 0x9a, 0xb8, 0xa9, 0x4d, 0x0b, 0xa8, 0x08, 0x29, 0xd7, - 0x8a, 0x62, 0x83, 0xac, 0x68, 0x92, 0x58, 0x11, 0xb1, 0x71, 0x0e, 0x50, 0x93, 0x5b, 0xdc, 0x98, - 0xf2, 0x90, 0x76, 0x83, 0x1b, 0xb7, 0xc6, 0xe1, 0x0c, 0xda, 0x23, 0x23, 0x33, 0xaa, 0x6b, 0x1b, - 0xae, 0x72, 0x99, 0x45, 0xca, 0x6e, 0x05, 0xd7, 0x6e, 0xc0, 0xec, 0xf8, 0x57, 0x61, 0x93, 0xb4, - 0x5f, 0x9e, 0xd9, 0xb1, 0x2f, 0xc3, 0x1e, 0x85, 0xb4, 0x6d, 0xd4, 0x4d, 0xfa, 0xf8, 0x81, 0x5b, - 0xa6, 0x07, 0x40, 0xf3, 0xfe, 0xef, 0x9c, 0x53, 0x4b, 0xa4, 0x5f, 0x61, 0xf0, 0x7d, 0xc4, 0xfc, - 0x61, 0x98, 0xf6, 0x3e, 0x1f, 0xee, 0x71, 0x02, 0x17, 0x17, 0xb9, 0xd5, 0x65, 0x51, 0xab, 0xfc, - 0xba, 0x04, 0x09, 0xe6, 0x40, 0xbe, 0xe1, 0x90, 0x7a, 0x0f, 0x47, 0xa4, 0xdf, 0x70, 0x44, 0x6f, - 0x7f, 0x38, 0x72, 0x00, 0xae, 0xa8, 0x36, 0xff, 0x06, 0x68, 0x8f, 0x6c, 0x8c, 0x89, 0x58, 0x36, - 0xea, 0x3c, 0x3e, 0xf8, 0x88, 0x94, 0x7f, 0x2f, 0x91, 0xe9, 0x99, 0xd7, 0xa3, 0x1c, 0x8c, 0x0b, - 0xb9, 0xb4, 0xed, 0x86, 0x5e, 0xe7, 0x26, 0x79, 0xac, 0xaf, 0x70, 0x97, 0x1a, 0x7a, 0x5d, 0x1d, - 0xe5, 0xf2, 0x90, 0x42, 0xef, 0xe1, 0x8d, 0xf4, 0x19, 0xde, 0x80, 0x3d, 0x45, 0x6f, 0xcf, 0x9e, - 0x02, 0x23, 0x1f, 0x0b, 0x8d, 0xbc, 0xf2, 0x6b, 0x31, 0xba, 0x08, 0x6a, 0x59, 0xb6, 0xde, 0xf8, - 0x6e, 0x38, 0xda, 0x11, 0x48, 0xb7, 0xac, 0x86, 0xc6, 0x6a, 0xd8, 0xc3, 0x88, 0x54, 0xcb, 0x6a, - 0xa8, 0x5d, 0xc3, 0x1e, 0xbf, 0x43, 0x5e, 0x98, 0xb8, 0x03, 0x5a, 0x4b, 0x86, 0xfd, 0xe5, 0x21, - 0x48, 0xb2, 0x88, 0x65, 0xf3, 0xef, 0xdd, 0x1f, 0xea, 0x96, 0x93, 0xc6, 0x36, 0x35, 0x41, 0x63, - 0x99, 0x8d, 0x16, 0x21, 0x25, 0x22, 0x28, 0xff, 0xf5, 0x84, 0xd9, 0x6e, 0x92, 0x22, 0xc7, 0x58, - 0x31, 0x6c, 0x47, 0x75, 0xf1, 0xd1, 0x45, 0x18, 0xf5, 0x4d, 0x51, 0xd4, 0xe7, 0x42, 0x59, 0x85, - 0xdf, 0x8e, 0x55, 0xf0, 0xe6, 0x2d, 0x74, 0x9e, 0x0c, 0x0e, 0x4d, 0x16, 0x46, 0xfb, 0x51, 0x05, - 0xb2, 0x04, 0x8e, 0xdd, 0x33, 0xc0, 0x8f, 0xf5, 0x0e, 0xf0, 0x6d, 0x18, 0x63, 0x66, 0xc1, 0xd3, - 0x89, 0x87, 0xdc, 0x26, 0xa5, 0xbd, 0x9b, 0x74, 0x1b, 0x7b, 0x08, 0x12, 0xbc, 0x6b, 0x91, 0x01, - 0x5d, 0xe3, 0x78, 0xca, 0x8f, 0x49, 0x00, 0x2b, 0xc4, 0xca, 0xe8, 0xd8, 0x93, 0x44, 0xc0, 0xa6, - 0x22, 0x68, 0x81, 0x96, 0x67, 0xfb, 0x19, 0x30, 0x6f, 0x7f, 0xcc, 0xf6, 0xcb, 0xbd, 0x04, 0xe3, - 0x9e, 0x63, 0xda, 0x58, 0x08, 0x33, 0xbb, 0xc7, 0xea, 0xad, 0x8c, 0x1d, 0x75, 0xec, 0xba, 0xaf, - 0xa4, 0xfc, 0x53, 0x09, 0xd2, 0x54, 0xa6, 0x55, 0xec, 0xe8, 0x01, 0x7b, 0x96, 0x6e, 0xdf, 0x9e, - 0x8f, 0x01, 0x30, 0x36, 0xb6, 0xf1, 0x1c, 0xe6, 0x5e, 0x96, 0xa6, 0x90, 0xb2, 0xf1, 0x1c, 0xf6, - 0x8d, 0x71, 0x74, 0x5f, 0x63, 0x7c, 0x08, 0x92, 0xf4, 0x5b, 0x04, 0x37, 0x6c, 0xbe, 0x60, 0x4b, - 0x98, 0x9d, 0x66, 0xe5, 0x86, 0xad, 0x3c, 0x03, 0xc9, 0xca, 0x0d, 0xb6, 0xbf, 0x74, 0x04, 0xd2, - 0x6d, 0xcb, 0xe2, 0x69, 0x11, 0x9b, 0x9d, 0x53, 0x04, 0x40, 0xb3, 0x00, 0xb1, 0xa7, 0x12, 0xf1, - 0xf6, 0x54, 0xbc, 0x4d, 0xa1, 0xe8, 0x70, 0x9b, 0x42, 0x5f, 0x91, 0x20, 0x25, 0xcc, 0x1e, 0xe9, - 0x70, 0xa8, 0xd6, 0x69, 0x35, 0x8c, 0x2a, 0xfd, 0x6c, 0x84, 0xe5, 0x60, 0xcd, 0xf5, 0x19, 0xa6, - 0xbe, 0xfb, 0xba, 0xbb, 0x56, 0x10, 0x04, 0x24, 0x55, 0x10, 0x9c, 0x2e, 0x8f, 0xa8, 0x07, 0x6a, - 0xbd, 0x2a, 0x90, 0x09, 0x47, 0x1b, 0xc4, 0x70, 0x34, 0xfe, 0x11, 0x5d, 0xdd, 0x71, 0xf4, 0xea, - 0x35, 0xaf, 0x1d, 0x36, 0xe8, 0x0f, 0x74, 0xb7, 0x43, 0xcd, 0x6d, 0x89, 0x12, 0xe5, 0x28, 0x8d, - 0xaf, 0xad, 0xc3, 0x8d, 0x7e, 0x95, 0x7c, 0x2b, 0x45, 0xf9, 0x50, 0x04, 0x0e, 0xf4, 0x94, 0x14, - 0x9d, 0x82, 0x04, 0xed, 0xa9, 0xce, 0xbb, 0x78, 0xb0, 0x87, 0xbd, 0x59, 0x0e, 0x56, 0xe3, 0x04, - 0x2b, 0xe7, 0xa2, 0x6f, 0x71, 0x49, 0xf7, 0x44, 0xcf, 0xef, 0x6f, 0x53, 0x21, 0x98, 0x4d, 0x30, - 0x54, 0x66, 0x19, 0x5e, 0x36, 0xc1, 0x10, 0xef, 0x40, 0x9e, 0xa3, 0xfc, 0x5e, 0x04, 0x0e, 0xf7, - 0x55, 0x2a, 0x2a, 0xc1, 0x94, 0xf8, 0x2e, 0x14, 0x91, 0xdb, 0x5b, 0x14, 0x87, 0x76, 0x08, 0x7c, - 0x83, 0x43, 0xfd, 0x46, 0x95, 0x7d, 0x64, 0x2c, 0x3a, 0xdc, 0x0d, 0xe3, 0x24, 0x6c, 0x58, 0xa6, - 0x16, 0x98, 0xa7, 0xc6, 0x18, 0xf0, 0x32, 0x9b, 0xad, 0xd6, 0x60, 0x66, 0x6b, 0xf7, 0x39, 0xdd, - 0x74, 0x0c, 0x13, 0xfb, 0x72, 0x73, 0xfe, 0x6b, 0x2d, 0x7b, 0x6e, 0xe1, 0x4c, 0xbb, 0x84, 0xbe, - 0xc3, 0xa4, 0xde, 0x8a, 0x8f, 0xf5, 0x51, 0xfc, 0x9d, 0xd0, 0xe7, 0x0a, 0x8c, 0xf9, 0xe7, 0x0f, - 0xf4, 0x16, 0xdf, 0x8c, 0xd3, 0x63, 0x5b, 0x33, 0x38, 0xe3, 0xf0, 0xd0, 0xe0, 0x52, 0x9c, 0xfc, - 0xb7, 0x12, 0x8c, 0xfa, 0x72, 0x18, 0x74, 0x06, 0x0e, 0xe4, 0x57, 0xd6, 0x97, 0x9e, 0xd0, 0x4a, - 0x05, 0xed, 0xd2, 0x4a, 0xce, 0xf7, 0x9a, 0x3d, 0x7b, 0xf0, 0xc5, 0x9b, 0xf3, 0xc8, 0x87, 0xbb, - 0x69, 0xd2, 0xdd, 0x72, 0x74, 0x1a, 0x66, 0x82, 0x24, 0xb9, 0x7c, 0xb9, 0xb8, 0x56, 0x91, 0xa5, - 0xec, 0x81, 0x17, 0x6f, 0xce, 0x4f, 0xf9, 0x28, 0x72, 0x5b, 0x36, 0x36, 0x9d, 0x6e, 0x82, 0xa5, - 0xf5, 0xd5, 0xd5, 0x52, 0x45, 0x8e, 0x74, 0x11, 0xf0, 0xd9, 0xed, 0x7e, 0x98, 0x0a, 0x12, 0xac, - 0x95, 0x56, 0xe4, 0x68, 0x16, 0xbd, 0x78, 0x73, 0x7e, 0xc2, 0x87, 0xbd, 0x66, 0x34, 0xb2, 0xa9, - 0x17, 0x3e, 0x35, 0x3b, 0xf2, 0xb3, 0x3f, 0x3d, 0x2b, 0x91, 0x9e, 0x8d, 0x07, 0xf2, 0x18, 0xf4, - 0x20, 0x1c, 0x2a, 0x97, 0x96, 0xd7, 0x8a, 0x05, 0x6d, 0xb5, 0xbc, 0x1c, 0xfa, 0x2a, 0x41, 0x76, - 0xf2, 0xc5, 0x9b, 0xf3, 0xa3, 0xbc, 0x4b, 0xfd, 0xb0, 0x37, 0xd4, 0xe2, 0xd5, 0xf5, 0x4a, 0x51, - 0x96, 0x18, 0xf6, 0x46, 0x1b, 0x13, 0xef, 0xa3, 0xd8, 0x0f, 0xc1, 0xe1, 0x1e, 0xd8, 0x6e, 0xc7, - 0xa6, 0x5e, 0xbc, 0x39, 0x3f, 0xbe, 0xd1, 0xc6, 0x6c, 0x5e, 0xa3, 0x14, 0x0b, 0x90, 0xe9, 0xa6, - 0x58, 0xdf, 0x58, 0x2f, 0xe7, 0x56, 0xe4, 0xf9, 0xac, 0xfc, 0xe2, 0xcd, 0xf9, 0x31, 0x91, 0xb0, - 0xd1, 0x43, 0x4c, 0xb7, 0x67, 0x6f, 0xe4, 0x8e, 0xd7, 0x5f, 0x9c, 0x81, 0x7b, 0xfa, 0x9c, 0x9f, - 0x8b, 0x93, 0xd7, 0xef, 0xee, 0x09, 0x7a, 0xb6, 0xff, 0xf1, 0x63, 0x76, 0xc0, 0xa9, 0xdc, 0xe0, - 0x0d, 0xa9, 0x3d, 0xf7, 0xbd, 0x94, 0xf7, 0x4b, 0x30, 0x71, 0xd9, 0xb0, 0x1d, 0xab, 0x6d, 0x54, - 0xf5, 0x06, 0x7d, 0x95, 0x7c, 0x7e, 0xd8, 0x9c, 0x27, 0x34, 0x05, 0x3f, 0x0e, 0x89, 0xeb, 0x7a, - 0x83, 0x25, 0x1b, 0x51, 0xfa, 0x69, 0xfd, 0x3e, 0xc7, 0xd9, 0x6e, 0x64, 0x11, 0x0c, 0x18, 0x99, - 0xf2, 0x0b, 0x11, 0x98, 0xa4, 0xce, 0x60, 0xb3, 0xdf, 0x96, 0x71, 0xe8, 0x9b, 0xf9, 0x58, 0x5b, - 0x77, 0xf8, 0x81, 0x48, 0x7e, 0x81, 0x5f, 0x6f, 0x39, 0x3e, 0xc4, 0x3d, 0x81, 0x02, 0xae, 0xaa, - 0x94, 0x16, 0xbd, 0x03, 0x52, 0x4d, 0xfd, 0x86, 0x46, 0xf9, 0xb0, 0x4d, 0x9d, 0xdc, 0xfe, 0xf8, - 0xbc, 0x76, 0x6b, 0x6e, 0x72, 0x57, 0x6f, 0x36, 0x16, 0x15, 0xc1, 0x47, 0x51, 0x93, 0x4d, 0xfd, - 0x06, 0x11, 0x11, 0xb5, 0xe8, 0x97, 0x0b, 0xb4, 0xea, 0x8e, 0x6e, 0xd6, 0x31, 0x6b, 0x84, 0x1e, - 0xef, 0xe4, 0x2f, 0xef, 0xbb, 0x91, 0x83, 0x5e, 0x23, 0x3e, 0x76, 0x8a, 0x3a, 0xde, 0xd4, 0x6f, - 0x2c, 0x51, 0x00, 0x69, 0x71, 0x31, 0xf5, 0xd2, 0xcb, 0x73, 0x23, 0xf4, 0xca, 0xd0, 0x97, 0x24, - 0x00, 0x4f, 0x63, 0xe8, 0x1d, 0x20, 0x57, 0xdd, 0x12, 0xa5, 0xb5, 0xdd, 0x5c, 0xa3, 0xcf, 0x58, - 0x84, 0xf4, 0xcd, 0xa2, 0xf1, 0x17, 0x6f, 0xcd, 0x49, 0xea, 0x64, 0x35, 0x34, 0x14, 0xdf, 0x07, - 0xa3, 0x9d, 0x56, 0x8d, 0x64, 0x33, 0x74, 0x8b, 0x2b, 0x32, 0x30, 0xb2, 0xcf, 0x12, 0x5e, 0xaf, - 0xdd, 0x9a, 0x43, 0xac, 0x5b, 0x3e, 0x62, 0x85, 0xc6, 0x7b, 0x60, 0x10, 0x42, 0xe0, 0xeb, 0xd3, - 0xef, 0xd0, 0x5f, 0x05, 0xf2, 0xee, 0x8b, 0x67, 0x20, 0xd9, 0xb4, 0x4c, 0xe3, 0x1a, 0xb7, 0xc7, - 0xb4, 0x2a, 0x8a, 0x28, 0x0b, 0x29, 0xf6, 0x35, 0x31, 0x67, 0x57, 0xfc, 0x04, 0x8d, 0x28, 0x13, - 0xaa, 0x67, 0xf1, 0x96, 0x6d, 0x88, 0xd1, 0x50, 0x45, 0x11, 0x5d, 0x02, 0xd9, 0xc6, 0xd5, 0x4e, - 0xdb, 0x70, 0x76, 0xb5, 0xaa, 0x65, 0x3a, 0x7a, 0x95, 0x7d, 0x27, 0x30, 0x9d, 0x3f, 0xf2, 0xda, - 0xad, 0xb9, 0x43, 0x4c, 0xd6, 0x30, 0x86, 0xa2, 0x4e, 0x0a, 0xd0, 0x12, 0x83, 0x90, 0x16, 0x6a, - 0xd8, 0xd1, 0x8d, 0x06, 0xfb, 0x8c, 0x43, 0x5a, 0x15, 0x45, 0x5f, 0x5f, 0x3e, 0x9b, 0xf4, 0x1f, - 0x6c, 0x5c, 0x02, 0xd9, 0x6a, 0xe1, 0x76, 0x60, 0xb1, 0x2c, 0x85, 0x5b, 0x0e, 0x63, 0x28, 0xea, - 0xa4, 0x00, 0x89, 0x85, 0xb4, 0x43, 0x86, 0x59, 0xec, 0xa1, 0xb5, 0x3a, 0x5b, 0xde, 0x79, 0xc8, - 0x4c, 0xd7, 0x68, 0xe4, 0xcc, 0xdd, 0xfc, 0xc3, 0x1e, 0xf7, 0x30, 0x9d, 0xf2, 0x85, 0xcf, 0x9f, - 0x9a, 0xe1, 0xa6, 0xe1, 0x9d, 0x4f, 0x90, 0xb5, 0xde, 0xa4, 0x8b, 0xba, 0x41, 0x31, 0xc9, 0xd2, - 0xf8, 0x19, 0xdd, 0x68, 0x88, 0x8f, 0x63, 0xaa, 0xbc, 0x84, 0x16, 0x21, 0x61, 0x3b, 0xba, 0xd3, - 0xb1, 0xf9, 0x2d, 0x16, 0xa5, 0x9f, 0xa9, 0xe5, 0x2d, 0xb3, 0x56, 0xa6, 0x98, 0x2a, 0xa7, 0x40, - 0x97, 0x20, 0xc1, 0xaf, 0x07, 0xc5, 0xf7, 0xed, 0xdf, 0xf4, 0x32, 0x1e, 0xa3, 0x26, 0x1a, 0xa9, - 0xe1, 0x06, 0xae, 0xb3, 0xe5, 0xce, 0x8e, 0xde, 0xc6, 0x6c, 0x97, 0x29, 0x9d, 0x2f, 0xed, 0xdb, - 0x09, 0xb9, 0xa6, 0xc2, 0xfc, 0x14, 0x75, 0xd2, 0x05, 0x95, 0x29, 0x04, 0x3d, 0x11, 0x78, 0xd8, - 0xc0, 0x3f, 0xdb, 0x79, 0x77, 0xbf, 0xee, 0xfb, 0x6c, 0x5a, 0x6c, 0xdd, 0xfa, 0x9f, 0x45, 0x5c, - 0x02, 0xb9, 0x63, 0x6e, 0x59, 0x26, 0xfd, 0xac, 0x05, 0xcf, 0xed, 0x52, 0x24, 0xc3, 0xf2, 0x1b, - 0x47, 0x18, 0x43, 0x51, 0x27, 0x5d, 0x10, 0xcf, 0xfd, 0x6a, 0x30, 0xe1, 0x61, 0x51, 0x47, 0x4d, - 0x0f, 0x74, 0xd4, 0xbb, 0xb8, 0xa3, 0x1e, 0x08, 0xb7, 0xe2, 0xf9, 0xea, 0xb8, 0x0b, 0x24, 0x64, - 0xe8, 0x32, 0x80, 0x17, 0x1e, 0xf8, 0x22, 0x5e, 0x19, 0x1c, 0x63, 0xc4, 0x9e, 0x94, 0x47, 0x8b, - 0x7e, 0x00, 0xa6, 0x9b, 0x86, 0xa9, 0xd9, 0xb8, 0xb1, 0xad, 0x71, 0x05, 0x13, 0x96, 0xf4, 0x47, - 0x23, 0xf2, 0x2b, 0xfb, 0xb3, 0x87, 0xd7, 0x6e, 0xcd, 0x65, 0x79, 0x08, 0xed, 0x66, 0xa9, 0xa8, - 0x53, 0x4d, 0xc3, 0x2c, 0xe3, 0xc6, 0x76, 0xc1, 0x85, 0x2d, 0x8e, 0xbd, 0xf0, 0xf2, 0xdc, 0x08, - 0x77, 0xd7, 0x11, 0xe5, 0x3c, 0x3d, 0x3b, 0xe5, 0x6e, 0x86, 0x6d, 0x74, 0x14, 0xd2, 0xba, 0x28, - 0xf0, 0x6b, 0x54, 0x1e, 0x80, 0xb9, 0xf9, 0xf3, 0x7f, 0x34, 0x2f, 0x29, 0x9f, 0x95, 0x20, 0x51, - 0xb8, 0xba, 0xa1, 0x1b, 0x6d, 0x92, 0xea, 0x7b, 0x96, 0x13, 0x74, 0xf2, 0xa3, 0xaf, 0xdd, 0x9a, - 0xcb, 0x84, 0x8d, 0xcb, 0xf5, 0x72, 0xcf, 0x80, 0x85, 0x9b, 0x97, 0xfa, 0x6d, 0xae, 0x05, 0x58, - 0x75, 0xa1, 0x28, 0xdd, 0x5b, 0x6f, 0xa1, 0x6e, 0x16, 0x21, 0xc9, 0xa4, 0xb5, 0xd1, 0x22, 0xc4, - 0x5b, 0xe4, 0x0f, 0x9e, 0x54, 0xcf, 0xf6, 0x35, 0x5e, 0x8a, 0xef, 0x9e, 0xf1, 0x10, 0x12, 0xe5, - 0xc3, 0x11, 0x80, 0xc2, 0xd5, 0xab, 0x95, 0xb6, 0xd1, 0x6a, 0x60, 0xe7, 0x4e, 0xf6, 0xbc, 0x02, - 0x07, 0x7c, 0xbb, 0x17, 0xed, 0x6a, 0xa8, 0xf7, 0xf3, 0xaf, 0xdd, 0x9a, 0x3b, 0x1a, 0xee, 0xbd, - 0x0f, 0x4d, 0x51, 0xa7, 0xbd, 0x7d, 0x8c, 0x76, 0xb5, 0x27, 0xd7, 0x9a, 0xed, 0xb8, 0x5c, 0xa3, - 0xfd, 0xb9, 0xfa, 0xd0, 0xfc, 0x5c, 0x0b, 0xb6, 0xd3, 0x5b, 0xb5, 0x65, 0x18, 0xf5, 0x54, 0x62, - 0xa3, 0x02, 0xa4, 0x1c, 0xfe, 0x37, 0xd7, 0xb0, 0xd2, 0x5f, 0xc3, 0x82, 0x4c, 0x2c, 0x5f, 0x04, - 0xa5, 0xf2, 0x97, 0x12, 0x80, 0x67, 0xb3, 0x6f, 0x4e, 0x13, 0x23, 0xa1, 0x9c, 0x07, 0xde, 0xe8, - 0x6d, 0xa5, 0x6a, 0x9c, 0x3a, 0xa4, 0xcf, 0x0f, 0x44, 0x60, 0x7a, 0x53, 0x44, 0x9e, 0x37, 0xbd, - 0x0e, 0x36, 0x20, 0x89, 0x4d, 0xa7, 0x6d, 0x60, 0xb1, 0xd4, 0x7e, 0xa8, 0xdf, 0x68, 0xf7, 0xe8, - 0x13, 0xfd, 0x69, 0x0c, 0x71, 0x1e, 0xc9, 0xd9, 0x84, 0xb4, 0xf1, 0x23, 0x51, 0xc8, 0xf4, 0xa3, - 0x44, 0x4b, 0x30, 0x59, 0x6d, 0x63, 0x76, 0xa9, 0xd4, 0x7f, 0x3a, 0x91, 0xcf, 0x7a, 0x99, 0x65, - 0x08, 0x41, 0x51, 0x27, 0x04, 0x84, 0xcf, 0x1e, 0x75, 0x20, 0x69, 0x1f, 0x31, 0x3b, 0x7a, 0x37, - 0x75, 0xb8, 0x3c, 0x4f, 0xe1, 0xd3, 0x87, 0x68, 0x24, 0xc8, 0x80, 0xcd, 0x1f, 0x13, 0x1e, 0x94, - 0x4e, 0x20, 0xef, 0x84, 0x49, 0xc3, 0x34, 0x1c, 0x43, 0x6f, 0x68, 0x5b, 0x7a, 0x43, 0x27, 0xeb, - 0xfa, 0xfd, 0x67, 0xcd, 0x2c, 0xe4, 0xf3, 0x66, 0x43, 0xec, 0x14, 0x75, 0x82, 0x43, 0xf2, 0x0c, - 0x80, 0x2e, 0x43, 0x52, 0x34, 0x15, 0xbb, 0xad, 0x6c, 0x43, 0x90, 0xfb, 0x12, 0xbc, 0x0f, 0x46, - 0x61, 0x4a, 0xc5, 0xb5, 0xff, 0x33, 0x14, 0xfb, 0x1b, 0x8a, 0x55, 0x00, 0xe6, 0xee, 0x24, 0xc0, - 0xde, 0xc6, 0x68, 0x90, 0x80, 0x91, 0x66, 0x1c, 0x0a, 0xb6, 0xe3, 0x1b, 0x8f, 0x5b, 0x11, 0x18, - 0xf3, 0x8f, 0xc7, 0xdf, 0xd2, 0x59, 0x09, 0x95, 0xbc, 0x48, 0x14, 0xe3, 0xbf, 0x57, 0xd8, 0x27, - 0x12, 0x75, 0x59, 0xef, 0xde, 0x21, 0xe8, 0xbf, 0x26, 0x20, 0xb1, 0xa1, 0xb7, 0xf5, 0xa6, 0x8d, - 0xaa, 0x5d, 0x99, 0xa6, 0x38, 0x16, 0xe8, 0xfa, 0xa5, 0x62, 0xbe, 0x65, 0x31, 0x20, 0xd1, 0x7c, - 0xa9, 0x47, 0xa2, 0xf9, 0xbd, 0x30, 0x41, 0x96, 0xc3, 0xbe, 0x4d, 0x4c, 0xa2, 0xed, 0xf1, 0xfc, - 0x61, 0x8f, 0x4b, 0xb0, 0x9e, 0xad, 0x96, 0xaf, 0xfa, 0xef, 0xb0, 0x8d, 0x12, 0x0c, 0x2f, 0x30, - 0x13, 0xf2, 0x83, 0xde, 0xb2, 0xd4, 0x57, 0xa9, 0xa8, 0xd0, 0xd4, 0x6f, 0x14, 0x59, 0x01, 0xad, - 0x00, 0xda, 0x71, 0x77, 0x46, 0x34, 0x4f, 0x9d, 0x84, 0xfe, 0xd8, 0x6b, 0xb7, 0xe6, 0x0e, 0x33, - 0xfa, 0x6e, 0x1c, 0x45, 0x9d, 0xf2, 0x80, 0x82, 0xdb, 0x23, 0x00, 0xa4, 0x5f, 0x1a, 0x7b, 0x23, - 0xc4, 0x96, 0x3b, 0x07, 0x5e, 0xbb, 0x35, 0x37, 0xc5, 0xb8, 0x78, 0x75, 0x8a, 0x9a, 0x26, 0x85, - 0x02, 0x7d, 0x3e, 0xc4, 0xb3, 0xe3, 0xd0, 0xaa, 0x9e, 0xaf, 0x6d, 0x56, 0xf6, 0xbd, 0xb6, 0xf1, - 0x65, 0xc7, 0x21, 0x96, 0x2c, 0x3b, 0x0e, 0xee, 0x06, 0xa0, 0x8f, 0x4b, 0x70, 0x90, 0x6a, 0xd7, - 0xb7, 0xed, 0xab, 0xd1, 0xa1, 0x64, 0xbf, 0xe8, 0x9a, 0x37, 0xf6, 0x27, 0xc1, 0xd7, 0x6f, 0xcd, - 0xf5, 0xe1, 0xf7, 0xda, 0xad, 0xb9, 0x63, 0xbe, 0xd1, 0xec, 0xaa, 0x57, 0xd4, 0x69, 0x32, 0xaa, - 0xde, 0x2e, 0xb3, 0x4a, 0xa0, 0xe8, 0x96, 0x04, 0xc7, 0xbb, 0x08, 0xf8, 0xe7, 0x76, 0x9b, 0xd8, - 0x74, 0x34, 0x67, 0xa7, 0x8d, 0xed, 0x1d, 0xab, 0x51, 0x63, 0x9f, 0xec, 0xce, 0xbf, 0x5f, 0xda, - 0x5f, 0x4c, 0xfb, 0xfa, 0xad, 0xb9, 0x21, 0x1b, 0x78, 0xed, 0xd6, 0xdc, 0xa9, 0x3e, 0x3d, 0xe8, - 0x89, 0xaf, 0xa8, 0x4a, 0xb0, 0x47, 0x45, 0x0f, 0xab, 0x22, 0x90, 0x7c, 0x91, 0xed, 0x53, 0x12, - 0x20, 0x6f, 0xca, 0x57, 0xb1, 0xdd, 0x22, 0xeb, 0x73, 0xb2, 0x10, 0xf3, 0xad, 0x9a, 0xa4, 0xbd, - 0x17, 0x62, 0x1e, 0xbd, 0x58, 0x88, 0xf9, 0x22, 0xe5, 0x45, 0x6f, 0x7a, 0x8c, 0x0c, 0x7a, 0xab, - 0xc3, 0x43, 0x44, 0x78, 0x3e, 0x1c, 0x51, 0xfe, 0xb9, 0x04, 0x87, 0xbb, 0x22, 0x8a, 0x2b, 0xec, - 0xff, 0x05, 0xa8, 0xed, 0xab, 0xe4, 0xbf, 0x0e, 0xc6, 0x84, 0xde, 0x77, 0x80, 0x9a, 0x6a, 0x77, - 0xcd, 0xbb, 0x77, 0x6e, 0x86, 0x67, 0x2f, 0xf2, 0x7e, 0x4d, 0x82, 0x19, 0x7f, 0xf3, 0x6e, 0x47, - 0xd6, 0x60, 0xcc, 0xdf, 0x3a, 0xef, 0xc2, 0x3d, 0xc3, 0x74, 0x81, 0x4b, 0x1f, 0xa0, 0x47, 0x6f, - 0xf3, 0xc2, 0x35, 0xdb, 0x3b, 0x3d, 0x33, 0xb4, 0x36, 0x84, 0x4c, 0xe1, 0xb0, 0x1d, 0xa3, 0xe3, - 0xf1, 0x1d, 0x09, 0x62, 0x1b, 0x96, 0xd5, 0x40, 0x16, 0x4c, 0x99, 0x96, 0xa3, 0x91, 0xc8, 0x82, - 0x6b, 0xfe, 0x37, 0x59, 0xe9, 0xfc, 0xd2, 0xbe, 0x5d, 0xa2, 0x9b, 0x95, 0x3a, 0x69, 0x5a, 0x4e, - 0x9e, 0x42, 0xf8, 0xb3, 0xac, 0x1f, 0x80, 0xf1, 0x60, 0x63, 0x6c, 0x96, 0x7c, 0x72, 0xdf, 0x8d, - 0x05, 0xd9, 0xbc, 0x76, 0x6b, 0x6e, 0xc6, 0x8b, 0x98, 0x2e, 0x58, 0x51, 0xc7, 0xb6, 0x7c, 0xad, - 0xb3, 0xeb, 0xdf, 0xdf, 0x7c, 0x79, 0x4e, 0x3a, 0xf9, 0x2b, 0x12, 0x80, 0xb7, 0xf3, 0x84, 0x1e, - 0x84, 0x43, 0xf9, 0xf5, 0xb5, 0x82, 0x56, 0xae, 0xe4, 0x2a, 0x9b, 0xe5, 0xe0, 0xfb, 0x25, 0x71, - 0x3c, 0x62, 0xb7, 0x70, 0x95, 0xfe, 0x30, 0x19, 0x3a, 0x0e, 0x33, 0x41, 0x6c, 0x52, 0x2a, 0x16, - 0x64, 0x29, 0x3b, 0xf6, 0xe2, 0xcd, 0xf9, 0x14, 0xcb, 0xc5, 0x71, 0x0d, 0x9d, 0x80, 0x03, 0xdd, - 0x78, 0xa5, 0xb5, 0x65, 0x39, 0x92, 0x1d, 0x7f, 0xf1, 0xe6, 0x7c, 0xda, 0x4d, 0xda, 0x91, 0x02, - 0xc8, 0x8f, 0xc9, 0xf9, 0x45, 0xb3, 0xf0, 0xe2, 0xcd, 0xf9, 0x04, 0x53, 0x60, 0x36, 0xf6, 0xc2, - 0xa7, 0x66, 0x47, 0xee, 0xf8, 0x2b, 0xa7, 0x3f, 0x4f, 0xf6, 0x3d, 0xf5, 0xa8, 0x63, 0x13, 0xdb, - 0x86, 0x3d, 0xe0, 0xd4, 0x63, 0xa8, 0x33, 0x93, 0x3e, 0xf7, 0x82, 0x7f, 0x3f, 0x0e, 0x63, 0xcb, - 0xac, 0x15, 0xf6, 0x7b, 0xea, 0x6f, 0x81, 0x44, 0x8b, 0xa6, 0x11, 0xee, 0xf5, 0x86, 0x3e, 0x06, - 0xcf, 0x92, 0x0d, 0xf7, 0x2e, 0x37, 0x4b, 0x3d, 0x6c, 0x7e, 0xcf, 0x91, 0x9d, 0x4a, 0x7a, 0xb7, - 0xa6, 0xc7, 0xf6, 0xb5, 0xdf, 0xc7, 0x72, 0x56, 0xbe, 0xb5, 0x16, 0xe6, 0xa7, 0xb0, 0x2b, 0x93, - 0x15, 0x02, 0x61, 0xe7, 0x9a, 0xef, 0x95, 0xe0, 0x00, 0xc5, 0x0a, 0x1d, 0x2b, 0x8b, 0xc5, 0xde, - 0xc9, 0x7e, 0x5d, 0x58, 0xd1, 0x6d, 0xef, 0x1a, 0x24, 0xbb, 0xcf, 0x7d, 0x0f, 0x4f, 0x84, 0x8e, - 0xfa, 0x1a, 0x0f, 0xb3, 0x55, 0xd4, 0xe9, 0x46, 0x17, 0xa5, 0x8d, 0x96, 0x03, 0x17, 0xfa, 0x63, - 0xfb, 0x3b, 0x6a, 0xf1, 0x5f, 0xee, 0xbf, 0x02, 0xa3, 0x5e, 0x2c, 0xb1, 0xe9, 0xef, 0x3e, 0xef, - 0x67, 0xee, 0xf0, 0x13, 0xa3, 0xf7, 0x49, 0x70, 0xc0, 0xcb, 0xe6, 0xfc, 0x6c, 0x13, 0x94, 0xed, - 0x03, 0xfb, 0x58, 0x08, 0x87, 0x95, 0xd3, 0x93, 0xaf, 0xa2, 0xce, 0x74, 0xba, 0x49, 0xc9, 0x12, - 0x7c, 0xdc, 0x1f, 0x59, 0xed, 0x8c, 0xf8, 0x0d, 0x96, 0xe1, 0x43, 0x73, 0x90, 0x01, 0xfb, 0xa1, - 0xfb, 0x96, 0xd5, 0x76, 0x30, 0x4b, 0x22, 0x52, 0xaa, 0x5b, 0x56, 0xd6, 0x00, 0x75, 0x0f, 0x6e, - 0xf8, 0x01, 0x83, 0xf7, 0xf6, 0x12, 0xcd, 0x40, 0xdc, 0x7f, 0xc5, 0x9f, 0x15, 0x16, 0x53, 0x2f, - 0xf0, 0xe9, 0xf3, 0x8e, 0xfb, 0xfc, 0x97, 0x23, 0x70, 0xd2, 0x7f, 0x56, 0xf9, 0xce, 0x0e, 0x6e, - 0xef, 0xba, 0x8e, 0xdb, 0xd2, 0xeb, 0x86, 0xe9, 0x7f, 0xe1, 0x77, 0xd8, 0x3f, 0xe1, 0x53, 0x5c, - 0xa1, 0x27, 0xe5, 0x05, 0x09, 0x46, 0x37, 0xf4, 0x3a, 0x56, 0xf1, 0x3b, 0x3b, 0xd8, 0x76, 0x7a, - 0xbc, 0xa0, 0x3a, 0x08, 0x09, 0x6b, 0x7b, 0x5b, 0xdc, 0x35, 0x8a, 0xa9, 0xbc, 0x44, 0xfa, 0xdc, - 0x30, 0x9a, 0x06, 0xbb, 0x29, 0x1d, 0x53, 0x59, 0x01, 0xcd, 0xc1, 0x68, 0xd5, 0xea, 0x98, 0xdc, - 0xe5, 0x32, 0x31, 0xf1, 0x1d, 0xb1, 0x8e, 0xc9, 0x5c, 0x8e, 0x28, 0xb1, 0x8d, 0xaf, 0xe3, 0xb6, - 0xcd, 0x7e, 0xde, 0x25, 0xa5, 0x8a, 0xa2, 0xf2, 0x38, 0x8c, 0x31, 0x49, 0xf8, 0x64, 0x7c, 0x18, - 0x52, 0xf4, 0x12, 0xb2, 0x27, 0x4f, 0x92, 0x94, 0x9f, 0x60, 0xef, 0xb0, 0x18, 0x7f, 0x26, 0x12, - 0x2b, 0xe4, 0xf3, 0x7d, 0xb5, 0x7c, 0x62, 0x70, 0xd4, 0x60, 0x3a, 0x74, 0x35, 0xfc, 0x9b, 0x71, - 0x38, 0xc0, 0x4f, 0x60, 0xf5, 0x96, 0x71, 0x7a, 0xc7, 0x71, 0xc4, 0xbb, 0x40, 0xe0, 0xab, 0x20, - 0xbd, 0x65, 0x28, 0xbb, 0x10, 0xbb, 0xec, 0x38, 0x2d, 0x74, 0x12, 0xe2, 0xed, 0x4e, 0x03, 0x8b, - 0xcd, 0x40, 0xf7, 0xb8, 0x46, 0x6f, 0x19, 0x0b, 0x04, 0x41, 0xed, 0x34, 0xb0, 0xca, 0x50, 0x50, - 0x11, 0xe6, 0xb6, 0x3b, 0x8d, 0xc6, 0xae, 0x56, 0xc3, 0xf4, 0xeb, 0xd3, 0xee, 0xaf, 0xb4, 0xe3, - 0x1b, 0x2d, 0x5d, 0xfc, 0x6e, 0x0c, 0x51, 0xcc, 0x51, 0x8a, 0x56, 0xa0, 0x58, 0xe2, 0xe7, 0xd5, - 0x8b, 0x02, 0x47, 0xf9, 0xc3, 0x08, 0xa4, 0x04, 0x6b, 0x62, 0xcb, 0x36, 0x6e, 0xe0, 0xaa, 0x63, - 0x89, 0xc3, 0x34, 0xb7, 0x8c, 0x10, 0x44, 0xeb, 0x7c, 0xf0, 0xd2, 0x97, 0x47, 0x54, 0x52, 0x20, - 0x30, 0xf7, 0xb9, 0x1a, 0x81, 0xb5, 0x3a, 0x64, 0x3c, 0x63, 0x2d, 0x4b, 0xac, 0xda, 0x2f, 0x8f, - 0xa8, 0xb4, 0x84, 0x32, 0x90, 0x20, 0x4e, 0xe3, 0xb0, 0xd1, 0x22, 0x70, 0x5e, 0x46, 0x07, 0x21, - 0xde, 0xd2, 0x9d, 0x2a, 0xbb, 0x88, 0x4e, 0x2a, 0x58, 0x11, 0x3d, 0x0a, 0x09, 0xf6, 0xc5, 0x11, - 0xea, 0x55, 0xbe, 0x1f, 0xed, 0x27, 0xca, 0x60, 0x9f, 0x76, 0x25, 0x72, 0x6f, 0xe8, 0x8e, 0x83, - 0xdb, 0x26, 0x61, 0xc8, 0xd0, 0x11, 0x82, 0xd8, 0x96, 0x55, 0x63, 0xbf, 0x2a, 0x9b, 0x56, 0xe9, - 0xdf, 0xfc, 0x57, 0xec, 0xa9, 0x3d, 0x68, 0xb4, 0x72, 0x8c, 0x7d, 0xa2, 0x42, 0x00, 0xf3, 0x04, - 0xa9, 0x08, 0xd3, 0x7a, 0x8d, 0x7d, 0x31, 0x5a, 0x6f, 0x68, 0x5b, 0x06, 0x0d, 0x1e, 0x76, 0x66, - 0x74, 0x8f, 0xb1, 0x40, 0x1e, 0x41, 0x9e, 0xe3, 0xe7, 0xd3, 0x90, 0x6c, 0x31, 0xa1, 0x94, 0xc7, - 0x60, 0xaa, 0x4b, 0x52, 0x22, 0xdf, 0x35, 0xc3, 0xac, 0x89, 0x37, 0x7c, 0xe4, 0x6f, 0x02, 0xa3, - 0xdf, 0xe2, 0x66, 0xc7, 0x94, 0xf4, 0xef, 0xfc, 0x7b, 0xfa, 0x3f, 0xf5, 0x9c, 0xf0, 0x3d, 0xf5, - 0xd4, 0x5b, 0x46, 0x3e, 0x4d, 0xf9, 0xf3, 0x07, 0x9e, 0xb9, 0xee, 0x07, 0x9e, 0x75, 0x6c, 0x8a, - 0x29, 0x97, 0x54, 0xe9, 0x2d, 0xc3, 0xa6, 0xe6, 0xe8, 0x7d, 0x1c, 0xdc, 0x7e, 0xcc, 0xf7, 0x37, - 0x7d, 0xef, 0x19, 0x5b, 0xce, 0x6d, 0x94, 0x5c, 0x3b, 0xfe, 0x8d, 0x08, 0x1c, 0xf5, 0xd9, 0xb1, - 0x0f, 0xb9, 0xdb, 0x9c, 0xb3, 0xbd, 0x2d, 0x7e, 0x88, 0x0f, 0x3e, 0x3c, 0x01, 0x31, 0x82, 0x8f, - 0x06, 0xfc, 0x40, 0x7c, 0xe6, 0x73, 0x5f, 0xf8, 0x27, 0x4a, 0xf0, 0x40, 0x33, 0x30, 0x2a, 0x94, - 0x49, 0xfe, 0x7d, 0xc3, 0xeb, 0x4f, 0xf6, 0x3e, 0x3a, 0x6e, 0xdf, 0x39, 0x35, 0x86, 0x75, 0xf8, - 0x95, 0x73, 0x7d, 0xbf, 0xcb, 0xc0, 0x82, 0xe9, 0xde, 0xf9, 0xd5, 0x3e, 0x22, 0xf5, 0xeb, 0xc9, - 0xc5, 0xb2, 0x7b, 0x8e, 0xb3, 0x72, 0x03, 0x0e, 0xbe, 0x8d, 0xb4, 0xed, 0xed, 0xa0, 0x88, 0x90, - 0x7f, 0xd0, 0x3d, 0xe8, 0x65, 0x96, 0xed, 0x1d, 0xe2, 0x82, 0x27, 0x1f, 0x5f, 0x3b, 0x1e, 0x5f, - 0xe8, 0x3b, 0x95, 0x2c, 0xf8, 0xa6, 0x11, 0xd5, 0x47, 0xa9, 0xfc, 0x9c, 0x04, 0x87, 0xba, 0x9a, - 0xe6, 0x31, 0x7e, 0xb9, 0xc7, 0x2b, 0xc6, 0xdb, 0x4a, 0x7a, 0x96, 0x7b, 0x08, 0x7b, 0xdf, 0x40, - 0x61, 0x99, 0x14, 0x01, 0x69, 0xdf, 0x0a, 0x07, 0x82, 0xc2, 0x0a, 0x35, 0xdd, 0x0b, 0x13, 0xc1, - 0xc3, 0x02, 0xae, 0xae, 0xf1, 0xc0, 0x71, 0x81, 0xa2, 0x85, 0xf5, 0xec, 0xf6, 0xb5, 0x08, 0x69, - 0x17, 0x95, 0x67, 0xc7, 0x43, 0x77, 0xd5, 0xa3, 0x54, 0x3e, 0x2c, 0xc1, 0x7c, 0xb0, 0x05, 0x5f, - 0x9e, 0xb4, 0x3f, 0x61, 0xef, 0xd8, 0x10, 0xbf, 0x2a, 0xc1, 0x5d, 0x7b, 0xc8, 0xc4, 0x15, 0xf0, - 0x1c, 0xcc, 0xf8, 0x36, 0x09, 0x44, 0x08, 0x17, 0xc3, 0x7e, 0x72, 0x70, 0x86, 0xea, 0xae, 0x89, - 0x8f, 0x10, 0xa5, 0x7c, 0xe6, 0xcb, 0x73, 0xd3, 0xdd, 0x75, 0xb6, 0x3a, 0xdd, 0xbd, 0xb0, 0xbf, - 0x83, 0xf6, 0xf1, 0x31, 0x09, 0xee, 0x0f, 0x76, 0xb5, 0x47, 0xaa, 0xfb, 0xd7, 0x35, 0x0e, 0xff, - 0x4e, 0x82, 0x93, 0xc3, 0x08, 0xc7, 0x07, 0x64, 0x0b, 0xa6, 0xbd, 0x24, 0x3c, 0x3c, 0x1e, 0xfb, - 0x4a, 0xed, 0x99, 0x95, 0x22, 0x97, 0xdb, 0x1b, 0xa0, 0xf8, 0x16, 0x77, 0x2c, 0xff, 0x90, 0xbb, - 0x4a, 0x0e, 0x6e, 0xf4, 0x0b, 0x25, 0x07, 0xb6, 0xfa, 0x7b, 0x8c, 0x45, 0xa4, 0xc7, 0x58, 0x78, - 0x59, 0xbb, 0x72, 0x9d, 0xc7, 0xad, 0x1e, 0xdb, 0x73, 0xdf, 0x07, 0xd3, 0x3d, 0x4c, 0x99, 0x7b, - 0xf5, 0x3e, 0x2c, 0x59, 0x45, 0xdd, 0xc6, 0xaa, 0xec, 0xc2, 0x1c, 0x6d, 0xb7, 0x87, 0xa2, 0xdf, - 0xe8, 0x2e, 0x37, 0x79, 0x6c, 0xe9, 0xd9, 0x34, 0xef, 0x7b, 0x09, 0x12, 0x6c, 0x9c, 0x79, 0x77, - 0x6f, 0xc3, 0x50, 0x38, 0x03, 0xe5, 0x27, 0x44, 0x2c, 0x2b, 0x08, 0xb1, 0x7b, 0xfb, 0xd0, 0x30, - 0x7d, 0xbd, 0x43, 0x3e, 0xe4, 0x53, 0xc6, 0x97, 0x44, 0x54, 0xeb, 0x2d, 0x1d, 0x57, 0x47, 0xf5, - 0x8e, 0x45, 0x35, 0xa6, 0x9b, 0x37, 0x36, 0x7c, 0xfd, 0xb4, 0x08, 0x5f, 0x6e, 0x9f, 0x06, 0x84, - 0xaf, 0xbf, 0x1e, 0xd5, 0xbb, 0x81, 0x6c, 0x80, 0x98, 0x7f, 0x13, 0x03, 0xd9, 0x37, 0x25, 0x38, - 0x4c, 0xfb, 0xe6, 0xdf, 0xa3, 0xd8, 0xaf, 0xca, 0x1f, 0x04, 0x64, 0xb7, 0xab, 0x5a, 0x4f, 0xef, - 0x96, 0xed, 0x76, 0xf5, 0x6a, 0x60, 0x7e, 0x79, 0x10, 0x50, 0x2d, 0xb0, 0x13, 0x45, 0xb1, 0xd9, - 0x05, 0x4a, 0xb9, 0xe6, 0xdb, 0xe8, 0xe8, 0x31, 0x9c, 0xb1, 0x3b, 0x30, 0x9c, 0x5f, 0x94, 0x20, - 0xdb, 0xab, 0xcb, 0x7c, 0xf8, 0x0c, 0x38, 0x18, 0x38, 0x3f, 0x08, 0x8f, 0xe0, 0x83, 0xc3, 0xec, - 0xf2, 0x84, 0xdc, 0xe8, 0x40, 0x1b, 0xbf, 0xd1, 0x79, 0xc0, 0x5c, 0xd0, 0x42, 0xbb, 0x33, 0xeb, - 0xbf, 0x36, 0xf7, 0xf9, 0x7c, 0x57, 0x5c, 0xfd, 0x1b, 0x91, 0x7b, 0xdf, 0x80, 0xd9, 0x3e, 0x52, - 0xbf, 0xd1, 0xf3, 0xde, 0x4e, 0xdf, 0xc1, 0xbc, 0xd3, 0xe9, 0xfb, 0x23, 0xdc, 0x13, 0x82, 0x97, - 0xf3, 0x7d, 0x6b, 0xb1, 0x5e, 0x2f, 0x90, 0x95, 0xa7, 0xe1, 0x48, 0x4f, 0x2a, 0x2e, 0xdb, 0x22, - 0xc4, 0x76, 0x0c, 0xdb, 0xe1, 0x62, 0x1d, 0xef, 0x27, 0x56, 0x88, 0x9a, 0xd2, 0x28, 0x08, 0x64, - 0xca, 0x7a, 0xc3, 0xb2, 0x1a, 0x5c, 0x0c, 0xe5, 0x09, 0x98, 0xf2, 0xc1, 0x78, 0x23, 0xe7, 0x21, - 0xd6, 0xb2, 0xac, 0x86, 0xfb, 0xc0, 0xa9, 0xdf, 0xc6, 0xbe, 0x65, 0x35, 0x78, 0xb7, 0x29, 0xbe, - 0x32, 0x03, 0x88, 0x31, 0xa3, 0x7b, 0xfc, 0xa2, 0x89, 0x32, 0x4c, 0x07, 0xa0, 0xbc, 0x91, 0xd7, - 0x75, 0x7e, 0x70, 0xf6, 0xeb, 0x07, 0x20, 0x4e, 0xb9, 0xa2, 0x8f, 0x4a, 0x81, 0xcf, 0xe6, 0x2d, - 0xf4, 0x63, 0xd3, 0x7b, 0x4d, 0x9c, 0x3d, 0x3d, 0x34, 0x3e, 0xcf, 0xd9, 0x4e, 0xbe, 0xe7, 0x5f, - 0x7d, 0xe5, 0x23, 0x91, 0x7b, 0x90, 0x72, 0xba, 0xcf, 0x0a, 0xde, 0xe7, 0x2f, 0x9f, 0x0e, 0x7c, - 0x16, 0xe7, 0xd4, 0x70, 0x4d, 0x09, 0xc9, 0x16, 0x86, 0x45, 0xe7, 0x82, 0x3d, 0x46, 0x05, 0x3b, - 0x87, 0x1e, 0x1e, 0x2c, 0xd8, 0xe9, 0x77, 0x05, 0x9d, 0xe6, 0x07, 0xd1, 0xef, 0x4b, 0x30, 0xd3, - 0x6b, 0x49, 0x87, 0x2e, 0x0c, 0x27, 0x45, 0x77, 0x4a, 0x91, 0xbd, 0x78, 0x1b, 0x94, 0xbc, 0x2b, - 0xcb, 0xb4, 0x2b, 0x39, 0xf4, 0xf8, 0x6d, 0x74, 0xe5, 0xb4, 0x7f, 0xeb, 0xff, 0xbf, 0x4b, 0x70, - 0x6c, 0xcf, 0x15, 0x12, 0xca, 0x0d, 0x27, 0xe5, 0x1e, 0xb9, 0x53, 0x36, 0xff, 0x7a, 0x58, 0xf0, - 0x1e, 0xbf, 0x8d, 0xf6, 0xf8, 0x09, 0x54, 0xba, 0x9d, 0x1e, 0xf7, 0x3c, 0x5f, 0x41, 0xbf, 0x15, - 0xbc, 0x74, 0xba, 0xb7, 0x39, 0x75, 0x2d, 0x3c, 0x06, 0x38, 0x46, 0x77, 0x52, 0xab, 0x3c, 0x45, - 0xbb, 0xa0, 0xa2, 0x8d, 0xd7, 0x39, 0x68, 0xa7, 0xdf, 0x15, 0x0c, 0xfc, 0x3f, 0x88, 0xfe, 0x9b, - 0xd4, 0xfb, 0x0e, 0xe9, 0xa3, 0x7b, 0x8a, 0xd8, 0x7f, 0x51, 0x95, 0xbd, 0xb0, 0x7f, 0x42, 0xde, - 0xc9, 0x26, 0xed, 0x64, 0x1d, 0xe1, 0x3b, 0xdd, 0xc9, 0x9e, 0x83, 0x88, 0x7e, 0x47, 0x82, 0x99, - 0x5e, 0x6b, 0x92, 0x01, 0x6e, 0xb9, 0xc7, 0x22, 0x6b, 0x80, 0x5b, 0xee, 0xb5, 0x00, 0x52, 0xde, - 0x42, 0x3b, 0x7f, 0x1e, 0x3d, 0xd2, 0xaf, 0xf3, 0x7b, 0x8e, 0x22, 0xf1, 0xc5, 0x3d, 0x93, 0xfc, - 0x01, 0xbe, 0x38, 0xcc, 0x3a, 0x66, 0x80, 0x2f, 0x0e, 0xb5, 0xc6, 0x18, 0xec, 0x8b, 0x6e, 0xcf, - 0x86, 0x1c, 0x46, 0x1b, 0xfd, 0x86, 0x04, 0xe3, 0x81, 0x8c, 0x18, 0x9d, 0xd9, 0x53, 0xd0, 0x5e, - 0x0b, 0x86, 0xec, 0xd9, 0xfd, 0x90, 0xf0, 0xbe, 0x94, 0x68, 0x5f, 0x96, 0x50, 0xee, 0x76, 0xfa, - 0x12, 0x3c, 0x46, 0xfd, 0xa2, 0x04, 0xd3, 0x3d, 0xb2, 0xcc, 0x01, 0x5e, 0xd8, 0x3f, 0x69, 0xce, - 0x5e, 0xd8, 0x3f, 0x21, 0xef, 0xd5, 0x25, 0xda, 0xab, 0xef, 0x45, 0x6f, 0xbd, 0x9d, 0x5e, 0xf9, - 0xe6, 0xe7, 0x5b, 0xde, 0x95, 0x2c, 0x5f, 0x3b, 0xe8, 0xfc, 0x3e, 0x05, 0x13, 0x1d, 0x7a, 0x74, - 0xdf, 0x74, 0xbc, 0x3f, 0x4f, 0xd2, 0xfe, 0xbc, 0x0d, 0xad, 0xbf, 0xbe, 0xfe, 0x74, 0x4f, 0xeb, - 0xbf, 0xdc, 0xfd, 0x38, 0x74, 0x6f, 0x2b, 0xea, 0x99, 0xac, 0x66, 0x1f, 0xde, 0x17, 0x0d, 0xef, - 0xd4, 0x05, 0xda, 0xa9, 0xb3, 0xe8, 0xa1, 0x7e, 0x9d, 0xf2, 0xdd, 0xbb, 0x34, 0xcc, 0x6d, 0xeb, - 0xf4, 0xbb, 0x58, 0x0a, 0xfc, 0x83, 0xe8, 0xdd, 0xe2, 0xce, 0xd3, 0x89, 0x3d, 0xdb, 0xf5, 0xe5, - 0xb1, 0xd9, 0xfb, 0x87, 0xc0, 0xe4, 0x72, 0xdd, 0x43, 0xe5, 0x9a, 0x45, 0x47, 0xfb, 0xc9, 0x45, - 0x72, 0x59, 0xf4, 0x7e, 0xc9, 0xbd, 0x26, 0x7b, 0x72, 0x6f, 0xde, 0xfe, 0x64, 0x37, 0xfb, 0xc0, - 0x50, 0xb8, 0x5c, 0x92, 0xe3, 0x54, 0x92, 0x79, 0x34, 0xdb, 0x57, 0x12, 0x96, 0xfa, 0xde, 0xe9, - 0x4b, 0x05, 0xff, 0xf3, 0x20, 0xcc, 0xf5, 0x69, 0xd1, 0xb9, 0xf1, 0x3a, 0x5f, 0x4e, 0x0f, 0x77, - 0xae, 0x75, 0x27, 0xdf, 0x57, 0x0f, 0x7a, 0x3f, 0xad, 0xfc, 0x5e, 0x0c, 0xd0, 0xaa, 0x5d, 0x5f, - 0x6a, 0x63, 0xdd, 0xf1, 0x7d, 0xeb, 0x31, 0xf4, 0xf8, 0x4f, 0x7a, 0x5d, 0x8f, 0xff, 0x56, 0x03, - 0xcf, 0xe9, 0x22, 0xfb, 0x7b, 0xb2, 0x3b, 0xf4, 0x9b, 0xba, 0xe8, 0x77, 0xe5, 0x4d, 0x5d, 0xef, - 0x2b, 0xf7, 0xb1, 0x3b, 0xf7, 0x36, 0x27, 0x7e, 0xbb, 0xef, 0x93, 0xf8, 0x53, 0xd9, 0xc4, 0x1e, - 0x4f, 0x65, 0x33, 0x7d, 0xdf, 0xc3, 0x72, 0x6a, 0x74, 0x4e, 0x7c, 0xc5, 0x3b, 0x39, 0xdc, 0x25, - 0x59, 0xfe, 0x99, 0x6f, 0x6f, 0x0b, 0xe1, 0x28, 0x64, 0xbb, 0xcd, 0xc9, 0x75, 0xea, 0x8f, 0x44, - 0x41, 0x5e, 0xb5, 0xeb, 0xc5, 0x9a, 0xe1, 0xbc, 0x41, 0xb6, 0xf6, 0x78, 0xff, 0xf7, 0x4e, 0xe8, - 0xb5, 0x5b, 0x73, 0x13, 0x4c, 0xa7, 0x7b, 0x68, 0xb2, 0x09, 0x93, 0xe1, 0xfb, 0xe8, 0xcc, 0xb2, - 0x0a, 0xb7, 0xf3, 0xd8, 0xbd, 0xeb, 0x1e, 0xfa, 0x44, 0xf0, 0xdd, 0x39, 0xba, 0xd1, 0xdb, 0x98, - 0x99, 0x41, 0x5d, 0x7e, 0x23, 0x1f, 0x87, 0x7a, 0x63, 0x96, 0x85, 0x4c, 0x78, 0x50, 0xdc, 0x11, - 0x7b, 0x45, 0x82, 0xd1, 0x55, 0x5b, 0xa4, 0x82, 0xf8, 0x4d, 0xfa, 0x34, 0xed, 0x51, 0xf7, 0x77, - 0x48, 0xa2, 0xc3, 0xd9, 0xad, 0xff, 0xb7, 0x49, 0x46, 0x94, 0x03, 0x30, 0xed, 0xeb, 0xa3, 0xdb, - 0xf7, 0x2f, 0x44, 0x68, 0x6c, 0xcc, 0xe3, 0xba, 0x61, 0xba, 0x19, 0x24, 0xfe, 0xdb, 0xfa, 0xe8, - 0xc6, 0xd3, 0x71, 0xec, 0x76, 0x74, 0x7c, 0x8d, 0x06, 0x86, 0x90, 0x2e, 0xdd, 0x0d, 0xaf, 0xd5, - 0xee, 0xe7, 0x60, 0xd2, 0x3e, 0xbe, 0xad, 0x13, 0x7a, 0xf4, 0xa5, 0x7c, 0x45, 0x82, 0xf1, 0x55, - 0xbb, 0xbe, 0x69, 0xd6, 0xfe, 0xb7, 0xb6, 0xdb, 0x6d, 0x38, 0x10, 0xe8, 0xe5, 0x1b, 0xa4, 0xce, - 0xb3, 0x1f, 0x8b, 0x41, 0x74, 0xd5, 0xae, 0xa3, 0x77, 0xc2, 0x64, 0x38, 0x51, 0xe8, 0x9b, 0xff, - 0x75, 0xcf, 0x02, 0xfd, 0xd7, 0x68, 0xfd, 0x67, 0x0c, 0x74, 0x0d, 0xc6, 0x83, 0xb3, 0xc5, 0x89, - 0x3d, 0x98, 0x04, 0x30, 0xb3, 0x0f, 0x0d, 0x8b, 0xe9, 0x36, 0xf6, 0x0e, 0x48, 0xb9, 0x81, 0xee, - 0xee, 0x3d, 0xa8, 0x05, 0x52, 0xff, 0x8c, 0xb6, 0x47, 0x38, 0x21, 0xda, 0x0b, 0x87, 0x92, 0xbd, - 0xb4, 0x17, 0xc2, 0xdd, 0x53, 0x7b, 0xfd, 0xdc, 0x6a, 0x0b, 0xc0, 0xe7, 0x03, 0xf7, 0xee, 0xc1, - 0xc1, 0x43, 0xcb, 0x9e, 0x1a, 0x0a, 0xcd, 0x3d, 0x68, 0xba, 0xc3, 0x09, 0xf8, 0xff, 0x0a, 0x00, - 0x00, 0xff, 0xff, 0x8b, 0x4e, 0x2e, 0xba, 0xf9, 0xb5, 0x00, 0x00, + 0x96, 0x92, 0xc9, 0x91, 0xfc, 0x0f, 0xc3, 0x74, 0xd5, 0x6a, 0x86, 0x47, 0x3c, 0x2f, 0x87, 0xae, + 0x1c, 0xd9, 0x4b, 0xd2, 0xdb, 0x4e, 0x71, 0xa4, 0xba, 0xd5, 0xd0, 0xcd, 0xfa, 0x9c, 0xd5, 0xae, + 0x7b, 0x4f, 0x96, 0xc8, 0xf2, 0xd1, 0xf6, 0x3d, 0x5c, 0x6a, 0x6d, 0xfe, 0xa5, 0x24, 0x7d, 0x22, + 0x12, 0x5d, 0x5c, 0xcf, 0x7f, 0x3a, 0x92, 0x5d, 0x64, 0x84, 0xeb, 0xc2, 0x9e, 0x54, 0xbc, 0xd5, + 0xc0, 0x55, 0x32, 0xe8, 0xf0, 0x8d, 0xfb, 0x60, 0xa6, 0x6e, 0xd5, 0x2d, 0xca, 0xe9, 0x34, 0xf9, + 0x8b, 0xbf, 0x79, 0x4a, 0xbb, 0xd0, 0xec, 0xc0, 0x07, 0x52, 0xf3, 0xab, 0x30, 0xcd, 0x91, 0x35, + 0xba, 0x9a, 0x65, 0xb7, 0x22, 0xd0, 0xae, 0x97, 0xf3, 0x32, 0xbf, 0xf8, 0x55, 0xba, 0x0d, 0xa9, + 0x4e, 0x71, 0x52, 0x52, 0xc7, 0x2e, 0x4e, 0xcc, 0xab, 0xb0, 0x2f, 0xc0, 0x8f, 0xed, 0x24, 0xe0, + 0xf6, 0x00, 0x8e, 0x5f, 0xe0, 0x1c, 0xa7, 0x7d, 0x1c, 0xcb, 0x9c, 0x74, 0x7e, 0x01, 0xc6, 0xf7, + 0xc2, 0xeb, 0x9f, 0x73, 0x5e, 0x63, 0xd8, 0xcf, 0x64, 0x11, 0x26, 0x29, 0x93, 0x6a, 0xc7, 0x76, + 0xac, 0x26, 0xdd, 0xa6, 0xd9, 0x9d, 0xcd, 0x6f, 0x7d, 0x95, 0x05, 0xeb, 0x09, 0x42, 0xb6, 0xe0, + 0x52, 0xcd, 0xcf, 0x03, 0x5d, 0x95, 0xd7, 0x70, 0xb5, 0x31, 0x80, 0xc3, 0x17, 0xb9, 0x20, 0x2e, + 0xfe, 0xfc, 0x15, 0xb2, 0x48, 0xeb, 0x34, 0xe9, 0x2e, 0x8a, 0x5f, 0x92, 0xc1, 0xd7, 0xf0, 0x32, + 0x5f, 0xfe, 0x11, 0x36, 0x1f, 0x4c, 0xbb, 0x0c, 0x7c, 0x32, 0xf9, 0x46, 0xb1, 0x8e, 0x1d, 0x07, + 0xb7, 0x6d, 0x4d, 0x6f, 0xf4, 0x12, 0xcf, 0x77, 0x8f, 0x29, 0xf3, 0x91, 0x6f, 0x06, 0x47, 0x71, + 0x91, 0x51, 0xe6, 0x1a, 0x8d, 0xf9, 0x0d, 0x38, 0xd0, 0xc3, 0x2a, 0x86, 0xe0, 0xf9, 0x51, 0xce, + 0x73, 0xa6, 0xcb, 0x32, 0x08, 0xdb, 0x75, 0x10, 0x70, 0x77, 0x2c, 0x87, 0xe0, 0xf9, 0x93, 0x9c, + 0x27, 0xe2, 0xb4, 0x62, 0x48, 0x09, 0xc7, 0xcb, 0x30, 0x75, 0x0d, 0xb7, 0x37, 0x2d, 0x9b, 0xdf, + 0x1d, 0x1b, 0x82, 0xdd, 0x4f, 0x71, 0x76, 0x93, 0x9c, 0x90, 0x5e, 0x26, 0x23, 0xbc, 0x2e, 0x42, + 0x6a, 0x4b, 0xaf, 0xe2, 0x21, 0x58, 0xdc, 0xe0, 0x2c, 0x92, 0x04, 0x9f, 0x90, 0xe6, 0x60, 0xac, + 0x6e, 0xf1, 0x8d, 0xb4, 0xc1, 0xe4, 0x1f, 0xe3, 0xe4, 0xa3, 0x82, 0x86, 0xb3, 0x68, 0x59, 0xad, + 0x4e, 0x43, 0x77, 0x86, 0x91, 0xe0, 0xa7, 0x05, 0x0b, 0x41, 0xc3, 0x59, 0xec, 0x41, 0xad, 0x2f, + 0x09, 0x16, 0xb6, 0x4f, 0x9f, 0x8f, 0xc2, 0xa8, 0x65, 0x36, 0x76, 0x2c, 0x73, 0x18, 0x21, 0x3e, + 0xce, 0x39, 0x00, 0x27, 0x21, 0x0c, 0x1e, 0x81, 0xf4, 0xb0, 0x03, 0xf1, 0xf7, 0xbe, 0x29, 0xdc, + 0x43, 0x8c, 0xc0, 0x22, 0x4c, 0x8a, 0x00, 0x65, 0x58, 0xe6, 0x10, 0x2c, 0x7e, 0x96, 0xb3, 0x98, + 0xf0, 0x91, 0xf1, 0x6e, 0x38, 0xd8, 0x76, 0xea, 0x78, 0x18, 0x26, 0x9f, 0x12, 0xdd, 0xe0, 0x24, + 0x5c, 0x95, 0x9b, 0xd8, 0xac, 0x6e, 0x0f, 0xc7, 0xe1, 0xe7, 0x84, 0x2a, 0x05, 0x0d, 0x61, 0xb1, + 0x00, 0xe3, 0x4d, 0xbd, 0x6d, 0x6f, 0xeb, 0x8d, 0xa1, 0x86, 0xe3, 0xef, 0x73, 0x1e, 0x63, 0x2e, + 0x11, 0xd7, 0x48, 0xc7, 0xdc, 0x0b, 0x9b, 0x4f, 0x0b, 0x8d, 0xf8, 0xc8, 0xb8, 0xeb, 0xd9, 0x0e, + 0xcd, 0xe3, 0xf7, 0xc2, 0xed, 0x33, 0xc2, 0xf5, 0x18, 0xed, 0x8a, 0x9f, 0xe3, 0x23, 0x90, 0xb6, + 0x8d, 0x67, 0x87, 0x62, 0xf3, 0x59, 0x31, 0xd2, 0x94, 0x80, 0x10, 0x3f, 0x05, 0x07, 0x7b, 0x4e, + 0x13, 0x43, 0x30, 0xfb, 0x79, 0xce, 0x6c, 0x7f, 0x8f, 0xa9, 0x82, 0x87, 0x84, 0xbd, 0xb2, 0xfc, + 0x07, 0x22, 0x24, 0xe0, 0x10, 0xaf, 0x75, 0x98, 0xe9, 0x98, 0xb6, 0xbe, 0xb5, 0x37, 0xad, 0xfd, + 0x82, 0xd0, 0x1a, 0xa3, 0x0d, 0x68, 0xad, 0x02, 0xfb, 0x39, 0xc7, 0xbd, 0x8d, 0xeb, 0xe7, 0x44, + 0x60, 0x65, 0xd4, 0x1b, 0xc1, 0xd1, 0xfd, 0x3e, 0xc8, 0xba, 0xea, 0x14, 0x49, 0xb7, 0xad, 0x35, + 0xf5, 0xd6, 0x10, 0x9c, 0x7f, 0x91, 0x73, 0x16, 0x11, 0xdf, 0xcd, 0xda, 0xed, 0x15, 0xbd, 0x45, + 0x98, 0x3f, 0x09, 0x19, 0xc1, 0xbc, 0x63, 0xb6, 0x71, 0xd5, 0xaa, 0x9b, 0xc6, 0xb3, 0xb8, 0x36, + 0x04, 0xeb, 0x5f, 0x0a, 0x0d, 0xd5, 0x86, 0x8f, 0x9c, 0x70, 0x2e, 0x81, 0xec, 0xe6, 0x2a, 0x9a, + 0xd1, 0xa4, 0xe7, 0x8d, 0xbb, 0x73, 0xfc, 0x65, 0x31, 0x52, 0x2e, 0x5d, 0x89, 0x92, 0xcd, 0x17, + 0x81, 0x3d, 0x60, 0x19, 0xd6, 0x24, 0x3f, 0xcf, 0x19, 0x8d, 0x7b, 0x54, 0x3c, 0x70, 0x54, 0xad, + 0x66, 0x4b, 0x6f, 0x0f, 0x13, 0xff, 0xfe, 0xa1, 0x08, 0x1c, 0x9c, 0x84, 0x07, 0x0e, 0x92, 0xd1, + 0x91, 0xd9, 0x7e, 0x08, 0x0e, 0xbf, 0x22, 0x02, 0x87, 0xa0, 0xe1, 0x2c, 0x44, 0xc2, 0x30, 0x04, + 0x8b, 0x7f, 0x24, 0x58, 0x08, 0x1a, 0xc2, 0xe2, 0x71, 0x6f, 0xa2, 0x6d, 0xe3, 0xba, 0x61, 0x3b, + 0xfc, 0x89, 0xd9, 0xee, 0xac, 0xfe, 0xf1, 0x37, 0x83, 0x49, 0x98, 0xea, 0x23, 0x25, 0x91, 0x88, + 0x6f, 0x7c, 0xd3, 0x83, 0x9d, 0xc1, 0x82, 0xfd, 0xaa, 0x88, 0x44, 0x3e, 0x32, 0x22, 0x9b, 0x2f, + 0x43, 0x24, 0x6a, 0xaf, 0x92, 0x05, 0xea, 0x10, 0xec, 0xfe, 0x49, 0x48, 0xb8, 0xb2, 0xa0, 0x25, + 0x3c, 0x7d, 0xf9, 0x4f, 0xc7, 0xbc, 0x8a, 0x77, 0x86, 0xb2, 0xce, 0x7f, 0x1a, 0xca, 0x7f, 0x36, + 0x18, 0x25, 0x8b, 0x21, 0x93, 0xa1, 0x7c, 0x0a, 0x0d, 0x7a, 0xc2, 0x9a, 0x79, 0xd7, 0xb7, 0x79, + 0x7f, 0x83, 0xe9, 0xd4, 0xfc, 0x32, 0x31, 0xf2, 0x60, 0xd2, 0x33, 0x98, 0xd9, 0x8f, 0x7c, 0xdb, + 0xb5, 0xf3, 0x40, 0xce, 0x33, 0x7f, 0x09, 0xc6, 0x03, 0x09, 0xcf, 0x60, 0x56, 0xef, 0xe1, 0xac, + 0xc6, 0xfc, 0xf9, 0xce, 0xfc, 0x39, 0x88, 0x91, 0xe4, 0x65, 0x30, 0xf9, 0xff, 0xc5, 0xc9, 0x29, + 0xfa, 0xfc, 0xf7, 0x40, 0x4a, 0x24, 0x2d, 0x83, 0x49, 0xdf, 0xcb, 0x49, 0x5d, 0x12, 0x42, 0x2e, + 0x12, 0x96, 0xc1, 0xe4, 0xff, 0xb7, 0x20, 0x17, 0x24, 0x84, 0x7c, 0x78, 0x15, 0xfe, 0xc6, 0xfb, + 0x63, 0x7c, 0xd2, 0x11, 0xba, 0x7b, 0x04, 0x92, 0x3c, 0x53, 0x19, 0x4c, 0xfd, 0x3e, 0xde, 0xb8, + 0xa0, 0x98, 0x7f, 0x18, 0xe2, 0x43, 0x2a, 0xfc, 0x03, 0x9c, 0x94, 0xe1, 0xcf, 0x2f, 0xc0, 0xa8, + 0x2f, 0x3b, 0x19, 0x4c, 0xfe, 0xff, 0x72, 0x72, 0x3f, 0x15, 0x11, 0x9d, 0x67, 0x27, 0x83, 0x19, + 0xfc, 0xa8, 0x10, 0x9d, 0x53, 0x10, 0xb5, 0x89, 0xc4, 0x64, 0x30, 0xf5, 0x07, 0x85, 0xd6, 0x05, + 0xc9, 0xfc, 0xa3, 0x90, 0x76, 0x27, 0x9b, 0xc1, 0xf4, 0x1f, 0xe2, 0xf4, 0x1e, 0x0d, 0xd1, 0x80, + 0x6f, 0xb2, 0x1b, 0xcc, 0xe2, 0xff, 0x13, 0x1a, 0xf0, 0x51, 0x11, 0x37, 0x0a, 0x27, 0x30, 0x83, + 0x39, 0x7d, 0x58, 0xb8, 0x51, 0x28, 0x7f, 0x21, 0xa3, 0x49, 0x63, 0xfe, 0x60, 0x16, 0x3f, 0x26, + 0x46, 0x93, 0xe2, 0x13, 0x31, 0xc2, 0x19, 0xc1, 0x60, 0x1e, 0x3f, 0x21, 0xc4, 0x08, 0x25, 0x04, + 0xf3, 0xeb, 0x80, 0xba, 0xb3, 0x81, 0xc1, 0xfc, 0x5e, 0xe4, 0xfc, 0xa6, 0xba, 0x92, 0x81, 0xf9, + 0x27, 0x60, 0x7f, 0xef, 0x4c, 0x60, 0x30, 0xd7, 0x8f, 0x7c, 0x3b, 0xb4, 0x76, 0xf3, 0x27, 0x02, + 0xf3, 0x15, 0x6f, 0x4a, 0xf1, 0x67, 0x01, 0x83, 0xd9, 0x7e, 0xf4, 0xdb, 0xc1, 0xc0, 0xed, 0x4f, + 0x02, 0xe6, 0x73, 0x00, 0xde, 0x04, 0x3c, 0x98, 0xd7, 0x4f, 0x71, 0x5e, 0x3e, 0x22, 0xe2, 0x1a, + 0x7c, 0xfe, 0x1d, 0x4c, 0x7f, 0x43, 0xb8, 0x06, 0xa7, 0x20, 0xae, 0x21, 0xa6, 0xde, 0xc1, 0xd4, + 0x1f, 0x13, 0xae, 0x21, 0x48, 0x88, 0x65, 0xfb, 0x66, 0xb7, 0xc1, 0x1c, 0x3e, 0x2e, 0x2c, 0xdb, + 0x47, 0x35, 0xbf, 0x0a, 0x53, 0x5d, 0x13, 0xe2, 0x60, 0x56, 0x9f, 0xe0, 0xac, 0xe4, 0xf0, 0x7c, + 0xe8, 0x9f, 0xbc, 0xf8, 0x64, 0x38, 0x98, 0xdb, 0x27, 0x43, 0x93, 0x17, 0x9f, 0x0b, 0xe7, 0x1f, + 0x81, 0x94, 0xd9, 0x69, 0x34, 0x88, 0xf3, 0xa0, 0xdd, 0x9f, 0x18, 0x67, 0xbe, 0xfe, 0x1d, 0xae, + 0x1d, 0x41, 0x30, 0x7f, 0x0e, 0xe2, 0xb8, 0xb9, 0x89, 0x6b, 0x83, 0x28, 0xbf, 0xf1, 0x1d, 0x11, + 0x30, 0x09, 0xf6, 0xfc, 0xa3, 0x00, 0x6c, 0x6b, 0x84, 0xde, 0xb1, 0x1f, 0x40, 0xfb, 0xa7, 0xdf, + 0xe1, 0x0f, 0xf2, 0x3c, 0x12, 0x8f, 0x01, 0x7b, 0xde, 0xb7, 0x3b, 0x83, 0x6f, 0x06, 0x19, 0xd0, + 0x11, 0xb9, 0x08, 0xc9, 0xa7, 0x6d, 0xcb, 0x74, 0xf4, 0xfa, 0x20, 0xea, 0xff, 0xc4, 0xa9, 0x05, + 0x3e, 0x51, 0x58, 0xd3, 0x6a, 0x63, 0x47, 0xaf, 0xdb, 0x83, 0x68, 0xff, 0x33, 0xa7, 0x75, 0x09, + 0x08, 0x71, 0x55, 0xb7, 0x9d, 0x61, 0xfa, 0xfd, 0x67, 0x82, 0x58, 0x10, 0x10, 0xa1, 0xc9, 0xdf, + 0x57, 0xf1, 0xce, 0x20, 0xda, 0x6f, 0x09, 0xa1, 0x39, 0xfe, 0xfc, 0xf7, 0x40, 0x9a, 0xfc, 0xc9, + 0x1e, 0xea, 0x0e, 0x20, 0xfe, 0x73, 0x4e, 0xec, 0x51, 0x90, 0x96, 0x6d, 0xa7, 0xe6, 0x18, 0x83, + 0x95, 0xfd, 0x1a, 0x1f, 0x69, 0x81, 0x3f, 0x9f, 0x83, 0x51, 0xdb, 0xa9, 0xd5, 0x3a, 0x3c, 0x3f, + 0x1d, 0x40, 0xfe, 0x17, 0xdf, 0x71, 0xb7, 0x2c, 0x5c, 0x1a, 0x32, 0xda, 0xcf, 0x5c, 0x75, 0x5a, + 0x16, 0xbd, 0x95, 0x35, 0x88, 0xc3, 0xb7, 0x39, 0x07, 0x1f, 0xc9, 0xfc, 0x02, 0x8c, 0x91, 0xbe, + 0x88, 0xcb, 0x2d, 0x83, 0x58, 0xfc, 0x17, 0xae, 0x80, 0x00, 0x51, 0xfe, 0xfb, 0xbf, 0xf8, 0xca, + 0x51, 0xe9, 0xe5, 0x57, 0x8e, 0x4a, 0xff, 0xe1, 0x95, 0xa3, 0xd2, 0x07, 0xff, 0xf8, 0xe8, 0xc8, + 0xcb, 0x7f, 0x7c, 0x74, 0xe4, 0x0f, 0xfe, 0xf8, 0xe8, 0x48, 0xef, 0x5d, 0x62, 0x58, 0xb4, 0x16, + 0x2d, 0xb6, 0x3f, 0xfc, 0x36, 0xa5, 0x6e, 0x38, 0xdb, 0x9d, 0xcd, 0xb9, 0xaa, 0xd5, 0xa4, 0xdb, + 0xb8, 0xde, 0x6e, 0xad, 0xbb, 0xc8, 0x81, 0xf7, 0x44, 0xe1, 0x68, 0xd5, 0xb2, 0x9b, 0x96, 0x7d, + 0x7a, 0x53, 0xb7, 0xf1, 0xe9, 0x6b, 0x67, 0x36, 0xb1, 0xa3, 0x9f, 0x39, 0x5d, 0xb5, 0x0c, 0x93, + 0x6f, 0xfb, 0x4e, 0xb3, 0xfa, 0x39, 0x52, 0x3f, 0xc7, 0xeb, 0xb3, 0x3d, 0x77, 0x88, 0x95, 0x45, + 0x88, 0x2d, 0x58, 0x06, 0xbd, 0xe8, 0x5f, 0xc3, 0xa6, 0xd5, 0xe4, 0x8f, 0x40, 0x59, 0x01, 0xdd, + 0x09, 0x09, 0xbd, 0x69, 0x75, 0x4c, 0x87, 0x9d, 0x8d, 0xe4, 0x47, 0xbf, 0x78, 0x73, 0x76, 0xe4, + 0x0f, 0x6f, 0xce, 0x46, 0x4b, 0xa6, 0xa3, 0xf2, 0xaa, 0xf9, 0xd8, 0xab, 0x2f, 0xcd, 0x4a, 0xca, + 0x65, 0x48, 0x16, 0x70, 0xf5, 0x56, 0x78, 0x15, 0x70, 0x35, 0xc4, 0xeb, 0x5e, 0x48, 0x95, 0x4c, + 0x87, 0x3d, 0xd3, 0x3d, 0x02, 0x51, 0xc3, 0x64, 0xaf, 0xbb, 0x42, 0xed, 0x13, 0x38, 0x41, 0x2d, + 0xe0, 0xaa, 0x8b, 0x5a, 0xc3, 0xd5, 0x30, 0x2a, 0x61, 0x4f, 0xe0, 0xf9, 0xc2, 0x1f, 0xfc, 0xc7, + 0xa3, 0x23, 0xcf, 0xbd, 0x72, 0x74, 0xa4, 0xdf, 0xf8, 0x04, 0xd4, 0xcf, 0x55, 0xcc, 0xfe, 0x3b, + 0x65, 0xd7, 0xae, 0xb2, 0xed, 0xf9, 0xcd, 0x04, 0xfb, 0x38, 0x02, 0xbc, 0x3b, 0x0a, 0x07, 0x59, + 0xa5, 0xc6, 0x94, 0xca, 0x75, 0xce, 0x46, 0x60, 0xcc, 0x5f, 0x35, 0xc4, 0xde, 0xfb, 0x12, 0x4c, + 0x50, 0x0b, 0xa4, 0xbb, 0x8e, 0xd4, 0xe9, 0x07, 0xc6, 0xe9, 0xdf, 0xfe, 0x37, 0x71, 0xaa, 0xde, + 0x71, 0x97, 0x90, 0xbe, 0x4d, 0xaa, 0xc0, 0x8c, 0xd1, 0x6c, 0x35, 0x30, 0x3d, 0xe4, 0xd3, 0xdc, + 0xba, 0xc1, 0xfc, 0xbe, 0xc4, 0xf9, 0x4d, 0x7b, 0xe4, 0x25, 0x41, 0x3d, 0xbf, 0x0c, 0x53, 0x7a, + 0xb5, 0x8a, 0x5b, 0x01, 0x96, 0x03, 0xbc, 0x43, 0x08, 0x28, 0x73, 0x4a, 0x97, 0x5b, 0xfe, 0xd1, + 0xbe, 0x23, 0x70, 0xb7, 0x6f, 0x04, 0xda, 0xb8, 0x8e, 0xcd, 0x53, 0x26, 0x76, 0x9e, 0xb1, 0xda, + 0x57, 0xc5, 0x40, 0xb0, 0xa6, 0xc4, 0x20, 0xfc, 0x6e, 0x02, 0x14, 0x3e, 0x50, 0xb6, 0xa3, 0x5f, + 0x35, 0xcc, 0xba, 0xeb, 0x0e, 0x7a, 0xc7, 0xd9, 0x7e, 0x96, 0x8f, 0xc6, 0x7e, 0x3e, 0x36, 0x1c, + 0xc7, 0x75, 0x89, 0x01, 0x7e, 0x94, 0xed, 0x3f, 0xc0, 0x7d, 0xbc, 0xe9, 0x77, 0xa2, 0x80, 0xca, + 0x8e, 0x7e, 0x15, 0xe7, 0x3a, 0xce, 0xb6, 0xd5, 0x36, 0x9e, 0x65, 0xb1, 0x0c, 0x03, 0x34, 0xf5, + 0xeb, 0x9a, 0x63, 0x5d, 0xc5, 0xa6, 0x78, 0x22, 0x70, 0x70, 0xae, 0x87, 0x93, 0xce, 0x11, 0xff, + 0xc9, 0xdf, 0xf7, 0xe9, 0xaf, 0xcc, 0xde, 0x33, 0xd8, 0x14, 0x29, 0x32, 0x49, 0xae, 0xaf, 0x57, + 0x28, 0x63, 0x74, 0x05, 0xd8, 0x35, 0x7e, 0xad, 0x61, 0xd8, 0x0e, 0xbf, 0x5b, 0x7e, 0x6e, 0xae, + 0x77, 0xdf, 0xe7, 0xba, 0xc5, 0x9c, 0xe3, 0x97, 0x66, 0xac, 0xb6, 0xbd, 0x34, 0xa2, 0xa6, 0x29, + 0xab, 0x65, 0xc3, 0x76, 0x50, 0x05, 0xd2, 0x35, 0x6c, 0xee, 0x30, 0xb6, 0xd1, 0xd7, 0xc7, 0x36, + 0x45, 0x38, 0x51, 0xae, 0x4f, 0x02, 0xd2, 0xfd, 0x78, 0xe2, 0x2b, 0x58, 0xec, 0x2e, 0x67, 0x1f, + 0xf6, 0x01, 0xce, 0xf4, 0xcd, 0xd8, 0x94, 0x1e, 0x06, 0x65, 0x8f, 0x03, 0x78, 0x6d, 0xa2, 0x0c, + 0x24, 0xf5, 0x5a, 0xad, 0x8d, 0x6d, 0x76, 0xd7, 0x23, 0xad, 0x8a, 0xe2, 0xfc, 0xd4, 0xef, 0x7d, + 0xfe, 0xd4, 0x78, 0x80, 0x63, 0x7e, 0x0c, 0xe0, 0x9a, 0x4b, 0x7a, 0xf2, 0x63, 0x12, 0x4c, 0x75, + 0xb5, 0x88, 0x14, 0x38, 0x9a, 0xdb, 0xa8, 0x2c, 0xad, 0xa9, 0xa5, 0xb7, 0xb1, 0xeb, 0x44, 0xfc, + 0xc2, 0x53, 0x79, 0xbd, 0xb8, 0xc0, 0xbe, 0x81, 0x33, 0x82, 0x66, 0xe1, 0x50, 0x0f, 0x9c, 0x42, + 0x71, 0xb9, 0xb8, 0x98, 0xab, 0x14, 0x65, 0x09, 0xdd, 0x01, 0x47, 0x7a, 0x32, 0x71, 0x51, 0x22, + 0x7d, 0x50, 0xd4, 0xa2, 0x8b, 0x12, 0xcd, 0x5f, 0xea, 0xeb, 0x48, 0xf7, 0xef, 0x6a, 0x3f, 0xd7, + 0x5d, 0x77, 0x09, 0x06, 0xb5, 0x77, 0x45, 0xe0, 0x60, 0x38, 0x56, 0xe9, 0xe6, 0x4e, 0x9f, 0x2f, + 0x28, 0xf6, 0x71, 0x82, 0x25, 0x88, 0xe6, 0xcc, 0x1d, 0x74, 0x90, 0xe5, 0xd3, 0x5a, 0xa7, 0xdd, + 0xe0, 0x13, 0x41, 0x92, 0x94, 0x37, 0xda, 0x8d, 0xe0, 0xab, 0xb2, 0x31, 0xfe, 0xaa, 0x6c, 0x5e, + 0x7e, 0xf1, 0xa5, 0xd9, 0x91, 0xcf, 0xbd, 0x34, 0x3b, 0xf2, 0xad, 0x8f, 0xcf, 0x8e, 0x3c, 0xf7, + 0x47, 0xc7, 0x46, 0xf2, 0x57, 0xc3, 0xdd, 0xfb, 0x8d, 0x81, 0xb3, 0x69, 0x2a, 0x67, 0xee, 0xd0, + 0xd9, 0x60, 0x5d, 0x7a, 0x5b, 0x9c, 0x76, 0x4e, 0x1c, 0xa0, 0x1e, 0x0d, 0x1f, 0xa0, 0x3e, 0x81, + 0x1b, 0x8d, 0xc7, 0x4c, 0xeb, 0x19, 0x3a, 0xaa, 0x9e, 0x0e, 0x3e, 0x1c, 0x81, 0xa3, 0x5d, 0xf1, + 0x9a, 0x67, 0x18, 0xfd, 0x3e, 0x25, 0x39, 0x0f, 0xa9, 0x82, 0x48, 0x5c, 0x32, 0x90, 0xb4, 0x71, + 0xd5, 0x32, 0x6b, 0xcc, 0xd3, 0xa3, 0xaa, 0x28, 0x92, 0x6e, 0x9b, 0xba, 0x69, 0xd9, 0xfc, 0x4b, + 0x1c, 0xac, 0x90, 0xff, 0x49, 0x69, 0x6f, 0xf9, 0xc2, 0xb8, 0x68, 0x49, 0x74, 0xf3, 0xcc, 0xc0, + 0x23, 0xe5, 0xab, 0xa4, 0x97, 0x6e, 0x27, 0x02, 0xc7, 0xca, 0xc3, 0x6a, 0xe5, 0x27, 0x22, 0x30, + 0x1b, 0xd6, 0x0a, 0x49, 0xdb, 0x6c, 0x47, 0x6f, 0xb6, 0xfa, 0xa9, 0xe5, 0x11, 0x48, 0x57, 0x04, + 0xce, 0x9e, 0xf5, 0x72, 0x63, 0x8f, 0x7a, 0x99, 0x70, 0x9b, 0x12, 0x8a, 0x39, 0x3b, 0xa4, 0x62, + 0xdc, 0x7e, 0xdc, 0x92, 0x66, 0x3e, 0x1d, 0x83, 0x23, 0xf4, 0x6b, 0x4f, 0xed, 0xa6, 0x61, 0x3a, + 0xa7, 0xab, 0xed, 0x9d, 0x96, 0x43, 0x13, 0x37, 0x6b, 0x8b, 0xeb, 0x65, 0xca, 0xab, 0x9e, 0x63, + 0xd5, 0x7d, 0x3c, 0x67, 0x0b, 0xe2, 0xeb, 0x84, 0x8e, 0x68, 0xc4, 0xb1, 0x1c, 0xbd, 0xc1, 0x35, + 0xc5, 0x0a, 0x04, 0xca, 0xbe, 0x10, 0x15, 0x61, 0x50, 0x43, 0x7c, 0x1c, 0xaa, 0x81, 0xf5, 0x2d, + 0xf6, 0x95, 0x8c, 0x28, 0x75, 0xa8, 0x14, 0x01, 0xd0, 0x0f, 0x62, 0xcc, 0x40, 0x5c, 0xef, 0xb0, + 0x1b, 0x44, 0x51, 0xe2, 0x69, 0xb4, 0xa0, 0x3c, 0x06, 0x49, 0x7e, 0xa0, 0x8c, 0x64, 0x88, 0x5e, + 0xc5, 0x3b, 0xb4, 0x9d, 0x31, 0x95, 0xfc, 0x89, 0xe6, 0x20, 0x4e, 0x85, 0xe7, 0x13, 0x48, 0x66, + 0xae, 0x4b, 0xfa, 0x39, 0x2a, 0xa4, 0xca, 0xd0, 0x94, 0xcb, 0x90, 0x2a, 0x58, 0x4d, 0xc3, 0xb4, + 0x82, 0xdc, 0xd2, 0x8c, 0x1b, 0x95, 0xb9, 0xd5, 0x71, 0xc4, 0x03, 0x52, 0x5a, 0x40, 0xfb, 0x21, + 0xc1, 0xbe, 0x9a, 0xc2, 0x6f, 0x41, 0xf1, 0x92, 0xb2, 0x00, 0x49, 0xca, 0x7b, 0xad, 0xe5, 0x7e, + 0xcd, 0x4c, 0xf2, 0x7d, 0xcd, 0x8c, 0xb3, 0x8f, 0x78, 0xc2, 0x22, 0x88, 0xd5, 0x74, 0x47, 0xe7, + 0xfd, 0xa6, 0x7f, 0x2b, 0x6f, 0x85, 0x14, 0x67, 0x62, 0xa3, 0xb3, 0x10, 0xb5, 0x5a, 0xe2, 0x92, + 0x5f, 0xb6, 0x5f, 0x57, 0xd6, 0x5a, 0xf9, 0x18, 0x49, 0x17, 0x55, 0x82, 0x9c, 0x57, 0xfb, 0x06, + 0xd5, 0x0b, 0xbe, 0xa0, 0xea, 0x1b, 0x72, 0xdf, 0x9f, 0x6c, 0x48, 0xbb, 0xcc, 0xc1, 0x35, 0x96, + 0xbf, 0x92, 0xe0, 0x70, 0xb7, 0xb1, 0x5c, 0xc5, 0x3b, 0xf6, 0x5e, 0x6d, 0xe5, 0x49, 0x48, 0xaf, + 0xd3, 0x2f, 0xae, 0x3e, 0x86, 0x77, 0x50, 0x16, 0x92, 0xb8, 0x76, 0xf6, 0xdc, 0xb9, 0x33, 0x17, + 0xd9, 0x48, 0x2e, 0x8d, 0xa8, 0x02, 0x30, 0x9f, 0x22, 0x29, 0xf5, 0xab, 0x1f, 0x9f, 0x95, 0xf2, + 0x71, 0x88, 0xda, 0x9d, 0x26, 0xbb, 0x32, 0x77, 0x39, 0x96, 0x8a, 0xca, 0x31, 0x35, 0x6d, 0xe3, + 0x6a, 0xeb, 0xec, 0xb9, 0xf3, 0x57, 0xcf, 0xa8, 0x49, 0xbb, 0x4d, 0x09, 0xde, 0xd0, 0xfe, 0x7f, + 0x34, 0x0e, 0xc7, 0xfc, 0x94, 0xd4, 0x0b, 0xdd, 0x19, 0x97, 0xeb, 0x40, 0xf6, 0xe9, 0x80, 0x62, + 0xf4, 0x56, 0x41, 0x76, 0x57, 0x4d, 0x2a, 0xbf, 0x24, 0xc1, 0x98, 0x9b, 0x06, 0x94, 0xb1, 0x83, + 0x1e, 0xf1, 0xcf, 0xed, 0xdc, 0x24, 0x0e, 0xcd, 0x85, 0xdb, 0xf2, 0xd2, 0x15, 0xd5, 0x87, 0x8e, + 0x1e, 0x86, 0x54, 0xab, 0x6d, 0xb5, 0x2c, 0x9b, 0x7f, 0x48, 0x69, 0x00, 0xa9, 0x8b, 0x8c, 0xee, + 0x07, 0x44, 0xbd, 0x57, 0xbb, 0x66, 0x39, 0x86, 0x59, 0xd7, 0x5a, 0xd6, 0x33, 0xfc, 0x0b, 0x77, + 0x51, 0x55, 0xa6, 0x35, 0x57, 0x68, 0xc5, 0x3a, 0x81, 0x13, 0xa1, 0xd3, 0x2e, 0x97, 0x60, 0xea, + 0x42, 0x0c, 0x5c, 0x14, 0xd1, 0x23, 0x90, 0x6c, 0x75, 0x36, 0x35, 0xe1, 0x0d, 0xa3, 0x67, 0x0f, + 0xf7, 0xb2, 0x6d, 0x61, 0x1f, 0xdc, 0xba, 0x13, 0xad, 0xce, 0x26, 0xb1, 0x96, 0x3b, 0x60, 0xac, + 0x87, 0x30, 0xa3, 0xd7, 0x3c, 0x39, 0xe8, 0x87, 0x7e, 0x79, 0x0f, 0xb4, 0x56, 0xdb, 0xb0, 0xda, + 0x86, 0xb3, 0x43, 0x73, 0xb3, 0xa8, 0x2a, 0x8b, 0x8a, 0x75, 0x0e, 0x57, 0xae, 0xc2, 0x64, 0x99, + 0x2e, 0x1a, 0x3c, 0xc9, 0xcf, 0x79, 0xf2, 0x49, 0x83, 0xe5, 0xeb, 0x2b, 0x59, 0xa4, 0x4b, 0xb2, + 0xfc, 0xe3, 0x7d, 0xad, 0xf3, 0xe1, 0xbd, 0x5b, 0x67, 0x30, 0xfb, 0x79, 0x45, 0x82, 0xa3, 0xbe, + 0xca, 0x6b, 0xb8, 0x6d, 0x1b, 0x96, 0xc9, 0x93, 0x6d, 0x66, 0x9a, 0xc8, 0xd7, 0x0b, 0x5e, 0xdf, + 0xc7, 0x3f, 0x2f, 0x42, 0x7a, 0xc1, 0x32, 0x6d, 0x6c, 0xda, 0x1d, 0x3a, 0xc3, 0x6d, 0x36, 0xac, + 0xea, 0x55, 0xaa, 0x8c, 0x98, 0xca, 0x0a, 0x24, 0x9c, 0xe9, 0xad, 0x16, 0xed, 0x64, 0x4c, 0x25, + 0x7f, 0xb2, 0xe5, 0x6f, 0xbe, 0xdc, 0xb7, 0x8b, 0x17, 0xf7, 0xde, 0x45, 0x2e, 0xa5, 0xdb, 0xc9, + 0x97, 0x25, 0x98, 0x20, 0x53, 0x85, 0xbe, 0x29, 0x26, 0x4f, 0x94, 0x12, 0xe5, 0x21, 0x16, 0xaa, + 0x8f, 0x82, 0x8b, 0x3d, 0xc4, 0xc9, 0xc9, 0xc7, 0x7f, 0xed, 0x0b, 0x12, 0xdb, 0x09, 0x14, 0x44, + 0xf9, 0x52, 0xdf, 0xce, 0x9d, 0x1e, 0xb2, 0x73, 0x82, 0x95, 0xdb, 0xa5, 0xdf, 0xbb, 0x3b, 0x10, + 0x54, 0x59, 0x50, 0xf1, 0x8f, 0xda, 0xb0, 0x01, 0x65, 0x50, 0x86, 0x93, 0xdd, 0x7d, 0xa2, 0xcf, + 0x0e, 0x0c, 0x6d, 0xd9, 0x01, 0xf6, 0x95, 0x0d, 0x0d, 0x8d, 0xf2, 0x03, 0x30, 0xbe, 0xae, 0xb7, + 0x9d, 0x32, 0x76, 0x96, 0xb0, 0x5e, 0xc3, 0x6d, 0x74, 0xd0, 0x9f, 0x19, 0x8c, 0x2f, 0x8d, 0xf0, + 0xdc, 0xe0, 0x79, 0x49, 0x42, 0x07, 0x20, 0x46, 0x73, 0x00, 0x3a, 0x3d, 0x2e, 0x49, 0x2a, 0x2d, + 0x3d, 0x2f, 0x49, 0xf3, 0x89, 0x2f, 0x3e, 0xff, 0xca, 0x67, 0xc6, 0xa4, 0x7c, 0x0a, 0x12, 0x1a, + 0xc5, 0xce, 0x27, 0x21, 0x4e, 0xf3, 0x05, 0x65, 0x1b, 0x62, 0xf4, 0x1d, 0x9e, 0x9b, 0x5a, 0x50, + 0xb6, 0x22, 0xb5, 0x20, 0x66, 0xbb, 0xe3, 0xf0, 0x77, 0xca, 0x63, 0x2a, 0x2b, 0xa0, 0x87, 0x44, + 0x82, 0x10, 0xdd, 0x3d, 0x41, 0xe0, 0x51, 0x87, 0xa7, 0x09, 0xff, 0xbf, 0x04, 0xc9, 0x3c, 0x31, + 0xfb, 0x52, 0xc1, 0x95, 0x54, 0xcc, 0x55, 0x42, 0x52, 0xb4, 0x0c, 0x93, 0x2d, 0xbd, 0xed, 0xd0, + 0x6f, 0xfb, 0x6c, 0xd3, 0x0e, 0xf3, 0xf0, 0x36, 0xdb, 0x1d, 0x6c, 0x03, 0x7a, 0x59, 0x92, 0xd4, + 0xf1, 0x96, 0x1f, 0xe0, 0xef, 0xb7, 0xe8, 0x6d, 0x1e, 0x81, 0xac, 0x85, 0xf8, 0x2b, 0x7f, 0x12, + 0x83, 0x04, 0xd7, 0xed, 0xf7, 0x40, 0x92, 0x8f, 0x09, 0x0f, 0x5a, 0x47, 0xe6, 0xba, 0xdd, 0x7d, + 0xce, 0xf5, 0x6a, 0xde, 0x3f, 0x41, 0x83, 0x8e, 0x43, 0xaa, 0xba, 0xad, 0x1b, 0xa6, 0x66, 0xd4, + 0xc4, 0x16, 0xd7, 0x2b, 0x37, 0x67, 0x93, 0x0b, 0x04, 0x56, 0x2a, 0xa8, 0x49, 0x5a, 0x59, 0xaa, + 0x91, 0xe4, 0x67, 0x1b, 0x1b, 0xf5, 0x6d, 0x87, 0x07, 0x5e, 0x5e, 0x42, 0x17, 0x20, 0x46, 0xec, + 0x8d, 0x5f, 0xaa, 0xcf, 0x76, 0x39, 0x97, 0x9b, 0xdf, 0xe6, 0x53, 0xa4, 0xe1, 0x0f, 0x7e, 0x65, + 0x56, 0x52, 0x29, 0x05, 0x5a, 0x80, 0xf1, 0x86, 0x6e, 0x3b, 0x1a, 0x0d, 0x2b, 0xa4, 0xf9, 0x38, + 0xdf, 0x62, 0xe8, 0x52, 0x1a, 0x1f, 0x01, 0x2e, 0xfa, 0x28, 0xa1, 0x62, 0xa0, 0x1a, 0x3a, 0x01, + 0x32, 0x65, 0x52, 0xb5, 0x9a, 0x4d, 0xc3, 0x61, 0xe9, 0x64, 0x82, 0x8e, 0xfb, 0x04, 0x81, 0x2f, + 0x50, 0x30, 0x4d, 0x2a, 0x0f, 0x41, 0x9a, 0x7e, 0xe4, 0x8a, 0xa2, 0xb0, 0x67, 0xa2, 0x29, 0x02, + 0xa0, 0x95, 0xf7, 0xc0, 0xa4, 0x37, 0x6d, 0x32, 0x94, 0x14, 0xe3, 0xe2, 0x81, 0x29, 0xe2, 0x03, + 0x30, 0x63, 0xe2, 0xeb, 0x8e, 0x16, 0xc6, 0x4e, 0x53, 0x6c, 0x44, 0xea, 0xae, 0x04, 0x29, 0xee, + 0x86, 0x89, 0xaa, 0x50, 0x3e, 0xc3, 0x05, 0x8a, 0x3b, 0xee, 0x42, 0x29, 0xda, 0x41, 0x48, 0xe9, + 0xad, 0x16, 0x43, 0x18, 0xe5, 0xd3, 0x66, 0xab, 0x45, 0xab, 0x4e, 0xc2, 0x14, 0xed, 0x63, 0x1b, + 0xdb, 0x9d, 0x86, 0xc3, 0x99, 0x8c, 0x51, 0x9c, 0x49, 0x52, 0xa1, 0x32, 0x38, 0xc5, 0xbd, 0x13, + 0xc6, 0xf1, 0x35, 0xa3, 0x86, 0xcd, 0x2a, 0x66, 0x78, 0xe3, 0x14, 0x6f, 0x4c, 0x00, 0x29, 0xd2, + 0xbd, 0xe0, 0x4e, 0x87, 0x9a, 0x98, 0xaa, 0x27, 0x18, 0x3f, 0x01, 0xcf, 0x31, 0xb0, 0x92, 0x81, + 0x58, 0x41, 0x77, 0x74, 0x12, 0xf5, 0x9d, 0xeb, 0x2c, 0xff, 0x18, 0x53, 0xc9, 0x9f, 0xca, 0x51, + 0x88, 0x57, 0xae, 0x93, 0xe9, 0x6f, 0x1f, 0x24, 0x9c, 0xeb, 0x9a, 0x97, 0x8f, 0xc7, 0x1d, 0x02, + 0x56, 0x7e, 0x2e, 0x06, 0xb1, 0x2b, 0x96, 0x83, 0xa9, 0x85, 0x78, 0xdf, 0x41, 0xea, 0xe1, 0x13, + 0x65, 0xa3, 0x6e, 0xe2, 0xda, 0x8a, 0x5d, 0x27, 0x4b, 0x14, 0xe2, 0x58, 0x04, 0x4c, 0x1c, 0xeb, + 0x90, 0x6b, 0x73, 0x74, 0x4a, 0x5d, 0x92, 0x84, 0xd5, 0x91, 0xca, 0x83, 0x10, 0x6f, 0x5b, 0x1d, + 0x93, 0x7d, 0xeb, 0x21, 0xbe, 0x14, 0x51, 0x59, 0x91, 0x54, 0x5d, 0x84, 0x94, 0x6b, 0x54, 0xb1, + 0x01, 0x46, 0xb5, 0x14, 0x55, 0x93, 0x9b, 0xcc, 0x98, 0x08, 0xe9, 0x03, 0x30, 0xe5, 0x0e, 0xad, + 0xab, 0x1b, 0x6a, 0x50, 0x4b, 0x31, 0x55, 0x76, 0xab, 0xb8, 0x7a, 0x08, 0xc5, 0xfd, 0x3e, 0xd3, + 0xe1, 0xdf, 0xc2, 0x4d, 0x52, 0x89, 0xe2, 0x3e, 0xe3, 0xa1, 0x5f, 0xc4, 0x25, 0xd8, 0x77, 0x40, + 0xda, 0x36, 0xea, 0x26, 0x7d, 0xf7, 0xc1, 0x4c, 0x6c, 0x29, 0xa1, 0x7a, 0x20, 0x82, 0x72, 0xb7, + 0xff, 0x3b, 0xef, 0xd4, 0xae, 0xf2, 0x91, 0x8c, 0xb4, 0x94, 0xf4, 0x7d, 0xc6, 0x9d, 0xa0, 0x5d, + 0x80, 0x69, 0xef, 0x1b, 0xea, 0x1e, 0x4f, 0x70, 0x09, 0x52, 0x2a, 0x72, 0x11, 0xca, 0xbe, 0x06, + 0x02, 0x11, 0x86, 0xe8, 0x22, 0x9f, 0x86, 0xa4, 0xc6, 0x14, 0x4b, 0xa3, 0x2d, 0xd5, 0x63, 0x7e, + 0x14, 0xd2, 0xae, 0x6b, 0xe6, 0x67, 0x00, 0x69, 0x5d, 0x7a, 0xa1, 0x91, 0x29, 0xd4, 0xf7, 0xfc, + 0x18, 0x80, 0x27, 0x0d, 0x2d, 0xb9, 0x42, 0xe4, 0xf7, 0xc3, 0x8c, 0xd6, 0x43, 0x66, 0xe5, 0x37, + 0x24, 0x48, 0x30, 0x4f, 0xf5, 0x85, 0x19, 0x29, 0x10, 0x66, 0x66, 0xc4, 0x68, 0xf3, 0xd5, 0x36, + 0x2d, 0xa0, 0xa2, 0x6f, 0xa0, 0xa3, 0x83, 0xa2, 0xc7, 0x24, 0x89, 0x1e, 0x24, 0xb6, 0x71, 0x80, + 0x3b, 0xee, 0x28, 0x07, 0xe0, 0x0a, 0x63, 0xf3, 0xcf, 0xb3, 0xf6, 0x48, 0x94, 0x99, 0x88, 0x65, + 0xa3, 0xce, 0x03, 0x91, 0x8f, 0x48, 0xf9, 0xf7, 0x12, 0xc9, 0x9c, 0x78, 0x3d, 0xca, 0xc1, 0xb8, + 0x90, 0x4b, 0xdb, 0x6a, 0xe8, 0x75, 0x6e, 0xfb, 0x47, 0xfa, 0x0a, 0x77, 0xa9, 0xa1, 0xd7, 0xd5, + 0x51, 0x2e, 0x0f, 0x29, 0x90, 0x5c, 0xb6, 0xdb, 0x10, 0xd9, 0x8c, 0xd6, 0x65, 0x86, 0x28, 0x0f, + 0x69, 0x77, 0xd2, 0xe7, 0x8a, 0x18, 0x2e, 0x12, 0x7b, 0x64, 0xe8, 0xb0, 0xdf, 0x32, 0x63, 0xb4, + 0x21, 0x0f, 0xa0, 0xfc, 0x7a, 0x8c, 0xae, 0x4f, 0x5b, 0x96, 0xad, 0x37, 0xd0, 0x83, 0x7b, 0xf2, + 0x68, 0xbe, 0x0c, 0xde, 0x1f, 0x74, 0xe6, 0xee, 0x91, 0x8d, 0xfa, 0x47, 0xf6, 0x10, 0xa4, 0x5b, + 0x56, 0x83, 0x99, 0x22, 0x7f, 0xb3, 0x92, 0x6a, 0x59, 0x0d, 0xb5, 0x6b, 0xd8, 0xe3, 0xb7, 0x3e, + 0xec, 0x01, 0xad, 0x25, 0x6e, 0x83, 0xd6, 0x92, 0x21, 0xad, 0xa1, 0x07, 0x20, 0xc9, 0x42, 0xa3, + 0xcd, 0x7f, 0x8a, 0xe0, 0x40, 0xb7, 0x9c, 0x34, 0x88, 0xaa, 0x09, 0x1a, 0x34, 0x6d, 0x34, 0x0f, + 0x29, 0x11, 0xaa, 0xf9, 0x0f, 0x5b, 0x1c, 0xed, 0x26, 0x29, 0x72, 0x8c, 0x65, 0xc3, 0x76, 0x54, + 0x17, 0x1f, 0x5d, 0x84, 0x51, 0xdf, 0x5c, 0x48, 0x23, 0x41, 0x28, 0xd1, 0xf1, 0xdb, 0xb1, 0x0a, + 0xde, 0x04, 0x89, 0xce, 0x93, 0xc1, 0xa1, 0x99, 0xcb, 0x68, 0x3f, 0x2a, 0x96, 0x6e, 0x88, 0x45, + 0x19, 0xc3, 0xee, 0x39, 0x93, 0x8c, 0xf5, 0x9e, 0x49, 0xda, 0x30, 0xc6, 0xcc, 0x82, 0xe7, 0x2d, + 0x0f, 0xb8, 0x4d, 0x4a, 0xbb, 0x37, 0xe9, 0x36, 0xf6, 0x00, 0x24, 0x78, 0xd7, 0x22, 0x03, 0xba, + 0xc6, 0xf1, 0x94, 0x1f, 0x97, 0x00, 0x96, 0x69, 0x5c, 0xa3, 0x4b, 0x97, 0x05, 0x18, 0xb7, 0xa9, + 0x08, 0x5a, 0xa0, 0xe5, 0xa3, 0xfd, 0x0c, 0x98, 0xb7, 0x3f, 0x66, 0xfb, 0xe5, 0x5e, 0x80, 0x71, + 0xcf, 0x31, 0x6d, 0x2c, 0x84, 0x39, 0xba, 0xcb, 0xc2, 0xba, 0x8c, 0x1d, 0x75, 0xec, 0x9a, 0xaf, + 0xa4, 0xfc, 0x33, 0x09, 0xd2, 0x54, 0xa6, 0x15, 0xec, 0xe8, 0x01, 0x7b, 0x96, 0x6e, 0xdd, 0x9e, + 0x8f, 0x00, 0x30, 0x36, 0xb6, 0xf1, 0x2c, 0xe6, 0x5e, 0x96, 0xa6, 0x90, 0xb2, 0xf1, 0x2c, 0xf6, + 0x8d, 0x71, 0x74, 0x4f, 0x63, 0x7c, 0x00, 0x92, 0xf4, 0x33, 0x11, 0xd7, 0x6d, 0xbe, 0x96, 0x4e, + 0x98, 0x9d, 0x66, 0xe5, 0xba, 0xad, 0x3c, 0x0d, 0xc9, 0xca, 0x75, 0xb6, 0xf5, 0x77, 0x08, 0xd2, + 0x6d, 0xcb, 0xe2, 0xf9, 0x17, 0x4b, 0x03, 0x52, 0x04, 0x40, 0xd3, 0x0d, 0xb1, 0xdd, 0x15, 0xf1, + 0xb6, 0xbb, 0xbc, 0xfd, 0xba, 0xe8, 0x70, 0xfb, 0x75, 0x5f, 0x95, 0x20, 0x25, 0xcc, 0x1e, 0xe9, + 0x70, 0xa0, 0xd6, 0x69, 0x35, 0x8c, 0x2a, 0xfd, 0xa2, 0x87, 0xe5, 0x60, 0xcd, 0xf5, 0x19, 0xa6, + 0xbe, 0x7b, 0xba, 0xbb, 0x56, 0x10, 0x04, 0x24, 0x27, 0x11, 0x9c, 0x96, 0x46, 0xd4, 0x7d, 0xb5, + 0x5e, 0x15, 0xc8, 0x84, 0xc3, 0x0d, 0x62, 0x38, 0x1a, 0xff, 0xbe, 0xb1, 0xee, 0x38, 0x7a, 0xf5, + 0xaa, 0xd7, 0x0e, 0x1b, 0xf4, 0xfb, 0xba, 0xdb, 0xa1, 0xe6, 0xb6, 0x40, 0x89, 0x72, 0x94, 0xc6, + 0xd7, 0xd6, 0xc1, 0x46, 0xbf, 0x4a, 0xbe, 0xcb, 0xa5, 0x7c, 0x30, 0x02, 0xfb, 0x7a, 0x4a, 0x8a, + 0x4e, 0x41, 0x82, 0xf6, 0x54, 0xe7, 0x5d, 0xdc, 0xdf, 0xc3, 0xde, 0x2c, 0x07, 0xab, 0x71, 0x82, + 0x95, 0x73, 0xd1, 0x37, 0xb9, 0xa4, 0xbb, 0xa2, 0xe7, 0xf7, 0xb6, 0xdf, 0x13, 0xc8, 0x96, 0x39, + 0x2a, 0xb3, 0x0c, 0x2f, 0xe1, 0x61, 0x88, 0x81, 0x08, 0x1b, 0xbf, 0xa5, 0x08, 0xab, 0xfc, 0x6e, + 0x04, 0x0e, 0xf6, 0x55, 0x2a, 0x2a, 0xc1, 0x94, 0xf8, 0x64, 0x17, 0x91, 0xdb, 0xdb, 0xaf, 0x08, + 0x6d, 0xde, 0xf8, 0x06, 0x87, 0xfa, 0x8d, 0x2a, 0xfb, 0xc8, 0x58, 0x74, 0xb8, 0x13, 0xc6, 0x49, + 0xd8, 0xb0, 0x4c, 0x2d, 0x30, 0x4f, 0x8d, 0x31, 0xe0, 0x12, 0x9b, 0xad, 0x56, 0x61, 0x66, 0x73, + 0xe7, 0x59, 0xdd, 0x74, 0x0c, 0x13, 0xfb, 0x16, 0x01, 0xfc, 0x87, 0x74, 0x76, 0xdd, 0x5d, 0x9b, + 0x76, 0x09, 0x7d, 0xe7, 0x7c, 0xbd, 0x15, 0x1f, 0xeb, 0xa3, 0xf8, 0xdb, 0xa1, 0xcf, 0x65, 0x18, + 0xf3, 0xcf, 0x1f, 0xe8, 0x2d, 0xbe, 0x19, 0xa7, 0xc7, 0x8e, 0x73, 0x70, 0xc6, 0xe1, 0xa1, 0xc1, + 0xa5, 0x38, 0xf9, 0x6f, 0x25, 0x18, 0xf5, 0xe5, 0x30, 0xe8, 0x0c, 0xec, 0xcb, 0x2f, 0xaf, 0x2d, + 0x3c, 0xa6, 0x95, 0x0a, 0xda, 0xa5, 0xe5, 0x9c, 0xef, 0x43, 0x03, 0xd9, 0xfd, 0x2f, 0xdc, 0x38, + 0x86, 0x7c, 0xb8, 0x1b, 0x26, 0x3d, 0xc8, 0x40, 0xa7, 0x61, 0x26, 0x48, 0x92, 0xcb, 0x97, 0x8b, + 0xab, 0x15, 0x59, 0xca, 0xee, 0x7b, 0xe1, 0xc6, 0xb1, 0x29, 0x1f, 0x45, 0x6e, 0xd3, 0xc6, 0xa6, + 0xd3, 0x4d, 0xb0, 0xb0, 0xb6, 0xb2, 0x52, 0xaa, 0xc8, 0x91, 0x2e, 0x02, 0x3e, 0xbb, 0xdd, 0x0b, + 0x53, 0x41, 0x82, 0xd5, 0xd2, 0xb2, 0x1c, 0xcd, 0xa2, 0x17, 0x6e, 0x1c, 0x9b, 0xf0, 0x61, 0xaf, + 0x1a, 0x8d, 0x6c, 0xea, 0xf9, 0x4f, 0x1e, 0x1d, 0xf9, 0xb9, 0x9f, 0x39, 0x2a, 0x91, 0x9e, 0x8d, + 0x07, 0xf2, 0x18, 0x74, 0x3f, 0x1c, 0x28, 0x97, 0x16, 0x57, 0x8b, 0x05, 0x6d, 0xa5, 0xbc, 0x18, + 0xfa, 0x60, 0x44, 0x76, 0xf2, 0x85, 0x1b, 0xc7, 0x46, 0x79, 0x97, 0xfa, 0x61, 0xaf, 0xab, 0xc5, + 0x2b, 0x6b, 0x95, 0xa2, 0x2c, 0x31, 0xec, 0xf5, 0x36, 0x26, 0xde, 0x47, 0xb1, 0x1f, 0x80, 0x83, + 0x3d, 0xb0, 0xdd, 0x8e, 0x4d, 0xbd, 0x70, 0xe3, 0xd8, 0xf8, 0x7a, 0x1b, 0xb3, 0x79, 0x8d, 0x52, + 0xcc, 0x41, 0xa6, 0x9b, 0x62, 0x6d, 0x7d, 0xad, 0x9c, 0x5b, 0x96, 0x8f, 0x65, 0xe5, 0x17, 0x6e, + 0x1c, 0x1b, 0x13, 0x09, 0x1b, 0x3d, 0x5f, 0x76, 0x7b, 0xf6, 0x46, 0x6e, 0x46, 0xfe, 0xc5, 0x19, + 0xb8, 0xab, 0xcf, 0xd5, 0x06, 0x71, 0x28, 0xfe, 0xd7, 0x7b, 0xb9, 0x21, 0xdb, 0xff, 0x64, 0x38, + 0x3b, 0xe0, 0xc0, 0x74, 0xf0, 0xc6, 0xda, 0xae, 0xfb, 0x77, 0xca, 0xfb, 0x24, 0x98, 0x58, 0x32, + 0x6c, 0xc7, 0x6a, 0x1b, 0x55, 0xbd, 0x41, 0x1f, 0x8c, 0x9f, 0x1f, 0x36, 0xe7, 0x09, 0x4d, 0xc1, + 0x8f, 0x42, 0xe2, 0x9a, 0xde, 0x60, 0xc9, 0x46, 0x94, 0xfe, 0xea, 0x41, 0x9f, 0x9b, 0x06, 0x6e, + 0x64, 0x11, 0x0c, 0x18, 0x99, 0xf2, 0x0b, 0x11, 0x98, 0xa4, 0xce, 0x60, 0xb3, 0x9f, 0xfd, 0x71, + 0xe8, 0xe7, 0x0c, 0x62, 0x6d, 0xdd, 0xe1, 0x67, 0x55, 0xf9, 0x39, 0x7e, 0xf3, 0xe8, 0xf8, 0x10, + 0x57, 0x38, 0x0a, 0xb8, 0xaa, 0x52, 0x5a, 0xf4, 0x76, 0x48, 0x35, 0xf5, 0xeb, 0x1a, 0xe5, 0xc3, + 0x76, 0x8f, 0x72, 0x7b, 0xe3, 0xf3, 0xda, 0xcd, 0xd9, 0xc9, 0x1d, 0xbd, 0xd9, 0x98, 0x57, 0x04, + 0x1f, 0x45, 0x4d, 0x36, 0xf5, 0xeb, 0x44, 0x44, 0xd4, 0xa2, 0x1f, 0x95, 0xd0, 0xaa, 0xdb, 0xba, + 0x59, 0xc7, 0xac, 0x11, 0x7a, 0xf2, 0x96, 0x5f, 0xda, 0x73, 0x23, 0xfb, 0xbd, 0x46, 0x7c, 0xec, + 0x14, 0x75, 0xbc, 0xa9, 0x5f, 0x5f, 0xa0, 0x00, 0xd2, 0xe2, 0x7c, 0xea, 0xc5, 0x97, 0x66, 0x47, + 0xe8, 0x6d, 0xae, 0x2f, 0x4b, 0x00, 0x9e, 0xc6, 0xd0, 0xdb, 0x41, 0xae, 0xba, 0x25, 0x4a, 0x6b, + 0xbb, 0xb9, 0x46, 0x9f, 0xb1, 0x08, 0xe9, 0x9b, 0x45, 0xe3, 0x97, 0x6f, 0xce, 0x4a, 0xea, 0x64, + 0x35, 0x34, 0x14, 0xdf, 0x07, 0xa3, 0x9d, 0x56, 0x8d, 0x64, 0x33, 0x74, 0x2f, 0x2d, 0x32, 0x30, + 0xb2, 0x1f, 0x25, 0xbc, 0x5e, 0xbb, 0x39, 0x8b, 0x58, 0xb7, 0x7c, 0xc4, 0x0a, 0x8d, 0xf7, 0xc0, + 0x20, 0x84, 0xc0, 0xd7, 0xa7, 0xdf, 0xa6, 0x3f, 0xd8, 0xe4, 0x5d, 0xe5, 0xcf, 0x40, 0xb2, 0x69, + 0x99, 0xc6, 0x55, 0x6e, 0x8f, 0x69, 0x55, 0x14, 0x51, 0x16, 0x52, 0xec, 0x43, 0x6f, 0xce, 0x8e, + 0xf8, 0x75, 0x20, 0x51, 0x26, 0x54, 0xcf, 0xe0, 0x4d, 0xdb, 0x10, 0xa3, 0xa1, 0x8a, 0x22, 0xba, + 0x04, 0xb2, 0x8d, 0xab, 0x9d, 0xb6, 0xe1, 0xec, 0x68, 0x55, 0xcb, 0x74, 0xf4, 0x2a, 0xfb, 0x84, + 0x63, 0x3a, 0x7f, 0xe8, 0xb5, 0x9b, 0xb3, 0x07, 0x98, 0xac, 0x61, 0x0c, 0x45, 0x9d, 0x14, 0xa0, + 0x05, 0x06, 0x21, 0x2d, 0xd4, 0xb0, 0xa3, 0x1b, 0x0d, 0xf6, 0x85, 0x8d, 0xb4, 0x2a, 0x8a, 0xbe, + 0xbe, 0x7c, 0x36, 0xe9, 0x3f, 0x73, 0xba, 0x04, 0xb2, 0xd5, 0xc2, 0xed, 0xc0, 0x62, 0x59, 0x0a, + 0xb7, 0x1c, 0xc6, 0x50, 0xd4, 0x49, 0x01, 0x12, 0x0b, 0x69, 0x87, 0x0c, 0xb3, 0xd8, 0xac, 0x6b, + 0x75, 0x36, 0xbd, 0xa3, 0xaa, 0x99, 0xae, 0xd1, 0xc8, 0x99, 0x3b, 0xf9, 0x07, 0x3d, 0xee, 0x61, + 0x3a, 0xe5, 0x4b, 0x9f, 0x3f, 0x35, 0xc3, 0x4d, 0xc3, 0x3b, 0x3a, 0x22, 0x6b, 0xbd, 0x49, 0x17, + 0x75, 0x9d, 0x62, 0x92, 0xa5, 0xf1, 0xd3, 0xba, 0xd1, 0x10, 0xdf, 0x2d, 0x55, 0x79, 0x09, 0xcd, + 0x43, 0xc2, 0x76, 0x74, 0xa7, 0x63, 0xf3, 0x0b, 0x46, 0x4a, 0x3f, 0x53, 0xcb, 0x5b, 0x66, 0xad, + 0x4c, 0x31, 0x55, 0x4e, 0x81, 0x2e, 0x41, 0x82, 0xdf, 0xdc, 0x8a, 0xef, 0xd9, 0xbf, 0xe9, 0x3d, + 0x49, 0x46, 0x4d, 0x34, 0x52, 0xc3, 0x0d, 0x5c, 0x67, 0xcb, 0x9d, 0x6d, 0xbd, 0x8d, 0xd9, 0x7e, + 0x58, 0x3a, 0x5f, 0xda, 0xb3, 0x13, 0x72, 0x4d, 0x85, 0xf9, 0x29, 0xea, 0xa4, 0x0b, 0x2a, 0x53, + 0x08, 0x7a, 0x2c, 0xf0, 0xe6, 0x84, 0x7f, 0x51, 0xf5, 0xce, 0x7e, 0xdd, 0xf7, 0xd9, 0xb4, 0xd8, + 0x23, 0xf6, 0xbf, 0x58, 0xb9, 0x04, 0x72, 0xc7, 0xdc, 0xb4, 0x4c, 0xfa, 0xc5, 0x11, 0x9e, 0xdb, + 0xa5, 0x48, 0x86, 0xe5, 0x37, 0x8e, 0x30, 0x86, 0xa2, 0x4e, 0xba, 0x20, 0x9e, 0xfb, 0xd5, 0x60, + 0xc2, 0xc3, 0xa2, 0x8e, 0x9a, 0x1e, 0xe8, 0xa8, 0x77, 0x70, 0x47, 0xdd, 0x17, 0x6e, 0xc5, 0xf3, + 0xd5, 0x71, 0x17, 0x48, 0xc8, 0xd0, 0x12, 0x80, 0x17, 0x1e, 0xf8, 0x22, 0x5e, 0x19, 0x1c, 0x63, + 0xc4, 0x9e, 0x94, 0x47, 0x8b, 0x7e, 0x10, 0xa6, 0x9b, 0x86, 0xa9, 0xd9, 0xb8, 0xb1, 0xa5, 0x71, + 0x05, 0x13, 0x96, 0xf4, 0xf7, 0x3c, 0xf2, 0xcb, 0x7b, 0xb3, 0x87, 0xd7, 0x6e, 0xce, 0x66, 0x79, + 0x08, 0xed, 0x66, 0xa9, 0xa8, 0x53, 0x4d, 0xc3, 0x2c, 0xe3, 0xc6, 0x56, 0xc1, 0x85, 0xcd, 0x8f, + 0x3d, 0xff, 0xd2, 0xec, 0x08, 0x77, 0xd7, 0x11, 0xe5, 0x3c, 0x3d, 0xd6, 0xe6, 0x6e, 0x86, 0x6d, + 0x74, 0x18, 0xd2, 0xba, 0x28, 0xf0, 0x1b, 0x6e, 0x1e, 0x80, 0xb9, 0xf9, 0x73, 0x7f, 0x74, 0x4c, + 0x52, 0x3e, 0x2b, 0x41, 0xa2, 0x70, 0x65, 0x5d, 0x37, 0xda, 0x24, 0xd5, 0xf7, 0x2c, 0x27, 0xe8, + 0xe4, 0x87, 0x5f, 0xbb, 0x39, 0x9b, 0x09, 0x1b, 0x97, 0xeb, 0xe5, 0x9e, 0x01, 0x0b, 0x37, 0x2f, + 0xf5, 0xdb, 0x5c, 0x0b, 0xb0, 0xea, 0x42, 0x51, 0xba, 0xb7, 0xde, 0x42, 0xdd, 0x2c, 0x42, 0x92, + 0x49, 0x6b, 0xa3, 0x79, 0x88, 0xb7, 0xc8, 0x1f, 0x3c, 0xa9, 0x3e, 0xda, 0xd7, 0x78, 0x29, 0xbe, + 0x7b, 0xec, 0x44, 0x48, 0x94, 0x0f, 0x45, 0x00, 0x0a, 0x57, 0xae, 0x54, 0xda, 0x46, 0xab, 0x81, + 0x9d, 0xdb, 0xd9, 0xf3, 0x0a, 0xec, 0xf3, 0xed, 0x5e, 0xb4, 0xab, 0xa1, 0xde, 0x1f, 0x7b, 0xed, + 0xe6, 0xec, 0xe1, 0x70, 0xef, 0x7d, 0x68, 0x8a, 0x3a, 0xed, 0xed, 0x63, 0xb4, 0xab, 0x3d, 0xb9, + 0xd6, 0x6c, 0xc7, 0xe5, 0x1a, 0xed, 0xcf, 0xd5, 0x87, 0xe6, 0xe7, 0x5a, 0xb0, 0x9d, 0xde, 0xaa, + 0x2d, 0xc3, 0xa8, 0xa7, 0x12, 0x1b, 0x15, 0x20, 0xe5, 0xf0, 0xbf, 0xb9, 0x86, 0x95, 0xfe, 0x1a, + 0x16, 0x64, 0x62, 0xf9, 0x22, 0x28, 0x95, 0xbf, 0x94, 0x00, 0x3c, 0x9b, 0x7d, 0x73, 0x9a, 0x18, + 0x09, 0xe5, 0x3c, 0xf0, 0x46, 0x6f, 0x29, 0x55, 0xe3, 0xd4, 0x21, 0x7d, 0xbe, 0x3f, 0x02, 0xd3, + 0x1b, 0x22, 0xf2, 0xbc, 0xe9, 0x75, 0xb0, 0x0e, 0x49, 0x6c, 0x3a, 0x6d, 0x03, 0x8b, 0xa5, 0xf6, + 0x03, 0xfd, 0x46, 0xbb, 0x47, 0x9f, 0xe8, 0xaf, 0x96, 0x88, 0x83, 0x4f, 0xce, 0x26, 0xa4, 0x8d, + 0x1f, 0x8d, 0x42, 0xa6, 0x1f, 0x25, 0x5a, 0x80, 0xc9, 0x6a, 0x1b, 0xb3, 0xfb, 0xbe, 0xfe, 0xd3, + 0x89, 0x7c, 0xd6, 0xcb, 0x2c, 0x43, 0x08, 0x8a, 0x3a, 0x21, 0x20, 0x7c, 0xf6, 0xa8, 0x03, 0x49, + 0xfb, 0x88, 0xd9, 0xd1, 0x6b, 0xc3, 0xc3, 0xe5, 0x79, 0x0a, 0x9f, 0x3e, 0x44, 0x23, 0x41, 0x06, + 0x6c, 0xfe, 0x98, 0xf0, 0xa0, 0x74, 0x02, 0x79, 0x07, 0x4c, 0x1a, 0xa6, 0xe1, 0x18, 0x7a, 0x43, + 0xdb, 0xd4, 0x1b, 0x3a, 0x59, 0xd7, 0xef, 0x3d, 0x6b, 0x66, 0x21, 0x9f, 0x37, 0x1b, 0x62, 0xa7, + 0xa8, 0x13, 0x1c, 0x92, 0x67, 0x00, 0xb4, 0x04, 0x49, 0xd1, 0x54, 0xec, 0x96, 0xb2, 0x0d, 0x41, + 0xee, 0x4b, 0xf0, 0x3e, 0x10, 0x85, 0x29, 0x15, 0xd7, 0xfe, 0xcf, 0x50, 0xec, 0x6d, 0x28, 0x56, + 0x00, 0x98, 0xbb, 0x93, 0x00, 0x7b, 0x0b, 0xa3, 0x41, 0x02, 0x46, 0x9a, 0x71, 0x28, 0xd8, 0x8e, + 0x6f, 0x3c, 0x6e, 0x46, 0x60, 0xcc, 0x3f, 0x1e, 0x7f, 0x47, 0x67, 0x25, 0x54, 0xf2, 0x22, 0x51, + 0x8c, 0xff, 0x94, 0x64, 0x9f, 0x48, 0xd4, 0x65, 0xbd, 0xbb, 0x87, 0xa0, 0xff, 0x9a, 0x80, 0xc4, + 0xba, 0xde, 0xd6, 0x9b, 0x36, 0xaa, 0x76, 0x65, 0x9a, 0xe2, 0x58, 0xa0, 0xeb, 0x47, 0xa4, 0xf9, + 0x96, 0xc5, 0x80, 0x44, 0xf3, 0xc5, 0x1e, 0x89, 0xe6, 0xf7, 0xc2, 0x04, 0x59, 0x0e, 0xfb, 0x36, + 0x31, 0x89, 0xb6, 0xc7, 0xf3, 0x07, 0x3d, 0x2e, 0xc1, 0x7a, 0xb6, 0x5a, 0xbe, 0xe2, 0xbf, 0x5e, + 0x38, 0x4a, 0x30, 0xbc, 0xc0, 0x4c, 0xc8, 0xf7, 0x7b, 0xcb, 0x52, 0x5f, 0xa5, 0xa2, 0x42, 0x53, + 0xbf, 0x5e, 0x64, 0x05, 0xb4, 0x0c, 0x68, 0xdb, 0xdd, 0x19, 0xd1, 0x3c, 0x75, 0x12, 0xfa, 0x23, + 0xaf, 0xdd, 0x9c, 0x3d, 0xc8, 0xe8, 0xbb, 0x71, 0x14, 0x75, 0xca, 0x03, 0x0a, 0x6e, 0x0f, 0x01, + 0x90, 0x7e, 0x69, 0xec, 0xf9, 0x16, 0x5b, 0xee, 0xec, 0x7b, 0xed, 0xe6, 0xec, 0x14, 0xe3, 0xe2, + 0xd5, 0x29, 0x6a, 0x9a, 0x14, 0x0a, 0xf4, 0x65, 0x17, 0xcf, 0x8e, 0x43, 0xab, 0x7a, 0xbe, 0xb6, + 0x59, 0xde, 0xf3, 0xda, 0xc6, 0x97, 0x1d, 0x87, 0x58, 0xb2, 0xec, 0x38, 0xb8, 0x1b, 0x80, 0x3e, + 0x26, 0xc1, 0x7e, 0xaa, 0x5d, 0xdf, 0xb6, 0xaf, 0x46, 0x87, 0x92, 0xfd, 0xd8, 0x6e, 0xde, 0xd8, + 0x9b, 0x04, 0xdf, 0xb8, 0x39, 0xdb, 0x87, 0xdf, 0x6b, 0x37, 0x67, 0x8f, 0xf8, 0x46, 0xb3, 0xab, + 0x5e, 0x51, 0xa7, 0xc9, 0xa8, 0x7a, 0xbb, 0xcc, 0x2a, 0x81, 0xa2, 0x9b, 0x12, 0x1c, 0xef, 0x22, + 0xe0, 0x5f, 0x42, 0x6e, 0x62, 0xd3, 0xd1, 0x9c, 0xed, 0x36, 0xb6, 0xb7, 0xad, 0x46, 0x8d, 0x7d, + 0x4d, 0x3d, 0xff, 0x3e, 0x69, 0x6f, 0x31, 0xed, 0x1b, 0x37, 0x67, 0x87, 0x6c, 0xe0, 0xb5, 0x9b, + 0xb3, 0xa7, 0xfa, 0xf4, 0xa0, 0x27, 0xbe, 0xa2, 0x2a, 0xc1, 0x1e, 0x15, 0x3d, 0xac, 0x8a, 0x40, + 0xf2, 0x45, 0xb6, 0x4f, 0x4a, 0x80, 0xbc, 0x29, 0x5f, 0xc5, 0x76, 0x8b, 0xac, 0xcf, 0xc9, 0x42, + 0xcc, 0xb7, 0x6a, 0x92, 0x76, 0x5f, 0x88, 0x79, 0xf4, 0x62, 0x21, 0xe6, 0x8b, 0x94, 0x17, 0xbd, + 0xe9, 0x31, 0x32, 0xe8, 0x19, 0x15, 0x0f, 0x11, 0xe1, 0xf9, 0x70, 0x44, 0xf9, 0x17, 0x12, 0x1c, + 0xec, 0x8a, 0x28, 0xae, 0xb0, 0x3f, 0x00, 0xa8, 0xed, 0xab, 0xe4, 0x3f, 0xdc, 0xc6, 0x84, 0xde, + 0x73, 0x80, 0x9a, 0x6a, 0x77, 0xcd, 0xbb, 0xb7, 0x6f, 0x86, 0x67, 0x8f, 0x25, 0x7f, 0x5d, 0x82, + 0x19, 0x7f, 0xf3, 0x6e, 0x47, 0x56, 0x61, 0xcc, 0xdf, 0x3a, 0xef, 0xc2, 0x5d, 0xc3, 0x74, 0x81, + 0x4b, 0x1f, 0xa0, 0x47, 0x8f, 0x7b, 0xe1, 0x9a, 0xed, 0x9d, 0x9e, 0x19, 0x5a, 0x1b, 0x42, 0xa6, + 0x70, 0xd8, 0x8e, 0xd1, 0xf1, 0xf8, 0xae, 0x04, 0xb1, 0x75, 0xcb, 0x6a, 0x20, 0x0b, 0xa6, 0x4c, + 0xcb, 0xd1, 0x48, 0x64, 0xc1, 0x35, 0xff, 0x73, 0xb9, 0x74, 0x7e, 0x61, 0xcf, 0x2e, 0xd1, 0xcd, + 0x4a, 0x9d, 0x34, 0x2d, 0x27, 0x4f, 0x21, 0xfc, 0xc5, 0xdc, 0x0f, 0xc2, 0x78, 0xb0, 0x31, 0x36, + 0x4b, 0x3e, 0xb1, 0xe7, 0xc6, 0x82, 0x6c, 0x5e, 0xbb, 0x39, 0x3b, 0xe3, 0x45, 0x4c, 0x17, 0xac, + 0xa8, 0x63, 0x9b, 0xbe, 0xd6, 0xd9, 0xcd, 0xfc, 0x6f, 0xbd, 0x34, 0x2b, 0x9d, 0xfc, 0x15, 0x09, + 0xc0, 0xdb, 0x79, 0x42, 0xf7, 0xc3, 0x81, 0xfc, 0xda, 0x6a, 0x41, 0x2b, 0x57, 0x72, 0x95, 0x8d, + 0x72, 0xf0, 0x69, 0x99, 0x38, 0x1e, 0xb1, 0x5b, 0xb8, 0x4a, 0x7f, 0x33, 0x0e, 0x1d, 0x87, 0x99, + 0x20, 0x36, 0x29, 0x15, 0x0b, 0xb2, 0x94, 0x1d, 0x7b, 0xe1, 0xc6, 0xb1, 0x14, 0xcb, 0xc5, 0x71, + 0x0d, 0x9d, 0x80, 0x7d, 0xdd, 0x78, 0xa5, 0xd5, 0x45, 0x39, 0x92, 0x1d, 0x7f, 0xe1, 0xc6, 0xb1, + 0xb4, 0x9b, 0xb4, 0x23, 0x05, 0x90, 0x1f, 0x93, 0xf3, 0x8b, 0x66, 0xe1, 0x85, 0x1b, 0xc7, 0x12, + 0x4c, 0x81, 0xd9, 0xd8, 0xf3, 0x9f, 0x3c, 0x3a, 0x72, 0xdb, 0x1f, 0xa0, 0xfd, 0x79, 0xb2, 0xef, + 0xa9, 0x47, 0x1d, 0x9b, 0xd8, 0x36, 0xec, 0x01, 0xa7, 0x1e, 0x43, 0x9d, 0x99, 0xf4, 0xb9, 0xb2, + 0xfd, 0xfb, 0x71, 0x18, 0x5b, 0x64, 0xad, 0xb0, 0x9f, 0xba, 0x7f, 0x0b, 0x24, 0x5a, 0x34, 0x8d, + 0x70, 0xaf, 0x37, 0xf4, 0x31, 0x78, 0x96, 0x6c, 0xb8, 0xd7, 0xec, 0x59, 0xea, 0x61, 0xf3, 0x0b, + 0x95, 0xec, 0x54, 0xd2, 0xbb, 0xd0, 0x3e, 0xb6, 0xa7, 0xfd, 0x3e, 0x96, 0xb3, 0xf2, 0xad, 0xb5, + 0x30, 0x3f, 0x85, 0xdd, 0xcd, 0xac, 0x10, 0x08, 0x3b, 0xd7, 0x7c, 0x8f, 0x04, 0xfb, 0x28, 0x56, + 0xe8, 0x58, 0x59, 0x2c, 0xf6, 0x4e, 0xf6, 0xeb, 0xc2, 0xb2, 0x6e, 0x7b, 0xf7, 0x2d, 0xd9, 0x55, + 0xfb, 0xbb, 0x78, 0x22, 0x74, 0xd8, 0xd7, 0x78, 0x98, 0xad, 0xa2, 0x4e, 0x37, 0xba, 0x28, 0x6d, + 0xb4, 0x18, 0x78, 0x6b, 0x11, 0xdb, 0xdb, 0x51, 0x8b, 0xff, 0xdd, 0xc5, 0x65, 0x18, 0xf5, 0x62, + 0x89, 0x4d, 0x7f, 0x92, 0x7b, 0x2f, 0x73, 0x87, 0x9f, 0x18, 0xbd, 0x57, 0x82, 0x7d, 0x5e, 0x36, + 0xe7, 0x67, 0x9b, 0xa0, 0x6c, 0xef, 0xdb, 0xc3, 0x42, 0x38, 0xac, 0x9c, 0x9e, 0x7c, 0x15, 0x75, + 0xa6, 0xd3, 0x4d, 0x4a, 0x96, 0xe0, 0xe3, 0xfe, 0xc8, 0x6a, 0x67, 0xc4, 0xcf, 0xe3, 0x0c, 0x1f, + 0x9a, 0x83, 0x0c, 0x50, 0x16, 0x52, 0xf8, 0x7a, 0xcb, 0x6a, 0x3b, 0x98, 0x25, 0x11, 0x29, 0xd5, + 0x2d, 0x2b, 0xab, 0x80, 0xba, 0x07, 0x37, 0xfc, 0xb6, 0xc4, 0x7b, 0x16, 0x8b, 0x66, 0x20, 0xee, + 0x7f, 0x7d, 0xc1, 0x0a, 0xf3, 0xa9, 0xe7, 0xf9, 0xf4, 0x79, 0xdb, 0x7d, 0xfe, 0x2b, 0x11, 0x38, + 0xe9, 0x3f, 0xab, 0x7c, 0x47, 0x07, 0xb7, 0x77, 0x5c, 0xc7, 0x6d, 0xe9, 0x75, 0xc3, 0xf4, 0x3f, + 0xbe, 0x3c, 0xe8, 0x9f, 0xf0, 0x29, 0xae, 0xd0, 0x93, 0xf2, 0xbc, 0x04, 0xa3, 0xeb, 0x7a, 0x1d, + 0xab, 0xf8, 0x1d, 0x1d, 0x6c, 0x3b, 0x3d, 0x1e, 0xb7, 0xed, 0x87, 0x84, 0xb5, 0xb5, 0x25, 0xee, + 0x1a, 0xc5, 0x54, 0x5e, 0x22, 0x7d, 0x6e, 0x18, 0x4d, 0x83, 0x5d, 0xc9, 0x8e, 0xa9, 0xac, 0x80, + 0x66, 0x61, 0xb4, 0x6a, 0x75, 0x4c, 0xee, 0x72, 0x99, 0x98, 0xf8, 0xc4, 0x5b, 0xc7, 0x64, 0x2e, + 0x47, 0x94, 0xd8, 0xc6, 0xd7, 0x70, 0xdb, 0x66, 0xbf, 0xbc, 0x93, 0x52, 0x45, 0x51, 0x79, 0x14, + 0xc6, 0x98, 0x24, 0x7c, 0x32, 0x3e, 0x08, 0x29, 0x7a, 0xdb, 0xd9, 0x93, 0x27, 0x49, 0xca, 0x8f, + 0xb1, 0x27, 0x72, 0x8c, 0x3f, 0x13, 0x89, 0x15, 0xf2, 0xf9, 0xbe, 0x5a, 0x3e, 0x31, 0x38, 0x6a, + 0x30, 0x1d, 0xba, 0x1a, 0xfe, 0x42, 0x1c, 0xf6, 0xf1, 0x13, 0x58, 0xbd, 0x65, 0x9c, 0xde, 0x76, + 0x1c, 0xf1, 0x64, 0x13, 0xf8, 0x2a, 0x48, 0x6f, 0x19, 0xca, 0x0e, 0xc4, 0x96, 0x1c, 0xa7, 0x85, + 0x4e, 0x42, 0xbc, 0xdd, 0x69, 0x60, 0xb1, 0x19, 0xe8, 0x1e, 0xd7, 0xe8, 0x2d, 0x63, 0x8e, 0x20, + 0xa8, 0x9d, 0x06, 0x56, 0x19, 0x0a, 0x2a, 0xc2, 0xec, 0x56, 0xa7, 0xd1, 0xd8, 0xd1, 0x6a, 0x98, + 0x7e, 0x18, 0xdc, 0xfd, 0x01, 0x7d, 0x7c, 0xbd, 0xa5, 0x8b, 0x9f, 0xf4, 0x21, 0x8a, 0x39, 0x4c, + 0xd1, 0x0a, 0x14, 0x4b, 0xfc, 0xf2, 0x7d, 0x51, 0xe0, 0x28, 0x7f, 0x18, 0x81, 0x94, 0x60, 0x4d, + 0x6c, 0xd9, 0xc6, 0x0d, 0x5c, 0x75, 0x2c, 0x71, 0x98, 0xe6, 0x96, 0x11, 0x82, 0x68, 0x9d, 0x0f, + 0x5e, 0x7a, 0x69, 0x44, 0x25, 0x05, 0x02, 0x73, 0x5f, 0x12, 0x12, 0x58, 0xab, 0x43, 0xc6, 0x33, + 0xd6, 0xb2, 0xc4, 0xaa, 0x7d, 0x69, 0x44, 0xa5, 0x25, 0x94, 0x81, 0x04, 0x71, 0x1a, 0x87, 0x8d, + 0x16, 0x81, 0xf3, 0x32, 0xda, 0x0f, 0xf1, 0x96, 0xee, 0x54, 0xd9, 0x8d, 0x77, 0x52, 0xc1, 0x8a, + 0xe8, 0x61, 0x48, 0xb0, 0x8f, 0xc1, 0x50, 0xaf, 0x1a, 0x3d, 0x7b, 0xc4, 0xaf, 0x0c, 0xf6, 0xd5, + 0x5d, 0x22, 0xf7, 0xba, 0xee, 0x38, 0xb8, 0x6d, 0x12, 0x86, 0x0c, 0x1d, 0x21, 0x88, 0x6d, 0x5a, + 0x35, 0xf6, 0x83, 0xbf, 0x69, 0x95, 0xfe, 0x8d, 0xee, 0x24, 0x6e, 0xcf, 0xec, 0x41, 0xa3, 0x95, + 0x63, 0xec, 0xeb, 0x21, 0x02, 0x98, 0x27, 0x48, 0x45, 0x98, 0xd6, 0x6b, 0xec, 0x63, 0xde, 0x7a, + 0x43, 0xdb, 0x34, 0x68, 0xf0, 0xb0, 0x33, 0xa3, 0xbb, 0x8c, 0x05, 0xf2, 0x08, 0xf2, 0x1c, 0x3f, + 0x9f, 0x86, 0x64, 0x8b, 0x09, 0xa5, 0x3c, 0x02, 0x53, 0x5d, 0x92, 0x12, 0xf9, 0xae, 0x1a, 0x66, + 0x4d, 0x3c, 0xaf, 0x24, 0x7f, 0x13, 0x18, 0xfd, 0x4c, 0x3a, 0x3b, 0xa6, 0xa4, 0x7f, 0xe7, 0xdf, + 0xdd, 0xff, 0x15, 0xee, 0x84, 0xef, 0x15, 0xae, 0xde, 0x32, 0xf2, 0x69, 0xca, 0x9f, 0xbf, 0xbd, + 0xcd, 0x75, 0xbf, 0xbd, 0xad, 0x63, 0x53, 0x4c, 0xb9, 0xa4, 0x4a, 0x6f, 0x19, 0x36, 0x35, 0x47, + 0xef, 0xbb, 0xed, 0xf6, 0x23, 0xbe, 0xbf, 0xe9, 0x53, 0xdc, 0xd8, 0x62, 0x6e, 0xbd, 0xe4, 0xda, + 0xf1, 0x6f, 0x46, 0xe0, 0xb0, 0xcf, 0x8e, 0x7d, 0xc8, 0xdd, 0xe6, 0x9c, 0xed, 0x6d, 0xf1, 0x43, + 0x3c, 0x71, 0x7a, 0x0c, 0x62, 0x04, 0x1f, 0x0d, 0xf8, 0xed, 0xfe, 0xcc, 0xe7, 0xbe, 0xf4, 0x6b, + 0x4a, 0xf0, 0x40, 0x33, 0x30, 0x2a, 0x94, 0x49, 0xfe, 0xbd, 0xc3, 0xeb, 0x4f, 0xf6, 0xbe, 0x07, + 0x6f, 0xdf, 0x3e, 0x35, 0x86, 0x75, 0xf8, 0xd5, 0x73, 0x7d, 0x3f, 0x99, 0xc1, 0x82, 0xe9, 0xee, + 0xf9, 0xd5, 0x1e, 0x22, 0xf5, 0xeb, 0xc9, 0xc5, 0xb2, 0xbb, 0x8e, 0xb3, 0x72, 0x1d, 0xf6, 0x3f, + 0x4e, 0xda, 0xf6, 0x76, 0x50, 0x44, 0xc8, 0xdf, 0xef, 0x1e, 0xf4, 0x32, 0xcb, 0xf6, 0x0e, 0x71, + 0xc1, 0x93, 0x8f, 0xaf, 0x1d, 0x8f, 0xcf, 0xf5, 0x9d, 0x4a, 0xe6, 0x7c, 0xd3, 0x88, 0xea, 0xa3, + 0x54, 0x3e, 0x23, 0xc1, 0x81, 0xae, 0xa6, 0x79, 0x8c, 0x5f, 0xec, 0xf1, 0xc0, 0xf4, 0x96, 0x92, + 0x9e, 0xc5, 0x1e, 0xc2, 0xde, 0x33, 0x50, 0x58, 0x26, 0x45, 0x40, 0xda, 0xb7, 0xc2, 0xbe, 0xa0, + 0xb0, 0x42, 0x4d, 0x77, 0xc3, 0x44, 0xf0, 0xb0, 0x80, 0xab, 0x6b, 0x3c, 0x70, 0x5c, 0xa0, 0x68, + 0x61, 0x3d, 0xbb, 0x7d, 0x2d, 0x42, 0xda, 0x45, 0xe5, 0xd9, 0xf1, 0xd0, 0x5d, 0xf5, 0x28, 0x95, + 0x0f, 0x49, 0x70, 0x2c, 0xd8, 0x82, 0x2f, 0x4f, 0xda, 0x9b, 0xb0, 0xb7, 0x6d, 0x88, 0x5f, 0x95, + 0xe0, 0x8e, 0x5d, 0x64, 0xe2, 0x0a, 0x78, 0x16, 0x66, 0x7c, 0x9b, 0x04, 0x22, 0x84, 0x8b, 0x61, + 0x3f, 0x39, 0x38, 0x43, 0x75, 0xd7, 0xc4, 0x87, 0x88, 0x52, 0x3e, 0xfd, 0x95, 0xd9, 0xe9, 0xee, + 0x3a, 0x5b, 0x9d, 0xee, 0x5e, 0xd8, 0xdf, 0x46, 0xfb, 0xf8, 0xa8, 0x04, 0xf7, 0x06, 0xbb, 0xda, + 0x23, 0xd5, 0xfd, 0x9b, 0x1a, 0x87, 0x7f, 0x27, 0xc1, 0xc9, 0x61, 0x84, 0xe3, 0x03, 0xb2, 0x09, + 0xd3, 0x5e, 0x12, 0x1e, 0x1e, 0x8f, 0x3d, 0xa5, 0xf6, 0xcc, 0x4a, 0x91, 0xcb, 0xed, 0x0d, 0x50, + 0x7c, 0x8b, 0x3b, 0x96, 0x7f, 0xc8, 0x5d, 0x25, 0x07, 0x37, 0xfa, 0x85, 0x92, 0x03, 0x5b, 0xfd, + 0x3d, 0xc6, 0x22, 0xd2, 0x63, 0x2c, 0xbc, 0xac, 0x5d, 0xb9, 0xc6, 0xe3, 0x56, 0x8f, 0xed, 0xb9, + 0xef, 0x83, 0xe9, 0x1e, 0xa6, 0xcc, 0xbd, 0x7a, 0x0f, 0x96, 0xac, 0xa2, 0x6e, 0x63, 0x55, 0x76, + 0x60, 0x96, 0xb6, 0xdb, 0x43, 0xd1, 0x6f, 0x74, 0x97, 0x9b, 0x3c, 0xb6, 0xf4, 0x6c, 0x9a, 0xf7, + 0xbd, 0x04, 0x09, 0x36, 0xce, 0xbc, 0xbb, 0xb7, 0x60, 0x28, 0x9c, 0x81, 0xf2, 0x93, 0x22, 0x96, + 0x15, 0x84, 0xd8, 0xbd, 0x7d, 0x68, 0x98, 0xbe, 0xde, 0x26, 0x1f, 0xf2, 0x29, 0xe3, 0xcb, 0x22, + 0xaa, 0xf5, 0x96, 0x8e, 0xab, 0xa3, 0x7a, 0xdb, 0xa2, 0x1a, 0xd3, 0xcd, 0x1b, 0x1b, 0xbe, 0x7e, + 0x46, 0x84, 0x2f, 0xb7, 0x4f, 0x03, 0xc2, 0xd7, 0xdf, 0x8c, 0xea, 0xdd, 0x40, 0x36, 0x40, 0xcc, + 0xbf, 0x8d, 0x81, 0xec, 0x5b, 0x12, 0x1c, 0xa4, 0x7d, 0xf3, 0xef, 0x51, 0xec, 0x55, 0xe5, 0xf7, + 0x03, 0xb2, 0xdb, 0x55, 0xad, 0xa7, 0x77, 0xcb, 0x76, 0xbb, 0x7a, 0x25, 0x30, 0xbf, 0xdc, 0x0f, + 0xa8, 0x16, 0xd8, 0x89, 0xa2, 0xd8, 0xec, 0x02, 0xa5, 0x5c, 0xf3, 0x6d, 0x74, 0xf4, 0x18, 0xce, + 0xd8, 0x6d, 0x18, 0xce, 0x97, 0x25, 0xc8, 0xf6, 0xea, 0x32, 0x1f, 0x3e, 0x03, 0xf6, 0x07, 0xce, + 0x0f, 0xc2, 0x23, 0x78, 0xff, 0x30, 0xbb, 0x3c, 0x21, 0x37, 0xda, 0xd7, 0xc6, 0x6f, 0x74, 0x1e, + 0x30, 0x1b, 0xb4, 0xd0, 0xee, 0xcc, 0xfa, 0x6f, 0xcc, 0x7d, 0x3e, 0xdf, 0x15, 0x57, 0xff, 0x56, + 0xe4, 0xde, 0xd7, 0xe1, 0x68, 0x1f, 0xa9, 0xdf, 0xe8, 0x79, 0x6f, 0xbb, 0xef, 0x60, 0xde, 0xee, + 0xf4, 0xfd, 0x21, 0xee, 0x09, 0xc1, 0xcb, 0xf9, 0xbe, 0xb5, 0x58, 0xaf, 0x17, 0xc8, 0xca, 0x53, + 0x70, 0xa8, 0x27, 0x15, 0x97, 0x6d, 0x1e, 0x62, 0xdb, 0x86, 0xed, 0x70, 0xb1, 0x8e, 0xf7, 0x13, + 0x2b, 0x44, 0x4d, 0x69, 0x14, 0x04, 0x32, 0x65, 0xbd, 0x6e, 0x59, 0x0d, 0x2e, 0x86, 0xf2, 0x18, + 0x4c, 0xf9, 0x60, 0xbc, 0x91, 0xf3, 0x10, 0x6b, 0x59, 0x56, 0xc3, 0x7d, 0xe0, 0xd4, 0x6f, 0x63, + 0xdf, 0xb2, 0x1a, 0xbc, 0xdb, 0x14, 0x5f, 0x99, 0x01, 0xc4, 0x98, 0xd1, 0x3d, 0x7e, 0xd1, 0x44, + 0x19, 0xa6, 0x03, 0x50, 0xde, 0xc8, 0xeb, 0x3a, 0x3f, 0x38, 0xfb, 0x8d, 0x7d, 0x10, 0xa7, 0x5c, + 0xd1, 0x47, 0xa4, 0xc0, 0x17, 0x0d, 0xe7, 0xfa, 0xb1, 0xe9, 0xbd, 0x26, 0xce, 0x9e, 0x1e, 0x1a, + 0x9f, 0xe7, 0x6c, 0x27, 0xdf, 0xfd, 0xaf, 0xbe, 0xfa, 0xe1, 0xc8, 0x5d, 0x48, 0x39, 0xdd, 0x67, + 0x05, 0xef, 0xf3, 0x97, 0x4f, 0x05, 0xbe, 0x58, 0x74, 0x6a, 0xb8, 0xa6, 0x84, 0x64, 0x73, 0xc3, + 0xa2, 0x73, 0xc1, 0x1e, 0xa1, 0x82, 0x9d, 0x43, 0x0f, 0x0e, 0x16, 0xec, 0xf4, 0x3b, 0x83, 0x4e, + 0xf3, 0x43, 0xe8, 0xf7, 0x25, 0x98, 0xe9, 0xb5, 0xa4, 0x43, 0x17, 0x86, 0x93, 0xa2, 0x3b, 0xa5, + 0xc8, 0x5e, 0xbc, 0x05, 0x4a, 0xde, 0x95, 0x45, 0xda, 0x95, 0x1c, 0x7a, 0xf4, 0x16, 0xba, 0x72, + 0xda, 0xbf, 0xf5, 0xff, 0xdf, 0x25, 0x38, 0xb2, 0xeb, 0x0a, 0x09, 0xe5, 0x86, 0x93, 0x72, 0x97, + 0xdc, 0x29, 0x9b, 0x7f, 0x3d, 0x2c, 0x78, 0x8f, 0x1f, 0xa7, 0x3d, 0x7e, 0x0c, 0x95, 0x6e, 0xa5, + 0xc7, 0x3d, 0xcf, 0x57, 0xd0, 0x6f, 0x05, 0x2f, 0x9d, 0xee, 0x6e, 0x4e, 0x5d, 0x0b, 0x8f, 0x01, + 0x8e, 0xd1, 0x9d, 0xd4, 0x2a, 0x4f, 0xd2, 0x2e, 0xa8, 0x68, 0xfd, 0x75, 0x0e, 0xda, 0xe9, 0x77, + 0x06, 0x03, 0xff, 0x0f, 0xa1, 0xff, 0x26, 0xf5, 0xbe, 0x43, 0xfa, 0xf0, 0xae, 0x22, 0xf6, 0x5f, + 0x54, 0x65, 0x2f, 0xec, 0x9d, 0x90, 0x77, 0xb2, 0x49, 0x3b, 0x59, 0x47, 0xf8, 0x76, 0x77, 0xb2, + 0xe7, 0x20, 0xa2, 0xdf, 0x96, 0x60, 0xa6, 0xd7, 0x9a, 0x64, 0x80, 0x5b, 0xee, 0xb2, 0xc8, 0x1a, + 0xe0, 0x96, 0xbb, 0x2d, 0x80, 0x94, 0xb7, 0xd0, 0xce, 0x9f, 0x47, 0x0f, 0xf5, 0xeb, 0xfc, 0xae, + 0xa3, 0x48, 0x7c, 0x71, 0xd7, 0x24, 0x7f, 0x80, 0x2f, 0x0e, 0xb3, 0x8e, 0x19, 0xe0, 0x8b, 0x43, + 0xad, 0x31, 0x06, 0xfb, 0xa2, 0xdb, 0xb3, 0x21, 0x87, 0xd1, 0x46, 0xbf, 0x29, 0xc1, 0x78, 0x20, + 0x23, 0x46, 0x67, 0x76, 0x15, 0xb4, 0xd7, 0x82, 0x21, 0x7b, 0x76, 0x2f, 0x24, 0xbc, 0x2f, 0x25, + 0xda, 0x97, 0x05, 0x94, 0xbb, 0x95, 0xbe, 0x04, 0x8f, 0x51, 0x5f, 0x96, 0x60, 0xba, 0x47, 0x96, + 0x39, 0xc0, 0x0b, 0xfb, 0x27, 0xcd, 0xd9, 0x0b, 0x7b, 0x27, 0xe4, 0xbd, 0xba, 0x44, 0x7b, 0xf5, + 0xbd, 0xe8, 0xad, 0xb7, 0xd2, 0x2b, 0xdf, 0xfc, 0x7c, 0xd3, 0xbb, 0x92, 0xe5, 0x6b, 0x07, 0x9d, + 0xdf, 0xa3, 0x60, 0xa2, 0x43, 0x0f, 0xef, 0x99, 0x8e, 0xf7, 0xe7, 0x09, 0xda, 0x9f, 0xc7, 0xd1, + 0xda, 0xeb, 0xeb, 0x4f, 0xf7, 0xb4, 0xfe, 0xcb, 0xdd, 0x8f, 0x43, 0x77, 0xb7, 0xa2, 0x9e, 0xc9, + 0x6a, 0xf6, 0xc1, 0x3d, 0xd1, 0xf0, 0x4e, 0x5d, 0xa0, 0x9d, 0x3a, 0x8b, 0x1e, 0xe8, 0xd7, 0x29, + 0xdf, 0xbd, 0x4b, 0xc3, 0xdc, 0xb2, 0x4e, 0xbf, 0x93, 0xa5, 0xc0, 0x3f, 0x84, 0xde, 0x25, 0xee, + 0x3c, 0x9d, 0xd8, 0xb5, 0x5d, 0x5f, 0x1e, 0x9b, 0xbd, 0x77, 0x08, 0x4c, 0x2e, 0xd7, 0x5d, 0x54, + 0xae, 0xa3, 0xe8, 0x70, 0x3f, 0xb9, 0x48, 0x2e, 0x8b, 0xde, 0x27, 0xb9, 0xd7, 0x64, 0x4f, 0xee, + 0xce, 0xdb, 0x9f, 0xec, 0x66, 0xef, 0x1b, 0x0a, 0x97, 0x4b, 0x72, 0x9c, 0x4a, 0x72, 0x0c, 0x1d, + 0xed, 0x2b, 0x09, 0x4b, 0x7d, 0x6f, 0xf7, 0xa5, 0x82, 0xff, 0xb9, 0x1f, 0x66, 0xfb, 0xb4, 0xe8, + 0x5c, 0x7f, 0x9d, 0x2f, 0xa7, 0x87, 0x3b, 0xd7, 0xba, 0x9d, 0xef, 0xab, 0x07, 0xbd, 0x9f, 0x56, + 0x7e, 0x37, 0x06, 0x68, 0xc5, 0xae, 0x2f, 0xb4, 0xb1, 0xee, 0xf8, 0x3e, 0xc3, 0x19, 0x7a, 0xfc, + 0x27, 0xbd, 0xae, 0xc7, 0x7f, 0x2b, 0x81, 0xe7, 0x74, 0x91, 0xbd, 0x3d, 0xd9, 0x1d, 0xfa, 0x4d, + 0x5d, 0xf4, 0xaf, 0xe5, 0x4d, 0x5d, 0xef, 0x2b, 0xf7, 0xb1, 0xdb, 0xf7, 0x36, 0x27, 0x7e, 0xab, + 0xef, 0x93, 0xf8, 0x53, 0xd9, 0xc4, 0x2e, 0x4f, 0x65, 0x33, 0x7d, 0xdf, 0xc3, 0x72, 0x6a, 0x74, + 0x4e, 0x7c, 0x60, 0x3d, 0x39, 0xdc, 0x25, 0x59, 0xfe, 0x05, 0x76, 0x6f, 0x0b, 0xe1, 0x30, 0x64, + 0xbb, 0xcd, 0xc9, 0x75, 0xea, 0x0f, 0x47, 0x41, 0x5e, 0xb1, 0xeb, 0xc5, 0x9a, 0xe1, 0xbc, 0x41, + 0xb6, 0xf6, 0x68, 0xff, 0xf7, 0x4e, 0xe8, 0xb5, 0x9b, 0xb3, 0x13, 0x4c, 0xa7, 0xbb, 0x68, 0xb2, + 0x09, 0x93, 0xe1, 0xfb, 0xe8, 0xcc, 0xb2, 0x0a, 0xb7, 0xf2, 0xd8, 0xbd, 0xeb, 0x1e, 0xfa, 0x44, + 0xf0, 0xdd, 0x39, 0xba, 0xde, 0xdb, 0x98, 0x99, 0x41, 0x2d, 0xbd, 0x91, 0x8f, 0x43, 0xbd, 0x31, + 0xcb, 0x42, 0x26, 0x3c, 0x28, 0xee, 0x88, 0xbd, 0x22, 0xc1, 0xe8, 0x8a, 0x2d, 0x52, 0x41, 0xfc, + 0x26, 0x7d, 0x9a, 0xf6, 0xb0, 0xfb, 0x13, 0x31, 0xd1, 0xe1, 0xec, 0xd6, 0xff, 0xb3, 0x31, 0x23, + 0xca, 0x3e, 0x98, 0xf6, 0xf5, 0xd1, 0xed, 0xfb, 0x97, 0x22, 0x34, 0x36, 0xe6, 0x71, 0xdd, 0x30, + 0xdd, 0x0c, 0x12, 0xff, 0x5d, 0x7d, 0x74, 0xe3, 0xe9, 0x38, 0x76, 0x2b, 0x3a, 0xbe, 0x4a, 0x03, + 0x43, 0x48, 0x97, 0xee, 0x86, 0xd7, 0x4a, 0xf7, 0x73, 0x30, 0x69, 0x0f, 0xdf, 0xd6, 0x09, 0x3d, + 0xfa, 0x52, 0xbe, 0x2a, 0xc1, 0xf8, 0x8a, 0x5d, 0xdf, 0x30, 0x6b, 0xff, 0x5b, 0xdb, 0xed, 0x16, + 0xec, 0x0b, 0xf4, 0xf2, 0x0d, 0x52, 0xe7, 0xd9, 0x8f, 0xc6, 0x20, 0xba, 0x62, 0xd7, 0xd1, 0x3b, + 0x60, 0x32, 0x9c, 0x28, 0xf4, 0xcd, 0xff, 0xba, 0x67, 0x81, 0xfe, 0x6b, 0xb4, 0xfe, 0x33, 0x06, + 0xba, 0x0a, 0xe3, 0xc1, 0xd9, 0xe2, 0xc4, 0x2e, 0x4c, 0x02, 0x98, 0xd9, 0x07, 0x86, 0xc5, 0x74, + 0x1b, 0x7b, 0x3b, 0xa4, 0xdc, 0x40, 0x77, 0xe7, 0x2e, 0xd4, 0x02, 0xa9, 0x7f, 0x46, 0xdb, 0x23, + 0x9c, 0x10, 0xed, 0x85, 0x43, 0xc9, 0x6e, 0xda, 0x0b, 0xe1, 0xee, 0xaa, 0xbd, 0x7e, 0x6e, 0xb5, + 0x09, 0xe0, 0xf3, 0x81, 0xbb, 0x77, 0xe1, 0xe0, 0xa1, 0x65, 0x4f, 0x0d, 0x85, 0xe6, 0x1e, 0x34, + 0xdd, 0xe6, 0x04, 0xfc, 0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, 0xbe, 0x0a, 0xc7, 0xec, 0x94, 0xb7, + 0x00, 0x00, } r := bytes.NewReader(gzipped) gzipr, err := compress_gzip.NewReader(r) diff --git a/sei-tendermint/cmd/buf_plugin/main.go b/sei-tendermint/cmd/buf_plugin/main.go index 2e20575748..e1ec2a8086 100644 --- a/sei-tendermint/cmd/buf_plugin/main.go +++ b/sei-tendermint/cmd/buf_plugin/main.go @@ -4,29 +4,26 @@ import ( "fmt" "iter" "log" + "errors" "google.golang.org/protobuf/compiler/protogen" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/descriptorpb" "google.golang.org/protobuf/types/dynamicpb" + "google.golang.org/protobuf/types/pluginpb" + "google.golang.org/protobuf/reflect/protodesc" + "google.golang.org/protobuf/reflect/protoregistry" ) +func (d md) GetBoolOption(ext protoreflect.ExtensionTypeDescriptor) bool { + options := d.Options().(*descriptorpb.MessageOptions).ProtoReflect() + if !options.Has(ext) { return false } + return options.Get(ext).Bool() +} type md struct{ protoreflect.MessageDescriptor } type mds = map[protoreflect.FullName]md -func getExtType(p *protogen.Plugin, name protoreflect.FullName) (protoreflect.ExtensionType, bool) { - for _, file := range p.Files { - es := file.Desc.Extensions() - for i := range es.Len() { - if e := es.Get(i); e.FullName() == name { - return dynamicpb.NewExtensionType(e), true - } - } - } - return nil, false -} - func (d md) walk(yield func(md) bool) bool { if !yield(d) { return false @@ -40,10 +37,10 @@ func (d md) walk(yield func(md) bool) bool { return true } -func allMDs(plugin *protogen.Plugin) iter.Seq[md] { +func allMDs(files *protoregistry.Files) iter.Seq[md] { return func(yield func(md) bool) { - for _, file := range plugin.Files { - descs := file.Desc.Messages() + for file := range files.RangeFiles { + descs := file.Messages() for i := range descs.Len() { if !(md{descs.Get(i)}).walk(yield) { return @@ -53,50 +50,60 @@ func allMDs(plugin *protogen.Plugin) iter.Seq[md] { } } -func (d md) GetBoolOption(opt protoreflect.ExtensionType) bool { - options, ok := d.Options().(*descriptorpb.MessageOptions) - if !ok || !proto.HasExtension(options, opt) { - return false - } - has, ok := proto.GetExtension(options, opt).(bool) - return ok && has +func OrPanic(err error) { + if err!=nil { panic(err) } +} + +func OrPanic1[T any](v T, err error) T { + OrPanic(err) + return v } -// run reads the proto descriptors and checks that the can_hash messages satisfy the following constraints: -// * all can_hash messages have to use proto3 syntax -// * message fields of can_hash messages have to be can_hash as well -// * fields of can_hash messages have to be repeated/optional (explicit presence) -// * fields of can_hash messages cannot be maps +// run reads the proto descriptors and checks that the hashable messages satisfy the following constraints: +// * all hashable messages have to use proto3 syntax +// * message fields of hashable messages have to be hashable as well +// * fields of hashable messages have to be repeated/optional (explicit presence) +// * fields of hashable messages cannot be maps func run(p *protogen.Plugin) error { - canHashName := protoreflect.FullName("tendermint.utils.can_hash") - canHashOpt, ok := getExtType(p, canHashName) - if !ok { - // When the module being processed does not declare the extension we have nothing to validate. - return nil + p.SupportedFeatures = uint64(pluginpb.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL) + + fds := &descriptorpb.FileDescriptorSet{File: p.Request.ProtoFile} + // Re-unmarshal proto files, so that dynamic options are registered. + OrPanic(proto.UnmarshalOptions{ + Resolver: dynamicpb.NewTypes(OrPanic1(protodesc.NewFiles(fds))), + }.Unmarshal(OrPanic1(proto.Marshal(fds)),fds)) + files := OrPanic1(protodesc.NewFiles(fds)) + + hashableOpt,err := dynamicpb.NewTypes(files).FindExtensionByName("hashable.hashable") + if err!=nil { + if errors.Is(err,protoregistry.NotFound) { + return nil + } + panic(fmt.Errorf("files.FindExtensionByName(): %w",err)) } descs := mds{} - for d := range allMDs(p) { - if d.GetBoolOption(canHashOpt) { + for d := range allMDs(files) { + if d.GetBoolOption(hashableOpt.TypeDescriptor()) { descs[d.FullName()] = d } } - log.Printf("buf_plugin: found can_hash option; %d message type(s) marked with it", len(descs)) + log.Printf("buf_plugin: found hashable option; %d message type(s) marked with it", len(descs)) for _, d := range descs { if d.Syntax() != protoreflect.Proto3 { - return fmt.Errorf("%q: can_hash messages have to be in proto3 syntax", d.FullName()) + return fmt.Errorf("%q: hashable messages have to be in proto3 syntax", d.FullName()) } fields := d.Fields() for i := 0; i < fields.Len(); i++ { f := fields.Get(i) if f.IsMap() { - return fmt.Errorf("%q: maps are not allowed in can_hash messages", f.FullName()) + return fmt.Errorf("%q: maps are not allowed in hashable messages", f.FullName()) } if !f.IsList() && !f.HasPresence() { - return fmt.Errorf("%q: all fields of can_hash messages should be optional or repeated", f.FullName()) + return fmt.Errorf("%q: all fields of hashable messages should be optional or repeated", f.FullName()) } if f.Kind() == protoreflect.MessageKind { if _, ok := descs[f.Message().FullName()]; !ok { - return fmt.Errorf("%q: message fields of can_hash messages have to be can_hash", f.FullName()) + return fmt.Errorf("%q: message fields of hashable messages have to be hashable", f.FullName()) } } } diff --git a/sei-tendermint/proto/hashable.proto b/sei-tendermint/proto/hashable.proto new file mode 100644 index 0000000000..4b00cff79b --- /dev/null +++ b/sei-tendermint/proto/hashable.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package hashable; + +import "google/protobuf/descriptor.proto"; + +option go_package = "github.com/tendermint/tendermint/proto/hashable"; + +// hashable marks messages which support canonical protobuf serialization and therefore +// are suitable for hashing. +// NOTE: you still need to use proto.Canonical for canonical encoding. proto.Marshal will not do. +extend google.protobuf.MessageOptions { + bool hashable = 414126217; +} diff --git a/sei-tendermint/proto/tendermint/consensus/types.pb.go b/sei-tendermint/proto/tendermint/consensus/types.pb.go index 753ccf374b..29fbb299f9 100644 --- a/sei-tendermint/proto/tendermint/consensus/types.pb.go +++ b/sei-tendermint/proto/tendermint/consensus/types.pb.go @@ -7,6 +7,7 @@ import ( fmt "fmt" _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" + _ "github.com/tendermint/tendermint/proto/hashable" bits "github.com/tendermint/tendermint/proto/tendermint/libs/bits" types "github.com/tendermint/tendermint/proto/tendermint/types" io "io" @@ -804,61 +805,62 @@ func init() { func init() { proto.RegisterFile("tendermint/consensus/types.proto", fileDescriptor_81a22d2efc008981) } var fileDescriptor_81a22d2efc008981 = []byte{ - // 852 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x4f, 0x8f, 0xdb, 0x44, - 0x14, 0xb7, 0x59, 0x67, 0x93, 0x7d, 0xde, 0xec, 0xc2, 0x68, 0x5b, 0x85, 0x00, 0x49, 0x30, 0x97, - 0x15, 0x42, 0x0e, 0xca, 0x1e, 0x90, 0x0a, 0x12, 0x60, 0xfe, 0xd4, 0xad, 0x9a, 0x36, 0x72, 0x4a, - 0x85, 0xb8, 0x58, 0x4e, 0x3c, 0x4a, 0x86, 0xc6, 0x1e, 0xcb, 0x33, 0xc9, 0xb2, 0x57, 0x3e, 0x01, - 0x1f, 0x80, 0xaf, 0x81, 0xc4, 0x47, 0xe8, 0xb1, 0x47, 0x4e, 0x15, 0xca, 0x7e, 0x04, 0x04, 0x67, - 0x34, 0xe3, 0x49, 0x3c, 0xa1, 0xde, 0x85, 0xbd, 0x20, 0xf5, 0x36, 0xe3, 0xf7, 0xde, 0x6f, 0xde, - 0xfc, 0xde, 0x7b, 0x3f, 0x0f, 0xf4, 0x38, 0x4e, 0x63, 0x9c, 0x27, 0x24, 0xe5, 0xfd, 0x29, 0x4d, - 0x19, 0x4e, 0xd9, 0x92, 0xf5, 0xf9, 0x45, 0x86, 0x99, 0x9b, 0xe5, 0x94, 0x53, 0x74, 0x52, 0x7a, - 0xb8, 0x5b, 0x8f, 0xf6, 0xc9, 0x8c, 0xce, 0xa8, 0x74, 0xe8, 0x8b, 0x55, 0xe1, 0xdb, 0xd6, 0xd1, - 0x16, 0x64, 0xc2, 0xfa, 0x13, 0xc2, 0x77, 0xd0, 0xda, 0x6f, 0x6b, 0x1e, 0xf2, 0xbb, 0x6e, 0x75, - 0x7e, 0x31, 0xe1, 0xf0, 0x21, 0x3e, 0x0f, 0xe8, 0x32, 0x8d, 0xc7, 0x1c, 0x67, 0xe8, 0x36, 0xec, - 0xcf, 0x31, 0x99, 0xcd, 0x79, 0xcb, 0xec, 0x99, 0xa7, 0x7b, 0x81, 0xda, 0xa1, 0x13, 0xa8, 0xe5, - 0xc2, 0xa9, 0xf5, 0x5a, 0xcf, 0x3c, 0xad, 0x05, 0xc5, 0x06, 0x21, 0xb0, 0x18, 0xc7, 0x59, 0x6b, - 0xaf, 0x67, 0x9e, 0x36, 0x03, 0xb9, 0x46, 0x1f, 0x41, 0x8b, 0xe1, 0x29, 0x4d, 0x63, 0x16, 0x32, - 0x92, 0x4e, 0x71, 0xc8, 0x78, 0x94, 0xf3, 0x90, 0x93, 0x04, 0xb7, 0x2c, 0x89, 0x79, 0x4b, 0xd9, - 0xc7, 0xc2, 0x3c, 0x16, 0xd6, 0xc7, 0x24, 0xc1, 0xe8, 0x7d, 0x78, 0x63, 0x11, 0x31, 0x1e, 0x4e, - 0x69, 0x92, 0x10, 0x1e, 0x16, 0xc7, 0xd5, 0xe4, 0x71, 0xc7, 0xc2, 0xf0, 0x85, 0xfc, 0x2e, 0x53, - 0x75, 0xfe, 0x34, 0xa1, 0xf9, 0x10, 0x9f, 0x3f, 0x89, 0x16, 0x24, 0xf6, 0x16, 0x74, 0xfa, 0xf4, - 0x86, 0x89, 0x7f, 0x0b, 0xb7, 0x26, 0x22, 0x2c, 0xcc, 0x44, 0x6e, 0x0c, 0xf3, 0x70, 0x8e, 0xa3, - 0x18, 0xe7, 0xf2, 0x26, 0xf6, 0xa0, 0xeb, 0x6a, 0x35, 0x28, 0xf8, 0x1a, 0x45, 0x39, 0x1f, 0x63, - 0xee, 0x4b, 0x37, 0xcf, 0x7a, 0xf6, 0xa2, 0x6b, 0x04, 0x48, 0x62, 0xec, 0x58, 0xd0, 0xa7, 0x60, - 0x97, 0xc8, 0x4c, 0xde, 0xd8, 0x1e, 0x74, 0x74, 0x3c, 0x51, 0x27, 0x57, 0xd4, 0xc9, 0xf5, 0x08, - 0xff, 0x3c, 0xcf, 0xa3, 0x8b, 0x00, 0xb6, 0x40, 0x0c, 0xbd, 0x05, 0x07, 0x84, 0x29, 0x12, 0xe4, - 0xf5, 0x1b, 0x41, 0x83, 0xb0, 0xe2, 0xf2, 0x8e, 0x0f, 0x8d, 0x51, 0x4e, 0x33, 0xca, 0xa2, 0x05, - 0xfa, 0x04, 0x1a, 0x99, 0x5a, 0xcb, 0x3b, 0xdb, 0x83, 0x76, 0x45, 0xda, 0xca, 0x43, 0x65, 0xbc, - 0x8d, 0x70, 0x7e, 0x36, 0xc1, 0xde, 0x18, 0x47, 0x8f, 0x1e, 0x5c, 0xc9, 0xdf, 0x07, 0x80, 0x36, - 0x31, 0x61, 0x46, 0x17, 0xa1, 0x4e, 0xe6, 0xeb, 0x1b, 0xcb, 0x88, 0x2e, 0x64, 0x5d, 0xd0, 0x5d, - 0x38, 0xd4, 0xbd, 0x15, 0x9d, 0xff, 0x72, 0x7d, 0x95, 0x9b, 0xad, 0xa1, 0x39, 0x4f, 0xe1, 0xc0, - 0xdb, 0x70, 0x72, 0xc3, 0xda, 0x7e, 0x08, 0x96, 0xe0, 0x5e, 0x9d, 0x7d, 0xbb, 0xba, 0x94, 0xea, - 0x4c, 0xe9, 0xe9, 0x0c, 0xc0, 0x7a, 0x42, 0xb9, 0xe8, 0x40, 0x6b, 0x45, 0x39, 0x56, 0x6c, 0x56, - 0x44, 0x0a, 0xaf, 0x40, 0xfa, 0x38, 0x3f, 0x9a, 0x50, 0xf7, 0x23, 0x26, 0xe3, 0x6e, 0x96, 0xdf, - 0x19, 0x58, 0x02, 0x4d, 0xe6, 0x77, 0x54, 0xd5, 0x6a, 0x63, 0x32, 0x4b, 0x71, 0x3c, 0x64, 0xb3, - 0xc7, 0x17, 0x19, 0x0e, 0xa4, 0xb3, 0x80, 0x22, 0x69, 0x8c, 0x7f, 0x90, 0x0d, 0x55, 0x0b, 0x8a, - 0x8d, 0xf3, 0xab, 0x09, 0x87, 0x22, 0x83, 0x31, 0xe6, 0xc3, 0xe8, 0xfb, 0xc1, 0xd9, 0xff, 0x91, - 0xc9, 0x57, 0xd0, 0x28, 0x1a, 0x9c, 0xc4, 0xaa, 0xbb, 0xdf, 0x7c, 0x39, 0x50, 0xd6, 0xee, 0xde, - 0x97, 0xde, 0xb1, 0x60, 0x79, 0xfd, 0xa2, 0x5b, 0x57, 0x1f, 0x82, 0xba, 0x8c, 0xbd, 0x17, 0x3b, - 0x7f, 0x98, 0x60, 0xab, 0xd4, 0x3d, 0xc2, 0xd9, 0xab, 0x93, 0x39, 0xba, 0x03, 0x35, 0xd1, 0x01, - 0x4c, 0x0e, 0xe7, 0x7f, 0x6d, 0xee, 0x22, 0xc4, 0xf9, 0xcb, 0x82, 0xfa, 0x10, 0x33, 0x16, 0xcd, - 0x30, 0xba, 0x0f, 0x47, 0x29, 0x3e, 0x2f, 0x06, 0x2a, 0x94, 0x32, 0x5a, 0xf4, 0x9d, 0xe3, 0x56, - 0xfd, 0x00, 0x5c, 0x5d, 0xa6, 0x7d, 0x23, 0x38, 0x4c, 0x75, 0xd9, 0x1e, 0xc2, 0xb1, 0xc0, 0x5a, - 0x09, 0x3d, 0x0c, 0x65, 0xa2, 0x92, 0x2f, 0x7b, 0xf0, 0xde, 0x95, 0x60, 0xa5, 0x76, 0xfa, 0x46, - 0xd0, 0x4c, 0x77, 0xc4, 0x54, 0x97, 0x96, 0x8a, 0x11, 0x2e, 0x71, 0x36, 0x0a, 0xe2, 0x6b, 0xd2, - 0x82, 0xbe, 0xfe, 0x87, 0x08, 0x14, 0x5c, 0xbf, 0x7b, 0x3d, 0xc2, 0xe8, 0xd1, 0x03, 0x7f, 0x57, - 0x03, 0xd0, 0x67, 0x00, 0xa5, 0x94, 0x2a, 0xb6, 0xbb, 0xd5, 0x28, 0x5b, 0xad, 0xf0, 0x8d, 0xe0, - 0x60, 0x2b, 0xa6, 0x42, 0x0a, 0xe4, 0x40, 0xef, 0xbf, 0x2c, 0x8f, 0x65, 0xac, 0xe8, 0x42, 0xdf, - 0x28, 0xc6, 0x1a, 0xdd, 0x81, 0xc6, 0x3c, 0x62, 0xa1, 0x8c, 0xaa, 0xcb, 0xa8, 0x77, 0xaa, 0xa3, - 0xd4, 0xec, 0xfb, 0x46, 0x50, 0x9f, 0x2b, 0x19, 0xb8, 0x0f, 0x47, 0x22, 0x4e, 0xfe, 0x4e, 0x12, - 0x31, 0x8e, 0xad, 0xc6, 0x75, 0x05, 0xd5, 0x07, 0x57, 0x14, 0x74, 0xa5, 0x0f, 0xf2, 0x5d, 0x68, - 0x6e, 0xb1, 0x44, 0x3f, 0xb5, 0x0e, 0xae, 0x23, 0x51, 0x1b, 0x24, 0x41, 0xe2, 0xaa, 0xdc, 0x7a, - 0x35, 0xd8, 0x63, 0xcb, 0xc4, 0xfb, 0xe6, 0xd9, 0xba, 0x63, 0x3e, 0x5f, 0x77, 0xcc, 0xdf, 0xd7, - 0x1d, 0xf3, 0xa7, 0xcb, 0x8e, 0xf1, 0xfc, 0xb2, 0x63, 0xfc, 0x76, 0xd9, 0x31, 0xbe, 0xfb, 0x78, - 0x46, 0xf8, 0x7c, 0x39, 0x71, 0xa7, 0x34, 0xe9, 0xeb, 0x6f, 0x85, 0x72, 0x59, 0xbc, 0x3a, 0xaa, - 0xde, 0x2d, 0x93, 0x7d, 0x69, 0x3b, 0xfb, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xf9, 0xf1, 0xeb, 0x6b, - 0xd6, 0x08, 0x00, 0x00, + // 871 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x4f, 0x6f, 0xe3, 0x44, + 0x14, 0xb7, 0xa9, 0xd3, 0xa4, 0xcf, 0x69, 0x0b, 0xa3, 0xee, 0x2a, 0x14, 0x48, 0x83, 0xb9, 0x54, + 0x08, 0x39, 0x28, 0x3d, 0x20, 0x05, 0x24, 0xc0, 0xfc, 0x59, 0xef, 0x6a, 0xb3, 0x1b, 0x39, 0xcb, + 0x0a, 0x71, 0xb1, 0x9c, 0x78, 0x14, 0x0f, 0x6b, 0x7b, 0x2c, 0xcf, 0x24, 0xa5, 0x57, 0x4e, 0x1c, + 0xf9, 0x00, 0x7c, 0x03, 0xce, 0x48, 0x7c, 0x84, 0x1e, 0xf7, 0xc8, 0x69, 0x85, 0xd2, 0x8f, 0x80, + 0xe0, 0x8c, 0x66, 0x3c, 0x89, 0x1d, 0xd6, 0x5b, 0xe8, 0x05, 0x69, 0x6f, 0x33, 0x7e, 0xef, 0xfd, + 0xe6, 0xcd, 0xef, 0xbd, 0xf7, 0xf3, 0x40, 0x8f, 0xe3, 0x34, 0xc4, 0x79, 0x42, 0x52, 0xde, 0x9f, + 0xd1, 0x94, 0xe1, 0x94, 0x2d, 0x58, 0x9f, 0x5f, 0x64, 0x98, 0xd9, 0x59, 0x4e, 0x39, 0x45, 0x47, + 0xa5, 0x87, 0xbd, 0xf1, 0x38, 0x3e, 0x9a, 0xd3, 0x39, 0x95, 0x0e, 0x7d, 0xb1, 0x2a, 0x7c, 0x8f, + 0xab, 0x68, 0x31, 0x99, 0xb2, 0xfe, 0x94, 0xf0, 0x2d, 0xb4, 0xe3, 0x37, 0x2b, 0x1e, 0xf2, 0xfb, + 0x96, 0xf5, 0x20, 0x0a, 0x58, 0x14, 0x4c, 0x63, 0x5c, 0xec, 0xad, 0x5f, 0x74, 0x68, 0x3f, 0xc0, + 0xe7, 0x1e, 0x5d, 0xa4, 0xe1, 0x84, 0xe3, 0x0c, 0xdd, 0x86, 0xdd, 0x08, 0x93, 0x79, 0xc4, 0x3b, + 0x7a, 0x4f, 0x3f, 0xdd, 0xf1, 0xd4, 0x0e, 0x1d, 0x41, 0x23, 0x17, 0x4e, 0x9d, 0x57, 0x7a, 0xfa, + 0x69, 0xc3, 0x2b, 0x36, 0x08, 0x81, 0xc1, 0x38, 0xce, 0x3a, 0x3b, 0x3d, 0xfd, 0x74, 0xdf, 0x93, + 0x6b, 0xf4, 0x01, 0x74, 0x18, 0x9e, 0xd1, 0x34, 0x64, 0x3e, 0x23, 0xe9, 0x0c, 0xfb, 0x8c, 0x07, + 0x39, 0xf7, 0x39, 0x49, 0x70, 0xc7, 0x90, 0x98, 0xb7, 0x94, 0x7d, 0x22, 0xcc, 0x13, 0x61, 0x7d, + 0x44, 0x12, 0x8c, 0xde, 0x85, 0xd7, 0xe2, 0x80, 0x71, 0x7f, 0x46, 0x93, 0x84, 0x70, 0xbf, 0x38, + 0xae, 0x21, 0x8f, 0x3b, 0x14, 0x86, 0xcf, 0xe4, 0x77, 0x99, 0xaa, 0xf5, 0xa7, 0x0e, 0xfb, 0x0f, + 0xf0, 0xf9, 0xe3, 0x20, 0x26, 0xa1, 0x13, 0xd3, 0xd9, 0x93, 0x1b, 0x26, 0xfe, 0x35, 0xdc, 0x9a, + 0x8a, 0x30, 0x3f, 0x13, 0xb9, 0x31, 0xcc, 0xfd, 0x08, 0x07, 0x21, 0xce, 0xe5, 0x4d, 0xcc, 0xc1, + 0x89, 0x5d, 0xa9, 0x49, 0xc1, 0xdf, 0x38, 0xc8, 0xf9, 0x04, 0x73, 0x57, 0xba, 0x39, 0xc6, 0xe5, + 0xb3, 0x13, 0xcd, 0x43, 0x12, 0x63, 0xcb, 0x82, 0x3e, 0x06, 0xb3, 0x44, 0x66, 0xf2, 0xc6, 0xe6, + 0xa0, 0x5b, 0xc5, 0x13, 0x75, 0xb3, 0x45, 0xdd, 0x6c, 0x87, 0xf0, 0x4f, 0xf3, 0x3c, 0xb8, 0xf0, + 0x60, 0x03, 0xc4, 0xd0, 0x1b, 0xb0, 0x47, 0x98, 0x22, 0x41, 0x5e, 0xbf, 0xe5, 0xb5, 0x08, 0x2b, + 0x2e, 0x6f, 0xb9, 0xd0, 0x1a, 0xe7, 0x34, 0xa3, 0x2c, 0x88, 0xd1, 0x47, 0xd0, 0xca, 0xd4, 0x5a, + 0xde, 0xd9, 0x1c, 0x1c, 0xd7, 0xa4, 0xad, 0x3c, 0x54, 0xc6, 0x9b, 0x08, 0xeb, 0x27, 0x1d, 0xcc, + 0xb5, 0x71, 0xfc, 0xf0, 0xfe, 0x0b, 0xf9, 0x7b, 0x0f, 0xd0, 0x3a, 0xc6, 0xcf, 0x68, 0xec, 0x57, + 0xc9, 0x7c, 0x75, 0x6d, 0x19, 0xd3, 0x58, 0xd6, 0x05, 0xdd, 0x81, 0x76, 0xd5, 0x5b, 0xd1, 0xf9, + 0x2f, 0xd7, 0x57, 0xb9, 0x99, 0x15, 0x34, 0xeb, 0x09, 0xec, 0x39, 0x6b, 0x4e, 0x6e, 0x58, 0xdb, + 0xf7, 0xc1, 0x10, 0xdc, 0xab, 0xb3, 0x6f, 0xd7, 0x97, 0x52, 0x9d, 0x29, 0x3d, 0xad, 0x21, 0x18, + 0x8f, 0x29, 0x17, 0x1d, 0x68, 0x2c, 0x29, 0xc7, 0x8a, 0xcd, 0x9a, 0x48, 0xe1, 0xe5, 0x49, 0x9f, + 0xe1, 0xee, 0xe5, 0x0f, 0xab, 0x9f, 0xdb, 0xba, 0xf5, 0xbd, 0x0e, 0x4d, 0x37, 0x60, 0x32, 0xfe, + 0x66, 0x79, 0x9e, 0x81, 0x21, 0x50, 0x65, 0x9e, 0x07, 0x75, 0x2d, 0x37, 0x21, 0xf3, 0x14, 0x87, + 0x23, 0x36, 0x7f, 0x74, 0x91, 0x61, 0x4f, 0x3a, 0x0b, 0x28, 0x92, 0x86, 0xf8, 0x3b, 0xd9, 0x58, + 0x0d, 0xaf, 0xd8, 0x58, 0xbf, 0xea, 0xd0, 0x16, 0x19, 0x4c, 0x30, 0x1f, 0x05, 0xdf, 0x0e, 0xce, + 0xfe, 0x8f, 0x4c, 0xbe, 0x80, 0x56, 0xd1, 0xe8, 0x24, 0x54, 0x5d, 0xfe, 0xfa, 0xf3, 0x81, 0xb2, + 0x86, 0x77, 0x3f, 0x77, 0x0e, 0x05, 0xdb, 0xab, 0x67, 0x27, 0x4d, 0xf5, 0xc1, 0x6b, 0xca, 0xd8, + 0xbb, 0xa1, 0xf5, 0x87, 0x0e, 0xa6, 0x4a, 0xdd, 0x21, 0x9c, 0xbd, 0x3c, 0x99, 0xa3, 0x21, 0x34, + 0x44, 0x27, 0x30, 0x39, 0xa4, 0xff, 0xb5, 0xc9, 0x8b, 0x10, 0xeb, 0x2f, 0x03, 0x9a, 0x23, 0xcc, + 0x58, 0x30, 0xc7, 0xe8, 0x1e, 0x1c, 0xa4, 0xf8, 0xbc, 0x18, 0x2c, 0x5f, 0xca, 0x69, 0xd1, 0x7f, + 0x96, 0x5d, 0xf7, 0x63, 0xb0, 0xab, 0x72, 0xed, 0x6a, 0x5e, 0x3b, 0xad, 0xca, 0xf7, 0x08, 0x0e, + 0x05, 0xd6, 0x52, 0xe8, 0xa2, 0x2f, 0x13, 0x95, 0x7c, 0x99, 0x83, 0x77, 0x5e, 0x08, 0x56, 0x6a, + 0xa8, 0xab, 0x79, 0xfb, 0xe9, 0x96, 0xa8, 0x56, 0x25, 0xa6, 0x66, 0x94, 0x4b, 0x9c, 0xb5, 0x92, + 0xb8, 0x15, 0x89, 0x41, 0x5f, 0xfe, 0x43, 0x0c, 0x0a, 0xae, 0xdf, 0xbe, 0x1e, 0x61, 0xfc, 0xf0, + 0xbe, 0xbb, 0xad, 0x05, 0xe8, 0x13, 0x80, 0x52, 0x52, 0x15, 0xdb, 0x27, 0xf5, 0x28, 0x1b, 0xcd, + 0x70, 0x35, 0x6f, 0x6f, 0x23, 0xaa, 0x42, 0x12, 0xe4, 0x60, 0xef, 0x3e, 0x2f, 0x93, 0x65, 0xac, + 0xe8, 0x42, 0x57, 0x2b, 0xc6, 0x1b, 0x0d, 0xa1, 0x15, 0x05, 0xcc, 0x97, 0x51, 0x4d, 0x19, 0xf5, + 0x56, 0x7d, 0x94, 0x9a, 0x7d, 0x57, 0xf3, 0x9a, 0x91, 0x92, 0x81, 0x7b, 0x70, 0x20, 0xe2, 0xe4, + 0x6f, 0x25, 0x11, 0xe3, 0xd8, 0x69, 0x5d, 0x57, 0xd0, 0xea, 0xe0, 0x8a, 0x82, 0x2e, 0xab, 0x83, + 0x7c, 0x07, 0xf6, 0x37, 0x58, 0xa2, 0x9f, 0x3a, 0x7b, 0xd7, 0x91, 0x58, 0x19, 0x24, 0x41, 0xe2, + 0xb2, 0xdc, 0x3a, 0x0d, 0xd8, 0x61, 0x8b, 0xc4, 0xf9, 0xea, 0x72, 0xd5, 0xd5, 0x9f, 0xae, 0xba, + 0xfa, 0xef, 0xab, 0xae, 0xfe, 0xe3, 0x55, 0x57, 0x7b, 0x7a, 0xd5, 0xd5, 0x7e, 0xbb, 0xea, 0x6a, + 0xdf, 0x7c, 0x38, 0x27, 0x3c, 0x5a, 0x4c, 0xed, 0x19, 0x4d, 0xfa, 0xd5, 0x37, 0x44, 0xb9, 0x2c, + 0x5e, 0x23, 0x75, 0xef, 0x99, 0xe9, 0xae, 0xb4, 0x9d, 0xfd, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x65, + 0x3a, 0x50, 0x64, 0xee, 0x08, 0x00, 0x00, } func (m *NewRoundStep) Marshal() (dAtA []byte, err error) { diff --git a/sei-tendermint/proto/tendermint/consensus/types.proto b/sei-tendermint/proto/tendermint/consensus/types.proto index 4fd8e3c36b..e84d5d89dd 100644 --- a/sei-tendermint/proto/tendermint/consensus/types.proto +++ b/sei-tendermint/proto/tendermint/consensus/types.proto @@ -5,6 +5,7 @@ package tendermint.consensus; import "gogoproto/gogo.proto"; import "tendermint/libs/bits/types.proto"; import "tendermint/types/types.proto"; +import "hashable.proto"; option go_package = "github.com/tendermint/tendermint/proto/tendermint/consensus"; @@ -52,6 +53,7 @@ message BlockPart { // Vote is sent when voting for a proposal (or lack thereof). message Vote { + option (hashable.hashable) = true; tendermint.types.Vote vote = 1; } diff --git a/sei-tendermint/proto/tendermint/types/types.pb.go b/sei-tendermint/proto/tendermint/types/types.pb.go index 39009a11d2..de4222a448 100644 --- a/sei-tendermint/proto/tendermint/types/types.pb.go +++ b/sei-tendermint/proto/tendermint/types/types.pb.go @@ -9,6 +9,7 @@ import ( proto "github.com/gogo/protobuf/proto" _ "github.com/gogo/protobuf/types" github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" + _ "github.com/tendermint/tendermint/proto/hashable" crypto "github.com/tendermint/tendermint/proto/tendermint/crypto" version "github.com/tendermint/tendermint/proto/tendermint/version" io "io" @@ -97,8 +98,12 @@ func (SignedMsgType) EnumDescriptor() ([]byte, []int) { // PartsetHeader type PartSetHeader struct { - Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"` - Hash []byte `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"` + // Types that are valid to be assigned to XTotal: + // *PartSetHeader_Total + XTotal isPartSetHeader_XTotal `protobuf_oneof:"_total"` + // Types that are valid to be assigned to XHash: + // *PartSetHeader_Hash + XHash isPartSetHeader_XHash `protobuf_oneof:"_hash"` } func (m *PartSetHeader) Reset() { *m = PartSetHeader{} } @@ -134,20 +139,62 @@ func (m *PartSetHeader) XXX_DiscardUnknown() { var xxx_messageInfo_PartSetHeader proto.InternalMessageInfo -func (m *PartSetHeader) GetTotal() uint32 { +type isPartSetHeader_XTotal interface { + isPartSetHeader_XTotal() + MarshalTo([]byte) (int, error) + Size() int +} +type isPartSetHeader_XHash interface { + isPartSetHeader_XHash() + MarshalTo([]byte) (int, error) + Size() int +} + +type PartSetHeader_Total struct { + Total uint32 `protobuf:"varint,1,opt,name=total,proto3,oneof" json:"total,omitempty"` +} +type PartSetHeader_Hash struct { + Hash []byte `protobuf:"bytes,2,opt,name=hash,proto3,oneof" json:"hash,omitempty"` +} + +func (*PartSetHeader_Total) isPartSetHeader_XTotal() {} +func (*PartSetHeader_Hash) isPartSetHeader_XHash() {} + +func (m *PartSetHeader) GetXTotal() isPartSetHeader_XTotal { + if m != nil { + return m.XTotal + } + return nil +} +func (m *PartSetHeader) GetXHash() isPartSetHeader_XHash { if m != nil { - return m.Total + return m.XHash + } + return nil +} + +func (m *PartSetHeader) GetTotal() uint32 { + if x, ok := m.GetXTotal().(*PartSetHeader_Total); ok { + return x.Total } return 0 } func (m *PartSetHeader) GetHash() []byte { - if m != nil { - return m.Hash + if x, ok := m.GetXHash().(*PartSetHeader_Hash); ok { + return x.Hash } return nil } +// XXX_OneofWrappers is for the internal use of the proto package. +func (*PartSetHeader) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*PartSetHeader_Total)(nil), + (*PartSetHeader_Hash)(nil), + } +} + type Part struct { Index uint32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` Bytes []byte `protobuf:"bytes,2,opt,name=bytes,proto3" json:"bytes,omitempty"` @@ -210,8 +257,14 @@ func (m *Part) GetProof() crypto.Proof { // BlockID type BlockID struct { - Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` - PartSetHeader PartSetHeader `protobuf:"bytes,2,opt,name=part_set_header,json=partSetHeader,proto3" json:"part_set_header"` + // Types that are valid to be assigned to XHash: + // + // *BlockID_Hash + XHash isBlockID_XHash `protobuf_oneof:"_hash"` + // Types that are valid to be assigned to XPartSetHeader: + // + // *BlockID_PartSetHeader + XPartSetHeader isBlockID_XPartSetHeader `protobuf_oneof:"_part_set_header"` } func (m *BlockID) Reset() { *m = BlockID{} } @@ -247,18 +300,60 @@ func (m *BlockID) XXX_DiscardUnknown() { var xxx_messageInfo_BlockID proto.InternalMessageInfo -func (m *BlockID) GetHash() []byte { +type isBlockID_XHash interface { + isBlockID_XHash() + MarshalTo([]byte) (int, error) + Size() int +} +type isBlockID_XPartSetHeader interface { + isBlockID_XPartSetHeader() + MarshalTo([]byte) (int, error) + Size() int +} + +type BlockID_Hash struct { + Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3,oneof" json:"hash,omitempty"` +} +type BlockID_PartSetHeader struct { + PartSetHeader *PartSetHeader `protobuf:"bytes,2,opt,name=part_set_header,json=partSetHeader,proto3,oneof" json:"part_set_header,omitempty"` +} + +func (*BlockID_Hash) isBlockID_XHash() {} +func (*BlockID_PartSetHeader) isBlockID_XPartSetHeader() {} + +func (m *BlockID) GetXHash() isBlockID_XHash { if m != nil { - return m.Hash + return m.XHash } return nil } - -func (m *BlockID) GetPartSetHeader() PartSetHeader { +func (m *BlockID) GetXPartSetHeader() isBlockID_XPartSetHeader { if m != nil { - return m.PartSetHeader + return m.XPartSetHeader + } + return nil +} + +func (m *BlockID) GetHash() []byte { + if x, ok := m.GetXHash().(*BlockID_Hash); ok { + return x.Hash + } + return nil +} + +func (m *BlockID) GetPartSetHeader() *PartSetHeader { + if x, ok := m.GetXPartSetHeader().(*BlockID_PartSetHeader); ok { + return x.PartSetHeader + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*BlockID) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*BlockID_Hash)(nil), + (*BlockID_PartSetHeader)(nil), } - return PartSetHeader{} } // Header defines the structure of a Tendermint block header. @@ -510,18 +605,42 @@ func (m *TxKey) GetTxKey() []byte { // Vote represents a prevote, precommit, or commit vote from validators for // consensus. type Vote struct { - Type SignedMsgType `protobuf:"varint,1,opt,name=type,proto3,enum=tendermint.types.SignedMsgType" json:"type,omitempty"` - Height int64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"` - Round int32 `protobuf:"varint,3,opt,name=round,proto3" json:"round,omitempty"` - BlockID BlockID `protobuf:"bytes,4,opt,name=block_id,json=blockId,proto3" json:"block_id"` - Timestamp time.Time `protobuf:"bytes,5,opt,name=timestamp,proto3,stdtime" json:"timestamp"` - ValidatorAddress []byte `protobuf:"bytes,6,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"` - ValidatorIndex int32 `protobuf:"varint,7,opt,name=validator_index,json=validatorIndex,proto3" json:"validator_index,omitempty"` - // Vote signature by the validator if they participated in consensus for the - // associated block. - Signature []byte `protobuf:"bytes,8,opt,name=signature,proto3" json:"signature,omitempty"` - Extension []byte `protobuf:"bytes,9,opt,name=extension,proto3" json:"extension,omitempty"` // Deprecated: Do not use. - ExtensionSignature []byte `protobuf:"bytes,10,opt,name=extension_signature,json=extensionSignature,proto3" json:"extension_signature,omitempty"` // Deprecated: Do not use. + // Types that are valid to be assigned to XType: + // + // *Vote_Type + XType isVote_XType `protobuf_oneof:"_type"` + // Types that are valid to be assigned to XHeight: + // + // *Vote_Height + XHeight isVote_XHeight `protobuf_oneof:"_height"` + // Types that are valid to be assigned to XRound: + // + // *Vote_Round + XRound isVote_XRound `protobuf_oneof:"_round"` + // Types that are valid to be assigned to XBlockId: + // + // *Vote_BlockId + XBlockId isVote_XBlockId `protobuf_oneof:"_block_id"` + // Types that are valid to be assigned to XValidatorAddress: + // + // *Vote_ValidatorAddress + XValidatorAddress isVote_XValidatorAddress `protobuf_oneof:"_validator_address"` + // Types that are valid to be assigned to XValidatorIndex: + // + // *Vote_ValidatorIndex + XValidatorIndex isVote_XValidatorIndex `protobuf_oneof:"_validator_index"` + // Types that are valid to be assigned to XSignature: + // + // *Vote_Signature + XSignature isVote_XSignature `protobuf_oneof:"_signature"` + // Types that are valid to be assigned to XExtension: + // + // *Vote_Extension + XExtension isVote_XExtension `protobuf_oneof:"_extension"` + // Types that are valid to be assigned to XExtensionSignature: + // + // *Vote_ExtensionSignature + XExtensionSignature isVote_XExtensionSignature `protobuf_oneof:"_extension_signature"` } func (m *Vote) Reset() { *m = Vote{} } @@ -557,78 +676,225 @@ func (m *Vote) XXX_DiscardUnknown() { var xxx_messageInfo_Vote proto.InternalMessageInfo -func (m *Vote) GetType() SignedMsgType { +type isVote_XType interface { + isVote_XType() + MarshalTo([]byte) (int, error) + Size() int +} +type isVote_XHeight interface { + isVote_XHeight() + MarshalTo([]byte) (int, error) + Size() int +} +type isVote_XRound interface { + isVote_XRound() + MarshalTo([]byte) (int, error) + Size() int +} +type isVote_XBlockId interface { + isVote_XBlockId() + MarshalTo([]byte) (int, error) + Size() int +} +type isVote_XValidatorAddress interface { + isVote_XValidatorAddress() + MarshalTo([]byte) (int, error) + Size() int +} +type isVote_XValidatorIndex interface { + isVote_XValidatorIndex() + MarshalTo([]byte) (int, error) + Size() int +} +type isVote_XSignature interface { + isVote_XSignature() + MarshalTo([]byte) (int, error) + Size() int +} +type isVote_XExtension interface { + isVote_XExtension() + MarshalTo([]byte) (int, error) + Size() int +} +type isVote_XExtensionSignature interface { + isVote_XExtensionSignature() + MarshalTo([]byte) (int, error) + Size() int +} + +type Vote_Type struct { + Type SignedMsgType `protobuf:"varint,1,opt,name=type,proto3,enum=tendermint.types.SignedMsgType,oneof" json:"type,omitempty"` +} +type Vote_Height struct { + Height int64 `protobuf:"varint,2,opt,name=height,proto3,oneof" json:"height,omitempty"` +} +type Vote_Round struct { + Round int32 `protobuf:"varint,3,opt,name=round,proto3,oneof" json:"round,omitempty"` +} +type Vote_BlockId struct { + BlockId *BlockID `protobuf:"bytes,4,opt,name=block_id,json=blockId,proto3,oneof" json:"block_id,omitempty"` +} +type Vote_ValidatorAddress struct { + ValidatorAddress []byte `protobuf:"bytes,6,opt,name=validator_address,json=validatorAddress,proto3,oneof" json:"validator_address,omitempty"` +} +type Vote_ValidatorIndex struct { + ValidatorIndex int32 `protobuf:"varint,7,opt,name=validator_index,json=validatorIndex,proto3,oneof" json:"validator_index,omitempty"` +} +type Vote_Signature struct { + Signature []byte `protobuf:"bytes,8,opt,name=signature,proto3,oneof" json:"signature,omitempty"` +} +type Vote_Extension struct { + Extension []byte `protobuf:"bytes,9,opt,name=extension,proto3,oneof" json:"extension,omitempty"` +} +type Vote_ExtensionSignature struct { + ExtensionSignature []byte `protobuf:"bytes,10,opt,name=extension_signature,json=extensionSignature,proto3,oneof" json:"extension_signature,omitempty"` +} + +func (*Vote_Type) isVote_XType() {} +func (*Vote_Height) isVote_XHeight() {} +func (*Vote_Round) isVote_XRound() {} +func (*Vote_BlockId) isVote_XBlockId() {} +func (*Vote_ValidatorAddress) isVote_XValidatorAddress() {} +func (*Vote_ValidatorIndex) isVote_XValidatorIndex() {} +func (*Vote_Signature) isVote_XSignature() {} +func (*Vote_Extension) isVote_XExtension() {} +func (*Vote_ExtensionSignature) isVote_XExtensionSignature() {} + +func (m *Vote) GetXType() isVote_XType { if m != nil { - return m.Type + return m.XType + } + return nil +} +func (m *Vote) GetXHeight() isVote_XHeight { + if m != nil { + return m.XHeight + } + return nil +} +func (m *Vote) GetXRound() isVote_XRound { + if m != nil { + return m.XRound + } + return nil +} +func (m *Vote) GetXBlockId() isVote_XBlockId { + if m != nil { + return m.XBlockId + } + return nil +} +func (m *Vote) GetXValidatorAddress() isVote_XValidatorAddress { + if m != nil { + return m.XValidatorAddress + } + return nil +} +func (m *Vote) GetXValidatorIndex() isVote_XValidatorIndex { + if m != nil { + return m.XValidatorIndex + } + return nil +} +func (m *Vote) GetXSignature() isVote_XSignature { + if m != nil { + return m.XSignature + } + return nil +} +func (m *Vote) GetXExtension() isVote_XExtension { + if m != nil { + return m.XExtension + } + return nil +} +func (m *Vote) GetXExtensionSignature() isVote_XExtensionSignature { + if m != nil { + return m.XExtensionSignature + } + return nil +} + +func (m *Vote) GetType() SignedMsgType { + if x, ok := m.GetXType().(*Vote_Type); ok { + return x.Type } return UnknownType } func (m *Vote) GetHeight() int64 { - if m != nil { - return m.Height + if x, ok := m.GetXHeight().(*Vote_Height); ok { + return x.Height } return 0 } func (m *Vote) GetRound() int32 { - if m != nil { - return m.Round + if x, ok := m.GetXRound().(*Vote_Round); ok { + return x.Round } return 0 } -func (m *Vote) GetBlockID() BlockID { - if m != nil { - return m.BlockID +func (m *Vote) GetBlockId() *BlockID { + if x, ok := m.GetXBlockId().(*Vote_BlockId); ok { + return x.BlockId } - return BlockID{} -} - -func (m *Vote) GetTimestamp() time.Time { - if m != nil { - return m.Timestamp - } - return time.Time{} + return nil } func (m *Vote) GetValidatorAddress() []byte { - if m != nil { - return m.ValidatorAddress + if x, ok := m.GetXValidatorAddress().(*Vote_ValidatorAddress); ok { + return x.ValidatorAddress } return nil } func (m *Vote) GetValidatorIndex() int32 { - if m != nil { - return m.ValidatorIndex + if x, ok := m.GetXValidatorIndex().(*Vote_ValidatorIndex); ok { + return x.ValidatorIndex } return 0 } func (m *Vote) GetSignature() []byte { - if m != nil { - return m.Signature + if x, ok := m.GetXSignature().(*Vote_Signature); ok { + return x.Signature } return nil } // Deprecated: Do not use. func (m *Vote) GetExtension() []byte { - if m != nil { - return m.Extension + if x, ok := m.GetXExtension().(*Vote_Extension); ok { + return x.Extension } return nil } // Deprecated: Do not use. func (m *Vote) GetExtensionSignature() []byte { - if m != nil { - return m.ExtensionSignature + if x, ok := m.GetXExtensionSignature().(*Vote_ExtensionSignature); ok { + return x.ExtensionSignature } return nil } +// XXX_OneofWrappers is for the internal use of the proto package. +func (*Vote) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*Vote_Type)(nil), + (*Vote_Height)(nil), + (*Vote_Round)(nil), + (*Vote_BlockId)(nil), + (*Vote_ValidatorAddress)(nil), + (*Vote_ValidatorIndex)(nil), + (*Vote_Signature)(nil), + (*Vote_Extension)(nil), + (*Vote_ExtensionSignature)(nil), + } +} + // Commit contains the evidence that a block was committed by a set of // validators. type Commit struct { @@ -1446,113 +1712,124 @@ func init() { func init() { proto.RegisterFile("tendermint/types/types.proto", fileDescriptor_d3a6e55e2345de56) } var fileDescriptor_d3a6e55e2345de56 = []byte{ - // 1694 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0x4f, 0x73, 0x1a, 0xc9, - 0x15, 0xd7, 0xc0, 0xf0, 0xef, 0x01, 0x12, 0xea, 0x95, 0x6c, 0x84, 0x6d, 0x44, 0xb1, 0x95, 0xac, - 0xf6, 0x4f, 0x90, 0x22, 0xa7, 0x92, 0x6c, 0x2a, 0x39, 0x00, 0xd2, 0xda, 0x94, 0x25, 0x44, 0x06, - 0xd6, 0xa9, 0xe4, 0x32, 0x35, 0x40, 0x1b, 0x26, 0x1e, 0x66, 0xa6, 0x66, 0x1a, 0x2d, 0xf2, 0x27, - 0x48, 0xe9, 0xe4, 0x53, 0x6e, 0x3a, 0x25, 0x87, 0x7c, 0x8b, 0x4d, 0xe5, 0xb4, 0x97, 0x54, 0xed, - 0x2d, 0xb9, 0x64, 0x93, 0xb2, 0x53, 0xf9, 0x1c, 0xa9, 0x7e, 0xdd, 0x33, 0x0c, 0x02, 0x76, 0x1d, - 0x97, 0x2b, 0x17, 0xd5, 0xf4, 0x7b, 0xbf, 0xd7, 0xfd, 0xfe, 0xfc, 0xfa, 0xf5, 0x13, 0x70, 0x9f, - 0x51, 0x7b, 0x48, 0xbd, 0x89, 0x69, 0xb3, 0x43, 0x76, 0xe5, 0x52, 0x5f, 0xfc, 0xad, 0xb9, 0x9e, - 0xc3, 0x1c, 0x52, 0x98, 0x6b, 0x6b, 0x28, 0x2f, 0xed, 0x8c, 0x9c, 0x91, 0x83, 0xca, 0x43, 0xfe, - 0x25, 0x70, 0xa5, 0xfd, 0x91, 0xe3, 0x8c, 0x2c, 0x7a, 0x88, 0xab, 0xfe, 0xf4, 0xd9, 0x21, 0x33, - 0x27, 0xd4, 0x67, 0xc6, 0xc4, 0x95, 0x80, 0x07, 0x91, 0x63, 0x06, 0xde, 0x95, 0xcb, 0x1c, 0x8e, - 0x75, 0x9e, 0x49, 0x75, 0x65, 0xc9, 0x8b, 0x4b, 0xc3, 0x32, 0x87, 0x06, 0x73, 0x3c, 0x89, 0x28, - 0x47, 0x10, 0x97, 0xd4, 0xf3, 0x4d, 0xc7, 0x8e, 0x7a, 0x5a, 0xfd, 0x14, 0xf2, 0x1d, 0xc3, 0x63, - 0x5d, 0xca, 0x1e, 0x53, 0x63, 0x48, 0x3d, 0xb2, 0x03, 0x09, 0xe6, 0x30, 0xc3, 0x2a, 0x2a, 0x15, - 0xe5, 0x20, 0xaf, 0x89, 0x05, 0x21, 0xa0, 0x8e, 0x0d, 0x7f, 0x5c, 0x8c, 0x55, 0x94, 0x83, 0x9c, - 0x86, 0xdf, 0xd5, 0x31, 0xa8, 0xdc, 0x94, 0x5b, 0x98, 0xf6, 0x90, 0xce, 0x02, 0x0b, 0x5c, 0x70, - 0x69, 0xff, 0x8a, 0x51, 0x5f, 0x9a, 0x88, 0x05, 0xf9, 0x11, 0x24, 0xd0, 0xff, 0x62, 0xbc, 0xa2, - 0x1c, 0x64, 0x8f, 0x8b, 0xb5, 0x48, 0xa2, 0x44, 0x7c, 0xb5, 0x0e, 0xd7, 0x37, 0xd4, 0xaf, 0xbe, - 0xd9, 0xdf, 0xd0, 0x04, 0xb8, 0x6a, 0x41, 0xaa, 0x61, 0x39, 0x83, 0xe7, 0xad, 0x93, 0xd0, 0x11, - 0x65, 0xee, 0x08, 0x39, 0x87, 0x2d, 0xd7, 0xf0, 0x98, 0xee, 0x53, 0xa6, 0x8f, 0x31, 0x0a, 0x3c, - 0x34, 0x7b, 0xbc, 0x5f, 0xbb, 0x5d, 0x87, 0xda, 0x42, 0xb0, 0xf2, 0x94, 0xbc, 0x1b, 0x15, 0x56, - 0xff, 0xa3, 0x42, 0x52, 0x26, 0xe3, 0x17, 0x90, 0x92, 0x49, 0xc3, 0x03, 0xb3, 0xc7, 0x0f, 0xa2, - 0x3b, 0x4a, 0x55, 0xad, 0xe9, 0xd8, 0x3e, 0xb5, 0xfd, 0xa9, 0x2f, 0xf7, 0x0b, 0x6c, 0xc8, 0xf7, - 0x21, 0x3d, 0x18, 0x1b, 0xa6, 0xad, 0x9b, 0x43, 0xf4, 0x28, 0xd3, 0xc8, 0xbe, 0xfa, 0x66, 0x3f, - 0xd5, 0xe4, 0xb2, 0xd6, 0x89, 0x96, 0x42, 0x65, 0x6b, 0x48, 0xee, 0x40, 0x72, 0x4c, 0xcd, 0xd1, - 0x98, 0x61, 0x5a, 0xe2, 0x9a, 0x5c, 0x91, 0x9f, 0x82, 0xca, 0x09, 0x51, 0x54, 0xf1, 0xec, 0x52, - 0x4d, 0xb0, 0xa5, 0x16, 0xb0, 0xa5, 0xd6, 0x0b, 0xd8, 0xd2, 0x48, 0xf3, 0x83, 0x5f, 0xfe, 0x73, - 0x5f, 0xd1, 0xd0, 0x82, 0x34, 0x21, 0x6f, 0x19, 0x3e, 0xd3, 0xfb, 0x3c, 0x6d, 0xfc, 0xf8, 0x04, - 0x6e, 0xb1, 0xb7, 0x9c, 0x10, 0x99, 0x58, 0xe9, 0x7a, 0x96, 0x5b, 0x09, 0xd1, 0x90, 0x1c, 0x40, - 0x01, 0x37, 0x19, 0x38, 0x93, 0x89, 0xc9, 0x74, 0xcc, 0x7b, 0x12, 0xf3, 0xbe, 0xc9, 0xe5, 0x4d, - 0x14, 0x3f, 0xe6, 0x15, 0xb8, 0x07, 0x99, 0xa1, 0xc1, 0x0c, 0x01, 0x49, 0x21, 0x24, 0xcd, 0x05, - 0xa8, 0xfc, 0x00, 0xb6, 0x42, 0x56, 0xfa, 0x02, 0x92, 0x16, 0xbb, 0xcc, 0xc5, 0x08, 0x3c, 0x82, - 0x1d, 0x9b, 0xce, 0x98, 0x7e, 0x1b, 0x9d, 0x41, 0x34, 0xe1, 0xba, 0xa7, 0x8b, 0x16, 0xdf, 0x83, - 0xcd, 0x41, 0x90, 0x7c, 0x81, 0x05, 0xc4, 0xe6, 0x43, 0x29, 0xc2, 0xf6, 0x20, 0x6d, 0xb8, 0xae, - 0x00, 0x64, 0x11, 0x90, 0x32, 0x5c, 0x17, 0x55, 0x1f, 0xc1, 0x36, 0xc6, 0xe8, 0x51, 0x7f, 0x6a, - 0x31, 0xb9, 0x49, 0x0e, 0x31, 0x5b, 0x5c, 0xa1, 0x09, 0x39, 0x62, 0xdf, 0x87, 0x3c, 0xbd, 0x34, - 0x87, 0xd4, 0x1e, 0x50, 0x81, 0xcb, 0x23, 0x2e, 0x17, 0x08, 0x11, 0xf4, 0x21, 0x14, 0x5c, 0xcf, - 0x71, 0x1d, 0x9f, 0x7a, 0xba, 0x31, 0x1c, 0x7a, 0xd4, 0xf7, 0x8b, 0x9b, 0x62, 0xbf, 0x40, 0x5e, - 0x17, 0xe2, 0x6a, 0x11, 0xd4, 0x13, 0x83, 0x19, 0xa4, 0x00, 0x71, 0x36, 0xf3, 0x8b, 0x4a, 0x25, - 0x7e, 0x90, 0xd3, 0xf8, 0x67, 0xb5, 0x0c, 0x89, 0xde, 0xec, 0x09, 0xbd, 0x22, 0xbb, 0x90, 0x64, - 0x33, 0xfd, 0x39, 0xbd, 0x92, 0x84, 0x4f, 0x30, 0x2e, 0xae, 0x7e, 0x19, 0x07, 0xf5, 0xa9, 0xc3, - 0x28, 0x79, 0x08, 0x2a, 0x2f, 0x23, 0x6a, 0x37, 0x57, 0xf1, 0xbd, 0x6b, 0x8e, 0x6c, 0x3a, 0x3c, - 0xf7, 0x47, 0xbd, 0x2b, 0x97, 0x6a, 0x08, 0x8e, 0xd0, 0x2d, 0xb6, 0x40, 0xb7, 0x1d, 0x48, 0x78, - 0xce, 0xd4, 0x1e, 0x22, 0x0b, 0x13, 0x9a, 0x58, 0x90, 0x53, 0x48, 0x87, 0x2c, 0x52, 0xbf, 0x8b, - 0x45, 0x5b, 0x9c, 0x45, 0x9c, 0xe3, 0x52, 0xa0, 0xa5, 0xfa, 0x92, 0x4c, 0x0d, 0xc8, 0x84, 0xcd, - 0x4d, 0xb2, 0xf1, 0xcd, 0x08, 0x3d, 0x37, 0x23, 0x1f, 0xc3, 0x76, 0xc8, 0x8d, 0x30, 0xb9, 0x82, - 0x91, 0x85, 0x50, 0x21, 0xb3, 0xbb, 0x40, 0x3b, 0x5d, 0x34, 0xa8, 0x14, 0xc6, 0x35, 0xa7, 0x5d, - 0x0b, 0x3b, 0xd5, 0x7d, 0xc8, 0xf8, 0xe6, 0xc8, 0x36, 0xd8, 0xd4, 0xa3, 0x92, 0x99, 0x73, 0x01, - 0xa9, 0x40, 0x86, 0xce, 0x18, 0xb5, 0xb1, 0x09, 0x20, 0x13, 0x1b, 0xb1, 0xa2, 0xa2, 0xcd, 0x85, - 0xe4, 0x21, 0xbc, 0x17, 0x2e, 0xf4, 0xf9, 0x4e, 0x10, 0x62, 0x49, 0xa8, 0xee, 0x06, 0xda, 0xea, - 0x9f, 0x15, 0x48, 0x8a, 0x0b, 0x14, 0x29, 0x87, 0xb2, 0xba, 0x1c, 0xb1, 0x75, 0xe5, 0x88, 0xbf, - 0x7d, 0x39, 0xea, 0x00, 0xa1, 0xab, 0x7e, 0x51, 0xad, 0xc4, 0x0f, 0xb2, 0xc7, 0xf7, 0x96, 0x37, - 0x12, 0x2e, 0x76, 0xcd, 0x91, 0xec, 0x0f, 0x11, 0xa3, 0xea, 0x3f, 0x14, 0xc8, 0x84, 0x7a, 0x52, - 0x87, 0x7c, 0xe0, 0x97, 0xfe, 0xcc, 0x32, 0x46, 0x92, 0x92, 0x0f, 0xd6, 0x3a, 0xf7, 0x99, 0x65, - 0x8c, 0xb4, 0xac, 0xf4, 0x87, 0x2f, 0x56, 0x97, 0x37, 0xb6, 0xa6, 0xbc, 0x0b, 0x7c, 0x8a, 0xbf, - 0x1d, 0x9f, 0x16, 0x2a, 0xaf, 0xde, 0xaa, 0x7c, 0xf5, 0x4b, 0x15, 0xd2, 0x1d, 0xbc, 0xb2, 0x86, - 0xf5, 0xff, 0xb8, 0x68, 0xf7, 0x20, 0xe3, 0x3a, 0x96, 0x2e, 0x34, 0x2a, 0x6a, 0xd2, 0xae, 0x63, - 0x69, 0x4b, 0x65, 0x4f, 0xbc, 0xa3, 0x5b, 0x98, 0x7c, 0x07, 0x59, 0x4b, 0xdd, 0xbe, 0x2f, 0x47, - 0x90, 0x12, 0x1d, 0xcb, 0x2f, 0xa6, 0x91, 0x55, 0x77, 0x97, 0xfd, 0xc4, 0xde, 0xa6, 0x25, 0xb1, - 0x97, 0xf9, 0xe4, 0x67, 0x90, 0x0e, 0x3a, 0x28, 0x5e, 0xb0, 0xec, 0x71, 0x79, 0xd9, 0xe4, 0x54, - 0x22, 0xce, 0x4c, 0x9f, 0x69, 0x21, 0x9e, 0x7c, 0x0a, 0xd9, 0xc8, 0x13, 0x85, 0x77, 0xee, 0xd6, - 0x54, 0x11, 0xe5, 0xb1, 0x06, 0xf3, 0x77, 0x8b, 0xfc, 0x98, 0x17, 0x07, 0x87, 0x85, 0xec, 0x3a, - 0xab, 0x85, 0x29, 0x41, 0xa2, 0x57, 0x36, 0xf8, 0xdc, 0xea, 0x06, 0xef, 0x41, 0x4e, 0xd0, 0x42, - 0x8e, 0x13, 0x47, 0xe1, 0x91, 0xca, 0xb7, 0x1f, 0x19, 0x1e, 0x76, 0x04, 0x49, 0x19, 0x5a, 0xec, - 0x3b, 0x42, 0x93, 0xb8, 0xea, 0xef, 0x15, 0x80, 0x33, 0xce, 0x32, 0xac, 0x3d, 0x1f, 0x04, 0x7c, - 0x74, 0x41, 0x5f, 0x38, 0xb9, 0xbc, 0x8e, 0xc0, 0xf2, 0xfc, 0x9c, 0x1f, 0xf5, 0xbb, 0x09, 0xf9, - 0xf9, 0xc5, 0xf4, 0x69, 0xe0, 0xcc, 0x8a, 0x4d, 0xc2, 0xf7, 0xb9, 0x4b, 0x99, 0x96, 0xbb, 0x8c, - 0xac, 0xaa, 0x7f, 0x51, 0x20, 0x83, 0x3e, 0x9d, 0x53, 0x66, 0x2c, 0xf0, 0x59, 0x79, 0x7b, 0x3e, - 0x3f, 0x00, 0x10, 0xdb, 0xf8, 0xe6, 0x0b, 0x2a, 0x6f, 0x59, 0x06, 0x25, 0x5d, 0xf3, 0x05, 0x8d, - 0xd4, 0x38, 0xfe, 0x3f, 0xd5, 0xf8, 0x2e, 0xa4, 0xec, 0xe9, 0x44, 0xe7, 0xaf, 0xb2, 0x2a, 0x6e, - 0xae, 0x3d, 0x9d, 0xf4, 0x66, 0x7e, 0xf5, 0xb7, 0x90, 0xea, 0xcd, 0x70, 0x42, 0xe5, 0xd7, 0xd5, - 0x73, 0x1c, 0x39, 0x16, 0x89, 0xd7, 0x39, 0xcd, 0x05, 0x38, 0x05, 0x10, 0x50, 0xf9, 0xfc, 0x13, - 0xcc, 0xcb, 0xfc, 0x9b, 0xd4, 0xde, 0x70, 0xf6, 0x0d, 0xa6, 0xde, 0x7f, 0x2b, 0x90, 0x0e, 0x68, - 0x4f, 0x0c, 0xb8, 0x3b, 0x9c, 0xba, 0x96, 0x39, 0x30, 0x18, 0xd5, 0x2f, 0x1d, 0x46, 0xf5, 0xf0, - 0xce, 0x88, 0xf4, 0x7d, 0xb0, 0x1c, 0xda, 0x49, 0x60, 0xc0, 0x47, 0x85, 0x60, 0xa7, 0xc7, 0x1b, - 0xda, 0xee, 0x70, 0x95, 0x82, 0xd8, 0x70, 0xdf, 0xe2, 0xc4, 0xd1, 0x07, 0x96, 0x49, 0x6d, 0xa6, - 0x1b, 0x8c, 0x19, 0x83, 0xe7, 0xf3, 0x73, 0x44, 0xd1, 0x3f, 0x5e, 0x3e, 0x07, 0xe9, 0xd6, 0x44, - 0xa3, 0x3a, 0xda, 0x44, 0xce, 0xda, 0xb3, 0xd6, 0x29, 0x1b, 0x09, 0x88, 0xfb, 0xd3, 0x49, 0xf5, - 0x65, 0x0c, 0x76, 0x57, 0x7a, 0x4a, 0x7e, 0x00, 0x49, 0x8c, 0xd4, 0x90, 0x21, 0xde, 0x59, 0xc1, - 0x37, 0x87, 0x51, 0x2d, 0xc1, 0x51, 0xf5, 0x10, 0xde, 0x97, 0x9e, 0x7e, 0x2b, 0xbc, 0x41, 0x3e, - 0x01, 0x82, 0xff, 0xdb, 0xf0, 0x6c, 0x9a, 0xf6, 0x48, 0x77, 0x9d, 0x2f, 0x24, 0x4f, 0xe2, 0x5a, - 0x01, 0x35, 0x4f, 0x51, 0xd1, 0xe1, 0xf2, 0xc5, 0x69, 0x42, 0x40, 0x05, 0x33, 0xe6, 0xd3, 0x84, - 0x00, 0xbe, 0x83, 0x39, 0xa7, 0xfa, 0xd7, 0x18, 0xec, 0xad, 0x4d, 0x2a, 0x69, 0xc1, 0xf6, 0xc0, - 0xb1, 0x9f, 0x59, 0xe6, 0x00, 0xfd, 0x46, 0xb6, 0xcb, 0x0c, 0xdd, 0x5f, 0x53, 0x1c, 0xbc, 0x37, - 0x5a, 0x21, 0x62, 0x26, 0xba, 0xc3, 0xfb, 0x90, 0xe7, 0x6d, 0xc3, 0xb1, 0xf5, 0x85, 0x77, 0x2a, - 0x27, 0x84, 0x8f, 0xc5, 0x6b, 0xd5, 0x86, 0x9d, 0xfe, 0xd5, 0x0b, 0xc3, 0x66, 0xa6, 0x4d, 0x23, - 0xb3, 0x79, 0x31, 0xbe, 0x6e, 0x68, 0x08, 0x9b, 0x80, 0xf6, 0x5e, 0x68, 0x38, 0x1f, 0xdc, 0xd7, - 0x24, 0x5e, 0x5d, 0x93, 0xf8, 0x77, 0x91, 0xcf, 0x33, 0xc8, 0x45, 0xdf, 0x0f, 0xf2, 0xf3, 0xc8, - 0x8b, 0xa3, 0x60, 0x14, 0xa5, 0xf5, 0x2f, 0x8e, 0x6c, 0x0d, 0xa1, 0xc5, 0x47, 0x7f, 0x53, 0x20, - 0x1b, 0x99, 0x61, 0xc8, 0x0f, 0x61, 0xb7, 0x71, 0x76, 0xd1, 0x7c, 0xa2, 0xb7, 0x4e, 0xf4, 0xcf, - 0xce, 0xea, 0x8f, 0xf4, 0xcf, 0xdb, 0x4f, 0xda, 0x17, 0xbf, 0x6a, 0x17, 0x36, 0x4a, 0x77, 0xae, - 0x6f, 0x2a, 0x24, 0x82, 0xfd, 0xdc, 0x7e, 0x6e, 0x3b, 0x5f, 0xd8, 0xe4, 0x10, 0x76, 0x16, 0x4d, - 0xea, 0x8d, 0xee, 0x69, 0xbb, 0x57, 0x50, 0x4a, 0xbb, 0xd7, 0x37, 0x95, 0xed, 0x88, 0x45, 0xbd, - 0xef, 0x53, 0x9b, 0x2d, 0x1b, 0x34, 0x2f, 0xce, 0xcf, 0x5b, 0xbd, 0x42, 0x6c, 0xc9, 0x40, 0xbe, - 0x6e, 0x1f, 0xc2, 0xf6, 0xa2, 0x41, 0xbb, 0x75, 0x56, 0x88, 0x97, 0xc8, 0xf5, 0x4d, 0x65, 0x33, - 0x82, 0x6e, 0x9b, 0x56, 0x29, 0xfd, 0xbb, 0x3f, 0x94, 0x37, 0xfe, 0xf4, 0xc7, 0xb2, 0xc2, 0x23, - 0xcb, 0x2f, 0xcc, 0x31, 0xe4, 0x13, 0xb8, 0xdb, 0x6d, 0x3d, 0x6a, 0x9f, 0x9e, 0xe8, 0xe7, 0xdd, - 0x47, 0x7a, 0xef, 0xd7, 0x9d, 0xd3, 0x48, 0x74, 0x5b, 0xd7, 0x37, 0x95, 0xac, 0x0c, 0x69, 0x1d, - 0xba, 0xa3, 0x9d, 0x3e, 0xbd, 0xe8, 0x9d, 0x16, 0x14, 0x81, 0xee, 0x78, 0x94, 0xdf, 0x3e, 0x44, - 0x1f, 0xc1, 0xde, 0x0a, 0x74, 0x18, 0xd8, 0xf6, 0xf5, 0x4d, 0x25, 0xdf, 0xf1, 0xa8, 0x78, 0xd7, - 0xd0, 0xa2, 0x06, 0xc5, 0x65, 0x8b, 0x8b, 0xce, 0x45, 0xb7, 0x7e, 0x56, 0xa8, 0x94, 0x0a, 0xd7, - 0x37, 0x95, 0x5c, 0x30, 0xb0, 0x71, 0xfc, 0x3c, 0xb2, 0xc6, 0x2f, 0xbf, 0x7a, 0x55, 0x56, 0xbe, - 0x7e, 0x55, 0x56, 0xfe, 0xf5, 0xaa, 0xac, 0xbc, 0x7c, 0x5d, 0xde, 0xf8, 0xfa, 0x75, 0x79, 0xe3, - 0xef, 0xaf, 0xcb, 0x1b, 0xbf, 0xf9, 0xc9, 0xc8, 0x64, 0xe3, 0x69, 0xbf, 0x36, 0x70, 0x26, 0x87, - 0xd1, 0x5f, 0x53, 0xe6, 0x9f, 0xe2, 0x57, 0x9b, 0xdb, 0xbf, 0xb4, 0xf4, 0x93, 0x28, 0x7f, 0xf8, - 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa8, 0xea, 0x99, 0x71, 0x0a, 0x12, 0x00, 0x00, + // 1862 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0x4f, 0x6f, 0x1b, 0xc7, + 0x15, 0xd7, 0x8a, 0xff, 0x1f, 0x49, 0x89, 0x9a, 0x48, 0x16, 0x45, 0xdb, 0x14, 0xcb, 0x20, 0x8d, + 0x92, 0xb8, 0x94, 0xaa, 0x14, 0x6d, 0x12, 0xb4, 0x07, 0xae, 0xa4, 0x98, 0x84, 0xf5, 0x87, 0x5d, + 0x32, 0x2e, 0xda, 0x43, 0x17, 0x4b, 0x72, 0x4c, 0x6e, 0xbd, 0xdc, 0x5d, 0xec, 0x0e, 0x15, 0xc9, + 0x9f, 0xc0, 0xd0, 0xc9, 0x97, 0xf6, 0xa6, 0x53, 0x7b, 0x08, 0xd0, 0x0f, 0xd1, 0xa2, 0x27, 0x5f, + 0x0a, 0xe4, 0xd6, 0x5e, 0x9a, 0x16, 0x72, 0xd1, 0xcf, 0x51, 0xcc, 0x9b, 0xd9, 0xe5, 0x52, 0x24, + 0xe3, 0xc4, 0xf0, 0x45, 0xd8, 0x79, 0xef, 0xf7, 0x66, 0xde, 0x9f, 0xdf, 0xbc, 0x79, 0x22, 0xdc, + 0x63, 0xd4, 0xee, 0x53, 0x6f, 0x64, 0xda, 0x6c, 0x97, 0x5d, 0xba, 0xd4, 0x17, 0x7f, 0x6b, 0xae, + 0xe7, 0x30, 0x87, 0x14, 0x26, 0xda, 0x1a, 0xca, 0x4b, 0xeb, 0x03, 0x67, 0xe0, 0xa0, 0x72, 0x97, + 0x7f, 0x09, 0x5c, 0x69, 0x7b, 0xe0, 0x38, 0x03, 0x8b, 0xee, 0xe2, 0xaa, 0x3b, 0x7e, 0xb2, 0xcb, + 0xcc, 0x11, 0xf5, 0x99, 0x31, 0x72, 0x25, 0xe0, 0x7e, 0xe4, 0x98, 0x9e, 0x77, 0xe9, 0x32, 0x87, + 0x63, 0x9d, 0x27, 0x52, 0x5d, 0x99, 0xf1, 0xe2, 0xdc, 0xb0, 0xcc, 0xbe, 0xc1, 0x1c, 0x4f, 0x22, + 0xca, 0x11, 0xc4, 0x39, 0xf5, 0x7c, 0xd3, 0xb1, 0xa3, 0x9e, 0x96, 0x56, 0x86, 0x86, 0x3f, 0x34, + 0xba, 0x16, 0x15, 0xeb, 0xea, 0x6f, 0x21, 0xdf, 0x32, 0x3c, 0xd6, 0xa6, 0xac, 0x41, 0x8d, 0x3e, + 0xf5, 0xc8, 0x16, 0x24, 0x98, 0xc3, 0x0c, 0xab, 0xa8, 0x54, 0x94, 0x9d, 0x7c, 0x63, 0x49, 0x13, + 0xcb, 0xe7, 0x8a, 0x42, 0x36, 0x21, 0xce, 0xad, 0x8b, 0xcb, 0x15, 0x65, 0x27, 0xd7, 0x50, 0x34, + 0x5c, 0x3d, 0x57, 0x94, 0xcf, 0x92, 0x2f, 0x9f, 0xdf, 0xfc, 0x39, 0xa7, 0xa8, 0x69, 0x48, 0xea, + 0x88, 0x56, 0x53, 0x90, 0xd0, 0xb9, 0xb6, 0x3a, 0x84, 0x38, 0xdf, 0x9f, 0xac, 0x43, 0xc2, 0xb4, + 0xfb, 0xf4, 0x42, 0x6c, 0xab, 0x89, 0x05, 0x97, 0x76, 0x2f, 0x19, 0xf5, 0xc5, 0x96, 0x9a, 0x58, + 0x90, 0x9f, 0x40, 0x02, 0x83, 0x2e, 0xc6, 0x2a, 0xca, 0x4e, 0x76, 0xbf, 0x58, 0x8b, 0x64, 0x57, + 0x24, 0xa5, 0xd6, 0xe2, 0x7a, 0x35, 0xfe, 0xf2, 0x9b, 0xed, 0x25, 0x4d, 0x80, 0xab, 0xbf, 0x57, + 0x20, 0xa5, 0x5a, 0x4e, 0xef, 0x69, 0xf3, 0x30, 0xf4, 0x54, 0x41, 0x4f, 0x97, 0x42, 0x4f, 0xc9, + 0x31, 0xac, 0xba, 0x86, 0xc7, 0x74, 0x9f, 0x32, 0x7d, 0x88, 0x01, 0xe3, 0xd1, 0xd9, 0xfd, 0xed, + 0xda, 0xed, 0x12, 0xd6, 0xa6, 0xf2, 0xd2, 0x50, 0xb4, 0xbc, 0x1b, 0x15, 0x44, 0xe3, 0x0e, 0xa2, + 0x55, 0x09, 0x14, 0xf4, 0x5b, 0xfb, 0x57, 0xff, 0x17, 0x87, 0xa4, 0xcc, 0xed, 0x2f, 0x20, 0x25, + 0x6b, 0x82, 0x9e, 0x65, 0xf7, 0xef, 0x47, 0x4f, 0x95, 0xaa, 0xda, 0x81, 0x63, 0xfb, 0xd4, 0xf6, + 0xc7, 0xbe, 0x8c, 0x2f, 0xb0, 0x21, 0x3f, 0x84, 0x74, 0x6f, 0x68, 0x98, 0xb6, 0x6e, 0xf6, 0xd1, + 0xeb, 0x8c, 0x9a, 0xbd, 0xf9, 0x66, 0x3b, 0x75, 0xc0, 0x65, 0xcd, 0x43, 0x2d, 0x85, 0xca, 0x66, + 0x9f, 0xdc, 0x81, 0xe4, 0x90, 0x9a, 0x83, 0x21, 0xc3, 0x04, 0xc6, 0x34, 0xb9, 0x22, 0x9f, 0x40, + 0x9c, 0xf3, 0xad, 0x18, 0xc7, 0xb3, 0x4b, 0x35, 0x41, 0xc6, 0x5a, 0x40, 0xc6, 0x5a, 0x27, 0x20, + 0xa3, 0x9a, 0xe6, 0x07, 0xbf, 0xf8, 0xf7, 0xb6, 0xa2, 0xa1, 0x05, 0x39, 0x80, 0xbc, 0x65, 0xf8, + 0x4c, 0xef, 0xf2, 0xfc, 0xf2, 0xe3, 0x13, 0xb8, 0xc5, 0xd6, 0x6c, 0xd2, 0x64, 0x05, 0xa4, 0xeb, + 0x59, 0x6e, 0x25, 0x44, 0x7d, 0xb2, 0x03, 0x05, 0xdc, 0xa4, 0xe7, 0x8c, 0x46, 0x26, 0xc3, 0x84, + 0x15, 0x93, 0x58, 0xf7, 0x15, 0x2e, 0x3f, 0x40, 0x71, 0xc3, 0xf0, 0x87, 0xe4, 0x2e, 0x64, 0xfa, + 0x06, 0x33, 0x04, 0x24, 0x85, 0x90, 0x34, 0x17, 0xa0, 0xf2, 0x7d, 0x58, 0x0d, 0x49, 0xef, 0x0b, + 0x48, 0x5a, 0xec, 0x32, 0x11, 0x23, 0x70, 0x0f, 0xd6, 0x6d, 0x7a, 0xc1, 0xf4, 0xdb, 0xe8, 0x0c, + 0xa2, 0x09, 0xd7, 0x3d, 0x9e, 0xb6, 0x78, 0x0f, 0x56, 0x7a, 0x41, 0xf2, 0x05, 0x16, 0x10, 0x9b, + 0x0f, 0xa5, 0x08, 0xdb, 0x82, 0xb4, 0xe1, 0xba, 0x02, 0x90, 0x45, 0x40, 0xca, 0x70, 0x5d, 0x54, + 0x7d, 0x08, 0x6b, 0x18, 0xa3, 0x47, 0xfd, 0xb1, 0xc5, 0xe4, 0x26, 0x39, 0xc4, 0xac, 0x72, 0x85, + 0x26, 0xe4, 0x88, 0x7d, 0x17, 0xf2, 0xf4, 0xdc, 0xec, 0x53, 0xbb, 0x47, 0x05, 0x2e, 0x8f, 0xb8, + 0x5c, 0x20, 0x44, 0xd0, 0x07, 0x50, 0x70, 0x3d, 0xc7, 0x75, 0x7c, 0xea, 0xe9, 0x46, 0xbf, 0xef, + 0x51, 0xdf, 0x2f, 0xae, 0x88, 0xfd, 0x02, 0x79, 0x5d, 0x88, 0xab, 0x45, 0x88, 0x1f, 0x1a, 0xcc, + 0x20, 0x05, 0x88, 0xb1, 0x0b, 0xbf, 0xa8, 0x54, 0x62, 0x3b, 0x39, 0x8d, 0x7f, 0x56, 0xcb, 0x90, + 0xe8, 0x5c, 0x3c, 0xa2, 0x97, 0x64, 0x03, 0x92, 0xec, 0x42, 0x7f, 0x4a, 0x2f, 0xc5, 0xcd, 0xd0, + 0x12, 0x8c, 0x8b, 0xab, 0x5f, 0xc5, 0x21, 0xfe, 0xd8, 0x61, 0x14, 0x19, 0x72, 0xe9, 0x52, 0xd4, + 0xae, 0xcc, 0xbb, 0x13, 0x6d, 0x73, 0x60, 0xd3, 0xfe, 0x89, 0x3f, 0xe8, 0x5c, 0xba, 0x94, 0x5f, + 0x2c, 0x2e, 0xe6, 0x17, 0xeb, 0x6e, 0xc8, 0x39, 0xce, 0xcc, 0x58, 0x43, 0x09, 0x58, 0xc7, 0x95, + 0x5b, 0x90, 0xf0, 0x9c, 0xb1, 0xdd, 0x47, 0x3e, 0x26, 0x1a, 0xcb, 0x9a, 0x58, 0x72, 0xd5, 0xa7, + 0x90, 0x0e, 0x49, 0x15, 0x7f, 0x0d, 0xa9, 0x1a, 0x31, 0x2d, 0xd5, 0x15, 0x64, 0xe2, 0xa6, 0x7b, + 0xb0, 0x16, 0x96, 0x36, 0xcc, 0x0d, 0x12, 0xaa, 0x11, 0xd7, 0x0a, 0xa1, 0x4a, 0xa6, 0x87, 0x5b, + 0x3c, 0x88, 0x50, 0x47, 0x17, 0xed, 0x28, 0x85, 0x1e, 0x25, 0x22, 0xe4, 0x69, 0x72, 0x39, 0x47, + 0xff, 0x00, 0x32, 0xbe, 0x39, 0xb0, 0x0d, 0x36, 0xf6, 0xa8, 0xa0, 0x58, 0x23, 0xa9, 0x4d, 0x44, + 0x1c, 0xf2, 0x1e, 0x64, 0xe8, 0x05, 0xa3, 0x36, 0x5e, 0x69, 0xe4, 0x95, 0xba, 0x5c, 0x54, 0x1a, + 0x29, 0x6d, 0x22, 0xe6, 0xb0, 0x4f, 0xe0, 0x9d, 0x70, 0xad, 0x4f, 0xf6, 0x84, 0xd0, 0x20, 0xad, + 0x91, 0x10, 0xd0, 0x8e, 0x1c, 0x30, 0xd5, 0x61, 0x78, 0x2e, 0xd4, 0x0c, 0xa4, 0x74, 0x91, 0x58, + 0xec, 0xb6, 0x98, 0x47, 0x35, 0x0b, 0x99, 0xf0, 0x6a, 0xaa, 0xeb, 0x40, 0xf4, 0x99, 0xbc, 0x60, + 0x67, 0xba, 0x15, 0xbb, 0x9a, 0x03, 0x98, 0x78, 0x83, 0xab, 0xd0, 0x09, 0xf5, 0x0e, 0xac, 0xeb, + 0x73, 0x7c, 0xae, 0xfe, 0x55, 0x81, 0xa4, 0xb8, 0xa9, 0x91, 0x36, 0xa3, 0x4c, 0xb5, 0x99, 0xf5, + 0xa0, 0xda, 0x9c, 0x09, 0x09, 0x59, 0x6b, 0x72, 0x14, 0x29, 0x74, 0xec, 0x75, 0xdd, 0x63, 0x95, + 0x77, 0x0f, 0xde, 0xdb, 0xa4, 0x20, 0xac, 0x3b, 0xa9, 0x03, 0x84, 0xce, 0xf8, 0xc5, 0x78, 0x25, + 0xb6, 0x93, 0xdd, 0xbf, 0x3b, 0xbb, 0x91, 0x70, 0xb1, 0x6d, 0x0e, 0x64, 0x23, 0x8a, 0x18, 0x55, + 0xff, 0xa5, 0x40, 0x26, 0xd4, 0x93, 0x3a, 0xe4, 0x03, 0xbf, 0xf4, 0x27, 0x96, 0x31, 0x90, 0xdc, + 0xbf, 0xbf, 0xd0, 0xb9, 0xcf, 0x2d, 0x63, 0xa0, 0x65, 0xa5, 0x3f, 0x7c, 0x41, 0x3e, 0x9a, 0x47, + 0x44, 0xf1, 0xa2, 0xcd, 0xd0, 0x90, 0xa8, 0x90, 0x09, 0x1f, 0x7d, 0x99, 0x88, 0xef, 0xd6, 0x89, + 0x27, 0x66, 0xe4, 0x5e, 0x94, 0x99, 0x71, 0x3c, 0x68, 0x22, 0xa8, 0xfe, 0x25, 0x0e, 0xe9, 0x16, + 0xf6, 0x06, 0xc3, 0x22, 0x1f, 0x7f, 0xaf, 0x1b, 0x2d, 0xee, 0x73, 0xa4, 0xb2, 0xcb, 0xf3, 0x2b, + 0x1b, 0x8b, 0x56, 0xf6, 0x2e, 0x64, 0x5c, 0xc7, 0x12, 0x54, 0x44, 0x6f, 0x12, 0x5a, 0xda, 0x75, + 0x2c, 0x6d, 0xa6, 0xec, 0x89, 0x37, 0x2f, 0xfb, 0x54, 0xd6, 0x92, 0x6f, 0x21, 0x6b, 0xa9, 0x5b, + 0x59, 0x23, 0x7b, 0x90, 0x12, 0xad, 0xd1, 0x2f, 0xa6, 0x91, 0x55, 0x9b, 0xb3, 0x7e, 0x62, 0x13, + 0xd5, 0x92, 0xd8, 0x34, 0x7d, 0xf2, 0x19, 0xa4, 0x83, 0x56, 0x8d, 0x77, 0x3f, 0xbb, 0x5f, 0x9e, + 0x35, 0x39, 0x92, 0x88, 0x63, 0xd3, 0x67, 0x5a, 0x88, 0x27, 0x9f, 0x42, 0x36, 0xf2, 0x16, 0x62, + 0x27, 0xb8, 0x35, 0xe8, 0x44, 0x79, 0xac, 0xc1, 0xe4, 0x81, 0x24, 0x3f, 0xe5, 0xc5, 0xc1, 0xc9, + 0x25, 0xbb, 0xc8, 0x4a, 0x8c, 0x1b, 0x92, 0xfa, 0x12, 0x3d, 0xf7, 0x25, 0xc9, 0xcd, 0x7f, 0x49, + 0x3c, 0xc8, 0x09, 0x5a, 0xc8, 0xb9, 0x65, 0x2f, 0x3c, 0x52, 0xf9, 0xf6, 0x23, 0xc3, 0xc3, 0xf6, + 0x20, 0x29, 0x43, 0x5b, 0x7e, 0x4d, 0x68, 0x12, 0x57, 0xfd, 0x83, 0x02, 0x70, 0x8c, 0x7d, 0x8d, + 0x97, 0x9c, 0x4f, 0x1c, 0x3e, 0xba, 0xa0, 0x4f, 0x9d, 0x5c, 0x5e, 0x44, 0x60, 0x79, 0x7e, 0xce, + 0x8f, 0xfa, 0x7d, 0x00, 0xf9, 0xc9, 0xc5, 0xf4, 0x69, 0xe0, 0xcc, 0x9c, 0x4d, 0xc2, 0x41, 0xa0, + 0x4d, 0x99, 0x96, 0x3b, 0x8f, 0xac, 0xaa, 0x7f, 0x53, 0x20, 0x83, 0x3e, 0x9d, 0x50, 0x66, 0x4c, + 0xf1, 0x59, 0x79, 0x73, 0x3e, 0xdf, 0x07, 0x10, 0xdb, 0xf8, 0xe6, 0x33, 0x2a, 0x6f, 0x59, 0x06, + 0x25, 0x6d, 0xf3, 0x19, 0x8d, 0xd4, 0x38, 0xf6, 0xbd, 0x6a, 0xbc, 0x09, 0x29, 0x7b, 0x3c, 0xd2, + 0xf9, 0xf3, 0x1f, 0x17, 0x37, 0xd7, 0x1e, 0x8f, 0x3a, 0x17, 0x7e, 0xf5, 0x77, 0x90, 0xea, 0x5c, + 0xe0, 0xd0, 0xcc, 0xaf, 0xab, 0xe7, 0x38, 0x72, 0xfe, 0x12, 0x63, 0x40, 0x9a, 0x0b, 0x70, 0xdc, + 0x20, 0x10, 0xe7, 0x83, 0x96, 0xec, 0x5e, 0xf8, 0x4d, 0x6a, 0xdf, 0x71, 0x1c, 0x0f, 0x06, 0xf1, + 0xff, 0x2a, 0x90, 0x0e, 0x68, 0x4f, 0x0c, 0xd8, 0xec, 0x8f, 0x5d, 0xcb, 0xec, 0x19, 0x8c, 0xea, + 0xe7, 0x0e, 0xa3, 0x7a, 0x78, 0x67, 0x44, 0xfa, 0xde, 0x9f, 0x0d, 0xed, 0x30, 0x30, 0xe0, 0x33, + 0x49, 0xb0, 0x53, 0x63, 0x49, 0xdb, 0xe8, 0xcf, 0x53, 0x10, 0x1b, 0xee, 0x59, 0x9c, 0x38, 0x7a, + 0xcf, 0x32, 0xa9, 0xcd, 0x74, 0x83, 0x31, 0xa3, 0xf7, 0x74, 0x72, 0x8e, 0x28, 0xfa, 0x47, 0xb3, + 0xe7, 0x20, 0xdd, 0x0e, 0xd0, 0xa8, 0x8e, 0x36, 0x91, 0xb3, 0xb6, 0xac, 0x45, 0x4a, 0x35, 0x01, + 0x31, 0x7f, 0x3c, 0xaa, 0xbe, 0x58, 0x86, 0x8d, 0xb9, 0x9e, 0x92, 0x1f, 0x41, 0x12, 0x23, 0x35, + 0x64, 0x88, 0x77, 0xe6, 0xf0, 0xcd, 0x61, 0x54, 0x4b, 0x70, 0x54, 0x3d, 0x84, 0x77, 0xa5, 0xa7, + 0xdf, 0x0a, 0x57, 0xc9, 0x03, 0x20, 0xf8, 0x3f, 0x16, 0xcf, 0xa6, 0x69, 0x0f, 0x74, 0xd7, 0xf9, + 0x52, 0xf2, 0x24, 0xa6, 0x15, 0x50, 0xf3, 0x18, 0x15, 0x2d, 0x2e, 0x9f, 0x9a, 0x96, 0x25, 0x54, + 0x30, 0x63, 0x32, 0xf0, 0x08, 0xe0, 0x54, 0x87, 0x4d, 0xbc, 0x51, 0x87, 0xad, 0xfe, 0x7d, 0x19, + 0xb6, 0x16, 0x26, 0x95, 0x34, 0x61, 0xad, 0xe7, 0xd8, 0x4f, 0x2c, 0xb3, 0x87, 0x7e, 0x23, 0xdb, + 0x65, 0x86, 0xee, 0x2d, 0x28, 0x0e, 0xde, 0x1b, 0xad, 0x10, 0x31, 0x13, 0xdd, 0xe1, 0x5d, 0xc8, + 0xf3, 0xb6, 0xe1, 0xd8, 0xfa, 0xd4, 0x3b, 0x95, 0x13, 0xc2, 0x86, 0x78, 0xad, 0x4e, 0x61, 0xbd, + 0x7b, 0xf9, 0xcc, 0xb0, 0x99, 0x69, 0xd3, 0xc8, 0x3f, 0x01, 0xc5, 0xd8, 0xa2, 0xa1, 0x21, 0x6c, + 0x02, 0xda, 0x3b, 0xa1, 0xe1, 0xe4, 0x3f, 0x84, 0x05, 0x89, 0x8f, 0x2f, 0x48, 0xfc, 0xdb, 0xc8, + 0xe7, 0x31, 0xe4, 0xa2, 0xef, 0x07, 0xf9, 0x79, 0xe4, 0xc5, 0x51, 0x30, 0x8a, 0xd2, 0xe2, 0x17, + 0x47, 0xb6, 0x86, 0xd0, 0xe2, 0xc3, 0x7f, 0x28, 0x90, 0x8d, 0xcc, 0x30, 0xe4, 0xc7, 0xb0, 0xa1, + 0x1e, 0x9f, 0x1d, 0x3c, 0xd2, 0x9b, 0x87, 0xfa, 0xe7, 0xc7, 0xf5, 0x87, 0xfa, 0x17, 0xa7, 0x8f, + 0x4e, 0xcf, 0x7e, 0x75, 0x5a, 0x58, 0x2a, 0xdd, 0xb9, 0xba, 0xae, 0x90, 0x08, 0xf6, 0x0b, 0xfb, + 0xa9, 0xed, 0x7c, 0x69, 0x93, 0x5d, 0x58, 0x9f, 0x36, 0xa9, 0xab, 0xed, 0xa3, 0xd3, 0x4e, 0x41, + 0x29, 0x6d, 0x5c, 0x5d, 0x57, 0xd6, 0x22, 0x16, 0xf5, 0xae, 0x4f, 0x6d, 0x36, 0x6b, 0x70, 0x70, + 0x76, 0x72, 0xd2, 0xec, 0x14, 0x96, 0x67, 0x0c, 0xe4, 0xeb, 0xf6, 0x01, 0xac, 0x4d, 0x1b, 0x9c, + 0x36, 0x8f, 0x0b, 0xb1, 0x12, 0xb9, 0xba, 0xae, 0xac, 0x44, 0xd0, 0xa7, 0xa6, 0x55, 0x4a, 0x3f, + 0xff, 0x63, 0x79, 0xe9, 0xab, 0x3f, 0x95, 0x15, 0x1e, 0x59, 0x7e, 0x6a, 0x8e, 0x21, 0x0f, 0x60, + 0xb3, 0xdd, 0x7c, 0x78, 0x7a, 0x74, 0xa8, 0x9f, 0xb4, 0x1f, 0xea, 0x9d, 0x5f, 0xb7, 0x8e, 0x22, + 0xd1, 0xad, 0x5e, 0x5d, 0x57, 0xb2, 0x32, 0xa4, 0x45, 0xe8, 0x96, 0x76, 0xf4, 0xf8, 0xac, 0x73, + 0x54, 0x50, 0x04, 0xba, 0xe5, 0x51, 0x7e, 0xfb, 0x10, 0xbd, 0x07, 0x5b, 0x73, 0xd0, 0x61, 0x60, + 0x6b, 0x57, 0xd7, 0x95, 0x7c, 0xcb, 0xa3, 0xe2, 0x5d, 0x43, 0x8b, 0x1a, 0x14, 0x67, 0x2d, 0xce, + 0x5a, 0x67, 0xed, 0xfa, 0x71, 0xa1, 0x52, 0x2a, 0x5c, 0x5d, 0x57, 0x72, 0xc1, 0xc0, 0xc6, 0xf1, + 0x93, 0xc8, 0xd4, 0x5f, 0xbe, 0xbc, 0x29, 0x2b, 0x5f, 0xdf, 0x94, 0x95, 0xff, 0xdc, 0x94, 0x95, + 0x17, 0xaf, 0xca, 0x4b, 0x5f, 0xbf, 0x2a, 0x2f, 0xfd, 0xf3, 0x55, 0x79, 0xe9, 0x37, 0x3f, 0x1b, + 0x98, 0x6c, 0x38, 0xee, 0xd6, 0x7a, 0xce, 0x68, 0x37, 0xfa, 0xab, 0xd0, 0xe4, 0x53, 0xfc, 0xfa, + 0x74, 0xfb, 0x17, 0xa3, 0x6e, 0x12, 0xe5, 0x1f, 0xff, 0x3f, 0x00, 0x00, 0xff, 0xff, 0xeb, 0x2d, + 0x75, 0xce, 0xd2, 0x12, 0x00, 0x00, } func (m *PartSetHeader) Marshal() (dAtA []byte, err error) { @@ -1575,21 +1852,55 @@ func (m *PartSetHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.Hash) > 0 { + if m.XHash != nil { + { + size := m.XHash.Size() + i -= size + if _, err := m.XHash.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + if m.XTotal != nil { + { + size := m.XTotal.Size() + i -= size + if _, err := m.XTotal.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + return len(dAtA) - i, nil +} + +func (m *PartSetHeader_Total) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PartSetHeader_Total) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + i = encodeVarintTypes(dAtA, i, uint64(m.Total)) + i-- + dAtA[i] = 0x8 + return len(dAtA) - i, nil +} +func (m *PartSetHeader_Hash) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PartSetHeader_Hash) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Hash != nil { i -= len(m.Hash) copy(dAtA[i:], m.Hash) i = encodeVarintTypes(dAtA, i, uint64(len(m.Hash))) i-- dAtA[i] = 0x12 } - if m.Total != 0 { - i = encodeVarintTypes(dAtA, i, uint64(m.Total)) - i-- - dAtA[i] = 0x8 - } return len(dAtA) - i, nil } - func (m *Part) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1655,17 +1966,35 @@ func (m *BlockID) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - { - size, err := m.PartSetHeader.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if m.XPartSetHeader != nil { + { + size := m.XPartSetHeader.Size() + i -= size + if _, err := m.XPartSetHeader.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } } - i -= size - i = encodeVarintTypes(dAtA, i, uint64(size)) } - i-- - dAtA[i] = 0x12 - if len(m.Hash) > 0 { + if m.XHash != nil { + { + size := m.XHash.Size() + i -= size + if _, err := m.XHash.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + return len(dAtA) - i, nil +} + +func (m *BlockID_Hash) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *BlockID_Hash) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Hash != nil { i -= len(m.Hash) copy(dAtA[i:], m.Hash) i = encodeVarintTypes(dAtA, i, uint64(len(m.Hash))) @@ -1674,7 +2003,27 @@ func (m *BlockID) MarshalToSizedBuffer(dAtA []byte) (int, error) { } return len(dAtA) - i, nil } +func (m *BlockID_PartSetHeader) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} +func (m *BlockID_PartSetHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.PartSetHeader != nil { + { + size, err := m.PartSetHeader.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + return len(dAtA) - i, nil +} func (m *Header) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1883,75 +2232,223 @@ func (m *Vote) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.ExtensionSignature) > 0 { - i -= len(m.ExtensionSignature) - copy(dAtA[i:], m.ExtensionSignature) - i = encodeVarintTypes(dAtA, i, uint64(len(m.ExtensionSignature))) - i-- - dAtA[i] = 0x52 + if m.XExtensionSignature != nil { + { + size := m.XExtensionSignature.Size() + i -= size + if _, err := m.XExtensionSignature.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } } - if len(m.Extension) > 0 { - i -= len(m.Extension) - copy(dAtA[i:], m.Extension) - i = encodeVarintTypes(dAtA, i, uint64(len(m.Extension))) - i-- - dAtA[i] = 0x4a + if m.XExtension != nil { + { + size := m.XExtension.Size() + i -= size + if _, err := m.XExtension.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } } - if len(m.Signature) > 0 { - i -= len(m.Signature) - copy(dAtA[i:], m.Signature) - i = encodeVarintTypes(dAtA, i, uint64(len(m.Signature))) - i-- - dAtA[i] = 0x42 + if m.XSignature != nil { + { + size := m.XSignature.Size() + i -= size + if _, err := m.XSignature.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + if m.XValidatorIndex != nil { + { + size := m.XValidatorIndex.Size() + i -= size + if _, err := m.XValidatorIndex.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + if m.XValidatorAddress != nil { + { + size := m.XValidatorAddress.Size() + i -= size + if _, err := m.XValidatorAddress.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + if m.XBlockId != nil { + { + size := m.XBlockId.Size() + i -= size + if _, err := m.XBlockId.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + if m.XRound != nil { + { + size := m.XRound.Size() + i -= size + if _, err := m.XRound.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + if m.XHeight != nil { + { + size := m.XHeight.Size() + i -= size + if _, err := m.XHeight.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } } - if m.ValidatorIndex != 0 { - i = encodeVarintTypes(dAtA, i, uint64(m.ValidatorIndex)) + if m.XType != nil { + { + size := m.XType.Size() + i -= size + if _, err := m.XType.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + return len(dAtA) - i, nil +} + +func (m *Vote_Type) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Vote_Type) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + i = encodeVarintTypes(dAtA, i, uint64(m.Type)) + i-- + dAtA[i] = 0x8 + return len(dAtA) - i, nil +} +func (m *Vote_Height) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Vote_Height) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + i = encodeVarintTypes(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x10 + return len(dAtA) - i, nil +} +func (m *Vote_Round) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Vote_Round) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + i = encodeVarintTypes(dAtA, i, uint64(m.Round)) + i-- + dAtA[i] = 0x18 + return len(dAtA) - i, nil +} +func (m *Vote_BlockId) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Vote_BlockId) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.BlockId != nil { + { + size, err := m.BlockId.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } i-- - dAtA[i] = 0x38 + dAtA[i] = 0x22 } - if len(m.ValidatorAddress) > 0 { + return len(dAtA) - i, nil +} +func (m *Vote_ValidatorAddress) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Vote_ValidatorAddress) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.ValidatorAddress != nil { i -= len(m.ValidatorAddress) copy(dAtA[i:], m.ValidatorAddress) i = encodeVarintTypes(dAtA, i, uint64(len(m.ValidatorAddress))) i-- dAtA[i] = 0x32 } - n6, err6 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) - if err6 != nil { - return 0, err6 - } - i -= n6 - i = encodeVarintTypes(dAtA, i, uint64(n6)) - i-- - dAtA[i] = 0x2a - { - size, err := m.BlockID.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTypes(dAtA, i, uint64(size)) - } + return len(dAtA) - i, nil +} +func (m *Vote_ValidatorIndex) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Vote_ValidatorIndex) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + i = encodeVarintTypes(dAtA, i, uint64(m.ValidatorIndex)) i-- - dAtA[i] = 0x22 - if m.Round != 0 { - i = encodeVarintTypes(dAtA, i, uint64(m.Round)) + dAtA[i] = 0x38 + return len(dAtA) - i, nil +} +func (m *Vote_Signature) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Vote_Signature) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Signature != nil { + i -= len(m.Signature) + copy(dAtA[i:], m.Signature) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Signature))) i-- - dAtA[i] = 0x18 + dAtA[i] = 0x42 } - if m.Height != 0 { - i = encodeVarintTypes(dAtA, i, uint64(m.Height)) + return len(dAtA) - i, nil +} +func (m *Vote_Extension) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Vote_Extension) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Extension != nil { + i -= len(m.Extension) + copy(dAtA[i:], m.Extension) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Extension))) i-- - dAtA[i] = 0x10 + dAtA[i] = 0x4a } - if m.Type != 0 { - i = encodeVarintTypes(dAtA, i, uint64(m.Type)) + return len(dAtA) - i, nil +} +func (m *Vote_ExtensionSignature) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Vote_ExtensionSignature) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.ExtensionSignature != nil { + i -= len(m.ExtensionSignature) + copy(dAtA[i:], m.ExtensionSignature) + i = encodeVarintTypes(dAtA, i, uint64(len(m.ExtensionSignature))) i-- - dAtA[i] = 0x8 + dAtA[i] = 0x52 } return len(dAtA) - i, nil } - func (m *Commit) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2036,12 +2533,12 @@ func (m *CommitSig) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x22 } - n9, err9 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) - if err9 != nil { - return 0, err9 + n8, err8 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) + if err8 != nil { + return 0, err8 } - i -= n9 - i = encodeVarintTypes(dAtA, i, uint64(n9)) + i -= n8 + i = encodeVarintTypes(dAtA, i, uint64(n8)) i-- dAtA[i] = 0x1a if len(m.ValidatorAddress) > 0 { @@ -2141,12 +2638,12 @@ func (m *Proposal) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x3a } - n13, err13 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) - if err13 != nil { - return 0, err13 + n12, err12 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) + if err12 != nil { + return 0, err12 } - i -= n13 - i = encodeVarintTypes(dAtA, i, uint64(n13)) + i -= n12 + i = encodeVarintTypes(dAtA, i, uint64(n12)) i-- dAtA[i] = 0x32 { @@ -2472,12 +2969,12 @@ func (m *DuplicateVoteEvidence) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - n24, err24 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) - if err24 != nil { - return 0, err24 + n23, err23 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) + if err23 != nil { + return 0, err23 } - i -= n24 - i = encodeVarintTypes(dAtA, i, uint64(n24)) + i -= n23 + i = encodeVarintTypes(dAtA, i, uint64(n23)) i-- dAtA[i] = 0x2a if m.ValidatorPower != 0 { @@ -2537,12 +3034,12 @@ func (m *LightClientAttackEvidence) MarshalToSizedBuffer(dAtA []byte) (int, erro _ = i var l int _ = l - n27, err27 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) - if err27 != nil { - return 0, err27 + n26, err26 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) + if err26 != nil { + return 0, err26 } - i -= n27 - i = encodeVarintTypes(dAtA, i, uint64(n27)) + i -= n26 + i = encodeVarintTypes(dAtA, i, uint64(n26)) i-- dAtA[i] = 0x2a if m.TotalVotingPower != 0 { @@ -2638,16 +3135,36 @@ func (m *PartSetHeader) Size() (n int) { } var l int _ = l - if m.Total != 0 { - n += 1 + sovTypes(uint64(m.Total)) + if m.XTotal != nil { + n += m.XTotal.Size() } - l = len(m.Hash) - if l > 0 { - n += 1 + l + sovTypes(uint64(l)) + if m.XHash != nil { + n += m.XHash.Size() } return n } +func (m *PartSetHeader_Total) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += 1 + sovTypes(uint64(m.Total)) + return n +} +func (m *PartSetHeader_Hash) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Hash != nil { + l = len(m.Hash) + n += 1 + l + sovTypes(uint64(l)) + } + return n +} func (m *Part) Size() (n int) { if m == nil { return 0 @@ -2672,15 +3189,39 @@ func (m *BlockID) Size() (n int) { } var l int _ = l - l = len(m.Hash) - if l > 0 { - n += 1 + l + sovTypes(uint64(l)) + if m.XHash != nil { + n += m.XHash.Size() + } + if m.XPartSetHeader != nil { + n += m.XPartSetHeader.Size() } - l = m.PartSetHeader.Size() - n += 1 + l + sovTypes(uint64(l)) return n } +func (m *BlockID_Hash) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Hash != nil { + l = len(m.Hash) + n += 1 + l + sovTypes(uint64(l)) + } + return n +} +func (m *BlockID_PartSetHeader) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.PartSetHeader != nil { + l = m.PartSetHeader.Size() + n += 1 + l + sovTypes(uint64(l)) + } + return n +} func (m *Header) Size() (n int) { if m == nil { return 0 @@ -2773,41 +3314,132 @@ func (m *Vote) Size() (n int) { } var l int _ = l - if m.Type != 0 { - n += 1 + sovTypes(uint64(m.Type)) + if m.XType != nil { + n += m.XType.Size() } - if m.Height != 0 { - n += 1 + sovTypes(uint64(m.Height)) + if m.XHeight != nil { + n += m.XHeight.Size() } - if m.Round != 0 { - n += 1 + sovTypes(uint64(m.Round)) + if m.XRound != nil { + n += m.XRound.Size() } - l = m.BlockID.Size() - n += 1 + l + sovTypes(uint64(l)) - l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp) - n += 1 + l + sovTypes(uint64(l)) - l = len(m.ValidatorAddress) - if l > 0 { + if m.XBlockId != nil { + n += m.XBlockId.Size() + } + if m.XValidatorAddress != nil { + n += m.XValidatorAddress.Size() + } + if m.XValidatorIndex != nil { + n += m.XValidatorIndex.Size() + } + if m.XSignature != nil { + n += m.XSignature.Size() + } + if m.XExtension != nil { + n += m.XExtension.Size() + } + if m.XExtensionSignature != nil { + n += m.XExtensionSignature.Size() + } + return n +} + +func (m *Vote_Type) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += 1 + sovTypes(uint64(m.Type)) + return n +} +func (m *Vote_Height) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += 1 + sovTypes(uint64(m.Height)) + return n +} +func (m *Vote_Round) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += 1 + sovTypes(uint64(m.Round)) + return n +} +func (m *Vote_BlockId) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BlockId != nil { + l = m.BlockId.Size() n += 1 + l + sovTypes(uint64(l)) } - if m.ValidatorIndex != 0 { - n += 1 + sovTypes(uint64(m.ValidatorIndex)) + return n +} +func (m *Vote_ValidatorAddress) Size() (n int) { + if m == nil { + return 0 } - l = len(m.Signature) - if l > 0 { + var l int + _ = l + if m.ValidatorAddress != nil { + l = len(m.ValidatorAddress) n += 1 + l + sovTypes(uint64(l)) } - l = len(m.Extension) - if l > 0 { + return n +} +func (m *Vote_ValidatorIndex) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += 1 + sovTypes(uint64(m.ValidatorIndex)) + return n +} +func (m *Vote_Signature) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Signature != nil { + l = len(m.Signature) n += 1 + l + sovTypes(uint64(l)) } - l = len(m.ExtensionSignature) - if l > 0 { + return n +} +func (m *Vote_Extension) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Extension != nil { + l = len(m.Extension) + n += 1 + l + sovTypes(uint64(l)) + } + return n +} +func (m *Vote_ExtensionSignature) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ExtensionSignature != nil { + l = len(m.ExtensionSignature) n += 1 + l + sovTypes(uint64(l)) } return n } - func (m *Commit) Size() (n int) { if m == nil { return 0 @@ -3118,7 +3750,7 @@ func (m *PartSetHeader) Unmarshal(dAtA []byte) error { if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Total", wireType) } - m.Total = 0 + var v uint32 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -3128,11 +3760,12 @@ func (m *PartSetHeader) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Total |= uint32(b&0x7F) << shift + v |= uint32(b&0x7F) << shift if b < 0x80 { break } } + m.XTotal = &PartSetHeader_Total{v} case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) @@ -3162,10 +3795,9 @@ func (m *PartSetHeader) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Hash = append(m.Hash[:0], dAtA[iNdEx:postIndex]...) - if m.Hash == nil { - m.Hash = []byte{} - } + v := make([]byte, postIndex-iNdEx) + copy(v, dAtA[iNdEx:postIndex]) + m.XHash = &PartSetHeader_Hash{v} iNdEx = postIndex default: iNdEx = preIndex @@ -3382,10 +4014,9 @@ func (m *BlockID) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Hash = append(m.Hash[:0], dAtA[iNdEx:postIndex]...) - if m.Hash == nil { - m.Hash = []byte{} - } + v := make([]byte, postIndex-iNdEx) + copy(v, dAtA[iNdEx:postIndex]) + m.XHash = &BlockID_Hash{v} iNdEx = postIndex case 2: if wireType != 2 { @@ -3416,9 +4047,11 @@ func (m *BlockID) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.PartSetHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + v := &PartSetHeader{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } + m.XPartSetHeader = &BlockID_PartSetHeader{v} iNdEx = postIndex default: iNdEx = preIndex @@ -4146,7 +4779,7 @@ func (m *Vote) Unmarshal(dAtA []byte) error { if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) } - m.Type = 0 + var v SignedMsgType for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -4156,16 +4789,17 @@ func (m *Vote) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Type |= SignedMsgType(b&0x7F) << shift + v |= SignedMsgType(b&0x7F) << shift if b < 0x80 { break } } + m.XType = &Vote_Type{v} case 2: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) } - m.Height = 0 + var v int64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -4175,16 +4809,17 @@ func (m *Vote) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Height |= int64(b&0x7F) << shift + v |= int64(b&0x7F) << shift if b < 0x80 { break } } + m.XHeight = &Vote_Height{v} case 3: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Round", wireType) } - m.Round = 0 + var v int32 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -4194,47 +4829,15 @@ func (m *Vote) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Round |= int32(b&0x7F) << shift + v |= int32(b&0x7F) << shift if b < 0x80 { break } } + m.XRound = &Vote_Round{v} case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BlockID", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTypes - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTypes - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTypes - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.BlockID.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BlockId", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4261,9 +4864,11 @@ func (m *Vote) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Timestamp, dAtA[iNdEx:postIndex]); err != nil { + v := &BlockID{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } + m.XBlockId = &Vote_BlockId{v} iNdEx = postIndex case 6: if wireType != 2 { @@ -4294,16 +4899,15 @@ func (m *Vote) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ValidatorAddress = append(m.ValidatorAddress[:0], dAtA[iNdEx:postIndex]...) - if m.ValidatorAddress == nil { - m.ValidatorAddress = []byte{} - } + v := make([]byte, postIndex-iNdEx) + copy(v, dAtA[iNdEx:postIndex]) + m.XValidatorAddress = &Vote_ValidatorAddress{v} iNdEx = postIndex case 7: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field ValidatorIndex", wireType) } - m.ValidatorIndex = 0 + var v int32 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -4313,11 +4917,12 @@ func (m *Vote) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ValidatorIndex |= int32(b&0x7F) << shift + v |= int32(b&0x7F) << shift if b < 0x80 { break } } + m.XValidatorIndex = &Vote_ValidatorIndex{v} case 8: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType) @@ -4347,10 +4952,9 @@ func (m *Vote) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...) - if m.Signature == nil { - m.Signature = []byte{} - } + v := make([]byte, postIndex-iNdEx) + copy(v, dAtA[iNdEx:postIndex]) + m.XSignature = &Vote_Signature{v} iNdEx = postIndex case 9: if wireType != 2 { @@ -4381,10 +4985,9 @@ func (m *Vote) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Extension = append(m.Extension[:0], dAtA[iNdEx:postIndex]...) - if m.Extension == nil { - m.Extension = []byte{} - } + v := make([]byte, postIndex-iNdEx) + copy(v, dAtA[iNdEx:postIndex]) + m.XExtension = &Vote_Extension{v} iNdEx = postIndex case 10: if wireType != 2 { @@ -4415,10 +5018,9 @@ func (m *Vote) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ExtensionSignature = append(m.ExtensionSignature[:0], dAtA[iNdEx:postIndex]...) - if m.ExtensionSignature == nil { - m.ExtensionSignature = []byte{} - } + v := make([]byte, postIndex-iNdEx) + copy(v, dAtA[iNdEx:postIndex]) + m.XExtensionSignature = &Vote_ExtensionSignature{v} iNdEx = postIndex default: iNdEx = preIndex diff --git a/sei-tendermint/proto/tendermint/types/types.proto b/sei-tendermint/proto/tendermint/types/types.proto index 33d4c6007f..d35db41203 100644 --- a/sei-tendermint/proto/tendermint/types/types.proto +++ b/sei-tendermint/proto/tendermint/types/types.proto @@ -7,6 +7,7 @@ import "google/protobuf/timestamp.proto"; import "tendermint/crypto/proof.proto"; import "tendermint/types/validator.proto"; import "tendermint/version/types.proto"; +import "hashable.proto"; option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; @@ -37,8 +38,9 @@ enum SignedMsgType { // PartsetHeader message PartSetHeader { - uint32 total = 1; - bytes hash = 2; + option (hashable.hashable) = true; + optional uint32 total = 1; + optional bytes hash = 2; } message Part { @@ -49,8 +51,9 @@ message Part { // BlockID message BlockID { - bytes hash = 1; - PartSetHeader part_set_header = 2 [(gogoproto.nullable) = false]; + option (hashable.hashable) = true; + optional bytes hash = 1; + optional PartSetHeader part_set_header = 2; } // -------------------------------- @@ -100,25 +103,19 @@ message TxKey { // Vote represents a prevote, precommit, or commit vote from validators for // consensus. message Vote { - SignedMsgType type = 1; - int64 height = 2; - int32 round = 3; - BlockID block_id = 4 [ - (gogoproto.nullable) = false, - (gogoproto.customname) = "BlockID" - ]; // zero if vote is nil. - google.protobuf.Timestamp timestamp = 5 [ - (gogoproto.nullable) = false, - (gogoproto.stdtime) = true - ]; - bytes validator_address = 6; - int32 validator_index = 7; + option (hashable.hashable) = true; + optional SignedMsgType type = 1; + optional int64 height = 2; + optional int32 round = 3; + optional BlockID block_id = 4; + optional bytes validator_address = 6; + optional int32 validator_index = 7; // Vote signature by the validator if they participated in consensus for the // associated block. - bytes signature = 8; + optional bytes signature = 8; - bytes extension = 9 [deprecated = true]; - bytes extension_signature = 10 [deprecated = true]; + optional bytes extension = 9 [deprecated = true]; + optional bytes extension_signature = 10 [deprecated = true]; } // Commit contains the evidence that a block was committed by a set of diff --git a/sei-tendermint/proto/tendermint/utils.proto b/sei-tendermint/proto/tendermint/utils.proto deleted file mode 100644 index 3798f035d3..0000000000 --- a/sei-tendermint/proto/tendermint/utils.proto +++ /dev/null @@ -1,13 +0,0 @@ -syntax = "proto3"; - -package tendermint.utils; - -import "google/protobuf/descriptor.proto"; - -option go_package = "github.com/tendermint/tendermint/proto/tendermint/utils"; - -// can_hash marks messages which support canonical protobuf serialization and therefore -// are suitable for hashing. -extend google.protobuf.MessageOptions { - bool can_hash = 51001; -} From e74e72898e031c1695c70840dc1cd95da68e621a Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Fri, 12 Dec 2025 12:27:49 +0100 Subject: [PATCH 05/53] separate module --- buf.gen.yaml | 8 -------- buf.gen_v2.yaml | 13 +++++++++++++ buf.yaml | 1 + scripts/protoc.sh | 3 ++- sei-tendermint/cmd/buf_plugin/main.go | 3 +++ .../hashable}/hashable.proto | 2 +- sei-tendermint/proto_v2/test/test.proto | 18 ++++++++++++++++++ 7 files changed, 38 insertions(+), 10 deletions(-) create mode 100644 buf.gen_v2.yaml rename sei-tendermint/{proto => proto_v2/hashable}/hashable.proto (83%) create mode 100644 sei-tendermint/proto_v2/test/test.proto diff --git a/buf.gen.yaml b/buf.gen.yaml index ae63227624..dfe4a5e848 100644 --- a/buf.gen.yaml +++ b/buf.gen.yaml @@ -6,14 +6,6 @@ inputs: - directory: sei-tendermint/proto - directory: sei-wasmd/proto plugins: - - local: - - go - - run - - ./sei-tendermint/cmd/buf_plugin - strategy: all - opt: - - Mgoogle/protobuf/any.proto=github.com/cosmos/cosmos-sdk/codec/types - out: ./build/proto/validation - local: - ./build/proto/gocosmos/protoc-gen-gocosmos opt: diff --git a/buf.gen_v2.yaml b/buf.gen_v2.yaml new file mode 100644 index 0000000000..1f2d49c156 --- /dev/null +++ b/buf.gen_v2.yaml @@ -0,0 +1,13 @@ +version: v2 +inputs: + - directory: sei-tendermint/proto_v2 +plugins: + - local: + - go + - run + - ./sei-tendermint/cmd/buf_plugin + strategy: all + out: ./sei-tendermint/proto_v2 + - remote: buf.build/protocolbuffers/go:v1.36.10 + out: ./sei-tendermint/proto_v2 + opt: [paths=source_relative] diff --git a/buf.yaml b/buf.yaml index c15a632022..b35af2f509 100644 --- a/buf.yaml +++ b/buf.yaml @@ -8,6 +8,7 @@ modules: - path: sei-ibc-go/proto - path: sei-ibc-go/third_party/proto - path: sei-tendermint/proto + - path: sei-tendermint/proto_v2 - path: sei-wasmd/proto lint: diff --git a/scripts/protoc.sh b/scripts/protoc.sh index 9a6636e9f9..d2710006f8 100755 --- a/scripts/protoc.sh +++ b/scripts/protoc.sh @@ -24,6 +24,7 @@ pushd "$(go env GOMODCACHE)/github.com/regen-network/cosmos-proto@v0.3.1" && popd go run github.com/bufbuild/buf/cmd/buf@v1.58.0 generate +go run github.com/bufbuild/buf/cmd/buf@v1.58.0 generate --template buf.gen_v2.yaml # We can't manipulate the outputs enough to eliminate the extra move-abouts. # So we just copy the files we want to the right places manually. @@ -37,4 +38,4 @@ cp -rf ./build/proto/gogofaster/github.com/tendermint/tendermint/* ./sei-tenderm rm -rf ./build/proto -echo "Protobuf code generation complete." \ No newline at end of file +echo "Protobuf code generation complete." diff --git a/sei-tendermint/cmd/buf_plugin/main.go b/sei-tendermint/cmd/buf_plugin/main.go index e1ec2a8086..3fa6bc9413 100644 --- a/sei-tendermint/cmd/buf_plugin/main.go +++ b/sei-tendermint/cmd/buf_plugin/main.go @@ -101,6 +101,9 @@ func run(p *protogen.Plugin) error { if !f.IsList() && !f.HasPresence() { return fmt.Errorf("%q: all fields of hashable messages should be optional or repeated", f.FullName()) } + if f.Kind() == protoreflect.FloatKind { + return fmt.Errorf("%q: float fields are not hashable",f.FullName()) + } if f.Kind() == protoreflect.MessageKind { if _, ok := descs[f.Message().FullName()]; !ok { return fmt.Errorf("%q: message fields of hashable messages have to be hashable", f.FullName()) diff --git a/sei-tendermint/proto/hashable.proto b/sei-tendermint/proto_v2/hashable/hashable.proto similarity index 83% rename from sei-tendermint/proto/hashable.proto rename to sei-tendermint/proto_v2/hashable/hashable.proto index 4b00cff79b..e9440c483a 100644 --- a/sei-tendermint/proto/hashable.proto +++ b/sei-tendermint/proto_v2/hashable/hashable.proto @@ -4,7 +4,7 @@ package hashable; import "google/protobuf/descriptor.proto"; -option go_package = "github.com/tendermint/tendermint/proto/hashable"; +option go_package = "github.com/tendermint/tendermint/proto_v2/hashable"; // hashable marks messages which support canonical protobuf serialization and therefore // are suitable for hashing. diff --git a/sei-tendermint/proto_v2/test/test.proto b/sei-tendermint/proto_v2/test/test.proto new file mode 100644 index 0000000000..02e78ec444 --- /dev/null +++ b/sei-tendermint/proto_v2/test/test.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +package test; + +import "hashable/hashable.proto"; + +option go_package = "github.com/tendermint/tendermint/proto_v2/test"; + +message A { + option (hashable.hashable) = true; + +} + +message B { + option (hashable.hashable) = true; + repeated int32 dupa = 1; + optional A ww = 2; +} From 3f5798b2babfad9d638421e899e0a35c013341c8 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Fri, 12 Dec 2025 14:32:51 +0100 Subject: [PATCH 06/53] added canonical encoding --- sei-tendermint/cmd/buf_plugin/main.go | 13 +- sei-tendermint/libs/utils/proto/canonical.go | 145 +++++++++++++++++++ 2 files changed, 154 insertions(+), 4 deletions(-) create mode 100644 sei-tendermint/libs/utils/proto/canonical.go diff --git a/sei-tendermint/cmd/buf_plugin/main.go b/sei-tendermint/cmd/buf_plugin/main.go index 3fa6bc9413..43509449cd 100644 --- a/sei-tendermint/cmd/buf_plugin/main.go +++ b/sei-tendermint/cmd/buf_plugin/main.go @@ -95,16 +95,21 @@ func run(p *protogen.Plugin) error { fields := d.Fields() for i := 0; i < fields.Len(); i++ { f := fields.Get(i) + if f.IsExtension() { + return fmt.Errorf("%q: extension fields are not hashable", f.FullName()) + } if f.IsMap() { - return fmt.Errorf("%q: maps are not allowed in hashable messages", f.FullName()) + return fmt.Errorf("%q: maps are not hashable", f.FullName()) } if !f.IsList() && !f.HasPresence() { return fmt.Errorf("%q: all fields of hashable messages should be optional or repeated", f.FullName()) } - if f.Kind() == protoreflect.FloatKind { + switch f.Kind() { + case protoreflect.FloatKind, protoreflect.DoubleKind: return fmt.Errorf("%q: float fields are not hashable",f.FullName()) - } - if f.Kind() == protoreflect.MessageKind { + case protoreflect.GroupKind: + return fmt.Errorf("%q: group field are not hashable",f.FullName()) + case protoreflect.MessageKind: if _, ok := descs[f.Message().FullName()]; !ok { return fmt.Errorf("%q: message fields of hashable messages have to be hashable", f.FullName()) } diff --git a/sei-tendermint/libs/utils/proto/canonical.go b/sei-tendermint/libs/utils/proto/canonical.go new file mode 100644 index 0000000000..edb94154cc --- /dev/null +++ b/sei-tendermint/libs/utils/proto/canonical.go @@ -0,0 +1,145 @@ +package proto + +import ( + "fmt" + "slices" + "cmp" + + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/encoding/protowire" + "google.golang.org/protobuf/reflect/protoreflect" +) + +type Hashable interface { + proto.Message + IsHashable() +} + +// MarshalCanonical returns the canonical protobuf encoding of msg according to +// the custom Tendermint hashing/signing rules described in canonical.go. +// The output is deterministic and suitable for hashing and signing. +func MarshalCanonical[T Hashable](msg T) []byte { + return builder{}.Message(msg.ProtoReflect()) +} + +type builder []byte + +func (b builder) Tag(num protowire.Number, typ protowire.Type) builder { return protowire.AppendTag(b,num,typ) } +func (b builder) Varint(v uint64) builder { return protowire.AppendVarint(b, v) } +func (b builder) Fixed32(v uint32) builder { return protowire.AppendFixed32(b, v) } +func (b builder) Fixed64(v uint64) builder { return protowire.AppendFixed64(b, v) } +func (b builder) Bytes(bytes []byte) builder { return protowire.AppendBytes(b,bytes) } +func (b builder) String(s string) builder { return protowire.AppendString(b,s) } + +func (b builder) Message(msg protoreflect.Message) builder { + // NOTE: we ignore unknown fields - we are unable to encode them canonically. + // NOTE: we can sort fields on init if needed (in the generated files). + for _, fd := range sortedFields(msg.Descriptor().Fields()) { + if fd.IsList() { + b = b.List(fd.Number(), fd.Kind(), msg.Get(fd).List()) + } else if msg.Has(fd) { + b = b.Singular(fd.Number(), fd.Kind(), msg.Get(fd)) + } + } + return b +} + +func (b builder) List(num protoreflect.FieldNumber, kind protoreflect.Kind, list protoreflect.List) builder { + size := list.Len() + if size == 0 { + return b + } + // We pack only lists longer than 1 for backward compatibility of optional -> repeated changes. + if isPackable(kind) && size > 1 { + var packed builder + for i := range list.Len() { + packed = packed.Value(kind, list.Get(i)) + } + return b.Tag(num, protowire.BytesType).Bytes(packed) + } + + for i := range size { + b = b.Singular(num, kind, list.Get(i)) + } + return b +} + +func (b builder) Singular(num protoreflect.FieldNumber, kind protoreflect.Kind, value protoreflect.Value) builder { + switch kind { + case protoreflect.BoolKind, + protoreflect.EnumKind, + protoreflect.Int32Kind, + protoreflect.Int64Kind, + protoreflect.Sint32Kind, + protoreflect.Sint64Kind, + protoreflect.Uint32Kind, + protoreflect.Uint64Kind: + b = b.Tag(num, protowire.VarintType) + case protoreflect.Fixed32Kind, protoreflect.Sfixed32Kind: + b = b.Tag(num, protowire.Fixed32Type) + case protoreflect.Fixed64Kind, protoreflect.Sfixed64Kind: + b = b.Tag(num, protowire.Fixed64Type) + case protoreflect.BytesKind, protoreflect.StringKind, protoreflect.MessageKind: + b = b.Tag(num, protowire.BytesType) + default: + panic(fmt.Errorf("unsupported field kind %s", kind)) + } + return b.Value(kind, value) +} + +func (b builder) Value(kind protoreflect.Kind, value protoreflect.Value) builder { + switch kind { + case protoreflect.BoolKind: + var v uint64 + if value.Bool() { + v = 1 + } + return b.Varint(v) + case protoreflect.EnumKind: return b.Varint(uint64(value.Enum())) + case protoreflect.Int32Kind: return b.Varint(uint64(uint32(value.Int()))) + case protoreflect.Int64Kind: return b.Varint(uint64(value.Int())) + case protoreflect.Sint32Kind: return b.Varint(protowire.EncodeZigZag(int64(int32(value.Int())))) + case protoreflect.Sint64Kind: return b.Varint(protowire.EncodeZigZag(value.Int())) + case protoreflect.Uint32Kind: return b.Varint(uint64(uint32(value.Uint()))) + case protoreflect.Uint64Kind: return b.Varint(value.Uint()) + case protoreflect.Fixed32Kind: return b.Fixed32(uint32(value.Uint())) + case protoreflect.Fixed64Kind: return b.Fixed64(value.Uint()) + case protoreflect.Sfixed32Kind: return b.Fixed32(uint32(int32(value.Int()))) + case protoreflect.Sfixed64Kind: return b.Fixed64(uint64(value.Int())) + case protoreflect.BytesKind: return b.Bytes(value.Bytes()) + case protoreflect.StringKind: return b.String(value.String()) + case protoreflect.MessageKind: return b.Message(value.Message()) + default: panic(fmt.Errorf("kind %s is not packable", kind)) + } +} + +func isPackable(kind protoreflect.Kind) bool { + switch kind { + case protoreflect.BoolKind, + protoreflect.EnumKind, + protoreflect.Int32Kind, + protoreflect.Int64Kind, + protoreflect.Sint32Kind, + protoreflect.Sint64Kind, + protoreflect.Uint32Kind, + protoreflect.Uint64Kind, + protoreflect.Fixed32Kind, + protoreflect.Fixed64Kind, + protoreflect.Sfixed32Kind, + protoreflect.Sfixed64Kind: + return true + default: + return false + } +} + +func sortedFields(fields protoreflect.FieldDescriptors) []protoreflect.FieldDescriptor { + result := make([]protoreflect.FieldDescriptor, fields.Len()) + for i := 0; i < fields.Len(); i++ { + result[i] = fields.Get(i) + } + slices.SortFunc(result,func(a,b protoreflect.FieldDescriptor) int { + return cmp.Compare(a.Number(),b.Number()) + }) + return result +} From f8753b7d089c9226c8243b303b8d794c7d18e866 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Fri, 12 Dec 2025 15:33:04 +0100 Subject: [PATCH 07/53] IsHashable --- buf.gen_v2.yaml | 6 +- sei-cosmos/x/staking/types/staking.pb.go | 1546 ++++++++--------- sei-tendermint/cmd/buf_plugin/main.go | 77 +- .../proto/tendermint/consensus/types.pb.go | 112 +- .../proto/tendermint/consensus/types.proto | 2 - .../proto/tendermint/types/types.pb.go | 1360 ++++----------- .../proto/tendermint/types/types.proto | 37 +- 7 files changed, 1288 insertions(+), 1852 deletions(-) diff --git a/buf.gen_v2.yaml b/buf.gen_v2.yaml index 1f2d49c156..7d22d5772f 100644 --- a/buf.gen_v2.yaml +++ b/buf.gen_v2.yaml @@ -2,12 +2,12 @@ version: v2 inputs: - directory: sei-tendermint/proto_v2 plugins: + - remote: buf.build/protocolbuffers/go:v1.36.10 + out: ./sei-tendermint/proto_v2 + opt: [paths=source_relative] - local: - go - run - ./sei-tendermint/cmd/buf_plugin strategy: all out: ./sei-tendermint/proto_v2 - - remote: buf.build/protocolbuffers/go:v1.36.10 - out: ./sei-tendermint/proto_v2 - opt: [paths=source_relative] diff --git a/sei-cosmos/x/staking/types/staking.pb.go b/sei-cosmos/x/staking/types/staking.pb.go index fcda29b9d3..49103fb7e4 100644 --- a/sei-cosmos/x/staking/types/staking.pb.go +++ b/sei-cosmos/x/staking/types/staking.pb.go @@ -1273,790 +1273,776 @@ func (this *Pool) Description() (desc *github_com_gogo_protobuf_protoc_gen_gogo_ func StakingDescription() (desc *github_com_gogo_protobuf_protoc_gen_gogo_descriptor.FileDescriptorSet) { d := &github_com_gogo_protobuf_protoc_gen_gogo_descriptor.FileDescriptorSet{} var gzipped = []byte{ - // 12514 bytes of a gzipped FileDescriptorSet - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x6b, 0x94, 0x5b, 0xd7, - 0x75, 0x18, 0x3c, 0x17, 0x6f, 0xec, 0x79, 0xdd, 0x39, 0x33, 0x24, 0x41, 0xf0, 0x31, 0xd4, 0x95, - 0x44, 0x51, 0x94, 0x38, 0x14, 0x29, 0x91, 0x22, 0x47, 0x8e, 0x15, 0x60, 0x00, 0xce, 0x80, 0x9a, - 0x97, 0x2e, 0x30, 0x94, 0xe4, 0x38, 0xb9, 0xeb, 0x0e, 0x70, 0x06, 0x73, 0x45, 0xe0, 0x5e, 0x18, - 0xf7, 0x82, 0xe2, 0xc8, 0x49, 0x96, 0xec, 0xf8, 0xf3, 0x27, 0xcb, 0x9f, 0xbf, 0xd8, 0x9f, 0xf3, - 0x25, 0xb2, 0x13, 0x3a, 0xb2, 0x9d, 0xc6, 0xa9, 0xed, 0x34, 0x4e, 0xe2, 0xa6, 0x4d, 0x9b, 0xb5, - 0x92, 0x74, 0x2d, 0x37, 0x8e, 0x9b, 0x74, 0xc9, 0x69, 0xda, 0xa6, 0x59, 0x29, 0xdd, 0x2a, 0x5e, - 0xb1, 0xec, 0xb8, 0x8d, 0xa3, 0xb8, 0x6d, 0xba, 0xdc, 0xd4, 0x5d, 0xe7, 0x75, 0x5f, 0x00, 0x06, - 0x18, 0x8a, 0x4a, 0x94, 0xa6, 0x7f, 0xc8, 0x39, 0xfb, 0xec, 0xbd, 0xcf, 0x3e, 0xfb, 0xec, 0xbd, - 0xcf, 0x3e, 0xaf, 0x0b, 0xf8, 0x2b, 0x03, 0x8e, 0xd5, 0x2d, 0xab, 0xde, 0xc0, 0xa7, 0x5b, 0x6d, - 0xcb, 0xb1, 0x36, 0x3b, 0x5b, 0xa7, 0x6b, 0xd8, 0xae, 0xb6, 0x8d, 0x96, 0x63, 0xb5, 0xe7, 0x28, - 0x0c, 0x4d, 0x32, 0x8c, 0x39, 0x81, 0xa1, 0x7c, 0x49, 0x82, 0xa9, 0x4b, 0x46, 0x03, 0x17, 0x5c, - 0xcc, 0x32, 0x76, 0xd0, 0x05, 0x88, 0x6d, 0x19, 0x0d, 0x9c, 0x91, 0x8e, 0x45, 0x4f, 0x8c, 0x9e, - 0xbd, 0x6b, 0x2e, 0x44, 0x35, 0x17, 0xa4, 0x58, 0x27, 0x60, 0x95, 0x52, 0x9c, 0x7c, 0x67, 0xea, - 0xb9, 0x6f, 0x7e, 0xe9, 0xbb, 0x92, 0xfc, 0x2e, 0xf2, 0x6f, 0xb6, 0x89, 0xae, 0xb2, 0x32, 0x7a, - 0x68, 0x8e, 0xd0, 0xf9, 0xe4, 0xb9, 0x76, 0x86, 0x40, 0x34, 0x42, 0xa4, 0x79, 0x60, 0xcd, 0xc6, - 0x8e, 0x86, 0xaf, 0x3b, 0xd8, 0xb4, 0x0d, 0xcb, 0xcc, 0x9e, 0xea, 0x41, 0xd5, 0x25, 0x6d, 0x51, - 0xa0, 0x2b, 0x5f, 0x88, 0xc3, 0x74, 0x0f, 0xd1, 0x10, 0x82, 0x98, 0xa9, 0x37, 0x49, 0x77, 0xa4, - 0x13, 0x69, 0x95, 0xfe, 0x8d, 0x32, 0x90, 0x6c, 0xe9, 0xd5, 0xab, 0x7a, 0x1d, 0x67, 0x22, 0x14, - 0x2c, 0x8a, 0xe8, 0x28, 0x40, 0x0d, 0xb7, 0xb0, 0x59, 0xc3, 0x66, 0x75, 0x27, 0x13, 0x3d, 0x16, - 0x3d, 0x91, 0x56, 0x7d, 0x10, 0x74, 0x1f, 0x4c, 0xb5, 0x3a, 0x9b, 0x0d, 0xa3, 0xaa, 0xf9, 0xd0, - 0xe0, 0x58, 0xf4, 0x44, 0x5c, 0x95, 0x59, 0x45, 0xc1, 0x43, 0xbe, 0x07, 0x26, 0x9f, 0xc1, 0xfa, - 0x55, 0x3f, 0xea, 0x28, 0x45, 0x9d, 0x20, 0xe0, 0x42, 0x80, 0xab, 0xd5, 0x72, 0x0c, 0xcb, 0xf4, - 0xa3, 0x4e, 0xd2, 0xc6, 0x65, 0x56, 0xe1, 0x43, 0x5e, 0x80, 0xb1, 0x26, 0xb6, 0x6d, 0xbd, 0x8e, - 0x35, 0x67, 0xa7, 0x85, 0x33, 0x31, 0x3a, 0x4e, 0xc7, 0xba, 0xc6, 0x29, 0x3c, 0x46, 0xa3, 0x9c, - 0xaa, 0xb2, 0xd3, 0xc2, 0x28, 0x07, 0x69, 0x6c, 0x76, 0x9a, 0x8c, 0x43, 0xbc, 0xcf, 0x48, 0x17, - 0xcd, 0x4e, 0x33, 0xcc, 0x25, 0x45, 0xc8, 0x38, 0x8b, 0xa4, 0x8d, 0xdb, 0xd7, 0x8c, 0x2a, 0xce, - 0x24, 0x28, 0x83, 0x7b, 0xba, 0x18, 0x94, 0x59, 0x7d, 0x98, 0x87, 0xa0, 0x43, 0x0b, 0x90, 0x76, - 0xc7, 0x3b, 0x93, 0xa4, 0x4c, 0xee, 0xee, 0x61, 0x6f, 0xb8, 0x51, 0x0b, 0xb3, 0xf0, 0xe8, 0xd0, - 0x79, 0x48, 0x32, 0x1d, 0xd9, 0x99, 0xd4, 0x31, 0xe9, 0xc4, 0xe8, 0xd9, 0xc3, 0x3d, 0x4d, 0x76, - 0x8d, 0xe1, 0xa8, 0x02, 0x19, 0x95, 0x40, 0xb6, 0xad, 0x4e, 0xbb, 0x8a, 0xb5, 0xaa, 0x55, 0xc3, - 0x9a, 0x61, 0x6e, 0x59, 0x99, 0x34, 0x65, 0x30, 0xdb, 0xdd, 0x11, 0x8a, 0xb8, 0x60, 0xd5, 0x70, - 0xc9, 0xdc, 0xb2, 0xd4, 0x09, 0x3b, 0x50, 0x46, 0xfb, 0x21, 0x61, 0xef, 0x98, 0x8e, 0x7e, 0x3d, - 0x33, 0x46, 0xcd, 0x89, 0x97, 0xd0, 0x59, 0x48, 0xe2, 0x9a, 0x41, 0x9a, 0xcb, 0x4c, 0x1c, 0x93, - 0x4e, 0x4c, 0x9c, 0xcd, 0x74, 0xeb, 0x98, 0xd5, 0xab, 0x02, 0x51, 0xf9, 0x1f, 0x09, 0x98, 0x1c, - 0xc6, 0x86, 0x1f, 0x81, 0xf8, 0x16, 0xd1, 0x4c, 0x26, 0xb2, 0x17, 0xbd, 0x31, 0x9a, 0xa0, 0xe2, - 0x13, 0xb7, 0xa8, 0xf8, 0x1c, 0x8c, 0x9a, 0xd8, 0x76, 0x70, 0x8d, 0x59, 0x51, 0x74, 0x48, 0x3b, - 0x04, 0x46, 0xd4, 0x6d, 0x86, 0xb1, 0x5b, 0x32, 0xc3, 0x27, 0x61, 0xd2, 0x15, 0x49, 0x6b, 0xeb, - 0x66, 0x5d, 0xd8, 0xf3, 0xe9, 0x41, 0x92, 0xcc, 0xb9, 0xc1, 0x43, 0x25, 0x64, 0xea, 0x04, 0x0e, - 0x94, 0x51, 0x01, 0xc0, 0x32, 0xb1, 0xb5, 0xa5, 0xd5, 0x70, 0xb5, 0x91, 0x49, 0xf5, 0xd1, 0xd2, - 0x1a, 0x41, 0xe9, 0xd2, 0x92, 0xc5, 0xa0, 0xd5, 0x06, 0xba, 0xe8, 0x99, 0x67, 0xb2, 0x8f, 0x75, - 0xad, 0x30, 0xc7, 0xec, 0xb2, 0xd0, 0x0d, 0x98, 0x68, 0x63, 0xe2, 0x2b, 0xb8, 0xc6, 0x7b, 0x96, - 0xa6, 0x42, 0xcc, 0x0d, 0xec, 0x99, 0xca, 0xc9, 0x58, 0xc7, 0xc6, 0xdb, 0xfe, 0x22, 0xba, 0x13, - 0x5c, 0x80, 0x46, 0xcd, 0x0a, 0x68, 0xa4, 0x19, 0x13, 0xc0, 0x55, 0x62, 0x5e, 0x39, 0x80, 0x6b, - 0x86, 0x6d, 0x6c, 0x1a, 0x0d, 0xc3, 0x21, 0x61, 0x8b, 0x58, 0xef, 0x1d, 0xdd, 0x7e, 0xb1, 0xd3, - 0xdc, 0xb4, 0x1a, 0x57, 0x5c, 0x44, 0xd5, 0x47, 0x94, 0x7d, 0x16, 0x26, 0x82, 0x1a, 0x46, 0x33, - 0x10, 0xb7, 0x1d, 0xbd, 0xed, 0x50, 0x43, 0x8e, 0xab, 0xac, 0x80, 0x64, 0x88, 0x62, 0xb3, 0x46, - 0x23, 0x71, 0x5c, 0x25, 0x7f, 0xa2, 0xef, 0xf5, 0x74, 0x16, 0xa5, 0x3a, 0x3b, 0xde, 0x6d, 0x14, - 0x01, 0xce, 0x61, 0xd5, 0x65, 0x1f, 0x86, 0xf1, 0x80, 0x0e, 0x86, 0x6d, 0x5a, 0xf9, 0x9d, 0x18, - 0xec, 0xeb, 0xc9, 0x1b, 0x3d, 0x09, 0x33, 0x1d, 0xd3, 0x30, 0x1d, 0xdc, 0x6e, 0xb5, 0x31, 0xb1, - 0x7a, 0xd6, 0x56, 0xe6, 0x6b, 0xc9, 0x3e, 0x76, 0xbb, 0xe1, 0xc7, 0x66, 0x5c, 0xd4, 0xe9, 0x4e, - 0x37, 0x10, 0x3d, 0x05, 0xa3, 0xc4, 0xc4, 0xf4, 0xb6, 0x4e, 0x19, 0x32, 0x87, 0x3e, 0x3b, 0x5c, - 0x97, 0xe7, 0x0a, 0x1e, 0x65, 0x3e, 0xfa, 0xbc, 0x14, 0x51, 0xfd, 0xbc, 0xd0, 0xc3, 0x90, 0xda, - 0xc2, 0xba, 0xd3, 0x69, 0x63, 0x3b, 0x73, 0x96, 0xaa, 0xf2, 0x50, 0xb7, 0x9f, 0x33, 0x84, 0x32, - 0x76, 0x54, 0x17, 0x19, 0x35, 0x61, 0xec, 0x1a, 0x6e, 0x1b, 0x5b, 0x46, 0x95, 0x09, 0x15, 0xa5, - 0x16, 0x70, 0x61, 0x48, 0xa1, 0xae, 0xf8, 0x48, 0xcb, 0x8e, 0xee, 0xe0, 0x79, 0xd8, 0x58, 0xbd, - 0x52, 0x54, 0x4b, 0x97, 0x4a, 0xc5, 0x02, 0x13, 0x33, 0xc0, 0x3e, 0xfb, 0x63, 0x12, 0x8c, 0xfa, - 0x7a, 0x42, 0x22, 0xaa, 0xd9, 0x69, 0x6e, 0xe2, 0x36, 0x1f, 0x2f, 0x5e, 0x42, 0x87, 0x20, 0xbd, - 0xd5, 0x69, 0x34, 0x98, 0xdd, 0xb2, 0xb9, 0x3b, 0x45, 0x00, 0xd4, 0x66, 0x11, 0xc4, 0x78, 0x24, - 0xa2, 0x61, 0x92, 0xfc, 0x8d, 0xb2, 0x90, 0x12, 0x76, 0x9d, 0x89, 0x1f, 0x93, 0x4e, 0xa4, 0x54, - 0xb7, 0xcc, 0xea, 0x5a, 0x58, 0x77, 0x70, 0x2d, 0x93, 0x10, 0x75, 0xac, 0x7c, 0x39, 0x96, 0x8a, - 0xc9, 0x71, 0xe5, 0x21, 0x98, 0xea, 0xea, 0x0a, 0x9a, 0x84, 0xd1, 0x42, 0x71, 0x61, 0x39, 0xa7, - 0xe6, 0x2a, 0xa5, 0xb5, 0x55, 0x79, 0x04, 0x4d, 0x80, 0xaf, 0x77, 0xb2, 0x74, 0x32, 0x9d, 0x7a, - 0x35, 0x29, 0x3f, 0xf7, 0xdc, 0x73, 0xcf, 0x45, 0x94, 0xdf, 0x4c, 0xc0, 0x4c, 0xaf, 0x38, 0xda, - 0x33, 0xa4, 0x7b, 0x9d, 0x8e, 0x06, 0x3a, 0x9d, 0x83, 0x78, 0x43, 0xdf, 0xc4, 0x8d, 0x4c, 0x8c, - 0x0e, 0xc2, 0x7d, 0x43, 0x45, 0xea, 0xb9, 0x65, 0x42, 0xa2, 0x32, 0x4a, 0xf4, 0x56, 0xae, 0x9a, - 0x38, 0xe5, 0x70, 0x72, 0x38, 0x0e, 0x24, 0xbe, 0x72, 0x35, 0x1e, 0x82, 0x34, 0xf9, 0x9f, 0xe9, - 0x3d, 0xc1, 0xf4, 0x4e, 0x00, 0x54, 0xef, 0x59, 0x48, 0xd1, 0xd0, 0x59, 0xc3, 0xee, 0x98, 0x88, - 0x32, 0x09, 0x36, 0x35, 0xbc, 0xa5, 0x77, 0x1a, 0x8e, 0x76, 0x4d, 0x6f, 0x74, 0x30, 0x0d, 0x82, - 0x69, 0x75, 0x8c, 0x03, 0xaf, 0x10, 0x18, 0x9a, 0x85, 0x51, 0x16, 0x69, 0x0d, 0xb3, 0x86, 0xaf, - 0xd3, 0x59, 0x38, 0xae, 0xb2, 0xe0, 0x5b, 0x22, 0x10, 0xd2, 0xfc, 0xd3, 0xb6, 0x65, 0x8a, 0x70, - 0x45, 0x9b, 0x20, 0x00, 0xda, 0xfc, 0xc3, 0xe1, 0x04, 0xe0, 0x48, 0xef, 0xee, 0x75, 0xc5, 0xd7, - 0x7b, 0x60, 0x92, 0x62, 0x3c, 0xc8, 0x5d, 0x59, 0x6f, 0x64, 0xa6, 0xa8, 0x19, 0x4c, 0x30, 0xf0, - 0x1a, 0x87, 0x2a, 0xbf, 0x12, 0x81, 0x18, 0x9d, 0x6c, 0x26, 0x61, 0xb4, 0xf2, 0xd4, 0x7a, 0x51, - 0x2b, 0xac, 0x6d, 0xe4, 0x97, 0x8b, 0xb2, 0x44, 0x86, 0x9e, 0x02, 0x2e, 0x2d, 0xaf, 0xe5, 0x2a, - 0x72, 0xc4, 0x2d, 0x97, 0x56, 0x2b, 0xe7, 0x1f, 0x92, 0xa3, 0x2e, 0xc1, 0x06, 0x03, 0xc4, 0xfc, - 0x08, 0x0f, 0x9e, 0x95, 0xe3, 0x48, 0x86, 0x31, 0xc6, 0xa0, 0xf4, 0x64, 0xb1, 0x70, 0xfe, 0x21, - 0x39, 0x11, 0x84, 0x3c, 0x78, 0x56, 0x4e, 0xa2, 0x71, 0x48, 0x53, 0x48, 0x7e, 0x6d, 0x6d, 0x59, - 0x4e, 0xb9, 0x3c, 0xcb, 0x15, 0xb5, 0xb4, 0xba, 0x28, 0xa7, 0x5d, 0x9e, 0x8b, 0xea, 0xda, 0xc6, - 0xba, 0x0c, 0x2e, 0x87, 0x95, 0x62, 0xb9, 0x9c, 0x5b, 0x2c, 0xca, 0xa3, 0x2e, 0x46, 0xfe, 0xa9, - 0x4a, 0xb1, 0x2c, 0x8f, 0x05, 0xc4, 0x7a, 0xf0, 0xac, 0x3c, 0xee, 0x36, 0x51, 0x5c, 0xdd, 0x58, - 0x91, 0x27, 0xd0, 0x14, 0x8c, 0xb3, 0x26, 0x84, 0x10, 0x93, 0x21, 0xd0, 0xf9, 0x87, 0x64, 0xd9, - 0x13, 0x84, 0x71, 0x99, 0x0a, 0x00, 0xce, 0x3f, 0x24, 0x23, 0x65, 0x01, 0xe2, 0xd4, 0x0c, 0x11, - 0x82, 0x89, 0xe5, 0x5c, 0xbe, 0xb8, 0xac, 0xad, 0xad, 0x13, 0xa7, 0xc9, 0x2d, 0xcb, 0x92, 0x07, - 0x53, 0x8b, 0xeb, 0xc5, 0x5c, 0xa5, 0x58, 0x90, 0xa3, 0x7e, 0xd8, 0xe3, 0x1b, 0x25, 0xb5, 0x58, - 0x90, 0x23, 0x4a, 0x15, 0x66, 0x7a, 0x4d, 0xb2, 0x3d, 0x5d, 0xc8, 0x67, 0x0b, 0x91, 0x3e, 0xb6, - 0x40, 0x79, 0x85, 0x6d, 0x41, 0xf9, 0xd9, 0x28, 0x4c, 0xf7, 0x48, 0x34, 0x7a, 0x36, 0xf2, 0x28, - 0xc4, 0x99, 0x2d, 0xb3, 0x48, 0x7d, 0x6f, 0xcf, 0x8c, 0x85, 0x5a, 0x76, 0x57, 0xfa, 0x45, 0xe9, - 0xfc, 0x29, 0x6b, 0xb4, 0x4f, 0xca, 0x4a, 0x58, 0x74, 0x19, 0xec, 0xf7, 0x77, 0x25, 0x04, 0x2c, - 0x67, 0x3a, 0x3f, 0x4c, 0xce, 0x44, 0x61, 0x7b, 0x4b, 0x0c, 0xe2, 0x03, 0x13, 0x83, 0xc4, 0xad, - 0x24, 0x06, 0x8f, 0xc0, 0x54, 0x97, 0x2c, 0x43, 0x4f, 0xd0, 0x3f, 0x22, 0x41, 0xa6, 0x9f, 0x7e, - 0x07, 0x44, 0xd5, 0x48, 0x20, 0xaa, 0x3e, 0x12, 0x1e, 0x84, 0x3b, 0xfa, 0x8f, 0x63, 0x97, 0xb9, - 0x7c, 0x4a, 0x82, 0xfd, 0xbd, 0x57, 0x37, 0x3d, 0x65, 0x78, 0x2b, 0x24, 0x9a, 0xd8, 0xd9, 0xb6, - 0x44, 0xb6, 0x7e, 0xbc, 0x47, 0x0e, 0x48, 0xaa, 0xc3, 0xf6, 0xc2, 0xa9, 0xfc, 0x49, 0x64, 0xb4, - 0xdf, 0x12, 0x85, 0x49, 0xd3, 0x25, 0xe9, 0xfb, 0x22, 0xb0, 0xaf, 0x27, 0xf3, 0x9e, 0x82, 0x1e, - 0x01, 0x30, 0xcc, 0x56, 0xc7, 0x61, 0x19, 0x39, 0x0b, 0xe6, 0x69, 0x0a, 0xa1, 0xf1, 0x8f, 0x04, - 0xea, 0x8e, 0xe3, 0xd6, 0xb3, 0x89, 0x16, 0x18, 0x88, 0x22, 0x5c, 0xf0, 0x04, 0x8d, 0x51, 0x41, - 0x8f, 0xf6, 0xe9, 0x69, 0x97, 0x6d, 0x3f, 0x00, 0x72, 0xb5, 0x61, 0x60, 0xd3, 0xd1, 0x6c, 0xa7, - 0x8d, 0xf5, 0xa6, 0x61, 0xd6, 0xd9, 0x84, 0x3d, 0x1f, 0xdf, 0xd2, 0x1b, 0x36, 0x56, 0x27, 0x59, - 0x75, 0x59, 0xd4, 0x12, 0x0a, 0x6a, 0x40, 0x6d, 0x1f, 0x45, 0x22, 0x40, 0xc1, 0xaa, 0x5d, 0x0a, - 0xe5, 0xe7, 0xd3, 0x30, 0xea, 0x5b, 0x0b, 0xa2, 0x3b, 0x60, 0xec, 0x69, 0xfd, 0x9a, 0xae, 0x89, - 0xcd, 0x00, 0xa6, 0x89, 0x51, 0x02, 0x5b, 0xe7, 0x1b, 0x02, 0x0f, 0xc0, 0x0c, 0x45, 0xb1, 0x3a, - 0x0e, 0x6e, 0x6b, 0xd5, 0x86, 0x6e, 0xdb, 0x54, 0x69, 0x29, 0x8a, 0x8a, 0x48, 0xdd, 0x1a, 0xa9, - 0x5a, 0x10, 0x35, 0xe8, 0x1c, 0x4c, 0x53, 0x8a, 0x66, 0xa7, 0xe1, 0x18, 0xad, 0x06, 0xa6, 0xdb, - 0x1c, 0x36, 0x9d, 0xb5, 0x5c, 0xc9, 0xa6, 0x08, 0xc6, 0x0a, 0x47, 0x20, 0x12, 0xd9, 0xa8, 0x00, - 0x47, 0x28, 0x59, 0x1d, 0x9b, 0xb8, 0xad, 0x3b, 0x58, 0xc3, 0xef, 0xe8, 0xe8, 0x0d, 0x5b, 0xd3, - 0xcd, 0x9a, 0xb6, 0xad, 0xdb, 0xdb, 0x99, 0x19, 0xc2, 0x20, 0x1f, 0xc9, 0x48, 0xea, 0x41, 0x82, - 0xb8, 0xc8, 0xf1, 0x8a, 0x14, 0x2d, 0x67, 0xd6, 0x96, 0x74, 0x7b, 0x1b, 0xcd, 0xc3, 0x7e, 0xca, - 0xc5, 0x76, 0xda, 0x86, 0x59, 0xd7, 0xaa, 0xdb, 0xb8, 0x7a, 0x55, 0xeb, 0x38, 0x5b, 0x17, 0x32, - 0x87, 0xfc, 0xed, 0x53, 0x09, 0xcb, 0x14, 0x67, 0x81, 0xa0, 0x6c, 0x38, 0x5b, 0x17, 0x50, 0x19, - 0xc6, 0xc8, 0x60, 0x34, 0x8d, 0x67, 0xb1, 0xb6, 0x65, 0xb5, 0xe9, 0x34, 0x3c, 0xd1, 0x23, 0xba, - 0xf9, 0x34, 0x38, 0xb7, 0xc6, 0x09, 0x56, 0xac, 0x1a, 0x9e, 0x8f, 0x97, 0xd7, 0x8b, 0xc5, 0x82, - 0x3a, 0x2a, 0xb8, 0x5c, 0xb2, 0xda, 0xc4, 0xa0, 0xea, 0x96, 0xab, 0xe0, 0x51, 0x66, 0x50, 0x75, - 0x4b, 0xa8, 0xf7, 0x1c, 0x4c, 0x57, 0xab, 0xac, 0xcf, 0x46, 0x55, 0xe3, 0xfb, 0x02, 0x76, 0x46, - 0x0e, 0x28, 0xab, 0x5a, 0x5d, 0x64, 0x08, 0xdc, 0xc6, 0x6d, 0x74, 0x11, 0xf6, 0x79, 0xca, 0xf2, - 0x13, 0x4e, 0x75, 0xf5, 0x32, 0x4c, 0x7a, 0x0e, 0xa6, 0x5b, 0x3b, 0xdd, 0x84, 0x28, 0xd0, 0x62, - 0x6b, 0x27, 0x4c, 0x76, 0x37, 0xdd, 0x18, 0x6a, 0xe3, 0x2a, 0xcd, 0x16, 0x0f, 0xf8, 0xb1, 0x7d, - 0x15, 0x68, 0x0e, 0xe4, 0x6a, 0x55, 0xc3, 0xa6, 0xbe, 0xd9, 0xc0, 0x9a, 0xde, 0xc6, 0xa6, 0x6e, - 0x67, 0x66, 0x29, 0x72, 0xcc, 0x69, 0x77, 0xb0, 0x3a, 0x51, 0xad, 0x16, 0x69, 0x65, 0x8e, 0xd6, - 0xa1, 0x93, 0x30, 0x65, 0x6d, 0x3e, 0x5d, 0x65, 0x86, 0xa5, 0xb5, 0xda, 0x78, 0xcb, 0xb8, 0x9e, - 0xb9, 0x8b, 0x6a, 0x69, 0x92, 0x54, 0x50, 0xb3, 0x5a, 0xa7, 0x60, 0x74, 0x2f, 0xc8, 0x55, 0x7b, - 0x5b, 0x6f, 0xb7, 0x68, 0x70, 0xb6, 0x5b, 0x7a, 0x15, 0x67, 0xee, 0x66, 0xa8, 0x0c, 0xbe, 0x2a, - 0xc0, 0xc4, 0xb0, 0xed, 0x67, 0x8c, 0x2d, 0x47, 0x70, 0xbc, 0x87, 0x19, 0x36, 0x85, 0x71, 0x6e, - 0x27, 0x40, 0x6e, 0x6d, 0xb7, 0x82, 0x0d, 0x9f, 0xa0, 0x68, 0x13, 0xad, 0xed, 0x96, 0xbf, 0xdd, - 0x3b, 0x61, 0x9c, 0x60, 0x7a, 0x8d, 0xde, 0xcb, 0x52, 0xb8, 0xd6, 0xb6, 0xaf, 0xc5, 0x87, 0x60, - 0x3f, 0x41, 0x6a, 0x62, 0x47, 0xaf, 0xe9, 0x8e, 0xee, 0xc3, 0xbe, 0x9f, 0x62, 0xcf, 0xb4, 0xb6, - 0x5b, 0x2b, 0xbc, 0x32, 0x20, 0x67, 0xbb, 0xb3, 0xb9, 0xe3, 0xda, 0xc7, 0x29, 0x26, 0x27, 0x81, - 0x09, 0x0b, 0xb9, 0xe5, 0x15, 0xcc, 0x1b, 0xb6, 0x5e, 0x53, 0xe6, 0x61, 0xcc, 0x6f, 0xf7, 0x28, - 0x0d, 0xcc, 0xf2, 0x65, 0x89, 0xe4, 0x51, 0x0b, 0x6b, 0x05, 0x92, 0x01, 0xbd, 0xad, 0x28, 0x47, - 0x48, 0x26, 0xb6, 0x5c, 0xaa, 0x14, 0x35, 0x75, 0x63, 0xb5, 0x52, 0x5a, 0x29, 0xca, 0x51, 0xdf, - 0xda, 0xe0, 0x72, 0x2c, 0x75, 0x52, 0xbe, 0xef, 0x72, 0x2c, 0x75, 0x5c, 0xbe, 0x87, 0xaa, 0xa7, - 0xcb, 0x28, 0x95, 0x6f, 0x47, 0x61, 0x22, 0xb8, 0x39, 0x80, 0xde, 0x02, 0x07, 0xc4, 0xee, 0x9f, - 0x8d, 0x1d, 0xed, 0x19, 0xa3, 0x4d, 0x9d, 0xb5, 0xa9, 0xb3, 0x89, 0xd3, 0x35, 0xca, 0x19, 0x8e, - 0x55, 0xc6, 0xce, 0x13, 0x46, 0x9b, 0xb8, 0x62, 0x53, 0x77, 0xd0, 0x32, 0xcc, 0x9a, 0x96, 0x66, - 0x3b, 0xba, 0x59, 0xd3, 0xdb, 0x35, 0xff, 0xde, 0xab, 0x5e, 0xad, 0x62, 0xdb, 0xb6, 0xd8, 0x24, - 0xe9, 0x72, 0x39, 0x6c, 0x5a, 0x65, 0x8e, 0xec, 0xcd, 0x1e, 0x39, 0x8e, 0x1a, 0xf2, 0x89, 0x68, - 0x3f, 0x9f, 0x38, 0x04, 0xe9, 0xa6, 0xde, 0xd2, 0xb0, 0xe9, 0xb4, 0x77, 0x68, 0xfa, 0x9f, 0x52, - 0x53, 0x4d, 0xbd, 0x55, 0x24, 0x65, 0x74, 0x05, 0x8e, 0x7b, 0xa8, 0x5a, 0x03, 0xd7, 0xf5, 0xea, - 0x8e, 0x46, 0x73, 0x7d, 0xba, 0x53, 0xa5, 0x55, 0x2d, 0x73, 0xab, 0x61, 0x54, 0x1d, 0x9b, 0xc6, - 0x0e, 0x16, 0xff, 0x14, 0x8f, 0x62, 0x99, 0x12, 0x5c, 0xb6, 0x2d, 0x93, 0xa6, 0xf8, 0x0b, 0x02, - 0x3b, 0x60, 0x36, 0x63, 0x6f, 0x0a, 0xb3, 0x09, 0x0e, 0x7d, 0x4c, 0x8e, 0x5f, 0x8e, 0xa5, 0xe2, - 0x72, 0xe2, 0x72, 0x2c, 0x95, 0x90, 0x93, 0x97, 0x63, 0xa9, 0x94, 0x9c, 0xbe, 0x1c, 0x4b, 0xa5, - 0x65, 0x50, 0x6e, 0x8c, 0xc3, 0x98, 0x7f, 0xc5, 0x42, 0x16, 0x80, 0x55, 0x3a, 0xe1, 0x4a, 0x34, - 0x24, 0xdf, 0xb9, 0xeb, 0xfa, 0x66, 0x6e, 0x81, 0xcc, 0xc4, 0xf3, 0x09, 0xb6, 0x3c, 0x50, 0x19, - 0x25, 0xc9, 0x82, 0x88, 0x93, 0x61, 0x96, 0x4b, 0xa5, 0x54, 0x5e, 0x42, 0x8b, 0x90, 0x78, 0xda, - 0xa6, 0xbc, 0x59, 0x2a, 0x77, 0xd7, 0xee, 0xbc, 0x2f, 0x97, 0x29, 0xf3, 0xf4, 0xe5, 0xb2, 0xb6, - 0xba, 0xa6, 0xae, 0xe4, 0x96, 0x55, 0x4e, 0x8e, 0x0e, 0x42, 0xac, 0xa1, 0x3f, 0xbb, 0x13, 0x9c, - 0xb3, 0x29, 0x08, 0xcd, 0xc1, 0x64, 0xc7, 0x64, 0xcb, 0x7d, 0x32, 0xc6, 0x04, 0x6b, 0xd2, 0x8f, - 0x35, 0xe1, 0xd5, 0x2e, 0x13, 0xfc, 0x21, 0xed, 0xea, 0x20, 0xc4, 0x9e, 0xc1, 0xfa, 0xd5, 0xe0, - 0xcc, 0x4a, 0x41, 0xe8, 0x04, 0x8c, 0xd5, 0xf0, 0x66, 0xa7, 0xae, 0xb5, 0x71, 0x4d, 0xaf, 0x3a, - 0xc1, 0xf9, 0x64, 0x94, 0x56, 0xa9, 0xb4, 0x06, 0x3d, 0x06, 0x69, 0x32, 0x46, 0x26, 0x1d, 0xe3, - 0x29, 0xaa, 0x82, 0x53, 0xbb, 0xab, 0x80, 0x0f, 0xb1, 0x20, 0x52, 0x3d, 0x7a, 0xb4, 0x04, 0x49, - 0x47, 0x6f, 0xd7, 0xb1, 0x63, 0x67, 0xa6, 0x8f, 0x45, 0x4f, 0x4c, 0xf4, 0xd8, 0xa9, 0xeb, 0xc1, - 0xaa, 0x42, 0x49, 0xe8, 0x62, 0x5b, 0x90, 0xa3, 0x27, 0x40, 0xe6, 0x1b, 0xc2, 0x1a, 0x5f, 0x29, - 0xdb, 0x99, 0x19, 0x6a, 0x80, 0xf7, 0xef, 0xce, 0x92, 0xef, 0x27, 0x17, 0x18, 0x91, 0x3a, 0x89, - 0x03, 0xe5, 0xa0, 0x5f, 0xec, 0xdb, 0x8b, 0x5f, 0x6c, 0xc0, 0x24, 0xff, 0x5b, 0xb3, 0x3b, 0xad, - 0x96, 0xd5, 0x76, 0x32, 0xfb, 0x29, 0xfd, 0x00, 0x81, 0x04, 0x33, 0x46, 0xa3, 0x4e, 0x6c, 0x05, - 0xca, 0x6f, 0x9c, 0xbb, 0x65, 0xdf, 0x06, 0x13, 0x41, 0x65, 0xf8, 0xb7, 0xe3, 0xa3, 0x43, 0x6e, - 0xc7, 0x93, 0x65, 0x89, 0x58, 0xeb, 0x91, 0xa9, 0x89, 0x15, 0xb2, 0x3f, 0x1e, 0x81, 0x89, 0x60, - 0xc7, 0xd0, 0x22, 0x20, 0x31, 0x62, 0x86, 0xe9, 0xb4, 0xad, 0x5a, 0xa7, 0x8a, 0x6b, 0xdc, 0x61, - 0xfb, 0xb7, 0x33, 0xc5, 0x69, 0x4a, 0x2e, 0x89, 0x9f, 0x91, 0xcf, 0x0b, 0x22, 0x43, 0x32, 0x2a, - 0x78, 0xfe, 0x71, 0x1a, 0xa6, 0x05, 0x03, 0xc2, 0xec, 0x19, 0xbd, 0x6d, 0x92, 0x14, 0x99, 0x25, - 0xed, 0xc8, 0x57, 0xf5, 0x04, 0xab, 0x41, 0x39, 0x10, 0xe6, 0xa2, 0xb5, 0x71, 0xd3, 0xba, 0x86, - 0x6b, 0x7c, 0xc7, 0xa9, 0x7f, 0xb3, 0x13, 0x9c, 0x40, 0x65, 0xf8, 0xca, 0x69, 0x88, 0xd3, 0xf0, - 0x83, 0x00, 0x78, 0x00, 0x92, 0x47, 0x50, 0x0a, 0x62, 0x0b, 0x6b, 0x2a, 0x99, 0x1e, 0x65, 0x18, - 0x63, 0x50, 0x6d, 0xbd, 0x54, 0x5c, 0x28, 0xca, 0x11, 0xe5, 0x1c, 0x24, 0x58, 0x4c, 0x21, 0x53, - 0xa7, 0x1b, 0x55, 0xe4, 0x11, 0x5e, 0xe4, 0x3c, 0x24, 0x51, 0xbb, 0xb1, 0x92, 0x2f, 0xaa, 0x72, - 0x44, 0xd9, 0x80, 0xc9, 0x90, 0x1f, 0xa2, 0x7d, 0x30, 0xa5, 0x16, 0x2b, 0xc5, 0xd5, 0x4a, 0x69, - 0x6d, 0x55, 0xdb, 0x58, 0x7d, 0x6c, 0x75, 0xed, 0x89, 0x55, 0x79, 0x24, 0x08, 0x16, 0xf3, 0xb0, - 0x84, 0x66, 0x40, 0xf6, 0xc0, 0xe5, 0xb5, 0x0d, 0x95, 0x4a, 0xf3, 0xff, 0x44, 0x40, 0x0e, 0x3b, - 0x25, 0x3a, 0x00, 0xd3, 0x95, 0x9c, 0xba, 0x58, 0xac, 0x68, 0x6c, 0xcf, 0xc4, 0x65, 0x3d, 0x03, - 0xb2, 0xbf, 0xe2, 0x52, 0x89, 0x6e, 0x09, 0xcd, 0xc2, 0x21, 0x3f, 0xb4, 0xf8, 0x64, 0xa5, 0xb8, - 0x5a, 0xa6, 0x8d, 0xe7, 0x56, 0x17, 0x49, 0x52, 0x10, 0xe2, 0x27, 0x76, 0x69, 0xa2, 0x44, 0xd4, - 0x20, 0xbf, 0xe2, 0x72, 0x41, 0x8e, 0x85, 0xc1, 0x6b, 0xab, 0xc5, 0xb5, 0x4b, 0x72, 0x3c, 0xdc, - 0x3a, 0xdd, 0xb9, 0x49, 0xa0, 0x2c, 0xec, 0x0f, 0x43, 0xb5, 0xe2, 0x6a, 0x45, 0x7d, 0x4a, 0x4e, - 0x86, 0x1b, 0x2e, 0x17, 0xd5, 0x2b, 0xa5, 0x85, 0xa2, 0x9c, 0x42, 0xfb, 0x01, 0x05, 0x25, 0xaa, - 0x2c, 0xad, 0x15, 0xe4, 0x74, 0xaf, 0x19, 0x0b, 0xc9, 0xd3, 0xca, 0x67, 0x25, 0x18, 0xf3, 0xef, - 0xa2, 0x04, 0x82, 0x8a, 0xf4, 0x66, 0x9b, 0x6c, 0x95, 0x2f, 0x47, 0x60, 0xd4, 0xb7, 0x9d, 0x42, - 0x16, 0xb1, 0x7a, 0xa3, 0x61, 0x3d, 0xa3, 0xe9, 0x0d, 0x43, 0xb7, 0xf9, 0x7c, 0x08, 0x14, 0x94, - 0x23, 0x90, 0x61, 0xe7, 0x9f, 0xe1, 0x53, 0x97, 0xc4, 0x2d, 0xa7, 0x2e, 0xc9, 0x37, 0x61, 0xea, - 0x12, 0x97, 0x13, 0xca, 0x1f, 0x44, 0x40, 0x0e, 0xef, 0x8e, 0x84, 0xf4, 0x26, 0xf5, 0xd3, 0x9b, - 0xbf, 0x7f, 0x91, 0xbd, 0xf4, 0x2f, 0x3c, 0xab, 0x47, 0xfb, 0xce, 0xea, 0x3d, 0x26, 0xab, 0xd8, - 0x9b, 0x79, 0xb2, 0xf2, 0x9b, 0xeb, 0xbf, 0x96, 0x60, 0x22, 0xb8, 0x99, 0x13, 0xd0, 0x98, 0xb2, - 0x17, 0x8d, 0x05, 0x47, 0xe4, 0x8e, 0x7e, 0x23, 0xf2, 0xd7, 0xd2, 0xaf, 0x8f, 0x44, 0x61, 0x3c, - 0xb0, 0xf7, 0x33, 0xac, 0x74, 0xef, 0x80, 0x29, 0xa3, 0x86, 0x9b, 0x2d, 0xcb, 0xc1, 0x66, 0x75, - 0x47, 0x6b, 0xe0, 0x6b, 0xb8, 0x41, 0xd5, 0x30, 0xd1, 0xe3, 0x8c, 0x37, 0xd0, 0xc2, 0x5c, 0xc9, - 0xa3, 0x5b, 0x26, 0x64, 0xf3, 0xd3, 0xa5, 0x42, 0x71, 0x65, 0x7d, 0xad, 0x52, 0x5c, 0x5d, 0x78, - 0x4a, 0x44, 0x72, 0x55, 0x36, 0x42, 0x68, 0x01, 0x85, 0xdf, 0xf9, 0xe6, 0x58, 0x74, 0xae, 0x83, - 0x1c, 0xee, 0x0d, 0x09, 0xe8, 0x3d, 0xfa, 0x23, 0x8f, 0xa0, 0x69, 0x98, 0x5c, 0x5d, 0xd3, 0xca, - 0xa5, 0x42, 0x51, 0x2b, 0x5e, 0xba, 0x54, 0x5c, 0xa8, 0x94, 0xd9, 0x59, 0x85, 0x8b, 0x5d, 0x91, - 0x23, 0xfe, 0xb1, 0xf9, 0x68, 0x14, 0xa6, 0x7b, 0x48, 0x82, 0x72, 0x7c, 0x8b, 0x90, 0xed, 0x5a, - 0x9e, 0x1a, 0x46, 0xfa, 0x39, 0xb2, 0xba, 0x5f, 0xd7, 0xdb, 0x0e, 0xdf, 0x51, 0xbc, 0x17, 0x88, - 0x7a, 0x4d, 0x87, 0xa4, 0xf7, 0x6d, 0x7e, 0x06, 0xc4, 0x52, 0x90, 0x49, 0x0f, 0xce, 0x8e, 0x81, - 0xee, 0x07, 0xd4, 0xb2, 0x6c, 0xc3, 0x31, 0xae, 0x61, 0x92, 0x43, 0x71, 0x64, 0xe2, 0xb8, 0x31, - 0x55, 0x16, 0x35, 0x25, 0xd3, 0x71, 0xb1, 0x4d, 0x5c, 0xd7, 0x43, 0xd8, 0x64, 0xf9, 0x11, 0x55, - 0x65, 0x51, 0xe3, 0x62, 0xdf, 0x01, 0x63, 0x35, 0xab, 0xb3, 0xd9, 0xc0, 0x1c, 0x8f, 0x84, 0x64, - 0x49, 0x1d, 0x65, 0x30, 0x17, 0x85, 0x6f, 0x9b, 0x79, 0x27, 0x55, 0x63, 0xea, 0x28, 0x83, 0x31, - 0x94, 0x7b, 0x60, 0x52, 0xaf, 0xd7, 0xdb, 0x84, 0xb9, 0x60, 0xc4, 0x36, 0x02, 0x27, 0x5c, 0x30, - 0x45, 0xcc, 0x5e, 0x86, 0x94, 0xd0, 0x03, 0x59, 0xff, 0x12, 0x4d, 0x68, 0x2d, 0xb6, 0xbb, 0x1d, - 0x39, 0x91, 0x56, 0x53, 0xa6, 0xa8, 0xbc, 0x03, 0xc6, 0x0c, 0xdb, 0xbb, 0xf5, 0x94, 0x89, 0x1c, - 0x8b, 0x9c, 0x48, 0xa9, 0xa3, 0x86, 0xed, 0xdd, 0x6c, 0xfa, 0x55, 0x19, 0xc0, 0x33, 0x36, 0xf4, - 0x21, 0x09, 0x26, 0xd8, 0x04, 0xd3, 0x6a, 0x63, 0x1b, 0x9b, 0x55, 0xb1, 0x2c, 0xbc, 0x77, 0x17, - 0x13, 0x65, 0x61, 0x6e, 0x9d, 0x13, 0xe4, 0x1f, 0x7d, 0x5e, 0x92, 0x5e, 0x94, 0x62, 0x2f, 0x4a, - 0xd2, 0x27, 0xa4, 0x71, 0x94, 0x2a, 0x3e, 0xb9, 0xbe, 0x5c, 0x5a, 0x28, 0x55, 0x32, 0xef, 0x49, - 0xd2, 0x72, 0x69, 0x85, 0x97, 0xbf, 0x96, 0x0c, 0xd6, 0xbf, 0x9a, 0xfc, 0x25, 0x29, 0x9a, 0x7a, - 0x35, 0xa9, 0x8e, 0x6f, 0xf9, 0xf9, 0xa1, 0x86, 0xff, 0x1e, 0x47, 0xa4, 0xdf, 0x42, 0xd2, 0x93, - 0xa6, 0xc8, 0x6f, 0x6f, 0xe4, 0xef, 0xa5, 0x82, 0x24, 0xa8, 0x20, 0xa3, 0x28, 0xb1, 0xb0, 0xbc, - 0x56, 0x2e, 0x16, 0xa8, 0x18, 0x69, 0x14, 0x5b, 0x5b, 0x2f, 0xae, 0x66, 0xbe, 0x26, 0x9a, 0xf4, - 0xae, 0x7c, 0xbc, 0x28, 0xc1, 0x01, 0x71, 0x50, 0xcb, 0xe7, 0x5a, 0x6c, 0x56, 0xad, 0x9a, 0xc8, - 0x6e, 0x27, 0xce, 0x9e, 0xd9, 0xad, 0x71, 0x95, 0x93, 0x52, 0x95, 0x14, 0x39, 0x61, 0xfe, 0x54, - 0x97, 0x4a, 0x72, 0xab, 0x05, 0x2e, 0xcb, 0x28, 0x4a, 0xac, 0xe7, 0x16, 0x1e, 0x2b, 0x16, 0x3c, - 0x69, 0xf6, 0xb5, 0x7b, 0x71, 0x41, 0x3f, 0x0c, 0x93, 0x1d, 0x67, 0xeb, 0x02, 0xb1, 0x0d, 0xa3, - 0xc6, 0x4e, 0xce, 0x63, 0xfd, 0x8e, 0x5c, 0x3d, 0x89, 0x36, 0x9c, 0xad, 0x0b, 0x57, 0x5c, 0x0a, - 0xae, 0x14, 0x26, 0x4a, 0x1a, 0xc5, 0x56, 0xd7, 0x56, 0x8b, 0x42, 0x0c, 0x7a, 0xca, 0xfc, 0x94, - 0x27, 0xc6, 0x44, 0x27, 0x40, 0x8a, 0x7e, 0x18, 0x64, 0xb1, 0x3d, 0xe4, 0xaa, 0x24, 0xde, 0xef, - 0xd4, 0xd8, 0x13, 0x80, 0x6f, 0x32, 0xb9, 0xca, 0x38, 0xee, 0x93, 0x60, 0x06, 0x4d, 0x2e, 0x17, - 0x57, 0x17, 0x2b, 0x4b, 0xda, 0xba, 0x5a, 0xa4, 0x87, 0x7f, 0x99, 0xf7, 0x88, 0xe6, 0x27, 0x9b, - 0x41, 0x42, 0xf4, 0x6e, 0x09, 0x46, 0x59, 0x0a, 0xc4, 0xf6, 0xa4, 0xd8, 0xa6, 0xc2, 0xf1, 0xdd, - 0xda, 0xa6, 0x19, 0x10, 0xc5, 0xce, 0x5f, 0xa4, 0xcd, 0x46, 0x85, 0x41, 0x1c, 0x40, 0x68, 0xb9, - 0xb8, 0x98, 0x5b, 0x78, 0x4a, 0xcb, 0x17, 0xcb, 0x15, 0x12, 0xc9, 0xd6, 0x54, 0x66, 0xa3, 0x80, - 0xe2, 0xb9, 0xe5, 0xe5, 0xb5, 0x27, 0x3c, 0x45, 0xc0, 0xd3, 0x2e, 0x1b, 0xf4, 0x19, 0x09, 0x66, - 0xb0, 0xb9, 0x65, 0xb5, 0xab, 0xf4, 0xc0, 0x9a, 0x78, 0xb4, 0xed, 0xec, 0x34, 0x98, 0x47, 0xf7, - 0x5c, 0x94, 0xfb, 0x2d, 0x93, 0xd2, 0xad, 0x52, 0xb2, 0x32, 0xa1, 0xca, 0x97, 0x9e, 0x97, 0x22, - 0x2f, 0x12, 0xc1, 0x22, 0x54, 0xb6, 0xd8, 0x8b, 0x52, 0x9c, 0x4a, 0x98, 0x7c, 0x51, 0x4a, 0xbd, - 0x28, 0xa5, 0x3f, 0x21, 0x4d, 0xa1, 0xb1, 0x72, 0xe5, 0xa9, 0xe5, 0xa2, 0xc6, 0xa4, 0xa5, 0x12, - 0x4e, 0xa0, 0x34, 0x85, 0x9d, 0x7d, 0xe0, 0xec, 0x43, 0x99, 0xaf, 0x53, 0x29, 0xbf, 0x9e, 0x54, - 0x11, 0xee, 0x62, 0x8f, 0x7e, 0x55, 0x82, 0x83, 0xe2, 0x88, 0xdc, 0xa6, 0xc7, 0x66, 0x9a, 0xef, - 0x80, 0x2d, 0x45, 0x45, 0x2e, 0xee, 0x26, 0xb2, 0x77, 0xca, 0xc6, 0x81, 0x73, 0x7c, 0xc1, 0x1b, - 0x3e, 0x84, 0xcb, 0x9f, 0x67, 0x3d, 0xf9, 0x84, 0x34, 0x89, 0xa0, 0xf8, 0xe4, 0xfa, 0x9a, 0x5a, - 0xd1, 0x72, 0xcb, 0xcb, 0x54, 0xde, 0x7d, 0x48, 0xe6, 0x90, 0xca, 0xda, 0xba, 0xb6, 0x5c, 0xbc, - 0x52, 0x5c, 0xf6, 0xc4, 0x3e, 0x50, 0xeb, 0xcd, 0x30, 0xfb, 0x71, 0x09, 0xa6, 0xba, 0x9a, 0x57, - 0xde, 0x25, 0xc1, 0x81, 0x3e, 0x22, 0xa0, 0xbb, 0xe1, 0x8e, 0x42, 0xf1, 0x52, 0x6e, 0x63, 0xb9, - 0xa2, 0x95, 0x9f, 0x5a, 0xc9, 0xaf, 0x2d, 0x6b, 0x57, 0x4a, 0xe5, 0x52, 0xbe, 0xb4, 0x5c, 0xaa, - 0xf8, 0x27, 0xb0, 0x09, 0xf0, 0x09, 0xc8, 0x96, 0x6b, 0x61, 0xf1, 0xe4, 0x08, 0x59, 0x14, 0x2e, - 0xaf, 0x2d, 0xe4, 0x96, 0x29, 0x52, 0x54, 0xac, 0x39, 0x17, 0x2a, 0x72, 0xec, 0x72, 0x2a, 0x25, - 0xf1, 0xb9, 0xed, 0xed, 0x30, 0x1e, 0x08, 0x7e, 0x64, 0x89, 0x44, 0x97, 0x56, 0xc4, 0x9e, 0xcb, - 0xc5, 0xd5, 0x05, 0xff, 0x92, 0x6e, 0x0c, 0xdc, 0x60, 0x27, 0x4b, 0xa4, 0x24, 0x42, 0xa1, 0x1c, - 0x21, 0x93, 0x2a, 0x37, 0x47, 0xf7, 0x70, 0x3a, 0xaa, 0x3c, 0x0c, 0x29, 0x11, 0xcc, 0xc8, 0x42, - 0x8d, 0xae, 0xb7, 0x42, 0xcb, 0xc4, 0x14, 0xd0, 0x48, 0x26, 0x4b, 0x44, 0x40, 0x16, 0xe1, 0xe4, - 0x88, 0x72, 0x05, 0xf6, 0xf5, 0x0c, 0x44, 0xe8, 0x4e, 0x98, 0x15, 0x07, 0xe2, 0x6c, 0x09, 0xa8, - 0x15, 0x57, 0x17, 0xd6, 0x0a, 0x64, 0xd1, 0xec, 0xf1, 0x04, 0xe0, 0x11, 0x89, 0x49, 0x29, 0xa2, - 0x95, 0x1c, 0x51, 0x4a, 0x30, 0x11, 0x0c, 0x27, 0xe8, 0x10, 0x1c, 0xd8, 0xa8, 0x5c, 0xba, 0xa0, - 0x5d, 0xc9, 0x2d, 0x97, 0x0a, 0xb9, 0xd0, 0xf2, 0x18, 0x80, 0xc7, 0x14, 0x39, 0x42, 0x04, 0x25, - 0xb1, 0x46, 0x8e, 0x2a, 0xb1, 0x94, 0x24, 0x4b, 0x4a, 0x19, 0x26, 0x43, 0x81, 0x01, 0x1d, 0x86, - 0x0c, 0x5f, 0xaf, 0xf6, 0x92, 0x8a, 0x6a, 0x28, 0x10, 0x2a, 0xd8, 0xca, 0xbd, 0x50, 0x5c, 0x2e, - 0xad, 0x94, 0x2a, 0x54, 0xbe, 0x25, 0x00, 0xcf, 0xe3, 0x49, 0x06, 0x73, 0xb9, 0xbc, 0xb6, 0xaa, + // 12299 bytes of a gzipped FileDescriptorSet + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x7d, 0x94, 0x1b, 0xd7, + 0x75, 0x18, 0xbe, 0x83, 0x6f, 0xdc, 0xfd, 0x9a, 0x7d, 0xbb, 0x24, 0x41, 0x90, 0xdc, 0x5d, 0x8d, + 0x24, 0x8a, 0xa2, 0xc4, 0xa5, 0x48, 0x89, 0x14, 0xb9, 0x72, 0xac, 0x00, 0x0b, 0x70, 0x09, 0x6a, + 0xbf, 0x3c, 0xc0, 0x52, 0x92, 0xe3, 0xfc, 0xe6, 0xcc, 0x02, 0x6f, 0xb1, 0x23, 0x02, 0x33, 0x30, + 0x66, 0x40, 0x71, 0xe5, 0x24, 0x47, 0x76, 0xfc, 0xf3, 0x4f, 0x96, 0x7f, 0xfe, 0xc5, 0xfe, 0x39, + 0x27, 0x91, 0x9d, 0xd0, 0x91, 0xed, 0x34, 0x4e, 0x1d, 0xa7, 0x71, 0x12, 0x37, 0x6d, 0xda, 0x9e, + 0x93, 0xa4, 0xe7, 0xa4, 0x49, 0xdc, 0xa4, 0xc7, 0x6e, 0xd3, 0x36, 0xcd, 0x49, 0xe9, 0x56, 0xf1, + 0x89, 0x65, 0xc7, 0x6d, 0x1c, 0xc5, 0x6d, 0xd3, 0xe3, 0xa6, 0xee, 0x79, 0x5f, 0xf3, 0x05, 0x60, + 0x81, 0xa5, 0x28, 0x47, 0x69, 0xfa, 0x0f, 0xb9, 0xef, 0xbe, 0x7b, 0xef, 0xbb, 0xef, 0xbe, 0x7b, + 0xef, 0xbb, 0xef, 0x6b, 0x00, 0x7f, 0x65, 0xc0, 0x7c, 0xdd, 0xb2, 0xea, 0x0d, 0x7c, 0xba, 0xd5, + 0xb6, 0x1c, 0x6b, 0xab, 0xb3, 0x7d, 0xba, 0x86, 0xed, 0x6a, 0xdb, 0x68, 0x39, 0x56, 0x7b, 0x81, + 0xc2, 0xd0, 0x24, 0xc3, 0x58, 0x10, 0x18, 0xca, 0x17, 0x24, 0x98, 0xba, 0x64, 0x34, 0x70, 0xc1, + 0xc5, 0x2c, 0x63, 0x07, 0x5d, 0x80, 0xd8, 0xb6, 0xd1, 0xc0, 0x19, 0x69, 0x3e, 0x7a, 0x62, 0xf4, + 0xec, 0x3d, 0x0b, 0x21, 0xaa, 0x85, 0x20, 0xc5, 0x06, 0x01, 0xab, 0x94, 0xe2, 0xe4, 0xbb, 0x52, + 0xcf, 0x7f, 0xe3, 0x0b, 0xdf, 0x91, 0xe4, 0x77, 0x93, 0x7f, 0xb3, 0x4d, 0x74, 0x8d, 0x95, 0xd1, + 0x23, 0x0b, 0x84, 0xce, 0x27, 0xcf, 0xf5, 0x33, 0x04, 0xa2, 0x11, 0x22, 0xcd, 0x03, 0x6b, 0x36, + 0x76, 0x34, 0x7c, 0xc3, 0xc1, 0xa6, 0x6d, 0x58, 0x66, 0xf6, 0x54, 0x0f, 0xaa, 0x2e, 0x69, 0x8b, + 0x02, 0x5d, 0xf9, 0xcd, 0x38, 0x4c, 0xf7, 0x10, 0x0d, 0x21, 0x88, 0x99, 0x7a, 0x93, 0x74, 0x47, + 0x3a, 0x91, 0x56, 0xe9, 0xdf, 0x28, 0x03, 0xc9, 0x96, 0x5e, 0xbd, 0xa6, 0xd7, 0x71, 0x26, 0x42, + 0xc1, 0xa2, 0x88, 0x66, 0x01, 0x6a, 0xb8, 0x85, 0xcd, 0x1a, 0x36, 0xab, 0xbb, 0x99, 0xe8, 0x7c, + 0xf4, 0x44, 0x5a, 0xf5, 0x41, 0xd0, 0x03, 0x30, 0xd5, 0xea, 0x6c, 0x35, 0x8c, 0xaa, 0xe6, 0x43, + 0x83, 0xf9, 0xe8, 0x89, 0xb8, 0x2a, 0xb3, 0x8a, 0x82, 0x87, 0x7c, 0x1f, 0x4c, 0x3e, 0x8b, 0xf5, + 0x6b, 0x7e, 0xd4, 0x51, 0x8a, 0x3a, 0x41, 0xc0, 0x85, 0x00, 0x57, 0xab, 0xe5, 0x18, 0x96, 0xe9, + 0x47, 0x9d, 0xa4, 0x8d, 0xcb, 0xac, 0xc2, 0x87, 0xbc, 0x04, 0x63, 0x4d, 0x6c, 0xdb, 0x7a, 0x1d, + 0x6b, 0xce, 0x6e, 0x0b, 0x67, 0x62, 0x74, 0x9c, 0xe6, 0xbb, 0xc6, 0x29, 0x3c, 0x46, 0xa3, 0x9c, + 0xaa, 0xb2, 0xdb, 0xc2, 0x28, 0x07, 0x69, 0x6c, 0x76, 0x9a, 0x8c, 0x43, 0xbc, 0xcf, 0x48, 0x17, + 0xcd, 0x4e, 0x33, 0xcc, 0x25, 0x45, 0xc8, 0x38, 0x8b, 0xa4, 0x8d, 0xdb, 0xd7, 0x8d, 0x2a, 0xce, + 0x24, 0x28, 0x83, 0xfb, 0xba, 0x18, 0x94, 0x59, 0x7d, 0x98, 0x87, 0xa0, 0x43, 0x4b, 0x90, 0x76, + 0xc7, 0x3b, 0x93, 0xa4, 0x4c, 0xee, 0xed, 0x61, 0x6f, 0xb8, 0x51, 0x0b, 0xb3, 0xf0, 0xe8, 0xd0, + 0x79, 0x48, 0x32, 0x1d, 0xd9, 0x99, 0xd4, 0xbc, 0x74, 0x62, 0xf4, 0xec, 0xd1, 0x9e, 0x26, 0xbb, + 0xce, 0x70, 0x54, 0x81, 0x8c, 0x4a, 0x20, 0xdb, 0x56, 0xa7, 0x5d, 0xc5, 0x5a, 0xd5, 0xaa, 0x61, + 0xcd, 0x30, 0xb7, 0xad, 0x4c, 0x9a, 0x32, 0x98, 0xeb, 0xee, 0x08, 0x45, 0x5c, 0xb2, 0x6a, 0xb8, + 0x64, 0x6e, 0x5b, 0xea, 0x84, 0x1d, 0x28, 0xa3, 0x83, 0x90, 0xb0, 0x77, 0x4d, 0x47, 0xbf, 0x91, + 0x19, 0xa3, 0xe6, 0xc4, 0x4b, 0xe8, 0x2c, 0x24, 0x71, 0xcd, 0x20, 0xcd, 0x65, 0x26, 0xe6, 0xa5, + 0x13, 0x13, 0x67, 0x33, 0xdd, 0x3a, 0x66, 0xf5, 0xaa, 0x40, 0x54, 0xfe, 0x47, 0x02, 0x26, 0x87, + 0xb1, 0xe1, 0xc7, 0x20, 0xbe, 0x4d, 0x34, 0x93, 0x89, 0xec, 0x47, 0x6f, 0x8c, 0x26, 0xa8, 0xf8, + 0xc4, 0x6d, 0x2a, 0x3e, 0x07, 0xa3, 0x26, 0xb6, 0x1d, 0x5c, 0x63, 0x56, 0x14, 0x1d, 0xd2, 0x0e, + 0x81, 0x11, 0x75, 0x9b, 0x61, 0xec, 0xb6, 0xcc, 0xf0, 0x29, 0x98, 0x74, 0x45, 0xd2, 0xda, 0xba, + 0x59, 0x17, 0xf6, 0x7c, 0x7a, 0x90, 0x24, 0x0b, 0x6e, 0xf0, 0x50, 0x09, 0x99, 0x3a, 0x81, 0x03, + 0x65, 0x54, 0x00, 0xb0, 0x4c, 0x6c, 0x6d, 0x6b, 0x35, 0x5c, 0x6d, 0x64, 0x52, 0x7d, 0xb4, 0xb4, + 0x4e, 0x50, 0xba, 0xb4, 0x64, 0x31, 0x68, 0xb5, 0x81, 0x2e, 0x7a, 0xe6, 0x99, 0xec, 0x63, 0x5d, + 0xab, 0xcc, 0x31, 0xbb, 0x2c, 0x74, 0x13, 0x26, 0xda, 0x98, 0xf8, 0x0a, 0xae, 0xf1, 0x9e, 0xa5, + 0xa9, 0x10, 0x0b, 0x03, 0x7b, 0xa6, 0x72, 0x32, 0xd6, 0xb1, 0xf1, 0xb6, 0xbf, 0x88, 0xee, 0x06, + 0x17, 0xa0, 0x51, 0xb3, 0x02, 0x1a, 0x69, 0xc6, 0x04, 0x70, 0x8d, 0x98, 0x57, 0x0e, 0xe0, 0xba, + 0x61, 0x1b, 0x5b, 0x46, 0xc3, 0x70, 0x48, 0xd8, 0x22, 0xd6, 0x7b, 0x57, 0xb7, 0x5f, 0xec, 0x36, + 0xb7, 0xac, 0xc6, 0x55, 0x17, 0x51, 0xf5, 0x11, 0x65, 0x9f, 0x83, 0x89, 0xa0, 0x86, 0xd1, 0x0c, + 0xc4, 0x6d, 0x47, 0x6f, 0x3b, 0xd4, 0x90, 0xe3, 0x2a, 0x2b, 0x20, 0x19, 0xa2, 0xd8, 0xac, 0xd1, + 0x48, 0x1c, 0x57, 0xc9, 0x9f, 0xe8, 0x7b, 0x3d, 0x9d, 0x45, 0xa9, 0xce, 0x8e, 0x77, 0x1b, 0x45, + 0x80, 0x73, 0x58, 0x75, 0xd9, 0x47, 0x61, 0x3c, 0xa0, 0x83, 0x61, 0x9b, 0x56, 0x7e, 0x37, 0x06, + 0x07, 0x7a, 0xf2, 0x46, 0x4f, 0xc1, 0x4c, 0xc7, 0x34, 0x4c, 0x07, 0xb7, 0x5b, 0x6d, 0x4c, 0xac, + 0x9e, 0xb5, 0x95, 0xf9, 0x6a, 0xb2, 0x8f, 0xdd, 0x6e, 0xfa, 0xb1, 0x19, 0x17, 0x75, 0xba, 0xd3, + 0x0d, 0x44, 0x4f, 0xc3, 0x28, 0x31, 0x31, 0xbd, 0xad, 0x53, 0x86, 0xcc, 0xa1, 0xcf, 0x0e, 0xd7, + 0xe5, 0x85, 0x82, 0x47, 0x99, 0x8f, 0xbe, 0x20, 0x45, 0x54, 0x3f, 0x2f, 0xf4, 0x28, 0xa4, 0xb6, + 0xb1, 0xee, 0x74, 0xda, 0xd8, 0xce, 0x9c, 0xa5, 0xaa, 0x3c, 0xd2, 0xed, 0xe7, 0x0c, 0xa1, 0x8c, + 0x1d, 0xd5, 0x45, 0x46, 0x4d, 0x18, 0xbb, 0x8e, 0xdb, 0xc6, 0xb6, 0x51, 0x65, 0x42, 0x45, 0xa9, + 0x05, 0x5c, 0x18, 0x52, 0xa8, 0xab, 0x3e, 0xd2, 0xb2, 0xa3, 0x3b, 0x78, 0x11, 0x36, 0xd7, 0xae, + 0x16, 0xd5, 0xd2, 0xa5, 0x52, 0xb1, 0xc0, 0xc4, 0x0c, 0xb0, 0xcf, 0xfe, 0xa8, 0x04, 0xa3, 0xbe, + 0x9e, 0x90, 0x88, 0x6a, 0x76, 0x9a, 0x5b, 0xb8, 0xcd, 0xc7, 0x8b, 0x97, 0xd0, 0x11, 0x48, 0x6f, + 0x77, 0x1a, 0x0d, 0x66, 0xb7, 0x6c, 0xee, 0x4e, 0x11, 0x00, 0xb5, 0x59, 0x04, 0x31, 0x1e, 0x89, + 0x68, 0x98, 0x24, 0x7f, 0xa3, 0x2c, 0xa4, 0x84, 0x5d, 0x67, 0xe2, 0xf3, 0xd2, 0x89, 0x94, 0xea, + 0x96, 0x59, 0x5d, 0x0b, 0xeb, 0x0e, 0xae, 0x65, 0x12, 0xa2, 0x8e, 0x95, 0xaf, 0xc4, 0x52, 0x31, + 0x39, 0xae, 0x3c, 0x02, 0x53, 0x5d, 0x5d, 0x41, 0x93, 0x30, 0x5a, 0x28, 0x2e, 0xad, 0xe4, 0xd4, + 0x5c, 0xa5, 0xb4, 0xbe, 0x26, 0x8f, 0xa0, 0x09, 0xf0, 0xf5, 0x4e, 0x96, 0x4e, 0xa6, 0x53, 0xaf, + 0x26, 0xe5, 0xe7, 0x9f, 0x7f, 0xfe, 0xf9, 0x88, 0xf2, 0x1b, 0x09, 0x98, 0xe9, 0x15, 0x47, 0x7b, + 0x86, 0x74, 0xaf, 0xd3, 0xd1, 0x40, 0xa7, 0x73, 0x10, 0x6f, 0xe8, 0x5b, 0xb8, 0x91, 0x89, 0xd1, + 0x41, 0x78, 0x60, 0xa8, 0x48, 0xbd, 0xb0, 0x42, 0x48, 0x54, 0x46, 0x89, 0xde, 0xca, 0x55, 0x13, + 0xa7, 0x1c, 0x4e, 0x0e, 0xc7, 0x81, 0xc4, 0x57, 0xae, 0xc6, 0x23, 0x90, 0x26, 0xff, 0x33, 0xbd, + 0x27, 0x98, 0xde, 0x09, 0x80, 0xea, 0x3d, 0x0b, 0x29, 0x1a, 0x3a, 0x6b, 0xd8, 0x1d, 0x13, 0x51, + 0x26, 0xc1, 0xa6, 0x86, 0xb7, 0xf5, 0x4e, 0xc3, 0xd1, 0xae, 0xeb, 0x8d, 0x0e, 0xa6, 0x41, 0x30, + 0xad, 0x8e, 0x71, 0xe0, 0x55, 0x02, 0x43, 0x73, 0x30, 0xca, 0x22, 0xad, 0x61, 0xd6, 0xf0, 0x0d, + 0x3a, 0x0b, 0xc7, 0x55, 0x16, 0x7c, 0x4b, 0x04, 0x42, 0x9a, 0x7f, 0xc6, 0xb6, 0x4c, 0x11, 0xae, + 0x68, 0x13, 0x04, 0x40, 0x9b, 0x7f, 0x34, 0x9c, 0x00, 0x1c, 0xeb, 0xdd, 0xbd, 0xae, 0xf8, 0x7a, + 0x1f, 0x4c, 0x52, 0x8c, 0x87, 0xb9, 0x2b, 0xeb, 0x8d, 0xcc, 0x14, 0x35, 0x83, 0x09, 0x06, 0x5e, + 0xe7, 0x50, 0xe5, 0x57, 0x22, 0x10, 0xa3, 0x93, 0xcd, 0x24, 0x8c, 0x56, 0x9e, 0xde, 0x28, 0x6a, + 0x85, 0xf5, 0xcd, 0xfc, 0x4a, 0x51, 0x96, 0xc8, 0xd0, 0x53, 0xc0, 0xa5, 0x95, 0xf5, 0x5c, 0x45, + 0x8e, 0xb8, 0xe5, 0xd2, 0x5a, 0xe5, 0xfc, 0x23, 0x72, 0xd4, 0x25, 0xd8, 0x64, 0x80, 0x98, 0x1f, + 0xe1, 0xe1, 0xb3, 0x72, 0x1c, 0xc9, 0x30, 0xc6, 0x18, 0x94, 0x9e, 0x2a, 0x16, 0xce, 0x3f, 0x22, + 0x27, 0x82, 0x90, 0x87, 0xcf, 0xca, 0x49, 0x34, 0x0e, 0x69, 0x0a, 0xc9, 0xaf, 0xaf, 0xaf, 0xc8, + 0x29, 0x97, 0x67, 0xb9, 0xa2, 0x96, 0xd6, 0x96, 0xe5, 0xb4, 0xcb, 0x73, 0x59, 0x5d, 0xdf, 0xdc, + 0x90, 0xc1, 0xe5, 0xb0, 0x5a, 0x2c, 0x97, 0x73, 0xcb, 0x45, 0x79, 0xd4, 0xc5, 0xc8, 0x3f, 0x5d, + 0x29, 0x96, 0xe5, 0xb1, 0x80, 0x58, 0x0f, 0x9f, 0x95, 0xc7, 0xdd, 0x26, 0x8a, 0x6b, 0x9b, 0xab, + 0xf2, 0x04, 0x9a, 0x82, 0x71, 0xd6, 0x84, 0x10, 0x62, 0x32, 0x04, 0x3a, 0xff, 0x88, 0x2c, 0x7b, + 0x82, 0x30, 0x2e, 0x53, 0x01, 0xc0, 0xf9, 0x47, 0x64, 0xa4, 0x2c, 0x41, 0x9c, 0x9a, 0x21, 0x42, + 0x30, 0xb1, 0x92, 0xcb, 0x17, 0x57, 0xb4, 0xf5, 0x0d, 0xe2, 0x34, 0xb9, 0x15, 0x59, 0xf2, 0x60, + 0x6a, 0x71, 0xa3, 0x98, 0xab, 0x14, 0x0b, 0x72, 0xd4, 0x0f, 0x7b, 0xdb, 0x66, 0x49, 0x2d, 0x16, + 0xe4, 0x88, 0x52, 0x85, 0x99, 0x5e, 0x93, 0x6c, 0x4f, 0x17, 0xf2, 0xd9, 0x42, 0xa4, 0x8f, 0x2d, + 0x50, 0x5e, 0x61, 0x5b, 0x50, 0x7e, 0x26, 0x0a, 0xd3, 0x3d, 0x12, 0x8d, 0x9e, 0x8d, 0x3c, 0x0e, + 0x71, 0x66, 0xcb, 0x2c, 0x52, 0xdf, 0xdf, 0x33, 0x63, 0xa1, 0x96, 0xdd, 0x95, 0x7e, 0x51, 0x3a, + 0x7f, 0xca, 0x1a, 0xed, 0x93, 0xb2, 0x12, 0x16, 0x5d, 0x06, 0xfb, 0xfd, 0x5d, 0x09, 0x01, 0xcb, + 0x99, 0xce, 0x0f, 0x93, 0x33, 0x51, 0xd8, 0xfe, 0x12, 0x83, 0xf8, 0xc0, 0xc4, 0x20, 0x71, 0x3b, + 0x89, 0xc1, 0x63, 0x30, 0xd5, 0x25, 0xcb, 0xd0, 0x13, 0xf4, 0x0f, 0x4b, 0x90, 0xe9, 0xa7, 0xdf, + 0x01, 0x51, 0x35, 0x12, 0x88, 0xaa, 0x8f, 0x85, 0x07, 0xe1, 0xae, 0xfe, 0xe3, 0xd8, 0x65, 0x2e, + 0x9f, 0x96, 0xe0, 0x60, 0xef, 0xd5, 0x4d, 0x4f, 0x19, 0xde, 0x0a, 0x89, 0x26, 0x76, 0x76, 0x2c, + 0x91, 0xad, 0x1f, 0xef, 0x91, 0x03, 0x92, 0xea, 0xb0, 0xbd, 0x70, 0x2a, 0x7f, 0x12, 0x19, 0xed, + 0xb7, 0x44, 0x61, 0xd2, 0x74, 0x49, 0xfa, 0xfe, 0x08, 0x1c, 0xe8, 0xc9, 0xbc, 0xa7, 0xa0, 0xc7, + 0x00, 0x0c, 0xb3, 0xd5, 0x71, 0x58, 0x46, 0xce, 0x82, 0x79, 0x9a, 0x42, 0x68, 0xfc, 0x23, 0x81, + 0xba, 0xe3, 0xb8, 0xf5, 0x6c, 0xa2, 0x05, 0x06, 0xa2, 0x08, 0x17, 0x3c, 0x41, 0x63, 0x54, 0xd0, + 0xd9, 0x3e, 0x3d, 0xed, 0xb2, 0xed, 0x87, 0x40, 0xae, 0x36, 0x0c, 0x6c, 0x3a, 0x9a, 0xed, 0xb4, + 0xb1, 0xde, 0x34, 0xcc, 0x3a, 0x9b, 0xb0, 0x17, 0xe3, 0xdb, 0x7a, 0xc3, 0xc6, 0xea, 0x24, 0xab, + 0x2e, 0x8b, 0x5a, 0x42, 0x41, 0x0d, 0xa8, 0xed, 0xa3, 0x48, 0x04, 0x28, 0x58, 0xb5, 0x4b, 0xa1, + 0xfc, 0x7c, 0x1a, 0x46, 0x7d, 0x6b, 0x41, 0x74, 0x17, 0x8c, 0x3d, 0xa3, 0x5f, 0xd7, 0x35, 0xb1, + 0x19, 0xc0, 0x34, 0x31, 0x4a, 0x60, 0x1b, 0x7c, 0x43, 0xe0, 0x21, 0x98, 0xa1, 0x28, 0x56, 0xc7, + 0xc1, 0x6d, 0xad, 0xda, 0xd0, 0x6d, 0x9b, 0x2a, 0x2d, 0x45, 0x51, 0x11, 0xa9, 0x5b, 0x27, 0x55, + 0x4b, 0xa2, 0x06, 0x9d, 0x83, 0x69, 0x4a, 0xd1, 0xec, 0x34, 0x1c, 0xa3, 0xd5, 0xc0, 0x74, 0x9b, + 0xc3, 0xa6, 0xb3, 0x96, 0x2b, 0xd9, 0x14, 0xc1, 0x58, 0xe5, 0x08, 0x44, 0x22, 0x1b, 0x15, 0xe0, + 0x18, 0x25, 0xab, 0x63, 0x13, 0xb7, 0x75, 0x07, 0x6b, 0xf8, 0x9d, 0x1d, 0xbd, 0x61, 0x6b, 0xba, + 0x59, 0xd3, 0x76, 0x74, 0x7b, 0x27, 0x33, 0x43, 0x18, 0xe4, 0x23, 0x19, 0x49, 0x3d, 0x4c, 0x10, + 0x97, 0x39, 0x5e, 0x91, 0xa2, 0xe5, 0xcc, 0xda, 0x65, 0xdd, 0xde, 0x41, 0x8b, 0x70, 0x90, 0x72, + 0xb1, 0x9d, 0xb6, 0x61, 0xd6, 0xb5, 0xea, 0x0e, 0xae, 0x5e, 0xd3, 0x3a, 0xce, 0xf6, 0x85, 0xcc, + 0x11, 0x7f, 0xfb, 0x54, 0xc2, 0x32, 0xc5, 0x59, 0x22, 0x28, 0x9b, 0xce, 0xf6, 0x05, 0x54, 0x86, + 0x31, 0x32, 0x18, 0x4d, 0xe3, 0x39, 0xac, 0x6d, 0x5b, 0x6d, 0x3a, 0x0d, 0x4f, 0xf4, 0x88, 0x6e, + 0x3e, 0x0d, 0x2e, 0xac, 0x73, 0x82, 0x55, 0xab, 0x86, 0x17, 0xe3, 0xe5, 0x8d, 0x62, 0xb1, 0xa0, + 0x8e, 0x0a, 0x2e, 0x97, 0xac, 0x36, 0x31, 0xa8, 0xba, 0xe5, 0x2a, 0x78, 0x94, 0x19, 0x54, 0xdd, + 0x12, 0xea, 0x3d, 0x07, 0xd3, 0xd5, 0x2a, 0xeb, 0xb3, 0x51, 0xd5, 0xf8, 0xbe, 0x80, 0x9d, 0x91, + 0x03, 0xca, 0xaa, 0x56, 0x97, 0x19, 0x02, 0xb7, 0x71, 0x1b, 0x5d, 0x84, 0x03, 0x9e, 0xb2, 0xfc, + 0x84, 0x53, 0x5d, 0xbd, 0x0c, 0x93, 0x9e, 0x83, 0xe9, 0xd6, 0x6e, 0x37, 0x21, 0x0a, 0xb4, 0xd8, + 0xda, 0x0d, 0x93, 0xdd, 0x4b, 0x37, 0x86, 0xda, 0xb8, 0x4a, 0xb3, 0xc5, 0x43, 0x7e, 0x6c, 0x5f, + 0x05, 0x5a, 0x00, 0xb9, 0x5a, 0xd5, 0xb0, 0xa9, 0x6f, 0x35, 0xb0, 0xa6, 0xb7, 0xb1, 0xa9, 0xdb, + 0x99, 0x39, 0x8a, 0x1c, 0x73, 0xda, 0x1d, 0xac, 0x4e, 0x54, 0xab, 0x45, 0x5a, 0x99, 0xa3, 0x75, + 0xe8, 0x24, 0x4c, 0x59, 0x5b, 0xcf, 0x54, 0x99, 0x61, 0x69, 0xad, 0x36, 0xde, 0x36, 0x6e, 0x64, + 0xee, 0xa1, 0x5a, 0x9a, 0x24, 0x15, 0xd4, 0xac, 0x36, 0x28, 0x18, 0xdd, 0x0f, 0x72, 0xd5, 0xde, + 0xd1, 0xdb, 0x2d, 0x1a, 0x9c, 0xed, 0x96, 0x5e, 0xc5, 0x99, 0x7b, 0x19, 0x2a, 0x83, 0xaf, 0x09, + 0x30, 0x31, 0x6c, 0xfb, 0x59, 0x63, 0xdb, 0x11, 0x1c, 0xef, 0x63, 0x86, 0x4d, 0x61, 0x9c, 0xdb, + 0x09, 0x90, 0x5b, 0x3b, 0xad, 0x60, 0xc3, 0x27, 0x28, 0xda, 0x44, 0x6b, 0xa7, 0xe5, 0x6f, 0xf7, + 0x6e, 0x18, 0x27, 0x98, 0x5e, 0xa3, 0xf7, 0xb3, 0x14, 0xae, 0xb5, 0xe3, 0x6b, 0xf1, 0x11, 0x38, + 0x48, 0x90, 0x9a, 0xd8, 0xd1, 0x6b, 0xba, 0xa3, 0xfb, 0xb0, 0x1f, 0xa4, 0xd8, 0x33, 0xad, 0x9d, + 0xd6, 0x2a, 0xaf, 0x0c, 0xc8, 0xd9, 0xee, 0x6c, 0xed, 0xba, 0xf6, 0x71, 0x8a, 0xc9, 0x49, 0x60, + 0xc2, 0x42, 0x6e, 0x7b, 0x05, 0xf3, 0x86, 0xad, 0xd7, 0x94, 0x45, 0x18, 0xf3, 0xdb, 0x3d, 0x4a, + 0x03, 0xb3, 0x7c, 0x59, 0x22, 0x79, 0xd4, 0xd2, 0x7a, 0x81, 0x64, 0x40, 0x6f, 0x2f, 0xca, 0x11, + 0x92, 0x89, 0xad, 0x94, 0x2a, 0x45, 0x4d, 0xdd, 0x5c, 0xab, 0x94, 0x56, 0x8b, 0x72, 0xd4, 0xb7, + 0x36, 0xb8, 0x12, 0x4b, 0x9d, 0x94, 0x1f, 0xb8, 0x12, 0x4b, 0x1d, 0x97, 0xef, 0xa3, 0xea, 0xe9, + 0x32, 0x4a, 0xe5, 0x5b, 0x51, 0x98, 0x08, 0x6e, 0x0e, 0xa0, 0xb7, 0xc0, 0x21, 0xb1, 0xfb, 0x67, + 0x63, 0x47, 0x7b, 0xd6, 0x68, 0x53, 0x67, 0x6d, 0xea, 0x6c, 0xe2, 0x74, 0x8d, 0x72, 0x86, 0x63, + 0x95, 0xb1, 0xf3, 0xa4, 0xd1, 0x26, 0xae, 0xd8, 0xd4, 0x1d, 0xb4, 0x02, 0x73, 0xa6, 0xa5, 0xd9, + 0x8e, 0x6e, 0xd6, 0xf4, 0x76, 0xcd, 0xbf, 0xf7, 0xaa, 0x57, 0xab, 0xd8, 0xb6, 0x2d, 0x36, 0x49, + 0xba, 0x5c, 0x8e, 0x9a, 0x56, 0x99, 0x23, 0x7b, 0xb3, 0x47, 0x8e, 0xa3, 0x86, 0x7c, 0x22, 0xda, + 0xcf, 0x27, 0x8e, 0x40, 0xba, 0xa9, 0xb7, 0x34, 0x6c, 0x3a, 0xed, 0x5d, 0x9a, 0xfe, 0xa7, 0xd4, + 0x54, 0x53, 0x6f, 0x15, 0x49, 0x19, 0x5d, 0x85, 0xe3, 0x1e, 0xaa, 0xd6, 0xc0, 0x75, 0xbd, 0xba, + 0xab, 0xd1, 0x5c, 0x9f, 0xee, 0x54, 0x69, 0x55, 0xcb, 0xdc, 0x6e, 0x18, 0x55, 0xc7, 0xa6, 0xb1, + 0x83, 0xc5, 0x3f, 0xc5, 0xa3, 0x58, 0xa1, 0x04, 0x57, 0x6c, 0xcb, 0xa4, 0x29, 0xfe, 0x92, 0xc0, + 0x0e, 0x98, 0xcd, 0xd8, 0x9b, 0xc2, 0x6c, 0x82, 0x43, 0x1f, 0x93, 0xe3, 0x57, 0x62, 0xa9, 0xb8, + 0x9c, 0xb8, 0x12, 0x4b, 0x25, 0xe4, 0xe4, 0x95, 0x58, 0x2a, 0x25, 0xa7, 0xaf, 0xc4, 0x52, 0x69, + 0x19, 0x94, 0x9b, 0xe3, 0x30, 0xe6, 0x5f, 0xb1, 0x90, 0x05, 0x60, 0x95, 0x4e, 0xb8, 0x12, 0x0d, + 0xc9, 0x77, 0xef, 0xb9, 0xbe, 0x59, 0x58, 0x22, 0x33, 0xf1, 0x62, 0x82, 0x2d, 0x0f, 0x54, 0x46, + 0x49, 0xb2, 0x20, 0xe2, 0x64, 0x98, 0xe5, 0x52, 0x29, 0x95, 0x97, 0xd0, 0x32, 0x24, 0x9e, 0xb1, + 0x29, 0x6f, 0x96, 0xca, 0xdd, 0xb3, 0x37, 0xef, 0x2b, 0x65, 0xca, 0x3c, 0x7d, 0xa5, 0xac, 0xad, + 0xad, 0xab, 0xab, 0xb9, 0x15, 0x95, 0x93, 0xa3, 0xc3, 0x10, 0x6b, 0xe8, 0xcf, 0xed, 0x06, 0xe7, + 0x6c, 0x0a, 0x42, 0x0b, 0x30, 0xd9, 0x31, 0xd9, 0x72, 0x9f, 0x8c, 0x31, 0xc1, 0x9a, 0xf4, 0x63, + 0x4d, 0x78, 0xb5, 0x2b, 0x04, 0x7f, 0x48, 0xbb, 0x3a, 0x0c, 0xb1, 0x67, 0xb1, 0x7e, 0x2d, 0x38, + 0xb3, 0x52, 0x10, 0x3a, 0x01, 0x63, 0x35, 0xbc, 0xd5, 0xa9, 0x6b, 0x6d, 0x5c, 0xd3, 0xab, 0x4e, + 0x70, 0x3e, 0x19, 0xa5, 0x55, 0x2a, 0xad, 0x41, 0x4f, 0x40, 0x9a, 0x8c, 0x91, 0x49, 0xc7, 0x78, + 0x8a, 0xaa, 0xe0, 0xd4, 0xde, 0x2a, 0xe0, 0x43, 0x2c, 0x88, 0x54, 0x8f, 0x1e, 0x5d, 0x86, 0xa4, + 0xa3, 0xb7, 0xeb, 0xd8, 0xb1, 0x33, 0xd3, 0xf3, 0xd1, 0x13, 0x13, 0x3d, 0x76, 0xea, 0x7a, 0xb0, + 0xaa, 0x50, 0x12, 0xba, 0xd8, 0x16, 0xe4, 0xe8, 0x49, 0x90, 0xf9, 0x86, 0xb0, 0xc6, 0x57, 0xca, + 0x76, 0x66, 0x86, 0x1a, 0xe0, 0x83, 0x7b, 0xb3, 0xe4, 0xfb, 0xc9, 0x05, 0x46, 0xa4, 0x4e, 0xe2, + 0x40, 0x39, 0xe8, 0x17, 0x07, 0xf6, 0xe3, 0x17, 0x9b, 0x30, 0xc9, 0xff, 0xd6, 0xec, 0x4e, 0xab, + 0x65, 0xb5, 0x9d, 0xcc, 0x41, 0x4a, 0x3f, 0x40, 0x20, 0xc1, 0x8c, 0xd1, 0xa8, 0x13, 0xdb, 0x81, + 0xf2, 0x1b, 0xe7, 0x6e, 0xd9, 0xb7, 0xc3, 0x44, 0x50, 0x19, 0xfe, 0xed, 0xf8, 0xe8, 0x90, 0xdb, + 0xf1, 0x64, 0x59, 0x22, 0xd6, 0x7a, 0x64, 0x6a, 0x62, 0x85, 0xec, 0x8f, 0x45, 0x60, 0x22, 0xd8, + 0x31, 0xb4, 0x0c, 0x48, 0x8c, 0x98, 0x61, 0x3a, 0x6d, 0xab, 0xd6, 0xa9, 0xe2, 0x1a, 0x77, 0xd8, + 0xfe, 0xed, 0x4c, 0x71, 0x9a, 0x92, 0x4b, 0xe2, 0x67, 0xe4, 0xf3, 0x82, 0xc8, 0x90, 0x8c, 0x0a, + 0x9e, 0x7f, 0x9c, 0x86, 0x69, 0xc1, 0x80, 0x30, 0x7b, 0x56, 0x6f, 0x9b, 0x24, 0x45, 0x66, 0x49, + 0x3b, 0xf2, 0x55, 0x3d, 0xc9, 0x6a, 0x50, 0x0e, 0x84, 0xb9, 0x68, 0x6d, 0xdc, 0xb4, 0xae, 0xe3, + 0x1a, 0xdf, 0x71, 0xea, 0xdf, 0xec, 0x04, 0x27, 0x50, 0x19, 0xbe, 0x72, 0x1a, 0xe2, 0x34, 0xfc, + 0x20, 0x00, 0x1e, 0x80, 0xe4, 0x11, 0x94, 0x82, 0xd8, 0xd2, 0xba, 0x4a, 0xa6, 0x47, 0x19, 0xc6, + 0x18, 0x54, 0xdb, 0x28, 0x15, 0x97, 0x8a, 0x72, 0x44, 0x39, 0x07, 0x09, 0x16, 0x53, 0xc8, 0xd4, + 0xe9, 0x46, 0x15, 0x79, 0x84, 0x17, 0x39, 0x0f, 0x49, 0xd4, 0x6e, 0xae, 0xe6, 0x8b, 0xaa, 0x1c, + 0x51, 0x36, 0x61, 0x32, 0xe4, 0x87, 0xe8, 0x00, 0x4c, 0xa9, 0xc5, 0x4a, 0x71, 0xad, 0x52, 0x5a, + 0x5f, 0xd3, 0x36, 0xd7, 0x9e, 0x58, 0x5b, 0x7f, 0x72, 0x4d, 0x1e, 0x09, 0x82, 0xc5, 0x3c, 0x2c, + 0xa1, 0x19, 0x90, 0x3d, 0x70, 0x79, 0x7d, 0x53, 0xa5, 0xd2, 0xfc, 0xbf, 0x11, 0x90, 0xc3, 0x4e, + 0x89, 0x0e, 0xc1, 0x74, 0x25, 0xa7, 0x2e, 0x17, 0x2b, 0x1a, 0xdb, 0x33, 0x71, 0x59, 0xcf, 0x80, + 0xec, 0xaf, 0xb8, 0x54, 0xa2, 0x5b, 0x42, 0x73, 0x70, 0xc4, 0x0f, 0x2d, 0x3e, 0x55, 0x29, 0xae, + 0x95, 0x69, 0xe3, 0xb9, 0xb5, 0x65, 0x92, 0x14, 0x84, 0xf8, 0x89, 0x5d, 0x9a, 0x28, 0x11, 0x35, + 0xc8, 0xaf, 0xb8, 0x52, 0x90, 0x63, 0x61, 0xf0, 0xfa, 0x5a, 0x71, 0xfd, 0x92, 0x1c, 0x0f, 0xb7, + 0x4e, 0x77, 0x6e, 0x12, 0x28, 0x0b, 0x07, 0xc3, 0x50, 0xad, 0xb8, 0x56, 0x51, 0x9f, 0x96, 0x93, + 0xe1, 0x86, 0xcb, 0x45, 0xf5, 0x6a, 0x69, 0xa9, 0x28, 0xa7, 0xd0, 0x41, 0x40, 0x41, 0x89, 0x2a, + 0x97, 0xd7, 0x0b, 0x72, 0xba, 0xd7, 0x8c, 0x85, 0xe4, 0x69, 0xe5, 0xb3, 0x12, 0x8c, 0xf9, 0x77, + 0x51, 0x02, 0x41, 0x45, 0x7a, 0xb3, 0x4d, 0xb6, 0xca, 0x97, 0x22, 0x30, 0xea, 0xdb, 0x4e, 0x21, + 0x8b, 0x58, 0xbd, 0xd1, 0xb0, 0x9e, 0xd5, 0xf4, 0x86, 0xa1, 0xdb, 0x7c, 0x3e, 0x04, 0x0a, 0xca, + 0x11, 0xc8, 0xb0, 0xf3, 0xcf, 0xf0, 0xa9, 0x4b, 0xe2, 0xb6, 0x53, 0x97, 0xe4, 0x9b, 0x30, 0x75, + 0x89, 0xcb, 0x09, 0xe5, 0x0f, 0x22, 0x20, 0x87, 0x77, 0x47, 0x42, 0x7a, 0x93, 0xfa, 0xe9, 0xcd, + 0xdf, 0xbf, 0xc8, 0x7e, 0xfa, 0x17, 0x9e, 0xd5, 0xa3, 0x7d, 0x67, 0xf5, 0x1e, 0x93, 0x55, 0xec, + 0xcd, 0x3c, 0x59, 0xf9, 0xcd, 0xf5, 0x5f, 0x4b, 0x30, 0x11, 0xdc, 0xcc, 0x09, 0x68, 0x4c, 0xd9, + 0x8f, 0xc6, 0x82, 0x23, 0x72, 0x57, 0xbf, 0x11, 0xf9, 0xae, 0xf4, 0xeb, 0xa3, 0x51, 0x18, 0x0f, + 0xec, 0xfd, 0x0c, 0x2b, 0xdd, 0x3b, 0x61, 0xca, 0xa8, 0xe1, 0x66, 0xcb, 0x72, 0xb0, 0x59, 0xdd, + 0xd5, 0x1a, 0xf8, 0x3a, 0x6e, 0x50, 0x35, 0x4c, 0xf4, 0x38, 0xe3, 0x0d, 0xb4, 0xb0, 0x50, 0xf2, + 0xe8, 0x56, 0x08, 0xd9, 0xe2, 0x74, 0xa9, 0x50, 0x5c, 0xdd, 0x58, 0xaf, 0x14, 0xd7, 0x96, 0x9e, + 0x16, 0x91, 0x5c, 0x95, 0x8d, 0x10, 0x5a, 0x40, 0xe1, 0x77, 0xbf, 0x39, 0x16, 0x9d, 0x1b, 0x20, + 0x87, 0x7b, 0x43, 0x02, 0x7a, 0x8f, 0xfe, 0xc8, 0x23, 0x68, 0x1a, 0x26, 0xd7, 0xd6, 0xb5, 0x72, + 0xa9, 0x50, 0xd4, 0x8a, 0x97, 0x2e, 0x15, 0x97, 0x2a, 0x65, 0x76, 0x56, 0xe1, 0x62, 0x57, 0xe4, + 0x88, 0x7f, 0x6c, 0x3e, 0x16, 0x85, 0xe9, 0x1e, 0x92, 0xa0, 0x1c, 0xdf, 0x22, 0x64, 0xbb, 0x96, + 0xa7, 0x86, 0x91, 0x7e, 0x81, 0xac, 0xee, 0x37, 0xf4, 0xb6, 0xc3, 0x77, 0x14, 0xef, 0x07, 0xa2, + 0x5e, 0xd3, 0x21, 0xe9, 0x7d, 0x9b, 0x9f, 0x01, 0xb1, 0x14, 0x64, 0xd2, 0x83, 0xb3, 0x63, 0xa0, + 0x07, 0x01, 0xb5, 0x2c, 0xdb, 0x70, 0x8c, 0xeb, 0x98, 0xe4, 0x50, 0x1c, 0x99, 0x38, 0x6e, 0x4c, + 0x95, 0x45, 0x4d, 0xc9, 0x74, 0x5c, 0x6c, 0x13, 0xd7, 0xf5, 0x10, 0x36, 0x59, 0x7e, 0x44, 0x55, + 0x59, 0xd4, 0xb8, 0xd8, 0x77, 0xc1, 0x58, 0xcd, 0xea, 0x6c, 0x35, 0x30, 0xc7, 0x23, 0x21, 0x59, + 0x52, 0x47, 0x19, 0xcc, 0x45, 0xe1, 0xdb, 0x66, 0xde, 0x49, 0xd5, 0x98, 0x3a, 0xca, 0x60, 0x0c, + 0xe5, 0x3e, 0x98, 0xd4, 0xeb, 0xf5, 0x36, 0x61, 0x2e, 0x18, 0xb1, 0x8d, 0xc0, 0x09, 0x17, 0x4c, + 0x11, 0xb3, 0x57, 0x20, 0x25, 0xf4, 0x40, 0xd6, 0xbf, 0x44, 0x13, 0x5a, 0x8b, 0xed, 0x6e, 0x47, + 0x4e, 0xa4, 0xd5, 0x94, 0x29, 0x2a, 0xef, 0x82, 0x31, 0xc3, 0xf6, 0x6e, 0x3d, 0x65, 0x22, 0xf3, + 0x91, 0x13, 0x29, 0x75, 0xd4, 0xb0, 0xbd, 0x9b, 0x4d, 0xbf, 0x2a, 0x03, 0x78, 0xc6, 0x86, 0x3e, + 0x2c, 0xc1, 0x04, 0x9b, 0x60, 0x5a, 0x6d, 0x6c, 0x63, 0xb3, 0x2a, 0x96, 0x85, 0xf7, 0xef, 0x61, + 0xa2, 0x2c, 0xcc, 0x6d, 0x70, 0x82, 0xfc, 0xe3, 0x2f, 0x48, 0xd2, 0x4b, 0x52, 0xec, 0x25, 0x49, + 0xfa, 0xa4, 0x34, 0x8e, 0x52, 0xc5, 0xa7, 0x36, 0x56, 0x4a, 0x4b, 0xa5, 0x4a, 0xe6, 0xbd, 0x49, + 0x5a, 0x2e, 0xad, 0xf2, 0xf2, 0x57, 0x93, 0xc1, 0xfa, 0x57, 0x93, 0xbf, 0x24, 0x45, 0x53, 0xaf, + 0x26, 0xd5, 0xf1, 0x6d, 0x3f, 0x3f, 0xd4, 0xf0, 0xdf, 0xe3, 0x88, 0xf4, 0x5b, 0x48, 0x7a, 0xd2, + 0x14, 0xf9, 0xed, 0x8d, 0xfc, 0xfd, 0x54, 0x90, 0x04, 0x15, 0x64, 0x14, 0x25, 0x96, 0x56, 0xd6, + 0xcb, 0xc5, 0x02, 0x15, 0x23, 0x8d, 0x62, 0xeb, 0x1b, 0xc5, 0xb5, 0xcc, 0x57, 0x45, 0x93, 0xde, + 0x95, 0x8f, 0x97, 0x24, 0x38, 0x24, 0x0e, 0x6a, 0xf9, 0x5c, 0x8b, 0xcd, 0xaa, 0x55, 0x13, 0xd9, + 0xed, 0xc4, 0xd9, 0x33, 0x7b, 0x35, 0xae, 0x72, 0x52, 0xaa, 0x92, 0x22, 0x27, 0xcc, 0x9f, 0xea, + 0x52, 0x49, 0x6e, 0xad, 0xc0, 0x65, 0x19, 0x45, 0x89, 0x8d, 0xdc, 0xd2, 0x13, 0xc5, 0x82, 0x27, + 0xcd, 0x81, 0x76, 0x2f, 0x2e, 0xe8, 0x87, 0x60, 0xb2, 0xe3, 0x6c, 0x5f, 0x20, 0xb6, 0x61, 0xd4, + 0xd8, 0xc9, 0x79, 0xac, 0xdf, 0x91, 0xab, 0x27, 0xd1, 0xa6, 0xb3, 0x7d, 0xe1, 0xaa, 0x4b, 0xc1, + 0x95, 0xc2, 0x44, 0x49, 0xa3, 0xd8, 0xda, 0xfa, 0x5a, 0x51, 0x88, 0x41, 0x4f, 0x99, 0x9f, 0xf6, + 0xc4, 0x98, 0xe8, 0x04, 0x48, 0xd1, 0x0f, 0x81, 0x2c, 0xb6, 0x87, 0x5c, 0x95, 0xc4, 0xfb, 0x9d, + 0x1a, 0x7b, 0x02, 0xf0, 0x4d, 0x26, 0x57, 0x19, 0xc7, 0x7d, 0x12, 0xcc, 0xa0, 0xc9, 0x95, 0xe2, + 0xda, 0x72, 0xe5, 0xb2, 0xb6, 0xa1, 0x16, 0xe9, 0xe1, 0x5f, 0xe6, 0xbd, 0xa2, 0xf9, 0xc9, 0x66, + 0x90, 0x10, 0xbd, 0x47, 0x82, 0x51, 0x96, 0x02, 0xb1, 0x3d, 0x29, 0xb6, 0xa9, 0x70, 0x7c, 0xaf, + 0xb6, 0x69, 0x06, 0x44, 0xb1, 0xf3, 0x17, 0x69, 0xb3, 0x51, 0x61, 0x10, 0x87, 0x10, 0x5a, 0x29, + 0x2e, 0xe7, 0x96, 0x9e, 0xd6, 0xf2, 0xc5, 0x72, 0x85, 0x44, 0xb2, 0x75, 0x95, 0xd9, 0x28, 0xa0, + 0x78, 0x6e, 0x65, 0x65, 0xfd, 0x49, 0x4f, 0x11, 0xf0, 0x8c, 0xcb, 0x06, 0xfd, 0x9c, 0x04, 0x33, + 0xd8, 0xdc, 0xb6, 0xda, 0x55, 0x7a, 0x60, 0x4d, 0x3c, 0xda, 0x76, 0x76, 0x1b, 0xcc, 0xa3, 0x7b, + 0x2e, 0xca, 0xfd, 0x96, 0x49, 0xe9, 0xd6, 0x28, 0x59, 0x99, 0x50, 0xe5, 0x4b, 0x2f, 0x48, 0x91, + 0x97, 0x88, 0x60, 0x11, 0x2a, 0x5b, 0xec, 0x25, 0x29, 0x4e, 0x25, 0x4c, 0xbe, 0x24, 0xa5, 0x5e, + 0x92, 0xd2, 0x9f, 0x94, 0xa6, 0xd0, 0x58, 0xb9, 0xf2, 0xf4, 0x4a, 0x51, 0x63, 0xd2, 0x52, 0x09, + 0x27, 0x50, 0x9a, 0xc2, 0xce, 0x3e, 0x74, 0xf6, 0x91, 0xcc, 0xd7, 0xa8, 0x94, 0x5f, 0x4b, 0xaa, + 0x08, 0x77, 0xb1, 0x47, 0xbf, 0x2a, 0xc1, 0x61, 0x71, 0x44, 0x6e, 0xd3, 0x63, 0x33, 0xcd, 0x77, + 0xc0, 0x96, 0xa2, 0x22, 0x17, 0xf7, 0x12, 0xd9, 0x3b, 0x65, 0xe3, 0xc0, 0x05, 0xbe, 0xe0, 0x0d, + 0x1f, 0xc2, 0xe5, 0xcf, 0xb3, 0x9e, 0x7c, 0x52, 0x9a, 0x44, 0x50, 0x7c, 0x6a, 0x63, 0x5d, 0xad, + 0x68, 0xb9, 0x95, 0x15, 0x2a, 0xef, 0x01, 0x24, 0x73, 0x48, 0x65, 0x7d, 0x43, 0x5b, 0x29, 0x5e, + 0x2d, 0xae, 0x78, 0x62, 0x1f, 0xaa, 0xf5, 0x66, 0x98, 0xfd, 0x84, 0x04, 0x53, 0x5d, 0xcd, 0x2b, + 0xef, 0x96, 0xe0, 0x50, 0x1f, 0x11, 0xd0, 0xbd, 0x70, 0x57, 0xa1, 0x78, 0x29, 0xb7, 0xb9, 0x52, + 0xd1, 0xca, 0x4f, 0xaf, 0xe6, 0xd7, 0x57, 0xb4, 0xab, 0xa5, 0x72, 0x29, 0x5f, 0x5a, 0x29, 0x55, + 0xfc, 0x13, 0xd8, 0x04, 0xf8, 0x04, 0x64, 0xcb, 0xb5, 0xb0, 0x78, 0x72, 0x84, 0x2c, 0x0a, 0x57, + 0xd6, 0x97, 0x72, 0x2b, 0x14, 0x29, 0x2a, 0xd6, 0x9c, 0x4b, 0x15, 0x39, 0x76, 0x25, 0x95, 0x92, + 0xf8, 0xdc, 0xf6, 0x0e, 0x18, 0x0f, 0x04, 0x3f, 0xb2, 0x44, 0xa2, 0x4b, 0x2b, 0x62, 0xcf, 0xe5, + 0xe2, 0xda, 0x92, 0x7f, 0x49, 0x37, 0x06, 0x6e, 0xb0, 0x93, 0x25, 0x52, 0x12, 0xa1, 0x50, 0x8e, + 0x90, 0x49, 0x95, 0x9b, 0xa3, 0x7b, 0x38, 0x1d, 0x55, 0x1e, 0x85, 0x94, 0x08, 0x66, 0x64, 0xa1, + 0x46, 0xd7, 0x5b, 0xa1, 0x65, 0x62, 0x0a, 0x68, 0x24, 0x93, 0x25, 0x22, 0x20, 0x8b, 0x70, 0x72, + 0x44, 0xb9, 0x0a, 0x07, 0x7a, 0x06, 0x22, 0x74, 0x37, 0xcc, 0x89, 0x03, 0x71, 0xb6, 0x04, 0xd4, + 0x8a, 0x6b, 0x4b, 0xeb, 0x05, 0xb2, 0x68, 0xf6, 0x78, 0x02, 0xf0, 0x88, 0xc4, 0xa4, 0x14, 0xd1, + 0x4a, 0x8e, 0x28, 0x25, 0x98, 0x08, 0x86, 0x13, 0x74, 0x04, 0x0e, 0x6d, 0x56, 0x2e, 0x5d, 0xd0, + 0xae, 0xe6, 0x56, 0x4a, 0x85, 0x5c, 0x68, 0x79, 0x0c, 0xc0, 0x63, 0x8a, 0x1c, 0x21, 0x82, 0x92, + 0x58, 0x23, 0x47, 0x95, 0x58, 0x4a, 0x92, 0x25, 0xa5, 0x0c, 0x93, 0xa1, 0xc0, 0x80, 0x8e, 0x42, + 0x86, 0xaf, 0x57, 0x7b, 0x49, 0x45, 0x35, 0x14, 0x08, 0x15, 0x6c, 0xe5, 0x5e, 0x28, 0xae, 0x94, + 0x56, 0x4b, 0x15, 0x2a, 0xdf, 0x65, 0x00, 0xcf, 0xe3, 0x49, 0x06, 0x73, 0xa5, 0xbc, 0xbe, 0xa6, 0x5d, 0x22, 0xcb, 0xfe, 0x8a, 0x8f, 0x55, 0x1a, 0x98, 0x87, 0xcb, 0x12, 0x59, 0x9d, 0x76, 0x87, - 0x01, 0x39, 0xa2, 0x3c, 0x01, 0xa8, 0xdb, 0x5b, 0xd1, 0x31, 0x38, 0x5c, 0x5c, 0xbd, 0xb4, 0xa6, - 0x2e, 0x14, 0xb5, 0xd5, 0xdc, 0x0a, 0x91, 0x8f, 0xf9, 0xa6, 0xc7, 0x7a, 0x1c, 0x3c, 0xd7, 0x14, - 0x7b, 0x12, 0x9e, 0xf7, 0xca, 0x91, 0x93, 0x9f, 0x93, 0x48, 0x66, 0xf4, 0xfe, 0xd5, 0xec, 0xa7, - 0x24, 0x74, 0x24, 0xf5, 0x6a, 0x12, 0x25, 0xe7, 0x5a, 0x9b, 0x73, 0xd5, 0x56, 0x2b, 0x3b, 0x49, - 0xfe, 0x58, 0x68, 0xb5, 0x2e, 0x89, 0x7c, 0x6f, 0x36, 0xf5, 0xf5, 0x24, 0x4a, 0x11, 0xe8, 0xd3, - 0xfa, 0x35, 0x3d, 0x2b, 0x93, 0xbf, 0x2e, 0xeb, 0xd7, 0x74, 0x17, 0xe1, 0x50, 0xea, 0x1b, 0x49, - 0x94, 0x20, 0xe0, 0xba, 0x95, 0x9d, 0x20, 0xff, 0x2f, 0x5a, 0x6e, 0xe5, 0x9d, 0xa9, 0x3f, 0x4d, - 0x22, 0x20, 0xc0, 0xd6, 0x8e, 0xb3, 0x6d, 0x99, 0x59, 0x44, 0xfe, 0x5e, 0xa7, 0x7f, 0xfb, 0x90, - 0xde, 0xbb, 0xca, 0x91, 0x88, 0xf3, 0x9f, 0xe1, 0x48, 0xf4, 0x6f, 0x81, 0x74, 0x32, 0x91, 0x7a, - 0xff, 0xaa, 0xfc, 0xc1, 0xd5, 0x93, 0x89, 0xd4, 0x07, 0x57, 0xe5, 0x0f, 0xad, 0x5e, 0x4e, 0xa4, - 0xbe, 0x96, 0x94, 0x5f, 0x4d, 0x2a, 0x7f, 0x16, 0x05, 0xe4, 0x85, 0x0a, 0x77, 0x17, 0xf0, 0x49, - 0x48, 0xb9, 0xdb, 0x8a, 0xec, 0x9e, 0xf7, 0x5b, 0x76, 0x89, 0x30, 0x82, 0xcc, 0x07, 0x0a, 0x6d, - 0x33, 0xba, 0xdc, 0x50, 0x0e, 0x26, 0x9b, 0x86, 0x69, 0x34, 0x3b, 0x4d, 0x4d, 0xec, 0xb5, 0x0d, - 0xdc, 0x43, 0xe2, 0x04, 0xbc, 0x4c, 0x59, 0xe8, 0xd7, 0x03, 0x2c, 0xe2, 0x03, 0x59, 0x30, 0x02, - 0x5e, 0xce, 0xfe, 0xa5, 0x04, 0x99, 0x7e, 0xc2, 0xde, 0xd2, 0x36, 0xe0, 0x2a, 0xcc, 0x58, 0xd7, - 0x70, 0xbb, 0x6d, 0xd4, 0xe8, 0xc9, 0x9e, 0xbb, 0x38, 0x88, 0x0d, 0x5e, 0x1c, 0x4c, 0xfb, 0x08, - 0xdd, 0x41, 0xcd, 0x93, 0x1c, 0xee, 0x3a, 0x49, 0x5f, 0x04, 0xa7, 0xf8, 0x60, 0x4e, 0xe3, 0x94, - 0x44, 0xf0, 0xb8, 0x4c, 0x9c, 0x94, 0xac, 0xc7, 0x23, 0x72, 0xd4, 0x5b, 0x81, 0x28, 0x1f, 0x8b, - 0xc2, 0x44, 0xf0, 0xba, 0x32, 0x2a, 0x40, 0xaa, 0x61, 0xf1, 0x7b, 0x7c, 0x6c, 0xb4, 0x4f, 0x0c, - 0xb8, 0xe1, 0x3c, 0xb7, 0xcc, 0xf1, 0x55, 0x97, 0x32, 0xfb, 0x2f, 0x25, 0x48, 0x09, 0x30, 0xda, - 0x0f, 0xb1, 0x96, 0xee, 0x6c, 0x53, 0x76, 0xf1, 0x7c, 0x44, 0x96, 0x54, 0x5a, 0x26, 0x70, 0xbb, - 0xa5, 0xb3, 0x3b, 0x8c, 0x1c, 0x4e, 0xca, 0x64, 0x15, 0xd0, 0xc0, 0x7a, 0x8d, 0x9e, 0x49, 0x5b, - 0xcd, 0x26, 0x36, 0x1d, 0x5b, 0xac, 0x02, 0x38, 0x7c, 0x81, 0x83, 0xd1, 0x7d, 0x30, 0xe5, 0xb4, - 0x75, 0xa3, 0x11, 0xc0, 0x8d, 0x51, 0x5c, 0x59, 0x54, 0xb8, 0xc8, 0xf3, 0x70, 0x50, 0xf0, 0xad, - 0x61, 0x47, 0xaf, 0x6e, 0xe3, 0x9a, 0x47, 0x94, 0xa0, 0xd7, 0x57, 0x0e, 0x70, 0x84, 0x02, 0xaf, - 0x17, 0xb4, 0x27, 0x3b, 0x81, 0xe7, 0x0a, 0x75, 0x84, 0xf9, 0x73, 0x85, 0x33, 0x7d, 0x9e, 0x2b, - 0x84, 0x6f, 0x8b, 0xfb, 0xde, 0x2a, 0x9c, 0xec, 0x41, 0x12, 0xd4, 0xa8, 0x97, 0xce, 0xbf, 0x1c, - 0x81, 0x29, 0x71, 0x78, 0x5f, 0x73, 0xc7, 0x68, 0x05, 0x40, 0x37, 0x4d, 0xcb, 0xf1, 0x8f, 0x52, - 0xf7, 0x7a, 0xab, 0x8b, 0x6e, 0x2e, 0xe7, 0x12, 0xa9, 0x3e, 0x06, 0xd9, 0x3f, 0x95, 0x00, 0xbc, - 0xaa, 0xbe, 0xc3, 0x35, 0x0b, 0xa3, 0xbc, 0x57, 0xf4, 0xc9, 0x07, 0xdb, 0xe3, 0x06, 0x06, 0xba, - 0x64, 0x34, 0xe8, 0xad, 0x9c, 0x4d, 0x5c, 0x37, 0x4c, 0x7e, 0x23, 0x91, 0x15, 0xc4, 0xad, 0x9c, + 0x01, 0x39, 0xa2, 0x3c, 0x09, 0xa8, 0xdb, 0x5b, 0xd1, 0x3c, 0x1c, 0x2d, 0xae, 0x5d, 0x5a, 0x57, + 0x97, 0x8a, 0xda, 0x5a, 0x6e, 0x95, 0xc8, 0xc7, 0x7c, 0xd3, 0x63, 0x3d, 0x0e, 0x9e, 0x6b, 0x8a, + 0x3d, 0x09, 0xcf, 0x7b, 0xe5, 0xc8, 0xc9, 0xcf, 0x49, 0x24, 0x33, 0xfa, 0xc0, 0x5a, 0xf6, 0xd3, + 0x12, 0x3a, 0x96, 0x7a, 0x35, 0x89, 0x92, 0x0b, 0xad, 0xad, 0x85, 0x6a, 0xab, 0x95, 0x9d, 0x24, + 0x7f, 0x2c, 0xb5, 0x5a, 0x97, 0x44, 0xbe, 0x37, 0x97, 0xfa, 0x5a, 0x12, 0xa5, 0x08, 0xf4, 0x19, + 0xfd, 0xba, 0x9e, 0x95, 0xc9, 0x5f, 0x57, 0xf4, 0xeb, 0xba, 0x8b, 0x70, 0x24, 0xf5, 0xf5, 0x24, + 0x4a, 0x10, 0x70, 0xdd, 0xca, 0x4e, 0x90, 0xff, 0x97, 0x2d, 0xb7, 0xf2, 0xee, 0xd4, 0x9f, 0x26, + 0x11, 0x10, 0x60, 0x6b, 0xd7, 0xd9, 0xb1, 0xcc, 0x2c, 0x22, 0x7f, 0x6f, 0xd0, 0xbf, 0x7d, 0x48, + 0xef, 0x5b, 0xe3, 0x48, 0xc4, 0xf9, 0xcf, 0x70, 0x24, 0xfa, 0xb7, 0x40, 0x3a, 0x99, 0x48, 0x7d, + 0x60, 0x4d, 0xfe, 0xd0, 0xda, 0xc9, 0x44, 0xea, 0x43, 0x6b, 0xf2, 0x87, 0xd7, 0xae, 0x24, 0x52, + 0x5f, 0x4d, 0xca, 0xaf, 0x26, 0x95, 0x3f, 0x8b, 0x02, 0xf2, 0x42, 0x85, 0xbb, 0x0b, 0xf8, 0x14, + 0xa4, 0xdc, 0x6d, 0x45, 0x76, 0xcf, 0xfb, 0x2d, 0x7b, 0x44, 0x18, 0x41, 0xe6, 0x03, 0x85, 0xb6, + 0x19, 0x5d, 0x6e, 0x28, 0x07, 0x93, 0x4d, 0xc3, 0x34, 0x9a, 0x9d, 0xa6, 0x26, 0xf6, 0xda, 0x06, + 0xee, 0x21, 0x71, 0x02, 0x5e, 0xa6, 0x2c, 0xf4, 0x1b, 0x01, 0x16, 0xf1, 0x81, 0x2c, 0x18, 0x01, + 0x2f, 0x67, 0xff, 0x52, 0x82, 0x4c, 0x3f, 0x61, 0x6f, 0x6b, 0x1b, 0x70, 0x0d, 0x66, 0xac, 0xeb, + 0xb8, 0xdd, 0x36, 0x6a, 0xf4, 0x64, 0xcf, 0x5d, 0x1c, 0xc4, 0x06, 0x2f, 0x0e, 0xa6, 0x7d, 0x84, + 0xee, 0xa0, 0xe6, 0x49, 0x0e, 0x77, 0x83, 0xa4, 0x2f, 0x82, 0x53, 0x7c, 0x30, 0xa7, 0x71, 0x4a, + 0x22, 0x78, 0x5c, 0x21, 0x4e, 0x4a, 0xd6, 0xe3, 0x11, 0x39, 0xea, 0xad, 0x40, 0x94, 0x8f, 0x47, + 0x61, 0x22, 0x78, 0x5d, 0x19, 0x15, 0x20, 0xd5, 0xb0, 0xf8, 0x3d, 0x3e, 0x36, 0xda, 0x27, 0x06, + 0xdc, 0x70, 0x5e, 0x58, 0xe1, 0xf8, 0xaa, 0x4b, 0x99, 0xfd, 0x17, 0x12, 0xa4, 0x04, 0x18, 0x1d, + 0x84, 0x58, 0x4b, 0x77, 0x76, 0x28, 0xbb, 0x78, 0x3e, 0x22, 0x4b, 0x2a, 0x2d, 0x13, 0xb8, 0xdd, + 0xd2, 0xd9, 0x1d, 0x46, 0x0e, 0x27, 0x65, 0xb2, 0x0a, 0x68, 0x60, 0xbd, 0x46, 0xcf, 0xa4, 0xad, + 0x66, 0x13, 0x9b, 0x8e, 0x2d, 0x56, 0x01, 0x1c, 0xbe, 0xc4, 0xc1, 0xe8, 0x01, 0x98, 0x72, 0xda, + 0xba, 0xd1, 0x08, 0xe0, 0xc6, 0x28, 0xae, 0x2c, 0x2a, 0x5c, 0xe4, 0x45, 0x38, 0x2c, 0xf8, 0xd6, + 0xb0, 0xa3, 0x57, 0x77, 0x70, 0xcd, 0x23, 0x4a, 0xd0, 0xeb, 0x2b, 0x87, 0x38, 0x42, 0x81, 0xd7, + 0x0b, 0xda, 0x93, 0x9d, 0xc0, 0x73, 0x85, 0x3a, 0xc2, 0xfc, 0xb9, 0xc2, 0x99, 0x3e, 0xcf, 0x15, + 0xc2, 0xb7, 0xc5, 0x7d, 0x6f, 0x15, 0x4e, 0xf6, 0x20, 0x09, 0x6a, 0xd4, 0x4b, 0xe7, 0xbf, 0x18, + 0x81, 0x29, 0x71, 0x78, 0x5f, 0x73, 0xc7, 0x68, 0x15, 0x40, 0x37, 0x4d, 0xcb, 0xf1, 0x8f, 0x52, + 0xf7, 0x7a, 0xab, 0x8b, 0x6e, 0x21, 0xe7, 0x12, 0xa9, 0x3e, 0x06, 0xd9, 0x3f, 0x95, 0x00, 0xbc, + 0xaa, 0xbe, 0xc3, 0x35, 0x07, 0xa3, 0xbc, 0x57, 0xf4, 0xc9, 0x07, 0xdb, 0xe3, 0x06, 0x06, 0xba, + 0x64, 0x34, 0xe8, 0xad, 0x9c, 0x2d, 0x5c, 0x37, 0x4c, 0x7e, 0x23, 0x91, 0x15, 0xc4, 0xad, 0x9c, 0x98, 0x77, 0x63, 0x57, 0x85, 0x94, 0x8d, 0x9b, 0xba, 0xe9, 0x18, 0x55, 0xee, 0xac, 0xe7, 0xf7, - 0x24, 0xfc, 0x5c, 0x99, 0x53, 0xab, 0x2e, 0x1f, 0xe5, 0x04, 0xa4, 0x04, 0xd4, 0x9d, 0x9a, 0x46, + 0x25, 0xfc, 0x42, 0x99, 0x53, 0xab, 0x2e, 0x1f, 0xe5, 0x04, 0xa4, 0x04, 0xd4, 0x9d, 0x9a, 0x46, 0x50, 0x12, 0xa2, 0xe5, 0x22, 0x99, 0x9c, 0xe9, 0x0c, 0x51, 0xca, 0x95, 0xe5, 0xc8, 0xc9, 0x4f, - 0x45, 0x20, 0x29, 0xa2, 0xc7, 0x34, 0x4c, 0x16, 0x0b, 0xa5, 0xd0, 0x2c, 0x37, 0x0d, 0x13, 0x02, - 0xc8, 0xa3, 0xfc, 0x7b, 0x92, 0x7e, 0xe0, 0xba, 0xba, 0x56, 0x59, 0x3b, 0x2b, 0xff, 0x49, 0x37, - 0xf0, 0x41, 0xf9, 0x6b, 0x49, 0x34, 0x05, 0x63, 0x02, 0x78, 0xf6, 0x81, 0xb3, 0x0f, 0xca, 0xaf, - 0x86, 0x41, 0x0f, 0xc9, 0x5f, 0xa7, 0xdb, 0xab, 0x02, 0x74, 0x46, 0xab, 0x90, 0xa9, 0x6a, 0x6d, - 0x75, 0xf9, 0x29, 0x59, 0xf2, 0x57, 0x9c, 0xf5, 0x55, 0x44, 0xd0, 0x11, 0x38, 0x20, 0x2a, 0x2e, - 0x5e, 0xbc, 0x78, 0xf1, 0x61, 0x5f, 0xe5, 0x8d, 0x0f, 0x24, 0xc2, 0xd5, 0x17, 0x7c, 0xd5, 0x1f, - 0xeb, 0xae, 0xbe, 0xe8, 0xab, 0xfe, 0xe9, 0x0f, 0x24, 0xd0, 0x34, 0x8c, 0x8a, 0xea, 0x95, 0xdc, - 0x93, 0xf2, 0x77, 0xbf, 0xfb, 0xdd, 0xef, 0x26, 0x4f, 0x6e, 0x80, 0xdc, 0x95, 0x92, 0xcd, 0x80, + 0x47, 0x20, 0x29, 0xa2, 0xc7, 0x34, 0x4c, 0x16, 0x0b, 0xa5, 0xd0, 0x2c, 0x37, 0x0d, 0x13, 0x02, + 0xc8, 0xa3, 0xfc, 0x7b, 0x93, 0x7e, 0xe0, 0x86, 0xba, 0x5e, 0x59, 0x3f, 0x2b, 0xff, 0x49, 0x37, + 0xf0, 0x61, 0xf9, 0xab, 0x49, 0x34, 0x05, 0x63, 0x02, 0x78, 0xf6, 0xa1, 0xb3, 0x0f, 0xcb, 0xaf, + 0x86, 0x41, 0x8f, 0xc8, 0x5f, 0xa3, 0xdb, 0xab, 0x02, 0x74, 0x46, 0xab, 0x90, 0xa9, 0x6a, 0x7d, + 0x6d, 0xe5, 0x69, 0x59, 0xf2, 0x57, 0x9c, 0xf5, 0x55, 0x44, 0xd0, 0x31, 0x38, 0x24, 0x2a, 0x2e, + 0x5e, 0xbc, 0x78, 0xf1, 0x51, 0x5f, 0xe5, 0xcd, 0x0f, 0x26, 0xc2, 0xd5, 0x17, 0x7c, 0xd5, 0x1f, + 0xef, 0xae, 0xbe, 0xe8, 0xab, 0xfe, 0xa9, 0x0f, 0x26, 0xd0, 0x34, 0x8c, 0x8a, 0xea, 0xd5, 0xdc, + 0x53, 0xf2, 0x77, 0xbe, 0xf3, 0x9d, 0xef, 0x24, 0x4f, 0x6e, 0x82, 0xdc, 0x95, 0x92, 0xcd, 0x80, 0x1c, 0xc8, 0xc1, 0x88, 0x7a, 0x47, 0x42, 0x50, 0x9a, 0x66, 0xc9, 0x12, 0x49, 0x71, 0x7c, 0x50, - 0x96, 0x92, 0xc9, 0x91, 0xfc, 0x0f, 0xc3, 0x74, 0xd5, 0x6a, 0x86, 0x47, 0x3c, 0x2f, 0x87, 0xae, - 0x1c, 0xd9, 0x4b, 0xd2, 0xdb, 0x4e, 0x71, 0xa4, 0xba, 0xd5, 0xd0, 0xcd, 0xfa, 0x9c, 0xd5, 0xae, - 0x7b, 0x4f, 0x96, 0xc8, 0xf2, 0xd1, 0xf6, 0x3d, 0x5c, 0x6a, 0x6d, 0xfe, 0xa5, 0x24, 0x7d, 0x22, - 0x12, 0x5d, 0x5c, 0xcf, 0x7f, 0x3a, 0x92, 0x5d, 0x64, 0x84, 0xeb, 0xc2, 0x9e, 0x54, 0xbc, 0xd5, - 0xc0, 0x55, 0x32, 0xe8, 0xf0, 0x8d, 0xfb, 0x60, 0xa6, 0x6e, 0xd5, 0x2d, 0xca, 0xe9, 0x34, 0xf9, - 0x8b, 0xbf, 0x79, 0x4a, 0xbb, 0xd0, 0xec, 0xc0, 0x07, 0x52, 0xf3, 0xab, 0x30, 0xcd, 0x91, 0x35, - 0xba, 0x9a, 0x65, 0xb7, 0x22, 0xd0, 0xae, 0x97, 0xf3, 0x32, 0xbf, 0xf8, 0x55, 0xba, 0x0d, 0xa9, - 0x4e, 0x71, 0x52, 0x52, 0xc7, 0x2e, 0x4e, 0xcc, 0xab, 0xb0, 0x2f, 0xc0, 0x8f, 0xed, 0x24, 0xe0, - 0xf6, 0x00, 0x8e, 0x5f, 0xe0, 0x1c, 0xa7, 0x7d, 0x1c, 0xcb, 0x9c, 0x74, 0x7e, 0x01, 0xc6, 0xf7, - 0xc2, 0xeb, 0x9f, 0x73, 0x5e, 0x63, 0xd8, 0xcf, 0x64, 0x11, 0x26, 0x29, 0x93, 0x6a, 0xc7, 0x76, - 0xac, 0x26, 0xdd, 0xa6, 0xd9, 0x9d, 0xcd, 0x6f, 0x7d, 0x95, 0x05, 0xeb, 0x09, 0x42, 0xb6, 0xe0, - 0x52, 0xcd, 0xcf, 0x03, 0x5d, 0x95, 0xd7, 0x70, 0xb5, 0x31, 0x80, 0xc3, 0x17, 0xb9, 0x20, 0x2e, - 0xfe, 0xfc, 0x15, 0xb2, 0x48, 0xeb, 0x34, 0xe9, 0x2e, 0x8a, 0x5f, 0x92, 0xc1, 0xd7, 0xf0, 0x32, - 0x5f, 0xfe, 0x11, 0x36, 0x1f, 0x4c, 0xbb, 0x0c, 0x7c, 0x32, 0xf9, 0x46, 0xb1, 0x8e, 0x1d, 0x07, - 0xb7, 0x6d, 0x4d, 0x6f, 0xf4, 0x12, 0xcf, 0x77, 0x8f, 0x29, 0xf3, 0x91, 0x6f, 0x06, 0x47, 0x71, - 0x91, 0x51, 0xe6, 0x1a, 0x8d, 0xf9, 0x0d, 0x38, 0xd0, 0xc3, 0x2a, 0x86, 0xe0, 0xf9, 0x51, 0xce, - 0x73, 0xa6, 0xcb, 0x32, 0x08, 0xdb, 0x75, 0x10, 0x70, 0x77, 0x2c, 0x87, 0xe0, 0xf9, 0x93, 0x9c, - 0x27, 0xe2, 0xb4, 0x62, 0x48, 0x09, 0xc7, 0xcb, 0x30, 0x75, 0x0d, 0xb7, 0x37, 0x2d, 0x9b, 0xdf, - 0x1d, 0x1b, 0x82, 0xdd, 0x4f, 0x71, 0x76, 0x93, 0x9c, 0x90, 0x5e, 0x26, 0x23, 0xbc, 0x2e, 0x42, - 0x6a, 0x4b, 0xaf, 0xe2, 0x21, 0x58, 0xdc, 0xe0, 0x2c, 0x92, 0x04, 0x9f, 0x90, 0xe6, 0x60, 0xac, - 0x6e, 0xf1, 0x8d, 0xb4, 0xc1, 0xe4, 0x1f, 0xe3, 0xe4, 0xa3, 0x82, 0x86, 0xb3, 0x68, 0x59, 0xad, - 0x4e, 0x43, 0x77, 0x86, 0x91, 0xe0, 0xa7, 0x05, 0x0b, 0x41, 0xc3, 0x59, 0xec, 0x41, 0xad, 0x2f, - 0x09, 0x16, 0xb6, 0x4f, 0x9f, 0x8f, 0xc2, 0xa8, 0x65, 0x36, 0x76, 0x2c, 0x73, 0x18, 0x21, 0x3e, - 0xce, 0x39, 0x00, 0x27, 0x21, 0x0c, 0x1e, 0x81, 0xf4, 0xb0, 0x03, 0xf1, 0xf7, 0xbe, 0x29, 0xdc, - 0x43, 0x8c, 0xc0, 0x22, 0x4c, 0x8a, 0x00, 0x65, 0x58, 0xe6, 0x10, 0x2c, 0x7e, 0x96, 0xb3, 0x98, - 0xf0, 0x91, 0xf1, 0x6e, 0x38, 0xd8, 0x76, 0xea, 0x78, 0x18, 0x26, 0x9f, 0x12, 0xdd, 0xe0, 0x24, - 0x5c, 0x95, 0x9b, 0xd8, 0xac, 0x6e, 0x0f, 0xc7, 0xe1, 0xe7, 0x84, 0x2a, 0x05, 0x0d, 0x61, 0xb1, - 0x00, 0xe3, 0x4d, 0xbd, 0x6d, 0x6f, 0xeb, 0x8d, 0xa1, 0x86, 0xe3, 0xef, 0x73, 0x1e, 0x63, 0x2e, - 0x11, 0xd7, 0x48, 0xc7, 0xdc, 0x0b, 0x9b, 0x4f, 0x0b, 0x8d, 0xf8, 0xc8, 0xb8, 0xeb, 0xd9, 0x0e, - 0xcd, 0xe3, 0xf7, 0xc2, 0xed, 0x33, 0xc2, 0xf5, 0x18, 0xed, 0x8a, 0x9f, 0xe3, 0x23, 0x90, 0xb6, - 0x8d, 0x67, 0x87, 0x62, 0xf3, 0x59, 0x31, 0xd2, 0x94, 0x80, 0x10, 0x3f, 0x05, 0x07, 0x7b, 0x4e, - 0x13, 0x43, 0x30, 0xfb, 0x79, 0xce, 0x6c, 0x7f, 0x8f, 0xa9, 0x82, 0x87, 0x84, 0xbd, 0xb2, 0xfc, - 0x07, 0x22, 0x24, 0xe0, 0x10, 0xaf, 0x75, 0x98, 0xe9, 0x98, 0xb6, 0xbe, 0xb5, 0x37, 0xad, 0xfd, - 0x82, 0xd0, 0x1a, 0xa3, 0x0d, 0x68, 0xad, 0x02, 0xfb, 0x39, 0xc7, 0xbd, 0x8d, 0xeb, 0xe7, 0x44, - 0x60, 0x65, 0xd4, 0x1b, 0xc1, 0xd1, 0xfd, 0x3e, 0xc8, 0xba, 0xea, 0x14, 0x49, 0xb7, 0xad, 0x35, - 0xf5, 0xd6, 0x10, 0x9c, 0x7f, 0x91, 0x73, 0x16, 0x11, 0xdf, 0xcd, 0xda, 0xed, 0x15, 0xbd, 0x45, - 0x98, 0x3f, 0x09, 0x19, 0xc1, 0xbc, 0x63, 0xb6, 0x71, 0xd5, 0xaa, 0x9b, 0xc6, 0xb3, 0xb8, 0x36, - 0x04, 0xeb, 0x5f, 0x0a, 0x0d, 0xd5, 0x86, 0x8f, 0x9c, 0x70, 0x2e, 0x81, 0xec, 0xe6, 0x2a, 0x9a, - 0xd1, 0xa4, 0xe7, 0x8d, 0xbb, 0x73, 0xfc, 0x65, 0x31, 0x52, 0x2e, 0x5d, 0x89, 0x92, 0xcd, 0x17, - 0x81, 0x3d, 0x60, 0x19, 0xd6, 0x24, 0x3f, 0xcf, 0x19, 0x8d, 0x7b, 0x54, 0x3c, 0x70, 0x54, 0xad, - 0x66, 0x4b, 0x6f, 0x0f, 0x13, 0xff, 0xfe, 0xa1, 0x08, 0x1c, 0x9c, 0x84, 0x07, 0x0e, 0x92, 0xd1, - 0x91, 0xd9, 0x7e, 0x08, 0x0e, 0xbf, 0x22, 0x02, 0x87, 0xa0, 0xe1, 0x2c, 0x44, 0xc2, 0x30, 0x04, - 0x8b, 0x7f, 0x24, 0x58, 0x08, 0x1a, 0xc2, 0xe2, 0x71, 0x6f, 0xa2, 0x6d, 0xe3, 0xba, 0x61, 0x3b, - 0xfc, 0x89, 0xd9, 0xee, 0xac, 0xfe, 0xf1, 0x37, 0x83, 0x49, 0x98, 0xea, 0x23, 0x25, 0x91, 0x88, - 0x6f, 0x7c, 0xd3, 0x83, 0x9d, 0xc1, 0x82, 0xfd, 0xaa, 0x88, 0x44, 0x3e, 0x32, 0x22, 0x9b, 0x2f, - 0x43, 0x24, 0x6a, 0xaf, 0x92, 0x05, 0xea, 0x10, 0xec, 0xfe, 0x49, 0x48, 0xb8, 0xb2, 0xa0, 0x25, - 0x3c, 0x7d, 0xf9, 0x4f, 0xc7, 0xbc, 0x8a, 0x77, 0x86, 0xb2, 0xce, 0x7f, 0x1a, 0xca, 0x7f, 0x36, - 0x18, 0x25, 0x8b, 0x21, 0x93, 0xa1, 0x7c, 0x0a, 0x0d, 0x7a, 0xc2, 0x9a, 0x79, 0xd7, 0xb7, 0x79, - 0x7f, 0x83, 0xe9, 0xd4, 0xfc, 0x32, 0x31, 0xf2, 0x60, 0xd2, 0x33, 0x98, 0xd9, 0x8f, 0x7c, 0xdb, - 0xb5, 0xf3, 0x40, 0xce, 0x33, 0x7f, 0x09, 0xc6, 0x03, 0x09, 0xcf, 0x60, 0x56, 0xef, 0xe1, 0xac, - 0xc6, 0xfc, 0xf9, 0xce, 0xfc, 0x39, 0x88, 0x91, 0xe4, 0x65, 0x30, 0xf9, 0xff, 0xc5, 0xc9, 0x29, - 0xfa, 0xfc, 0xf7, 0x40, 0x4a, 0x24, 0x2d, 0x83, 0x49, 0xdf, 0xcb, 0x49, 0x5d, 0x12, 0x42, 0x2e, - 0x12, 0x96, 0xc1, 0xe4, 0xff, 0xb7, 0x20, 0x17, 0x24, 0x84, 0x7c, 0x78, 0x15, 0xfe, 0xc6, 0xfb, - 0x63, 0x7c, 0xd2, 0x11, 0xba, 0x7b, 0x04, 0x92, 0x3c, 0x53, 0x19, 0x4c, 0xfd, 0x3e, 0xde, 0xb8, - 0xa0, 0x98, 0x7f, 0x18, 0xe2, 0x43, 0x2a, 0xfc, 0x03, 0x9c, 0x94, 0xe1, 0xcf, 0x2f, 0xc0, 0xa8, - 0x2f, 0x3b, 0x19, 0x4c, 0xfe, 0xff, 0x72, 0x72, 0x3f, 0x15, 0x11, 0x9d, 0x67, 0x27, 0x83, 0x19, - 0xfc, 0xa8, 0x10, 0x9d, 0x53, 0x10, 0xb5, 0x89, 0xc4, 0x64, 0x30, 0xf5, 0x07, 0x85, 0xd6, 0x05, - 0xc9, 0xfc, 0xa3, 0x90, 0x76, 0x27, 0x9b, 0xc1, 0xf4, 0x1f, 0xe2, 0xf4, 0x1e, 0x0d, 0xd1, 0x80, - 0x6f, 0xb2, 0x1b, 0xcc, 0xe2, 0xff, 0x13, 0x1a, 0xf0, 0x51, 0x11, 0x37, 0x0a, 0x27, 0x30, 0x83, - 0x39, 0x7d, 0x58, 0xb8, 0x51, 0x28, 0x7f, 0x21, 0xa3, 0x49, 0x63, 0xfe, 0x60, 0x16, 0x3f, 0x26, - 0x46, 0x93, 0xe2, 0x13, 0x31, 0xc2, 0x19, 0xc1, 0x60, 0x1e, 0x3f, 0x21, 0xc4, 0x08, 0x25, 0x04, - 0xf3, 0xeb, 0x80, 0xba, 0xb3, 0x81, 0xc1, 0xfc, 0x5e, 0xe4, 0xfc, 0xa6, 0xba, 0x92, 0x81, 0xf9, - 0x27, 0x60, 0x7f, 0xef, 0x4c, 0x60, 0x30, 0xd7, 0x8f, 0x7c, 0x3b, 0xb4, 0x76, 0xf3, 0x27, 0x02, - 0xf3, 0x15, 0x6f, 0x4a, 0xf1, 0x67, 0x01, 0x83, 0xd9, 0x7e, 0xf4, 0xdb, 0xc1, 0xc0, 0xed, 0x4f, - 0x02, 0xe6, 0x73, 0x00, 0xde, 0x04, 0x3c, 0x98, 0xd7, 0x4f, 0x71, 0x5e, 0x3e, 0x22, 0xe2, 0x1a, - 0x7c, 0xfe, 0x1d, 0x4c, 0x7f, 0x43, 0xb8, 0x06, 0xa7, 0x20, 0xae, 0x21, 0xa6, 0xde, 0xc1, 0xd4, - 0x1f, 0x13, 0xae, 0x21, 0x48, 0x88, 0x65, 0xfb, 0x66, 0xb7, 0xc1, 0x1c, 0x3e, 0x2e, 0x2c, 0xdb, - 0x47, 0x35, 0xbf, 0x0a, 0x53, 0x5d, 0x13, 0xe2, 0x60, 0x56, 0x9f, 0xe0, 0xac, 0xe4, 0xf0, 0x7c, - 0xe8, 0x9f, 0xbc, 0xf8, 0x64, 0x38, 0x98, 0xdb, 0x27, 0x43, 0x93, 0x17, 0x9f, 0x0b, 0xe7, 0x1f, - 0x81, 0x94, 0xd9, 0x69, 0x34, 0x88, 0xf3, 0xa0, 0xdd, 0x9f, 0x18, 0x67, 0xbe, 0xfe, 0x1d, 0xae, - 0x1d, 0x41, 0x30, 0x7f, 0x0e, 0xe2, 0xb8, 0xb9, 0x89, 0x6b, 0x83, 0x28, 0xbf, 0xf1, 0x1d, 0x11, - 0x30, 0x09, 0xf6, 0xfc, 0xa3, 0x00, 0x6c, 0x6b, 0x84, 0xde, 0xb1, 0x1f, 0x40, 0xfb, 0xa7, 0xdf, - 0xe1, 0x0f, 0xf2, 0x3c, 0x12, 0x8f, 0x01, 0x7b, 0xde, 0xb7, 0x3b, 0x83, 0x6f, 0x06, 0x19, 0xd0, - 0x11, 0xb9, 0x08, 0xc9, 0xa7, 0x6d, 0xcb, 0x74, 0xf4, 0xfa, 0x20, 0xea, 0xff, 0xc4, 0xa9, 0x05, - 0x3e, 0x51, 0x58, 0xd3, 0x6a, 0x63, 0x47, 0xaf, 0xdb, 0x83, 0x68, 0xff, 0x33, 0xa7, 0x75, 0x09, - 0x08, 0x71, 0x55, 0xb7, 0x9d, 0x61, 0xfa, 0xfd, 0x67, 0x82, 0x58, 0x10, 0x10, 0xa1, 0xc9, 0xdf, - 0x57, 0xf1, 0xce, 0x20, 0xda, 0x6f, 0x09, 0xa1, 0x39, 0xfe, 0xfc, 0xf7, 0x40, 0x9a, 0xfc, 0xc9, - 0x1e, 0xea, 0x0e, 0x20, 0xfe, 0x73, 0x4e, 0xec, 0x51, 0x90, 0x96, 0x6d, 0xa7, 0xe6, 0x18, 0x83, - 0x95, 0xfd, 0x1a, 0x1f, 0x69, 0x81, 0x3f, 0x9f, 0x83, 0x51, 0xdb, 0xa9, 0xd5, 0x3a, 0x3c, 0x3f, - 0x1d, 0x40, 0xfe, 0x17, 0xdf, 0x71, 0xb7, 0x2c, 0x5c, 0x1a, 0x32, 0xda, 0xcf, 0x5c, 0x75, 0x5a, - 0x16, 0xbd, 0x95, 0x35, 0x88, 0xc3, 0xb7, 0x39, 0x07, 0x1f, 0xc9, 0xfc, 0x02, 0x8c, 0x91, 0xbe, - 0x88, 0xcb, 0x2d, 0x83, 0x58, 0xfc, 0x17, 0xae, 0x80, 0x00, 0x51, 0xfe, 0xfb, 0xbf, 0xf8, 0xca, - 0x51, 0xe9, 0xe5, 0x57, 0x8e, 0x4a, 0xff, 0xe1, 0x95, 0xa3, 0xd2, 0x07, 0xff, 0xf8, 0xe8, 0xc8, - 0xcb, 0x7f, 0x7c, 0x74, 0xe4, 0x0f, 0xfe, 0xf8, 0xe8, 0x48, 0xef, 0x5d, 0x62, 0x58, 0xb4, 0x16, - 0x2d, 0xb6, 0x3f, 0xfc, 0x36, 0xa5, 0x6e, 0x38, 0xdb, 0x9d, 0xcd, 0xb9, 0xaa, 0xd5, 0xa4, 0xdb, - 0xb8, 0xde, 0x6e, 0xad, 0xbb, 0xc8, 0x81, 0xf7, 0x44, 0xe1, 0x68, 0xd5, 0xb2, 0x9b, 0x96, 0x7d, - 0x7a, 0x53, 0xb7, 0xf1, 0xe9, 0x6b, 0x67, 0x36, 0xb1, 0xa3, 0x9f, 0x39, 0x5d, 0xb5, 0x0c, 0x93, - 0x6f, 0xfb, 0x4e, 0xb3, 0xfa, 0x39, 0x52, 0x3f, 0xc7, 0xeb, 0xb3, 0x3d, 0x77, 0x88, 0x95, 0x45, - 0x88, 0x2d, 0x58, 0x06, 0xbd, 0xe8, 0x5f, 0xc3, 0xa6, 0xd5, 0xe4, 0x8f, 0x40, 0x59, 0x01, 0xdd, - 0x09, 0x09, 0xbd, 0x69, 0x75, 0x4c, 0x87, 0x9d, 0x8d, 0xe4, 0x47, 0xbf, 0x78, 0x73, 0x76, 0xe4, - 0x0f, 0x6f, 0xce, 0x46, 0x4b, 0xa6, 0xa3, 0xf2, 0xaa, 0xf9, 0xd8, 0xab, 0x2f, 0xcd, 0x4a, 0xca, - 0x65, 0x48, 0x16, 0x70, 0xf5, 0x56, 0x78, 0x15, 0x70, 0x35, 0xc4, 0xeb, 0x5e, 0x48, 0x95, 0x4c, - 0x87, 0x3d, 0xd3, 0x3d, 0x02, 0x51, 0xc3, 0x64, 0xaf, 0xbb, 0x42, 0xed, 0x13, 0x38, 0x41, 0x2d, - 0xe0, 0xaa, 0x8b, 0x5a, 0xc3, 0xd5, 0x30, 0x2a, 0x61, 0x4f, 0xe0, 0xf9, 0xc2, 0x1f, 0xfc, 0xc7, - 0xa3, 0x23, 0xcf, 0xbd, 0x72, 0x74, 0xa4, 0xdf, 0xf8, 0x04, 0xd4, 0xcf, 0x55, 0xcc, 0xfe, 0x3b, - 0x65, 0xd7, 0xae, 0xb2, 0xed, 0xf9, 0xcd, 0x04, 0xfb, 0x38, 0x02, 0xbc, 0x3b, 0x0a, 0x07, 0x59, - 0xa5, 0xc6, 0x94, 0xca, 0x75, 0xce, 0x46, 0x60, 0xcc, 0x5f, 0x35, 0xc4, 0xde, 0xfb, 0x12, 0x4c, - 0x50, 0x0b, 0xa4, 0xbb, 0x8e, 0xd4, 0xe9, 0x07, 0xc6, 0xe9, 0xdf, 0xfe, 0x37, 0x71, 0xaa, 0xde, - 0x71, 0x97, 0x90, 0xbe, 0x4d, 0xaa, 0xc0, 0x8c, 0xd1, 0x6c, 0x35, 0x30, 0x3d, 0xe4, 0xd3, 0xdc, - 0xba, 0xc1, 0xfc, 0xbe, 0xc4, 0xf9, 0x4d, 0x7b, 0xe4, 0x25, 0x41, 0x3d, 0xbf, 0x0c, 0x53, 0x7a, - 0xb5, 0x8a, 0x5b, 0x01, 0x96, 0x03, 0xbc, 0x43, 0x08, 0x28, 0x73, 0x4a, 0x97, 0x5b, 0xfe, 0xd1, - 0xbe, 0x23, 0x70, 0xb7, 0x6f, 0x04, 0xda, 0xb8, 0x8e, 0xcd, 0x53, 0x26, 0x76, 0x9e, 0xb1, 0xda, - 0x57, 0xc5, 0x40, 0xb0, 0xa6, 0xc4, 0x20, 0xfc, 0x6e, 0x02, 0x14, 0x3e, 0x50, 0xb6, 0xa3, 0x5f, - 0x35, 0xcc, 0xba, 0xeb, 0x0e, 0x7a, 0xc7, 0xd9, 0x7e, 0x96, 0x8f, 0xc6, 0x7e, 0x3e, 0x36, 0x1c, - 0xc7, 0x75, 0x89, 0x01, 0x7e, 0x94, 0xed, 0x3f, 0xc0, 0x7d, 0xbc, 0xe9, 0x77, 0xa2, 0x80, 0xca, - 0x8e, 0x7e, 0x15, 0xe7, 0x3a, 0xce, 0xb6, 0xd5, 0x36, 0x9e, 0x65, 0xb1, 0x0c, 0x03, 0x34, 0xf5, - 0xeb, 0x9a, 0x63, 0x5d, 0xc5, 0xa6, 0x78, 0x22, 0x70, 0x70, 0xae, 0x87, 0x93, 0xce, 0x11, 0xff, - 0xc9, 0xdf, 0xf7, 0xe9, 0xaf, 0xcc, 0xde, 0x33, 0xd8, 0x14, 0x29, 0x32, 0x49, 0xae, 0xaf, 0x57, - 0x28, 0x63, 0x74, 0x05, 0xd8, 0x35, 0x7e, 0xad, 0x61, 0xd8, 0x0e, 0xbf, 0x5b, 0x7e, 0x6e, 0xae, - 0x77, 0xdf, 0xe7, 0xba, 0xc5, 0x9c, 0xe3, 0x97, 0x66, 0xac, 0xb6, 0xbd, 0x34, 0xa2, 0xa6, 0x29, - 0xab, 0x65, 0xc3, 0x76, 0x50, 0x05, 0xd2, 0x35, 0x6c, 0xee, 0x30, 0xb6, 0xd1, 0xd7, 0xc7, 0x36, - 0x45, 0x38, 0x51, 0xae, 0x4f, 0x02, 0xd2, 0xfd, 0x78, 0xe2, 0x2b, 0x58, 0xec, 0x2e, 0x67, 0x1f, - 0xf6, 0x01, 0xce, 0xf4, 0xcd, 0xd8, 0x94, 0x1e, 0x06, 0x65, 0x8f, 0x03, 0x78, 0x6d, 0xa2, 0x0c, - 0x24, 0xf5, 0x5a, 0xad, 0x8d, 0x6d, 0x76, 0xd7, 0x23, 0xad, 0x8a, 0xe2, 0xfc, 0xd4, 0xef, 0x7d, - 0xfe, 0xd4, 0x78, 0x80, 0x63, 0x7e, 0x0c, 0xe0, 0x9a, 0x4b, 0x7a, 0xf2, 0x63, 0x12, 0x4c, 0x75, - 0xb5, 0x88, 0x14, 0x38, 0x9a, 0xdb, 0xa8, 0x2c, 0xad, 0xa9, 0xa5, 0xb7, 0xb1, 0xeb, 0x44, 0xfc, - 0xc2, 0x53, 0x79, 0xbd, 0xb8, 0xc0, 0xbe, 0x81, 0x33, 0x82, 0x66, 0xe1, 0x50, 0x0f, 0x9c, 0x42, - 0x71, 0xb9, 0xb8, 0x98, 0xab, 0x14, 0x65, 0x09, 0xdd, 0x01, 0x47, 0x7a, 0x32, 0x71, 0x51, 0x22, - 0x7d, 0x50, 0xd4, 0xa2, 0x8b, 0x12, 0xcd, 0x5f, 0xea, 0xeb, 0x48, 0xf7, 0xef, 0x6a, 0x3f, 0xd7, - 0x5d, 0x77, 0x09, 0x06, 0xb5, 0x77, 0x45, 0xe0, 0x60, 0x38, 0x56, 0xe9, 0xe6, 0x4e, 0x9f, 0x2f, - 0x28, 0xf6, 0x71, 0x82, 0x25, 0x88, 0xe6, 0xcc, 0x1d, 0x74, 0x90, 0xe5, 0xd3, 0x5a, 0xa7, 0xdd, - 0xe0, 0x13, 0x41, 0x92, 0x94, 0x37, 0xda, 0x8d, 0xe0, 0xab, 0xb2, 0x31, 0xfe, 0xaa, 0x6c, 0x5e, - 0x7e, 0xf1, 0xa5, 0xd9, 0x91, 0xcf, 0xbd, 0x34, 0x3b, 0xf2, 0xad, 0x8f, 0xcf, 0x8e, 0x3c, 0xf7, - 0x47, 0xc7, 0x46, 0xf2, 0x57, 0xc3, 0xdd, 0xfb, 0x8d, 0x81, 0xb3, 0x69, 0x2a, 0x67, 0xee, 0xd0, - 0xd9, 0x60, 0x5d, 0x7a, 0x5b, 0x9c, 0x76, 0x4e, 0x1c, 0xa0, 0x1e, 0x0d, 0x1f, 0xa0, 0x3e, 0x81, - 0x1b, 0x8d, 0xc7, 0x4c, 0xeb, 0x19, 0x3a, 0xaa, 0x9e, 0x0e, 0x3e, 0x1c, 0x81, 0xa3, 0x5d, 0xf1, - 0x9a, 0x67, 0x18, 0xfd, 0x3e, 0x25, 0x39, 0x0f, 0xa9, 0x82, 0x48, 0x5c, 0x32, 0x90, 0xb4, 0x71, - 0xd5, 0x32, 0x6b, 0xcc, 0xd3, 0xa3, 0xaa, 0x28, 0x92, 0x6e, 0x9b, 0xba, 0x69, 0xd9, 0xfc, 0x4b, - 0x1c, 0xac, 0x90, 0xff, 0x49, 0x69, 0x6f, 0xf9, 0xc2, 0xb8, 0x68, 0x49, 0x74, 0xf3, 0xcc, 0xc0, - 0x23, 0xe5, 0xab, 0xa4, 0x97, 0x6e, 0x27, 0x02, 0xc7, 0xca, 0xc3, 0x6a, 0xe5, 0x27, 0x22, 0x30, - 0x1b, 0xd6, 0x0a, 0x49, 0xdb, 0x6c, 0x47, 0x6f, 0xb6, 0xfa, 0xa9, 0xe5, 0x11, 0x48, 0x57, 0x04, - 0xce, 0x9e, 0xf5, 0x72, 0x63, 0x8f, 0x7a, 0x99, 0x70, 0x9b, 0x12, 0x8a, 0x39, 0x3b, 0xa4, 0x62, - 0xdc, 0x7e, 0xdc, 0x92, 0x66, 0x3e, 0x1d, 0x83, 0x23, 0xf4, 0x6b, 0x4f, 0xed, 0xa6, 0x61, 0x3a, - 0xa7, 0xab, 0xed, 0x9d, 0x96, 0x43, 0x13, 0x37, 0x6b, 0x8b, 0xeb, 0x65, 0xca, 0xab, 0x9e, 0x63, - 0xd5, 0x7d, 0x3c, 0x67, 0x0b, 0xe2, 0xeb, 0x84, 0x8e, 0x68, 0xc4, 0xb1, 0x1c, 0xbd, 0xc1, 0x35, - 0xc5, 0x0a, 0x04, 0xca, 0xbe, 0x10, 0x15, 0x61, 0x50, 0x43, 0x7c, 0x1c, 0xaa, 0x81, 0xf5, 0x2d, - 0xf6, 0x95, 0x8c, 0x28, 0x75, 0xa8, 0x14, 0x01, 0xd0, 0x0f, 0x62, 0xcc, 0x40, 0x5c, 0xef, 0xb0, - 0x1b, 0x44, 0x51, 0xe2, 0x69, 0xb4, 0xa0, 0x3c, 0x06, 0x49, 0x7e, 0xa0, 0x8c, 0x64, 0x88, 0x5e, - 0xc5, 0x3b, 0xb4, 0x9d, 0x31, 0x95, 0xfc, 0x89, 0xe6, 0x20, 0x4e, 0x85, 0xe7, 0x13, 0x48, 0x66, - 0xae, 0x4b, 0xfa, 0x39, 0x2a, 0xa4, 0xca, 0xd0, 0x94, 0xcb, 0x90, 0x2a, 0x58, 0x4d, 0xc3, 0xb4, - 0x82, 0xdc, 0xd2, 0x8c, 0x1b, 0x95, 0xb9, 0xd5, 0x71, 0xc4, 0x03, 0x52, 0x5a, 0x40, 0xfb, 0x21, - 0xc1, 0xbe, 0x9a, 0xc2, 0x6f, 0x41, 0xf1, 0x92, 0xb2, 0x00, 0x49, 0xca, 0x7b, 0xad, 0xe5, 0x7e, - 0xcd, 0x4c, 0xf2, 0x7d, 0xcd, 0x8c, 0xb3, 0x8f, 0x78, 0xc2, 0x22, 0x88, 0xd5, 0x74, 0x47, 0xe7, - 0xfd, 0xa6, 0x7f, 0x2b, 0x6f, 0x85, 0x14, 0x67, 0x62, 0xa3, 0xb3, 0x10, 0xb5, 0x5a, 0xe2, 0x92, - 0x5f, 0xb6, 0x5f, 0x57, 0xd6, 0x5a, 0xf9, 0x18, 0x49, 0x17, 0x55, 0x82, 0x9c, 0x57, 0xfb, 0x06, - 0xd5, 0x0b, 0xbe, 0xa0, 0xea, 0x1b, 0x72, 0xdf, 0x9f, 0x6c, 0x48, 0xbb, 0xcc, 0xc1, 0x35, 0x96, - 0xbf, 0x92, 0xe0, 0x70, 0xb7, 0xb1, 0x5c, 0xc5, 0x3b, 0xf6, 0x5e, 0x6d, 0xe5, 0x49, 0x48, 0xaf, - 0xd3, 0x2f, 0xae, 0x3e, 0x86, 0x77, 0x50, 0x16, 0x92, 0xb8, 0x76, 0xf6, 0xdc, 0xb9, 0x33, 0x17, - 0xd9, 0x48, 0x2e, 0x8d, 0xa8, 0x02, 0x30, 0x9f, 0x22, 0x29, 0xf5, 0xab, 0x1f, 0x9f, 0x95, 0xf2, - 0x71, 0x88, 0xda, 0x9d, 0x26, 0xbb, 0x32, 0x77, 0x39, 0x96, 0x8a, 0xca, 0x31, 0x35, 0x6d, 0xe3, - 0x6a, 0xeb, 0xec, 0xb9, 0xf3, 0x57, 0xcf, 0xa8, 0x49, 0xbb, 0x4d, 0x09, 0xde, 0xd0, 0xfe, 0x7f, - 0x34, 0x0e, 0xc7, 0xfc, 0x94, 0xd4, 0x0b, 0xdd, 0x19, 0x97, 0xeb, 0x40, 0xf6, 0xe9, 0x80, 0x62, - 0xf4, 0x56, 0x41, 0x76, 0x57, 0x4d, 0x2a, 0xbf, 0x24, 0xc1, 0x98, 0x9b, 0x06, 0x94, 0xb1, 0x83, - 0x1e, 0xf1, 0xcf, 0xed, 0xdc, 0x24, 0x0e, 0xcd, 0x85, 0xdb, 0xf2, 0xd2, 0x15, 0xd5, 0x87, 0x8e, - 0x1e, 0x86, 0x54, 0xab, 0x6d, 0xb5, 0x2c, 0x9b, 0x7f, 0x48, 0x69, 0x00, 0xa9, 0x8b, 0x8c, 0xee, - 0x07, 0x44, 0xbd, 0x57, 0xbb, 0x66, 0x39, 0x86, 0x59, 0xd7, 0x5a, 0xd6, 0x33, 0xfc, 0x0b, 0x77, - 0x51, 0x55, 0xa6, 0x35, 0x57, 0x68, 0xc5, 0x3a, 0x81, 0x13, 0xa1, 0xd3, 0x2e, 0x97, 0x60, 0xea, - 0x42, 0x0c, 0x5c, 0x14, 0xd1, 0x23, 0x90, 0x6c, 0x75, 0x36, 0x35, 0xe1, 0x0d, 0xa3, 0x67, 0x0f, - 0xf7, 0xb2, 0x6d, 0x61, 0x1f, 0xdc, 0xba, 0x13, 0xad, 0xce, 0x26, 0xb1, 0x96, 0x3b, 0x60, 0xac, - 0x87, 0x30, 0xa3, 0xd7, 0x3c, 0x39, 0xe8, 0x87, 0x7e, 0x79, 0x0f, 0xb4, 0x56, 0xdb, 0xb0, 0xda, - 0x86, 0xb3, 0x43, 0x73, 0xb3, 0xa8, 0x2a, 0x8b, 0x8a, 0x75, 0x0e, 0x57, 0xae, 0xc2, 0x64, 0x99, - 0x2e, 0x1a, 0x3c, 0xc9, 0xcf, 0x79, 0xf2, 0x49, 0x83, 0xe5, 0xeb, 0x2b, 0x59, 0xa4, 0x4b, 0xb2, - 0xfc, 0xe3, 0x7d, 0xad, 0xf3, 0xe1, 0xbd, 0x5b, 0x67, 0x30, 0xfb, 0x79, 0x45, 0x82, 0xa3, 0xbe, - 0xca, 0x6b, 0xb8, 0x6d, 0x1b, 0x96, 0xc9, 0x93, 0x6d, 0x66, 0x9a, 0xc8, 0xd7, 0x0b, 0x5e, 0xdf, - 0xc7, 0x3f, 0x2f, 0x42, 0x7a, 0xc1, 0x32, 0x6d, 0x6c, 0xda, 0x1d, 0x3a, 0xc3, 0x6d, 0x36, 0xac, - 0xea, 0x55, 0xaa, 0x8c, 0x98, 0xca, 0x0a, 0x24, 0x9c, 0xe9, 0xad, 0x16, 0xed, 0x64, 0x4c, 0x25, - 0x7f, 0xb2, 0xe5, 0x6f, 0xbe, 0xdc, 0xb7, 0x8b, 0x17, 0xf7, 0xde, 0x45, 0x2e, 0xa5, 0xdb, 0xc9, - 0x97, 0x25, 0x98, 0x20, 0x53, 0x85, 0xbe, 0x29, 0x26, 0x4f, 0x94, 0x12, 0xe5, 0x21, 0x16, 0xaa, - 0x8f, 0x82, 0x8b, 0x3d, 0xc4, 0xc9, 0xc9, 0xc7, 0x7f, 0xed, 0x0b, 0x12, 0xdb, 0x09, 0x14, 0x44, - 0xf9, 0x52, 0xdf, 0xce, 0x9d, 0x1e, 0xb2, 0x73, 0x82, 0x95, 0xdb, 0xa5, 0xdf, 0xbb, 0x3b, 0x10, - 0x54, 0x59, 0x50, 0xf1, 0x8f, 0xda, 0xb0, 0x01, 0x65, 0x50, 0x86, 0x93, 0xdd, 0x7d, 0xa2, 0xcf, - 0x0e, 0x0c, 0x6d, 0xd9, 0x01, 0xf6, 0x95, 0x0d, 0x0d, 0x8d, 0xf2, 0x03, 0x30, 0xbe, 0xae, 0xb7, - 0x9d, 0x32, 0x76, 0x96, 0xb0, 0x5e, 0xc3, 0x6d, 0x74, 0xd0, 0x9f, 0x19, 0x8c, 0x2f, 0x8d, 0xf0, - 0xdc, 0xe0, 0x79, 0x49, 0x42, 0x07, 0x20, 0x46, 0x73, 0x00, 0x3a, 0x3d, 0x2e, 0x49, 0x2a, 0x2d, - 0x3d, 0x2f, 0x49, 0xf3, 0x89, 0x2f, 0x3e, 0xff, 0xca, 0x67, 0xc6, 0xa4, 0x7c, 0x0a, 0x12, 0x1a, - 0xc5, 0xce, 0x27, 0x21, 0x4e, 0xf3, 0x05, 0x65, 0x1b, 0x62, 0xf4, 0x1d, 0x9e, 0x9b, 0x5a, 0x50, - 0xb6, 0x22, 0xb5, 0x20, 0x66, 0xbb, 0xe3, 0xf0, 0x77, 0xca, 0x63, 0x2a, 0x2b, 0xa0, 0x87, 0x44, - 0x82, 0x10, 0xdd, 0x3d, 0x41, 0xe0, 0x51, 0x87, 0xa7, 0x09, 0xff, 0xbf, 0x04, 0xc9, 0x3c, 0x31, - 0xfb, 0x52, 0xc1, 0x95, 0x54, 0xcc, 0x55, 0x42, 0x52, 0xb4, 0x0c, 0x93, 0x2d, 0xbd, 0xed, 0xd0, - 0x6f, 0xfb, 0x6c, 0xd3, 0x0e, 0xf3, 0xf0, 0x36, 0xdb, 0x1d, 0x6c, 0x03, 0x7a, 0x59, 0x92, 0xd4, - 0xf1, 0x96, 0x1f, 0xe0, 0xef, 0xb7, 0xe8, 0x6d, 0x1e, 0x81, 0xac, 0x85, 0xf8, 0x2b, 0x7f, 0x12, - 0x83, 0x04, 0xd7, 0xed, 0xf7, 0x40, 0x92, 0x8f, 0x09, 0x0f, 0x5a, 0x47, 0xe6, 0xba, 0xdd, 0x7d, - 0xce, 0xf5, 0x6a, 0xde, 0x3f, 0x41, 0x83, 0x8e, 0x43, 0xaa, 0xba, 0xad, 0x1b, 0xa6, 0x66, 0xd4, - 0xc4, 0x16, 0xd7, 0x2b, 0x37, 0x67, 0x93, 0x0b, 0x04, 0x56, 0x2a, 0xa8, 0x49, 0x5a, 0x59, 0xaa, - 0x91, 0xe4, 0x67, 0x1b, 0x1b, 0xf5, 0x6d, 0x87, 0x07, 0x5e, 0x5e, 0x42, 0x17, 0x20, 0x46, 0xec, - 0x8d, 0x5f, 0xaa, 0xcf, 0x76, 0x39, 0x97, 0x9b, 0xdf, 0xe6, 0x53, 0xa4, 0xe1, 0x0f, 0x7e, 0x65, - 0x56, 0x52, 0x29, 0x05, 0x5a, 0x80, 0xf1, 0x86, 0x6e, 0x3b, 0x1a, 0x0d, 0x2b, 0xa4, 0xf9, 0x38, - 0xdf, 0x62, 0xe8, 0x52, 0x1a, 0x1f, 0x01, 0x2e, 0xfa, 0x28, 0xa1, 0x62, 0xa0, 0x1a, 0x3a, 0x01, - 0x32, 0x65, 0x52, 0xb5, 0x9a, 0x4d, 0xc3, 0x61, 0xe9, 0x64, 0x82, 0x8e, 0xfb, 0x04, 0x81, 0x2f, - 0x50, 0x30, 0x4d, 0x2a, 0x0f, 0x41, 0x9a, 0x7e, 0xe4, 0x8a, 0xa2, 0xb0, 0x67, 0xa2, 0x29, 0x02, - 0xa0, 0x95, 0xf7, 0xc0, 0xa4, 0x37, 0x6d, 0x32, 0x94, 0x14, 0xe3, 0xe2, 0x81, 0x29, 0xe2, 0x03, - 0x30, 0x63, 0xe2, 0xeb, 0x8e, 0x16, 0xc6, 0x4e, 0x53, 0x6c, 0x44, 0xea, 0xae, 0x04, 0x29, 0xee, - 0x86, 0x89, 0xaa, 0x50, 0x3e, 0xc3, 0x05, 0x8a, 0x3b, 0xee, 0x42, 0x29, 0xda, 0x41, 0x48, 0xe9, - 0xad, 0x16, 0x43, 0x18, 0xe5, 0xd3, 0x66, 0xab, 0x45, 0xab, 0x4e, 0xc2, 0x14, 0xed, 0x63, 0x1b, - 0xdb, 0x9d, 0x86, 0xc3, 0x99, 0x8c, 0x51, 0x9c, 0x49, 0x52, 0xa1, 0x32, 0x38, 0xc5, 0xbd, 0x13, - 0xc6, 0xf1, 0x35, 0xa3, 0x86, 0xcd, 0x2a, 0x66, 0x78, 0xe3, 0x14, 0x6f, 0x4c, 0x00, 0x29, 0xd2, - 0xbd, 0xe0, 0x4e, 0x87, 0x9a, 0x98, 0xaa, 0x27, 0x18, 0x3f, 0x01, 0xcf, 0x31, 0xb0, 0x92, 0x81, - 0x58, 0x41, 0x77, 0x74, 0x12, 0xf5, 0x9d, 0xeb, 0x2c, 0xff, 0x18, 0x53, 0xc9, 0x9f, 0xca, 0x51, - 0x88, 0x57, 0xae, 0x93, 0xe9, 0x6f, 0x1f, 0x24, 0x9c, 0xeb, 0x9a, 0x97, 0x8f, 0xc7, 0x1d, 0x02, - 0x56, 0x7e, 0x2e, 0x06, 0xb1, 0x2b, 0x96, 0x83, 0xa9, 0x85, 0x78, 0xdf, 0x41, 0xea, 0xe1, 0x13, - 0x65, 0xa3, 0x6e, 0xe2, 0xda, 0x8a, 0x5d, 0x27, 0x4b, 0x14, 0xe2, 0x58, 0x04, 0x4c, 0x1c, 0xeb, - 0x90, 0x6b, 0x73, 0x74, 0x4a, 0x5d, 0x92, 0x84, 0xd5, 0x91, 0xca, 0x83, 0x10, 0x6f, 0x5b, 0x1d, - 0x93, 0x7d, 0xeb, 0x21, 0xbe, 0x14, 0x51, 0x59, 0x91, 0x54, 0x5d, 0x84, 0x94, 0x6b, 0x54, 0xb1, - 0x01, 0x46, 0xb5, 0x14, 0x55, 0x93, 0x9b, 0xcc, 0x98, 0x08, 0xe9, 0x03, 0x30, 0xe5, 0x0e, 0xad, - 0xab, 0x1b, 0x6a, 0x50, 0x4b, 0x31, 0x55, 0x76, 0xab, 0xb8, 0x7a, 0x08, 0xc5, 0xfd, 0x3e, 0xd3, - 0xe1, 0xdf, 0xc2, 0x4d, 0x52, 0x89, 0xe2, 0x3e, 0xe3, 0xa1, 0x5f, 0xc4, 0x25, 0xd8, 0x77, 0x40, - 0xda, 0x36, 0xea, 0x26, 0x7d, 0xf7, 0xc1, 0x4c, 0x6c, 0x29, 0xa1, 0x7a, 0x20, 0x82, 0x72, 0xb7, - 0xff, 0x3b, 0xef, 0xd4, 0xae, 0xf2, 0x91, 0x8c, 0xb4, 0x94, 0xf4, 0x7d, 0xc6, 0x9d, 0xa0, 0x5d, - 0x80, 0x69, 0xef, 0x1b, 0xea, 0x1e, 0x4f, 0x70, 0x09, 0x52, 0x2a, 0x72, 0x11, 0xca, 0xbe, 0x06, - 0x02, 0x11, 0x86, 0xe8, 0x22, 0x9f, 0x86, 0xa4, 0xc6, 0x14, 0x4b, 0xa3, 0x2d, 0xd5, 0x63, 0x7e, - 0x14, 0xd2, 0xae, 0x6b, 0xe6, 0x67, 0x00, 0x69, 0x5d, 0x7a, 0xa1, 0x91, 0x29, 0xd4, 0xf7, 0xfc, - 0x18, 0x80, 0x27, 0x0d, 0x2d, 0xb9, 0x42, 0xe4, 0xf7, 0xc3, 0x8c, 0xd6, 0x43, 0x66, 0xe5, 0x37, - 0x24, 0x48, 0x30, 0x4f, 0xf5, 0x85, 0x19, 0x29, 0x10, 0x66, 0x66, 0xc4, 0x68, 0xf3, 0xd5, 0x36, - 0x2d, 0xa0, 0xa2, 0x6f, 0xa0, 0xa3, 0x83, 0xa2, 0xc7, 0x24, 0x89, 0x1e, 0x24, 0xb6, 0x71, 0x80, - 0x3b, 0xee, 0x28, 0x07, 0xe0, 0x0a, 0x63, 0xf3, 0xcf, 0xb3, 0xf6, 0x48, 0x94, 0x99, 0x88, 0x65, - 0xa3, 0xce, 0x03, 0x91, 0x8f, 0x48, 0xf9, 0xf7, 0x12, 0xc9, 0x9c, 0x78, 0x3d, 0xca, 0xc1, 0xb8, - 0x90, 0x4b, 0xdb, 0x6a, 0xe8, 0x75, 0x6e, 0xfb, 0x47, 0xfa, 0x0a, 0x77, 0xa9, 0xa1, 0xd7, 0xd5, - 0x51, 0x2e, 0x0f, 0x29, 0x90, 0x5c, 0xb6, 0xdb, 0x10, 0xd9, 0x8c, 0xd6, 0x65, 0x86, 0x28, 0x0f, - 0x69, 0x77, 0xd2, 0xe7, 0x8a, 0x18, 0x2e, 0x12, 0x7b, 0x64, 0xe8, 0xb0, 0xdf, 0x32, 0x63, 0xb4, - 0x21, 0x0f, 0xa0, 0xfc, 0x7a, 0x8c, 0xae, 0x4f, 0x5b, 0x96, 0xad, 0x37, 0xd0, 0x83, 0x7b, 0xf2, - 0x68, 0xbe, 0x0c, 0xde, 0x1f, 0x74, 0xe6, 0xee, 0x91, 0x8d, 0xfa, 0x47, 0xf6, 0x10, 0xa4, 0x5b, - 0x56, 0x83, 0x99, 0x22, 0x7f, 0xb3, 0x92, 0x6a, 0x59, 0x0d, 0xb5, 0x6b, 0xd8, 0xe3, 0xb7, 0x3e, - 0xec, 0x01, 0xad, 0x25, 0x6e, 0x83, 0xd6, 0x92, 0x21, 0xad, 0xa1, 0x07, 0x20, 0xc9, 0x42, 0xa3, - 0xcd, 0x7f, 0x8a, 0xe0, 0x40, 0xb7, 0x9c, 0x34, 0x88, 0xaa, 0x09, 0x1a, 0x34, 0x6d, 0x34, 0x0f, - 0x29, 0x11, 0xaa, 0xf9, 0x0f, 0x5b, 0x1c, 0xed, 0x26, 0x29, 0x72, 0x8c, 0x65, 0xc3, 0x76, 0x54, - 0x17, 0x1f, 0x5d, 0x84, 0x51, 0xdf, 0x5c, 0x48, 0x23, 0x41, 0x28, 0xd1, 0xf1, 0xdb, 0xb1, 0x0a, - 0xde, 0x04, 0x89, 0xce, 0x93, 0xc1, 0xa1, 0x99, 0xcb, 0x68, 0x3f, 0x2a, 0x96, 0x6e, 0x88, 0x45, - 0x19, 0xc3, 0xee, 0x39, 0x93, 0x8c, 0xf5, 0x9e, 0x49, 0xda, 0x30, 0xc6, 0xcc, 0x82, 0xe7, 0x2d, - 0x0f, 0xb8, 0x4d, 0x4a, 0xbb, 0x37, 0xe9, 0x36, 0xf6, 0x00, 0x24, 0x78, 0xd7, 0x22, 0x03, 0xba, - 0xc6, 0xf1, 0x94, 0x1f, 0x97, 0x00, 0x96, 0x69, 0x5c, 0xa3, 0x4b, 0x97, 0x05, 0x18, 0xb7, 0xa9, - 0x08, 0x5a, 0xa0, 0xe5, 0xa3, 0xfd, 0x0c, 0x98, 0xb7, 0x3f, 0x66, 0xfb, 0xe5, 0x5e, 0x80, 0x71, - 0xcf, 0x31, 0x6d, 0x2c, 0x84, 0x39, 0xba, 0xcb, 0xc2, 0xba, 0x8c, 0x1d, 0x75, 0xec, 0x9a, 0xaf, - 0xa4, 0xfc, 0x33, 0x09, 0xd2, 0x54, 0xa6, 0x15, 0xec, 0xe8, 0x01, 0x7b, 0x96, 0x6e, 0xdd, 0x9e, - 0x8f, 0x00, 0x30, 0x36, 0xb6, 0xf1, 0x2c, 0xe6, 0x5e, 0x96, 0xa6, 0x90, 0xb2, 0xf1, 0x2c, 0xf6, - 0x8d, 0x71, 0x74, 0x4f, 0x63, 0x7c, 0x00, 0x92, 0xf4, 0x33, 0x11, 0xd7, 0x6d, 0xbe, 0x96, 0x4e, - 0x98, 0x9d, 0x66, 0xe5, 0xba, 0xad, 0x3c, 0x0d, 0xc9, 0xca, 0x75, 0xb6, 0xf5, 0x77, 0x08, 0xd2, - 0x6d, 0xcb, 0xe2, 0xf9, 0x17, 0x4b, 0x03, 0x52, 0x04, 0x40, 0xd3, 0x0d, 0xb1, 0xdd, 0x15, 0xf1, - 0xb6, 0xbb, 0xbc, 0xfd, 0xba, 0xe8, 0x70, 0xfb, 0x75, 0x5f, 0x95, 0x20, 0x25, 0xcc, 0x1e, 0xe9, - 0x70, 0xa0, 0xd6, 0x69, 0x35, 0x8c, 0x2a, 0xfd, 0xa2, 0x87, 0xe5, 0x60, 0xcd, 0xf5, 0x19, 0xa6, - 0xbe, 0x7b, 0xba, 0xbb, 0x56, 0x10, 0x04, 0x24, 0x27, 0x11, 0x9c, 0x96, 0x46, 0xd4, 0x7d, 0xb5, - 0x5e, 0x15, 0xc8, 0x84, 0xc3, 0x0d, 0x62, 0x38, 0x1a, 0xff, 0xbe, 0xb1, 0xee, 0x38, 0x7a, 0xf5, - 0xaa, 0xd7, 0x0e, 0x1b, 0xf4, 0xfb, 0xba, 0xdb, 0xa1, 0xe6, 0xb6, 0x40, 0x89, 0x72, 0x94, 0xc6, - 0xd7, 0xd6, 0xc1, 0x46, 0xbf, 0x4a, 0xbe, 0xcb, 0xa5, 0x7c, 0x30, 0x02, 0xfb, 0x7a, 0x4a, 0x8a, - 0x4e, 0x41, 0x82, 0xf6, 0x54, 0xe7, 0x5d, 0xdc, 0xdf, 0xc3, 0xde, 0x2c, 0x07, 0xab, 0x71, 0x82, - 0x95, 0x73, 0xd1, 0x37, 0xb9, 0xa4, 0xbb, 0xa2, 0xe7, 0xf7, 0xb6, 0xdf, 0x13, 0xc8, 0x96, 0x39, - 0x2a, 0xb3, 0x0c, 0x2f, 0xe1, 0x61, 0x88, 0x81, 0x08, 0x1b, 0xbf, 0xa5, 0x08, 0xab, 0xfc, 0x6e, - 0x04, 0x0e, 0xf6, 0x55, 0x2a, 0x2a, 0xc1, 0x94, 0xf8, 0x64, 0x17, 0x91, 0xdb, 0xdb, 0xaf, 0x08, - 0x6d, 0xde, 0xf8, 0x06, 0x87, 0xfa, 0x8d, 0x2a, 0xfb, 0xc8, 0x58, 0x74, 0xb8, 0x13, 0xc6, 0x49, - 0xd8, 0xb0, 0x4c, 0x2d, 0x30, 0x4f, 0x8d, 0x31, 0xe0, 0x12, 0x9b, 0xad, 0x56, 0x61, 0x66, 0x73, - 0xe7, 0x59, 0xdd, 0x74, 0x0c, 0x13, 0xfb, 0x16, 0x01, 0xfc, 0x87, 0x74, 0x76, 0xdd, 0x5d, 0x9b, - 0x76, 0x09, 0x7d, 0xe7, 0x7c, 0xbd, 0x15, 0x1f, 0xeb, 0xa3, 0xf8, 0xdb, 0xa1, 0xcf, 0x65, 0x18, - 0xf3, 0xcf, 0x1f, 0xe8, 0x2d, 0xbe, 0x19, 0xa7, 0xc7, 0x8e, 0x73, 0x70, 0xc6, 0xe1, 0xa1, 0xc1, - 0xa5, 0x38, 0xf9, 0x6f, 0x25, 0x18, 0xf5, 0xe5, 0x30, 0xe8, 0x0c, 0xec, 0xcb, 0x2f, 0xaf, 0x2d, - 0x3c, 0xa6, 0x95, 0x0a, 0xda, 0xa5, 0xe5, 0x9c, 0xef, 0x43, 0x03, 0xd9, 0xfd, 0x2f, 0xdc, 0x38, - 0x86, 0x7c, 0xb8, 0x1b, 0x26, 0x3d, 0xc8, 0x40, 0xa7, 0x61, 0x26, 0x48, 0x92, 0xcb, 0x97, 0x8b, - 0xab, 0x15, 0x59, 0xca, 0xee, 0x7b, 0xe1, 0xc6, 0xb1, 0x29, 0x1f, 0x45, 0x6e, 0xd3, 0xc6, 0xa6, - 0xd3, 0x4d, 0xb0, 0xb0, 0xb6, 0xb2, 0x52, 0xaa, 0xc8, 0x91, 0x2e, 0x02, 0x3e, 0xbb, 0xdd, 0x0b, - 0x53, 0x41, 0x82, 0xd5, 0xd2, 0xb2, 0x1c, 0xcd, 0xa2, 0x17, 0x6e, 0x1c, 0x9b, 0xf0, 0x61, 0xaf, - 0x1a, 0x8d, 0x6c, 0xea, 0xf9, 0x4f, 0x1e, 0x1d, 0xf9, 0xb9, 0x9f, 0x39, 0x2a, 0x91, 0x9e, 0x8d, - 0x07, 0xf2, 0x18, 0x74, 0x3f, 0x1c, 0x28, 0x97, 0x16, 0x57, 0x8b, 0x05, 0x6d, 0xa5, 0xbc, 0x18, - 0xfa, 0x60, 0x44, 0x76, 0xf2, 0x85, 0x1b, 0xc7, 0x46, 0x79, 0x97, 0xfa, 0x61, 0xaf, 0xab, 0xc5, - 0x2b, 0x6b, 0x95, 0xa2, 0x2c, 0x31, 0xec, 0xf5, 0x36, 0x26, 0xde, 0x47, 0xb1, 0x1f, 0x80, 0x83, - 0x3d, 0xb0, 0xdd, 0x8e, 0x4d, 0xbd, 0x70, 0xe3, 0xd8, 0xf8, 0x7a, 0x1b, 0xb3, 0x79, 0x8d, 0x52, - 0xcc, 0x41, 0xa6, 0x9b, 0x62, 0x6d, 0x7d, 0xad, 0x9c, 0x5b, 0x96, 0x8f, 0x65, 0xe5, 0x17, 0x6e, - 0x1c, 0x1b, 0x13, 0x09, 0x1b, 0x3d, 0x5f, 0x76, 0x7b, 0xf6, 0x46, 0x6e, 0x46, 0xfe, 0xc5, 0x19, - 0xb8, 0xab, 0xcf, 0xd5, 0x06, 0x71, 0x28, 0xfe, 0xd7, 0x7b, 0xb9, 0x21, 0xdb, 0xff, 0x64, 0x38, - 0x3b, 0xe0, 0xc0, 0x74, 0xf0, 0xc6, 0xda, 0xae, 0xfb, 0x77, 0xca, 0xfb, 0x24, 0x98, 0x58, 0x32, - 0x6c, 0xc7, 0x6a, 0x1b, 0x55, 0xbd, 0x41, 0x1f, 0x8c, 0x9f, 0x1f, 0x36, 0xe7, 0x09, 0x4d, 0xc1, - 0x8f, 0x42, 0xe2, 0x9a, 0xde, 0x60, 0xc9, 0x46, 0x94, 0xfe, 0xea, 0x41, 0x9f, 0x9b, 0x06, 0x6e, - 0x64, 0x11, 0x0c, 0x18, 0x99, 0xf2, 0x0b, 0x11, 0x98, 0xa4, 0xce, 0x60, 0xb3, 0x9f, 0xfd, 0x71, - 0xe8, 0xe7, 0x0c, 0x62, 0x6d, 0xdd, 0xe1, 0x67, 0x55, 0xf9, 0x39, 0x7e, 0xf3, 0xe8, 0xf8, 0x10, - 0x57, 0x38, 0x0a, 0xb8, 0xaa, 0x52, 0x5a, 0xf4, 0x76, 0x48, 0x35, 0xf5, 0xeb, 0x1a, 0xe5, 0xc3, - 0x76, 0x8f, 0x72, 0x7b, 0xe3, 0xf3, 0xda, 0xcd, 0xd9, 0xc9, 0x1d, 0xbd, 0xd9, 0x98, 0x57, 0x04, - 0x1f, 0x45, 0x4d, 0x36, 0xf5, 0xeb, 0x44, 0x44, 0xd4, 0xa2, 0x1f, 0x95, 0xd0, 0xaa, 0xdb, 0xba, - 0x59, 0xc7, 0xac, 0x11, 0x7a, 0xf2, 0x96, 0x5f, 0xda, 0x73, 0x23, 0xfb, 0xbd, 0x46, 0x7c, 0xec, - 0x14, 0x75, 0xbc, 0xa9, 0x5f, 0x5f, 0xa0, 0x00, 0xd2, 0xe2, 0x7c, 0xea, 0xc5, 0x97, 0x66, 0x47, - 0xe8, 0x6d, 0xae, 0x2f, 0x4b, 0x00, 0x9e, 0xc6, 0xd0, 0xdb, 0x41, 0xae, 0xba, 0x25, 0x4a, 0x6b, - 0xbb, 0xb9, 0x46, 0x9f, 0xb1, 0x08, 0xe9, 0x9b, 0x45, 0xe3, 0x97, 0x6f, 0xce, 0x4a, 0xea, 0x64, - 0x35, 0x34, 0x14, 0xdf, 0x07, 0xa3, 0x9d, 0x56, 0x8d, 0x64, 0x33, 0x74, 0x2f, 0x2d, 0x32, 0x30, - 0xb2, 0x1f, 0x25, 0xbc, 0x5e, 0xbb, 0x39, 0x8b, 0x58, 0xb7, 0x7c, 0xc4, 0x0a, 0x8d, 0xf7, 0xc0, - 0x20, 0x84, 0xc0, 0xd7, 0xa7, 0xdf, 0xa6, 0x3f, 0xd8, 0xe4, 0x5d, 0xe5, 0xcf, 0x40, 0xb2, 0x69, - 0x99, 0xc6, 0x55, 0x6e, 0x8f, 0x69, 0x55, 0x14, 0x51, 0x16, 0x52, 0xec, 0x43, 0x6f, 0xce, 0x8e, - 0xf8, 0x75, 0x20, 0x51, 0x26, 0x54, 0xcf, 0xe0, 0x4d, 0xdb, 0x10, 0xa3, 0xa1, 0x8a, 0x22, 0xba, - 0x04, 0xb2, 0x8d, 0xab, 0x9d, 0xb6, 0xe1, 0xec, 0x68, 0x55, 0xcb, 0x74, 0xf4, 0x2a, 0xfb, 0x84, - 0x63, 0x3a, 0x7f, 0xe8, 0xb5, 0x9b, 0xb3, 0x07, 0x98, 0xac, 0x61, 0x0c, 0x45, 0x9d, 0x14, 0xa0, - 0x05, 0x06, 0x21, 0x2d, 0xd4, 0xb0, 0xa3, 0x1b, 0x0d, 0xf6, 0x85, 0x8d, 0xb4, 0x2a, 0x8a, 0xbe, - 0xbe, 0x7c, 0x36, 0xe9, 0x3f, 0x73, 0xba, 0x04, 0xb2, 0xd5, 0xc2, 0xed, 0xc0, 0x62, 0x59, 0x0a, - 0xb7, 0x1c, 0xc6, 0x50, 0xd4, 0x49, 0x01, 0x12, 0x0b, 0x69, 0x87, 0x0c, 0xb3, 0xd8, 0xac, 0x6b, - 0x75, 0x36, 0xbd, 0xa3, 0xaa, 0x99, 0xae, 0xd1, 0xc8, 0x99, 0x3b, 0xf9, 0x07, 0x3d, 0xee, 0x61, - 0x3a, 0xe5, 0x4b, 0x9f, 0x3f, 0x35, 0xc3, 0x4d, 0xc3, 0x3b, 0x3a, 0x22, 0x6b, 0xbd, 0x49, 0x17, - 0x75, 0x9d, 0x62, 0x92, 0xa5, 0xf1, 0xd3, 0xba, 0xd1, 0x10, 0xdf, 0x2d, 0x55, 0x79, 0x09, 0xcd, - 0x43, 0xc2, 0x76, 0x74, 0xa7, 0x63, 0xf3, 0x0b, 0x46, 0x4a, 0x3f, 0x53, 0xcb, 0x5b, 0x66, 0xad, - 0x4c, 0x31, 0x55, 0x4e, 0x81, 0x2e, 0x41, 0x82, 0xdf, 0xdc, 0x8a, 0xef, 0xd9, 0xbf, 0xe9, 0x3d, - 0x49, 0x46, 0x4d, 0x34, 0x52, 0xc3, 0x0d, 0x5c, 0x67, 0xcb, 0x9d, 0x6d, 0xbd, 0x8d, 0xd9, 0x7e, - 0x58, 0x3a, 0x5f, 0xda, 0xb3, 0x13, 0x72, 0x4d, 0x85, 0xf9, 0x29, 0xea, 0xa4, 0x0b, 0x2a, 0x53, - 0x08, 0x7a, 0x2c, 0xf0, 0xe6, 0x84, 0x7f, 0x51, 0xf5, 0xce, 0x7e, 0xdd, 0xf7, 0xd9, 0xb4, 0xd8, - 0x23, 0xf6, 0xbf, 0x58, 0xb9, 0x04, 0x72, 0xc7, 0xdc, 0xb4, 0x4c, 0xfa, 0xc5, 0x11, 0x9e, 0xdb, - 0xa5, 0x48, 0x86, 0xe5, 0x37, 0x8e, 0x30, 0x86, 0xa2, 0x4e, 0xba, 0x20, 0x9e, 0xfb, 0xd5, 0x60, - 0xc2, 0xc3, 0xa2, 0x8e, 0x9a, 0x1e, 0xe8, 0xa8, 0x77, 0x70, 0x47, 0xdd, 0x17, 0x6e, 0xc5, 0xf3, - 0xd5, 0x71, 0x17, 0x48, 0xc8, 0xd0, 0x12, 0x80, 0x17, 0x1e, 0xf8, 0x22, 0x5e, 0x19, 0x1c, 0x63, - 0xc4, 0x9e, 0x94, 0x47, 0x8b, 0x7e, 0x10, 0xa6, 0x9b, 0x86, 0xa9, 0xd9, 0xb8, 0xb1, 0xa5, 0x71, - 0x05, 0x13, 0x96, 0xf4, 0xf7, 0x3c, 0xf2, 0xcb, 0x7b, 0xb3, 0x87, 0xd7, 0x6e, 0xce, 0x66, 0x79, - 0x08, 0xed, 0x66, 0xa9, 0xa8, 0x53, 0x4d, 0xc3, 0x2c, 0xe3, 0xc6, 0x56, 0xc1, 0x85, 0xcd, 0x8f, - 0x3d, 0xff, 0xd2, 0xec, 0x08, 0x77, 0xd7, 0x11, 0xe5, 0x3c, 0x3d, 0xd6, 0xe6, 0x6e, 0x86, 0x6d, - 0x74, 0x18, 0xd2, 0xba, 0x28, 0xf0, 0x1b, 0x6e, 0x1e, 0x80, 0xb9, 0xf9, 0x73, 0x7f, 0x74, 0x4c, - 0x52, 0x3e, 0x2b, 0x41, 0xa2, 0x70, 0x65, 0x5d, 0x37, 0xda, 0x24, 0xd5, 0xf7, 0x2c, 0x27, 0xe8, - 0xe4, 0x87, 0x5f, 0xbb, 0x39, 0x9b, 0x09, 0x1b, 0x97, 0xeb, 0xe5, 0x9e, 0x01, 0x0b, 0x37, 0x2f, - 0xf5, 0xdb, 0x5c, 0x0b, 0xb0, 0xea, 0x42, 0x51, 0xba, 0xb7, 0xde, 0x42, 0xdd, 0x2c, 0x42, 0x92, - 0x49, 0x6b, 0xa3, 0x79, 0x88, 0xb7, 0xc8, 0x1f, 0x3c, 0xa9, 0x3e, 0xda, 0xd7, 0x78, 0x29, 0xbe, - 0x7b, 0xec, 0x44, 0x48, 0x94, 0x0f, 0x45, 0x00, 0x0a, 0x57, 0xae, 0x54, 0xda, 0x46, 0xab, 0x81, - 0x9d, 0xdb, 0xd9, 0xf3, 0x0a, 0xec, 0xf3, 0xed, 0x5e, 0xb4, 0xab, 0xa1, 0xde, 0x1f, 0x7b, 0xed, - 0xe6, 0xec, 0xe1, 0x70, 0xef, 0x7d, 0x68, 0x8a, 0x3a, 0xed, 0xed, 0x63, 0xb4, 0xab, 0x3d, 0xb9, - 0xd6, 0x6c, 0xc7, 0xe5, 0x1a, 0xed, 0xcf, 0xd5, 0x87, 0xe6, 0xe7, 0x5a, 0xb0, 0x9d, 0xde, 0xaa, - 0x2d, 0xc3, 0xa8, 0xa7, 0x12, 0x1b, 0x15, 0x20, 0xe5, 0xf0, 0xbf, 0xb9, 0x86, 0x95, 0xfe, 0x1a, - 0x16, 0x64, 0x62, 0xf9, 0x22, 0x28, 0x95, 0xbf, 0x94, 0x00, 0x3c, 0x9b, 0x7d, 0x73, 0x9a, 0x18, - 0x09, 0xe5, 0x3c, 0xf0, 0x46, 0x6f, 0x29, 0x55, 0xe3, 0xd4, 0x21, 0x7d, 0xbe, 0x3f, 0x02, 0xd3, - 0x1b, 0x22, 0xf2, 0xbc, 0xe9, 0x75, 0xb0, 0x0e, 0x49, 0x6c, 0x3a, 0x6d, 0x03, 0x8b, 0xa5, 0xf6, - 0x03, 0xfd, 0x46, 0xbb, 0x47, 0x9f, 0xe8, 0xaf, 0x96, 0x88, 0x83, 0x4f, 0xce, 0x26, 0xa4, 0x8d, - 0x1f, 0x8d, 0x42, 0xa6, 0x1f, 0x25, 0x5a, 0x80, 0xc9, 0x6a, 0x1b, 0xb3, 0xfb, 0xbe, 0xfe, 0xd3, - 0x89, 0x7c, 0xd6, 0xcb, 0x2c, 0x43, 0x08, 0x8a, 0x3a, 0x21, 0x20, 0x7c, 0xf6, 0xa8, 0x03, 0x49, - 0xfb, 0x88, 0xd9, 0xd1, 0x6b, 0xc3, 0xc3, 0xe5, 0x79, 0x0a, 0x9f, 0x3e, 0x44, 0x23, 0x41, 0x06, - 0x6c, 0xfe, 0x98, 0xf0, 0xa0, 0x74, 0x02, 0x79, 0x07, 0x4c, 0x1a, 0xa6, 0xe1, 0x18, 0x7a, 0x43, - 0xdb, 0xd4, 0x1b, 0x3a, 0x59, 0xd7, 0xef, 0x3d, 0x6b, 0x66, 0x21, 0x9f, 0x37, 0x1b, 0x62, 0xa7, - 0xa8, 0x13, 0x1c, 0x92, 0x67, 0x00, 0xb4, 0x04, 0x49, 0xd1, 0x54, 0xec, 0x96, 0xb2, 0x0d, 0x41, - 0xee, 0x4b, 0xf0, 0x3e, 0x10, 0x85, 0x29, 0x15, 0xd7, 0xfe, 0xcf, 0x50, 0xec, 0x6d, 0x28, 0x56, - 0x00, 0x98, 0xbb, 0x93, 0x00, 0x7b, 0x0b, 0xa3, 0x41, 0x02, 0x46, 0x9a, 0x71, 0x28, 0xd8, 0x8e, - 0x6f, 0x3c, 0x6e, 0x46, 0x60, 0xcc, 0x3f, 0x1e, 0x7f, 0x47, 0x67, 0x25, 0x54, 0xf2, 0x22, 0x51, - 0x8c, 0xff, 0x94, 0x64, 0x9f, 0x48, 0xd4, 0x65, 0xbd, 0xbb, 0x87, 0xa0, 0xff, 0x9a, 0x80, 0xc4, - 0xba, 0xde, 0xd6, 0x9b, 0x36, 0xaa, 0x76, 0x65, 0x9a, 0xe2, 0x58, 0xa0, 0xeb, 0x47, 0xa4, 0xf9, - 0x96, 0xc5, 0x80, 0x44, 0xf3, 0xc5, 0x1e, 0x89, 0xe6, 0xf7, 0xc2, 0x04, 0x59, 0x0e, 0xfb, 0x36, - 0x31, 0x89, 0xb6, 0xc7, 0xf3, 0x07, 0x3d, 0x2e, 0xc1, 0x7a, 0xb6, 0x5a, 0xbe, 0xe2, 0xbf, 0x5e, - 0x38, 0x4a, 0x30, 0xbc, 0xc0, 0x4c, 0xc8, 0xf7, 0x7b, 0xcb, 0x52, 0x5f, 0xa5, 0xa2, 0x42, 0x53, - 0xbf, 0x5e, 0x64, 0x05, 0xb4, 0x0c, 0x68, 0xdb, 0xdd, 0x19, 0xd1, 0x3c, 0x75, 0x12, 0xfa, 0x23, - 0xaf, 0xdd, 0x9c, 0x3d, 0xc8, 0xe8, 0xbb, 0x71, 0x14, 0x75, 0xca, 0x03, 0x0a, 0x6e, 0x0f, 0x01, - 0x90, 0x7e, 0x69, 0xec, 0xf9, 0x16, 0x5b, 0xee, 0xec, 0x7b, 0xed, 0xe6, 0xec, 0x14, 0xe3, 0xe2, - 0xd5, 0x29, 0x6a, 0x9a, 0x14, 0x0a, 0xf4, 0x65, 0x17, 0xcf, 0x8e, 0x43, 0xab, 0x7a, 0xbe, 0xb6, - 0x59, 0xde, 0xf3, 0xda, 0xc6, 0x97, 0x1d, 0x87, 0x58, 0xb2, 0xec, 0x38, 0xb8, 0x1b, 0x80, 0x3e, - 0x26, 0xc1, 0x7e, 0xaa, 0x5d, 0xdf, 0xb6, 0xaf, 0x46, 0x87, 0x92, 0xfd, 0xd8, 0x6e, 0xde, 0xd8, - 0x9b, 0x04, 0xdf, 0xb8, 0x39, 0xdb, 0x87, 0xdf, 0x6b, 0x37, 0x67, 0x8f, 0xf8, 0x46, 0xb3, 0xab, - 0x5e, 0x51, 0xa7, 0xc9, 0xa8, 0x7a, 0xbb, 0xcc, 0x2a, 0x81, 0xa2, 0x9b, 0x12, 0x1c, 0xef, 0x22, - 0xe0, 0x5f, 0x42, 0x6e, 0x62, 0xd3, 0xd1, 0x9c, 0xed, 0x36, 0xb6, 0xb7, 0xad, 0x46, 0x8d, 0x7d, - 0x4d, 0x3d, 0xff, 0x3e, 0x69, 0x6f, 0x31, 0xed, 0x1b, 0x37, 0x67, 0x87, 0x6c, 0xe0, 0xb5, 0x9b, - 0xb3, 0xa7, 0xfa, 0xf4, 0xa0, 0x27, 0xbe, 0xa2, 0x2a, 0xc1, 0x1e, 0x15, 0x3d, 0xac, 0x8a, 0x40, - 0xf2, 0x45, 0xb6, 0x4f, 0x4a, 0x80, 0xbc, 0x29, 0x5f, 0xc5, 0x76, 0x8b, 0xac, 0xcf, 0xc9, 0x42, - 0xcc, 0xb7, 0x6a, 0x92, 0x76, 0x5f, 0x88, 0x79, 0xf4, 0x62, 0x21, 0xe6, 0x8b, 0x94, 0x17, 0xbd, - 0xe9, 0x31, 0x32, 0xe8, 0x19, 0x15, 0x0f, 0x11, 0xe1, 0xf9, 0x70, 0x44, 0xf9, 0x17, 0x12, 0x1c, - 0xec, 0x8a, 0x28, 0xae, 0xb0, 0x3f, 0x00, 0xa8, 0xed, 0xab, 0xe4, 0x3f, 0xdc, 0xc6, 0x84, 0xde, - 0x73, 0x80, 0x9a, 0x6a, 0x77, 0xcd, 0xbb, 0xb7, 0x6f, 0x86, 0x67, 0x8f, 0x25, 0x7f, 0x5d, 0x82, - 0x19, 0x7f, 0xf3, 0x6e, 0x47, 0x56, 0x61, 0xcc, 0xdf, 0x3a, 0xef, 0xc2, 0x5d, 0xc3, 0x74, 0x81, - 0x4b, 0x1f, 0xa0, 0x47, 0x8f, 0x7b, 0xe1, 0x9a, 0xed, 0x9d, 0x9e, 0x19, 0x5a, 0x1b, 0x42, 0xa6, - 0x70, 0xd8, 0x8e, 0xd1, 0xf1, 0xf8, 0xae, 0x04, 0xb1, 0x75, 0xcb, 0x6a, 0x20, 0x0b, 0xa6, 0x4c, - 0xcb, 0xd1, 0x48, 0x64, 0xc1, 0x35, 0xff, 0x73, 0xb9, 0x74, 0x7e, 0x61, 0xcf, 0x2e, 0xd1, 0xcd, - 0x4a, 0x9d, 0x34, 0x2d, 0x27, 0x4f, 0x21, 0xfc, 0xc5, 0xdc, 0x0f, 0xc2, 0x78, 0xb0, 0x31, 0x36, - 0x4b, 0x3e, 0xb1, 0xe7, 0xc6, 0x82, 0x6c, 0x5e, 0xbb, 0x39, 0x3b, 0xe3, 0x45, 0x4c, 0x17, 0xac, - 0xa8, 0x63, 0x9b, 0xbe, 0xd6, 0xd9, 0xcd, 0xfc, 0x6f, 0xbd, 0x34, 0x2b, 0x9d, 0xfc, 0x15, 0x09, - 0xc0, 0xdb, 0x79, 0x42, 0xf7, 0xc3, 0x81, 0xfc, 0xda, 0x6a, 0x41, 0x2b, 0x57, 0x72, 0x95, 0x8d, - 0x72, 0xf0, 0x69, 0x99, 0x38, 0x1e, 0xb1, 0x5b, 0xb8, 0x4a, 0x7f, 0x33, 0x0e, 0x1d, 0x87, 0x99, - 0x20, 0x36, 0x29, 0x15, 0x0b, 0xb2, 0x94, 0x1d, 0x7b, 0xe1, 0xc6, 0xb1, 0x14, 0xcb, 0xc5, 0x71, - 0x0d, 0x9d, 0x80, 0x7d, 0xdd, 0x78, 0xa5, 0xd5, 0x45, 0x39, 0x92, 0x1d, 0x7f, 0xe1, 0xc6, 0xb1, - 0xb4, 0x9b, 0xb4, 0x23, 0x05, 0x90, 0x1f, 0x93, 0xf3, 0x8b, 0x66, 0xe1, 0x85, 0x1b, 0xc7, 0x12, - 0x4c, 0x81, 0xd9, 0xd8, 0xf3, 0x9f, 0x3c, 0x3a, 0x72, 0xdb, 0x1f, 0xa0, 0xfd, 0x79, 0xb2, 0xef, - 0xa9, 0x47, 0x1d, 0x9b, 0xd8, 0x36, 0xec, 0x01, 0xa7, 0x1e, 0x43, 0x9d, 0x99, 0xf4, 0xb9, 0xb2, - 0xfd, 0xfb, 0x71, 0x18, 0x5b, 0x64, 0xad, 0xb0, 0x9f, 0xba, 0x7f, 0x0b, 0x24, 0x5a, 0x34, 0x8d, - 0x70, 0xaf, 0x37, 0xf4, 0x31, 0x78, 0x96, 0x6c, 0xb8, 0xd7, 0xec, 0x59, 0xea, 0x61, 0xf3, 0x0b, - 0x95, 0xec, 0x54, 0xd2, 0xbb, 0xd0, 0x3e, 0xb6, 0xa7, 0xfd, 0x3e, 0x96, 0xb3, 0xf2, 0xad, 0xb5, - 0x30, 0x3f, 0x85, 0xdd, 0xcd, 0xac, 0x10, 0x08, 0x3b, 0xd7, 0x7c, 0x8f, 0x04, 0xfb, 0x28, 0x56, - 0xe8, 0x58, 0x59, 0x2c, 0xf6, 0x4e, 0xf6, 0xeb, 0xc2, 0xb2, 0x6e, 0x7b, 0xf7, 0x2d, 0xd9, 0x55, - 0xfb, 0xbb, 0x78, 0x22, 0x74, 0xd8, 0xd7, 0x78, 0x98, 0xad, 0xa2, 0x4e, 0x37, 0xba, 0x28, 0x6d, - 0xb4, 0x18, 0x78, 0x6b, 0x11, 0xdb, 0xdb, 0x51, 0x8b, 0xff, 0xdd, 0xc5, 0x65, 0x18, 0xf5, 0x62, - 0x89, 0x4d, 0x7f, 0x92, 0x7b, 0x2f, 0x73, 0x87, 0x9f, 0x18, 0xbd, 0x57, 0x82, 0x7d, 0x5e, 0x36, - 0xe7, 0x67, 0x9b, 0xa0, 0x6c, 0xef, 0xdb, 0xc3, 0x42, 0x38, 0xac, 0x9c, 0x9e, 0x7c, 0x15, 0x75, - 0xa6, 0xd3, 0x4d, 0x4a, 0x96, 0xe0, 0xe3, 0xfe, 0xc8, 0x6a, 0x67, 0xc4, 0xcf, 0xe3, 0x0c, 0x1f, - 0x9a, 0x83, 0x0c, 0x50, 0x16, 0x52, 0xf8, 0x7a, 0xcb, 0x6a, 0x3b, 0x98, 0x25, 0x11, 0x29, 0xd5, - 0x2d, 0x2b, 0xab, 0x80, 0xba, 0x07, 0x37, 0xfc, 0xb6, 0xc4, 0x7b, 0x16, 0x8b, 0x66, 0x20, 0xee, - 0x7f, 0x7d, 0xc1, 0x0a, 0xf3, 0xa9, 0xe7, 0xf9, 0xf4, 0x79, 0xdb, 0x7d, 0xfe, 0x2b, 0x11, 0x38, - 0xe9, 0x3f, 0xab, 0x7c, 0x47, 0x07, 0xb7, 0x77, 0x5c, 0xc7, 0x6d, 0xe9, 0x75, 0xc3, 0xf4, 0x3f, - 0xbe, 0x3c, 0xe8, 0x9f, 0xf0, 0x29, 0xae, 0xd0, 0x93, 0xf2, 0xbc, 0x04, 0xa3, 0xeb, 0x7a, 0x1d, - 0xab, 0xf8, 0x1d, 0x1d, 0x6c, 0x3b, 0x3d, 0x1e, 0xb7, 0xed, 0x87, 0x84, 0xb5, 0xb5, 0x25, 0xee, - 0x1a, 0xc5, 0x54, 0x5e, 0x22, 0x7d, 0x6e, 0x18, 0x4d, 0x83, 0x5d, 0xc9, 0x8e, 0xa9, 0xac, 0x80, - 0x66, 0x61, 0xb4, 0x6a, 0x75, 0x4c, 0xee, 0x72, 0x99, 0x98, 0xf8, 0xc4, 0x5b, 0xc7, 0x64, 0x2e, - 0x47, 0x94, 0xd8, 0xc6, 0xd7, 0x70, 0xdb, 0x66, 0xbf, 0xbc, 0x93, 0x52, 0x45, 0x51, 0x79, 0x14, - 0xc6, 0x98, 0x24, 0x7c, 0x32, 0x3e, 0x08, 0x29, 0x7a, 0xdb, 0xd9, 0x93, 0x27, 0x49, 0xca, 0x8f, - 0xb1, 0x27, 0x72, 0x8c, 0x3f, 0x13, 0x89, 0x15, 0xf2, 0xf9, 0xbe, 0x5a, 0x3e, 0x31, 0x38, 0x6a, - 0x30, 0x1d, 0xba, 0x1a, 0xfe, 0x42, 0x1c, 0xf6, 0xf1, 0x13, 0x58, 0xbd, 0x65, 0x9c, 0xde, 0x76, - 0x1c, 0xf1, 0x64, 0x13, 0xf8, 0x2a, 0x48, 0x6f, 0x19, 0xca, 0x0e, 0xc4, 0x96, 0x1c, 0xa7, 0x85, - 0x4e, 0x42, 0xbc, 0xdd, 0x69, 0x60, 0xb1, 0x19, 0xe8, 0x1e, 0xd7, 0xe8, 0x2d, 0x63, 0x8e, 0x20, - 0xa8, 0x9d, 0x06, 0x56, 0x19, 0x0a, 0x2a, 0xc2, 0xec, 0x56, 0xa7, 0xd1, 0xd8, 0xd1, 0x6a, 0x98, - 0x7e, 0x18, 0xdc, 0xfd, 0x01, 0x7d, 0x7c, 0xbd, 0xa5, 0x8b, 0x9f, 0xf4, 0x21, 0x8a, 0x39, 0x4c, - 0xd1, 0x0a, 0x14, 0x4b, 0xfc, 0xf2, 0x7d, 0x51, 0xe0, 0x28, 0x7f, 0x18, 0x81, 0x94, 0x60, 0x4d, - 0x6c, 0xd9, 0xc6, 0x0d, 0x5c, 0x75, 0x2c, 0x71, 0x98, 0xe6, 0x96, 0x11, 0x82, 0x68, 0x9d, 0x0f, - 0x5e, 0x7a, 0x69, 0x44, 0x25, 0x05, 0x02, 0x73, 0x5f, 0x12, 0x12, 0x58, 0xab, 0x43, 0xc6, 0x33, - 0xd6, 0xb2, 0xc4, 0xaa, 0x7d, 0x69, 0x44, 0xa5, 0x25, 0x94, 0x81, 0x04, 0x71, 0x1a, 0x87, 0x8d, - 0x16, 0x81, 0xf3, 0x32, 0xda, 0x0f, 0xf1, 0x96, 0xee, 0x54, 0xd9, 0x8d, 0x77, 0x52, 0xc1, 0x8a, - 0xe8, 0x61, 0x48, 0xb0, 0x8f, 0xc1, 0x50, 0xaf, 0x1a, 0x3d, 0x7b, 0xc4, 0xaf, 0x0c, 0xf6, 0xd5, - 0x5d, 0x22, 0xf7, 0xba, 0xee, 0x38, 0xb8, 0x6d, 0x12, 0x86, 0x0c, 0x1d, 0x21, 0x88, 0x6d, 0x5a, - 0x35, 0xf6, 0x83, 0xbf, 0x69, 0x95, 0xfe, 0x8d, 0xee, 0x24, 0x6e, 0xcf, 0xec, 0x41, 0xa3, 0x95, - 0x63, 0xec, 0xeb, 0x21, 0x02, 0x98, 0x27, 0x48, 0x45, 0x98, 0xd6, 0x6b, 0xec, 0x63, 0xde, 0x7a, - 0x43, 0xdb, 0x34, 0x68, 0xf0, 0xb0, 0x33, 0xa3, 0xbb, 0x8c, 0x05, 0xf2, 0x08, 0xf2, 0x1c, 0x3f, - 0x9f, 0x86, 0x64, 0x8b, 0x09, 0xa5, 0x3c, 0x02, 0x53, 0x5d, 0x92, 0x12, 0xf9, 0xae, 0x1a, 0x66, - 0x4d, 0x3c, 0xaf, 0x24, 0x7f, 0x13, 0x18, 0xfd, 0x4c, 0x3a, 0x3b, 0xa6, 0xa4, 0x7f, 0xe7, 0xdf, - 0xdd, 0xff, 0x15, 0xee, 0x84, 0xef, 0x15, 0xae, 0xde, 0x32, 0xf2, 0x69, 0xca, 0x9f, 0xbf, 0xbd, - 0xcd, 0x75, 0xbf, 0xbd, 0xad, 0x63, 0x53, 0x4c, 0xb9, 0xa4, 0x4a, 0x6f, 0x19, 0x36, 0x35, 0x47, - 0xef, 0xbb, 0xed, 0xf6, 0x23, 0xbe, 0xbf, 0xe9, 0x53, 0xdc, 0xd8, 0x62, 0x6e, 0xbd, 0xe4, 0xda, - 0xf1, 0x6f, 0x46, 0xe0, 0xb0, 0xcf, 0x8e, 0x7d, 0xc8, 0xdd, 0xe6, 0x9c, 0xed, 0x6d, 0xf1, 0x43, - 0x3c, 0x71, 0x7a, 0x0c, 0x62, 0x04, 0x1f, 0x0d, 0xf8, 0xed, 0xfe, 0xcc, 0xe7, 0xbe, 0xf4, 0x6b, - 0x4a, 0xf0, 0x40, 0x33, 0x30, 0x2a, 0x94, 0x49, 0xfe, 0xbd, 0xc3, 0xeb, 0x4f, 0xf6, 0xbe, 0x07, - 0x6f, 0xdf, 0x3e, 0x35, 0x86, 0x75, 0xf8, 0xd5, 0x73, 0x7d, 0x3f, 0x99, 0xc1, 0x82, 0xe9, 0xee, - 0xf9, 0xd5, 0x1e, 0x22, 0xf5, 0xeb, 0xc9, 0xc5, 0xb2, 0xbb, 0x8e, 0xb3, 0x72, 0x1d, 0xf6, 0x3f, - 0x4e, 0xda, 0xf6, 0x76, 0x50, 0x44, 0xc8, 0xdf, 0xef, 0x1e, 0xf4, 0x32, 0xcb, 0xf6, 0x0e, 0x71, - 0xc1, 0x93, 0x8f, 0xaf, 0x1d, 0x8f, 0xcf, 0xf5, 0x9d, 0x4a, 0xe6, 0x7c, 0xd3, 0x88, 0xea, 0xa3, - 0x54, 0x3e, 0x23, 0xc1, 0x81, 0xae, 0xa6, 0x79, 0x8c, 0x5f, 0xec, 0xf1, 0xc0, 0xf4, 0x96, 0x92, - 0x9e, 0xc5, 0x1e, 0xc2, 0xde, 0x33, 0x50, 0x58, 0x26, 0x45, 0x40, 0xda, 0xb7, 0xc2, 0xbe, 0xa0, - 0xb0, 0x42, 0x4d, 0x77, 0xc3, 0x44, 0xf0, 0xb0, 0x80, 0xab, 0x6b, 0x3c, 0x70, 0x5c, 0xa0, 0x68, - 0x61, 0x3d, 0xbb, 0x7d, 0x2d, 0x42, 0xda, 0x45, 0xe5, 0xd9, 0xf1, 0xd0, 0x5d, 0xf5, 0x28, 0x95, - 0x0f, 0x49, 0x70, 0x2c, 0xd8, 0x82, 0x2f, 0x4f, 0xda, 0x9b, 0xb0, 0xb7, 0x6d, 0x88, 0x5f, 0x95, - 0xe0, 0x8e, 0x5d, 0x64, 0xe2, 0x0a, 0x78, 0x16, 0x66, 0x7c, 0x9b, 0x04, 0x22, 0x84, 0x8b, 0x61, - 0x3f, 0x39, 0x38, 0x43, 0x75, 0xd7, 0xc4, 0x87, 0x88, 0x52, 0x3e, 0xfd, 0x95, 0xd9, 0xe9, 0xee, - 0x3a, 0x5b, 0x9d, 0xee, 0x5e, 0xd8, 0xdf, 0x46, 0xfb, 0xf8, 0xa8, 0x04, 0xf7, 0x06, 0xbb, 0xda, - 0x23, 0xd5, 0xfd, 0x9b, 0x1a, 0x87, 0x7f, 0x27, 0xc1, 0xc9, 0x61, 0x84, 0xe3, 0x03, 0xb2, 0x09, - 0xd3, 0x5e, 0x12, 0x1e, 0x1e, 0x8f, 0x3d, 0xa5, 0xf6, 0xcc, 0x4a, 0x91, 0xcb, 0xed, 0x0d, 0x50, - 0x7c, 0x8b, 0x3b, 0x96, 0x7f, 0xc8, 0x5d, 0x25, 0x07, 0x37, 0xfa, 0x85, 0x92, 0x03, 0x5b, 0xfd, - 0x3d, 0xc6, 0x22, 0xd2, 0x63, 0x2c, 0xbc, 0xac, 0x5d, 0xb9, 0xc6, 0xe3, 0x56, 0x8f, 0xed, 0xb9, - 0xef, 0x83, 0xe9, 0x1e, 0xa6, 0xcc, 0xbd, 0x7a, 0x0f, 0x96, 0xac, 0xa2, 0x6e, 0x63, 0x55, 0x76, - 0x60, 0x96, 0xb6, 0xdb, 0x43, 0xd1, 0x6f, 0x74, 0x97, 0x9b, 0x3c, 0xb6, 0xf4, 0x6c, 0x9a, 0xf7, - 0xbd, 0x04, 0x09, 0x36, 0xce, 0xbc, 0xbb, 0xb7, 0x60, 0x28, 0x9c, 0x81, 0xf2, 0x93, 0x22, 0x96, - 0x15, 0x84, 0xd8, 0xbd, 0x7d, 0x68, 0x98, 0xbe, 0xde, 0x26, 0x1f, 0xf2, 0x29, 0xe3, 0xcb, 0x22, - 0xaa, 0xf5, 0x96, 0x8e, 0xab, 0xa3, 0x7a, 0xdb, 0xa2, 0x1a, 0xd3, 0xcd, 0x1b, 0x1b, 0xbe, 0x7e, - 0x46, 0x84, 0x2f, 0xb7, 0x4f, 0x03, 0xc2, 0xd7, 0xdf, 0x8c, 0xea, 0xdd, 0x40, 0x36, 0x40, 0xcc, - 0xbf, 0x8d, 0x81, 0xec, 0x5b, 0x12, 0x1c, 0xa4, 0x7d, 0xf3, 0xef, 0x51, 0xec, 0x55, 0xe5, 0xf7, - 0x03, 0xb2, 0xdb, 0x55, 0xad, 0xa7, 0x77, 0xcb, 0x76, 0xbb, 0x7a, 0x25, 0x30, 0xbf, 0xdc, 0x0f, - 0xa8, 0x16, 0xd8, 0x89, 0xa2, 0xd8, 0xec, 0x02, 0xa5, 0x5c, 0xf3, 0x6d, 0x74, 0xf4, 0x18, 0xce, - 0xd8, 0x6d, 0x18, 0xce, 0x97, 0x25, 0xc8, 0xf6, 0xea, 0x32, 0x1f, 0x3e, 0x03, 0xf6, 0x07, 0xce, - 0x0f, 0xc2, 0x23, 0x78, 0xff, 0x30, 0xbb, 0x3c, 0x21, 0x37, 0xda, 0xd7, 0xc6, 0x6f, 0x74, 0x1e, - 0x30, 0x1b, 0xb4, 0xd0, 0xee, 0xcc, 0xfa, 0x6f, 0xcc, 0x7d, 0x3e, 0xdf, 0x15, 0x57, 0xff, 0x56, - 0xe4, 0xde, 0xd7, 0xe1, 0x68, 0x1f, 0xa9, 0xdf, 0xe8, 0x79, 0x6f, 0xbb, 0xef, 0x60, 0xde, 0xee, - 0xf4, 0xfd, 0x21, 0xee, 0x09, 0xc1, 0xcb, 0xf9, 0xbe, 0xb5, 0x58, 0xaf, 0x17, 0xc8, 0xca, 0x53, - 0x70, 0xa8, 0x27, 0x15, 0x97, 0x6d, 0x1e, 0x62, 0xdb, 0x86, 0xed, 0x70, 0xb1, 0x8e, 0xf7, 0x13, - 0x2b, 0x44, 0x4d, 0x69, 0x14, 0x04, 0x32, 0x65, 0xbd, 0x6e, 0x59, 0x0d, 0x2e, 0x86, 0xf2, 0x18, - 0x4c, 0xf9, 0x60, 0xbc, 0x91, 0xf3, 0x10, 0x6b, 0x59, 0x56, 0xc3, 0x7d, 0xe0, 0xd4, 0x6f, 0x63, - 0xdf, 0xb2, 0x1a, 0xbc, 0xdb, 0x14, 0x5f, 0x99, 0x01, 0xc4, 0x98, 0xd1, 0x3d, 0x7e, 0xd1, 0x44, - 0x19, 0xa6, 0x03, 0x50, 0xde, 0xc8, 0xeb, 0x3a, 0x3f, 0x38, 0xfb, 0x8d, 0x7d, 0x10, 0xa7, 0x5c, - 0xd1, 0x47, 0xa4, 0xc0, 0x17, 0x0d, 0xe7, 0xfa, 0xb1, 0xe9, 0xbd, 0x26, 0xce, 0x9e, 0x1e, 0x1a, - 0x9f, 0xe7, 0x6c, 0x27, 0xdf, 0xfd, 0xaf, 0xbe, 0xfa, 0xe1, 0xc8, 0x5d, 0x48, 0x39, 0xdd, 0x67, - 0x05, 0xef, 0xf3, 0x97, 0x4f, 0x05, 0xbe, 0x58, 0x74, 0x6a, 0xb8, 0xa6, 0x84, 0x64, 0x73, 0xc3, - 0xa2, 0x73, 0xc1, 0x1e, 0xa1, 0x82, 0x9d, 0x43, 0x0f, 0x0e, 0x16, 0xec, 0xf4, 0x3b, 0x83, 0x4e, - 0xf3, 0x43, 0xe8, 0xf7, 0x25, 0x98, 0xe9, 0xb5, 0xa4, 0x43, 0x17, 0x86, 0x93, 0xa2, 0x3b, 0xa5, - 0xc8, 0x5e, 0xbc, 0x05, 0x4a, 0xde, 0x95, 0x45, 0xda, 0x95, 0x1c, 0x7a, 0xf4, 0x16, 0xba, 0x72, - 0xda, 0xbf, 0xf5, 0xff, 0xdf, 0x25, 0x38, 0xb2, 0xeb, 0x0a, 0x09, 0xe5, 0x86, 0x93, 0x72, 0x97, - 0xdc, 0x29, 0x9b, 0x7f, 0x3d, 0x2c, 0x78, 0x8f, 0x1f, 0xa7, 0x3d, 0x7e, 0x0c, 0x95, 0x6e, 0xa5, - 0xc7, 0x3d, 0xcf, 0x57, 0xd0, 0x6f, 0x05, 0x2f, 0x9d, 0xee, 0x6e, 0x4e, 0x5d, 0x0b, 0x8f, 0x01, - 0x8e, 0xd1, 0x9d, 0xd4, 0x2a, 0x4f, 0xd2, 0x2e, 0xa8, 0x68, 0xfd, 0x75, 0x0e, 0xda, 0xe9, 0x77, - 0x06, 0x03, 0xff, 0x0f, 0xa1, 0xff, 0x26, 0xf5, 0xbe, 0x43, 0xfa, 0xf0, 0xae, 0x22, 0xf6, 0x5f, - 0x54, 0x65, 0x2f, 0xec, 0x9d, 0x90, 0x77, 0xb2, 0x49, 0x3b, 0x59, 0x47, 0xf8, 0x76, 0x77, 0xb2, - 0xe7, 0x20, 0xa2, 0xdf, 0x96, 0x60, 0xa6, 0xd7, 0x9a, 0x64, 0x80, 0x5b, 0xee, 0xb2, 0xc8, 0x1a, - 0xe0, 0x96, 0xbb, 0x2d, 0x80, 0x94, 0xb7, 0xd0, 0xce, 0x9f, 0x47, 0x0f, 0xf5, 0xeb, 0xfc, 0xae, - 0xa3, 0x48, 0x7c, 0x71, 0xd7, 0x24, 0x7f, 0x80, 0x2f, 0x0e, 0xb3, 0x8e, 0x19, 0xe0, 0x8b, 0x43, - 0xad, 0x31, 0x06, 0xfb, 0xa2, 0xdb, 0xb3, 0x21, 0x87, 0xd1, 0x46, 0xbf, 0x29, 0xc1, 0x78, 0x20, - 0x23, 0x46, 0x67, 0x76, 0x15, 0xb4, 0xd7, 0x82, 0x21, 0x7b, 0x76, 0x2f, 0x24, 0xbc, 0x2f, 0x25, - 0xda, 0x97, 0x05, 0x94, 0xbb, 0x95, 0xbe, 0x04, 0x8f, 0x51, 0x5f, 0x96, 0x60, 0xba, 0x47, 0x96, - 0x39, 0xc0, 0x0b, 0xfb, 0x27, 0xcd, 0xd9, 0x0b, 0x7b, 0x27, 0xe4, 0xbd, 0xba, 0x44, 0x7b, 0xf5, - 0xbd, 0xe8, 0xad, 0xb7, 0xd2, 0x2b, 0xdf, 0xfc, 0x7c, 0xd3, 0xbb, 0x92, 0xe5, 0x6b, 0x07, 0x9d, - 0xdf, 0xa3, 0x60, 0xa2, 0x43, 0x0f, 0xef, 0x99, 0x8e, 0xf7, 0xe7, 0x09, 0xda, 0x9f, 0xc7, 0xd1, - 0xda, 0xeb, 0xeb, 0x4f, 0xf7, 0xb4, 0xfe, 0xcb, 0xdd, 0x8f, 0x43, 0x77, 0xb7, 0xa2, 0x9e, 0xc9, - 0x6a, 0xf6, 0xc1, 0x3d, 0xd1, 0xf0, 0x4e, 0x5d, 0xa0, 0x9d, 0x3a, 0x8b, 0x1e, 0xe8, 0xd7, 0x29, - 0xdf, 0xbd, 0x4b, 0xc3, 0xdc, 0xb2, 0x4e, 0xbf, 0x93, 0xa5, 0xc0, 0x3f, 0x84, 0xde, 0x25, 0xee, - 0x3c, 0x9d, 0xd8, 0xb5, 0x5d, 0x5f, 0x1e, 0x9b, 0xbd, 0x77, 0x08, 0x4c, 0x2e, 0xd7, 0x5d, 0x54, - 0xae, 0xa3, 0xe8, 0x70, 0x3f, 0xb9, 0x48, 0x2e, 0x8b, 0xde, 0x27, 0xb9, 0xd7, 0x64, 0x4f, 0xee, - 0xce, 0xdb, 0x9f, 0xec, 0x66, 0xef, 0x1b, 0x0a, 0x97, 0x4b, 0x72, 0x9c, 0x4a, 0x72, 0x0c, 0x1d, - 0xed, 0x2b, 0x09, 0x4b, 0x7d, 0x6f, 0xf7, 0xa5, 0x82, 0xff, 0xb9, 0x1f, 0x66, 0xfb, 0xb4, 0xe8, - 0x5c, 0x7f, 0x9d, 0x2f, 0xa7, 0x87, 0x3b, 0xd7, 0xba, 0x9d, 0xef, 0xab, 0x07, 0xbd, 0x9f, 0x56, - 0x7e, 0x37, 0x06, 0x68, 0xc5, 0xae, 0x2f, 0xb4, 0xb1, 0xee, 0xf8, 0x3e, 0xc3, 0x19, 0x7a, 0xfc, - 0x27, 0xbd, 0xae, 0xc7, 0x7f, 0x2b, 0x81, 0xe7, 0x74, 0x91, 0xbd, 0x3d, 0xd9, 0x1d, 0xfa, 0x4d, - 0x5d, 0xf4, 0xaf, 0xe5, 0x4d, 0x5d, 0xef, 0x2b, 0xf7, 0xb1, 0xdb, 0xf7, 0x36, 0x27, 0x7e, 0xab, - 0xef, 0x93, 0xf8, 0x53, 0xd9, 0xc4, 0x2e, 0x4f, 0x65, 0x33, 0x7d, 0xdf, 0xc3, 0x72, 0x6a, 0x74, - 0x4e, 0x7c, 0x60, 0x3d, 0x39, 0xdc, 0x25, 0x59, 0xfe, 0x05, 0x76, 0x6f, 0x0b, 0xe1, 0x30, 0x64, - 0xbb, 0xcd, 0xc9, 0x75, 0xea, 0x0f, 0x47, 0x41, 0x5e, 0xb1, 0xeb, 0xc5, 0x9a, 0xe1, 0xbc, 0x41, - 0xb6, 0xf6, 0x68, 0xff, 0xf7, 0x4e, 0xe8, 0xb5, 0x9b, 0xb3, 0x13, 0x4c, 0xa7, 0xbb, 0x68, 0xb2, - 0x09, 0x93, 0xe1, 0xfb, 0xe8, 0xcc, 0xb2, 0x0a, 0xb7, 0xf2, 0xd8, 0xbd, 0xeb, 0x1e, 0xfa, 0x44, - 0xf0, 0xdd, 0x39, 0xba, 0xde, 0xdb, 0x98, 0x99, 0x41, 0x2d, 0xbd, 0x91, 0x8f, 0x43, 0xbd, 0x31, - 0xcb, 0x42, 0x26, 0x3c, 0x28, 0xee, 0x88, 0xbd, 0x22, 0xc1, 0xe8, 0x8a, 0x2d, 0x52, 0x41, 0xfc, - 0x26, 0x7d, 0x9a, 0xf6, 0xb0, 0xfb, 0x13, 0x31, 0xd1, 0xe1, 0xec, 0xd6, 0xff, 0xb3, 0x31, 0x23, - 0xca, 0x3e, 0x98, 0xf6, 0xf5, 0xd1, 0xed, 0xfb, 0x97, 0x22, 0x34, 0x36, 0xe6, 0x71, 0xdd, 0x30, - 0xdd, 0x0c, 0x12, 0xff, 0x5d, 0x7d, 0x74, 0xe3, 0xe9, 0x38, 0x76, 0x2b, 0x3a, 0xbe, 0x4a, 0x03, - 0x43, 0x48, 0x97, 0xee, 0x86, 0xd7, 0x4a, 0xf7, 0x73, 0x30, 0x69, 0x0f, 0xdf, 0xd6, 0x09, 0x3d, - 0xfa, 0x52, 0xbe, 0x2a, 0xc1, 0xf8, 0x8a, 0x5d, 0xdf, 0x30, 0x6b, 0xff, 0x5b, 0xdb, 0xed, 0x16, - 0xec, 0x0b, 0xf4, 0xf2, 0x0d, 0x52, 0xe7, 0xd9, 0x8f, 0xc6, 0x20, 0xba, 0x62, 0xd7, 0xd1, 0x3b, - 0x60, 0x32, 0x9c, 0x28, 0xf4, 0xcd, 0xff, 0xba, 0x67, 0x81, 0xfe, 0x6b, 0xb4, 0xfe, 0x33, 0x06, - 0xba, 0x0a, 0xe3, 0xc1, 0xd9, 0xe2, 0xc4, 0x2e, 0x4c, 0x02, 0x98, 0xd9, 0x07, 0x86, 0xc5, 0x74, - 0x1b, 0x7b, 0x3b, 0xa4, 0xdc, 0x40, 0x77, 0xe7, 0x2e, 0xd4, 0x02, 0xa9, 0x7f, 0x46, 0xdb, 0x23, - 0x9c, 0x10, 0xed, 0x85, 0x43, 0xc9, 0x6e, 0xda, 0x0b, 0xe1, 0xee, 0xaa, 0xbd, 0x7e, 0x6e, 0xb5, - 0x09, 0xe0, 0xf3, 0x81, 0xbb, 0x77, 0xe1, 0xe0, 0xa1, 0x65, 0x4f, 0x0d, 0x85, 0xe6, 0x1e, 0x34, - 0xdd, 0xe6, 0x04, 0xfc, 0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, 0xbe, 0x0a, 0xc7, 0xec, 0x94, 0xb7, - 0x00, 0x00, + 0x96, 0x92, 0xc9, 0x91, 0xfc, 0x0f, 0xc1, 0x74, 0xd5, 0x6a, 0x86, 0x47, 0x3c, 0x2f, 0x87, 0xae, + 0x1c, 0xd9, 0x97, 0xa5, 0xb7, 0x9f, 0xe2, 0x48, 0x75, 0xab, 0xa1, 0x9b, 0xf5, 0x05, 0xab, 0x5d, + 0xf7, 0x9e, 0x2c, 0x91, 0xe5, 0xa3, 0xed, 0x7b, 0xb8, 0xd4, 0xda, 0xfa, 0x4b, 0x49, 0xfa, 0x64, + 0x24, 0xba, 0xbc, 0x91, 0xff, 0x4c, 0x24, 0xbb, 0xcc, 0x08, 0x37, 0x84, 0x3d, 0xa9, 0x78, 0xbb, + 0x81, 0xab, 0x64, 0xd0, 0xe1, 0xeb, 0x0f, 0xc0, 0x4c, 0xdd, 0xaa, 0x5b, 0x94, 0xd3, 0x69, 0xf2, + 0x17, 0x7f, 0xf3, 0x94, 0x76, 0xa1, 0xd9, 0x81, 0x0f, 0xa4, 0x16, 0xd7, 0x60, 0x9a, 0x23, 0x6b, + 0x74, 0x35, 0xcb, 0x6e, 0x45, 0xa0, 0x3d, 0x2f, 0xe7, 0x65, 0x7e, 0xf1, 0x2b, 0x74, 0x1b, 0x52, + 0x9d, 0xe2, 0xa4, 0xa4, 0x8e, 0x5d, 0x9c, 0x58, 0x54, 0xe1, 0x40, 0x80, 0x1f, 0xdb, 0x49, 0xc0, + 0xed, 0x01, 0x1c, 0x7f, 0x93, 0x73, 0x9c, 0xf6, 0x71, 0x2c, 0x73, 0xd2, 0xc5, 0x25, 0x18, 0xdf, + 0x0f, 0xaf, 0x7f, 0xc6, 0x79, 0x8d, 0x61, 0x3f, 0x93, 0x65, 0x98, 0xa4, 0x4c, 0xaa, 0x1d, 0xdb, + 0xb1, 0x9a, 0x74, 0x9b, 0x66, 0x6f, 0x36, 0xbf, 0xf5, 0x15, 0x16, 0xac, 0x27, 0x08, 0xd9, 0x92, + 0x4b, 0xb5, 0xb8, 0x08, 0x74, 0x55, 0x5e, 0xc3, 0xd5, 0xc6, 0x00, 0x0e, 0xbf, 0xcd, 0x05, 0x71, + 0xf1, 0x17, 0xaf, 0x92, 0x45, 0x5a, 0xa7, 0x49, 0x77, 0x51, 0xfc, 0x92, 0x0c, 0xbe, 0x86, 0x97, + 0xf9, 0xd2, 0x0f, 0xb3, 0xf9, 0x60, 0xda, 0x65, 0xe0, 0x93, 0xc9, 0x37, 0x8a, 0x75, 0xec, 0x38, + 0xb8, 0x6d, 0x6b, 0x7a, 0xa3, 0x97, 0x78, 0xbe, 0x7b, 0x4c, 0x99, 0x8f, 0x7e, 0x23, 0x38, 0x8a, + 0xcb, 0x8c, 0x32, 0xd7, 0x68, 0x2c, 0x6e, 0xc2, 0xa1, 0x1e, 0x56, 0x31, 0x04, 0xcf, 0x8f, 0x71, + 0x9e, 0x33, 0x5d, 0x96, 0x41, 0xd8, 0x6e, 0x80, 0x80, 0xbb, 0x63, 0x39, 0x04, 0xcf, 0x9f, 0xe0, + 0x3c, 0x11, 0xa7, 0x15, 0x43, 0x4a, 0x38, 0x5e, 0x81, 0xa9, 0xeb, 0xb8, 0xbd, 0x65, 0xd9, 0xfc, + 0xee, 0xd8, 0x10, 0xec, 0x7e, 0x92, 0xb3, 0x9b, 0xe4, 0x84, 0xf4, 0x32, 0x19, 0xe1, 0x75, 0x11, + 0x52, 0xdb, 0x7a, 0x15, 0x0f, 0xc1, 0xe2, 0x26, 0x67, 0x91, 0x24, 0xf8, 0x84, 0x34, 0x07, 0x63, + 0x75, 0x8b, 0x6f, 0xa4, 0x0d, 0x26, 0xff, 0x38, 0x27, 0x1f, 0x15, 0x34, 0x9c, 0x45, 0xcb, 0x6a, + 0x75, 0x1a, 0xba, 0x33, 0x8c, 0x04, 0x3f, 0x25, 0x58, 0x08, 0x1a, 0xce, 0x62, 0x1f, 0x6a, 0x7d, + 0x59, 0xb0, 0xb0, 0x7d, 0xfa, 0x7c, 0x1c, 0x46, 0x2d, 0xb3, 0xb1, 0x6b, 0x99, 0xc3, 0x08, 0xf1, + 0x09, 0xce, 0x01, 0x38, 0x09, 0x61, 0xf0, 0x18, 0xa4, 0x87, 0x1d, 0x88, 0xbf, 0xf3, 0x0d, 0xe1, + 0x1e, 0x62, 0x04, 0x96, 0x61, 0x52, 0x04, 0x28, 0xc3, 0x32, 0x87, 0x60, 0xf1, 0x33, 0x9c, 0xc5, + 0x84, 0x8f, 0x8c, 0x77, 0xc3, 0xc1, 0xb6, 0x53, 0xc7, 0xc3, 0x30, 0xf9, 0xb4, 0xe8, 0x06, 0x27, + 0xe1, 0xaa, 0xdc, 0xc2, 0x66, 0x75, 0x67, 0x38, 0x0e, 0x3f, 0x2b, 0x54, 0x29, 0x68, 0x08, 0x8b, + 0x25, 0x18, 0x6f, 0xea, 0x6d, 0x7b, 0x47, 0x6f, 0x0c, 0x35, 0x1c, 0x7f, 0x97, 0xf3, 0x18, 0x73, + 0x89, 0xb8, 0x46, 0x3a, 0xe6, 0x7e, 0xd8, 0x7c, 0x46, 0x68, 0xc4, 0x47, 0xc6, 0x5d, 0xcf, 0x76, + 0x68, 0x1e, 0xbf, 0x1f, 0x6e, 0x3f, 0x27, 0x5c, 0x8f, 0xd1, 0xae, 0xfa, 0x39, 0x3e, 0x06, 0x69, + 0xdb, 0x78, 0x6e, 0x28, 0x36, 0x9f, 0x15, 0x23, 0x4d, 0x09, 0x08, 0xf1, 0xd3, 0x70, 0xb8, 0xe7, + 0x34, 0x31, 0x04, 0xb3, 0x9f, 0xe7, 0xcc, 0x0e, 0xf6, 0x98, 0x2a, 0x78, 0x48, 0xd8, 0x2f, 0xcb, + 0xbf, 0x27, 0x42, 0x02, 0x0e, 0xf1, 0xda, 0x80, 0x99, 0x8e, 0x69, 0xeb, 0xdb, 0xfb, 0xd3, 0xda, + 0x2f, 0x08, 0xad, 0x31, 0xda, 0x80, 0xd6, 0x2a, 0x70, 0x90, 0x73, 0xdc, 0xdf, 0xb8, 0x7e, 0x4e, + 0x04, 0x56, 0x46, 0xbd, 0x19, 0x1c, 0xdd, 0xef, 0x83, 0xac, 0xab, 0x4e, 0x91, 0x74, 0xdb, 0x5a, + 0x53, 0x6f, 0x0d, 0xc1, 0xf9, 0x17, 0x39, 0x67, 0x11, 0xf1, 0xdd, 0xac, 0xdd, 0x5e, 0xd5, 0x5b, + 0x84, 0xf9, 0x53, 0x90, 0x11, 0xcc, 0x3b, 0x66, 0x1b, 0x57, 0xad, 0xba, 0x69, 0x3c, 0x87, 0x6b, + 0x43, 0xb0, 0xfe, 0xa5, 0xd0, 0x50, 0x6d, 0xfa, 0xc8, 0x09, 0xe7, 0x12, 0xc8, 0x6e, 0xae, 0xa2, + 0x19, 0x4d, 0x7a, 0xde, 0xb8, 0x37, 0xc7, 0x5f, 0x16, 0x23, 0xe5, 0xd2, 0x95, 0x28, 0xd9, 0x62, + 0x11, 0xd8, 0x03, 0x96, 0x61, 0x4d, 0xf2, 0xf3, 0x9c, 0xd1, 0xb8, 0x47, 0xc5, 0x03, 0x47, 0xd5, + 0x6a, 0xb6, 0xf4, 0xf6, 0x30, 0xf1, 0xef, 0xef, 0x8b, 0xc0, 0xc1, 0x49, 0x78, 0xe0, 0x20, 0x19, + 0x1d, 0x99, 0xed, 0x87, 0xe0, 0xf0, 0x2b, 0x22, 0x70, 0x08, 0x1a, 0xce, 0x42, 0x24, 0x0c, 0x43, + 0xb0, 0xf8, 0x07, 0x82, 0x85, 0xa0, 0x21, 0x2c, 0xde, 0xe6, 0x4d, 0xb4, 0x6d, 0x5c, 0x37, 0x6c, + 0x87, 0x3f, 0x31, 0xdb, 0x9b, 0xd5, 0x3f, 0xfc, 0x46, 0x30, 0x09, 0x53, 0x7d, 0xa4, 0x24, 0x12, + 0xf1, 0x8d, 0x6f, 0x7a, 0xb0, 0x33, 0x58, 0xb0, 0x5f, 0x15, 0x91, 0xc8, 0x47, 0x46, 0x64, 0xf3, + 0x65, 0x88, 0x44, 0xed, 0x55, 0xb2, 0x40, 0x1d, 0x82, 0xdd, 0x3f, 0x0a, 0x09, 0x57, 0x16, 0xb4, + 0x84, 0xa7, 0x2f, 0xff, 0xe9, 0x98, 0xd7, 0xf0, 0xee, 0x50, 0xd6, 0xf9, 0x8f, 0x43, 0xf9, 0xcf, + 0x26, 0xa3, 0x64, 0x31, 0x64, 0x32, 0x94, 0x4f, 0xa1, 0x41, 0x4f, 0x58, 0x33, 0xef, 0xfe, 0x16, + 0xef, 0x6f, 0x30, 0x9d, 0x5a, 0x5c, 0x21, 0x46, 0x1e, 0x4c, 0x7a, 0x06, 0x33, 0xfb, 0xe1, 0x6f, + 0xb9, 0x76, 0x1e, 0xc8, 0x79, 0x16, 0x2f, 0xc1, 0x78, 0x20, 0xe1, 0x19, 0xcc, 0xea, 0xbd, 0x9c, + 0xd5, 0x98, 0x3f, 0xdf, 0x59, 0x3c, 0x07, 0x31, 0x92, 0xbc, 0x0c, 0x26, 0xff, 0xbf, 0x39, 0x39, + 0x45, 0x5f, 0xfc, 0x1e, 0x48, 0x89, 0xa4, 0x65, 0x30, 0xe9, 0xfb, 0x38, 0xa9, 0x4b, 0x42, 0xc8, + 0x45, 0xc2, 0x32, 0x98, 0xfc, 0xff, 0x11, 0xe4, 0x82, 0x84, 0x90, 0x0f, 0xaf, 0xc2, 0x5f, 0xff, + 0x40, 0x8c, 0x4f, 0x3a, 0x42, 0x77, 0x8f, 0x41, 0x92, 0x67, 0x2a, 0x83, 0xa9, 0xdf, 0xcf, 0x1b, + 0x17, 0x14, 0x8b, 0x8f, 0x42, 0x7c, 0x48, 0x85, 0x7f, 0x90, 0x93, 0x32, 0xfc, 0xc5, 0x25, 0x18, + 0xf5, 0x65, 0x27, 0x83, 0xc9, 0xff, 0x3f, 0x4e, 0xee, 0xa7, 0x22, 0xa2, 0xf3, 0xec, 0x64, 0x30, + 0x83, 0x1f, 0x11, 0xa2, 0x73, 0x0a, 0xa2, 0x36, 0x91, 0x98, 0x0c, 0xa6, 0xfe, 0x90, 0xd0, 0xba, + 0x20, 0x59, 0x7c, 0x1c, 0xd2, 0xee, 0x64, 0x33, 0x98, 0xfe, 0xc3, 0x9c, 0xde, 0xa3, 0x21, 0x1a, + 0xf0, 0x4d, 0x76, 0x83, 0x59, 0xfc, 0xff, 0x42, 0x03, 0x3e, 0x2a, 0xe2, 0x46, 0xe1, 0x04, 0x66, + 0x30, 0xa7, 0x8f, 0x08, 0x37, 0x0a, 0xe5, 0x2f, 0x64, 0x34, 0x69, 0xcc, 0x1f, 0xcc, 0xe2, 0x47, + 0xc5, 0x68, 0x52, 0x7c, 0x22, 0x46, 0x38, 0x23, 0x18, 0xcc, 0xe3, 0xc7, 0x85, 0x18, 0xa1, 0x84, + 0x60, 0x71, 0x03, 0x50, 0x77, 0x36, 0x30, 0x98, 0xdf, 0x4b, 0x9c, 0xdf, 0x54, 0x57, 0x32, 0xb0, + 0xf8, 0x24, 0x1c, 0xec, 0x9d, 0x09, 0x0c, 0xe6, 0xfa, 0xd1, 0x6f, 0x85, 0xd6, 0x6e, 0xfe, 0x44, + 0x60, 0xb1, 0xe2, 0x4d, 0x29, 0xfe, 0x2c, 0x60, 0x30, 0xdb, 0x8f, 0x7d, 0x2b, 0x18, 0xb8, 0xfd, + 0x49, 0xc0, 0x62, 0x0e, 0xc0, 0x9b, 0x80, 0x07, 0xf3, 0xfa, 0x49, 0xce, 0xcb, 0x47, 0x44, 0x5c, + 0x83, 0xcf, 0xbf, 0x83, 0xe9, 0x6f, 0x0a, 0xd7, 0xe0, 0x14, 0xc4, 0x35, 0xc4, 0xd4, 0x3b, 0x98, + 0xfa, 0xe3, 0xc2, 0x35, 0x04, 0x09, 0xb1, 0x6c, 0xdf, 0xec, 0x36, 0x98, 0xc3, 0x27, 0x84, 0x65, + 0xfb, 0xa8, 0x16, 0xd7, 0x60, 0xaa, 0x6b, 0x42, 0x1c, 0xcc, 0xea, 0x93, 0x9c, 0x95, 0x1c, 0x9e, + 0x0f, 0xfd, 0x93, 0x17, 0x9f, 0x0c, 0x07, 0x73, 0xfb, 0x54, 0x68, 0xf2, 0xe2, 0x73, 0xe1, 0xe2, + 0x63, 0x90, 0x32, 0x3b, 0x8d, 0x06, 0x71, 0x1e, 0xb4, 0xf7, 0x13, 0xe3, 0xcc, 0xd7, 0xbe, 0xcd, + 0xb5, 0x23, 0x08, 0x16, 0xcf, 0x41, 0x1c, 0x37, 0xb7, 0x70, 0x6d, 0x10, 0xe5, 0xd7, 0xbf, 0x2d, + 0x02, 0x26, 0xc1, 0x5e, 0x7c, 0x1c, 0x80, 0x6d, 0x8d, 0xd0, 0x3b, 0xf6, 0x03, 0x68, 0xff, 0xf4, + 0xdb, 0xfc, 0x41, 0x9e, 0x47, 0xe2, 0x31, 0x60, 0xcf, 0xfb, 0xf6, 0x66, 0xf0, 0x8d, 0x20, 0x03, + 0x3a, 0x22, 0x17, 0x21, 0xf9, 0x8c, 0x6d, 0x99, 0x8e, 0x5e, 0x1f, 0x44, 0xfd, 0x9f, 0x38, 0xb5, + 0xc0, 0x27, 0x0a, 0x6b, 0x5a, 0x6d, 0xec, 0xe8, 0x75, 0x7b, 0x10, 0xed, 0x7f, 0xe6, 0xb4, 0x2e, + 0x01, 0x21, 0xae, 0xea, 0xb6, 0x33, 0x4c, 0xbf, 0xff, 0x4c, 0x10, 0x0b, 0x02, 0x22, 0x34, 0xf9, + 0xfb, 0x1a, 0xde, 0x1d, 0x44, 0xfb, 0x4d, 0x21, 0x34, 0xc7, 0x5f, 0xfc, 0x1e, 0x48, 0x93, 0x3f, + 0xd9, 0x43, 0xdd, 0x01, 0xc4, 0x7f, 0xce, 0x89, 0x3d, 0x0a, 0xd2, 0xb2, 0xed, 0xd4, 0x1c, 0x63, + 0xb0, 0xb2, 0x5f, 0xe3, 0x23, 0x2d, 0xf0, 0x17, 0x73, 0x30, 0x6a, 0x3b, 0xb5, 0x5a, 0x87, 0xe7, + 0xa7, 0x03, 0xc8, 0xff, 0xe2, 0xdb, 0xee, 0x96, 0x85, 0x4b, 0x43, 0x46, 0xfb, 0xd9, 0x6b, 0x4e, + 0xcb, 0xa2, 0xb7, 0xb2, 0x06, 0x71, 0xf8, 0x16, 0xe7, 0xe0, 0x23, 0x59, 0x5c, 0x82, 0x31, 0xd2, + 0x17, 0x71, 0xb9, 0x65, 0x10, 0x8b, 0xff, 0xc2, 0x15, 0x10, 0x20, 0xca, 0x7f, 0xff, 0x6f, 0xbf, + 0x32, 0x2b, 0x7d, 0xf1, 0x95, 0x59, 0xe9, 0x3f, 0xbc, 0x32, 0x2b, 0x7d, 0xe8, 0x8f, 0x67, 0x47, + 0xbe, 0xf8, 0xc7, 0xb3, 0x23, 0x7f, 0xf0, 0xc7, 0xb3, 0x23, 0xbd, 0x77, 0x89, 0x61, 0xd9, 0x5a, + 0xb6, 0xd8, 0xfe, 0xf0, 0xdb, 0x95, 0xba, 0xe1, 0xec, 0x74, 0xb6, 0x16, 0xaa, 0x56, 0x93, 0x6e, + 0xe3, 0x7a, 0xbb, 0xb5, 0xee, 0x22, 0x07, 0xde, 0x1b, 0x85, 0xd9, 0xaa, 0x65, 0x37, 0x2d, 0xfb, + 0xf4, 0x96, 0x6e, 0xe3, 0xd3, 0xd7, 0xcf, 0x6c, 0x61, 0x47, 0x3f, 0x73, 0xba, 0x6a, 0x19, 0x26, + 0xdf, 0xf6, 0x9d, 0x66, 0xf5, 0x0b, 0xa4, 0x7e, 0x81, 0xd7, 0x67, 0x7b, 0xee, 0x10, 0x2b, 0xcb, + 0x10, 0x5b, 0xb2, 0x0c, 0x7a, 0xd1, 0xbf, 0x86, 0x4d, 0xab, 0xc9, 0x1f, 0x81, 0xb2, 0x02, 0xba, + 0x1b, 0x12, 0x7a, 0xd3, 0xea, 0x98, 0x0e, 0x3b, 0x1b, 0xc9, 0x8f, 0xfe, 0xf6, 0xad, 0xb9, 0x91, + 0x3f, 0xbc, 0x35, 0x17, 0x2d, 0x99, 0x8e, 0xca, 0xab, 0x16, 0x63, 0xaf, 0xbe, 0x3c, 0x27, 0x29, + 0x57, 0x20, 0x59, 0xc0, 0xd5, 0xdb, 0xe1, 0x55, 0xc0, 0xd5, 0x10, 0xaf, 0xfb, 0x21, 0x55, 0x32, + 0x1d, 0xf6, 0x4c, 0xf7, 0x18, 0x44, 0x0d, 0x93, 0xbd, 0xee, 0x0a, 0xb5, 0x4f, 0xe0, 0x04, 0xb5, + 0x80, 0xab, 0x2e, 0x6a, 0x0d, 0x57, 0xc3, 0xa8, 0x84, 0x3d, 0x81, 0xe7, 0x0b, 0x7f, 0xf0, 0x1f, + 0x67, 0x47, 0x9e, 0x7f, 0x65, 0x76, 0xa4, 0xdf, 0xf8, 0x04, 0xd4, 0xcf, 0x55, 0xcc, 0xfe, 0x3b, + 0x65, 0xd7, 0xae, 0xb1, 0xed, 0xf9, 0xad, 0x04, 0xfb, 0x38, 0x02, 0xbc, 0x27, 0x0a, 0x87, 0x59, + 0xa5, 0xc6, 0x94, 0xca, 0x75, 0xce, 0x46, 0x60, 0xcc, 0x5f, 0x35, 0xc4, 0xde, 0xfb, 0x65, 0x98, + 0xa0, 0x16, 0x48, 0x77, 0x1d, 0xa9, 0xd3, 0x0f, 0x8c, 0xd3, 0xbf, 0xf3, 0x6f, 0xe2, 0x54, 0xbd, + 0xe3, 0x2e, 0x21, 0x7d, 0x9b, 0x54, 0x81, 0x19, 0xa3, 0xd9, 0x6a, 0x60, 0x7a, 0xc8, 0xa7, 0xb9, + 0x75, 0x83, 0xf9, 0x7d, 0x81, 0xf3, 0x9b, 0xf6, 0xc8, 0x4b, 0x82, 0x7a, 0x71, 0x05, 0xa6, 0xf4, + 0x6a, 0x15, 0xb7, 0x02, 0x2c, 0x07, 0x78, 0x87, 0x10, 0x50, 0xe6, 0x94, 0x2e, 0xb7, 0xfc, 0xe3, + 0x7d, 0x47, 0xe0, 0x5e, 0xdf, 0x08, 0xb4, 0x71, 0x1d, 0x9b, 0xa7, 0x4c, 0xec, 0x3c, 0x6b, 0xb5, + 0xaf, 0x89, 0x81, 0x60, 0x4d, 0x89, 0x41, 0xf8, 0xbd, 0x04, 0x28, 0x7c, 0xa0, 0x6c, 0x47, 0xbf, + 0x66, 0x98, 0x75, 0xd7, 0x1d, 0xf4, 0x8e, 0xb3, 0xf3, 0x1c, 0x1f, 0x8d, 0x83, 0x7c, 0x6c, 0x38, + 0x8e, 0xeb, 0x12, 0x03, 0xfc, 0x28, 0xdb, 0x7f, 0x80, 0xfb, 0x78, 0xd3, 0xef, 0x46, 0x01, 0x95, + 0x1d, 0xfd, 0x1a, 0xce, 0x75, 0x9c, 0x1d, 0xab, 0x6d, 0x3c, 0xc7, 0x62, 0x19, 0x06, 0x68, 0xea, + 0x37, 0x34, 0xc7, 0xba, 0x86, 0x4d, 0xf1, 0x44, 0xe0, 0xf0, 0x42, 0x0f, 0x27, 0x5d, 0x20, 0xfe, + 0x93, 0x7f, 0xe0, 0x33, 0x5f, 0x9e, 0xbb, 0x6f, 0xb0, 0x29, 0x52, 0x64, 0x92, 0x5c, 0xdf, 0xa8, + 0x50, 0xc6, 0xe8, 0x2a, 0xb0, 0x6b, 0xfc, 0x5a, 0xc3, 0xb0, 0x1d, 0x7e, 0xb7, 0xfc, 0xdc, 0x42, + 0xef, 0xbe, 0x2f, 0x74, 0x8b, 0xb9, 0xc0, 0x2f, 0xcd, 0x58, 0x6d, 0xfb, 0xf2, 0x88, 0x9a, 0xa6, + 0xac, 0x56, 0x0c, 0xdb, 0x41, 0x15, 0x48, 0xd7, 0xb0, 0xb9, 0xcb, 0xd8, 0x46, 0x5f, 0x1f, 0xdb, + 0x14, 0xe1, 0x44, 0xb9, 0x3e, 0x05, 0x48, 0xf7, 0xe3, 0x89, 0xaf, 0x60, 0xb1, 0xbb, 0x9c, 0x7d, + 0xd8, 0x07, 0x38, 0xd3, 0x37, 0x63, 0x53, 0x7a, 0x18, 0x94, 0x3d, 0x0e, 0xe0, 0xb5, 0x89, 0x32, + 0x90, 0xd4, 0x6b, 0xb5, 0x36, 0xb6, 0xd9, 0x5d, 0x8f, 0xb4, 0x2a, 0x8a, 0x8b, 0x53, 0xff, 0xf2, + 0xf3, 0xa7, 0xc6, 0x03, 0x1c, 0xf3, 0x63, 0x00, 0xd7, 0x5d, 0xd2, 0x93, 0x1f, 0x97, 0x60, 0xaa, + 0xab, 0x45, 0xa4, 0xc0, 0x6c, 0x6e, 0xb3, 0x72, 0x79, 0x5d, 0x2d, 0xbd, 0x9d, 0x5d, 0x27, 0xe2, + 0x17, 0x9e, 0xca, 0x1b, 0xc5, 0x25, 0xf6, 0x0d, 0x9c, 0x11, 0x34, 0x07, 0x47, 0x7a, 0xe0, 0x14, + 0x8a, 0x2b, 0xc5, 0xe5, 0x5c, 0xa5, 0x28, 0x4b, 0xe8, 0x2e, 0x38, 0xd6, 0x93, 0x89, 0x8b, 0x12, + 0xe9, 0x83, 0xa2, 0x16, 0x5d, 0x94, 0x68, 0xfe, 0x52, 0x5f, 0x47, 0x7a, 0x70, 0x4f, 0xfb, 0xb9, + 0xe1, 0xba, 0x4b, 0x30, 0xa8, 0xbd, 0x3b, 0x02, 0x87, 0xc3, 0xb1, 0x4a, 0x37, 0x77, 0xfb, 0x7c, + 0x41, 0xb1, 0x8f, 0x13, 0x5c, 0x86, 0x68, 0xce, 0xdc, 0x45, 0x87, 0x59, 0x3e, 0xad, 0x75, 0xda, + 0x0d, 0x3e, 0x11, 0x24, 0x49, 0x79, 0xb3, 0xdd, 0x08, 0xbe, 0x2a, 0x1b, 0xe3, 0xaf, 0xca, 0x16, + 0xe5, 0x97, 0x5e, 0x9e, 0x1b, 0xf9, 0xdc, 0xcb, 0x73, 0x23, 0xdf, 0xfc, 0xc4, 0xdc, 0xc8, 0xf3, + 0x7f, 0x34, 0x3f, 0x92, 0xbf, 0x16, 0xee, 0xde, 0xaf, 0x0f, 0x9c, 0x4d, 0x53, 0x39, 0x73, 0x97, + 0xce, 0x06, 0x1b, 0xd2, 0xdb, 0xe3, 0xb4, 0x73, 0xe2, 0x00, 0x75, 0x36, 0x7c, 0x80, 0xfa, 0x24, + 0x6e, 0x34, 0x9e, 0x30, 0xad, 0x67, 0xe9, 0xa8, 0x7a, 0x3a, 0xf8, 0x48, 0x04, 0x66, 0xbb, 0xe2, + 0x35, 0xcf, 0x30, 0xfa, 0x7d, 0x4a, 0x72, 0x11, 0x52, 0x05, 0x91, 0xb8, 0x64, 0x20, 0x69, 0xe3, + 0xaa, 0x65, 0xd6, 0x98, 0xa7, 0x47, 0x55, 0x51, 0x24, 0xdd, 0x36, 0x75, 0xd3, 0xb2, 0xf9, 0x97, + 0x38, 0x58, 0x21, 0xff, 0x13, 0xd2, 0xfe, 0xf2, 0x85, 0x71, 0xd1, 0x92, 0xe8, 0xe6, 0x99, 0x81, + 0x47, 0xca, 0xd7, 0x48, 0x2f, 0xdd, 0x4e, 0x04, 0x8e, 0x95, 0x87, 0xd5, 0xca, 0x8f, 0x47, 0x60, + 0x2e, 0xac, 0x15, 0x92, 0xb6, 0xd9, 0x8e, 0xde, 0x6c, 0xf5, 0x53, 0xcb, 0x63, 0x90, 0xae, 0x08, + 0x9c, 0x7d, 0xeb, 0xe5, 0xe6, 0x3e, 0xf5, 0x32, 0xe1, 0x36, 0x25, 0x14, 0x73, 0x76, 0x48, 0xc5, + 0xb8, 0xfd, 0xb8, 0x2d, 0xcd, 0x7c, 0x26, 0x06, 0xc7, 0xe8, 0xd7, 0x9e, 0xda, 0x4d, 0xc3, 0x74, + 0x4e, 0x57, 0xdb, 0xbb, 0x2d, 0x87, 0x26, 0x6e, 0xd6, 0x36, 0xd7, 0xcb, 0x94, 0x57, 0xbd, 0xc0, + 0xaa, 0xfb, 0x78, 0xce, 0x36, 0xc4, 0x37, 0x08, 0x1d, 0xd1, 0x88, 0x63, 0x39, 0x7a, 0x83, 0x6b, + 0x8a, 0x15, 0x08, 0x94, 0x7d, 0x21, 0x2a, 0xc2, 0xa0, 0x86, 0xf8, 0x38, 0x54, 0x03, 0xeb, 0xdb, + 0xec, 0x2b, 0x19, 0x51, 0xea, 0x50, 0x29, 0x02, 0xa0, 0x1f, 0xc4, 0x98, 0x81, 0xb8, 0xde, 0x61, + 0x37, 0x88, 0xa2, 0xc4, 0xd3, 0x68, 0x41, 0x79, 0x02, 0x92, 0xfc, 0x40, 0x19, 0xc9, 0x10, 0xbd, + 0x86, 0x77, 0x69, 0x3b, 0x63, 0x2a, 0xf9, 0x13, 0x2d, 0x40, 0x9c, 0x0a, 0xcf, 0x27, 0x90, 0xcc, + 0x42, 0x97, 0xf4, 0x0b, 0x54, 0x48, 0x95, 0xa1, 0x29, 0x57, 0x20, 0x55, 0xb0, 0x9a, 0x86, 0x69, + 0x05, 0xb9, 0xa5, 0x19, 0x37, 0x2a, 0x73, 0xab, 0xe3, 0x88, 0x07, 0xa4, 0xb4, 0x80, 0x0e, 0x42, + 0x82, 0x7d, 0x35, 0x85, 0xdf, 0x82, 0xe2, 0x25, 0x65, 0x09, 0x92, 0x94, 0xf7, 0x7a, 0xcb, 0xfd, + 0x9a, 0x99, 0xe4, 0xfb, 0x9a, 0x19, 0x67, 0x1f, 0xf1, 0x84, 0x45, 0x10, 0xab, 0xe9, 0x8e, 0xce, + 0xfb, 0x4d, 0xff, 0x56, 0xde, 0x0a, 0x29, 0xce, 0xc4, 0x46, 0x67, 0x21, 0x6a, 0xb5, 0xc4, 0x25, + 0xbf, 0x6c, 0xbf, 0xae, 0xac, 0xb7, 0xf2, 0x31, 0x92, 0x2e, 0xaa, 0x04, 0x39, 0xaf, 0xf6, 0x0d, + 0xaa, 0x17, 0x7c, 0x41, 0xd5, 0x37, 0xe4, 0xbe, 0x3f, 0xd9, 0x90, 0x76, 0x99, 0x83, 0x6b, 0x2c, + 0x7f, 0x25, 0xc1, 0xd1, 0x6e, 0x63, 0xb9, 0x86, 0x77, 0xed, 0xfd, 0xda, 0xca, 0x53, 0x90, 0xde, + 0xa0, 0x5f, 0x5c, 0x7d, 0x02, 0xef, 0xa2, 0x2c, 0x24, 0x71, 0xed, 0xec, 0xb9, 0x73, 0x67, 0x2e, + 0xb2, 0x91, 0xbc, 0x3c, 0xa2, 0x0a, 0xc0, 0x62, 0x8a, 0xa4, 0xd4, 0xaf, 0x7e, 0x62, 0x4e, 0xca, + 0xc7, 0x21, 0x6a, 0x77, 0x9a, 0xec, 0xca, 0xdc, 0x95, 0x58, 0x2a, 0x2a, 0xc7, 0xd4, 0xb4, 0x8d, + 0xab, 0xad, 0xb3, 0xe7, 0xce, 0x5f, 0x3b, 0xa3, 0x26, 0xed, 0x36, 0x25, 0x78, 0x43, 0xfb, 0xff, + 0xb1, 0x38, 0xcc, 0xfb, 0x29, 0xa9, 0x17, 0xba, 0x33, 0x2e, 0xd7, 0x81, 0xec, 0xd3, 0x01, 0xc5, + 0xe8, 0xad, 0x82, 0xec, 0x9e, 0x9a, 0x54, 0x7e, 0x49, 0x82, 0x31, 0x37, 0x0d, 0x28, 0x63, 0x07, + 0x3d, 0xe6, 0x9f, 0xdb, 0xb9, 0x49, 0x1c, 0x59, 0x08, 0xb7, 0xe5, 0xa5, 0x2b, 0xaa, 0x0f, 0x1d, + 0x3d, 0x0a, 0xa9, 0x56, 0xdb, 0x6a, 0x59, 0x36, 0xff, 0x90, 0xd2, 0x00, 0x52, 0x17, 0x19, 0x3d, + 0x08, 0x88, 0x7a, 0xaf, 0x76, 0xdd, 0x72, 0x0c, 0xb3, 0xae, 0xb5, 0xac, 0x67, 0xf9, 0x17, 0xee, + 0xa2, 0xaa, 0x4c, 0x6b, 0xae, 0xd2, 0x8a, 0x0d, 0x02, 0x27, 0x42, 0xa7, 0x5d, 0x2e, 0xc1, 0xd4, + 0x85, 0x18, 0xb8, 0x28, 0xa2, 0xc7, 0x20, 0xd9, 0xea, 0x6c, 0x69, 0xc2, 0x1b, 0x46, 0xcf, 0x1e, + 0xed, 0x65, 0xdb, 0xc2, 0x3e, 0xb8, 0x75, 0x27, 0x5a, 0x9d, 0x2d, 0x62, 0x2d, 0x77, 0xc1, 0x58, + 0x0f, 0x61, 0x46, 0xaf, 0x7b, 0x72, 0xd0, 0x0f, 0xfd, 0xf2, 0x1e, 0x68, 0xad, 0xb6, 0x61, 0xb5, + 0x0d, 0x67, 0x97, 0xe6, 0x66, 0x51, 0x55, 0x16, 0x15, 0x1b, 0x1c, 0xae, 0x5c, 0x83, 0xc9, 0x32, + 0x5d, 0x34, 0x78, 0x92, 0x9f, 0xf3, 0xe4, 0x93, 0x06, 0xcb, 0xd7, 0x57, 0xb2, 0x48, 0x97, 0x64, + 0xf9, 0xb7, 0xf5, 0xb5, 0xce, 0x47, 0xf7, 0x6f, 0x9d, 0xc1, 0xec, 0xe7, 0x15, 0x09, 0x66, 0x7d, + 0x95, 0xd7, 0x71, 0xdb, 0x36, 0x2c, 0x93, 0x27, 0xdb, 0xcc, 0x34, 0x91, 0xaf, 0x17, 0xbc, 0xbe, + 0x8f, 0x7f, 0x5e, 0x84, 0xf4, 0x92, 0x65, 0xda, 0xd8, 0xb4, 0x3b, 0x74, 0x86, 0xdb, 0x6a, 0x58, + 0xd5, 0x6b, 0x54, 0x19, 0x31, 0x95, 0x15, 0x48, 0x38, 0xd3, 0x5b, 0x2d, 0xda, 0xc9, 0x98, 0x4a, + 0xfe, 0x64, 0xcb, 0xdf, 0x7c, 0xb9, 0x6f, 0x17, 0x2f, 0xee, 0xbf, 0x8b, 0x5c, 0x4a, 0xb7, 0x93, + 0x2f, 0xde, 0x13, 0x88, 0x40, 0xcc, 0x03, 0xfd, 0x5d, 0x1c, 0xd6, 0xfb, 0x06, 0xa5, 0x03, 0xd9, + 0xbd, 0x67, 0xc5, 0xec, 0xc0, 0x38, 0x90, 0x1d, 0x30, 0x18, 0xca, 0x45, 0x18, 0xdf, 0xd0, 0xdb, + 0x4e, 0x19, 0x3b, 0x97, 0xb1, 0x5e, 0xc3, 0xed, 0xe0, 0xb4, 0x39, 0x2e, 0xa6, 0x4d, 0x04, 0x31, + 0x3a, 0x37, 0xb2, 0x69, 0x83, 0xfe, 0xad, 0xec, 0x40, 0x8c, 0xbe, 0x3f, 0x73, 0xa7, 0x54, 0x4e, + 0xc1, 0xa6, 0x54, 0x32, 0x5c, 0xbb, 0x0e, 0x7f, 0x9f, 0x3b, 0xa6, 0xb2, 0x02, 0x7a, 0x44, 0x4c, + 0x8c, 0xd1, 0xbd, 0x27, 0x46, 0xee, 0x6d, 0x7c, 0x7a, 0x6c, 0x40, 0x32, 0x4f, 0x46, 0xbb, 0x54, + 0x70, 0x05, 0x91, 0x3c, 0x41, 0xd0, 0x2a, 0x4c, 0xb6, 0xf4, 0xb6, 0x43, 0xbf, 0x66, 0xb3, 0x43, + 0x7b, 0xc1, 0x1d, 0x7a, 0xae, 0x3b, 0xbc, 0x04, 0x3a, 0xcb, 0x5b, 0x19, 0x6f, 0xf9, 0x81, 0xca, + 0x9f, 0xc4, 0x20, 0xc1, 0x95, 0xf1, 0x3d, 0x90, 0xe4, 0x4a, 0xe3, 0x2e, 0x78, 0x6c, 0xa1, 0xdb, + 0x78, 0x17, 0x5c, 0x1b, 0xe5, 0xfc, 0x04, 0x0d, 0x3a, 0x0e, 0xa9, 0xea, 0x8e, 0x6e, 0x98, 0x9a, + 0x51, 0x13, 0x1b, 0x36, 0xaf, 0xdc, 0x9a, 0x4b, 0x2e, 0x11, 0x58, 0xa9, 0xa0, 0x26, 0x69, 0x65, + 0xa9, 0x46, 0xa6, 0xf2, 0x1d, 0x6c, 0xd4, 0x77, 0x1c, 0x1e, 0x46, 0x78, 0x09, 0x5d, 0x80, 0x18, + 0x31, 0x08, 0x7e, 0x45, 0x3c, 0xdb, 0xb5, 0x55, 0xe0, 0x66, 0x6b, 0xf9, 0x14, 0x69, 0xf8, 0x43, + 0x5f, 0x9e, 0x93, 0x54, 0x4a, 0x81, 0x96, 0x60, 0xbc, 0xa1, 0xdb, 0x8e, 0x46, 0x9d, 0x84, 0x34, + 0x1f, 0xe7, 0x0b, 0xe6, 0x2e, 0x85, 0x70, 0xc5, 0x72, 0xd1, 0x47, 0x09, 0x15, 0x03, 0xd5, 0xd0, + 0x09, 0x90, 0x29, 0x93, 0xaa, 0xd5, 0x6c, 0x1a, 0x0e, 0x4b, 0x8e, 0x12, 0x54, 0xef, 0x13, 0x04, + 0xbe, 0x44, 0xc1, 0x34, 0x45, 0x3a, 0x02, 0x69, 0xfa, 0xc9, 0x26, 0x8a, 0xc2, 0x1e, 0x3d, 0xa6, + 0x08, 0x80, 0x56, 0xde, 0x07, 0x93, 0xde, 0x24, 0xc0, 0x50, 0x52, 0x8c, 0x8b, 0x07, 0xa6, 0x88, + 0x0f, 0xc1, 0x8c, 0x89, 0x6f, 0x38, 0x5a, 0x18, 0x3b, 0x4d, 0xb1, 0x11, 0xa9, 0xbb, 0x1a, 0xa4, + 0xb8, 0x17, 0x26, 0xaa, 0x42, 0xf9, 0x0c, 0x17, 0x28, 0xee, 0xb8, 0x0b, 0xa5, 0x68, 0x87, 0x21, + 0xa5, 0xb7, 0x5a, 0x0c, 0x61, 0x94, 0x4f, 0x02, 0xad, 0x16, 0xad, 0x3a, 0x09, 0x53, 0xb4, 0x8f, + 0x6d, 0x6c, 0x77, 0x1a, 0x0e, 0x67, 0x32, 0x46, 0x71, 0x26, 0x49, 0x85, 0xca, 0xe0, 0x14, 0xf7, + 0x6e, 0x18, 0xc7, 0xd7, 0x8d, 0x1a, 0x36, 0xab, 0x98, 0xe1, 0x8d, 0x53, 0xbc, 0x31, 0x01, 0xa4, + 0x48, 0xf7, 0x83, 0x1b, 0xdc, 0x35, 0x31, 0xf1, 0x4c, 0x30, 0x7e, 0x02, 0x9e, 0x63, 0x60, 0x25, + 0x03, 0xb1, 0x82, 0xee, 0xe8, 0x24, 0x86, 0x39, 0x37, 0xd8, 0x6c, 0x3a, 0xa6, 0x92, 0x3f, 0x95, + 0x59, 0x88, 0x57, 0x6e, 0x90, 0x60, 0x7e, 0x00, 0x12, 0xce, 0x0d, 0xcd, 0xcb, 0x2e, 0xe3, 0x0e, + 0x01, 0x2b, 0xbf, 0x16, 0x85, 0xd8, 0x55, 0xcb, 0xc1, 0xe8, 0x61, 0x5f, 0x86, 0x37, 0xd1, 0xcb, + 0xde, 0xcb, 0x46, 0xdd, 0xc4, 0xb5, 0x55, 0xbb, 0xee, 0xfb, 0x12, 0xab, 0x67, 0x6e, 0x91, 0x80, + 0xb9, 0xcd, 0x40, 0xbc, 0x6d, 0x75, 0xcc, 0x9a, 0xb8, 0xa9, 0x4d, 0x0b, 0xa8, 0x08, 0x29, 0xd7, + 0x8a, 0x62, 0x83, 0xac, 0x68, 0x92, 0x58, 0x11, 0xb1, 0x71, 0x0e, 0x50, 0x93, 0x5b, 0xdc, 0x98, + 0xf2, 0x90, 0x76, 0x83, 0x1b, 0xb7, 0xc6, 0xe1, 0x0c, 0xda, 0x23, 0x23, 0x33, 0xaa, 0x6b, 0x1b, + 0xae, 0x72, 0x99, 0x45, 0xca, 0x6e, 0x05, 0xd7, 0x6e, 0xc0, 0xec, 0xf8, 0x57, 0x61, 0x93, 0xb4, + 0x5f, 0x9e, 0xd9, 0xb1, 0x2f, 0xc3, 0x1e, 0x85, 0xb4, 0x6d, 0xd4, 0x4d, 0xfa, 0xf8, 0x81, 0x5b, + 0xa6, 0x07, 0x40, 0xf3, 0xfe, 0xef, 0x9c, 0x53, 0x4b, 0xa4, 0x5f, 0x61, 0xf0, 0x7d, 0xc4, 0xfc, + 0x61, 0x98, 0xf6, 0x3e, 0x1f, 0xee, 0x71, 0x02, 0x17, 0x17, 0xb9, 0xd5, 0x65, 0x51, 0xab, 0xfc, + 0xba, 0x04, 0x09, 0xe6, 0x40, 0xbe, 0xe1, 0x90, 0x7a, 0x0f, 0x47, 0xa4, 0xdf, 0x70, 0x44, 0x6f, + 0x7f, 0x38, 0x72, 0x00, 0xae, 0xa8, 0x36, 0xff, 0x06, 0x68, 0x8f, 0x6c, 0x8c, 0x89, 0x58, 0x36, + 0xea, 0x3c, 0x3e, 0xf8, 0x88, 0x94, 0x7f, 0x2f, 0x91, 0xe9, 0x99, 0xd7, 0xa3, 0x1c, 0x8c, 0x0b, + 0xb9, 0xb4, 0xed, 0x86, 0x5e, 0xe7, 0x26, 0x79, 0xac, 0xaf, 0x70, 0x97, 0x1a, 0x7a, 0x5d, 0x1d, + 0xe5, 0xf2, 0x90, 0x42, 0xef, 0xe1, 0x8d, 0xf4, 0x19, 0xde, 0x80, 0x3d, 0x45, 0x6f, 0xcf, 0x9e, + 0x02, 0x23, 0x1f, 0x0b, 0x8d, 0xbc, 0xf2, 0x6b, 0x31, 0xba, 0x08, 0x6a, 0x59, 0xb6, 0xde, 0xf8, + 0x6e, 0x38, 0xda, 0x11, 0x48, 0xb7, 0xac, 0x86, 0xc6, 0x6a, 0xd8, 0xc3, 0x88, 0x54, 0xcb, 0x6a, + 0xa8, 0x5d, 0xc3, 0x1e, 0xbf, 0x43, 0x5e, 0x98, 0xb8, 0x03, 0x5a, 0x4b, 0x86, 0xfd, 0xe5, 0x21, + 0x48, 0xb2, 0x88, 0x65, 0xf3, 0xef, 0xdd, 0x1f, 0xea, 0x96, 0x93, 0xc6, 0x36, 0x35, 0x41, 0x63, + 0x99, 0x8d, 0x16, 0x21, 0x25, 0x22, 0x28, 0xff, 0xf5, 0x84, 0xd9, 0x6e, 0x92, 0x22, 0xc7, 0x58, + 0x31, 0x6c, 0x47, 0x75, 0xf1, 0xd1, 0x45, 0x18, 0xf5, 0x4d, 0x51, 0xd4, 0xe7, 0x42, 0x59, 0x85, + 0xdf, 0x8e, 0x55, 0xf0, 0xe6, 0x2d, 0x74, 0x9e, 0x0c, 0x0e, 0x4d, 0x16, 0x46, 0xfb, 0x51, 0x05, + 0xb2, 0x04, 0x8e, 0xdd, 0x33, 0xc0, 0x8f, 0xf5, 0x0e, 0xf0, 0x6d, 0x18, 0x63, 0x66, 0xc1, 0xd3, + 0x89, 0x87, 0xdc, 0x26, 0xa5, 0xbd, 0x9b, 0x74, 0x1b, 0x7b, 0x08, 0x12, 0xbc, 0x6b, 0x91, 0x01, + 0x5d, 0xe3, 0x78, 0xca, 0x8f, 0x49, 0x00, 0x2b, 0xc4, 0xca, 0xe8, 0xd8, 0x93, 0x44, 0xc0, 0xa6, + 0x22, 0x68, 0x81, 0x96, 0x67, 0xfb, 0x19, 0x30, 0x6f, 0x7f, 0xcc, 0xf6, 0xcb, 0xbd, 0x04, 0xe3, + 0x9e, 0x63, 0xda, 0x58, 0x08, 0x33, 0xbb, 0xc7, 0xea, 0xad, 0x8c, 0x1d, 0x75, 0xec, 0xba, 0xaf, + 0xa4, 0xfc, 0x53, 0x09, 0xd2, 0x54, 0xa6, 0x55, 0xec, 0xe8, 0x01, 0x7b, 0x96, 0x6e, 0xdf, 0x9e, + 0x8f, 0x01, 0x30, 0x36, 0xb6, 0xf1, 0x1c, 0xe6, 0x5e, 0x96, 0xa6, 0x90, 0xb2, 0xf1, 0x1c, 0xf6, + 0x8d, 0x71, 0x74, 0x5f, 0x63, 0x7c, 0x08, 0x92, 0xf4, 0x5b, 0x04, 0x37, 0x6c, 0xbe, 0x60, 0x4b, + 0x98, 0x9d, 0x66, 0xe5, 0x86, 0xad, 0x3c, 0x03, 0xc9, 0xca, 0x0d, 0xb6, 0xbf, 0x74, 0x04, 0xd2, + 0x6d, 0xcb, 0xe2, 0x69, 0x11, 0x9b, 0x9d, 0x53, 0x04, 0x40, 0xb3, 0x00, 0xb1, 0xa7, 0x12, 0xf1, + 0xf6, 0x54, 0xbc, 0x4d, 0xa1, 0xe8, 0x70, 0x9b, 0x42, 0x5f, 0x91, 0x20, 0x25, 0xcc, 0x1e, 0xe9, + 0x70, 0xa8, 0xd6, 0x69, 0x35, 0x8c, 0x2a, 0xfd, 0x6c, 0x84, 0xe5, 0x60, 0xcd, 0xf5, 0x19, 0xa6, + 0xbe, 0xfb, 0xba, 0xbb, 0x56, 0x10, 0x04, 0x24, 0x55, 0x10, 0x9c, 0x2e, 0x8f, 0xa8, 0x07, 0x6a, + 0xbd, 0x2a, 0x90, 0x09, 0x47, 0x1b, 0xc4, 0x70, 0x34, 0xfe, 0x11, 0x5d, 0xdd, 0x71, 0xf4, 0xea, + 0x35, 0xaf, 0x1d, 0x36, 0xe8, 0x0f, 0x74, 0xb7, 0x43, 0xcd, 0x6d, 0x89, 0x12, 0xe5, 0x28, 0x8d, + 0xaf, 0xad, 0xc3, 0x8d, 0x7e, 0x95, 0x7c, 0x2b, 0x45, 0xf9, 0x50, 0x04, 0x0e, 0xf4, 0x94, 0x14, + 0x9d, 0x82, 0x04, 0xed, 0xa9, 0xce, 0xbb, 0x78, 0xb0, 0x87, 0xbd, 0x59, 0x0e, 0x56, 0xe3, 0x04, + 0x2b, 0xe7, 0xa2, 0x6f, 0x71, 0x49, 0xf7, 0x44, 0xcf, 0xef, 0x6f, 0x53, 0x21, 0x98, 0x4d, 0x30, + 0x54, 0x66, 0x19, 0x5e, 0x36, 0xc1, 0x10, 0xef, 0x40, 0x9e, 0xa3, 0xfc, 0x5e, 0x04, 0x0e, 0xf7, + 0x55, 0x2a, 0x2a, 0xc1, 0x94, 0xf8, 0x2e, 0x14, 0x91, 0xdb, 0x5b, 0x14, 0x87, 0x76, 0x08, 0x7c, + 0x83, 0x43, 0xfd, 0x46, 0x95, 0x7d, 0x64, 0x2c, 0x3a, 0xdc, 0x0d, 0xe3, 0x24, 0x6c, 0x58, 0xa6, + 0x16, 0x98, 0xa7, 0xc6, 0x18, 0xf0, 0x32, 0x9b, 0xad, 0xd6, 0x60, 0x66, 0x6b, 0xf7, 0x39, 0xdd, + 0x74, 0x0c, 0x13, 0xfb, 0x72, 0x73, 0xfe, 0x6b, 0x2d, 0x7b, 0x6e, 0xe1, 0x4c, 0xbb, 0x84, 0xbe, + 0xc3, 0xa4, 0xde, 0x8a, 0x8f, 0xf5, 0x51, 0xfc, 0x9d, 0xd0, 0xe7, 0x0a, 0x8c, 0xf9, 0xe7, 0x0f, + 0xf4, 0x16, 0xdf, 0x8c, 0xd3, 0x63, 0x5b, 0x33, 0x38, 0xe3, 0xf0, 0xd0, 0xe0, 0x52, 0x9c, 0xfc, + 0xb7, 0x12, 0x8c, 0xfa, 0x72, 0x18, 0x74, 0x06, 0x0e, 0xe4, 0x57, 0xd6, 0x97, 0x9e, 0xd0, 0x4a, + 0x05, 0xed, 0xd2, 0x4a, 0xce, 0xf7, 0x9a, 0x3d, 0x7b, 0xf0, 0xc5, 0x9b, 0xf3, 0xc8, 0x87, 0xbb, + 0x69, 0xd2, 0xdd, 0x72, 0x74, 0x1a, 0x66, 0x82, 0x24, 0xb9, 0x7c, 0xb9, 0xb8, 0x56, 0x91, 0xa5, + 0xec, 0x81, 0x17, 0x6f, 0xce, 0x4f, 0xf9, 0x28, 0x72, 0x5b, 0x36, 0x36, 0x9d, 0x6e, 0x82, 0xa5, + 0xf5, 0xd5, 0xd5, 0x52, 0x45, 0x8e, 0x74, 0x11, 0xf0, 0xd9, 0xed, 0x7e, 0x98, 0x0a, 0x12, 0xac, + 0x95, 0x56, 0xe4, 0x68, 0x16, 0xbd, 0x78, 0x73, 0x7e, 0xc2, 0x87, 0xbd, 0x66, 0x34, 0xb2, 0xa9, + 0x17, 0x3e, 0x35, 0x3b, 0xf2, 0xb3, 0x3f, 0x3d, 0x2b, 0x91, 0x9e, 0x8d, 0x07, 0xf2, 0x18, 0xf4, + 0x20, 0x1c, 0x2a, 0x97, 0x96, 0xd7, 0x8a, 0x05, 0x6d, 0xb5, 0xbc, 0x1c, 0xfa, 0x2a, 0x41, 0x76, + 0xf2, 0xc5, 0x9b, 0xf3, 0xa3, 0xbc, 0x4b, 0xfd, 0xb0, 0x37, 0xd4, 0xe2, 0xd5, 0xf5, 0x4a, 0x51, + 0x96, 0x18, 0xf6, 0x46, 0x1b, 0x13, 0xef, 0xa3, 0xd8, 0x0f, 0xc1, 0xe1, 0x1e, 0xd8, 0x6e, 0xc7, + 0xa6, 0x5e, 0xbc, 0x39, 0x3f, 0xbe, 0xd1, 0xc6, 0x6c, 0x5e, 0xa3, 0x14, 0x0b, 0x90, 0xe9, 0xa6, + 0x58, 0xdf, 0x58, 0x2f, 0xe7, 0x56, 0xe4, 0xf9, 0xac, 0xfc, 0xe2, 0xcd, 0xf9, 0x31, 0x91, 0xb0, + 0xd1, 0x43, 0x4c, 0xb7, 0x67, 0x6f, 0xe4, 0x8e, 0xd7, 0x5f, 0x9c, 0x81, 0x7b, 0xfa, 0x9c, 0x9f, + 0x8b, 0x93, 0xd7, 0xef, 0xee, 0x09, 0x7a, 0xb6, 0xff, 0xf1, 0x63, 0x76, 0xc0, 0xa9, 0xdc, 0xe0, + 0x0d, 0xa9, 0x3d, 0xf7, 0xbd, 0x94, 0xf7, 0x4b, 0x30, 0x71, 0xd9, 0xb0, 0x1d, 0xab, 0x6d, 0x54, + 0xf5, 0x06, 0x7d, 0x95, 0x7c, 0x7e, 0xd8, 0x9c, 0x27, 0x34, 0x05, 0x3f, 0x0e, 0x89, 0xeb, 0x7a, + 0x83, 0x25, 0x1b, 0x51, 0xfa, 0x69, 0xfd, 0x3e, 0xc7, 0xd9, 0x6e, 0x64, 0x11, 0x0c, 0x18, 0x99, + 0xf2, 0x0b, 0x11, 0x98, 0xa4, 0xce, 0x60, 0xb3, 0xdf, 0x96, 0x71, 0xe8, 0x9b, 0xf9, 0x58, 0x5b, + 0x77, 0xf8, 0x81, 0x48, 0x7e, 0x81, 0x5f, 0x6f, 0x39, 0x3e, 0xc4, 0x3d, 0x81, 0x02, 0xae, 0xaa, + 0x94, 0x16, 0xbd, 0x03, 0x52, 0x4d, 0xfd, 0x86, 0x46, 0xf9, 0xb0, 0x4d, 0x9d, 0xdc, 0xfe, 0xf8, + 0xbc, 0x76, 0x6b, 0x6e, 0x72, 0x57, 0x6f, 0x36, 0x16, 0x15, 0xc1, 0x47, 0x51, 0x93, 0x4d, 0xfd, + 0x06, 0x11, 0x11, 0xb5, 0xe8, 0x97, 0x0b, 0xb4, 0xea, 0x8e, 0x6e, 0xd6, 0x31, 0x6b, 0x84, 0x1e, + 0xef, 0xe4, 0x2f, 0xef, 0xbb, 0x91, 0x83, 0x5e, 0x23, 0x3e, 0x76, 0x8a, 0x3a, 0xde, 0xd4, 0x6f, + 0x2c, 0x51, 0x00, 0x69, 0x71, 0x31, 0xf5, 0xd2, 0xcb, 0x73, 0x23, 0xf4, 0xca, 0xd0, 0x97, 0x24, + 0x00, 0x4f, 0x63, 0xe8, 0x1d, 0x20, 0x57, 0xdd, 0x12, 0xa5, 0xb5, 0xdd, 0x5c, 0xa3, 0xcf, 0x58, + 0x84, 0xf4, 0xcd, 0xa2, 0xf1, 0x17, 0x6f, 0xcd, 0x49, 0xea, 0x64, 0x35, 0x34, 0x14, 0xdf, 0x07, + 0xa3, 0x9d, 0x56, 0x8d, 0x64, 0x33, 0x74, 0x8b, 0x2b, 0x32, 0x30, 0xb2, 0xcf, 0x12, 0x5e, 0xaf, + 0xdd, 0x9a, 0x43, 0xac, 0x5b, 0x3e, 0x62, 0x85, 0xc6, 0x7b, 0x60, 0x10, 0x42, 0xe0, 0xeb, 0xd3, + 0xef, 0xd0, 0x5f, 0x05, 0xf2, 0xee, 0x8b, 0x67, 0x20, 0xd9, 0xb4, 0x4c, 0xe3, 0x1a, 0xb7, 0xc7, + 0xb4, 0x2a, 0x8a, 0x28, 0x0b, 0x29, 0xf6, 0x35, 0x31, 0x67, 0x57, 0xfc, 0x04, 0x8d, 0x28, 0x13, + 0xaa, 0x67, 0xf1, 0x96, 0x6d, 0x88, 0xd1, 0x50, 0x45, 0x11, 0x5d, 0x02, 0xd9, 0xc6, 0xd5, 0x4e, + 0xdb, 0x70, 0x76, 0xb5, 0xaa, 0x65, 0x3a, 0x7a, 0x95, 0x7d, 0x27, 0x30, 0x9d, 0x3f, 0xf2, 0xda, + 0xad, 0xb9, 0x43, 0x4c, 0xd6, 0x30, 0x86, 0xa2, 0x4e, 0x0a, 0xd0, 0x12, 0x83, 0x90, 0x16, 0x6a, + 0xd8, 0xd1, 0x8d, 0x06, 0xfb, 0x8c, 0x43, 0x5a, 0x15, 0x45, 0x5f, 0x5f, 0x3e, 0x9b, 0xf4, 0x1f, + 0x6c, 0x5c, 0x02, 0xd9, 0x6a, 0xe1, 0x76, 0x60, 0xb1, 0x2c, 0x85, 0x5b, 0x0e, 0x63, 0x28, 0xea, + 0xa4, 0x00, 0x89, 0x85, 0xb4, 0x43, 0x86, 0x59, 0xec, 0xa1, 0xb5, 0x3a, 0x5b, 0xde, 0x79, 0xc8, + 0x4c, 0xd7, 0x68, 0xe4, 0xcc, 0xdd, 0xfc, 0xc3, 0x1e, 0xf7, 0x30, 0x9d, 0xf2, 0x85, 0xcf, 0x9f, + 0x9a, 0xe1, 0xa6, 0xe1, 0x9d, 0x4f, 0x90, 0xb5, 0xde, 0xa4, 0x8b, 0xba, 0x41, 0x31, 0xc9, 0xd2, + 0xf8, 0x19, 0xdd, 0x68, 0x88, 0x8f, 0x63, 0xaa, 0xbc, 0x84, 0x16, 0x21, 0x61, 0x3b, 0xba, 0xd3, + 0xb1, 0xf9, 0x2d, 0x16, 0xa5, 0x9f, 0xa9, 0xe5, 0x2d, 0xb3, 0x56, 0xa6, 0x98, 0x2a, 0xa7, 0x40, + 0x97, 0x20, 0xc1, 0xaf, 0x07, 0xc5, 0xf7, 0xed, 0xdf, 0xf4, 0x32, 0x1e, 0xa3, 0x26, 0x1a, 0xa9, + 0xe1, 0x06, 0xae, 0xb3, 0xe5, 0xce, 0x8e, 0xde, 0xc6, 0x6c, 0x97, 0x29, 0x9d, 0x2f, 0xed, 0xdb, + 0x09, 0xb9, 0xa6, 0xc2, 0xfc, 0x14, 0x75, 0xd2, 0x05, 0x95, 0x29, 0x04, 0x3d, 0x11, 0x78, 0xd8, + 0xc0, 0x3f, 0xdb, 0x79, 0x77, 0xbf, 0xee, 0xfb, 0x6c, 0x5a, 0x6c, 0xdd, 0xfa, 0x9f, 0x45, 0x5c, + 0x02, 0xb9, 0x63, 0x6e, 0x59, 0x26, 0xfd, 0xac, 0x05, 0xcf, 0xed, 0x52, 0x24, 0xc3, 0xf2, 0x1b, + 0x47, 0x18, 0x43, 0x51, 0x27, 0x5d, 0x10, 0xcf, 0xfd, 0x6a, 0x30, 0xe1, 0x61, 0x51, 0x47, 0x4d, + 0x0f, 0x74, 0xd4, 0xbb, 0xb8, 0xa3, 0x1e, 0x08, 0xb7, 0xe2, 0xf9, 0xea, 0xb8, 0x0b, 0x24, 0x64, + 0xe8, 0x32, 0x80, 0x17, 0x1e, 0xf8, 0x22, 0x5e, 0x19, 0x1c, 0x63, 0xc4, 0x9e, 0x94, 0x47, 0x8b, + 0x7e, 0x00, 0xa6, 0x9b, 0x86, 0xa9, 0xd9, 0xb8, 0xb1, 0xad, 0x71, 0x05, 0x13, 0x96, 0xf4, 0x47, + 0x23, 0xf2, 0x2b, 0xfb, 0xb3, 0x87, 0xd7, 0x6e, 0xcd, 0x65, 0x79, 0x08, 0xed, 0x66, 0xa9, 0xa8, + 0x53, 0x4d, 0xc3, 0x2c, 0xe3, 0xc6, 0x76, 0xc1, 0x85, 0x2d, 0x8e, 0xbd, 0xf0, 0xf2, 0xdc, 0x08, + 0x77, 0xd7, 0x11, 0xe5, 0x3c, 0x3d, 0x3b, 0xe5, 0x6e, 0x86, 0x6d, 0x74, 0x14, 0xd2, 0xba, 0x28, + 0xf0, 0x6b, 0x54, 0x1e, 0x80, 0xb9, 0xf9, 0xf3, 0x7f, 0x34, 0x2f, 0x29, 0x9f, 0x95, 0x20, 0x51, + 0xb8, 0xba, 0xa1, 0x1b, 0x6d, 0x92, 0xea, 0x7b, 0x96, 0x13, 0x74, 0xf2, 0xa3, 0xaf, 0xdd, 0x9a, + 0xcb, 0x84, 0x8d, 0xcb, 0xf5, 0x72, 0xcf, 0x80, 0x85, 0x9b, 0x97, 0xfa, 0x6d, 0xae, 0x05, 0x58, + 0x75, 0xa1, 0x28, 0xdd, 0x5b, 0x6f, 0xa1, 0x6e, 0x16, 0x21, 0xc9, 0xa4, 0xb5, 0xd1, 0x22, 0xc4, + 0x5b, 0xe4, 0x0f, 0x9e, 0x54, 0xcf, 0xf6, 0x35, 0x5e, 0x8a, 0xef, 0x9e, 0xf1, 0x10, 0x12, 0xe5, + 0xc3, 0x11, 0x80, 0xc2, 0xd5, 0xab, 0x95, 0xb6, 0xd1, 0x6a, 0x60, 0xe7, 0x4e, 0xf6, 0xbc, 0x02, + 0x07, 0x7c, 0xbb, 0x17, 0xed, 0x6a, 0xa8, 0xf7, 0xf3, 0xaf, 0xdd, 0x9a, 0x3b, 0x1a, 0xee, 0xbd, + 0x0f, 0x4d, 0x51, 0xa7, 0xbd, 0x7d, 0x8c, 0x76, 0xb5, 0x27, 0xd7, 0x9a, 0xed, 0xb8, 0x5c, 0xa3, + 0xfd, 0xb9, 0xfa, 0xd0, 0xfc, 0x5c, 0x0b, 0xb6, 0xd3, 0x5b, 0xb5, 0x65, 0x18, 0xf5, 0x54, 0x62, + 0xa3, 0x02, 0xa4, 0x1c, 0xfe, 0x37, 0xd7, 0xb0, 0xd2, 0x5f, 0xc3, 0x82, 0x4c, 0x2c, 0x5f, 0x04, + 0xa5, 0xf2, 0x97, 0x12, 0x80, 0x67, 0xb3, 0x6f, 0x4e, 0x13, 0x23, 0xa1, 0x9c, 0x07, 0xde, 0xe8, + 0x6d, 0xa5, 0x6a, 0x9c, 0x3a, 0xa4, 0xcf, 0x0f, 0x44, 0x60, 0x7a, 0x53, 0x44, 0x9e, 0x37, 0xbd, + 0x0e, 0x36, 0x20, 0x89, 0x4d, 0xa7, 0x6d, 0x60, 0xb1, 0xd4, 0x7e, 0xa8, 0xdf, 0x68, 0xf7, 0xe8, + 0x13, 0xfd, 0x69, 0x0c, 0x71, 0x1e, 0xc9, 0xd9, 0x84, 0xb4, 0xf1, 0x23, 0x51, 0xc8, 0xf4, 0xa3, + 0x44, 0x4b, 0x30, 0x59, 0x6d, 0x63, 0x76, 0xa9, 0xd4, 0x7f, 0x3a, 0x91, 0xcf, 0x7a, 0x99, 0x65, + 0x08, 0x41, 0x51, 0x27, 0x04, 0x84, 0xcf, 0x1e, 0x75, 0x20, 0x69, 0x1f, 0x31, 0x3b, 0x7a, 0x37, + 0x75, 0xb8, 0x3c, 0x4f, 0xe1, 0xd3, 0x87, 0x68, 0x24, 0xc8, 0x80, 0xcd, 0x1f, 0x13, 0x1e, 0x94, + 0x4e, 0x20, 0xef, 0x84, 0x49, 0xc3, 0x34, 0x1c, 0x43, 0x6f, 0x68, 0x5b, 0x7a, 0x43, 0x27, 0xeb, + 0xfa, 0xfd, 0x67, 0xcd, 0x2c, 0xe4, 0xf3, 0x66, 0x43, 0xec, 0x14, 0x75, 0x82, 0x43, 0xf2, 0x0c, + 0x80, 0x2e, 0x43, 0x52, 0x34, 0x15, 0xbb, 0xad, 0x6c, 0x43, 0x90, 0xfb, 0x12, 0xbc, 0x0f, 0x46, + 0x61, 0x4a, 0xc5, 0xb5, 0xff, 0x33, 0x14, 0xfb, 0x1b, 0x8a, 0x55, 0x00, 0xe6, 0xee, 0x24, 0xc0, + 0xde, 0xc6, 0x68, 0x90, 0x80, 0x91, 0x66, 0x1c, 0x0a, 0xb6, 0xe3, 0x1b, 0x8f, 0x5b, 0x11, 0x18, + 0xf3, 0x8f, 0xc7, 0xdf, 0xd2, 0x59, 0x09, 0x95, 0xbc, 0x48, 0x14, 0xe3, 0xbf, 0x57, 0xd8, 0x27, + 0x12, 0x75, 0x59, 0xef, 0xde, 0x21, 0xe8, 0xbf, 0x26, 0x20, 0xb1, 0xa1, 0xb7, 0xf5, 0xa6, 0x8d, + 0xaa, 0x5d, 0x99, 0xa6, 0x38, 0x16, 0xe8, 0xfa, 0xa5, 0x62, 0xbe, 0x65, 0x31, 0x20, 0xd1, 0x7c, + 0xa9, 0x47, 0xa2, 0xf9, 0xbd, 0x30, 0x41, 0x96, 0xc3, 0xbe, 0x4d, 0x4c, 0xa2, 0xed, 0xf1, 0xfc, + 0x61, 0x8f, 0x4b, 0xb0, 0x9e, 0xad, 0x96, 0xaf, 0xfa, 0xef, 0xb0, 0x8d, 0x12, 0x0c, 0x2f, 0x30, + 0x13, 0xf2, 0x83, 0xde, 0xb2, 0xd4, 0x57, 0xa9, 0xa8, 0xd0, 0xd4, 0x6f, 0x14, 0x59, 0x01, 0xad, + 0x00, 0xda, 0x71, 0x77, 0x46, 0x34, 0x4f, 0x9d, 0x84, 0xfe, 0xd8, 0x6b, 0xb7, 0xe6, 0x0e, 0x33, + 0xfa, 0x6e, 0x1c, 0x45, 0x9d, 0xf2, 0x80, 0x82, 0xdb, 0x23, 0x00, 0xa4, 0x5f, 0x1a, 0x7b, 0x23, + 0xc4, 0x96, 0x3b, 0x07, 0x5e, 0xbb, 0x35, 0x37, 0xc5, 0xb8, 0x78, 0x75, 0x8a, 0x9a, 0x26, 0x85, + 0x02, 0x7d, 0x3e, 0xc4, 0xb3, 0xe3, 0xd0, 0xaa, 0x9e, 0xaf, 0x6d, 0x56, 0xf6, 0xbd, 0xb6, 0xf1, + 0x65, 0xc7, 0x21, 0x96, 0x2c, 0x3b, 0x0e, 0xee, 0x06, 0xa0, 0x8f, 0x4b, 0x70, 0x90, 0x6a, 0xd7, + 0xb7, 0xed, 0xab, 0xd1, 0xa1, 0x64, 0xbf, 0xe8, 0x9a, 0x37, 0xf6, 0x27, 0xc1, 0xd7, 0x6f, 0xcd, + 0xf5, 0xe1, 0xf7, 0xda, 0xad, 0xb9, 0x63, 0xbe, 0xd1, 0xec, 0xaa, 0x57, 0xd4, 0x69, 0x32, 0xaa, + 0xde, 0x2e, 0xb3, 0x4a, 0xa0, 0xe8, 0x96, 0x04, 0xc7, 0xbb, 0x08, 0xf8, 0xe7, 0x76, 0x9b, 0xd8, + 0x74, 0x34, 0x67, 0xa7, 0x8d, 0xed, 0x1d, 0xab, 0x51, 0x63, 0x9f, 0xec, 0xce, 0xbf, 0x5f, 0xda, + 0x5f, 0x4c, 0xfb, 0xfa, 0xad, 0xb9, 0x21, 0x1b, 0x78, 0xed, 0xd6, 0xdc, 0xa9, 0x3e, 0x3d, 0xe8, + 0x89, 0xaf, 0xa8, 0x4a, 0xb0, 0x47, 0x45, 0x0f, 0xab, 0x22, 0x90, 0x7c, 0x91, 0xed, 0x53, 0x12, + 0x20, 0x6f, 0xca, 0x57, 0xb1, 0xdd, 0x22, 0xeb, 0x73, 0xb2, 0x10, 0xf3, 0xad, 0x9a, 0xa4, 0xbd, + 0x17, 0x62, 0x1e, 0xbd, 0x58, 0x88, 0xf9, 0x22, 0xe5, 0x45, 0x6f, 0x7a, 0x8c, 0x0c, 0x7a, 0xab, + 0xc3, 0x43, 0x44, 0x78, 0x3e, 0x1c, 0x51, 0xfe, 0xb9, 0x04, 0x87, 0xbb, 0x22, 0x8a, 0x2b, 0xec, + 0xff, 0x05, 0xa8, 0xed, 0xab, 0xe4, 0xbf, 0x0e, 0xc6, 0x84, 0xde, 0x77, 0x80, 0x9a, 0x6a, 0x77, + 0xcd, 0xbb, 0x77, 0x6e, 0x86, 0x67, 0x2f, 0xf2, 0x7e, 0x4d, 0x82, 0x19, 0x7f, 0xf3, 0x6e, 0x47, + 0xd6, 0x60, 0xcc, 0xdf, 0x3a, 0xef, 0xc2, 0x3d, 0xc3, 0x74, 0x81, 0x4b, 0x1f, 0xa0, 0x47, 0x6f, + 0xf3, 0xc2, 0x35, 0xdb, 0x3b, 0x3d, 0x33, 0xb4, 0x36, 0x84, 0x4c, 0xe1, 0xb0, 0x1d, 0xa3, 0xe3, + 0xf1, 0x1d, 0x09, 0x62, 0x1b, 0x96, 0xd5, 0x40, 0x16, 0x4c, 0x99, 0x96, 0xa3, 0x91, 0xc8, 0x82, + 0x6b, 0xfe, 0x37, 0x59, 0xe9, 0xfc, 0xd2, 0xbe, 0x5d, 0xa2, 0x9b, 0x95, 0x3a, 0x69, 0x5a, 0x4e, + 0x9e, 0x42, 0xf8, 0xb3, 0xac, 0x1f, 0x80, 0xf1, 0x60, 0x63, 0x6c, 0x96, 0x7c, 0x72, 0xdf, 0x8d, + 0x05, 0xd9, 0xbc, 0x76, 0x6b, 0x6e, 0xc6, 0x8b, 0x98, 0x2e, 0x58, 0x51, 0xc7, 0xb6, 0x7c, 0xad, + 0xb3, 0xeb, 0xdf, 0xdf, 0x7c, 0x79, 0x4e, 0x3a, 0xf9, 0x2b, 0x12, 0x80, 0xb7, 0xf3, 0x84, 0x1e, + 0x84, 0x43, 0xf9, 0xf5, 0xb5, 0x82, 0x56, 0xae, 0xe4, 0x2a, 0x9b, 0xe5, 0xe0, 0xfb, 0x25, 0x71, + 0x3c, 0x62, 0xb7, 0x70, 0x95, 0xfe, 0x30, 0x19, 0x3a, 0x0e, 0x33, 0x41, 0x6c, 0x52, 0x2a, 0x16, + 0x64, 0x29, 0x3b, 0xf6, 0xe2, 0xcd, 0xf9, 0x14, 0xcb, 0xc5, 0x71, 0x0d, 0x9d, 0x80, 0x03, 0xdd, + 0x78, 0xa5, 0xb5, 0x65, 0x39, 0x92, 0x1d, 0x7f, 0xf1, 0xe6, 0x7c, 0xda, 0x4d, 0xda, 0x91, 0x02, + 0xc8, 0x8f, 0xc9, 0xf9, 0x45, 0xb3, 0xf0, 0xe2, 0xcd, 0xf9, 0x04, 0x53, 0x60, 0x36, 0xf6, 0xc2, + 0xa7, 0x66, 0x47, 0xee, 0xf8, 0x2b, 0xa7, 0x3f, 0x4f, 0xf6, 0x3d, 0xf5, 0xa8, 0x63, 0x13, 0xdb, + 0x86, 0x3d, 0xe0, 0xd4, 0x63, 0xa8, 0x33, 0x93, 0x3e, 0xf7, 0x82, 0x7f, 0x3f, 0x0e, 0x63, 0xcb, + 0xac, 0x15, 0xf6, 0x7b, 0xea, 0x6f, 0x81, 0x44, 0x8b, 0xa6, 0x11, 0xee, 0xf5, 0x86, 0x3e, 0x06, + 0xcf, 0x92, 0x0d, 0xf7, 0x2e, 0x37, 0x4b, 0x3d, 0x6c, 0x7e, 0xcf, 0x91, 0x9d, 0x4a, 0x7a, 0xb7, + 0xa6, 0xc7, 0xf6, 0xb5, 0xdf, 0xc7, 0x72, 0x56, 0xbe, 0xb5, 0x16, 0xe6, 0xa7, 0xb0, 0x2b, 0x93, + 0x15, 0x02, 0x61, 0xe7, 0x9a, 0xef, 0x95, 0xe0, 0x00, 0xc5, 0x0a, 0x1d, 0x2b, 0x8b, 0xc5, 0xde, + 0xc9, 0x7e, 0x5d, 0x58, 0xd1, 0x6d, 0xef, 0x1a, 0x24, 0xbb, 0xcf, 0x7d, 0x0f, 0x4f, 0x84, 0x8e, + 0xfa, 0x1a, 0x0f, 0xb3, 0x55, 0xd4, 0xe9, 0x46, 0x17, 0xa5, 0x8d, 0x96, 0x03, 0x17, 0xfa, 0x63, + 0xfb, 0x3b, 0x6a, 0xf1, 0x5f, 0xee, 0xbf, 0x02, 0xa3, 0x5e, 0x2c, 0xb1, 0xe9, 0xef, 0x3e, 0xef, + 0x67, 0xee, 0xf0, 0x13, 0xa3, 0xf7, 0x49, 0x70, 0xc0, 0xcb, 0xe6, 0xfc, 0x6c, 0x13, 0x94, 0xed, + 0x03, 0xfb, 0x58, 0x08, 0x87, 0x95, 0xd3, 0x93, 0xaf, 0xa2, 0xce, 0x74, 0xba, 0x49, 0xc9, 0x12, + 0x7c, 0xdc, 0x1f, 0x59, 0xed, 0x8c, 0xf8, 0x0d, 0x96, 0xe1, 0x43, 0x73, 0x90, 0x01, 0xfb, 0xa1, + 0xfb, 0x96, 0xd5, 0x76, 0x30, 0x4b, 0x22, 0x52, 0xaa, 0x5b, 0x56, 0xd6, 0x00, 0x75, 0x0f, 0x6e, + 0xf8, 0x01, 0x83, 0xf7, 0xf6, 0x12, 0xcd, 0x40, 0xdc, 0x7f, 0xc5, 0x9f, 0x15, 0x16, 0x53, 0x2f, + 0xf0, 0xe9, 0xf3, 0x8e, 0xfb, 0xfc, 0x97, 0x23, 0x70, 0xd2, 0x7f, 0x56, 0xf9, 0xce, 0x0e, 0x6e, + 0xef, 0xba, 0x8e, 0xdb, 0xd2, 0xeb, 0x86, 0xe9, 0x7f, 0xe1, 0x77, 0xd8, 0x3f, 0xe1, 0x53, 0x5c, + 0xa1, 0x27, 0xe5, 0x05, 0x09, 0x46, 0x37, 0xf4, 0x3a, 0x56, 0xf1, 0x3b, 0x3b, 0xd8, 0x76, 0x7a, + 0xbc, 0xa0, 0x3a, 0x08, 0x09, 0x6b, 0x7b, 0x5b, 0xdc, 0x35, 0x8a, 0xa9, 0xbc, 0x44, 0xfa, 0xdc, + 0x30, 0x9a, 0x06, 0xbb, 0x29, 0x1d, 0x53, 0x59, 0x01, 0xcd, 0xc1, 0x68, 0xd5, 0xea, 0x98, 0xdc, + 0xe5, 0x32, 0x31, 0xf1, 0x1d, 0xb1, 0x8e, 0xc9, 0x5c, 0x8e, 0x28, 0xb1, 0x8d, 0xaf, 0xe3, 0xb6, + 0xcd, 0x7e, 0xde, 0x25, 0xa5, 0x8a, 0xa2, 0xf2, 0x38, 0x8c, 0x31, 0x49, 0xf8, 0x64, 0x7c, 0x18, + 0x52, 0xf4, 0x12, 0xb2, 0x27, 0x4f, 0x92, 0x94, 0x9f, 0x60, 0xef, 0xb0, 0x18, 0x7f, 0x26, 0x12, + 0x2b, 0xe4, 0xf3, 0x7d, 0xb5, 0x7c, 0x62, 0x70, 0xd4, 0x60, 0x3a, 0x74, 0x35, 0xfc, 0x9b, 0x71, + 0x38, 0xc0, 0x4f, 0x60, 0xf5, 0x96, 0x71, 0x7a, 0xc7, 0x71, 0xc4, 0xbb, 0x40, 0xe0, 0xab, 0x20, + 0xbd, 0x65, 0x28, 0xbb, 0x10, 0xbb, 0xec, 0x38, 0x2d, 0x74, 0x12, 0xe2, 0xed, 0x4e, 0x03, 0x8b, + 0xcd, 0x40, 0xf7, 0xb8, 0x46, 0x6f, 0x19, 0x0b, 0x04, 0x41, 0xed, 0x34, 0xb0, 0xca, 0x50, 0x50, + 0x11, 0xe6, 0xb6, 0x3b, 0x8d, 0xc6, 0xae, 0x56, 0xc3, 0xf4, 0xeb, 0xd3, 0xee, 0xaf, 0xb4, 0xe3, + 0x1b, 0x2d, 0x5d, 0xfc, 0x6e, 0x0c, 0x51, 0xcc, 0x51, 0x8a, 0x56, 0xa0, 0x58, 0xe2, 0xe7, 0xd5, + 0x8b, 0x02, 0x47, 0xf9, 0xc3, 0x08, 0xa4, 0x04, 0x6b, 0x62, 0xcb, 0x36, 0x6e, 0xe0, 0xaa, 0x63, + 0x89, 0xc3, 0x34, 0xb7, 0x8c, 0x10, 0x44, 0xeb, 0x7c, 0xf0, 0xd2, 0x97, 0x47, 0x54, 0x52, 0x20, + 0x30, 0xf7, 0xb9, 0x1a, 0x81, 0xb5, 0x3a, 0x64, 0x3c, 0x63, 0x2d, 0x4b, 0xac, 0xda, 0x2f, 0x8f, + 0xa8, 0xb4, 0x84, 0x32, 0x90, 0x20, 0x4e, 0xe3, 0xb0, 0xd1, 0x22, 0x70, 0x5e, 0x46, 0x07, 0x21, + 0xde, 0xd2, 0x9d, 0x2a, 0xbb, 0x88, 0x4e, 0x2a, 0x58, 0x11, 0x3d, 0x0a, 0x09, 0xf6, 0xc5, 0x11, + 0xea, 0x55, 0xbe, 0x1f, 0xed, 0x27, 0xca, 0x60, 0x9f, 0x76, 0x25, 0x72, 0x6f, 0xe8, 0x8e, 0x83, + 0xdb, 0x26, 0x61, 0xc8, 0xd0, 0x11, 0x82, 0xd8, 0x96, 0x55, 0x63, 0xbf, 0x2a, 0x9b, 0x56, 0xe9, + 0xdf, 0xfc, 0x57, 0xec, 0xa9, 0x3d, 0x68, 0xb4, 0x72, 0x8c, 0x7d, 0xa2, 0x42, 0x00, 0xf3, 0x04, + 0xa9, 0x08, 0xd3, 0x7a, 0x8d, 0x7d, 0x31, 0x5a, 0x6f, 0x68, 0x5b, 0x06, 0x0d, 0x1e, 0x76, 0x66, + 0x74, 0x8f, 0xb1, 0x40, 0x1e, 0x41, 0x9e, 0xe3, 0xe7, 0xd3, 0x90, 0x6c, 0x31, 0xa1, 0x94, 0xc7, + 0x60, 0xaa, 0x4b, 0x52, 0x22, 0xdf, 0x35, 0xc3, 0xac, 0x89, 0x37, 0x7c, 0xe4, 0x6f, 0x02, 0xa3, + 0xdf, 0xe2, 0x66, 0xc7, 0x94, 0xf4, 0xef, 0xfc, 0x7b, 0xfa, 0x3f, 0xf5, 0x9c, 0xf0, 0x3d, 0xf5, + 0xd4, 0x5b, 0x46, 0x3e, 0x4d, 0xf9, 0xf3, 0x07, 0x9e, 0xb9, 0xee, 0x07, 0x9e, 0x75, 0x6c, 0x8a, + 0x29, 0x97, 0x54, 0xe9, 0x2d, 0xc3, 0xa6, 0xe6, 0xe8, 0x7d, 0x1c, 0xdc, 0x7e, 0xcc, 0xf7, 0x37, + 0x7d, 0xef, 0x19, 0x5b, 0xce, 0x6d, 0x94, 0x5c, 0x3b, 0xfe, 0x8d, 0x08, 0x1c, 0xf5, 0xd9, 0xb1, + 0x0f, 0xb9, 0xdb, 0x9c, 0xb3, 0xbd, 0x2d, 0x7e, 0x88, 0x0f, 0x3e, 0x3c, 0x01, 0x31, 0x82, 0x8f, + 0x06, 0xfc, 0x40, 0x7c, 0xe6, 0x73, 0x5f, 0xf8, 0x27, 0x4a, 0xf0, 0x40, 0x33, 0x30, 0x2a, 0x94, + 0x49, 0xfe, 0x7d, 0xc3, 0xeb, 0x4f, 0xf6, 0x3e, 0x3a, 0x6e, 0xdf, 0x39, 0x35, 0x86, 0x75, 0xf8, + 0x95, 0x73, 0x7d, 0xbf, 0xcb, 0xc0, 0x82, 0xe9, 0xde, 0xf9, 0xd5, 0x3e, 0x22, 0xf5, 0xeb, 0xc9, + 0xc5, 0xb2, 0x7b, 0x8e, 0xb3, 0x72, 0x03, 0x0e, 0xbe, 0x8d, 0xb4, 0xed, 0xed, 0xa0, 0x88, 0x90, + 0x7f, 0xd0, 0x3d, 0xe8, 0x65, 0x96, 0xed, 0x1d, 0xe2, 0x82, 0x27, 0x1f, 0x5f, 0x3b, 0x1e, 0x5f, + 0xe8, 0x3b, 0x95, 0x2c, 0xf8, 0xa6, 0x11, 0xd5, 0x47, 0xa9, 0xfc, 0x9c, 0x04, 0x87, 0xba, 0x9a, + 0xe6, 0x31, 0x7e, 0xb9, 0xc7, 0x2b, 0xc6, 0xdb, 0x4a, 0x7a, 0x96, 0x7b, 0x08, 0x7b, 0xdf, 0x40, + 0x61, 0x99, 0x14, 0x01, 0x69, 0xdf, 0x0a, 0x07, 0x82, 0xc2, 0x0a, 0x35, 0xdd, 0x0b, 0x13, 0xc1, + 0xc3, 0x02, 0xae, 0xae, 0xf1, 0xc0, 0x71, 0x81, 0xa2, 0x85, 0xf5, 0xec, 0xf6, 0xb5, 0x08, 0x69, + 0x17, 0x95, 0x67, 0xc7, 0x43, 0x77, 0xd5, 0xa3, 0x54, 0x3e, 0x2c, 0xc1, 0x7c, 0xb0, 0x05, 0x5f, + 0x9e, 0xb4, 0x3f, 0x61, 0xef, 0xd8, 0x10, 0xbf, 0x2a, 0xc1, 0x5d, 0x7b, 0xc8, 0xc4, 0x15, 0xf0, + 0x1c, 0xcc, 0xf8, 0x36, 0x09, 0x44, 0x08, 0x17, 0xc3, 0x7e, 0x72, 0x70, 0x86, 0xea, 0xae, 0x89, + 0x8f, 0x10, 0xa5, 0x7c, 0xe6, 0xcb, 0x73, 0xd3, 0xdd, 0x75, 0xb6, 0x3a, 0xdd, 0xbd, 0xb0, 0xbf, + 0x83, 0xf6, 0xf1, 0x31, 0x09, 0xee, 0x0f, 0x76, 0xb5, 0x47, 0xaa, 0xfb, 0xd7, 0x35, 0x0e, 0xff, + 0x4e, 0x82, 0x93, 0xc3, 0x08, 0xc7, 0x07, 0x64, 0x0b, 0xa6, 0xbd, 0x24, 0x3c, 0x3c, 0x1e, 0xfb, + 0x4a, 0xed, 0x99, 0x95, 0x22, 0x97, 0xdb, 0x1b, 0xa0, 0xf8, 0x16, 0x77, 0x2c, 0xff, 0x90, 0xbb, + 0x4a, 0x0e, 0x6e, 0xf4, 0x0b, 0x25, 0x07, 0xb6, 0xfa, 0x7b, 0x8c, 0x45, 0xa4, 0xc7, 0x58, 0x78, + 0x59, 0xbb, 0x72, 0x9d, 0xc7, 0xad, 0x1e, 0xdb, 0x73, 0xdf, 0x07, 0xd3, 0x3d, 0x4c, 0x99, 0x7b, + 0xf5, 0x3e, 0x2c, 0x59, 0x45, 0xdd, 0xc6, 0xaa, 0xec, 0xc2, 0x1c, 0x6d, 0xb7, 0x87, 0xa2, 0xdf, + 0xe8, 0x2e, 0x37, 0x79, 0x6c, 0xe9, 0xd9, 0x34, 0xef, 0x7b, 0x09, 0x12, 0x6c, 0x9c, 0x79, 0x77, + 0x6f, 0xc3, 0x50, 0x38, 0x03, 0xe5, 0x27, 0x44, 0x2c, 0x2b, 0x08, 0xb1, 0x7b, 0xfb, 0xd0, 0x30, + 0x7d, 0xbd, 0x43, 0x3e, 0xe4, 0x53, 0xc6, 0x97, 0x44, 0x54, 0xeb, 0x2d, 0x1d, 0x57, 0x47, 0xf5, + 0x8e, 0x45, 0x35, 0xa6, 0x9b, 0x37, 0x36, 0x7c, 0xfd, 0xb4, 0x08, 0x5f, 0x6e, 0x9f, 0x06, 0x84, + 0xaf, 0xbf, 0x1e, 0xd5, 0xbb, 0x81, 0x6c, 0x80, 0x98, 0x7f, 0x13, 0x03, 0xd9, 0x37, 0x25, 0x38, + 0x4c, 0xfb, 0xe6, 0xdf, 0xa3, 0xd8, 0xaf, 0xca, 0x1f, 0x04, 0x64, 0xb7, 0xab, 0x5a, 0x4f, 0xef, + 0x96, 0xed, 0x76, 0xf5, 0x6a, 0x60, 0x7e, 0x79, 0x10, 0x50, 0x2d, 0xb0, 0x13, 0x45, 0xb1, 0xd9, + 0x05, 0x4a, 0xb9, 0xe6, 0xdb, 0xe8, 0xe8, 0x31, 0x9c, 0xb1, 0x3b, 0x30, 0x9c, 0x5f, 0x94, 0x20, + 0xdb, 0xab, 0xcb, 0x7c, 0xf8, 0x0c, 0x38, 0x18, 0x38, 0x3f, 0x08, 0x8f, 0xe0, 0x83, 0xc3, 0xec, + 0xf2, 0x84, 0xdc, 0xe8, 0x40, 0x1b, 0xbf, 0xd1, 0x79, 0xc0, 0x5c, 0xd0, 0x42, 0xbb, 0x33, 0xeb, + 0xbf, 0x36, 0xf7, 0xf9, 0x7c, 0x57, 0x5c, 0xfd, 0x1b, 0x91, 0x7b, 0xdf, 0x80, 0xd9, 0x3e, 0x52, + 0xbf, 0xd1, 0xf3, 0xde, 0x4e, 0xdf, 0xc1, 0xbc, 0xd3, 0xe9, 0xfb, 0x23, 0xdc, 0x13, 0x82, 0x97, + 0xf3, 0x7d, 0x6b, 0xb1, 0x5e, 0x2f, 0x90, 0x95, 0xa7, 0xe1, 0x48, 0x4f, 0x2a, 0x2e, 0xdb, 0x22, + 0xc4, 0x76, 0x0c, 0xdb, 0xe1, 0x62, 0x1d, 0xef, 0x27, 0x56, 0x88, 0x9a, 0xd2, 0x28, 0x08, 0x64, + 0xca, 0x7a, 0xc3, 0xb2, 0x1a, 0x5c, 0x0c, 0xe5, 0x09, 0x98, 0xf2, 0xc1, 0x78, 0x23, 0xe7, 0x21, + 0xd6, 0xb2, 0xac, 0x86, 0xfb, 0xc0, 0xa9, 0xdf, 0xc6, 0xbe, 0x65, 0x35, 0x78, 0xb7, 0x29, 0xbe, + 0x32, 0x03, 0x88, 0x31, 0xa3, 0x7b, 0xfc, 0xa2, 0x89, 0x32, 0x4c, 0x07, 0xa0, 0xbc, 0x91, 0xd7, + 0x75, 0x7e, 0x70, 0xf6, 0xeb, 0x07, 0x20, 0x4e, 0xb9, 0xa2, 0x8f, 0x4a, 0x81, 0xcf, 0xe6, 0x2d, + 0xf4, 0x63, 0xd3, 0x7b, 0x4d, 0x9c, 0x3d, 0x3d, 0x34, 0x3e, 0xcf, 0xd9, 0x4e, 0xbe, 0xe7, 0x5f, + 0x7d, 0xe5, 0x23, 0x91, 0x7b, 0x90, 0x72, 0xba, 0xcf, 0x0a, 0xde, 0xe7, 0x2f, 0x9f, 0x0e, 0x7c, + 0x16, 0xe7, 0xd4, 0x70, 0x4d, 0x09, 0xc9, 0x16, 0x86, 0x45, 0xe7, 0x82, 0x3d, 0x46, 0x05, 0x3b, + 0x87, 0x1e, 0x1e, 0x2c, 0xd8, 0xe9, 0x77, 0x05, 0x9d, 0xe6, 0x07, 0xd1, 0xef, 0x4b, 0x30, 0xd3, + 0x6b, 0x49, 0x87, 0x2e, 0x0c, 0x27, 0x45, 0x77, 0x4a, 0x91, 0xbd, 0x78, 0x1b, 0x94, 0xbc, 0x2b, + 0xcb, 0xb4, 0x2b, 0x39, 0xf4, 0xf8, 0x6d, 0x74, 0xe5, 0xb4, 0x7f, 0xeb, 0xff, 0xbf, 0x4b, 0x70, + 0x6c, 0xcf, 0x15, 0x12, 0xca, 0x0d, 0x27, 0xe5, 0x1e, 0xb9, 0x53, 0x36, 0xff, 0x7a, 0x58, 0xf0, + 0x1e, 0xbf, 0x8d, 0xf6, 0xf8, 0x09, 0x54, 0xba, 0x9d, 0x1e, 0xf7, 0x3c, 0x5f, 0x41, 0xbf, 0x15, + 0xbc, 0x74, 0xba, 0xb7, 0x39, 0x75, 0x2d, 0x3c, 0x06, 0x38, 0x46, 0x77, 0x52, 0xab, 0x3c, 0x45, + 0xbb, 0xa0, 0xa2, 0x8d, 0xd7, 0x39, 0x68, 0xa7, 0xdf, 0x15, 0x0c, 0xfc, 0x3f, 0x88, 0xfe, 0x9b, + 0xd4, 0xfb, 0x0e, 0xe9, 0xa3, 0x7b, 0x8a, 0xd8, 0x7f, 0x51, 0x95, 0xbd, 0xb0, 0x7f, 0x42, 0xde, + 0xc9, 0x26, 0xed, 0x64, 0x1d, 0xe1, 0x3b, 0xdd, 0xc9, 0x9e, 0x83, 0x88, 0x7e, 0x47, 0x82, 0x99, + 0x5e, 0x6b, 0x92, 0x01, 0x6e, 0xb9, 0xc7, 0x22, 0x6b, 0x80, 0x5b, 0xee, 0xb5, 0x00, 0x52, 0xde, + 0x42, 0x3b, 0x7f, 0x1e, 0x3d, 0xd2, 0xaf, 0xf3, 0x7b, 0x8e, 0x22, 0xf1, 0xc5, 0x3d, 0x93, 0xfc, + 0x01, 0xbe, 0x38, 0xcc, 0x3a, 0x66, 0x80, 0x2f, 0x0e, 0xb5, 0xc6, 0x18, 0xec, 0x8b, 0x6e, 0xcf, + 0x86, 0x1c, 0x46, 0x1b, 0xfd, 0x86, 0x04, 0xe3, 0x81, 0x8c, 0x18, 0x9d, 0xd9, 0x53, 0xd0, 0x5e, + 0x0b, 0x86, 0xec, 0xd9, 0xfd, 0x90, 0xf0, 0xbe, 0x94, 0x68, 0x5f, 0x96, 0x50, 0xee, 0x76, 0xfa, + 0x12, 0x3c, 0x46, 0xfd, 0xa2, 0x04, 0xd3, 0x3d, 0xb2, 0xcc, 0x01, 0x5e, 0xd8, 0x3f, 0x69, 0xce, + 0x5e, 0xd8, 0x3f, 0x21, 0xef, 0xd5, 0x25, 0xda, 0xab, 0xef, 0x45, 0x6f, 0xbd, 0x9d, 0x5e, 0xf9, + 0xe6, 0xe7, 0x5b, 0xde, 0x95, 0x2c, 0x5f, 0x3b, 0xe8, 0xfc, 0x3e, 0x05, 0x13, 0x1d, 0x7a, 0x74, + 0xdf, 0x74, 0xbc, 0x3f, 0x4f, 0xd2, 0xfe, 0xbc, 0x0d, 0xad, 0xbf, 0xbe, 0xfe, 0x74, 0x4f, 0xeb, + 0xbf, 0xdc, 0xfd, 0x38, 0x74, 0x6f, 0x2b, 0xea, 0x99, 0xac, 0x66, 0x1f, 0xde, 0x17, 0x0d, 0xef, + 0xd4, 0x05, 0xda, 0xa9, 0xb3, 0xe8, 0xa1, 0x7e, 0x9d, 0xf2, 0xdd, 0xbb, 0x34, 0xcc, 0x6d, 0xeb, + 0xf4, 0xbb, 0x58, 0x0a, 0xfc, 0x83, 0xe8, 0xdd, 0xe2, 0xce, 0xd3, 0x89, 0x3d, 0xdb, 0xf5, 0xe5, + 0xb1, 0xd9, 0xfb, 0x87, 0xc0, 0xe4, 0x72, 0xdd, 0x43, 0xe5, 0x9a, 0x45, 0x47, 0xfb, 0xc9, 0x45, + 0x72, 0x59, 0xf4, 0x7e, 0xc9, 0xbd, 0x26, 0x7b, 0x72, 0x6f, 0xde, 0xfe, 0x64, 0x37, 0xfb, 0xc0, + 0x50, 0xb8, 0x5c, 0x92, 0xe3, 0x54, 0x92, 0x79, 0x34, 0xdb, 0x57, 0x12, 0x96, 0xfa, 0xde, 0xe9, + 0x4b, 0x05, 0xff, 0xf3, 0x20, 0xcc, 0xf5, 0x69, 0xd1, 0xb9, 0xf1, 0x3a, 0x5f, 0x4e, 0x0f, 0x77, + 0xae, 0x75, 0x27, 0xdf, 0x57, 0x0f, 0x7a, 0x3f, 0xad, 0xfc, 0x5e, 0x0c, 0xd0, 0xaa, 0x5d, 0x5f, + 0x6a, 0x63, 0xdd, 0xf1, 0x7d, 0xeb, 0x31, 0xf4, 0xf8, 0x4f, 0x7a, 0x5d, 0x8f, 0xff, 0x56, 0x03, + 0xcf, 0xe9, 0x22, 0xfb, 0x7b, 0xb2, 0x3b, 0xf4, 0x9b, 0xba, 0xe8, 0x77, 0xe5, 0x4d, 0x5d, 0xef, + 0x2b, 0xf7, 0xb1, 0x3b, 0xf7, 0x36, 0x27, 0x7e, 0xbb, 0xef, 0x93, 0xf8, 0x53, 0xd9, 0xc4, 0x1e, + 0x4f, 0x65, 0x33, 0x7d, 0xdf, 0xc3, 0x72, 0x6a, 0x74, 0x4e, 0x7c, 0xc5, 0x3b, 0x39, 0xdc, 0x25, + 0x59, 0xfe, 0x99, 0x6f, 0x6f, 0x0b, 0xe1, 0x28, 0x64, 0xbb, 0xcd, 0xc9, 0x75, 0xea, 0x8f, 0x44, + 0x41, 0x5e, 0xb5, 0xeb, 0xc5, 0x9a, 0xe1, 0xbc, 0x41, 0xb6, 0xf6, 0x78, 0xff, 0xf7, 0x4e, 0xe8, + 0xb5, 0x5b, 0x73, 0x13, 0x4c, 0xa7, 0x7b, 0x68, 0xb2, 0x09, 0x93, 0xe1, 0xfb, 0xe8, 0xcc, 0xb2, + 0x0a, 0xb7, 0xf3, 0xd8, 0xbd, 0xeb, 0x1e, 0xfa, 0x44, 0xf0, 0xdd, 0x39, 0xba, 0xd1, 0xdb, 0x98, + 0x99, 0x41, 0x5d, 0x7e, 0x23, 0x1f, 0x87, 0x7a, 0x63, 0x96, 0x85, 0x4c, 0x78, 0x50, 0xdc, 0x11, + 0x7b, 0x45, 0x82, 0xd1, 0x55, 0x5b, 0xa4, 0x82, 0xf8, 0x4d, 0xfa, 0x34, 0xed, 0x51, 0xf7, 0x77, + 0x48, 0xa2, 0xc3, 0xd9, 0xad, 0xff, 0xb7, 0x49, 0x46, 0x94, 0x03, 0x30, 0xed, 0xeb, 0xa3, 0xdb, + 0xf7, 0x2f, 0x44, 0x68, 0x6c, 0xcc, 0xe3, 0xba, 0x61, 0xba, 0x19, 0x24, 0xfe, 0xdb, 0xfa, 0xe8, + 0xc6, 0xd3, 0x71, 0xec, 0x76, 0x74, 0x7c, 0x8d, 0x06, 0x86, 0x90, 0x2e, 0xdd, 0x0d, 0xaf, 0xd5, + 0xee, 0xe7, 0x60, 0xd2, 0x3e, 0xbe, 0xad, 0x13, 0x7a, 0xf4, 0xa5, 0x7c, 0x45, 0x82, 0xf1, 0x55, + 0xbb, 0xbe, 0x69, 0xd6, 0xfe, 0xb7, 0xb6, 0xdb, 0x6d, 0x38, 0x10, 0xe8, 0xe5, 0x1b, 0xa4, 0xce, + 0xb3, 0x1f, 0x8b, 0x41, 0x74, 0xd5, 0xae, 0xa3, 0x77, 0xc2, 0x64, 0x38, 0x51, 0xe8, 0x9b, 0xff, + 0x75, 0xcf, 0x02, 0xfd, 0xd7, 0x68, 0xfd, 0x67, 0x0c, 0x74, 0x0d, 0xc6, 0x83, 0xb3, 0xc5, 0x89, + 0x3d, 0x98, 0x04, 0x30, 0xb3, 0x0f, 0x0d, 0x8b, 0xe9, 0x36, 0xf6, 0x0e, 0x48, 0xb9, 0x81, 0xee, + 0xee, 0x3d, 0xa8, 0x05, 0x52, 0xff, 0x8c, 0xb6, 0x47, 0x38, 0x21, 0xda, 0x0b, 0x87, 0x92, 0xbd, + 0xb4, 0x17, 0xc2, 0xdd, 0x53, 0x7b, 0xfd, 0xdc, 0x6a, 0x0b, 0xc0, 0xe7, 0x03, 0xf7, 0xee, 0xc1, + 0xc1, 0x43, 0xcb, 0x9e, 0x1a, 0x0a, 0xcd, 0x3d, 0x68, 0xba, 0xc3, 0x09, 0xf8, 0xff, 0x0a, 0x00, + 0x00, 0xff, 0xff, 0x8b, 0x4e, 0x2e, 0xba, 0xf9, 0xb5, 0x00, 0x00, } r := bytes.NewReader(gzipped) gzipr, err := compress_gzip.NewReader(r) diff --git a/sei-tendermint/cmd/buf_plugin/main.go b/sei-tendermint/cmd/buf_plugin/main.go index 43509449cd..e74f08cf90 100644 --- a/sei-tendermint/cmd/buf_plugin/main.go +++ b/sei-tendermint/cmd/buf_plugin/main.go @@ -1,26 +1,30 @@ package main import ( + "errors" "fmt" "iter" "log" - "errors" + "strings" "google.golang.org/protobuf/compiler/protogen" "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protodesc" "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/types/descriptorpb" "google.golang.org/protobuf/types/dynamicpb" "google.golang.org/protobuf/types/pluginpb" - "google.golang.org/protobuf/reflect/protodesc" - "google.golang.org/protobuf/reflect/protoregistry" ) func (d md) GetBoolOption(ext protoreflect.ExtensionTypeDescriptor) bool { options := d.Options().(*descriptorpb.MessageOptions).ProtoReflect() - if !options.Has(ext) { return false } + if !options.Has(ext) { + return false + } return options.Get(ext).Bool() } + type md struct{ protoreflect.MessageDescriptor } type mds = map[protoreflect.FullName]md @@ -51,7 +55,9 @@ func allMDs(files *protoregistry.Files) iter.Seq[md] { } func OrPanic(err error) { - if err!=nil { panic(err) } + if err != nil { + panic(err) + } } func OrPanic1[T any](v T, err error) T { @@ -71,15 +77,15 @@ func run(p *protogen.Plugin) error { // Re-unmarshal proto files, so that dynamic options are registered. OrPanic(proto.UnmarshalOptions{ Resolver: dynamicpb.NewTypes(OrPanic1(protodesc.NewFiles(fds))), - }.Unmarshal(OrPanic1(proto.Marshal(fds)),fds)) + }.Unmarshal(OrPanic1(proto.Marshal(fds)), fds)) files := OrPanic1(protodesc.NewFiles(fds)) - hashableOpt,err := dynamicpb.NewTypes(files).FindExtensionByName("hashable.hashable") - if err!=nil { - if errors.Is(err,protoregistry.NotFound) { + hashableOpt, err := dynamicpb.NewTypes(files).FindExtensionByName("hashable.hashable") + if err != nil { + if errors.Is(err, protoregistry.NotFound) { return nil } - panic(fmt.Errorf("files.FindExtensionByName(): %w",err)) + panic(fmt.Errorf("files.FindExtensionByName(): %w", err)) } descs := mds{} for d := range allMDs(files) { @@ -88,6 +94,9 @@ func run(p *protogen.Plugin) error { } } log.Printf("buf_plugin: found hashable option; %d message type(s) marked with it", len(descs)) + if len(descs) == 0 { + return nil + } for _, d := range descs { if d.Syntax() != protoreflect.Proto3 { return fmt.Errorf("%q: hashable messages have to be in proto3 syntax", d.FullName()) @@ -106,9 +115,9 @@ func run(p *protogen.Plugin) error { } switch f.Kind() { case protoreflect.FloatKind, protoreflect.DoubleKind: - return fmt.Errorf("%q: float fields are not hashable",f.FullName()) + return fmt.Errorf("%q: float fields are not hashable", f.FullName()) case protoreflect.GroupKind: - return fmt.Errorf("%q: group field are not hashable",f.FullName()) + return fmt.Errorf("%q: group field are not hashable", f.FullName()) case protoreflect.MessageKind: if _, ok := descs[f.Message().FullName()]; !ok { return fmt.Errorf("%q: message fields of hashable messages have to be hashable", f.FullName()) @@ -116,9 +125,53 @@ func run(p *protogen.Plugin) error { } } } + generateHashableFiles(p, descs) return nil } +type pm struct { *protogen.Message } + +func (m pm) walk(yield func(pm) bool) bool { + if !yield(m) { return false } + for _,x := range m.Messages { + if !(pm{x}).walk(yield) { return false } + } + return true +} + +func allPMs(f *protogen.File) iter.Seq[pm] { + return func(yield func(pm) bool) { + for _,m := range f.Messages { + if !(pm{m}).walk(yield) { return } + } + } +} + +func generateHashableFiles(p *protogen.Plugin, descs mds) { + for _, file := range p.Files { + if !file.Generate { + continue + } + var targets []*protogen.Message + for m := range allPMs(file) { + if _,ok := descs[m.Desc.FullName()]; ok { + targets = append(targets,m.Message) + } + } + if len(targets) == 0 { + continue + } + genPath := strings.TrimSuffix(file.Desc.Path(), ".proto")+".hashable.go" + g := p.NewGeneratedFile(genPath, file.GoImportPath) + g.P("// Code generated by buf_plugin. DO NOT EDIT.") + g.P("package ", file.GoPackageName) + g.P() + for _, m := range targets { + g.P("func (*",m.GoIdent,") IsHashable() {}") + } + } +} + func main() { protogen.Options{}.Run(run) } diff --git a/sei-tendermint/proto/tendermint/consensus/types.pb.go b/sei-tendermint/proto/tendermint/consensus/types.pb.go index 29fbb299f9..753ccf374b 100644 --- a/sei-tendermint/proto/tendermint/consensus/types.pb.go +++ b/sei-tendermint/proto/tendermint/consensus/types.pb.go @@ -7,7 +7,6 @@ import ( fmt "fmt" _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" - _ "github.com/tendermint/tendermint/proto/hashable" bits "github.com/tendermint/tendermint/proto/tendermint/libs/bits" types "github.com/tendermint/tendermint/proto/tendermint/types" io "io" @@ -805,62 +804,61 @@ func init() { func init() { proto.RegisterFile("tendermint/consensus/types.proto", fileDescriptor_81a22d2efc008981) } var fileDescriptor_81a22d2efc008981 = []byte{ - // 871 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x4f, 0x6f, 0xe3, 0x44, - 0x14, 0xb7, 0xa9, 0xd3, 0xa4, 0xcf, 0x69, 0x0b, 0xa3, 0xee, 0x2a, 0x14, 0x48, 0x83, 0xb9, 0x54, - 0x08, 0x39, 0x28, 0x3d, 0x20, 0x05, 0x24, 0xc0, 0xfc, 0x59, 0xef, 0x6a, 0xb3, 0x1b, 0x39, 0xcb, - 0x0a, 0x71, 0xb1, 0x9c, 0x78, 0x14, 0x0f, 0x6b, 0x7b, 0x2c, 0xcf, 0x24, 0xa5, 0x57, 0x4e, 0x1c, - 0xf9, 0x00, 0x7c, 0x03, 0xce, 0x48, 0x7c, 0x84, 0x1e, 0xf7, 0xc8, 0x69, 0x85, 0xd2, 0x8f, 0x80, - 0xe0, 0x8c, 0x66, 0x3c, 0x89, 0x1d, 0xd6, 0x5b, 0xe8, 0x05, 0x69, 0x6f, 0x33, 0x7e, 0xef, 0xfd, - 0xe6, 0xcd, 0xef, 0xbd, 0xf7, 0xf3, 0x40, 0x8f, 0xe3, 0x34, 0xc4, 0x79, 0x42, 0x52, 0xde, 0x9f, - 0xd1, 0x94, 0xe1, 0x94, 0x2d, 0x58, 0x9f, 0x5f, 0x64, 0x98, 0xd9, 0x59, 0x4e, 0x39, 0x45, 0x47, - 0xa5, 0x87, 0xbd, 0xf1, 0x38, 0x3e, 0x9a, 0xd3, 0x39, 0x95, 0x0e, 0x7d, 0xb1, 0x2a, 0x7c, 0x8f, - 0xab, 0x68, 0x31, 0x99, 0xb2, 0xfe, 0x94, 0xf0, 0x2d, 0xb4, 0xe3, 0x37, 0x2b, 0x1e, 0xf2, 0xfb, - 0x96, 0xf5, 0x20, 0x0a, 0x58, 0x14, 0x4c, 0x63, 0x5c, 0xec, 0xad, 0x5f, 0x74, 0x68, 0x3f, 0xc0, - 0xe7, 0x1e, 0x5d, 0xa4, 0xe1, 0x84, 0xe3, 0x0c, 0xdd, 0x86, 0xdd, 0x08, 0x93, 0x79, 0xc4, 0x3b, - 0x7a, 0x4f, 0x3f, 0xdd, 0xf1, 0xd4, 0x0e, 0x1d, 0x41, 0x23, 0x17, 0x4e, 0x9d, 0x57, 0x7a, 0xfa, - 0x69, 0xc3, 0x2b, 0x36, 0x08, 0x81, 0xc1, 0x38, 0xce, 0x3a, 0x3b, 0x3d, 0xfd, 0x74, 0xdf, 0x93, - 0x6b, 0xf4, 0x01, 0x74, 0x18, 0x9e, 0xd1, 0x34, 0x64, 0x3e, 0x23, 0xe9, 0x0c, 0xfb, 0x8c, 0x07, - 0x39, 0xf7, 0x39, 0x49, 0x70, 0xc7, 0x90, 0x98, 0xb7, 0x94, 0x7d, 0x22, 0xcc, 0x13, 0x61, 0x7d, - 0x44, 0x12, 0x8c, 0xde, 0x85, 0xd7, 0xe2, 0x80, 0x71, 0x7f, 0x46, 0x93, 0x84, 0x70, 0xbf, 0x38, - 0xae, 0x21, 0x8f, 0x3b, 0x14, 0x86, 0xcf, 0xe4, 0x77, 0x99, 0xaa, 0xf5, 0xa7, 0x0e, 0xfb, 0x0f, - 0xf0, 0xf9, 0xe3, 0x20, 0x26, 0xa1, 0x13, 0xd3, 0xd9, 0x93, 0x1b, 0x26, 0xfe, 0x35, 0xdc, 0x9a, - 0x8a, 0x30, 0x3f, 0x13, 0xb9, 0x31, 0xcc, 0xfd, 0x08, 0x07, 0x21, 0xce, 0xe5, 0x4d, 0xcc, 0xc1, - 0x89, 0x5d, 0xa9, 0x49, 0xc1, 0xdf, 0x38, 0xc8, 0xf9, 0x04, 0x73, 0x57, 0xba, 0x39, 0xc6, 0xe5, - 0xb3, 0x13, 0xcd, 0x43, 0x12, 0x63, 0xcb, 0x82, 0x3e, 0x06, 0xb3, 0x44, 0x66, 0xf2, 0xc6, 0xe6, - 0xa0, 0x5b, 0xc5, 0x13, 0x75, 0xb3, 0x45, 0xdd, 0x6c, 0x87, 0xf0, 0x4f, 0xf3, 0x3c, 0xb8, 0xf0, - 0x60, 0x03, 0xc4, 0xd0, 0x1b, 0xb0, 0x47, 0x98, 0x22, 0x41, 0x5e, 0xbf, 0xe5, 0xb5, 0x08, 0x2b, - 0x2e, 0x6f, 0xb9, 0xd0, 0x1a, 0xe7, 0x34, 0xa3, 0x2c, 0x88, 0xd1, 0x47, 0xd0, 0xca, 0xd4, 0x5a, - 0xde, 0xd9, 0x1c, 0x1c, 0xd7, 0xa4, 0xad, 0x3c, 0x54, 0xc6, 0x9b, 0x08, 0xeb, 0x27, 0x1d, 0xcc, - 0xb5, 0x71, 0xfc, 0xf0, 0xfe, 0x0b, 0xf9, 0x7b, 0x0f, 0xd0, 0x3a, 0xc6, 0xcf, 0x68, 0xec, 0x57, - 0xc9, 0x7c, 0x75, 0x6d, 0x19, 0xd3, 0x58, 0xd6, 0x05, 0xdd, 0x81, 0x76, 0xd5, 0x5b, 0xd1, 0xf9, - 0x2f, 0xd7, 0x57, 0xb9, 0x99, 0x15, 0x34, 0xeb, 0x09, 0xec, 0x39, 0x6b, 0x4e, 0x6e, 0x58, 0xdb, - 0xf7, 0xc1, 0x10, 0xdc, 0xab, 0xb3, 0x6f, 0xd7, 0x97, 0x52, 0x9d, 0x29, 0x3d, 0xad, 0x21, 0x18, - 0x8f, 0x29, 0x17, 0x1d, 0x68, 0x2c, 0x29, 0xc7, 0x8a, 0xcd, 0x9a, 0x48, 0xe1, 0xe5, 0x49, 0x9f, - 0xe1, 0xee, 0xe5, 0x0f, 0xab, 0x9f, 0xdb, 0xba, 0xf5, 0xbd, 0x0e, 0x4d, 0x37, 0x60, 0x32, 0xfe, - 0x66, 0x79, 0x9e, 0x81, 0x21, 0x50, 0x65, 0x9e, 0x07, 0x75, 0x2d, 0x37, 0x21, 0xf3, 0x14, 0x87, - 0x23, 0x36, 0x7f, 0x74, 0x91, 0x61, 0x4f, 0x3a, 0x0b, 0x28, 0x92, 0x86, 0xf8, 0x3b, 0xd9, 0x58, - 0x0d, 0xaf, 0xd8, 0x58, 0xbf, 0xea, 0xd0, 0x16, 0x19, 0x4c, 0x30, 0x1f, 0x05, 0xdf, 0x0e, 0xce, - 0xfe, 0x8f, 0x4c, 0xbe, 0x80, 0x56, 0xd1, 0xe8, 0x24, 0x54, 0x5d, 0xfe, 0xfa, 0xf3, 0x81, 0xb2, - 0x86, 0x77, 0x3f, 0x77, 0x0e, 0x05, 0xdb, 0xab, 0x67, 0x27, 0x4d, 0xf5, 0xc1, 0x6b, 0xca, 0xd8, - 0xbb, 0xa1, 0xf5, 0x87, 0x0e, 0xa6, 0x4a, 0xdd, 0x21, 0x9c, 0xbd, 0x3c, 0x99, 0xa3, 0x21, 0x34, - 0x44, 0x27, 0x30, 0x39, 0xa4, 0xff, 0xb5, 0xc9, 0x8b, 0x10, 0xeb, 0x2f, 0x03, 0x9a, 0x23, 0xcc, - 0x58, 0x30, 0xc7, 0xe8, 0x1e, 0x1c, 0xa4, 0xf8, 0xbc, 0x18, 0x2c, 0x5f, 0xca, 0x69, 0xd1, 0x7f, - 0x96, 0x5d, 0xf7, 0x63, 0xb0, 0xab, 0x72, 0xed, 0x6a, 0x5e, 0x3b, 0xad, 0xca, 0xf7, 0x08, 0x0e, - 0x05, 0xd6, 0x52, 0xe8, 0xa2, 0x2f, 0x13, 0x95, 0x7c, 0x99, 0x83, 0x77, 0x5e, 0x08, 0x56, 0x6a, - 0xa8, 0xab, 0x79, 0xfb, 0xe9, 0x96, 0xa8, 0x56, 0x25, 0xa6, 0x66, 0x94, 0x4b, 0x9c, 0xb5, 0x92, - 0xb8, 0x15, 0x89, 0x41, 0x5f, 0xfe, 0x43, 0x0c, 0x0a, 0xae, 0xdf, 0xbe, 0x1e, 0x61, 0xfc, 0xf0, - 0xbe, 0xbb, 0xad, 0x05, 0xe8, 0x13, 0x80, 0x52, 0x52, 0x15, 0xdb, 0x27, 0xf5, 0x28, 0x1b, 0xcd, - 0x70, 0x35, 0x6f, 0x6f, 0x23, 0xaa, 0x42, 0x12, 0xe4, 0x60, 0xef, 0x3e, 0x2f, 0x93, 0x65, 0xac, - 0xe8, 0x42, 0x57, 0x2b, 0xc6, 0x1b, 0x0d, 0xa1, 0x15, 0x05, 0xcc, 0x97, 0x51, 0x4d, 0x19, 0xf5, - 0x56, 0x7d, 0x94, 0x9a, 0x7d, 0x57, 0xf3, 0x9a, 0x91, 0x92, 0x81, 0x7b, 0x70, 0x20, 0xe2, 0xe4, - 0x6f, 0x25, 0x11, 0xe3, 0xd8, 0x69, 0x5d, 0x57, 0xd0, 0xea, 0xe0, 0x8a, 0x82, 0x2e, 0xab, 0x83, - 0x7c, 0x07, 0xf6, 0x37, 0x58, 0xa2, 0x9f, 0x3a, 0x7b, 0xd7, 0x91, 0x58, 0x19, 0x24, 0x41, 0xe2, - 0xb2, 0xdc, 0x3a, 0x0d, 0xd8, 0x61, 0x8b, 0xc4, 0xf9, 0xea, 0x72, 0xd5, 0xd5, 0x9f, 0xae, 0xba, - 0xfa, 0xef, 0xab, 0xae, 0xfe, 0xe3, 0x55, 0x57, 0x7b, 0x7a, 0xd5, 0xd5, 0x7e, 0xbb, 0xea, 0x6a, - 0xdf, 0x7c, 0x38, 0x27, 0x3c, 0x5a, 0x4c, 0xed, 0x19, 0x4d, 0xfa, 0xd5, 0x37, 0x44, 0xb9, 0x2c, - 0x5e, 0x23, 0x75, 0xef, 0x99, 0xe9, 0xae, 0xb4, 0x9d, 0xfd, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x65, - 0x3a, 0x50, 0x64, 0xee, 0x08, 0x00, 0x00, + // 852 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x4f, 0x8f, 0xdb, 0x44, + 0x14, 0xb7, 0x59, 0x67, 0x93, 0x7d, 0xde, 0xec, 0xc2, 0x68, 0x5b, 0x85, 0x00, 0x49, 0x30, 0x97, + 0x15, 0x42, 0x0e, 0xca, 0x1e, 0x90, 0x0a, 0x12, 0x60, 0xfe, 0xd4, 0xad, 0x9a, 0x36, 0x72, 0x4a, + 0x85, 0xb8, 0x58, 0x4e, 0x3c, 0x4a, 0x86, 0xc6, 0x1e, 0xcb, 0x33, 0xc9, 0xb2, 0x57, 0x3e, 0x01, + 0x1f, 0x80, 0xaf, 0x81, 0xc4, 0x47, 0xe8, 0xb1, 0x47, 0x4e, 0x15, 0xca, 0x7e, 0x04, 0x04, 0x67, + 0x34, 0xe3, 0x49, 0x3c, 0xa1, 0xde, 0x85, 0xbd, 0x20, 0xf5, 0x36, 0xe3, 0xf7, 0xde, 0x6f, 0xde, + 0xfc, 0xde, 0x7b, 0x3f, 0x0f, 0xf4, 0x38, 0x4e, 0x63, 0x9c, 0x27, 0x24, 0xe5, 0xfd, 0x29, 0x4d, + 0x19, 0x4e, 0xd9, 0x92, 0xf5, 0xf9, 0x45, 0x86, 0x99, 0x9b, 0xe5, 0x94, 0x53, 0x74, 0x52, 0x7a, + 0xb8, 0x5b, 0x8f, 0xf6, 0xc9, 0x8c, 0xce, 0xa8, 0x74, 0xe8, 0x8b, 0x55, 0xe1, 0xdb, 0xd6, 0xd1, + 0x16, 0x64, 0xc2, 0xfa, 0x13, 0xc2, 0x77, 0xd0, 0xda, 0x6f, 0x6b, 0x1e, 0xf2, 0xbb, 0x6e, 0x75, + 0x7e, 0x31, 0xe1, 0xf0, 0x21, 0x3e, 0x0f, 0xe8, 0x32, 0x8d, 0xc7, 0x1c, 0x67, 0xe8, 0x36, 0xec, + 0xcf, 0x31, 0x99, 0xcd, 0x79, 0xcb, 0xec, 0x99, 0xa7, 0x7b, 0x81, 0xda, 0xa1, 0x13, 0xa8, 0xe5, + 0xc2, 0xa9, 0xf5, 0x5a, 0xcf, 0x3c, 0xad, 0x05, 0xc5, 0x06, 0x21, 0xb0, 0x18, 0xc7, 0x59, 0x6b, + 0xaf, 0x67, 0x9e, 0x36, 0x03, 0xb9, 0x46, 0x1f, 0x41, 0x8b, 0xe1, 0x29, 0x4d, 0x63, 0x16, 0x32, + 0x92, 0x4e, 0x71, 0xc8, 0x78, 0x94, 0xf3, 0x90, 0x93, 0x04, 0xb7, 0x2c, 0x89, 0x79, 0x4b, 0xd9, + 0xc7, 0xc2, 0x3c, 0x16, 0xd6, 0xc7, 0x24, 0xc1, 0xe8, 0x7d, 0x78, 0x63, 0x11, 0x31, 0x1e, 0x4e, + 0x69, 0x92, 0x10, 0x1e, 0x16, 0xc7, 0xd5, 0xe4, 0x71, 0xc7, 0xc2, 0xf0, 0x85, 0xfc, 0x2e, 0x53, + 0x75, 0xfe, 0x34, 0xa1, 0xf9, 0x10, 0x9f, 0x3f, 0x89, 0x16, 0x24, 0xf6, 0x16, 0x74, 0xfa, 0xf4, + 0x86, 0x89, 0x7f, 0x0b, 0xb7, 0x26, 0x22, 0x2c, 0xcc, 0x44, 0x6e, 0x0c, 0xf3, 0x70, 0x8e, 0xa3, + 0x18, 0xe7, 0xf2, 0x26, 0xf6, 0xa0, 0xeb, 0x6a, 0x35, 0x28, 0xf8, 0x1a, 0x45, 0x39, 0x1f, 0x63, + 0xee, 0x4b, 0x37, 0xcf, 0x7a, 0xf6, 0xa2, 0x6b, 0x04, 0x48, 0x62, 0xec, 0x58, 0xd0, 0xa7, 0x60, + 0x97, 0xc8, 0x4c, 0xde, 0xd8, 0x1e, 0x74, 0x74, 0x3c, 0x51, 0x27, 0x57, 0xd4, 0xc9, 0xf5, 0x08, + 0xff, 0x3c, 0xcf, 0xa3, 0x8b, 0x00, 0xb6, 0x40, 0x0c, 0xbd, 0x05, 0x07, 0x84, 0x29, 0x12, 0xe4, + 0xf5, 0x1b, 0x41, 0x83, 0xb0, 0xe2, 0xf2, 0x8e, 0x0f, 0x8d, 0x51, 0x4e, 0x33, 0xca, 0xa2, 0x05, + 0xfa, 0x04, 0x1a, 0x99, 0x5a, 0xcb, 0x3b, 0xdb, 0x83, 0x76, 0x45, 0xda, 0xca, 0x43, 0x65, 0xbc, + 0x8d, 0x70, 0x7e, 0x36, 0xc1, 0xde, 0x18, 0x47, 0x8f, 0x1e, 0x5c, 0xc9, 0xdf, 0x07, 0x80, 0x36, + 0x31, 0x61, 0x46, 0x17, 0xa1, 0x4e, 0xe6, 0xeb, 0x1b, 0xcb, 0x88, 0x2e, 0x64, 0x5d, 0xd0, 0x5d, + 0x38, 0xd4, 0xbd, 0x15, 0x9d, 0xff, 0x72, 0x7d, 0x95, 0x9b, 0xad, 0xa1, 0x39, 0x4f, 0xe1, 0xc0, + 0xdb, 0x70, 0x72, 0xc3, 0xda, 0x7e, 0x08, 0x96, 0xe0, 0x5e, 0x9d, 0x7d, 0xbb, 0xba, 0x94, 0xea, + 0x4c, 0xe9, 0xe9, 0x0c, 0xc0, 0x7a, 0x42, 0xb9, 0xe8, 0x40, 0x6b, 0x45, 0x39, 0x56, 0x6c, 0x56, + 0x44, 0x0a, 0xaf, 0x40, 0xfa, 0x38, 0x3f, 0x9a, 0x50, 0xf7, 0x23, 0x26, 0xe3, 0x6e, 0x96, 0xdf, + 0x19, 0x58, 0x02, 0x4d, 0xe6, 0x77, 0x54, 0xd5, 0x6a, 0x63, 0x32, 0x4b, 0x71, 0x3c, 0x64, 0xb3, + 0xc7, 0x17, 0x19, 0x0e, 0xa4, 0xb3, 0x80, 0x22, 0x69, 0x8c, 0x7f, 0x90, 0x0d, 0x55, 0x0b, 0x8a, + 0x8d, 0xf3, 0xab, 0x09, 0x87, 0x22, 0x83, 0x31, 0xe6, 0xc3, 0xe8, 0xfb, 0xc1, 0xd9, 0xff, 0x91, + 0xc9, 0x57, 0xd0, 0x28, 0x1a, 0x9c, 0xc4, 0xaa, 0xbb, 0xdf, 0x7c, 0x39, 0x50, 0xd6, 0xee, 0xde, + 0x97, 0xde, 0xb1, 0x60, 0x79, 0xfd, 0xa2, 0x5b, 0x57, 0x1f, 0x82, 0xba, 0x8c, 0xbd, 0x17, 0x3b, + 0x7f, 0x98, 0x60, 0xab, 0xd4, 0x3d, 0xc2, 0xd9, 0xab, 0x93, 0x39, 0xba, 0x03, 0x35, 0xd1, 0x01, + 0x4c, 0x0e, 0xe7, 0x7f, 0x6d, 0xee, 0x22, 0xc4, 0xf9, 0xcb, 0x82, 0xfa, 0x10, 0x33, 0x16, 0xcd, + 0x30, 0xba, 0x0f, 0x47, 0x29, 0x3e, 0x2f, 0x06, 0x2a, 0x94, 0x32, 0x5a, 0xf4, 0x9d, 0xe3, 0x56, + 0xfd, 0x00, 0x5c, 0x5d, 0xa6, 0x7d, 0x23, 0x38, 0x4c, 0x75, 0xd9, 0x1e, 0xc2, 0xb1, 0xc0, 0x5a, + 0x09, 0x3d, 0x0c, 0x65, 0xa2, 0x92, 0x2f, 0x7b, 0xf0, 0xde, 0x95, 0x60, 0xa5, 0x76, 0xfa, 0x46, + 0xd0, 0x4c, 0x77, 0xc4, 0x54, 0x97, 0x96, 0x8a, 0x11, 0x2e, 0x71, 0x36, 0x0a, 0xe2, 0x6b, 0xd2, + 0x82, 0xbe, 0xfe, 0x87, 0x08, 0x14, 0x5c, 0xbf, 0x7b, 0x3d, 0xc2, 0xe8, 0xd1, 0x03, 0x7f, 0x57, + 0x03, 0xd0, 0x67, 0x00, 0xa5, 0x94, 0x2a, 0xb6, 0xbb, 0xd5, 0x28, 0x5b, 0xad, 0xf0, 0x8d, 0xe0, + 0x60, 0x2b, 0xa6, 0x42, 0x0a, 0xe4, 0x40, 0xef, 0xbf, 0x2c, 0x8f, 0x65, 0xac, 0xe8, 0x42, 0xdf, + 0x28, 0xc6, 0x1a, 0xdd, 0x81, 0xc6, 0x3c, 0x62, 0xa1, 0x8c, 0xaa, 0xcb, 0xa8, 0x77, 0xaa, 0xa3, + 0xd4, 0xec, 0xfb, 0x46, 0x50, 0x9f, 0x2b, 0x19, 0xb8, 0x0f, 0x47, 0x22, 0x4e, 0xfe, 0x4e, 0x12, + 0x31, 0x8e, 0xad, 0xc6, 0x75, 0x05, 0xd5, 0x07, 0x57, 0x14, 0x74, 0xa5, 0x0f, 0xf2, 0x5d, 0x68, + 0x6e, 0xb1, 0x44, 0x3f, 0xb5, 0x0e, 0xae, 0x23, 0x51, 0x1b, 0x24, 0x41, 0xe2, 0xaa, 0xdc, 0x7a, + 0x35, 0xd8, 0x63, 0xcb, 0xc4, 0xfb, 0xe6, 0xd9, 0xba, 0x63, 0x3e, 0x5f, 0x77, 0xcc, 0xdf, 0xd7, + 0x1d, 0xf3, 0xa7, 0xcb, 0x8e, 0xf1, 0xfc, 0xb2, 0x63, 0xfc, 0x76, 0xd9, 0x31, 0xbe, 0xfb, 0x78, + 0x46, 0xf8, 0x7c, 0x39, 0x71, 0xa7, 0x34, 0xe9, 0xeb, 0x6f, 0x85, 0x72, 0x59, 0xbc, 0x3a, 0xaa, + 0xde, 0x2d, 0x93, 0x7d, 0x69, 0x3b, 0xfb, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xf9, 0xf1, 0xeb, 0x6b, + 0xd6, 0x08, 0x00, 0x00, } func (m *NewRoundStep) Marshal() (dAtA []byte, err error) { diff --git a/sei-tendermint/proto/tendermint/consensus/types.proto b/sei-tendermint/proto/tendermint/consensus/types.proto index e84d5d89dd..4fd8e3c36b 100644 --- a/sei-tendermint/proto/tendermint/consensus/types.proto +++ b/sei-tendermint/proto/tendermint/consensus/types.proto @@ -5,7 +5,6 @@ package tendermint.consensus; import "gogoproto/gogo.proto"; import "tendermint/libs/bits/types.proto"; import "tendermint/types/types.proto"; -import "hashable.proto"; option go_package = "github.com/tendermint/tendermint/proto/tendermint/consensus"; @@ -53,7 +52,6 @@ message BlockPart { // Vote is sent when voting for a proposal (or lack thereof). message Vote { - option (hashable.hashable) = true; tendermint.types.Vote vote = 1; } diff --git a/sei-tendermint/proto/tendermint/types/types.pb.go b/sei-tendermint/proto/tendermint/types/types.pb.go index de4222a448..39009a11d2 100644 --- a/sei-tendermint/proto/tendermint/types/types.pb.go +++ b/sei-tendermint/proto/tendermint/types/types.pb.go @@ -9,7 +9,6 @@ import ( proto "github.com/gogo/protobuf/proto" _ "github.com/gogo/protobuf/types" github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" - _ "github.com/tendermint/tendermint/proto/hashable" crypto "github.com/tendermint/tendermint/proto/tendermint/crypto" version "github.com/tendermint/tendermint/proto/tendermint/version" io "io" @@ -98,12 +97,8 @@ func (SignedMsgType) EnumDescriptor() ([]byte, []int) { // PartsetHeader type PartSetHeader struct { - // Types that are valid to be assigned to XTotal: - // *PartSetHeader_Total - XTotal isPartSetHeader_XTotal `protobuf_oneof:"_total"` - // Types that are valid to be assigned to XHash: - // *PartSetHeader_Hash - XHash isPartSetHeader_XHash `protobuf_oneof:"_hash"` + Total uint32 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"` + Hash []byte `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"` } func (m *PartSetHeader) Reset() { *m = PartSetHeader{} } @@ -139,62 +134,20 @@ func (m *PartSetHeader) XXX_DiscardUnknown() { var xxx_messageInfo_PartSetHeader proto.InternalMessageInfo -type isPartSetHeader_XTotal interface { - isPartSetHeader_XTotal() - MarshalTo([]byte) (int, error) - Size() int -} -type isPartSetHeader_XHash interface { - isPartSetHeader_XHash() - MarshalTo([]byte) (int, error) - Size() int -} - -type PartSetHeader_Total struct { - Total uint32 `protobuf:"varint,1,opt,name=total,proto3,oneof" json:"total,omitempty"` -} -type PartSetHeader_Hash struct { - Hash []byte `protobuf:"bytes,2,opt,name=hash,proto3,oneof" json:"hash,omitempty"` -} - -func (*PartSetHeader_Total) isPartSetHeader_XTotal() {} -func (*PartSetHeader_Hash) isPartSetHeader_XHash() {} - -func (m *PartSetHeader) GetXTotal() isPartSetHeader_XTotal { - if m != nil { - return m.XTotal - } - return nil -} -func (m *PartSetHeader) GetXHash() isPartSetHeader_XHash { - if m != nil { - return m.XHash - } - return nil -} - func (m *PartSetHeader) GetTotal() uint32 { - if x, ok := m.GetXTotal().(*PartSetHeader_Total); ok { - return x.Total + if m != nil { + return m.Total } return 0 } func (m *PartSetHeader) GetHash() []byte { - if x, ok := m.GetXHash().(*PartSetHeader_Hash); ok { - return x.Hash + if m != nil { + return m.Hash } return nil } -// XXX_OneofWrappers is for the internal use of the proto package. -func (*PartSetHeader) XXX_OneofWrappers() []interface{} { - return []interface{}{ - (*PartSetHeader_Total)(nil), - (*PartSetHeader_Hash)(nil), - } -} - type Part struct { Index uint32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` Bytes []byte `protobuf:"bytes,2,opt,name=bytes,proto3" json:"bytes,omitempty"` @@ -257,14 +210,8 @@ func (m *Part) GetProof() crypto.Proof { // BlockID type BlockID struct { - // Types that are valid to be assigned to XHash: - // - // *BlockID_Hash - XHash isBlockID_XHash `protobuf_oneof:"_hash"` - // Types that are valid to be assigned to XPartSetHeader: - // - // *BlockID_PartSetHeader - XPartSetHeader isBlockID_XPartSetHeader `protobuf_oneof:"_part_set_header"` + Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` + PartSetHeader PartSetHeader `protobuf:"bytes,2,opt,name=part_set_header,json=partSetHeader,proto3" json:"part_set_header"` } func (m *BlockID) Reset() { *m = BlockID{} } @@ -300,60 +247,18 @@ func (m *BlockID) XXX_DiscardUnknown() { var xxx_messageInfo_BlockID proto.InternalMessageInfo -type isBlockID_XHash interface { - isBlockID_XHash() - MarshalTo([]byte) (int, error) - Size() int -} -type isBlockID_XPartSetHeader interface { - isBlockID_XPartSetHeader() - MarshalTo([]byte) (int, error) - Size() int -} - -type BlockID_Hash struct { - Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3,oneof" json:"hash,omitempty"` -} -type BlockID_PartSetHeader struct { - PartSetHeader *PartSetHeader `protobuf:"bytes,2,opt,name=part_set_header,json=partSetHeader,proto3,oneof" json:"part_set_header,omitempty"` -} - -func (*BlockID_Hash) isBlockID_XHash() {} -func (*BlockID_PartSetHeader) isBlockID_XPartSetHeader() {} - -func (m *BlockID) GetXHash() isBlockID_XHash { - if m != nil { - return m.XHash - } - return nil -} -func (m *BlockID) GetXPartSetHeader() isBlockID_XPartSetHeader { - if m != nil { - return m.XPartSetHeader - } - return nil -} - func (m *BlockID) GetHash() []byte { - if x, ok := m.GetXHash().(*BlockID_Hash); ok { - return x.Hash - } - return nil -} - -func (m *BlockID) GetPartSetHeader() *PartSetHeader { - if x, ok := m.GetXPartSetHeader().(*BlockID_PartSetHeader); ok { - return x.PartSetHeader + if m != nil { + return m.Hash } return nil } -// XXX_OneofWrappers is for the internal use of the proto package. -func (*BlockID) XXX_OneofWrappers() []interface{} { - return []interface{}{ - (*BlockID_Hash)(nil), - (*BlockID_PartSetHeader)(nil), +func (m *BlockID) GetPartSetHeader() PartSetHeader { + if m != nil { + return m.PartSetHeader } + return PartSetHeader{} } // Header defines the structure of a Tendermint block header. @@ -605,42 +510,18 @@ func (m *TxKey) GetTxKey() []byte { // Vote represents a prevote, precommit, or commit vote from validators for // consensus. type Vote struct { - // Types that are valid to be assigned to XType: - // - // *Vote_Type - XType isVote_XType `protobuf_oneof:"_type"` - // Types that are valid to be assigned to XHeight: - // - // *Vote_Height - XHeight isVote_XHeight `protobuf_oneof:"_height"` - // Types that are valid to be assigned to XRound: - // - // *Vote_Round - XRound isVote_XRound `protobuf_oneof:"_round"` - // Types that are valid to be assigned to XBlockId: - // - // *Vote_BlockId - XBlockId isVote_XBlockId `protobuf_oneof:"_block_id"` - // Types that are valid to be assigned to XValidatorAddress: - // - // *Vote_ValidatorAddress - XValidatorAddress isVote_XValidatorAddress `protobuf_oneof:"_validator_address"` - // Types that are valid to be assigned to XValidatorIndex: - // - // *Vote_ValidatorIndex - XValidatorIndex isVote_XValidatorIndex `protobuf_oneof:"_validator_index"` - // Types that are valid to be assigned to XSignature: - // - // *Vote_Signature - XSignature isVote_XSignature `protobuf_oneof:"_signature"` - // Types that are valid to be assigned to XExtension: - // - // *Vote_Extension - XExtension isVote_XExtension `protobuf_oneof:"_extension"` - // Types that are valid to be assigned to XExtensionSignature: - // - // *Vote_ExtensionSignature - XExtensionSignature isVote_XExtensionSignature `protobuf_oneof:"_extension_signature"` + Type SignedMsgType `protobuf:"varint,1,opt,name=type,proto3,enum=tendermint.types.SignedMsgType" json:"type,omitempty"` + Height int64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"` + Round int32 `protobuf:"varint,3,opt,name=round,proto3" json:"round,omitempty"` + BlockID BlockID `protobuf:"bytes,4,opt,name=block_id,json=blockId,proto3" json:"block_id"` + Timestamp time.Time `protobuf:"bytes,5,opt,name=timestamp,proto3,stdtime" json:"timestamp"` + ValidatorAddress []byte `protobuf:"bytes,6,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"` + ValidatorIndex int32 `protobuf:"varint,7,opt,name=validator_index,json=validatorIndex,proto3" json:"validator_index,omitempty"` + // Vote signature by the validator if they participated in consensus for the + // associated block. + Signature []byte `protobuf:"bytes,8,opt,name=signature,proto3" json:"signature,omitempty"` + Extension []byte `protobuf:"bytes,9,opt,name=extension,proto3" json:"extension,omitempty"` // Deprecated: Do not use. + ExtensionSignature []byte `protobuf:"bytes,10,opt,name=extension_signature,json=extensionSignature,proto3" json:"extension_signature,omitempty"` // Deprecated: Do not use. } func (m *Vote) Reset() { *m = Vote{} } @@ -676,225 +557,78 @@ func (m *Vote) XXX_DiscardUnknown() { var xxx_messageInfo_Vote proto.InternalMessageInfo -type isVote_XType interface { - isVote_XType() - MarshalTo([]byte) (int, error) - Size() int -} -type isVote_XHeight interface { - isVote_XHeight() - MarshalTo([]byte) (int, error) - Size() int -} -type isVote_XRound interface { - isVote_XRound() - MarshalTo([]byte) (int, error) - Size() int -} -type isVote_XBlockId interface { - isVote_XBlockId() - MarshalTo([]byte) (int, error) - Size() int -} -type isVote_XValidatorAddress interface { - isVote_XValidatorAddress() - MarshalTo([]byte) (int, error) - Size() int -} -type isVote_XValidatorIndex interface { - isVote_XValidatorIndex() - MarshalTo([]byte) (int, error) - Size() int -} -type isVote_XSignature interface { - isVote_XSignature() - MarshalTo([]byte) (int, error) - Size() int -} -type isVote_XExtension interface { - isVote_XExtension() - MarshalTo([]byte) (int, error) - Size() int -} -type isVote_XExtensionSignature interface { - isVote_XExtensionSignature() - MarshalTo([]byte) (int, error) - Size() int -} - -type Vote_Type struct { - Type SignedMsgType `protobuf:"varint,1,opt,name=type,proto3,enum=tendermint.types.SignedMsgType,oneof" json:"type,omitempty"` -} -type Vote_Height struct { - Height int64 `protobuf:"varint,2,opt,name=height,proto3,oneof" json:"height,omitempty"` -} -type Vote_Round struct { - Round int32 `protobuf:"varint,3,opt,name=round,proto3,oneof" json:"round,omitempty"` -} -type Vote_BlockId struct { - BlockId *BlockID `protobuf:"bytes,4,opt,name=block_id,json=blockId,proto3,oneof" json:"block_id,omitempty"` -} -type Vote_ValidatorAddress struct { - ValidatorAddress []byte `protobuf:"bytes,6,opt,name=validator_address,json=validatorAddress,proto3,oneof" json:"validator_address,omitempty"` -} -type Vote_ValidatorIndex struct { - ValidatorIndex int32 `protobuf:"varint,7,opt,name=validator_index,json=validatorIndex,proto3,oneof" json:"validator_index,omitempty"` -} -type Vote_Signature struct { - Signature []byte `protobuf:"bytes,8,opt,name=signature,proto3,oneof" json:"signature,omitempty"` -} -type Vote_Extension struct { - Extension []byte `protobuf:"bytes,9,opt,name=extension,proto3,oneof" json:"extension,omitempty"` -} -type Vote_ExtensionSignature struct { - ExtensionSignature []byte `protobuf:"bytes,10,opt,name=extension_signature,json=extensionSignature,proto3,oneof" json:"extension_signature,omitempty"` -} - -func (*Vote_Type) isVote_XType() {} -func (*Vote_Height) isVote_XHeight() {} -func (*Vote_Round) isVote_XRound() {} -func (*Vote_BlockId) isVote_XBlockId() {} -func (*Vote_ValidatorAddress) isVote_XValidatorAddress() {} -func (*Vote_ValidatorIndex) isVote_XValidatorIndex() {} -func (*Vote_Signature) isVote_XSignature() {} -func (*Vote_Extension) isVote_XExtension() {} -func (*Vote_ExtensionSignature) isVote_XExtensionSignature() {} - -func (m *Vote) GetXType() isVote_XType { - if m != nil { - return m.XType - } - return nil -} -func (m *Vote) GetXHeight() isVote_XHeight { - if m != nil { - return m.XHeight - } - return nil -} -func (m *Vote) GetXRound() isVote_XRound { - if m != nil { - return m.XRound - } - return nil -} -func (m *Vote) GetXBlockId() isVote_XBlockId { - if m != nil { - return m.XBlockId - } - return nil -} -func (m *Vote) GetXValidatorAddress() isVote_XValidatorAddress { - if m != nil { - return m.XValidatorAddress - } - return nil -} -func (m *Vote) GetXValidatorIndex() isVote_XValidatorIndex { - if m != nil { - return m.XValidatorIndex - } - return nil -} -func (m *Vote) GetXSignature() isVote_XSignature { - if m != nil { - return m.XSignature - } - return nil -} -func (m *Vote) GetXExtension() isVote_XExtension { - if m != nil { - return m.XExtension - } - return nil -} -func (m *Vote) GetXExtensionSignature() isVote_XExtensionSignature { - if m != nil { - return m.XExtensionSignature - } - return nil -} - func (m *Vote) GetType() SignedMsgType { - if x, ok := m.GetXType().(*Vote_Type); ok { - return x.Type + if m != nil { + return m.Type } return UnknownType } func (m *Vote) GetHeight() int64 { - if x, ok := m.GetXHeight().(*Vote_Height); ok { - return x.Height + if m != nil { + return m.Height } return 0 } func (m *Vote) GetRound() int32 { - if x, ok := m.GetXRound().(*Vote_Round); ok { - return x.Round + if m != nil { + return m.Round } return 0 } -func (m *Vote) GetBlockId() *BlockID { - if x, ok := m.GetXBlockId().(*Vote_BlockId); ok { - return x.BlockId +func (m *Vote) GetBlockID() BlockID { + if m != nil { + return m.BlockID } - return nil + return BlockID{} +} + +func (m *Vote) GetTimestamp() time.Time { + if m != nil { + return m.Timestamp + } + return time.Time{} } func (m *Vote) GetValidatorAddress() []byte { - if x, ok := m.GetXValidatorAddress().(*Vote_ValidatorAddress); ok { - return x.ValidatorAddress + if m != nil { + return m.ValidatorAddress } return nil } func (m *Vote) GetValidatorIndex() int32 { - if x, ok := m.GetXValidatorIndex().(*Vote_ValidatorIndex); ok { - return x.ValidatorIndex + if m != nil { + return m.ValidatorIndex } return 0 } func (m *Vote) GetSignature() []byte { - if x, ok := m.GetXSignature().(*Vote_Signature); ok { - return x.Signature + if m != nil { + return m.Signature } return nil } // Deprecated: Do not use. func (m *Vote) GetExtension() []byte { - if x, ok := m.GetXExtension().(*Vote_Extension); ok { - return x.Extension + if m != nil { + return m.Extension } return nil } // Deprecated: Do not use. func (m *Vote) GetExtensionSignature() []byte { - if x, ok := m.GetXExtensionSignature().(*Vote_ExtensionSignature); ok { - return x.ExtensionSignature + if m != nil { + return m.ExtensionSignature } return nil } -// XXX_OneofWrappers is for the internal use of the proto package. -func (*Vote) XXX_OneofWrappers() []interface{} { - return []interface{}{ - (*Vote_Type)(nil), - (*Vote_Height)(nil), - (*Vote_Round)(nil), - (*Vote_BlockId)(nil), - (*Vote_ValidatorAddress)(nil), - (*Vote_ValidatorIndex)(nil), - (*Vote_Signature)(nil), - (*Vote_Extension)(nil), - (*Vote_ExtensionSignature)(nil), - } -} - // Commit contains the evidence that a block was committed by a set of // validators. type Commit struct { @@ -1712,124 +1446,113 @@ func init() { func init() { proto.RegisterFile("tendermint/types/types.proto", fileDescriptor_d3a6e55e2345de56) } var fileDescriptor_d3a6e55e2345de56 = []byte{ - // 1862 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0x4f, 0x6f, 0x1b, 0xc7, - 0x15, 0xd7, 0x8a, 0xff, 0x1f, 0x49, 0x89, 0x9a, 0x48, 0x16, 0x45, 0xdb, 0x14, 0xcb, 0x20, 0x8d, - 0x92, 0xb8, 0x94, 0xaa, 0x14, 0x6d, 0x12, 0xb4, 0x07, 0xae, 0xa4, 0x98, 0x84, 0xf5, 0x87, 0x5d, - 0x32, 0x2e, 0xda, 0x43, 0x17, 0x4b, 0x72, 0x4c, 0x6e, 0xbd, 0xdc, 0x5d, 0xec, 0x0e, 0x15, 0xc9, - 0x9f, 0xc0, 0xd0, 0xc9, 0x97, 0xf6, 0xa6, 0x53, 0x7b, 0x08, 0xd0, 0x0f, 0xd1, 0xa2, 0x27, 0x5f, - 0x0a, 0xe4, 0xd6, 0x5e, 0x9a, 0x16, 0x72, 0xd1, 0xcf, 0x51, 0xcc, 0x9b, 0xd9, 0xe5, 0x52, 0x24, - 0xe3, 0xc4, 0xf0, 0x45, 0xd8, 0x79, 0xef, 0xf7, 0x66, 0xde, 0x9f, 0xdf, 0xbc, 0x79, 0x22, 0xdc, - 0x63, 0xd4, 0xee, 0x53, 0x6f, 0x64, 0xda, 0x6c, 0x97, 0x5d, 0xba, 0xd4, 0x17, 0x7f, 0x6b, 0xae, - 0xe7, 0x30, 0x87, 0x14, 0x26, 0xda, 0x1a, 0xca, 0x4b, 0xeb, 0x03, 0x67, 0xe0, 0xa0, 0x72, 0x97, - 0x7f, 0x09, 0x5c, 0x69, 0x7b, 0xe0, 0x38, 0x03, 0x8b, 0xee, 0xe2, 0xaa, 0x3b, 0x7e, 0xb2, 0xcb, - 0xcc, 0x11, 0xf5, 0x99, 0x31, 0x72, 0x25, 0xe0, 0x7e, 0xe4, 0x98, 0x9e, 0x77, 0xe9, 0x32, 0x87, - 0x63, 0x9d, 0x27, 0x52, 0x5d, 0x99, 0xf1, 0xe2, 0xdc, 0xb0, 0xcc, 0xbe, 0xc1, 0x1c, 0x4f, 0x22, - 0xca, 0x11, 0xc4, 0x39, 0xf5, 0x7c, 0xd3, 0xb1, 0xa3, 0x9e, 0x96, 0x56, 0x86, 0x86, 0x3f, 0x34, - 0xba, 0x16, 0x15, 0xeb, 0xea, 0x6f, 0x21, 0xdf, 0x32, 0x3c, 0xd6, 0xa6, 0xac, 0x41, 0x8d, 0x3e, - 0xf5, 0xc8, 0x16, 0x24, 0x98, 0xc3, 0x0c, 0xab, 0xa8, 0x54, 0x94, 0x9d, 0x7c, 0x63, 0x49, 0x13, - 0xcb, 0xe7, 0x8a, 0x42, 0x36, 0x21, 0xce, 0xad, 0x8b, 0xcb, 0x15, 0x65, 0x27, 0xd7, 0x50, 0x34, - 0x5c, 0x3d, 0x57, 0x94, 0xcf, 0x92, 0x2f, 0x9f, 0xdf, 0xfc, 0x39, 0xa7, 0xa8, 0x69, 0x48, 0xea, - 0x88, 0x56, 0x53, 0x90, 0xd0, 0xb9, 0xb6, 0x3a, 0x84, 0x38, 0xdf, 0x9f, 0xac, 0x43, 0xc2, 0xb4, - 0xfb, 0xf4, 0x42, 0x6c, 0xab, 0x89, 0x05, 0x97, 0x76, 0x2f, 0x19, 0xf5, 0xc5, 0x96, 0x9a, 0x58, - 0x90, 0x9f, 0x40, 0x02, 0x83, 0x2e, 0xc6, 0x2a, 0xca, 0x4e, 0x76, 0xbf, 0x58, 0x8b, 0x64, 0x57, - 0x24, 0xa5, 0xd6, 0xe2, 0x7a, 0x35, 0xfe, 0xf2, 0x9b, 0xed, 0x25, 0x4d, 0x80, 0xab, 0xbf, 0x57, - 0x20, 0xa5, 0x5a, 0x4e, 0xef, 0x69, 0xf3, 0x30, 0xf4, 0x54, 0x41, 0x4f, 0x97, 0x42, 0x4f, 0xc9, - 0x31, 0xac, 0xba, 0x86, 0xc7, 0x74, 0x9f, 0x32, 0x7d, 0x88, 0x01, 0xe3, 0xd1, 0xd9, 0xfd, 0xed, - 0xda, 0xed, 0x12, 0xd6, 0xa6, 0xf2, 0xd2, 0x50, 0xb4, 0xbc, 0x1b, 0x15, 0x44, 0xe3, 0x0e, 0xa2, - 0x55, 0x09, 0x14, 0xf4, 0x5b, 0xfb, 0x57, 0xff, 0x17, 0x87, 0xa4, 0xcc, 0xed, 0x2f, 0x20, 0x25, - 0x6b, 0x82, 0x9e, 0x65, 0xf7, 0xef, 0x47, 0x4f, 0x95, 0xaa, 0xda, 0x81, 0x63, 0xfb, 0xd4, 0xf6, - 0xc7, 0xbe, 0x8c, 0x2f, 0xb0, 0x21, 0x3f, 0x84, 0x74, 0x6f, 0x68, 0x98, 0xb6, 0x6e, 0xf6, 0xd1, - 0xeb, 0x8c, 0x9a, 0xbd, 0xf9, 0x66, 0x3b, 0x75, 0xc0, 0x65, 0xcd, 0x43, 0x2d, 0x85, 0xca, 0x66, - 0x9f, 0xdc, 0x81, 0xe4, 0x90, 0x9a, 0x83, 0x21, 0xc3, 0x04, 0xc6, 0x34, 0xb9, 0x22, 0x9f, 0x40, - 0x9c, 0xf3, 0xad, 0x18, 0xc7, 0xb3, 0x4b, 0x35, 0x41, 0xc6, 0x5a, 0x40, 0xc6, 0x5a, 0x27, 0x20, - 0xa3, 0x9a, 0xe6, 0x07, 0xbf, 0xf8, 0xf7, 0xb6, 0xa2, 0xa1, 0x05, 0x39, 0x80, 0xbc, 0x65, 0xf8, - 0x4c, 0xef, 0xf2, 0xfc, 0xf2, 0xe3, 0x13, 0xb8, 0xc5, 0xd6, 0x6c, 0xd2, 0x64, 0x05, 0xa4, 0xeb, - 0x59, 0x6e, 0x25, 0x44, 0x7d, 0xb2, 0x03, 0x05, 0xdc, 0xa4, 0xe7, 0x8c, 0x46, 0x26, 0xc3, 0x84, - 0x15, 0x93, 0x58, 0xf7, 0x15, 0x2e, 0x3f, 0x40, 0x71, 0xc3, 0xf0, 0x87, 0xe4, 0x2e, 0x64, 0xfa, - 0x06, 0x33, 0x04, 0x24, 0x85, 0x90, 0x34, 0x17, 0xa0, 0xf2, 0x7d, 0x58, 0x0d, 0x49, 0xef, 0x0b, - 0x48, 0x5a, 0xec, 0x32, 0x11, 0x23, 0x70, 0x0f, 0xd6, 0x6d, 0x7a, 0xc1, 0xf4, 0xdb, 0xe8, 0x0c, - 0xa2, 0x09, 0xd7, 0x3d, 0x9e, 0xb6, 0x78, 0x0f, 0x56, 0x7a, 0x41, 0xf2, 0x05, 0x16, 0x10, 0x9b, - 0x0f, 0xa5, 0x08, 0xdb, 0x82, 0xb4, 0xe1, 0xba, 0x02, 0x90, 0x45, 0x40, 0xca, 0x70, 0x5d, 0x54, - 0x7d, 0x08, 0x6b, 0x18, 0xa3, 0x47, 0xfd, 0xb1, 0xc5, 0xe4, 0x26, 0x39, 0xc4, 0xac, 0x72, 0x85, - 0x26, 0xe4, 0x88, 0x7d, 0x17, 0xf2, 0xf4, 0xdc, 0xec, 0x53, 0xbb, 0x47, 0x05, 0x2e, 0x8f, 0xb8, - 0x5c, 0x20, 0x44, 0xd0, 0x07, 0x50, 0x70, 0x3d, 0xc7, 0x75, 0x7c, 0xea, 0xe9, 0x46, 0xbf, 0xef, - 0x51, 0xdf, 0x2f, 0xae, 0x88, 0xfd, 0x02, 0x79, 0x5d, 0x88, 0xab, 0x45, 0x88, 0x1f, 0x1a, 0xcc, - 0x20, 0x05, 0x88, 0xb1, 0x0b, 0xbf, 0xa8, 0x54, 0x62, 0x3b, 0x39, 0x8d, 0x7f, 0x56, 0xcb, 0x90, - 0xe8, 0x5c, 0x3c, 0xa2, 0x97, 0x64, 0x03, 0x92, 0xec, 0x42, 0x7f, 0x4a, 0x2f, 0xc5, 0xcd, 0xd0, - 0x12, 0x8c, 0x8b, 0xab, 0x5f, 0xc5, 0x21, 0xfe, 0xd8, 0x61, 0x14, 0x19, 0x72, 0xe9, 0x52, 0xd4, - 0xae, 0xcc, 0xbb, 0x13, 0x6d, 0x73, 0x60, 0xd3, 0xfe, 0x89, 0x3f, 0xe8, 0x5c, 0xba, 0x94, 0x5f, - 0x2c, 0x2e, 0xe6, 0x17, 0xeb, 0x6e, 0xc8, 0x39, 0xce, 0xcc, 0x58, 0x43, 0x09, 0x58, 0xc7, 0x95, - 0x5b, 0x90, 0xf0, 0x9c, 0xb1, 0xdd, 0x47, 0x3e, 0x26, 0x1a, 0xcb, 0x9a, 0x58, 0x72, 0xd5, 0xa7, - 0x90, 0x0e, 0x49, 0x15, 0x7f, 0x0d, 0xa9, 0x1a, 0x31, 0x2d, 0xd5, 0x15, 0x64, 0xe2, 0xa6, 0x7b, - 0xb0, 0x16, 0x96, 0x36, 0xcc, 0x0d, 0x12, 0xaa, 0x11, 0xd7, 0x0a, 0xa1, 0x4a, 0xa6, 0x87, 0x5b, - 0x3c, 0x88, 0x50, 0x47, 0x17, 0xed, 0x28, 0x85, 0x1e, 0x25, 0x22, 0xe4, 0x69, 0x72, 0x39, 0x47, - 0xff, 0x00, 0x32, 0xbe, 0x39, 0xb0, 0x0d, 0x36, 0xf6, 0xa8, 0xa0, 0x58, 0x23, 0xa9, 0x4d, 0x44, - 0x1c, 0xf2, 0x1e, 0x64, 0xe8, 0x05, 0xa3, 0x36, 0x5e, 0x69, 0xe4, 0x95, 0xba, 0x5c, 0x54, 0x1a, - 0x29, 0x6d, 0x22, 0xe6, 0xb0, 0x4f, 0xe0, 0x9d, 0x70, 0xad, 0x4f, 0xf6, 0x84, 0xd0, 0x20, 0xad, - 0x91, 0x10, 0xd0, 0x8e, 0x1c, 0x30, 0xd5, 0x61, 0x78, 0x2e, 0xd4, 0x0c, 0xa4, 0x74, 0x91, 0x58, - 0xec, 0xb6, 0x98, 0x47, 0x35, 0x0b, 0x99, 0xf0, 0x6a, 0xaa, 0xeb, 0x40, 0xf4, 0x99, 0xbc, 0x60, - 0x67, 0xba, 0x15, 0xbb, 0x9a, 0x03, 0x98, 0x78, 0x83, 0xab, 0xd0, 0x09, 0xf5, 0x0e, 0xac, 0xeb, - 0x73, 0x7c, 0xae, 0xfe, 0x55, 0x81, 0xa4, 0xb8, 0xa9, 0x91, 0x36, 0xa3, 0x4c, 0xb5, 0x99, 0xf5, - 0xa0, 0xda, 0x9c, 0x09, 0x09, 0x59, 0x6b, 0x72, 0x14, 0x29, 0x74, 0xec, 0x75, 0xdd, 0x63, 0x95, - 0x77, 0x0f, 0xde, 0xdb, 0xa4, 0x20, 0xac, 0x3b, 0xa9, 0x03, 0x84, 0xce, 0xf8, 0xc5, 0x78, 0x25, - 0xb6, 0x93, 0xdd, 0xbf, 0x3b, 0xbb, 0x91, 0x70, 0xb1, 0x6d, 0x0e, 0x64, 0x23, 0x8a, 0x18, 0x55, - 0xff, 0xa5, 0x40, 0x26, 0xd4, 0x93, 0x3a, 0xe4, 0x03, 0xbf, 0xf4, 0x27, 0x96, 0x31, 0x90, 0xdc, - 0xbf, 0xbf, 0xd0, 0xb9, 0xcf, 0x2d, 0x63, 0xa0, 0x65, 0xa5, 0x3f, 0x7c, 0x41, 0x3e, 0x9a, 0x47, - 0x44, 0xf1, 0xa2, 0xcd, 0xd0, 0x90, 0xa8, 0x90, 0x09, 0x1f, 0x7d, 0x99, 0x88, 0xef, 0xd6, 0x89, - 0x27, 0x66, 0xe4, 0x5e, 0x94, 0x99, 0x71, 0x3c, 0x68, 0x22, 0xa8, 0xfe, 0x25, 0x0e, 0xe9, 0x16, - 0xf6, 0x06, 0xc3, 0x22, 0x1f, 0x7f, 0xaf, 0x1b, 0x2d, 0xee, 0x73, 0xa4, 0xb2, 0xcb, 0xf3, 0x2b, - 0x1b, 0x8b, 0x56, 0xf6, 0x2e, 0x64, 0x5c, 0xc7, 0x12, 0x54, 0x44, 0x6f, 0x12, 0x5a, 0xda, 0x75, - 0x2c, 0x6d, 0xa6, 0xec, 0x89, 0x37, 0x2f, 0xfb, 0x54, 0xd6, 0x92, 0x6f, 0x21, 0x6b, 0xa9, 0x5b, - 0x59, 0x23, 0x7b, 0x90, 0x12, 0xad, 0xd1, 0x2f, 0xa6, 0x91, 0x55, 0x9b, 0xb3, 0x7e, 0x62, 0x13, - 0xd5, 0x92, 0xd8, 0x34, 0x7d, 0xf2, 0x19, 0xa4, 0x83, 0x56, 0x8d, 0x77, 0x3f, 0xbb, 0x5f, 0x9e, - 0x35, 0x39, 0x92, 0x88, 0x63, 0xd3, 0x67, 0x5a, 0x88, 0x27, 0x9f, 0x42, 0x36, 0xf2, 0x16, 0x62, - 0x27, 0xb8, 0x35, 0xe8, 0x44, 0x79, 0xac, 0xc1, 0xe4, 0x81, 0x24, 0x3f, 0xe5, 0xc5, 0xc1, 0xc9, - 0x25, 0xbb, 0xc8, 0x4a, 0x8c, 0x1b, 0x92, 0xfa, 0x12, 0x3d, 0xf7, 0x25, 0xc9, 0xcd, 0x7f, 0x49, - 0x3c, 0xc8, 0x09, 0x5a, 0xc8, 0xb9, 0x65, 0x2f, 0x3c, 0x52, 0xf9, 0xf6, 0x23, 0xc3, 0xc3, 0xf6, - 0x20, 0x29, 0x43, 0x5b, 0x7e, 0x4d, 0x68, 0x12, 0x57, 0xfd, 0x83, 0x02, 0x70, 0x8c, 0x7d, 0x8d, - 0x97, 0x9c, 0x4f, 0x1c, 0x3e, 0xba, 0xa0, 0x4f, 0x9d, 0x5c, 0x5e, 0x44, 0x60, 0x79, 0x7e, 0xce, - 0x8f, 0xfa, 0x7d, 0x00, 0xf9, 0xc9, 0xc5, 0xf4, 0x69, 0xe0, 0xcc, 0x9c, 0x4d, 0xc2, 0x41, 0xa0, - 0x4d, 0x99, 0x96, 0x3b, 0x8f, 0xac, 0xaa, 0x7f, 0x53, 0x20, 0x83, 0x3e, 0x9d, 0x50, 0x66, 0x4c, - 0xf1, 0x59, 0x79, 0x73, 0x3e, 0xdf, 0x07, 0x10, 0xdb, 0xf8, 0xe6, 0x33, 0x2a, 0x6f, 0x59, 0x06, - 0x25, 0x6d, 0xf3, 0x19, 0x8d, 0xd4, 0x38, 0xf6, 0xbd, 0x6a, 0xbc, 0x09, 0x29, 0x7b, 0x3c, 0xd2, - 0xf9, 0xf3, 0x1f, 0x17, 0x37, 0xd7, 0x1e, 0x8f, 0x3a, 0x17, 0x7e, 0xf5, 0x77, 0x90, 0xea, 0x5c, - 0xe0, 0xd0, 0xcc, 0xaf, 0xab, 0xe7, 0x38, 0x72, 0xfe, 0x12, 0x63, 0x40, 0x9a, 0x0b, 0x70, 0xdc, - 0x20, 0x10, 0xe7, 0x83, 0x96, 0xec, 0x5e, 0xf8, 0x4d, 0x6a, 0xdf, 0x71, 0x1c, 0x0f, 0x06, 0xf1, - 0xff, 0x2a, 0x90, 0x0e, 0x68, 0x4f, 0x0c, 0xd8, 0xec, 0x8f, 0x5d, 0xcb, 0xec, 0x19, 0x8c, 0xea, - 0xe7, 0x0e, 0xa3, 0x7a, 0x78, 0x67, 0x44, 0xfa, 0xde, 0x9f, 0x0d, 0xed, 0x30, 0x30, 0xe0, 0x33, - 0x49, 0xb0, 0x53, 0x63, 0x49, 0xdb, 0xe8, 0xcf, 0x53, 0x10, 0x1b, 0xee, 0x59, 0x9c, 0x38, 0x7a, - 0xcf, 0x32, 0xa9, 0xcd, 0x74, 0x83, 0x31, 0xa3, 0xf7, 0x74, 0x72, 0x8e, 0x28, 0xfa, 0x47, 0xb3, - 0xe7, 0x20, 0xdd, 0x0e, 0xd0, 0xa8, 0x8e, 0x36, 0x91, 0xb3, 0xb6, 0xac, 0x45, 0x4a, 0x35, 0x01, - 0x31, 0x7f, 0x3c, 0xaa, 0xbe, 0x58, 0x86, 0x8d, 0xb9, 0x9e, 0x92, 0x1f, 0x41, 0x12, 0x23, 0x35, - 0x64, 0x88, 0x77, 0xe6, 0xf0, 0xcd, 0x61, 0x54, 0x4b, 0x70, 0x54, 0x3d, 0x84, 0x77, 0xa5, 0xa7, - 0xdf, 0x0a, 0x57, 0xc9, 0x03, 0x20, 0xf8, 0x3f, 0x16, 0xcf, 0xa6, 0x69, 0x0f, 0x74, 0xd7, 0xf9, - 0x52, 0xf2, 0x24, 0xa6, 0x15, 0x50, 0xf3, 0x18, 0x15, 0x2d, 0x2e, 0x9f, 0x9a, 0x96, 0x25, 0x54, - 0x30, 0x63, 0x32, 0xf0, 0x08, 0xe0, 0x54, 0x87, 0x4d, 0xbc, 0x51, 0x87, 0xad, 0xfe, 0x7d, 0x19, - 0xb6, 0x16, 0x26, 0x95, 0x34, 0x61, 0xad, 0xe7, 0xd8, 0x4f, 0x2c, 0xb3, 0x87, 0x7e, 0x23, 0xdb, - 0x65, 0x86, 0xee, 0x2d, 0x28, 0x0e, 0xde, 0x1b, 0xad, 0x10, 0x31, 0x13, 0xdd, 0xe1, 0x5d, 0xc8, - 0xf3, 0xb6, 0xe1, 0xd8, 0xfa, 0xd4, 0x3b, 0x95, 0x13, 0xc2, 0x86, 0x78, 0xad, 0x4e, 0x61, 0xbd, - 0x7b, 0xf9, 0xcc, 0xb0, 0x99, 0x69, 0xd3, 0xc8, 0x3f, 0x01, 0xc5, 0xd8, 0xa2, 0xa1, 0x21, 0x6c, - 0x02, 0xda, 0x3b, 0xa1, 0xe1, 0xe4, 0x3f, 0x84, 0x05, 0x89, 0x8f, 0x2f, 0x48, 0xfc, 0xdb, 0xc8, - 0xe7, 0x31, 0xe4, 0xa2, 0xef, 0x07, 0xf9, 0x79, 0xe4, 0xc5, 0x51, 0x30, 0x8a, 0xd2, 0xe2, 0x17, - 0x47, 0xb6, 0x86, 0xd0, 0xe2, 0xc3, 0x7f, 0x28, 0x90, 0x8d, 0xcc, 0x30, 0xe4, 0xc7, 0xb0, 0xa1, - 0x1e, 0x9f, 0x1d, 0x3c, 0xd2, 0x9b, 0x87, 0xfa, 0xe7, 0xc7, 0xf5, 0x87, 0xfa, 0x17, 0xa7, 0x8f, - 0x4e, 0xcf, 0x7e, 0x75, 0x5a, 0x58, 0x2a, 0xdd, 0xb9, 0xba, 0xae, 0x90, 0x08, 0xf6, 0x0b, 0xfb, - 0xa9, 0xed, 0x7c, 0x69, 0x93, 0x5d, 0x58, 0x9f, 0x36, 0xa9, 0xab, 0xed, 0xa3, 0xd3, 0x4e, 0x41, - 0x29, 0x6d, 0x5c, 0x5d, 0x57, 0xd6, 0x22, 0x16, 0xf5, 0xae, 0x4f, 0x6d, 0x36, 0x6b, 0x70, 0x70, - 0x76, 0x72, 0xd2, 0xec, 0x14, 0x96, 0x67, 0x0c, 0xe4, 0xeb, 0xf6, 0x01, 0xac, 0x4d, 0x1b, 0x9c, - 0x36, 0x8f, 0x0b, 0xb1, 0x12, 0xb9, 0xba, 0xae, 0xac, 0x44, 0xd0, 0xa7, 0xa6, 0x55, 0x4a, 0x3f, - 0xff, 0x63, 0x79, 0xe9, 0xab, 0x3f, 0x95, 0x15, 0x1e, 0x59, 0x7e, 0x6a, 0x8e, 0x21, 0x0f, 0x60, - 0xb3, 0xdd, 0x7c, 0x78, 0x7a, 0x74, 0xa8, 0x9f, 0xb4, 0x1f, 0xea, 0x9d, 0x5f, 0xb7, 0x8e, 0x22, - 0xd1, 0xad, 0x5e, 0x5d, 0x57, 0xb2, 0x32, 0xa4, 0x45, 0xe8, 0x96, 0x76, 0xf4, 0xf8, 0xac, 0x73, - 0x54, 0x50, 0x04, 0xba, 0xe5, 0x51, 0x7e, 0xfb, 0x10, 0xbd, 0x07, 0x5b, 0x73, 0xd0, 0x61, 0x60, - 0x6b, 0x57, 0xd7, 0x95, 0x7c, 0xcb, 0xa3, 0xe2, 0x5d, 0x43, 0x8b, 0x1a, 0x14, 0x67, 0x2d, 0xce, - 0x5a, 0x67, 0xed, 0xfa, 0x71, 0xa1, 0x52, 0x2a, 0x5c, 0x5d, 0x57, 0x72, 0xc1, 0xc0, 0xc6, 0xf1, - 0x93, 0xc8, 0xd4, 0x5f, 0xbe, 0xbc, 0x29, 0x2b, 0x5f, 0xdf, 0x94, 0x95, 0xff, 0xdc, 0x94, 0x95, - 0x17, 0xaf, 0xca, 0x4b, 0x5f, 0xbf, 0x2a, 0x2f, 0xfd, 0xf3, 0x55, 0x79, 0xe9, 0x37, 0x3f, 0x1b, - 0x98, 0x6c, 0x38, 0xee, 0xd6, 0x7a, 0xce, 0x68, 0x37, 0xfa, 0xab, 0xd0, 0xe4, 0x53, 0xfc, 0xfa, - 0x74, 0xfb, 0x17, 0xa3, 0x6e, 0x12, 0xe5, 0x1f, 0xff, 0x3f, 0x00, 0x00, 0xff, 0xff, 0xeb, 0x2d, - 0x75, 0xce, 0xd2, 0x12, 0x00, 0x00, + // 1694 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0x4f, 0x73, 0x1a, 0xc9, + 0x15, 0xd7, 0xc0, 0xf0, 0xef, 0x01, 0x12, 0xea, 0x95, 0x6c, 0x84, 0x6d, 0x44, 0xb1, 0x95, 0xac, + 0xf6, 0x4f, 0x90, 0x22, 0xa7, 0x92, 0x6c, 0x2a, 0x39, 0x00, 0xd2, 0xda, 0x94, 0x25, 0x44, 0x06, + 0xd6, 0xa9, 0xe4, 0x32, 0x35, 0x40, 0x1b, 0x26, 0x1e, 0x66, 0xa6, 0x66, 0x1a, 0x2d, 0xf2, 0x27, + 0x48, 0xe9, 0xe4, 0x53, 0x6e, 0x3a, 0x25, 0x87, 0x7c, 0x8b, 0x4d, 0xe5, 0xb4, 0x97, 0x54, 0xed, + 0x2d, 0xb9, 0x64, 0x93, 0xb2, 0x53, 0xf9, 0x1c, 0xa9, 0x7e, 0xdd, 0x33, 0x0c, 0x02, 0x76, 0x1d, + 0x97, 0x2b, 0x17, 0xd5, 0xf4, 0x7b, 0xbf, 0xd7, 0xfd, 0xfe, 0xfc, 0xfa, 0xf5, 0x13, 0x70, 0x9f, + 0x51, 0x7b, 0x48, 0xbd, 0x89, 0x69, 0xb3, 0x43, 0x76, 0xe5, 0x52, 0x5f, 0xfc, 0xad, 0xb9, 0x9e, + 0xc3, 0x1c, 0x52, 0x98, 0x6b, 0x6b, 0x28, 0x2f, 0xed, 0x8c, 0x9c, 0x91, 0x83, 0xca, 0x43, 0xfe, + 0x25, 0x70, 0xa5, 0xfd, 0x91, 0xe3, 0x8c, 0x2c, 0x7a, 0x88, 0xab, 0xfe, 0xf4, 0xd9, 0x21, 0x33, + 0x27, 0xd4, 0x67, 0xc6, 0xc4, 0x95, 0x80, 0x07, 0x91, 0x63, 0x06, 0xde, 0x95, 0xcb, 0x1c, 0x8e, + 0x75, 0x9e, 0x49, 0x75, 0x65, 0xc9, 0x8b, 0x4b, 0xc3, 0x32, 0x87, 0x06, 0x73, 0x3c, 0x89, 0x28, + 0x47, 0x10, 0x97, 0xd4, 0xf3, 0x4d, 0xc7, 0x8e, 0x7a, 0x5a, 0xfd, 0x14, 0xf2, 0x1d, 0xc3, 0x63, + 0x5d, 0xca, 0x1e, 0x53, 0x63, 0x48, 0x3d, 0xb2, 0x03, 0x09, 0xe6, 0x30, 0xc3, 0x2a, 0x2a, 0x15, + 0xe5, 0x20, 0xaf, 0x89, 0x05, 0x21, 0xa0, 0x8e, 0x0d, 0x7f, 0x5c, 0x8c, 0x55, 0x94, 0x83, 0x9c, + 0x86, 0xdf, 0xd5, 0x31, 0xa8, 0xdc, 0x94, 0x5b, 0x98, 0xf6, 0x90, 0xce, 0x02, 0x0b, 0x5c, 0x70, + 0x69, 0xff, 0x8a, 0x51, 0x5f, 0x9a, 0x88, 0x05, 0xf9, 0x11, 0x24, 0xd0, 0xff, 0x62, 0xbc, 0xa2, + 0x1c, 0x64, 0x8f, 0x8b, 0xb5, 0x48, 0xa2, 0x44, 0x7c, 0xb5, 0x0e, 0xd7, 0x37, 0xd4, 0xaf, 0xbe, + 0xd9, 0xdf, 0xd0, 0x04, 0xb8, 0x6a, 0x41, 0xaa, 0x61, 0x39, 0x83, 0xe7, 0xad, 0x93, 0xd0, 0x11, + 0x65, 0xee, 0x08, 0x39, 0x87, 0x2d, 0xd7, 0xf0, 0x98, 0xee, 0x53, 0xa6, 0x8f, 0x31, 0x0a, 0x3c, + 0x34, 0x7b, 0xbc, 0x5f, 0xbb, 0x5d, 0x87, 0xda, 0x42, 0xb0, 0xf2, 0x94, 0xbc, 0x1b, 0x15, 0x56, + 0xff, 0xa3, 0x42, 0x52, 0x26, 0xe3, 0x17, 0x90, 0x92, 0x49, 0xc3, 0x03, 0xb3, 0xc7, 0x0f, 0xa2, + 0x3b, 0x4a, 0x55, 0xad, 0xe9, 0xd8, 0x3e, 0xb5, 0xfd, 0xa9, 0x2f, 0xf7, 0x0b, 0x6c, 0xc8, 0xf7, + 0x21, 0x3d, 0x18, 0x1b, 0xa6, 0xad, 0x9b, 0x43, 0xf4, 0x28, 0xd3, 0xc8, 0xbe, 0xfa, 0x66, 0x3f, + 0xd5, 0xe4, 0xb2, 0xd6, 0x89, 0x96, 0x42, 0x65, 0x6b, 0x48, 0xee, 0x40, 0x72, 0x4c, 0xcd, 0xd1, + 0x98, 0x61, 0x5a, 0xe2, 0x9a, 0x5c, 0x91, 0x9f, 0x82, 0xca, 0x09, 0x51, 0x54, 0xf1, 0xec, 0x52, + 0x4d, 0xb0, 0xa5, 0x16, 0xb0, 0xa5, 0xd6, 0x0b, 0xd8, 0xd2, 0x48, 0xf3, 0x83, 0x5f, 0xfe, 0x73, + 0x5f, 0xd1, 0xd0, 0x82, 0x34, 0x21, 0x6f, 0x19, 0x3e, 0xd3, 0xfb, 0x3c, 0x6d, 0xfc, 0xf8, 0x04, + 0x6e, 0xb1, 0xb7, 0x9c, 0x10, 0x99, 0x58, 0xe9, 0x7a, 0x96, 0x5b, 0x09, 0xd1, 0x90, 0x1c, 0x40, + 0x01, 0x37, 0x19, 0x38, 0x93, 0x89, 0xc9, 0x74, 0xcc, 0x7b, 0x12, 0xf3, 0xbe, 0xc9, 0xe5, 0x4d, + 0x14, 0x3f, 0xe6, 0x15, 0xb8, 0x07, 0x99, 0xa1, 0xc1, 0x0c, 0x01, 0x49, 0x21, 0x24, 0xcd, 0x05, + 0xa8, 0xfc, 0x00, 0xb6, 0x42, 0x56, 0xfa, 0x02, 0x92, 0x16, 0xbb, 0xcc, 0xc5, 0x08, 0x3c, 0x82, + 0x1d, 0x9b, 0xce, 0x98, 0x7e, 0x1b, 0x9d, 0x41, 0x34, 0xe1, 0xba, 0xa7, 0x8b, 0x16, 0xdf, 0x83, + 0xcd, 0x41, 0x90, 0x7c, 0x81, 0x05, 0xc4, 0xe6, 0x43, 0x29, 0xc2, 0xf6, 0x20, 0x6d, 0xb8, 0xae, + 0x00, 0x64, 0x11, 0x90, 0x32, 0x5c, 0x17, 0x55, 0x1f, 0xc1, 0x36, 0xc6, 0xe8, 0x51, 0x7f, 0x6a, + 0x31, 0xb9, 0x49, 0x0e, 0x31, 0x5b, 0x5c, 0xa1, 0x09, 0x39, 0x62, 0xdf, 0x87, 0x3c, 0xbd, 0x34, + 0x87, 0xd4, 0x1e, 0x50, 0x81, 0xcb, 0x23, 0x2e, 0x17, 0x08, 0x11, 0xf4, 0x21, 0x14, 0x5c, 0xcf, + 0x71, 0x1d, 0x9f, 0x7a, 0xba, 0x31, 0x1c, 0x7a, 0xd4, 0xf7, 0x8b, 0x9b, 0x62, 0xbf, 0x40, 0x5e, + 0x17, 0xe2, 0x6a, 0x11, 0xd4, 0x13, 0x83, 0x19, 0xa4, 0x00, 0x71, 0x36, 0xf3, 0x8b, 0x4a, 0x25, + 0x7e, 0x90, 0xd3, 0xf8, 0x67, 0xb5, 0x0c, 0x89, 0xde, 0xec, 0x09, 0xbd, 0x22, 0xbb, 0x90, 0x64, + 0x33, 0xfd, 0x39, 0xbd, 0x92, 0x84, 0x4f, 0x30, 0x2e, 0xae, 0x7e, 0x19, 0x07, 0xf5, 0xa9, 0xc3, + 0x28, 0x79, 0x08, 0x2a, 0x2f, 0x23, 0x6a, 0x37, 0x57, 0xf1, 0xbd, 0x6b, 0x8e, 0x6c, 0x3a, 0x3c, + 0xf7, 0x47, 0xbd, 0x2b, 0x97, 0x6a, 0x08, 0x8e, 0xd0, 0x2d, 0xb6, 0x40, 0xb7, 0x1d, 0x48, 0x78, + 0xce, 0xd4, 0x1e, 0x22, 0x0b, 0x13, 0x9a, 0x58, 0x90, 0x53, 0x48, 0x87, 0x2c, 0x52, 0xbf, 0x8b, + 0x45, 0x5b, 0x9c, 0x45, 0x9c, 0xe3, 0x52, 0xa0, 0xa5, 0xfa, 0x92, 0x4c, 0x0d, 0xc8, 0x84, 0xcd, + 0x4d, 0xb2, 0xf1, 0xcd, 0x08, 0x3d, 0x37, 0x23, 0x1f, 0xc3, 0x76, 0xc8, 0x8d, 0x30, 0xb9, 0x82, + 0x91, 0x85, 0x50, 0x21, 0xb3, 0xbb, 0x40, 0x3b, 0x5d, 0x34, 0xa8, 0x14, 0xc6, 0x35, 0xa7, 0x5d, + 0x0b, 0x3b, 0xd5, 0x7d, 0xc8, 0xf8, 0xe6, 0xc8, 0x36, 0xd8, 0xd4, 0xa3, 0x92, 0x99, 0x73, 0x01, + 0xa9, 0x40, 0x86, 0xce, 0x18, 0xb5, 0xb1, 0x09, 0x20, 0x13, 0x1b, 0xb1, 0xa2, 0xa2, 0xcd, 0x85, + 0xe4, 0x21, 0xbc, 0x17, 0x2e, 0xf4, 0xf9, 0x4e, 0x10, 0x62, 0x49, 0xa8, 0xee, 0x06, 0xda, 0xea, + 0x9f, 0x15, 0x48, 0x8a, 0x0b, 0x14, 0x29, 0x87, 0xb2, 0xba, 0x1c, 0xb1, 0x75, 0xe5, 0x88, 0xbf, + 0x7d, 0x39, 0xea, 0x00, 0xa1, 0xab, 0x7e, 0x51, 0xad, 0xc4, 0x0f, 0xb2, 0xc7, 0xf7, 0x96, 0x37, + 0x12, 0x2e, 0x76, 0xcd, 0x91, 0xec, 0x0f, 0x11, 0xa3, 0xea, 0x3f, 0x14, 0xc8, 0x84, 0x7a, 0x52, + 0x87, 0x7c, 0xe0, 0x97, 0xfe, 0xcc, 0x32, 0x46, 0x92, 0x92, 0x0f, 0xd6, 0x3a, 0xf7, 0x99, 0x65, + 0x8c, 0xb4, 0xac, 0xf4, 0x87, 0x2f, 0x56, 0x97, 0x37, 0xb6, 0xa6, 0xbc, 0x0b, 0x7c, 0x8a, 0xbf, + 0x1d, 0x9f, 0x16, 0x2a, 0xaf, 0xde, 0xaa, 0x7c, 0xf5, 0x4b, 0x15, 0xd2, 0x1d, 0xbc, 0xb2, 0x86, + 0xf5, 0xff, 0xb8, 0x68, 0xf7, 0x20, 0xe3, 0x3a, 0x96, 0x2e, 0x34, 0x2a, 0x6a, 0xd2, 0xae, 0x63, + 0x69, 0x4b, 0x65, 0x4f, 0xbc, 0xa3, 0x5b, 0x98, 0x7c, 0x07, 0x59, 0x4b, 0xdd, 0xbe, 0x2f, 0x47, + 0x90, 0x12, 0x1d, 0xcb, 0x2f, 0xa6, 0x91, 0x55, 0x77, 0x97, 0xfd, 0xc4, 0xde, 0xa6, 0x25, 0xb1, + 0x97, 0xf9, 0xe4, 0x67, 0x90, 0x0e, 0x3a, 0x28, 0x5e, 0xb0, 0xec, 0x71, 0x79, 0xd9, 0xe4, 0x54, + 0x22, 0xce, 0x4c, 0x9f, 0x69, 0x21, 0x9e, 0x7c, 0x0a, 0xd9, 0xc8, 0x13, 0x85, 0x77, 0xee, 0xd6, + 0x54, 0x11, 0xe5, 0xb1, 0x06, 0xf3, 0x77, 0x8b, 0xfc, 0x98, 0x17, 0x07, 0x87, 0x85, 0xec, 0x3a, + 0xab, 0x85, 0x29, 0x41, 0xa2, 0x57, 0x36, 0xf8, 0xdc, 0xea, 0x06, 0xef, 0x41, 0x4e, 0xd0, 0x42, + 0x8e, 0x13, 0x47, 0xe1, 0x91, 0xca, 0xb7, 0x1f, 0x19, 0x1e, 0x76, 0x04, 0x49, 0x19, 0x5a, 0xec, + 0x3b, 0x42, 0x93, 0xb8, 0xea, 0xef, 0x15, 0x80, 0x33, 0xce, 0x32, 0xac, 0x3d, 0x1f, 0x04, 0x7c, + 0x74, 0x41, 0x5f, 0x38, 0xb9, 0xbc, 0x8e, 0xc0, 0xf2, 0xfc, 0x9c, 0x1f, 0xf5, 0xbb, 0x09, 0xf9, + 0xf9, 0xc5, 0xf4, 0x69, 0xe0, 0xcc, 0x8a, 0x4d, 0xc2, 0xf7, 0xb9, 0x4b, 0x99, 0x96, 0xbb, 0x8c, + 0xac, 0xaa, 0x7f, 0x51, 0x20, 0x83, 0x3e, 0x9d, 0x53, 0x66, 0x2c, 0xf0, 0x59, 0x79, 0x7b, 0x3e, + 0x3f, 0x00, 0x10, 0xdb, 0xf8, 0xe6, 0x0b, 0x2a, 0x6f, 0x59, 0x06, 0x25, 0x5d, 0xf3, 0x05, 0x8d, + 0xd4, 0x38, 0xfe, 0x3f, 0xd5, 0xf8, 0x2e, 0xa4, 0xec, 0xe9, 0x44, 0xe7, 0xaf, 0xb2, 0x2a, 0x6e, + 0xae, 0x3d, 0x9d, 0xf4, 0x66, 0x7e, 0xf5, 0xb7, 0x90, 0xea, 0xcd, 0x70, 0x42, 0xe5, 0xd7, 0xd5, + 0x73, 0x1c, 0x39, 0x16, 0x89, 0xd7, 0x39, 0xcd, 0x05, 0x38, 0x05, 0x10, 0x50, 0xf9, 0xfc, 0x13, + 0xcc, 0xcb, 0xfc, 0x9b, 0xd4, 0xde, 0x70, 0xf6, 0x0d, 0xa6, 0xde, 0x7f, 0x2b, 0x90, 0x0e, 0x68, + 0x4f, 0x0c, 0xb8, 0x3b, 0x9c, 0xba, 0x96, 0x39, 0x30, 0x18, 0xd5, 0x2f, 0x1d, 0x46, 0xf5, 0xf0, + 0xce, 0x88, 0xf4, 0x7d, 0xb0, 0x1c, 0xda, 0x49, 0x60, 0xc0, 0x47, 0x85, 0x60, 0xa7, 0xc7, 0x1b, + 0xda, 0xee, 0x70, 0x95, 0x82, 0xd8, 0x70, 0xdf, 0xe2, 0xc4, 0xd1, 0x07, 0x96, 0x49, 0x6d, 0xa6, + 0x1b, 0x8c, 0x19, 0x83, 0xe7, 0xf3, 0x73, 0x44, 0xd1, 0x3f, 0x5e, 0x3e, 0x07, 0xe9, 0xd6, 0x44, + 0xa3, 0x3a, 0xda, 0x44, 0xce, 0xda, 0xb3, 0xd6, 0x29, 0x1b, 0x09, 0x88, 0xfb, 0xd3, 0x49, 0xf5, + 0x65, 0x0c, 0x76, 0x57, 0x7a, 0x4a, 0x7e, 0x00, 0x49, 0x8c, 0xd4, 0x90, 0x21, 0xde, 0x59, 0xc1, + 0x37, 0x87, 0x51, 0x2d, 0xc1, 0x51, 0xf5, 0x10, 0xde, 0x97, 0x9e, 0x7e, 0x2b, 0xbc, 0x41, 0x3e, + 0x01, 0x82, 0xff, 0xdb, 0xf0, 0x6c, 0x9a, 0xf6, 0x48, 0x77, 0x9d, 0x2f, 0x24, 0x4f, 0xe2, 0x5a, + 0x01, 0x35, 0x4f, 0x51, 0xd1, 0xe1, 0xf2, 0xc5, 0x69, 0x42, 0x40, 0x05, 0x33, 0xe6, 0xd3, 0x84, + 0x00, 0xbe, 0x83, 0x39, 0xa7, 0xfa, 0xd7, 0x18, 0xec, 0xad, 0x4d, 0x2a, 0x69, 0xc1, 0xf6, 0xc0, + 0xb1, 0x9f, 0x59, 0xe6, 0x00, 0xfd, 0x46, 0xb6, 0xcb, 0x0c, 0xdd, 0x5f, 0x53, 0x1c, 0xbc, 0x37, + 0x5a, 0x21, 0x62, 0x26, 0xba, 0xc3, 0xfb, 0x90, 0xe7, 0x6d, 0xc3, 0xb1, 0xf5, 0x85, 0x77, 0x2a, + 0x27, 0x84, 0x8f, 0xc5, 0x6b, 0xd5, 0x86, 0x9d, 0xfe, 0xd5, 0x0b, 0xc3, 0x66, 0xa6, 0x4d, 0x23, + 0xb3, 0x79, 0x31, 0xbe, 0x6e, 0x68, 0x08, 0x9b, 0x80, 0xf6, 0x5e, 0x68, 0x38, 0x1f, 0xdc, 0xd7, + 0x24, 0x5e, 0x5d, 0x93, 0xf8, 0x77, 0x91, 0xcf, 0x33, 0xc8, 0x45, 0xdf, 0x0f, 0xf2, 0xf3, 0xc8, + 0x8b, 0xa3, 0x60, 0x14, 0xa5, 0xf5, 0x2f, 0x8e, 0x6c, 0x0d, 0xa1, 0xc5, 0x47, 0x7f, 0x53, 0x20, + 0x1b, 0x99, 0x61, 0xc8, 0x0f, 0x61, 0xb7, 0x71, 0x76, 0xd1, 0x7c, 0xa2, 0xb7, 0x4e, 0xf4, 0xcf, + 0xce, 0xea, 0x8f, 0xf4, 0xcf, 0xdb, 0x4f, 0xda, 0x17, 0xbf, 0x6a, 0x17, 0x36, 0x4a, 0x77, 0xae, + 0x6f, 0x2a, 0x24, 0x82, 0xfd, 0xdc, 0x7e, 0x6e, 0x3b, 0x5f, 0xd8, 0xe4, 0x10, 0x76, 0x16, 0x4d, + 0xea, 0x8d, 0xee, 0x69, 0xbb, 0x57, 0x50, 0x4a, 0xbb, 0xd7, 0x37, 0x95, 0xed, 0x88, 0x45, 0xbd, + 0xef, 0x53, 0x9b, 0x2d, 0x1b, 0x34, 0x2f, 0xce, 0xcf, 0x5b, 0xbd, 0x42, 0x6c, 0xc9, 0x40, 0xbe, + 0x6e, 0x1f, 0xc2, 0xf6, 0xa2, 0x41, 0xbb, 0x75, 0x56, 0x88, 0x97, 0xc8, 0xf5, 0x4d, 0x65, 0x33, + 0x82, 0x6e, 0x9b, 0x56, 0x29, 0xfd, 0xbb, 0x3f, 0x94, 0x37, 0xfe, 0xf4, 0xc7, 0xb2, 0xc2, 0x23, + 0xcb, 0x2f, 0xcc, 0x31, 0xe4, 0x13, 0xb8, 0xdb, 0x6d, 0x3d, 0x6a, 0x9f, 0x9e, 0xe8, 0xe7, 0xdd, + 0x47, 0x7a, 0xef, 0xd7, 0x9d, 0xd3, 0x48, 0x74, 0x5b, 0xd7, 0x37, 0x95, 0xac, 0x0c, 0x69, 0x1d, + 0xba, 0xa3, 0x9d, 0x3e, 0xbd, 0xe8, 0x9d, 0x16, 0x14, 0x81, 0xee, 0x78, 0x94, 0xdf, 0x3e, 0x44, + 0x1f, 0xc1, 0xde, 0x0a, 0x74, 0x18, 0xd8, 0xf6, 0xf5, 0x4d, 0x25, 0xdf, 0xf1, 0xa8, 0x78, 0xd7, + 0xd0, 0xa2, 0x06, 0xc5, 0x65, 0x8b, 0x8b, 0xce, 0x45, 0xb7, 0x7e, 0x56, 0xa8, 0x94, 0x0a, 0xd7, + 0x37, 0x95, 0x5c, 0x30, 0xb0, 0x71, 0xfc, 0x3c, 0xb2, 0xc6, 0x2f, 0xbf, 0x7a, 0x55, 0x56, 0xbe, + 0x7e, 0x55, 0x56, 0xfe, 0xf5, 0xaa, 0xac, 0xbc, 0x7c, 0x5d, 0xde, 0xf8, 0xfa, 0x75, 0x79, 0xe3, + 0xef, 0xaf, 0xcb, 0x1b, 0xbf, 0xf9, 0xc9, 0xc8, 0x64, 0xe3, 0x69, 0xbf, 0x36, 0x70, 0x26, 0x87, + 0xd1, 0x5f, 0x53, 0xe6, 0x9f, 0xe2, 0x57, 0x9b, 0xdb, 0xbf, 0xb4, 0xf4, 0x93, 0x28, 0x7f, 0xf8, + 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa8, 0xea, 0x99, 0x71, 0x0a, 0x12, 0x00, 0x00, } func (m *PartSetHeader) Marshal() (dAtA []byte, err error) { @@ -1852,55 +1575,21 @@ func (m *PartSetHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.XHash != nil { - { - size := m.XHash.Size() - i -= size - if _, err := m.XHash.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - } - } - if m.XTotal != nil { - { - size := m.XTotal.Size() - i -= size - if _, err := m.XTotal.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - } - } - return len(dAtA) - i, nil -} - -func (m *PartSetHeader_Total) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PartSetHeader_Total) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - i = encodeVarintTypes(dAtA, i, uint64(m.Total)) - i-- - dAtA[i] = 0x8 - return len(dAtA) - i, nil -} -func (m *PartSetHeader_Hash) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PartSetHeader_Hash) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.Hash != nil { + if len(m.Hash) > 0 { i -= len(m.Hash) copy(dAtA[i:], m.Hash) i = encodeVarintTypes(dAtA, i, uint64(len(m.Hash))) i-- dAtA[i] = 0x12 } + if m.Total != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Total)) + i-- + dAtA[i] = 0x8 + } return len(dAtA) - i, nil } + func (m *Part) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1966,35 +1655,17 @@ func (m *BlockID) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.XPartSetHeader != nil { - { - size := m.XPartSetHeader.Size() - i -= size - if _, err := m.XPartSetHeader.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - } - } - if m.XHash != nil { - { - size := m.XHash.Size() - i -= size - if _, err := m.XHash.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } + { + size, err := m.PartSetHeader.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) } - return len(dAtA) - i, nil -} - -func (m *BlockID_Hash) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *BlockID_Hash) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.Hash != nil { + i-- + dAtA[i] = 0x12 + if len(m.Hash) > 0 { i -= len(m.Hash) copy(dAtA[i:], m.Hash) i = encodeVarintTypes(dAtA, i, uint64(len(m.Hash))) @@ -2003,27 +1674,7 @@ func (m *BlockID_Hash) MarshalToSizedBuffer(dAtA []byte) (int, error) { } return len(dAtA) - i, nil } -func (m *BlockID_PartSetHeader) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} -func (m *BlockID_PartSetHeader) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.PartSetHeader != nil { - { - size, err := m.PartSetHeader.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTypes(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - return len(dAtA) - i, nil -} func (m *Header) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2202,253 +1853,105 @@ func (m *TxKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.TxKey) > 0 { - i -= len(m.TxKey) - copy(dAtA[i:], m.TxKey) - i = encodeVarintTypes(dAtA, i, uint64(len(m.TxKey))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *Vote) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Vote) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Vote) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.XExtensionSignature != nil { - { - size := m.XExtensionSignature.Size() - i -= size - if _, err := m.XExtensionSignature.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - } - } - if m.XExtension != nil { - { - size := m.XExtension.Size() - i -= size - if _, err := m.XExtension.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - } - } - if m.XSignature != nil { - { - size := m.XSignature.Size() - i -= size - if _, err := m.XSignature.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - } - } - if m.XValidatorIndex != nil { - { - size := m.XValidatorIndex.Size() - i -= size - if _, err := m.XValidatorIndex.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - } - } - if m.XValidatorAddress != nil { - { - size := m.XValidatorAddress.Size() - i -= size - if _, err := m.XValidatorAddress.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - } - } - if m.XBlockId != nil { - { - size := m.XBlockId.Size() - i -= size - if _, err := m.XBlockId.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - } - } - if m.XRound != nil { - { - size := m.XRound.Size() - i -= size - if _, err := m.XRound.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - } - } - if m.XHeight != nil { - { - size := m.XHeight.Size() - i -= size - if _, err := m.XHeight.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - } - } - if m.XType != nil { - { - size := m.XType.Size() - i -= size - if _, err := m.XType.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - } - } - return len(dAtA) - i, nil -} - -func (m *Vote_Type) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Vote_Type) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - i = encodeVarintTypes(dAtA, i, uint64(m.Type)) - i-- - dAtA[i] = 0x8 - return len(dAtA) - i, nil -} -func (m *Vote_Height) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Vote_Height) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - i = encodeVarintTypes(dAtA, i, uint64(m.Height)) - i-- - dAtA[i] = 0x10 - return len(dAtA) - i, nil -} -func (m *Vote_Round) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Vote_Round) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - i = encodeVarintTypes(dAtA, i, uint64(m.Round)) - i-- - dAtA[i] = 0x18 - return len(dAtA) - i, nil -} -func (m *Vote_BlockId) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Vote_BlockId) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.BlockId != nil { - { - size, err := m.BlockId.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTypes(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } - return len(dAtA) - i, nil -} -func (m *Vote_ValidatorAddress) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Vote_ValidatorAddress) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.ValidatorAddress != nil { - i -= len(m.ValidatorAddress) - copy(dAtA[i:], m.ValidatorAddress) - i = encodeVarintTypes(dAtA, i, uint64(len(m.ValidatorAddress))) - i-- - dAtA[i] = 0x32 - } - return len(dAtA) - i, nil -} -func (m *Vote_ValidatorIndex) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Vote_ValidatorIndex) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - i = encodeVarintTypes(dAtA, i, uint64(m.ValidatorIndex)) - i-- - dAtA[i] = 0x38 - return len(dAtA) - i, nil -} -func (m *Vote_Signature) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Vote_Signature) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.Signature != nil { - i -= len(m.Signature) - copy(dAtA[i:], m.Signature) - i = encodeVarintTypes(dAtA, i, uint64(len(m.Signature))) - i-- - dAtA[i] = 0x42 - } - return len(dAtA) - i, nil -} -func (m *Vote_Extension) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Vote_Extension) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.Extension != nil { - i -= len(m.Extension) - copy(dAtA[i:], m.Extension) - i = encodeVarintTypes(dAtA, i, uint64(len(m.Extension))) + if len(m.TxKey) > 0 { + i -= len(m.TxKey) + copy(dAtA[i:], m.TxKey) + i = encodeVarintTypes(dAtA, i, uint64(len(m.TxKey))) i-- - dAtA[i] = 0x4a + dAtA[i] = 0xa } return len(dAtA) - i, nil } -func (m *Vote_ExtensionSignature) MarshalTo(dAtA []byte) (int, error) { + +func (m *Vote) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Vote) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *Vote_ExtensionSignature) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *Vote) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) - if m.ExtensionSignature != nil { + _ = i + var l int + _ = l + if len(m.ExtensionSignature) > 0 { i -= len(m.ExtensionSignature) copy(dAtA[i:], m.ExtensionSignature) i = encodeVarintTypes(dAtA, i, uint64(len(m.ExtensionSignature))) i-- dAtA[i] = 0x52 } + if len(m.Extension) > 0 { + i -= len(m.Extension) + copy(dAtA[i:], m.Extension) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Extension))) + i-- + dAtA[i] = 0x4a + } + if len(m.Signature) > 0 { + i -= len(m.Signature) + copy(dAtA[i:], m.Signature) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Signature))) + i-- + dAtA[i] = 0x42 + } + if m.ValidatorIndex != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.ValidatorIndex)) + i-- + dAtA[i] = 0x38 + } + if len(m.ValidatorAddress) > 0 { + i -= len(m.ValidatorAddress) + copy(dAtA[i:], m.ValidatorAddress) + i = encodeVarintTypes(dAtA, i, uint64(len(m.ValidatorAddress))) + i-- + dAtA[i] = 0x32 + } + n6, err6 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) + if err6 != nil { + return 0, err6 + } + i -= n6 + i = encodeVarintTypes(dAtA, i, uint64(n6)) + i-- + dAtA[i] = 0x2a + { + size, err := m.BlockID.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + if m.Round != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Round)) + i-- + dAtA[i] = 0x18 + } + if m.Height != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x10 + } + if m.Type != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Type)) + i-- + dAtA[i] = 0x8 + } return len(dAtA) - i, nil } + func (m *Commit) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2533,12 +2036,12 @@ func (m *CommitSig) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x22 } - n8, err8 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) - if err8 != nil { - return 0, err8 + n9, err9 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) + if err9 != nil { + return 0, err9 } - i -= n8 - i = encodeVarintTypes(dAtA, i, uint64(n8)) + i -= n9 + i = encodeVarintTypes(dAtA, i, uint64(n9)) i-- dAtA[i] = 0x1a if len(m.ValidatorAddress) > 0 { @@ -2638,12 +2141,12 @@ func (m *Proposal) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x3a } - n12, err12 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) - if err12 != nil { - return 0, err12 + n13, err13 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) + if err13 != nil { + return 0, err13 } - i -= n12 - i = encodeVarintTypes(dAtA, i, uint64(n12)) + i -= n13 + i = encodeVarintTypes(dAtA, i, uint64(n13)) i-- dAtA[i] = 0x32 { @@ -2969,12 +2472,12 @@ func (m *DuplicateVoteEvidence) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - n23, err23 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) - if err23 != nil { - return 0, err23 + n24, err24 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) + if err24 != nil { + return 0, err24 } - i -= n23 - i = encodeVarintTypes(dAtA, i, uint64(n23)) + i -= n24 + i = encodeVarintTypes(dAtA, i, uint64(n24)) i-- dAtA[i] = 0x2a if m.ValidatorPower != 0 { @@ -3034,12 +2537,12 @@ func (m *LightClientAttackEvidence) MarshalToSizedBuffer(dAtA []byte) (int, erro _ = i var l int _ = l - n26, err26 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) - if err26 != nil { - return 0, err26 + n27, err27 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) + if err27 != nil { + return 0, err27 } - i -= n26 - i = encodeVarintTypes(dAtA, i, uint64(n26)) + i -= n27 + i = encodeVarintTypes(dAtA, i, uint64(n27)) i-- dAtA[i] = 0x2a if m.TotalVotingPower != 0 { @@ -3135,36 +2638,16 @@ func (m *PartSetHeader) Size() (n int) { } var l int _ = l - if m.XTotal != nil { - n += m.XTotal.Size() - } - if m.XHash != nil { - n += m.XHash.Size() - } - return n -} - -func (m *PartSetHeader_Total) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - n += 1 + sovTypes(uint64(m.Total)) - return n -} -func (m *PartSetHeader_Hash) Size() (n int) { - if m == nil { - return 0 + if m.Total != 0 { + n += 1 + sovTypes(uint64(m.Total)) } - var l int - _ = l - if m.Hash != nil { - l = len(m.Hash) + l = len(m.Hash) + if l > 0 { n += 1 + l + sovTypes(uint64(l)) } return n } + func (m *Part) Size() (n int) { if m == nil { return 0 @@ -3189,39 +2672,15 @@ func (m *BlockID) Size() (n int) { } var l int _ = l - if m.XHash != nil { - n += m.XHash.Size() - } - if m.XPartSetHeader != nil { - n += m.XPartSetHeader.Size() - } - return n -} - -func (m *BlockID_Hash) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Hash != nil { - l = len(m.Hash) - n += 1 + l + sovTypes(uint64(l)) - } - return n -} -func (m *BlockID_PartSetHeader) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.PartSetHeader != nil { - l = m.PartSetHeader.Size() + l = len(m.Hash) + if l > 0 { n += 1 + l + sovTypes(uint64(l)) } + l = m.PartSetHeader.Size() + n += 1 + l + sovTypes(uint64(l)) return n } + func (m *Header) Size() (n int) { if m == nil { return 0 @@ -3314,132 +2773,41 @@ func (m *Vote) Size() (n int) { } var l int _ = l - if m.XType != nil { - n += m.XType.Size() - } - if m.XHeight != nil { - n += m.XHeight.Size() - } - if m.XRound != nil { - n += m.XRound.Size() - } - if m.XBlockId != nil { - n += m.XBlockId.Size() - } - if m.XValidatorAddress != nil { - n += m.XValidatorAddress.Size() - } - if m.XValidatorIndex != nil { - n += m.XValidatorIndex.Size() - } - if m.XSignature != nil { - n += m.XSignature.Size() - } - if m.XExtension != nil { - n += m.XExtension.Size() - } - if m.XExtensionSignature != nil { - n += m.XExtensionSignature.Size() - } - return n -} - -func (m *Vote_Type) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - n += 1 + sovTypes(uint64(m.Type)) - return n -} -func (m *Vote_Height) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - n += 1 + sovTypes(uint64(m.Height)) - return n -} -func (m *Vote_Round) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - n += 1 + sovTypes(uint64(m.Round)) - return n -} -func (m *Vote_BlockId) Size() (n int) { - if m == nil { - return 0 + if m.Type != 0 { + n += 1 + sovTypes(uint64(m.Type)) } - var l int - _ = l - if m.BlockId != nil { - l = m.BlockId.Size() - n += 1 + l + sovTypes(uint64(l)) + if m.Height != 0 { + n += 1 + sovTypes(uint64(m.Height)) } - return n -} -func (m *Vote_ValidatorAddress) Size() (n int) { - if m == nil { - return 0 + if m.Round != 0 { + n += 1 + sovTypes(uint64(m.Round)) } - var l int - _ = l - if m.ValidatorAddress != nil { - l = len(m.ValidatorAddress) + l = m.BlockID.Size() + n += 1 + l + sovTypes(uint64(l)) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp) + n += 1 + l + sovTypes(uint64(l)) + l = len(m.ValidatorAddress) + if l > 0 { n += 1 + l + sovTypes(uint64(l)) } - return n -} -func (m *Vote_ValidatorIndex) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - n += 1 + sovTypes(uint64(m.ValidatorIndex)) - return n -} -func (m *Vote_Signature) Size() (n int) { - if m == nil { - return 0 + if m.ValidatorIndex != 0 { + n += 1 + sovTypes(uint64(m.ValidatorIndex)) } - var l int - _ = l - if m.Signature != nil { - l = len(m.Signature) + l = len(m.Signature) + if l > 0 { n += 1 + l + sovTypes(uint64(l)) } - return n -} -func (m *Vote_Extension) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Extension != nil { - l = len(m.Extension) + l = len(m.Extension) + if l > 0 { n += 1 + l + sovTypes(uint64(l)) } - return n -} -func (m *Vote_ExtensionSignature) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.ExtensionSignature != nil { - l = len(m.ExtensionSignature) + l = len(m.ExtensionSignature) + if l > 0 { n += 1 + l + sovTypes(uint64(l)) } return n } + func (m *Commit) Size() (n int) { if m == nil { return 0 @@ -3750,7 +3118,7 @@ func (m *PartSetHeader) Unmarshal(dAtA []byte) error { if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Total", wireType) } - var v uint32 + m.Total = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -3760,12 +3128,11 @@ func (m *PartSetHeader) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= uint32(b&0x7F) << shift + m.Total |= uint32(b&0x7F) << shift if b < 0x80 { break } } - m.XTotal = &PartSetHeader_Total{v} case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) @@ -3795,9 +3162,10 @@ func (m *PartSetHeader) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - v := make([]byte, postIndex-iNdEx) - copy(v, dAtA[iNdEx:postIndex]) - m.XHash = &PartSetHeader_Hash{v} + m.Hash = append(m.Hash[:0], dAtA[iNdEx:postIndex]...) + if m.Hash == nil { + m.Hash = []byte{} + } iNdEx = postIndex default: iNdEx = preIndex @@ -4014,9 +3382,10 @@ func (m *BlockID) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - v := make([]byte, postIndex-iNdEx) - copy(v, dAtA[iNdEx:postIndex]) - m.XHash = &BlockID_Hash{v} + m.Hash = append(m.Hash[:0], dAtA[iNdEx:postIndex]...) + if m.Hash == nil { + m.Hash = []byte{} + } iNdEx = postIndex case 2: if wireType != 2 { @@ -4047,11 +3416,9 @@ func (m *BlockID) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - v := &PartSetHeader{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.PartSetHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - m.XPartSetHeader = &BlockID_PartSetHeader{v} iNdEx = postIndex default: iNdEx = preIndex @@ -4779,7 +4146,7 @@ func (m *Vote) Unmarshal(dAtA []byte) error { if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) } - var v SignedMsgType + m.Type = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -4789,17 +4156,16 @@ func (m *Vote) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= SignedMsgType(b&0x7F) << shift + m.Type |= SignedMsgType(b&0x7F) << shift if b < 0x80 { break } } - m.XType = &Vote_Type{v} case 2: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) } - var v int64 + m.Height = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -4809,17 +4175,16 @@ func (m *Vote) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int64(b&0x7F) << shift + m.Height |= int64(b&0x7F) << shift if b < 0x80 { break } } - m.XHeight = &Vote_Height{v} case 3: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Round", wireType) } - var v int32 + m.Round = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -4829,15 +4194,14 @@ func (m *Vote) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int32(b&0x7F) << shift + m.Round |= int32(b&0x7F) << shift if b < 0x80 { break } } - m.XRound = &Vote_Round{v} case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BlockId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BlockID", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4864,11 +4228,42 @@ func (m *Vote) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - v := &BlockID{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.BlockID.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Timestamp, dAtA[iNdEx:postIndex]); err != nil { return err } - m.XBlockId = &Vote_BlockId{v} iNdEx = postIndex case 6: if wireType != 2 { @@ -4899,15 +4294,16 @@ func (m *Vote) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - v := make([]byte, postIndex-iNdEx) - copy(v, dAtA[iNdEx:postIndex]) - m.XValidatorAddress = &Vote_ValidatorAddress{v} + m.ValidatorAddress = append(m.ValidatorAddress[:0], dAtA[iNdEx:postIndex]...) + if m.ValidatorAddress == nil { + m.ValidatorAddress = []byte{} + } iNdEx = postIndex case 7: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field ValidatorIndex", wireType) } - var v int32 + m.ValidatorIndex = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTypes @@ -4917,12 +4313,11 @@ func (m *Vote) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int32(b&0x7F) << shift + m.ValidatorIndex |= int32(b&0x7F) << shift if b < 0x80 { break } } - m.XValidatorIndex = &Vote_ValidatorIndex{v} case 8: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType) @@ -4952,9 +4347,10 @@ func (m *Vote) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - v := make([]byte, postIndex-iNdEx) - copy(v, dAtA[iNdEx:postIndex]) - m.XSignature = &Vote_Signature{v} + m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...) + if m.Signature == nil { + m.Signature = []byte{} + } iNdEx = postIndex case 9: if wireType != 2 { @@ -4985,9 +4381,10 @@ func (m *Vote) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - v := make([]byte, postIndex-iNdEx) - copy(v, dAtA[iNdEx:postIndex]) - m.XExtension = &Vote_Extension{v} + m.Extension = append(m.Extension[:0], dAtA[iNdEx:postIndex]...) + if m.Extension == nil { + m.Extension = []byte{} + } iNdEx = postIndex case 10: if wireType != 2 { @@ -5018,9 +4415,10 @@ func (m *Vote) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - v := make([]byte, postIndex-iNdEx) - copy(v, dAtA[iNdEx:postIndex]) - m.XExtensionSignature = &Vote_ExtensionSignature{v} + m.ExtensionSignature = append(m.ExtensionSignature[:0], dAtA[iNdEx:postIndex]...) + if m.ExtensionSignature == nil { + m.ExtensionSignature = []byte{} + } iNdEx = postIndex default: iNdEx = preIndex diff --git a/sei-tendermint/proto/tendermint/types/types.proto b/sei-tendermint/proto/tendermint/types/types.proto index d35db41203..33d4c6007f 100644 --- a/sei-tendermint/proto/tendermint/types/types.proto +++ b/sei-tendermint/proto/tendermint/types/types.proto @@ -7,7 +7,6 @@ import "google/protobuf/timestamp.proto"; import "tendermint/crypto/proof.proto"; import "tendermint/types/validator.proto"; import "tendermint/version/types.proto"; -import "hashable.proto"; option go_package = "github.com/tendermint/tendermint/proto/tendermint/types"; @@ -38,9 +37,8 @@ enum SignedMsgType { // PartsetHeader message PartSetHeader { - option (hashable.hashable) = true; - optional uint32 total = 1; - optional bytes hash = 2; + uint32 total = 1; + bytes hash = 2; } message Part { @@ -51,9 +49,8 @@ message Part { // BlockID message BlockID { - option (hashable.hashable) = true; - optional bytes hash = 1; - optional PartSetHeader part_set_header = 2; + bytes hash = 1; + PartSetHeader part_set_header = 2 [(gogoproto.nullable) = false]; } // -------------------------------- @@ -103,19 +100,25 @@ message TxKey { // Vote represents a prevote, precommit, or commit vote from validators for // consensus. message Vote { - option (hashable.hashable) = true; - optional SignedMsgType type = 1; - optional int64 height = 2; - optional int32 round = 3; - optional BlockID block_id = 4; - optional bytes validator_address = 6; - optional int32 validator_index = 7; + SignedMsgType type = 1; + int64 height = 2; + int32 round = 3; + BlockID block_id = 4 [ + (gogoproto.nullable) = false, + (gogoproto.customname) = "BlockID" + ]; // zero if vote is nil. + google.protobuf.Timestamp timestamp = 5 [ + (gogoproto.nullable) = false, + (gogoproto.stdtime) = true + ]; + bytes validator_address = 6; + int32 validator_index = 7; // Vote signature by the validator if they participated in consensus for the // associated block. - optional bytes signature = 8; + bytes signature = 8; - optional bytes extension = 9 [deprecated = true]; - optional bytes extension_signature = 10 [deprecated = true]; + bytes extension = 9 [deprecated = true]; + bytes extension_signature = 10 [deprecated = true]; } // Commit contains the evidence that a block was committed by a set of From 510c3b9567063d3f58948f90d0d4eb7afb5cddd6 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Fri, 12 Dec 2025 16:16:04 +0100 Subject: [PATCH 08/53] fix and test --- sei-tendermint/libs/utils/proto/canonical.go | 75 +++++--- .../libs/utils/proto/canonical_test.go | 182 ++++++++++++++++++ sei-tendermint/proto_v2/test/test.proto | 37 +++- 3 files changed, 261 insertions(+), 33 deletions(-) create mode 100644 sei-tendermint/libs/utils/proto/canonical_test.go diff --git a/sei-tendermint/libs/utils/proto/canonical.go b/sei-tendermint/libs/utils/proto/canonical.go index edb94154cc..ec1119e6f0 100644 --- a/sei-tendermint/libs/utils/proto/canonical.go +++ b/sei-tendermint/libs/utils/proto/canonical.go @@ -1,12 +1,12 @@ package proto import ( + "cmp" "fmt" "slices" - "cmp" - "google.golang.org/protobuf/proto" "google.golang.org/protobuf/encoding/protowire" + "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" ) @@ -24,18 +24,20 @@ func MarshalCanonical[T Hashable](msg T) []byte { type builder []byte -func (b builder) Tag(num protowire.Number, typ protowire.Type) builder { return protowire.AppendTag(b,num,typ) } -func (b builder) Varint(v uint64) builder { return protowire.AppendVarint(b, v) } -func (b builder) Fixed32(v uint32) builder { return protowire.AppendFixed32(b, v) } -func (b builder) Fixed64(v uint64) builder { return protowire.AppendFixed64(b, v) } -func (b builder) Bytes(bytes []byte) builder { return protowire.AppendBytes(b,bytes) } -func (b builder) String(s string) builder { return protowire.AppendString(b,s) } +func (b builder) Tag(num protowire.Number, typ protowire.Type) builder { + return protowire.AppendTag(b, num, typ) +} +func (b builder) Varint(v uint64) builder { return protowire.AppendVarint(b, v) } +func (b builder) Fixed32(v uint32) builder { return protowire.AppendFixed32(b, v) } +func (b builder) Fixed64(v uint64) builder { return protowire.AppendFixed64(b, v) } +func (b builder) Bytes(bytes []byte) builder { return protowire.AppendBytes(b, bytes) } +func (b builder) String(s string) builder { return protowire.AppendString(b, s) } -func (b builder) Message(msg protoreflect.Message) builder { +func (b builder) Message(msg protoreflect.Message) builder { // NOTE: we ignore unknown fields - we are unable to encode them canonically. // NOTE: we can sort fields on init if needed (in the generated files). for _, fd := range sortedFields(msg.Descriptor().Fields()) { - if fd.IsList() { + if fd.IsList() { b = b.List(fd.Number(), fd.Kind(), msg.Get(fd).List()) } else if msg.Has(fd) { b = b.Singular(fd.Number(), fd.Kind(), msg.Get(fd)) @@ -49,7 +51,7 @@ func (b builder) List(num protoreflect.FieldNumber, kind protoreflect.Kind, list if size == 0 { return b } - // We pack only lists longer than 1 for backward compatibility of optional -> repeated changes. + // We pack only lists longer than 1 for backward compatibility of optional -> repeated changes. if isPackable(kind) && size > 1 { var packed builder for i := range list.Len() { @@ -75,7 +77,7 @@ func (b builder) Singular(num protoreflect.FieldNumber, kind protoreflect.Kind, protoreflect.Uint32Kind, protoreflect.Uint64Kind: b = b.Tag(num, protowire.VarintType) - case protoreflect.Fixed32Kind, protoreflect.Sfixed32Kind: + case protoreflect.Fixed32Kind, protoreflect.Sfixed32Kind: b = b.Tag(num, protowire.Fixed32Type) case protoreflect.Fixed64Kind, protoreflect.Sfixed64Kind: b = b.Tag(num, protowire.Fixed64Type) @@ -95,21 +97,36 @@ func (b builder) Value(kind protoreflect.Kind, value protoreflect.Value) builder v = 1 } return b.Varint(v) - case protoreflect.EnumKind: return b.Varint(uint64(value.Enum())) - case protoreflect.Int32Kind: return b.Varint(uint64(uint32(value.Int()))) - case protoreflect.Int64Kind: return b.Varint(uint64(value.Int())) - case protoreflect.Sint32Kind: return b.Varint(protowire.EncodeZigZag(int64(int32(value.Int())))) - case protoreflect.Sint64Kind: return b.Varint(protowire.EncodeZigZag(value.Int())) - case protoreflect.Uint32Kind: return b.Varint(uint64(uint32(value.Uint()))) - case protoreflect.Uint64Kind: return b.Varint(value.Uint()) - case protoreflect.Fixed32Kind: return b.Fixed32(uint32(value.Uint())) - case protoreflect.Fixed64Kind: return b.Fixed64(value.Uint()) - case protoreflect.Sfixed32Kind: return b.Fixed32(uint32(int32(value.Int()))) - case protoreflect.Sfixed64Kind: return b.Fixed64(uint64(value.Int())) - case protoreflect.BytesKind: return b.Bytes(value.Bytes()) - case protoreflect.StringKind: return b.String(value.String()) - case protoreflect.MessageKind: return b.Message(value.Message()) - default: panic(fmt.Errorf("kind %s is not packable", kind)) + case protoreflect.EnumKind: + return b.Varint(uint64(value.Enum())) + case protoreflect.Int32Kind: + return b.Varint(uint64(uint32(value.Int()))) + case protoreflect.Int64Kind: + return b.Varint(uint64(value.Int())) + case protoreflect.Sint32Kind: + return b.Varint(protowire.EncodeZigZag(int64(int32(value.Int())))) + case protoreflect.Sint64Kind: + return b.Varint(protowire.EncodeZigZag(value.Int())) + case protoreflect.Uint32Kind: + return b.Varint(uint64(uint32(value.Uint()))) + case protoreflect.Uint64Kind: + return b.Varint(value.Uint()) + case protoreflect.Fixed32Kind: + return b.Fixed32(uint32(value.Uint())) + case protoreflect.Fixed64Kind: + return b.Fixed64(value.Uint()) + case protoreflect.Sfixed32Kind: + return b.Fixed32(uint32(int32(value.Int()))) + case protoreflect.Sfixed64Kind: + return b.Fixed64(uint64(value.Int())) + case protoreflect.BytesKind: + return b.Bytes(value.Bytes()) + case protoreflect.StringKind: + return b.String(value.String()) + case protoreflect.MessageKind: + return b.Bytes(builder{}.Message(value.Message())) + default: + panic(fmt.Errorf("kind %s is not packable", kind)) } } @@ -138,8 +155,8 @@ func sortedFields(fields protoreflect.FieldDescriptors) []protoreflect.FieldDesc for i := 0; i < fields.Len(); i++ { result[i] = fields.Get(i) } - slices.SortFunc(result,func(a,b protoreflect.FieldDescriptor) int { - return cmp.Compare(a.Number(),b.Number()) + slices.SortFunc(result, func(a, b protoreflect.FieldDescriptor) int { + return cmp.Compare(a.Number(), b.Number()) }) return result } diff --git a/sei-tendermint/libs/utils/proto/canonical_test.go b/sei-tendermint/libs/utils/proto/canonical_test.go new file mode 100644 index 0000000000..4315312823 --- /dev/null +++ b/sei-tendermint/libs/utils/proto/canonical_test.go @@ -0,0 +1,182 @@ +package proto + +import ( + "crypto/sha256" + "encoding/hex" + "fmt" + "math/rand" + "testing" + + stdproto "google.golang.org/protobuf/proto" + + "github.com/stretchr/testify/require" + + "github.com/tendermint/tendermint/libs/utils" + testpb "github.com/tendermint/tendermint/proto_v2/test" +) + +func TestMarshalCanonicalRoundTrip(t *testing.T) { + testCases := []struct { + name string + seed int64 + wantHash string + }{ + {name: "Seed0", seed: 101, wantHash: "ec16b6f1660dafb9afc9d49bc60f3798729495541dbbec8d6e508873945e8b9e"}, + {name: "Seed1", seed: 202, wantHash: "445bfc4d0e8234bda1bb9235c5953adc9eb5854b9f33ac793eddfb5e19690c4d"}, + {name: "Seed2", seed: 303, wantHash: "ba93fb2883451328cd88f1f695b5d6d3c29e3d11281c534f7a162c96eac80437"}, + {name: "Seed3", seed: 404, wantHash: "41a1af29fdbc352dc3e74c34a92f6052db5a3d95395eb95bdb4a2fc584d56ea4"}, + {name: "Seed4", seed: 505, wantHash: "006a588ad882c03507f9c9a50911b3ddd49f091a772bd280fc372f9679fba1cd"}, + {name: "Seed5", seed: 606, wantHash: "dbaf9ad50c0a227af6067a86ef6dcb704cff08f7e96dd4f15554c1ea2b769f89"}, + {name: "Seed6", seed: 707, wantHash: "003689d064ca46f46cb1ad709321c124e2b6f0bd8f311e16d3ca175ae8fa1e70"}, + {name: "Seed7", seed: 808, wantHash: "2ee310817f095f168cdccb1ebd3c8cea3b119c59db73159e6293c8b5ec8e39ac"}, + {name: "Seed8", seed: 909, wantHash: "0f09c55353603a270f128036efadd6748a5e267025f8501be2b9b374b4a8f02a"}, + {name: "Seed9", seed: 1010, wantHash: "87e328d813903d83d4838578f9653072aee3aa17542fb949804e272b9a466f49"}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + msg := newAllKindsFromSeed(tc.seed) + canonical := MarshalCanonical(msg) + var decoded testpb.AllKinds + require.NoError(t, stdproto.Unmarshal(canonical, &decoded)) + require.NoError(t, utils.TestDiff(msg, &decoded)) + + gotHash := sha256.Sum256(canonical) + require.Equal(t, tc.wantHash, hex.EncodeToString(gotHash[:])) + }) + } +} + +func newAllKindsFromSeed(seed int64) *testpb.AllKinds { + rng := rand.New(rand.NewSource(seed)) + msg := &testpb.AllKinds{} + + if rng.Intn(2) == 0 { + msg.BoolValue = utils.Alloc(rng.Intn(2) == 0) + } + if rng.Intn(2) == 0 { + msg.EnumValue = utils.Alloc(testpb.SampleEnum(rng.Intn(3))) + } + if rng.Intn(2) == 0 { + msg.Int32Value = utils.Alloc(int32(rng.Int63n(1 << 31))) + } + if rng.Intn(2) == 0 { + msg.Int64Value = utils.Alloc(rng.Int63()) + } + if rng.Intn(2) == 0 { + msg.Sint32Value = utils.Alloc(int32(rng.Intn(1<<15)) - 1<<14) + } + if rng.Intn(2) == 0 { + msg.Sint64Value = utils.Alloc(rng.Int63n(1<<40) - 1<<39) + } + if rng.Intn(2) == 0 { + msg.Uint32Value = utils.Alloc(uint32(rng.Uint32())) + } + if rng.Intn(2) == 0 { + msg.Uint64Value = utils.Alloc(rng.Uint64()) + } + if rng.Intn(2) == 0 { + msg.Fixed32Value = utils.Alloc(uint32(rng.Uint32())) + } + if rng.Intn(2) == 0 { + msg.Fixed64Value = utils.Alloc(rng.Uint64()) + } + if rng.Intn(2) == 0 { + msg.Sfixed32Value = utils.Alloc(int32(rng.Int63n(1 << 31))) + } + if rng.Intn(2) == 0 { + msg.Sfixed64Value = utils.Alloc(int64(rng.Int63())) + } + if rng.Intn(2) == 0 { + msg.BytesValue = randomBytes(rng, 8+int(rng.Int31n(8))) + } + if rng.Intn(2) == 0 { + msg.StringValue = utils.Alloc(randomString(rng, "string")) + } + if rng.Intn(2) == 0 { + msg.MessageValue = randomNested(rng) + } + if rng.Intn(2) == 0 { + msg.RepeatedPackable = randomInt64Slice(rng, 2+rng.Intn(3)) + } + if rng.Intn(2) == 0 { + msg.RepeatedString = randomStringSlice(rng, 1+rng.Intn(3)) + } + if rng.Intn(2) == 0 { + msg.RepeatedMessage = randomNestedSlice(rng, 1+rng.Intn(3)) + } + if rng.Intn(2) == 0 { + msg.OptionalMessage = randomNested(rng) + } + if rng.Intn(2) == 0 { + msg.RepeatedPackableSingleton = []uint32{uint32(rng.Uint32())} + } + if rng.Intn(2) == 0 { + msg.RepeatedBytes = randomBytesSlice(rng, 1+rng.Intn(3)) + } + // repeated_packable_empty intentionally left nil or empty to ensure we also exercise omitted fields. + if rng.Intn(2) == 0 { + msg.RepeatedPackableEmpty = make([]uint64, 0) + } + + return msg +} + +func randomString(rng *rand.Rand, label string) string { + return fmt.Sprintf("%s-%d", label, rng.Int()) +} + +func randomBytes(rng *rand.Rand, n int) []byte { + b := make([]byte, n) + _, _ = rng.Read(b) + return b +} + +func randomInt64Slice(rng *rand.Rand, n int) []int64 { + if n <= 1 { + n = 2 + } + out := make([]int64, n) + for i := range out { + out[i] = rng.Int63n(1<<20) - 1<<19 + } + return out +} + +func randomStringSlice(rng *rand.Rand, n int) []string { + out := make([]string, n) + for i := range out { + out[i] = randomString(rng, fmt.Sprintf("rep-str-%d", i)) + } + return out +} + +func randomBytesSlice(rng *rand.Rand, n int) [][]byte { + out := make([][]byte, n) + for i := range out { + out[i] = randomBytes(rng, 4+int(rng.Int31n(4))) + } + return out +} + +func randomNestedSlice(rng *rand.Rand, n int) []*testpb.Nested { + out := make([]*testpb.Nested, n) + for i := range out { + out[i] = randomNested(rng) + } + return out +} + +func randomNested(rng *rand.Rand) *testpb.Nested { + nested := &testpb.Nested{} + if rng.Intn(2) == 0 { + nested.Note = utils.Alloc(randomString(rng, "nested")) + } + if rng.Intn(2) == 0 { + nested.Value = utils.Alloc(uint32(rng.Uint32())) + } + if nested.Note == nil && nested.Value == nil { + nested.Note = utils.Alloc(randomString(rng, "fallback")) + } + return nested +} diff --git a/sei-tendermint/proto_v2/test/test.proto b/sei-tendermint/proto_v2/test/test.proto index 02e78ec444..6d231d7333 100644 --- a/sei-tendermint/proto_v2/test/test.proto +++ b/sei-tendermint/proto_v2/test/test.proto @@ -6,13 +6,42 @@ import "hashable/hashable.proto"; option go_package = "github.com/tendermint/tendermint/proto_v2/test"; -message A { +enum SampleEnum { + SAMPLE_ENUM_UNSPECIFIED = 0; + SAMPLE_ENUM_ALPHA = 1; + SAMPLE_ENUM_BETA = 2; +} + +message Nested { option (hashable.hashable) = true; + optional string note = 1; + optional uint32 value = 2; } -message B { +message AllKinds { option (hashable.hashable) = true; - repeated int32 dupa = 1; - optional A ww = 2; + + optional bool bool_value = 1; + optional SampleEnum enum_value = 2; + optional int32 int32_value = 3; + optional int64 int64_value = 4; + optional sint32 sint32_value = 5; + optional sint64 sint64_value = 6; + optional uint32 uint32_value = 7; + optional uint64 uint64_value = 8; + optional fixed32 fixed32_value = 9; + optional fixed64 fixed64_value = 10; + optional sfixed32 sfixed32_value = 11; + optional sfixed64 sfixed64_value = 12; + optional bytes bytes_value = 13; + optional string string_value = 14; + optional Nested message_value = 15; + repeated sint64 repeated_packable = 16; + repeated string repeated_string = 17; + repeated Nested repeated_message = 18; + optional Nested optional_message = 19; + repeated fixed32 repeated_packable_singleton = 20; + repeated bytes repeated_bytes = 21; + repeated uint64 repeated_packable_empty = 22; } From d1b30ff85737582270d63b7930b0788daf3e9047 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Fri, 12 Dec 2025 16:45:38 +0100 Subject: [PATCH 09/53] test updates --- .../libs/utils/proto/canonical_test.go | 180 ++++++++---------- sei-tendermint/proto_v2/test/test.proto | 7 +- 2 files changed, 81 insertions(+), 106 deletions(-) diff --git a/sei-tendermint/libs/utils/proto/canonical_test.go b/sei-tendermint/libs/utils/proto/canonical_test.go index 4315312823..5a26e2bfac 100644 --- a/sei-tendermint/libs/utils/proto/canonical_test.go +++ b/sei-tendermint/libs/utils/proto/canonical_test.go @@ -7,7 +7,7 @@ import ( "math/rand" "testing" - stdproto "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/proto" "github.com/stretchr/testify/require" @@ -16,29 +16,33 @@ import ( ) func TestMarshalCanonicalRoundTrip(t *testing.T) { + // NOTE: math/rand.New uses the Go stdlib implementation, so hashes might change + // if that implementation ever changes. If that happens, switch to a hardcoded PRNG + // instead of updating hashes blindly. testCases := []struct { name string seed int64 wantHash string }{ - {name: "Seed0", seed: 101, wantHash: "ec16b6f1660dafb9afc9d49bc60f3798729495541dbbec8d6e508873945e8b9e"}, - {name: "Seed1", seed: 202, wantHash: "445bfc4d0e8234bda1bb9235c5953adc9eb5854b9f33ac793eddfb5e19690c4d"}, - {name: "Seed2", seed: 303, wantHash: "ba93fb2883451328cd88f1f695b5d6d3c29e3d11281c534f7a162c96eac80437"}, - {name: "Seed3", seed: 404, wantHash: "41a1af29fdbc352dc3e74c34a92f6052db5a3d95395eb95bdb4a2fc584d56ea4"}, - {name: "Seed4", seed: 505, wantHash: "006a588ad882c03507f9c9a50911b3ddd49f091a772bd280fc372f9679fba1cd"}, - {name: "Seed5", seed: 606, wantHash: "dbaf9ad50c0a227af6067a86ef6dcb704cff08f7e96dd4f15554c1ea2b769f89"}, - {name: "Seed6", seed: 707, wantHash: "003689d064ca46f46cb1ad709321c124e2b6f0bd8f311e16d3ca175ae8fa1e70"}, - {name: "Seed7", seed: 808, wantHash: "2ee310817f095f168cdccb1ebd3c8cea3b119c59db73159e6293c8b5ec8e39ac"}, - {name: "Seed8", seed: 909, wantHash: "0f09c55353603a270f128036efadd6748a5e267025f8501be2b9b374b4a8f02a"}, - {name: "Seed9", seed: 1010, wantHash: "87e328d813903d83d4838578f9653072aee3aa17542fb949804e272b9a466f49"}, + {name: "Seed0", seed: 0x79, wantHash: "18e941dacee4ed1f374c11b7572c08d717ab10f1d87a2996b3028b246aba5577"}, + {name: "Seed1", seed: 0xca, wantHash: "445bfc4d0e8234bda1bb9235c5953adc9eb5854b9f33ac793eddfb5e19690c4d"}, + {name: "Seed2", seed: 0x12f, wantHash: "ba93fb2883451328cd88f1f695b5d6d3c29e3d11281c534f7a162c96eac80437"}, + {name: "Seed3", seed: 0x194, wantHash: "41a1af29fdbc352dc3e74c34a92f6052db5a3d95395eb95bdb4a2fc584d56ea4"}, + {name: "Seed4", seed: 0x1f9, wantHash: "006a588ad882c03507f9c9a50911b3ddd49f091a772bd280fc372f9679fba1cd"}, + {name: "Seed5", seed: 0x25e, wantHash: "dbaf9ad50c0a227af6067a86ef6dcb704cff08f7e96dd4f15554c1ea2b769f89"}, + {name: "Seed6", seed: 0x2c3, wantHash: "003689d064ca46f46cb1ad709321c124e2b6f0bd8f311e16d3ca175ae8fa1e70"}, + {name: "Seed7", seed: 0x328, wantHash: "2ee310817f095f168cdccb1ebd3c8cea3b119c59db73159e6293c8b5ec8e39ac"}, + {name: "Seed8", seed: 0x38d, wantHash: "0f09c55353603a270f128036efadd6748a5e267025f8501be2b9b374b4a8f02a"}, + {name: "Seed9", seed: 0x3f2, wantHash: "87e328d813903d83d4838578f9653072aee3aa17542fb949804e272b9a466f49"}, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - msg := newAllKindsFromSeed(tc.seed) - canonical := MarshalCanonical(msg) + msg := msgFromSeed(tc.seed) + var decoded testpb.AllKinds - require.NoError(t, stdproto.Unmarshal(canonical, &decoded)) + canonical := MarshalCanonical(msg) + require.NoError(t, proto.Unmarshal(canonical, &decoded)) require.NoError(t, utils.TestDiff(msg, &decoded)) gotHash := sha256.Sum256(canonical) @@ -47,136 +51,106 @@ func TestMarshalCanonicalRoundTrip(t *testing.T) { } } -func newAllKindsFromSeed(seed int64) *testpb.AllKinds { - rng := rand.New(rand.NewSource(seed)) +func msgFromSeed(seed int64) *testpb.AllKinds { + r := rand.New(rand.NewSource(seed)) msg := &testpb.AllKinds{} - if rng.Intn(2) == 0 { - msg.BoolValue = utils.Alloc(rng.Intn(2) == 0) + if r.Intn(2) == 0 { + msg.BoolValue = utils.Alloc(r.Intn(2) == 0) } - if rng.Intn(2) == 0 { - msg.EnumValue = utils.Alloc(testpb.SampleEnum(rng.Intn(3))) + if r.Intn(2) == 0 { + msg.EnumValue = utils.Alloc(testpb.SampleEnum(r.Intn(3))) } - if rng.Intn(2) == 0 { - msg.Int32Value = utils.Alloc(int32(rng.Int63n(1 << 31))) + if r.Intn(2) == 0 { + msg.Int32Value = utils.Alloc(int32(r.Int63n(1 << 31))) } - if rng.Intn(2) == 0 { - msg.Int64Value = utils.Alloc(rng.Int63()) + if r.Intn(2) == 0 { + msg.Int64Value = utils.Alloc(r.Int63()) } - if rng.Intn(2) == 0 { - msg.Sint32Value = utils.Alloc(int32(rng.Intn(1<<15)) - 1<<14) + if r.Intn(2) == 0 { + msg.Sint32Value = utils.Alloc(int32(r.Intn(1<<15)) - 1<<14) } - if rng.Intn(2) == 0 { - msg.Sint64Value = utils.Alloc(rng.Int63n(1<<40) - 1<<39) + if r.Intn(2) == 0 { + msg.Sint64Value = utils.Alloc(r.Int63n(1<<40) - 1<<39) } - if rng.Intn(2) == 0 { - msg.Uint32Value = utils.Alloc(uint32(rng.Uint32())) + if r.Intn(2) == 0 { + msg.Uint32Value = utils.Alloc(uint32(r.Uint32())) } - if rng.Intn(2) == 0 { - msg.Uint64Value = utils.Alloc(rng.Uint64()) + if r.Intn(2) == 0 { + msg.Uint64Value = utils.Alloc(r.Uint64()) } - if rng.Intn(2) == 0 { - msg.Fixed32Value = utils.Alloc(uint32(rng.Uint32())) + if r.Intn(2) == 0 { + msg.Fixed32Value = utils.Alloc(uint32(r.Uint32())) } - if rng.Intn(2) == 0 { - msg.Fixed64Value = utils.Alloc(rng.Uint64()) + if r.Intn(2) == 0 { + msg.Fixed64Value = utils.Alloc(r.Uint64()) } - if rng.Intn(2) == 0 { - msg.Sfixed32Value = utils.Alloc(int32(rng.Int63n(1 << 31))) + if r.Intn(2) == 0 { + msg.Sfixed32Value = utils.Alloc(int32(r.Int63n(1 << 31))) } - if rng.Intn(2) == 0 { - msg.Sfixed64Value = utils.Alloc(int64(rng.Int63())) + if r.Intn(2) == 0 { + msg.Sfixed64Value = utils.Alloc(r.Int63()) } - if rng.Intn(2) == 0 { - msg.BytesValue = randomBytes(rng, 8+int(rng.Int31n(8))) + if r.Intn(2) == 0 { + msg.BytesValue = randomBytes(r) } - if rng.Intn(2) == 0 { - msg.StringValue = utils.Alloc(randomString(rng, "string")) + if r.Intn(2) == 0 { + msg.StringValue = utils.Alloc(randomString(r)) } - if rng.Intn(2) == 0 { - msg.MessageValue = randomNested(rng) + if r.Intn(2) == 0 { + msg.MessageValue = randomNested(r) } - if rng.Intn(2) == 0 { - msg.RepeatedPackable = randomInt64Slice(rng, 2+rng.Intn(3)) + if r.Intn(2) == 0 { + msg.RepeatedPackable = randomSlice(r, func(r *rand.Rand) int64 { return r.Int63() }) } - if rng.Intn(2) == 0 { - msg.RepeatedString = randomStringSlice(rng, 1+rng.Intn(3)) + if r.Intn(2) == 0 { + msg.RepeatedString = randomSlice(r, randomString) } - if rng.Intn(2) == 0 { - msg.RepeatedMessage = randomNestedSlice(rng, 1+rng.Intn(3)) + if r.Intn(2) == 0 { + msg.RepeatedMessage = randomSlice(r,randomNested) } - if rng.Intn(2) == 0 { - msg.OptionalMessage = randomNested(rng) + if r.Intn(2) == 0 { + msg.OptionalMessage = randomNested(r) } - if rng.Intn(2) == 0 { - msg.RepeatedPackableSingleton = []uint32{uint32(rng.Uint32())} + if r.Intn(2) == 0 { + msg.RepeatedPackableSingleton = []uint32{uint32(r.Uint32())} } - if rng.Intn(2) == 0 { - msg.RepeatedBytes = randomBytesSlice(rng, 1+rng.Intn(3)) + if r.Intn(2) == 0 { + msg.RepeatedBytes = randomSlice(r, randomBytes) } - // repeated_packable_empty intentionally left nil or empty to ensure we also exercise omitted fields. - if rng.Intn(2) == 0 { + if r.Intn(2) == 0 { msg.RepeatedPackableEmpty = make([]uint64, 0) } return msg } -func randomString(rng *rand.Rand, label string) string { - return fmt.Sprintf("%s-%d", label, rng.Int()) +func randomString(r *rand.Rand) string { + return fmt.Sprintf("hello-%d", r.Int()) } -func randomBytes(rng *rand.Rand, n int) []byte { +func randomBytes(r *rand.Rand) []byte { + n := r.Intn(5)+10 b := make([]byte, n) - _, _ = rng.Read(b) + _, _ = r.Read(b) return b } -func randomInt64Slice(rng *rand.Rand, n int) []int64 { - if n <= 1 { - n = 2 - } - out := make([]int64, n) +func randomSlice[T any](r *rand.Rand, gen func(*rand.Rand) T) []T { + n := r.Intn(5)+3 + out := make([]T, n) for i := range out { - out[i] = rng.Int63n(1<<20) - 1<<19 + out[i] = gen(r) } return out } -func randomStringSlice(rng *rand.Rand, n int) []string { - out := make([]string, n) - for i := range out { - out[i] = randomString(rng, fmt.Sprintf("rep-str-%d", i)) - } - return out -} - -func randomBytesSlice(rng *rand.Rand, n int) [][]byte { - out := make([][]byte, n) - for i := range out { - out[i] = randomBytes(rng, 4+int(rng.Int31n(4))) - } - return out -} - -func randomNestedSlice(rng *rand.Rand, n int) []*testpb.Nested { - out := make([]*testpb.Nested, n) - for i := range out { - out[i] = randomNested(rng) - } - return out -} - -func randomNested(rng *rand.Rand) *testpb.Nested { +func randomNested(r *rand.Rand) *testpb.Nested { nested := &testpb.Nested{} - if rng.Intn(2) == 0 { - nested.Note = utils.Alloc(randomString(rng, "nested")) - } - if rng.Intn(2) == 0 { - nested.Value = utils.Alloc(uint32(rng.Uint32())) - } - if nested.Note == nil && nested.Value == nil { - nested.Note = utils.Alloc(randomString(rng, "fallback")) + switch r.Intn(3) { + case 0: nested.Note = utils.Alloc(randomString(r)) + case 1: nested.Value = utils.Alloc(uint32(r.Uint32())) + case 2: // empty oneof } return nested } diff --git a/sei-tendermint/proto_v2/test/test.proto b/sei-tendermint/proto_v2/test/test.proto index 6d231d7333..650df25c8e 100644 --- a/sei-tendermint/proto_v2/test/test.proto +++ b/sei-tendermint/proto_v2/test/test.proto @@ -14,9 +14,10 @@ enum SampleEnum { message Nested { option (hashable.hashable) = true; - - optional string note = 1; - optional uint32 value = 2; + oneof t { + string note = 1; + uint32 value = 2; + } } message AllKinds { From 9ad06cf1f7c1337eea886b9765358abfcc13c021 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Fri, 12 Dec 2025 17:00:33 +0100 Subject: [PATCH 10/53] everything in place --- .../libs/utils/{proto => }/canonical.go | 19 +- .../libs/utils/{proto => }/canonical_test.go | 67 +-- sei-tendermint/libs/utils/proto.go | 27 - sei-tendermint/libs/utils/testonly.go | 7 - .../proto_v2/hashable/hashable.pb.go | 82 +++ sei-tendermint/proto_v2/test/test.hashable.go | 5 + sei-tendermint/proto_v2/test/test.pb.go | 489 ++++++++++++++++++ 7 files changed, 629 insertions(+), 67 deletions(-) rename sei-tendermint/libs/utils/{proto => }/canonical.go (91%) rename sei-tendermint/libs/utils/{proto => }/canonical_test.go (53%) create mode 100644 sei-tendermint/proto_v2/hashable/hashable.pb.go create mode 100644 sei-tendermint/proto_v2/test/test.hashable.go create mode 100644 sei-tendermint/proto_v2/test/test.pb.go diff --git a/sei-tendermint/libs/utils/proto/canonical.go b/sei-tendermint/libs/utils/canonical.go similarity index 91% rename from sei-tendermint/libs/utils/proto/canonical.go rename to sei-tendermint/libs/utils/canonical.go index ec1119e6f0..7496ca468f 100644 --- a/sei-tendermint/libs/utils/proto/canonical.go +++ b/sei-tendermint/libs/utils/canonical.go @@ -1,9 +1,10 @@ -package proto +package utils import ( "cmp" "fmt" "slices" + "crypto/sha256" "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/proto" @@ -15,6 +16,22 @@ type Hashable interface { IsHashable() } +// Hash is a SHA-256 hash. +type Hash[T Hashable] [sha256.Size]byte + +// ParseHash parses a Hash from bytes. +func ParseHash[T Hashable](raw []byte) (Hash[T], error) { + if got, want := len(raw), sha256.Size; got != want { + return Hash[T]{}, fmt.Errorf("hash size = %v, want %v", got, want) + } + return Hash[T](raw), nil +} + +// ProtoHash hashes a Hashable proto object. +func ProtoHash[T Hashable](a T) Hash[T] { + return sha256.Sum256(MarshalCanonical(a)) +} + // MarshalCanonical returns the canonical protobuf encoding of msg according to // the custom Tendermint hashing/signing rules described in canonical.go. // The output is deterministic and suitable for hashing and signing. diff --git a/sei-tendermint/libs/utils/proto/canonical_test.go b/sei-tendermint/libs/utils/canonical_test.go similarity index 53% rename from sei-tendermint/libs/utils/proto/canonical_test.go rename to sei-tendermint/libs/utils/canonical_test.go index 5a26e2bfac..e020085d53 100644 --- a/sei-tendermint/libs/utils/proto/canonical_test.go +++ b/sei-tendermint/libs/utils/canonical_test.go @@ -1,4 +1,4 @@ -package proto +package utils import ( "crypto/sha256" @@ -11,10 +11,10 @@ import ( "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/libs/utils" testpb "github.com/tendermint/tendermint/proto_v2/test" ) +// Test checking that the canonical encoding is a valid proto encoding and that it is stable. func TestMarshalCanonicalRoundTrip(t *testing.T) { // NOTE: math/rand.New uses the Go stdlib implementation, so hashes might change // if that implementation ever changes. If that happens, switch to a hardcoded PRNG @@ -24,16 +24,16 @@ func TestMarshalCanonicalRoundTrip(t *testing.T) { seed int64 wantHash string }{ - {name: "Seed0", seed: 0x79, wantHash: "18e941dacee4ed1f374c11b7572c08d717ab10f1d87a2996b3028b246aba5577"}, - {name: "Seed1", seed: 0xca, wantHash: "445bfc4d0e8234bda1bb9235c5953adc9eb5854b9f33ac793eddfb5e19690c4d"}, - {name: "Seed2", seed: 0x12f, wantHash: "ba93fb2883451328cd88f1f695b5d6d3c29e3d11281c534f7a162c96eac80437"}, - {name: "Seed3", seed: 0x194, wantHash: "41a1af29fdbc352dc3e74c34a92f6052db5a3d95395eb95bdb4a2fc584d56ea4"}, - {name: "Seed4", seed: 0x1f9, wantHash: "006a588ad882c03507f9c9a50911b3ddd49f091a772bd280fc372f9679fba1cd"}, - {name: "Seed5", seed: 0x25e, wantHash: "dbaf9ad50c0a227af6067a86ef6dcb704cff08f7e96dd4f15554c1ea2b769f89"}, - {name: "Seed6", seed: 0x2c3, wantHash: "003689d064ca46f46cb1ad709321c124e2b6f0bd8f311e16d3ca175ae8fa1e70"}, - {name: "Seed7", seed: 0x328, wantHash: "2ee310817f095f168cdccb1ebd3c8cea3b119c59db73159e6293c8b5ec8e39ac"}, - {name: "Seed8", seed: 0x38d, wantHash: "0f09c55353603a270f128036efadd6748a5e267025f8501be2b9b374b4a8f02a"}, - {name: "Seed9", seed: 0x3f2, wantHash: "87e328d813903d83d4838578f9653072aee3aa17542fb949804e272b9a466f49"}, + {name: "Seed0", seed: 0x79, wantHash: "4787b6b8c6807694bd979b56d1a86c8cbe37f3764fb787f653cfbd82d91ab116"}, + {name: "Seed1", seed: 0xca, wantHash: "41f05a42ac8a1bd3fc5079202e516a93f0464e9d1bdd3a78c8e3d207ef9fa09d"}, + {name: "Seed2", seed: 0x12f, wantHash: "8b003e47c39776e8db30bb6153ada73ee60cffb15091c0facb68f31a20f099a3"}, + {name: "Seed3", seed: 0x194, wantHash: "b5ef94d6af6be1b2bc16fac8fefefad047f488798503bc4997bff63fbc1e6393"}, + {name: "Seed4", seed: 0x1f9, wantHash: "c54b74a5de4883d7dbd8b8bc2be7147c99b62384de8241a880802ce0cf23bf81"}, + {name: "Seed5", seed: 0x25e, wantHash: "ff465e5ecfc3446152f34fb3e48387b9316d49cc66876608c18d34d17bac072d"}, + {name: "Seed6", seed: 0x2c3, wantHash: "bb65b0f1869173abdd618c18e2b91eae2dc1d647cf2d01d6e9ed1c97b90a3b65"}, + {name: "Seed7", seed: 0x328, wantHash: "0ec51f6b630acdd89ffaa016850b88c2f9d278f5a464daa4a8ab95195b6c896d"}, + {name: "Seed8", seed: 0x38d, wantHash: "1c615c400ebddf4846fdfd4cb478f9158faf8aaa52f5871028327e27f8c1dd59"}, + {name: "Seed9", seed: 0x3f2, wantHash: "5a4bbc7725ed37b05c00d45a88a95e8918a97d17cfa86cd1f500fd8b2382a6f6"}, } for _, tc := range testCases { @@ -43,7 +43,7 @@ func TestMarshalCanonicalRoundTrip(t *testing.T) { var decoded testpb.AllKinds canonical := MarshalCanonical(msg) require.NoError(t, proto.Unmarshal(canonical, &decoded)) - require.NoError(t, utils.TestDiff(msg, &decoded)) + require.NoError(t, TestDiff(msg, &decoded)) gotHash := sha256.Sum256(canonical) require.Equal(t, tc.wantHash, hex.EncodeToString(gotHash[:])) @@ -56,46 +56,46 @@ func msgFromSeed(seed int64) *testpb.AllKinds { msg := &testpb.AllKinds{} if r.Intn(2) == 0 { - msg.BoolValue = utils.Alloc(r.Intn(2) == 0) + msg.BoolValue = Alloc(r.Intn(2) == 0) } if r.Intn(2) == 0 { - msg.EnumValue = utils.Alloc(testpb.SampleEnum(r.Intn(3))) + msg.EnumValue = Alloc(testpb.SampleEnum(r.Intn(3))) } if r.Intn(2) == 0 { - msg.Int32Value = utils.Alloc(int32(r.Int63n(1 << 31))) + msg.Int32Value = Alloc(int32(r.Int63n(1 << 31))) } if r.Intn(2) == 0 { - msg.Int64Value = utils.Alloc(r.Int63()) + msg.Int64Value = Alloc(r.Int63()) } if r.Intn(2) == 0 { - msg.Sint32Value = utils.Alloc(int32(r.Intn(1<<15)) - 1<<14) + msg.Sint32Value = Alloc(int32(r.Intn(1<<15)) - 1<<14) } if r.Intn(2) == 0 { - msg.Sint64Value = utils.Alloc(r.Int63n(1<<40) - 1<<39) + msg.Sint64Value = Alloc(r.Int63n(1<<40) - 1<<39) } if r.Intn(2) == 0 { - msg.Uint32Value = utils.Alloc(uint32(r.Uint32())) + msg.Uint32Value = Alloc(uint32(r.Uint32())) } if r.Intn(2) == 0 { - msg.Uint64Value = utils.Alloc(r.Uint64()) + msg.Uint64Value = Alloc(r.Uint64()) } if r.Intn(2) == 0 { - msg.Fixed32Value = utils.Alloc(uint32(r.Uint32())) + msg.Fixed32Value = Alloc(uint32(r.Uint32())) } if r.Intn(2) == 0 { - msg.Fixed64Value = utils.Alloc(r.Uint64()) + msg.Fixed64Value = Alloc(r.Uint64()) } if r.Intn(2) == 0 { - msg.Sfixed32Value = utils.Alloc(int32(r.Int63n(1 << 31))) + msg.Sfixed32Value = Alloc(int32(r.Int63n(1 << 31))) } if r.Intn(2) == 0 { - msg.Sfixed64Value = utils.Alloc(r.Int63()) + msg.Sfixed64Value = Alloc(r.Int63()) } if r.Intn(2) == 0 { msg.BytesValue = randomBytes(r) } if r.Intn(2) == 0 { - msg.StringValue = utils.Alloc(randomString(r)) + msg.StringValue = Alloc(randomString(r)) } if r.Intn(2) == 0 { msg.MessageValue = randomNested(r) @@ -107,7 +107,7 @@ func msgFromSeed(seed int64) *testpb.AllKinds { msg.RepeatedString = randomSlice(r, randomString) } if r.Intn(2) == 0 { - msg.RepeatedMessage = randomSlice(r,randomNested) + msg.RepeatedMessage = randomSlice(r, randomNested) } if r.Intn(2) == 0 { msg.OptionalMessage = randomNested(r) @@ -130,14 +130,14 @@ func randomString(r *rand.Rand) string { } func randomBytes(r *rand.Rand) []byte { - n := r.Intn(5)+10 + n := r.Intn(5) + 10 b := make([]byte, n) _, _ = r.Read(b) return b } func randomSlice[T any](r *rand.Rand, gen func(*rand.Rand) T) []T { - n := r.Intn(5)+3 + n := r.Intn(5) + 3 out := make([]T, n) for i := range out { out[i] = gen(r) @@ -148,9 +148,12 @@ func randomSlice[T any](r *rand.Rand, gen func(*rand.Rand) T) []T { func randomNested(r *rand.Rand) *testpb.Nested { nested := &testpb.Nested{} switch r.Intn(3) { - case 0: nested.Note = utils.Alloc(randomString(r)) - case 1: nested.Value = utils.Alloc(uint32(r.Uint32())) - case 2: // empty oneof + case 0: + nested.T = &testpb.Nested_Note{Note: randomString(r)} + case 1: + nested.T = &testpb.Nested_Value{Value: uint32(r.Uint32())} + default: + // leave oneof unset to test empty case } return nested } diff --git a/sei-tendermint/libs/utils/proto.go b/sei-tendermint/libs/utils/proto.go index b8c158a8ed..bff1474408 100644 --- a/sei-tendermint/libs/utils/proto.go +++ b/sei-tendermint/libs/utils/proto.go @@ -1,7 +1,6 @@ package utils import ( - "crypto/sha256" "errors" "fmt" "sync" @@ -33,22 +32,6 @@ func SafeCast[To Int, From Int](v From) (x To, ok bool) { return } -// Hash is a SHA-256 hash. -type Hash [sha256.Size]byte - -// GetHash computes a hash of the given data. -func GetHash(data []byte) Hash { - return sha256.Sum256(data) -} - -// ParseHash parses a Hash from bytes. -func ParseHash(raw []byte) (Hash, error) { - if got, want := len(raw), sha256.Size; got != want { - return Hash{}, fmt.Errorf("hash size = %v, want %v", got, want) - } - return Hash(raw), nil -} - // ProtoClone clones a proto.Message object. func ProtoClone[T proto.Message](item T) T { return proto.Clone(item).(T) @@ -59,16 +42,6 @@ func ProtoEqual[T proto.Message](a, b T) bool { return proto.Equal(a, b) } -// ProtoHash hashes a proto.Message object. -// TODO(gprusak): make it deterministic. -func ProtoHash(a proto.Message) Hash { - raw, err := proto.Marshal(a) - if err != nil { - panic(err) - } - return sha256.Sum256(raw) -} - // ProtoMessage is comparable proto.Message. type ProtoMessage interface { comparable diff --git a/sei-tendermint/libs/utils/testonly.go b/sei-tendermint/libs/utils/testonly.go index 394e05df53..23a1faa8be 100644 --- a/sei-tendermint/libs/utils/testonly.go +++ b/sei-tendermint/libs/utils/testonly.go @@ -184,13 +184,6 @@ func GenTimestamp(rng Rng) time.Time { return time.Unix(0, rng.Int63()) } -// GenHash generates a random Hash. -func GenHash(rng Rng) Hash { - var h Hash - _, _ = rng.Read(h[:]) - return h -} - // Test tests whether reencoding a value is an identity operation. func (c *ProtoConv[T, P]) Test(want T) error { p := c.Encode(want) diff --git a/sei-tendermint/proto_v2/hashable/hashable.pb.go b/sei-tendermint/proto_v2/hashable/hashable.pb.go new file mode 100644 index 0000000000..f7e0d7495d --- /dev/null +++ b/sei-tendermint/proto_v2/hashable/hashable.pb.go @@ -0,0 +1,82 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.10 +// protoc (unknown) +// source: hashable/hashable.proto + +package hashable + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + descriptorpb "google.golang.org/protobuf/types/descriptorpb" + reflect "reflect" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +var file_hashable_hashable_proto_extTypes = []protoimpl.ExtensionInfo{ + { + ExtendedType: (*descriptorpb.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 414126217, + Name: "hashable.hashable", + Tag: "varint,414126217,opt,name=hashable", + Filename: "hashable/hashable.proto", + }, +} + +// Extension fields to descriptorpb.MessageOptions. +var ( + // optional bool hashable = 414126217; + E_Hashable = &file_hashable_hashable_proto_extTypes[0] +) + +var File_hashable_hashable_proto protoreflect.FileDescriptor + +const file_hashable_hashable_proto_rawDesc = "" + + "\n" + + "\x17hashable/hashable.proto\x12\bhashable\x1a google/protobuf/descriptor.proto:?\n" + + "\bhashable\x12\x1f.google.protobuf.MessageOptions\x18\x89\xa1\xbc\xc5\x01 \x01(\bR\bhashableB4Z2github.com/tendermint/tendermint/proto_v2/hashableb\x06proto3" + +var file_hashable_hashable_proto_goTypes = []any{ + (*descriptorpb.MessageOptions)(nil), // 0: google.protobuf.MessageOptions +} +var file_hashable_hashable_proto_depIdxs = []int32{ + 0, // 0: hashable.hashable:extendee -> google.protobuf.MessageOptions + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 0, // [0:1] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_hashable_hashable_proto_init() } +func file_hashable_hashable_proto_init() { + if File_hashable_hashable_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_hashable_hashable_proto_rawDesc), len(file_hashable_hashable_proto_rawDesc)), + NumEnums: 0, + NumMessages: 0, + NumExtensions: 1, + NumServices: 0, + }, + GoTypes: file_hashable_hashable_proto_goTypes, + DependencyIndexes: file_hashable_hashable_proto_depIdxs, + ExtensionInfos: file_hashable_hashable_proto_extTypes, + }.Build() + File_hashable_hashable_proto = out.File + file_hashable_hashable_proto_goTypes = nil + file_hashable_hashable_proto_depIdxs = nil +} diff --git a/sei-tendermint/proto_v2/test/test.hashable.go b/sei-tendermint/proto_v2/test/test.hashable.go new file mode 100644 index 0000000000..8638c4f0b0 --- /dev/null +++ b/sei-tendermint/proto_v2/test/test.hashable.go @@ -0,0 +1,5 @@ +// Code generated by buf_plugin. DO NOT EDIT. +package test + +func (*Nested) IsHashable() {} +func (*AllKinds) IsHashable() {} diff --git a/sei-tendermint/proto_v2/test/test.pb.go b/sei-tendermint/proto_v2/test/test.pb.go new file mode 100644 index 0000000000..4bce4c2ace --- /dev/null +++ b/sei-tendermint/proto_v2/test/test.pb.go @@ -0,0 +1,489 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.10 +// protoc (unknown) +// source: test/test.proto + +package test + +import ( + _ "github.com/tendermint/tendermint/proto_v2/hashable" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type SampleEnum int32 + +const ( + SampleEnum_SAMPLE_ENUM_UNSPECIFIED SampleEnum = 0 + SampleEnum_SAMPLE_ENUM_ALPHA SampleEnum = 1 + SampleEnum_SAMPLE_ENUM_BETA SampleEnum = 2 +) + +// Enum value maps for SampleEnum. +var ( + SampleEnum_name = map[int32]string{ + 0: "SAMPLE_ENUM_UNSPECIFIED", + 1: "SAMPLE_ENUM_ALPHA", + 2: "SAMPLE_ENUM_BETA", + } + SampleEnum_value = map[string]int32{ + "SAMPLE_ENUM_UNSPECIFIED": 0, + "SAMPLE_ENUM_ALPHA": 1, + "SAMPLE_ENUM_BETA": 2, + } +) + +func (x SampleEnum) Enum() *SampleEnum { + p := new(SampleEnum) + *p = x + return p +} + +func (x SampleEnum) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (SampleEnum) Descriptor() protoreflect.EnumDescriptor { + return file_test_test_proto_enumTypes[0].Descriptor() +} + +func (SampleEnum) Type() protoreflect.EnumType { + return &file_test_test_proto_enumTypes[0] +} + +func (x SampleEnum) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use SampleEnum.Descriptor instead. +func (SampleEnum) EnumDescriptor() ([]byte, []int) { + return file_test_test_proto_rawDescGZIP(), []int{0} +} + +type Nested struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to T: + // + // *Nested_Note + // *Nested_Value + T isNested_T `protobuf_oneof:"t"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Nested) Reset() { + *x = Nested{} + mi := &file_test_test_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Nested) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Nested) ProtoMessage() {} + +func (x *Nested) ProtoReflect() protoreflect.Message { + mi := &file_test_test_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Nested.ProtoReflect.Descriptor instead. +func (*Nested) Descriptor() ([]byte, []int) { + return file_test_test_proto_rawDescGZIP(), []int{0} +} + +func (x *Nested) GetT() isNested_T { + if x != nil { + return x.T + } + return nil +} + +func (x *Nested) GetNote() string { + if x != nil { + if x, ok := x.T.(*Nested_Note); ok { + return x.Note + } + } + return "" +} + +func (x *Nested) GetValue() uint32 { + if x != nil { + if x, ok := x.T.(*Nested_Value); ok { + return x.Value + } + } + return 0 +} + +type isNested_T interface { + isNested_T() +} + +type Nested_Note struct { + Note string `protobuf:"bytes,1,opt,name=note,proto3,oneof"` +} + +type Nested_Value struct { + Value uint32 `protobuf:"varint,2,opt,name=value,proto3,oneof"` +} + +func (*Nested_Note) isNested_T() {} + +func (*Nested_Value) isNested_T() {} + +type AllKinds struct { + state protoimpl.MessageState `protogen:"open.v1"` + BoolValue *bool `protobuf:"varint,1,opt,name=bool_value,json=boolValue,proto3,oneof" json:"bool_value,omitempty"` + EnumValue *SampleEnum `protobuf:"varint,2,opt,name=enum_value,json=enumValue,proto3,enum=test.SampleEnum,oneof" json:"enum_value,omitempty"` + Int32Value *int32 `protobuf:"varint,3,opt,name=int32_value,json=int32Value,proto3,oneof" json:"int32_value,omitempty"` + Int64Value *int64 `protobuf:"varint,4,opt,name=int64_value,json=int64Value,proto3,oneof" json:"int64_value,omitempty"` + Sint32Value *int32 `protobuf:"zigzag32,5,opt,name=sint32_value,json=sint32Value,proto3,oneof" json:"sint32_value,omitempty"` + Sint64Value *int64 `protobuf:"zigzag64,6,opt,name=sint64_value,json=sint64Value,proto3,oneof" json:"sint64_value,omitempty"` + Uint32Value *uint32 `protobuf:"varint,7,opt,name=uint32_value,json=uint32Value,proto3,oneof" json:"uint32_value,omitempty"` + Uint64Value *uint64 `protobuf:"varint,8,opt,name=uint64_value,json=uint64Value,proto3,oneof" json:"uint64_value,omitempty"` + Fixed32Value *uint32 `protobuf:"fixed32,9,opt,name=fixed32_value,json=fixed32Value,proto3,oneof" json:"fixed32_value,omitempty"` + Fixed64Value *uint64 `protobuf:"fixed64,10,opt,name=fixed64_value,json=fixed64Value,proto3,oneof" json:"fixed64_value,omitempty"` + Sfixed32Value *int32 `protobuf:"fixed32,11,opt,name=sfixed32_value,json=sfixed32Value,proto3,oneof" json:"sfixed32_value,omitempty"` + Sfixed64Value *int64 `protobuf:"fixed64,12,opt,name=sfixed64_value,json=sfixed64Value,proto3,oneof" json:"sfixed64_value,omitempty"` + BytesValue []byte `protobuf:"bytes,13,opt,name=bytes_value,json=bytesValue,proto3,oneof" json:"bytes_value,omitempty"` + StringValue *string `protobuf:"bytes,14,opt,name=string_value,json=stringValue,proto3,oneof" json:"string_value,omitempty"` + MessageValue *Nested `protobuf:"bytes,15,opt,name=message_value,json=messageValue,proto3,oneof" json:"message_value,omitempty"` + RepeatedPackable []int64 `protobuf:"zigzag64,16,rep,packed,name=repeated_packable,json=repeatedPackable,proto3" json:"repeated_packable,omitempty"` + RepeatedString []string `protobuf:"bytes,17,rep,name=repeated_string,json=repeatedString,proto3" json:"repeated_string,omitempty"` + RepeatedMessage []*Nested `protobuf:"bytes,18,rep,name=repeated_message,json=repeatedMessage,proto3" json:"repeated_message,omitempty"` + OptionalMessage *Nested `protobuf:"bytes,19,opt,name=optional_message,json=optionalMessage,proto3,oneof" json:"optional_message,omitempty"` + RepeatedPackableSingleton []uint32 `protobuf:"fixed32,20,rep,packed,name=repeated_packable_singleton,json=repeatedPackableSingleton,proto3" json:"repeated_packable_singleton,omitempty"` + RepeatedBytes [][]byte `protobuf:"bytes,21,rep,name=repeated_bytes,json=repeatedBytes,proto3" json:"repeated_bytes,omitempty"` + RepeatedPackableEmpty []uint64 `protobuf:"varint,22,rep,packed,name=repeated_packable_empty,json=repeatedPackableEmpty,proto3" json:"repeated_packable_empty,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AllKinds) Reset() { + *x = AllKinds{} + mi := &file_test_test_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AllKinds) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AllKinds) ProtoMessage() {} + +func (x *AllKinds) ProtoReflect() protoreflect.Message { + mi := &file_test_test_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AllKinds.ProtoReflect.Descriptor instead. +func (*AllKinds) Descriptor() ([]byte, []int) { + return file_test_test_proto_rawDescGZIP(), []int{1} +} + +func (x *AllKinds) GetBoolValue() bool { + if x != nil && x.BoolValue != nil { + return *x.BoolValue + } + return false +} + +func (x *AllKinds) GetEnumValue() SampleEnum { + if x != nil && x.EnumValue != nil { + return *x.EnumValue + } + return SampleEnum_SAMPLE_ENUM_UNSPECIFIED +} + +func (x *AllKinds) GetInt32Value() int32 { + if x != nil && x.Int32Value != nil { + return *x.Int32Value + } + return 0 +} + +func (x *AllKinds) GetInt64Value() int64 { + if x != nil && x.Int64Value != nil { + return *x.Int64Value + } + return 0 +} + +func (x *AllKinds) GetSint32Value() int32 { + if x != nil && x.Sint32Value != nil { + return *x.Sint32Value + } + return 0 +} + +func (x *AllKinds) GetSint64Value() int64 { + if x != nil && x.Sint64Value != nil { + return *x.Sint64Value + } + return 0 +} + +func (x *AllKinds) GetUint32Value() uint32 { + if x != nil && x.Uint32Value != nil { + return *x.Uint32Value + } + return 0 +} + +func (x *AllKinds) GetUint64Value() uint64 { + if x != nil && x.Uint64Value != nil { + return *x.Uint64Value + } + return 0 +} + +func (x *AllKinds) GetFixed32Value() uint32 { + if x != nil && x.Fixed32Value != nil { + return *x.Fixed32Value + } + return 0 +} + +func (x *AllKinds) GetFixed64Value() uint64 { + if x != nil && x.Fixed64Value != nil { + return *x.Fixed64Value + } + return 0 +} + +func (x *AllKinds) GetSfixed32Value() int32 { + if x != nil && x.Sfixed32Value != nil { + return *x.Sfixed32Value + } + return 0 +} + +func (x *AllKinds) GetSfixed64Value() int64 { + if x != nil && x.Sfixed64Value != nil { + return *x.Sfixed64Value + } + return 0 +} + +func (x *AllKinds) GetBytesValue() []byte { + if x != nil { + return x.BytesValue + } + return nil +} + +func (x *AllKinds) GetStringValue() string { + if x != nil && x.StringValue != nil { + return *x.StringValue + } + return "" +} + +func (x *AllKinds) GetMessageValue() *Nested { + if x != nil { + return x.MessageValue + } + return nil +} + +func (x *AllKinds) GetRepeatedPackable() []int64 { + if x != nil { + return x.RepeatedPackable + } + return nil +} + +func (x *AllKinds) GetRepeatedString() []string { + if x != nil { + return x.RepeatedString + } + return nil +} + +func (x *AllKinds) GetRepeatedMessage() []*Nested { + if x != nil { + return x.RepeatedMessage + } + return nil +} + +func (x *AllKinds) GetOptionalMessage() *Nested { + if x != nil { + return x.OptionalMessage + } + return nil +} + +func (x *AllKinds) GetRepeatedPackableSingleton() []uint32 { + if x != nil { + return x.RepeatedPackableSingleton + } + return nil +} + +func (x *AllKinds) GetRepeatedBytes() [][]byte { + if x != nil { + return x.RepeatedBytes + } + return nil +} + +func (x *AllKinds) GetRepeatedPackableEmpty() []uint64 { + if x != nil { + return x.RepeatedPackableEmpty + } + return nil +} + +var File_test_test_proto protoreflect.FileDescriptor + +const file_test_test_proto_rawDesc = "" + + "\n" + + "\x0ftest/test.proto\x12\x04test\x1a\x17hashable/hashable.proto\"C\n" + + "\x06Nested\x12\x14\n" + + "\x04note\x18\x01 \x01(\tH\x00R\x04note\x12\x16\n" + + "\x05value\x18\x02 \x01(\rH\x00R\x05value:\x06Ȉ\xe2\xab\f\x01B\x03\n" + + "\x01t\"\x8a\n" + + "\n" + + "\bAllKinds\x12\"\n" + + "\n" + + "bool_value\x18\x01 \x01(\bH\x00R\tboolValue\x88\x01\x01\x124\n" + + "\n" + + "enum_value\x18\x02 \x01(\x0e2\x10.test.SampleEnumH\x01R\tenumValue\x88\x01\x01\x12$\n" + + "\vint32_value\x18\x03 \x01(\x05H\x02R\n" + + "int32Value\x88\x01\x01\x12$\n" + + "\vint64_value\x18\x04 \x01(\x03H\x03R\n" + + "int64Value\x88\x01\x01\x12&\n" + + "\fsint32_value\x18\x05 \x01(\x11H\x04R\vsint32Value\x88\x01\x01\x12&\n" + + "\fsint64_value\x18\x06 \x01(\x12H\x05R\vsint64Value\x88\x01\x01\x12&\n" + + "\fuint32_value\x18\a \x01(\rH\x06R\vuint32Value\x88\x01\x01\x12&\n" + + "\fuint64_value\x18\b \x01(\x04H\aR\vuint64Value\x88\x01\x01\x12(\n" + + "\rfixed32_value\x18\t \x01(\aH\bR\ffixed32Value\x88\x01\x01\x12(\n" + + "\rfixed64_value\x18\n" + + " \x01(\x06H\tR\ffixed64Value\x88\x01\x01\x12*\n" + + "\x0esfixed32_value\x18\v \x01(\x0fH\n" + + "R\rsfixed32Value\x88\x01\x01\x12*\n" + + "\x0esfixed64_value\x18\f \x01(\x10H\vR\rsfixed64Value\x88\x01\x01\x12$\n" + + "\vbytes_value\x18\r \x01(\fH\fR\n" + + "bytesValue\x88\x01\x01\x12&\n" + + "\fstring_value\x18\x0e \x01(\tH\rR\vstringValue\x88\x01\x01\x126\n" + + "\rmessage_value\x18\x0f \x01(\v2\f.test.NestedH\x0eR\fmessageValue\x88\x01\x01\x12+\n" + + "\x11repeated_packable\x18\x10 \x03(\x12R\x10repeatedPackable\x12'\n" + + "\x0frepeated_string\x18\x11 \x03(\tR\x0erepeatedString\x127\n" + + "\x10repeated_message\x18\x12 \x03(\v2\f.test.NestedR\x0frepeatedMessage\x12<\n" + + "\x10optional_message\x18\x13 \x01(\v2\f.test.NestedH\x0fR\x0foptionalMessage\x88\x01\x01\x12>\n" + + "\x1brepeated_packable_singleton\x18\x14 \x03(\aR\x19repeatedPackableSingleton\x12%\n" + + "\x0erepeated_bytes\x18\x15 \x03(\fR\rrepeatedBytes\x126\n" + + "\x17repeated_packable_empty\x18\x16 \x03(\x04R\x15repeatedPackableEmpty:\x06Ȉ\xe2\xab\f\x01B\r\n" + + "\v_bool_valueB\r\n" + + "\v_enum_valueB\x0e\n" + + "\f_int32_valueB\x0e\n" + + "\f_int64_valueB\x0f\n" + + "\r_sint32_valueB\x0f\n" + + "\r_sint64_valueB\x0f\n" + + "\r_uint32_valueB\x0f\n" + + "\r_uint64_valueB\x10\n" + + "\x0e_fixed32_valueB\x10\n" + + "\x0e_fixed64_valueB\x11\n" + + "\x0f_sfixed32_valueB\x11\n" + + "\x0f_sfixed64_valueB\x0e\n" + + "\f_bytes_valueB\x0f\n" + + "\r_string_valueB\x10\n" + + "\x0e_message_valueB\x13\n" + + "\x11_optional_message*V\n" + + "\n" + + "SampleEnum\x12\x1b\n" + + "\x17SAMPLE_ENUM_UNSPECIFIED\x10\x00\x12\x15\n" + + "\x11SAMPLE_ENUM_ALPHA\x10\x01\x12\x14\n" + + "\x10SAMPLE_ENUM_BETA\x10\x02B0Z.github.com/tendermint/tendermint/proto_v2/testb\x06proto3" + +var ( + file_test_test_proto_rawDescOnce sync.Once + file_test_test_proto_rawDescData []byte +) + +func file_test_test_proto_rawDescGZIP() []byte { + file_test_test_proto_rawDescOnce.Do(func() { + file_test_test_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_test_test_proto_rawDesc), len(file_test_test_proto_rawDesc))) + }) + return file_test_test_proto_rawDescData +} + +var file_test_test_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_test_test_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_test_test_proto_goTypes = []any{ + (SampleEnum)(0), // 0: test.SampleEnum + (*Nested)(nil), // 1: test.Nested + (*AllKinds)(nil), // 2: test.AllKinds +} +var file_test_test_proto_depIdxs = []int32{ + 0, // 0: test.AllKinds.enum_value:type_name -> test.SampleEnum + 1, // 1: test.AllKinds.message_value:type_name -> test.Nested + 1, // 2: test.AllKinds.repeated_message:type_name -> test.Nested + 1, // 3: test.AllKinds.optional_message:type_name -> test.Nested + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_test_test_proto_init() } +func file_test_test_proto_init() { + if File_test_test_proto != nil { + return + } + file_test_test_proto_msgTypes[0].OneofWrappers = []any{ + (*Nested_Note)(nil), + (*Nested_Value)(nil), + } + file_test_test_proto_msgTypes[1].OneofWrappers = []any{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_test_test_proto_rawDesc), len(file_test_test_proto_rawDesc)), + NumEnums: 1, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_test_test_proto_goTypes, + DependencyIndexes: file_test_test_proto_depIdxs, + EnumInfos: file_test_test_proto_enumTypes, + MessageInfos: file_test_test_proto_msgTypes, + }.Build() + File_test_test_proto = out.File + file_test_test_proto_goTypes = nil + file_test_test_proto_depIdxs = nil +} From 117563cb97f83c344604ea4639e89c9e3eafa031 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Fri, 12 Dec 2025 17:01:01 +0100 Subject: [PATCH 11/53] go fmt --- sei-tendermint/cmd/buf_plugin/main.go | 26 +++++++++++++-------- sei-tendermint/libs/utils/canonical.go | 4 ++-- sei-tendermint/libs/utils/canonical_test.go | 2 +- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/sei-tendermint/cmd/buf_plugin/main.go b/sei-tendermint/cmd/buf_plugin/main.go index e74f08cf90..3674d5eae1 100644 --- a/sei-tendermint/cmd/buf_plugin/main.go +++ b/sei-tendermint/cmd/buf_plugin/main.go @@ -129,20 +129,26 @@ func run(p *protogen.Plugin) error { return nil } -type pm struct { *protogen.Message } +type pm struct{ *protogen.Message } func (m pm) walk(yield func(pm) bool) bool { - if !yield(m) { return false } - for _,x := range m.Messages { - if !(pm{x}).walk(yield) { return false } + if !yield(m) { + return false + } + for _, x := range m.Messages { + if !(pm{x}).walk(yield) { + return false + } } return true } func allPMs(f *protogen.File) iter.Seq[pm] { return func(yield func(pm) bool) { - for _,m := range f.Messages { - if !(pm{m}).walk(yield) { return } + for _, m := range f.Messages { + if !(pm{m}).walk(yield) { + return + } } } } @@ -154,20 +160,20 @@ func generateHashableFiles(p *protogen.Plugin, descs mds) { } var targets []*protogen.Message for m := range allPMs(file) { - if _,ok := descs[m.Desc.FullName()]; ok { - targets = append(targets,m.Message) + if _, ok := descs[m.Desc.FullName()]; ok { + targets = append(targets, m.Message) } } if len(targets) == 0 { continue } - genPath := strings.TrimSuffix(file.Desc.Path(), ".proto")+".hashable.go" + genPath := strings.TrimSuffix(file.Desc.Path(), ".proto") + ".hashable.go" g := p.NewGeneratedFile(genPath, file.GoImportPath) g.P("// Code generated by buf_plugin. DO NOT EDIT.") g.P("package ", file.GoPackageName) g.P() for _, m := range targets { - g.P("func (*",m.GoIdent,") IsHashable() {}") + g.P("func (*", m.GoIdent, ") IsHashable() {}") } } } diff --git a/sei-tendermint/libs/utils/canonical.go b/sei-tendermint/libs/utils/canonical.go index 7496ca468f..8927a7bb1b 100644 --- a/sei-tendermint/libs/utils/canonical.go +++ b/sei-tendermint/libs/utils/canonical.go @@ -1,10 +1,10 @@ -package utils +package utils import ( "cmp" + "crypto/sha256" "fmt" "slices" - "crypto/sha256" "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/proto" diff --git a/sei-tendermint/libs/utils/canonical_test.go b/sei-tendermint/libs/utils/canonical_test.go index e020085d53..09875b0d6e 100644 --- a/sei-tendermint/libs/utils/canonical_test.go +++ b/sei-tendermint/libs/utils/canonical_test.go @@ -1,4 +1,4 @@ -package utils +package utils import ( "crypto/sha256" From 4c7826ab3abd3bc3473bf90d19e3c1f0a7b3473b Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Fri, 12 Dec 2025 17:18:26 +0100 Subject: [PATCH 12/53] changed location of the plugin --- buf.gen_v2.yaml | 2 +- .../{cmd/buf_plugin => proto_plugins/hashable}/main.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename sei-tendermint/{cmd/buf_plugin => proto_plugins/hashable}/main.go (98%) diff --git a/buf.gen_v2.yaml b/buf.gen_v2.yaml index 7d22d5772f..92c690a4a0 100644 --- a/buf.gen_v2.yaml +++ b/buf.gen_v2.yaml @@ -8,6 +8,6 @@ plugins: - local: - go - run - - ./sei-tendermint/cmd/buf_plugin + - ./sei-tendermint/proto_plugins/hashable strategy: all out: ./sei-tendermint/proto_v2 diff --git a/sei-tendermint/cmd/buf_plugin/main.go b/sei-tendermint/proto_plugins/hashable/main.go similarity index 98% rename from sei-tendermint/cmd/buf_plugin/main.go rename to sei-tendermint/proto_plugins/hashable/main.go index 3674d5eae1..43b1bda6bb 100644 --- a/sei-tendermint/cmd/buf_plugin/main.go +++ b/sei-tendermint/proto_plugins/hashable/main.go @@ -93,7 +93,7 @@ func run(p *protogen.Plugin) error { descs[d.FullName()] = d } } - log.Printf("buf_plugin: found hashable option; %d message type(s) marked with it", len(descs)) + log.Printf("found hashable option; %d message type(s) marked with it", len(descs)) if len(descs) == 0 { return nil } From 118d5665ad63897b64c445df5aede6dce5e5a8d4 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Fri, 12 Dec 2025 17:22:48 +0100 Subject: [PATCH 13/53] nits --- sei-tendermint/libs/utils/canonical.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sei-tendermint/libs/utils/canonical.go b/sei-tendermint/libs/utils/canonical.go index 8927a7bb1b..db9c06aba8 100644 --- a/sei-tendermint/libs/utils/canonical.go +++ b/sei-tendermint/libs/utils/canonical.go @@ -64,12 +64,11 @@ func (b builder) Message(msg protoreflect.Message) builder { } func (b builder) List(num protoreflect.FieldNumber, kind protoreflect.Kind, list protoreflect.List) builder { - size := list.Len() - if size == 0 { + if list.Len() == 0 { return b } // We pack only lists longer than 1 for backward compatibility of optional -> repeated changes. - if isPackable(kind) && size > 1 { + if isPackable(kind) && list.Len() > 1 { var packed builder for i := range list.Len() { packed = packed.Value(kind, list.Get(i)) @@ -77,7 +76,7 @@ func (b builder) List(num protoreflect.FieldNumber, kind protoreflect.Kind, list return b.Tag(num, protowire.BytesType).Bytes(packed) } - for i := range size { + for i := range list.Len() { b = b.Singular(num, kind, list.Get(i)) } return b @@ -169,7 +168,7 @@ func isPackable(kind protoreflect.Kind) bool { func sortedFields(fields protoreflect.FieldDescriptors) []protoreflect.FieldDescriptor { result := make([]protoreflect.FieldDescriptor, fields.Len()) - for i := 0; i < fields.Len(); i++ { + for i := range fields.Len() { result[i] = fields.Get(i) } slices.SortFunc(result, func(a, b protoreflect.FieldDescriptor) int { From 0189653419dd37fcd807a5ba1481e1028a601302 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Fri, 12 Dec 2025 17:27:27 +0100 Subject: [PATCH 14/53] panic msg --- sei-tendermint/libs/utils/canonical.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sei-tendermint/libs/utils/canonical.go b/sei-tendermint/libs/utils/canonical.go index db9c06aba8..5cfb047e63 100644 --- a/sei-tendermint/libs/utils/canonical.go +++ b/sei-tendermint/libs/utils/canonical.go @@ -142,7 +142,7 @@ func (b builder) Value(kind protoreflect.Kind, value protoreflect.Value) builder case protoreflect.MessageKind: return b.Bytes(builder{}.Message(value.Message())) default: - panic(fmt.Errorf("kind %s is not packable", kind)) + panic(fmt.Errorf("unsupported kind %s", kind)) } } From c0a0ec5198a0ddb6015c5f04c062324e1cc87dd1 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Mon, 15 Dec 2025 13:02:15 +0100 Subject: [PATCH 15/53] moved all hashable stuff together --- buf.gen_v2.yaml | 13 ---- sei-tendermint/libs/buf.gen.yaml | 14 ++++ sei-tendermint/libs/buf.yaml | 19 +++++ .../canonical.go => hashable/hashable.go} | 2 +- .../hashable/hashable.proto | 2 +- .../hashable_test.go} | 50 ++++++------ .../hashable/hashable_test.proto} | 2 +- .../hashable/pb}/hashable.pb.go | 4 +- .../hashable/pb/hashable_test.hashable.go} | 2 +- .../hashable/pb/hashable_test.pb.go} | 78 +++++++++---------- .../hashable => libs/hashable/plugin}/main.go | 22 ++++-- 11 files changed, 119 insertions(+), 89 deletions(-) delete mode 100644 buf.gen_v2.yaml create mode 100644 sei-tendermint/libs/buf.gen.yaml create mode 100644 sei-tendermint/libs/buf.yaml rename sei-tendermint/libs/{utils/canonical.go => hashable/hashable.go} (99%) rename sei-tendermint/{proto_v2 => libs}/hashable/hashable.proto (83%) rename sei-tendermint/libs/{utils/canonical_test.go => hashable/hashable_test.go} (74%) rename sei-tendermint/{proto_v2/test/test.proto => libs/hashable/hashable_test.proto} (94%) rename sei-tendermint/{proto_v2/hashable => libs/hashable/pb}/hashable.pb.go (95%) rename sei-tendermint/{proto_v2/test/test.hashable.go => libs/hashable/pb/hashable_test.hashable.go} (89%) rename sei-tendermint/{proto_v2/test/test.pb.go => libs/hashable/pb/hashable_test.pb.go} (84%) rename sei-tendermint/{proto_plugins/hashable => libs/hashable/plugin}/main.go (87%) diff --git a/buf.gen_v2.yaml b/buf.gen_v2.yaml deleted file mode 100644 index 92c690a4a0..0000000000 --- a/buf.gen_v2.yaml +++ /dev/null @@ -1,13 +0,0 @@ -version: v2 -inputs: - - directory: sei-tendermint/proto_v2 -plugins: - - remote: buf.build/protocolbuffers/go:v1.36.10 - out: ./sei-tendermint/proto_v2 - opt: [paths=source_relative] - - local: - - go - - run - - ./sei-tendermint/proto_plugins/hashable - strategy: all - out: ./sei-tendermint/proto_v2 diff --git a/sei-tendermint/libs/buf.gen.yaml b/sei-tendermint/libs/buf.gen.yaml new file mode 100644 index 0000000000..f8c52c837e --- /dev/null +++ b/sei-tendermint/libs/buf.gen.yaml @@ -0,0 +1,14 @@ +version: v2 +inputs: + - directory: ./ +plugins: + - remote: buf.build/protocolbuffers/go:v1.36.10 + out: ./ + opt: [module=github.com/tendermint/tendermint/libs] + - local: + - go + - run + - ./hashable/plugin + strategy: all + out: ./ + opt: [module=github.com/tendermint/tendermint/libs] diff --git a/sei-tendermint/libs/buf.yaml b/sei-tendermint/libs/buf.yaml new file mode 100644 index 0000000000..f83d4b1ddd --- /dev/null +++ b/sei-tendermint/libs/buf.yaml @@ -0,0 +1,19 @@ +# For details on buf.yaml configuration, visit https://buf.build/docs/configuration/v2/buf-yaml +version: v2 +modules: + - path: ./ +lint: + use: + - BASIC + - FILE_LOWER_SNAKE_CASE + - UNARY_RPC + except: + - COMMENT_FIELD + - PACKAGE_VERSION_SUFFIX + - PACKAGE_SAME_DIRECTORY + - PACKAGE_DIRECTORY_MATCH + - PACKAGE_SAME_GO_PACKAGE +breaking: + use: + - WIRE + - WIRE_JSON diff --git a/sei-tendermint/libs/utils/canonical.go b/sei-tendermint/libs/hashable/hashable.go similarity index 99% rename from sei-tendermint/libs/utils/canonical.go rename to sei-tendermint/libs/hashable/hashable.go index 5cfb047e63..d6c603c114 100644 --- a/sei-tendermint/libs/utils/canonical.go +++ b/sei-tendermint/libs/hashable/hashable.go @@ -1,4 +1,4 @@ -package utils +package hashable import ( "cmp" diff --git a/sei-tendermint/proto_v2/hashable/hashable.proto b/sei-tendermint/libs/hashable/hashable.proto similarity index 83% rename from sei-tendermint/proto_v2/hashable/hashable.proto rename to sei-tendermint/libs/hashable/hashable.proto index e9440c483a..c3058eb9c3 100644 --- a/sei-tendermint/proto_v2/hashable/hashable.proto +++ b/sei-tendermint/libs/hashable/hashable.proto @@ -4,7 +4,7 @@ package hashable; import "google/protobuf/descriptor.proto"; -option go_package = "github.com/tendermint/tendermint/proto_v2/hashable"; +option go_package = "github.com/tendermint/tendermint/libs/hashable/pb"; // hashable marks messages which support canonical protobuf serialization and therefore // are suitable for hashing. diff --git a/sei-tendermint/libs/utils/canonical_test.go b/sei-tendermint/libs/hashable/hashable_test.go similarity index 74% rename from sei-tendermint/libs/utils/canonical_test.go rename to sei-tendermint/libs/hashable/hashable_test.go index 09875b0d6e..ec2414c38c 100644 --- a/sei-tendermint/libs/utils/canonical_test.go +++ b/sei-tendermint/libs/hashable/hashable_test.go @@ -1,4 +1,4 @@ -package utils +package hashable import ( "crypto/sha256" @@ -9,9 +9,9 @@ import ( "google.golang.org/protobuf/proto" - "github.com/stretchr/testify/require" - - testpb "github.com/tendermint/tendermint/proto_v2/test" + "github.com/tendermint/tendermint/libs/utils" + "github.com/tendermint/tendermint/libs/utils/require" + "github.com/tendermint/tendermint/libs/hashable/pb" ) // Test checking that the canonical encoding is a valid proto encoding and that it is stable. @@ -40,10 +40,10 @@ func TestMarshalCanonicalRoundTrip(t *testing.T) { t.Run(tc.name, func(t *testing.T) { msg := msgFromSeed(tc.seed) - var decoded testpb.AllKinds + var decoded pb.AllKinds canonical := MarshalCanonical(msg) require.NoError(t, proto.Unmarshal(canonical, &decoded)) - require.NoError(t, TestDiff(msg, &decoded)) + require.NoError(t, utils.TestDiff(msg, &decoded)) gotHash := sha256.Sum256(canonical) require.Equal(t, tc.wantHash, hex.EncodeToString(gotHash[:])) @@ -51,51 +51,51 @@ func TestMarshalCanonicalRoundTrip(t *testing.T) { } } -func msgFromSeed(seed int64) *testpb.AllKinds { +func msgFromSeed(seed int64) *pb.AllKinds { r := rand.New(rand.NewSource(seed)) - msg := &testpb.AllKinds{} + msg := &pb.AllKinds{} if r.Intn(2) == 0 { - msg.BoolValue = Alloc(r.Intn(2) == 0) + msg.BoolValue = utils.Alloc(r.Intn(2) == 0) } if r.Intn(2) == 0 { - msg.EnumValue = Alloc(testpb.SampleEnum(r.Intn(3))) + msg.EnumValue = utils.Alloc(pb.SampleEnum(r.Intn(3))) } if r.Intn(2) == 0 { - msg.Int32Value = Alloc(int32(r.Int63n(1 << 31))) + msg.Int32Value = utils.Alloc(int32(r.Int63n(1 << 31))) } if r.Intn(2) == 0 { - msg.Int64Value = Alloc(r.Int63()) + msg.Int64Value = utils.Alloc(r.Int63()) } if r.Intn(2) == 0 { - msg.Sint32Value = Alloc(int32(r.Intn(1<<15)) - 1<<14) + msg.Sint32Value = utils.Alloc(int32(r.Intn(1<<15)) - 1<<14) } if r.Intn(2) == 0 { - msg.Sint64Value = Alloc(r.Int63n(1<<40) - 1<<39) + msg.Sint64Value = utils.Alloc(r.Int63n(1<<40) - 1<<39) } if r.Intn(2) == 0 { - msg.Uint32Value = Alloc(uint32(r.Uint32())) + msg.Uint32Value = utils.Alloc(uint32(r.Uint32())) } if r.Intn(2) == 0 { - msg.Uint64Value = Alloc(r.Uint64()) + msg.Uint64Value = utils.Alloc(r.Uint64()) } if r.Intn(2) == 0 { - msg.Fixed32Value = Alloc(uint32(r.Uint32())) + msg.Fixed32Value = utils.Alloc(uint32(r.Uint32())) } if r.Intn(2) == 0 { - msg.Fixed64Value = Alloc(r.Uint64()) + msg.Fixed64Value = utils.Alloc(r.Uint64()) } if r.Intn(2) == 0 { - msg.Sfixed32Value = Alloc(int32(r.Int63n(1 << 31))) + msg.Sfixed32Value = utils.Alloc(int32(r.Int63n(1 << 31))) } if r.Intn(2) == 0 { - msg.Sfixed64Value = Alloc(r.Int63()) + msg.Sfixed64Value = utils.Alloc(r.Int63()) } if r.Intn(2) == 0 { msg.BytesValue = randomBytes(r) } if r.Intn(2) == 0 { - msg.StringValue = Alloc(randomString(r)) + msg.StringValue = utils.Alloc(randomString(r)) } if r.Intn(2) == 0 { msg.MessageValue = randomNested(r) @@ -145,13 +145,13 @@ func randomSlice[T any](r *rand.Rand, gen func(*rand.Rand) T) []T { return out } -func randomNested(r *rand.Rand) *testpb.Nested { - nested := &testpb.Nested{} +func randomNested(r *rand.Rand) *pb.Nested { + nested := &pb.Nested{} switch r.Intn(3) { case 0: - nested.T = &testpb.Nested_Note{Note: randomString(r)} + nested.T = &pb.Nested_Note{Note: randomString(r)} case 1: - nested.T = &testpb.Nested_Value{Value: uint32(r.Uint32())} + nested.T = &pb.Nested_Value{Value: uint32(r.Uint32())} default: // leave oneof unset to test empty case } diff --git a/sei-tendermint/proto_v2/test/test.proto b/sei-tendermint/libs/hashable/hashable_test.proto similarity index 94% rename from sei-tendermint/proto_v2/test/test.proto rename to sei-tendermint/libs/hashable/hashable_test.proto index 650df25c8e..359dbb76ad 100644 --- a/sei-tendermint/proto_v2/test/test.proto +++ b/sei-tendermint/libs/hashable/hashable_test.proto @@ -4,7 +4,7 @@ package test; import "hashable/hashable.proto"; -option go_package = "github.com/tendermint/tendermint/proto_v2/test"; +option go_package = "github.com/tendermint/tendermint/libs/hashable/pb"; enum SampleEnum { SAMPLE_ENUM_UNSPECIFIED = 0; diff --git a/sei-tendermint/proto_v2/hashable/hashable.pb.go b/sei-tendermint/libs/hashable/pb/hashable.pb.go similarity index 95% rename from sei-tendermint/proto_v2/hashable/hashable.pb.go rename to sei-tendermint/libs/hashable/pb/hashable.pb.go index f7e0d7495d..6c0d6c5b83 100644 --- a/sei-tendermint/proto_v2/hashable/hashable.pb.go +++ b/sei-tendermint/libs/hashable/pb/hashable.pb.go @@ -4,7 +4,7 @@ // protoc (unknown) // source: hashable/hashable.proto -package hashable +package pb import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" @@ -43,7 +43,7 @@ var File_hashable_hashable_proto protoreflect.FileDescriptor const file_hashable_hashable_proto_rawDesc = "" + "\n" + "\x17hashable/hashable.proto\x12\bhashable\x1a google/protobuf/descriptor.proto:?\n" + - "\bhashable\x12\x1f.google.protobuf.MessageOptions\x18\x89\xa1\xbc\xc5\x01 \x01(\bR\bhashableB4Z2github.com/tendermint/tendermint/proto_v2/hashableb\x06proto3" + "\bhashable\x12\x1f.google.protobuf.MessageOptions\x18\x89\xa1\xbc\xc5\x01 \x01(\bR\bhashableB3Z1github.com/tendermint/tendermint/libs/hashable/pbb\x06proto3" var file_hashable_hashable_proto_goTypes = []any{ (*descriptorpb.MessageOptions)(nil), // 0: google.protobuf.MessageOptions diff --git a/sei-tendermint/proto_v2/test/test.hashable.go b/sei-tendermint/libs/hashable/pb/hashable_test.hashable.go similarity index 89% rename from sei-tendermint/proto_v2/test/test.hashable.go rename to sei-tendermint/libs/hashable/pb/hashable_test.hashable.go index 8638c4f0b0..9ac28e5c0a 100644 --- a/sei-tendermint/proto_v2/test/test.hashable.go +++ b/sei-tendermint/libs/hashable/pb/hashable_test.hashable.go @@ -1,5 +1,5 @@ // Code generated by buf_plugin. DO NOT EDIT. -package test +package pb func (*Nested) IsHashable() {} func (*AllKinds) IsHashable() {} diff --git a/sei-tendermint/proto_v2/test/test.pb.go b/sei-tendermint/libs/hashable/pb/hashable_test.pb.go similarity index 84% rename from sei-tendermint/proto_v2/test/test.pb.go rename to sei-tendermint/libs/hashable/pb/hashable_test.pb.go index 4bce4c2ace..5260cfb379 100644 --- a/sei-tendermint/proto_v2/test/test.pb.go +++ b/sei-tendermint/libs/hashable/pb/hashable_test.pb.go @@ -2,12 +2,11 @@ // versions: // protoc-gen-go v1.36.10 // protoc (unknown) -// source: test/test.proto +// source: hashable/hashable_test.proto -package test +package pb import ( - _ "github.com/tendermint/tendermint/proto_v2/hashable" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -55,11 +54,11 @@ func (x SampleEnum) String() string { } func (SampleEnum) Descriptor() protoreflect.EnumDescriptor { - return file_test_test_proto_enumTypes[0].Descriptor() + return file_hashable_hashable_test_proto_enumTypes[0].Descriptor() } func (SampleEnum) Type() protoreflect.EnumType { - return &file_test_test_proto_enumTypes[0] + return &file_hashable_hashable_test_proto_enumTypes[0] } func (x SampleEnum) Number() protoreflect.EnumNumber { @@ -68,7 +67,7 @@ func (x SampleEnum) Number() protoreflect.EnumNumber { // Deprecated: Use SampleEnum.Descriptor instead. func (SampleEnum) EnumDescriptor() ([]byte, []int) { - return file_test_test_proto_rawDescGZIP(), []int{0} + return file_hashable_hashable_test_proto_rawDescGZIP(), []int{0} } type Nested struct { @@ -84,7 +83,7 @@ type Nested struct { func (x *Nested) Reset() { *x = Nested{} - mi := &file_test_test_proto_msgTypes[0] + mi := &file_hashable_hashable_test_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -96,7 +95,7 @@ func (x *Nested) String() string { func (*Nested) ProtoMessage() {} func (x *Nested) ProtoReflect() protoreflect.Message { - mi := &file_test_test_proto_msgTypes[0] + mi := &file_hashable_hashable_test_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -109,7 +108,7 @@ func (x *Nested) ProtoReflect() protoreflect.Message { // Deprecated: Use Nested.ProtoReflect.Descriptor instead. func (*Nested) Descriptor() ([]byte, []int) { - return file_test_test_proto_rawDescGZIP(), []int{0} + return file_hashable_hashable_test_proto_rawDescGZIP(), []int{0} } func (x *Nested) GetT() isNested_T { @@ -183,7 +182,7 @@ type AllKinds struct { func (x *AllKinds) Reset() { *x = AllKinds{} - mi := &file_test_test_proto_msgTypes[1] + mi := &file_hashable_hashable_test_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -195,7 +194,7 @@ func (x *AllKinds) String() string { func (*AllKinds) ProtoMessage() {} func (x *AllKinds) ProtoReflect() protoreflect.Message { - mi := &file_test_test_proto_msgTypes[1] + mi := &file_hashable_hashable_test_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -208,7 +207,7 @@ func (x *AllKinds) ProtoReflect() protoreflect.Message { // Deprecated: Use AllKinds.ProtoReflect.Descriptor instead. func (*AllKinds) Descriptor() ([]byte, []int) { - return file_test_test_proto_rawDescGZIP(), []int{1} + return file_hashable_hashable_test_proto_rawDescGZIP(), []int{1} } func (x *AllKinds) GetBoolValue() bool { @@ -365,11 +364,11 @@ func (x *AllKinds) GetRepeatedPackableEmpty() []uint64 { return nil } -var File_test_test_proto protoreflect.FileDescriptor +var File_hashable_hashable_test_proto protoreflect.FileDescriptor -const file_test_test_proto_rawDesc = "" + +const file_hashable_hashable_test_proto_rawDesc = "" + "\n" + - "\x0ftest/test.proto\x12\x04test\x1a\x17hashable/hashable.proto\"C\n" + + "\x1chashable/hashable_test.proto\x12\x04test\x1a\x17hashable/hashable.proto\"C\n" + "\x06Nested\x12\x14\n" + "\x04note\x18\x01 \x01(\tH\x00R\x04note\x12\x16\n" + "\x05value\x18\x02 \x01(\rH\x00R\x05value:\x06Ȉ\xe2\xab\f\x01B\x03\n" + @@ -425,28 +424,28 @@ const file_test_test_proto_rawDesc = "" + "SampleEnum\x12\x1b\n" + "\x17SAMPLE_ENUM_UNSPECIFIED\x10\x00\x12\x15\n" + "\x11SAMPLE_ENUM_ALPHA\x10\x01\x12\x14\n" + - "\x10SAMPLE_ENUM_BETA\x10\x02B0Z.github.com/tendermint/tendermint/proto_v2/testb\x06proto3" + "\x10SAMPLE_ENUM_BETA\x10\x02B3Z1github.com/tendermint/tendermint/libs/hashable/pbb\x06proto3" var ( - file_test_test_proto_rawDescOnce sync.Once - file_test_test_proto_rawDescData []byte + file_hashable_hashable_test_proto_rawDescOnce sync.Once + file_hashable_hashable_test_proto_rawDescData []byte ) -func file_test_test_proto_rawDescGZIP() []byte { - file_test_test_proto_rawDescOnce.Do(func() { - file_test_test_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_test_test_proto_rawDesc), len(file_test_test_proto_rawDesc))) +func file_hashable_hashable_test_proto_rawDescGZIP() []byte { + file_hashable_hashable_test_proto_rawDescOnce.Do(func() { + file_hashable_hashable_test_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_hashable_hashable_test_proto_rawDesc), len(file_hashable_hashable_test_proto_rawDesc))) }) - return file_test_test_proto_rawDescData + return file_hashable_hashable_test_proto_rawDescData } -var file_test_test_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_test_test_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_test_test_proto_goTypes = []any{ +var file_hashable_hashable_test_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_hashable_hashable_test_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_hashable_hashable_test_proto_goTypes = []any{ (SampleEnum)(0), // 0: test.SampleEnum (*Nested)(nil), // 1: test.Nested (*AllKinds)(nil), // 2: test.AllKinds } -var file_test_test_proto_depIdxs = []int32{ +var file_hashable_hashable_test_proto_depIdxs = []int32{ 0, // 0: test.AllKinds.enum_value:type_name -> test.SampleEnum 1, // 1: test.AllKinds.message_value:type_name -> test.Nested 1, // 2: test.AllKinds.repeated_message:type_name -> test.Nested @@ -458,32 +457,33 @@ var file_test_test_proto_depIdxs = []int32{ 0, // [0:4] is the sub-list for field type_name } -func init() { file_test_test_proto_init() } -func file_test_test_proto_init() { - if File_test_test_proto != nil { +func init() { file_hashable_hashable_test_proto_init() } +func file_hashable_hashable_test_proto_init() { + if File_hashable_hashable_test_proto != nil { return } - file_test_test_proto_msgTypes[0].OneofWrappers = []any{ + file_hashable_hashable_proto_init() + file_hashable_hashable_test_proto_msgTypes[0].OneofWrappers = []any{ (*Nested_Note)(nil), (*Nested_Value)(nil), } - file_test_test_proto_msgTypes[1].OneofWrappers = []any{} + file_hashable_hashable_test_proto_msgTypes[1].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_test_test_proto_rawDesc), len(file_test_test_proto_rawDesc)), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_hashable_hashable_test_proto_rawDesc), len(file_hashable_hashable_test_proto_rawDesc)), NumEnums: 1, NumMessages: 2, NumExtensions: 0, NumServices: 0, }, - GoTypes: file_test_test_proto_goTypes, - DependencyIndexes: file_test_test_proto_depIdxs, - EnumInfos: file_test_test_proto_enumTypes, - MessageInfos: file_test_test_proto_msgTypes, + GoTypes: file_hashable_hashable_test_proto_goTypes, + DependencyIndexes: file_hashable_hashable_test_proto_depIdxs, + EnumInfos: file_hashable_hashable_test_proto_enumTypes, + MessageInfos: file_hashable_hashable_test_proto_msgTypes, }.Build() - File_test_test_proto = out.File - file_test_test_proto_goTypes = nil - file_test_test_proto_depIdxs = nil + File_hashable_hashable_test_proto = out.File + file_hashable_hashable_test_proto_goTypes = nil + file_hashable_hashable_test_proto_depIdxs = nil } diff --git a/sei-tendermint/proto_plugins/hashable/main.go b/sei-tendermint/libs/hashable/plugin/main.go similarity index 87% rename from sei-tendermint/proto_plugins/hashable/main.go rename to sei-tendermint/libs/hashable/plugin/main.go index 43b1bda6bb..e71ea63447 100644 --- a/sei-tendermint/proto_plugins/hashable/main.go +++ b/sei-tendermint/libs/hashable/plugin/main.go @@ -5,7 +5,9 @@ import ( "fmt" "iter" "log" + "flag" "strings" + "path/filepath" "google.golang.org/protobuf/compiler/protogen" "google.golang.org/protobuf/proto" @@ -17,6 +19,10 @@ import ( "google.golang.org/protobuf/types/pluginpb" ) +var flags flag.FlagSet + +var moduleFlag = flags.String("module","","prefix to strip from the absolute generated file path. Same as in protoc-gen-go") + func (d md) GetBoolOption(ext protoreflect.ExtensionTypeDescriptor) bool { options := d.Options().(*descriptorpb.MessageOptions).ProtoReflect() if !options.Has(ext) { @@ -125,8 +131,7 @@ func run(p *protogen.Plugin) error { } } } - generateHashableFiles(p, descs) - return nil + return generateHashableFiles(p, descs) } type pm struct{ *protogen.Message } @@ -153,7 +158,7 @@ func allPMs(f *protogen.File) iter.Seq[pm] { } } -func generateHashableFiles(p *protogen.Plugin, descs mds) { +func generateHashableFiles(p *protogen.Plugin, descs mds) error { for _, file := range p.Files { if !file.Generate { continue @@ -167,8 +172,12 @@ func generateHashableFiles(p *protogen.Plugin, descs mds) { if len(targets) == 0 { continue } - genPath := strings.TrimSuffix(file.Desc.Path(), ".proto") + ".hashable.go" - g := p.NewGeneratedFile(genPath, file.GoImportPath) + genDir,err := filepath.Rel(*moduleFlag,string(file.GoImportPath)) + if err!=nil { + return fmt.Errorf("filepath.Rel(): %w",err) + } + genFileName := strings.TrimSuffix(filepath.Base(file.Desc.Path()), ".proto") + ".hashable.go" + g := p.NewGeneratedFile(filepath.Join(genDir,genFileName), file.GoImportPath) g.P("// Code generated by buf_plugin. DO NOT EDIT.") g.P("package ", file.GoPackageName) g.P() @@ -176,8 +185,9 @@ func generateHashableFiles(p *protogen.Plugin, descs mds) { g.P("func (*", m.GoIdent, ") IsHashable() {}") } } + return nil } func main() { - protogen.Options{}.Run(run) + protogen.Options{ParamFunc:flags.Set}.Run(run) } From 15faaa52a96b035e2a8b371cf8acbda13ab4e381 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Mon, 15 Dec 2025 13:18:42 +0100 Subject: [PATCH 16/53] moved testonly proto to internal --- sei-tendermint/libs/hashable/hashable_test.go | 18 +- .../hashable/internal/pb/testonly.hashable.go | 5 + .../pb/testonly.pb.go} | 279 +++++++++--------- .../testonly.proto} | 22 +- .../hashable/pb/hashable_test.hashable.go | 5 - 5 files changed, 164 insertions(+), 165 deletions(-) create mode 100644 sei-tendermint/libs/hashable/internal/pb/testonly.hashable.go rename sei-tendermint/libs/hashable/{pb/hashable_test.pb.go => internal/pb/testonly.pb.go} (54%) rename sei-tendermint/libs/hashable/{hashable_test.proto => internal/testonly.proto} (73%) delete mode 100644 sei-tendermint/libs/hashable/pb/hashable_test.hashable.go diff --git a/sei-tendermint/libs/hashable/hashable_test.go b/sei-tendermint/libs/hashable/hashable_test.go index ec2414c38c..6219084fe9 100644 --- a/sei-tendermint/libs/hashable/hashable_test.go +++ b/sei-tendermint/libs/hashable/hashable_test.go @@ -11,7 +11,7 @@ import ( "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/libs/utils/require" - "github.com/tendermint/tendermint/libs/hashable/pb" + "github.com/tendermint/tendermint/libs/hashable/internal/pb" ) // Test checking that the canonical encoding is a valid proto encoding and that it is stable. @@ -40,7 +40,7 @@ func TestMarshalCanonicalRoundTrip(t *testing.T) { t.Run(tc.name, func(t *testing.T) { msg := msgFromSeed(tc.seed) - var decoded pb.AllKinds + var decoded pb.TestonlyMsg canonical := MarshalCanonical(msg) require.NoError(t, proto.Unmarshal(canonical, &decoded)) require.NoError(t, utils.TestDiff(msg, &decoded)) @@ -51,15 +51,15 @@ func TestMarshalCanonicalRoundTrip(t *testing.T) { } } -func msgFromSeed(seed int64) *pb.AllKinds { +func msgFromSeed(seed int64) *pb.TestonlyMsg { r := rand.New(rand.NewSource(seed)) - msg := &pb.AllKinds{} + msg := &pb.TestonlyMsg{} if r.Intn(2) == 0 { msg.BoolValue = utils.Alloc(r.Intn(2) == 0) } if r.Intn(2) == 0 { - msg.EnumValue = utils.Alloc(pb.SampleEnum(r.Intn(3))) + msg.EnumValue = utils.Alloc(pb.TestonlyEnum(r.Intn(3))) } if r.Intn(2) == 0 { msg.Int32Value = utils.Alloc(int32(r.Int63n(1 << 31))) @@ -145,13 +145,13 @@ func randomSlice[T any](r *rand.Rand, gen func(*rand.Rand) T) []T { return out } -func randomNested(r *rand.Rand) *pb.Nested { - nested := &pb.Nested{} +func randomNested(r *rand.Rand) *pb.TestonlyNested { + nested := &pb.TestonlyNested{} switch r.Intn(3) { case 0: - nested.T = &pb.Nested_Note{Note: randomString(r)} + nested.T = &pb.TestonlyNested_Note{Note: randomString(r)} case 1: - nested.T = &pb.Nested_Value{Value: uint32(r.Uint32())} + nested.T = &pb.TestonlyNested_Value{Value: uint32(r.Uint32())} default: // leave oneof unset to test empty case } diff --git a/sei-tendermint/libs/hashable/internal/pb/testonly.hashable.go b/sei-tendermint/libs/hashable/internal/pb/testonly.hashable.go new file mode 100644 index 0000000000..da8e144207 --- /dev/null +++ b/sei-tendermint/libs/hashable/internal/pb/testonly.hashable.go @@ -0,0 +1,5 @@ +// Code generated by buf_plugin. DO NOT EDIT. +package pb + +func (*TestonlyNested) IsHashable() {} +func (*TestonlyMsg) IsHashable() {} diff --git a/sei-tendermint/libs/hashable/pb/hashable_test.pb.go b/sei-tendermint/libs/hashable/internal/pb/testonly.pb.go similarity index 54% rename from sei-tendermint/libs/hashable/pb/hashable_test.pb.go rename to sei-tendermint/libs/hashable/internal/pb/testonly.pb.go index 5260cfb379..75b0af83bd 100644 --- a/sei-tendermint/libs/hashable/pb/hashable_test.pb.go +++ b/sei-tendermint/libs/hashable/internal/pb/testonly.pb.go @@ -2,11 +2,12 @@ // versions: // protoc-gen-go v1.36.10 // protoc (unknown) -// source: hashable/hashable_test.proto +// source: hashable/internal/testonly.proto package pb import ( + _ "github.com/tendermint/tendermint/libs/hashable/pb" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -21,81 +22,81 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type SampleEnum int32 +type TestonlyEnum int32 const ( - SampleEnum_SAMPLE_ENUM_UNSPECIFIED SampleEnum = 0 - SampleEnum_SAMPLE_ENUM_ALPHA SampleEnum = 1 - SampleEnum_SAMPLE_ENUM_BETA SampleEnum = 2 + TestonlyEnum_TESTONLY_ENUM_UNSPECIFIED TestonlyEnum = 0 + TestonlyEnum_TESTONLY_ENUM_ALPHA TestonlyEnum = 1 + TestonlyEnum_TESTONLY_ENUM_BETA TestonlyEnum = 2 ) -// Enum value maps for SampleEnum. +// Enum value maps for TestonlyEnum. var ( - SampleEnum_name = map[int32]string{ - 0: "SAMPLE_ENUM_UNSPECIFIED", - 1: "SAMPLE_ENUM_ALPHA", - 2: "SAMPLE_ENUM_BETA", + TestonlyEnum_name = map[int32]string{ + 0: "TESTONLY_ENUM_UNSPECIFIED", + 1: "TESTONLY_ENUM_ALPHA", + 2: "TESTONLY_ENUM_BETA", } - SampleEnum_value = map[string]int32{ - "SAMPLE_ENUM_UNSPECIFIED": 0, - "SAMPLE_ENUM_ALPHA": 1, - "SAMPLE_ENUM_BETA": 2, + TestonlyEnum_value = map[string]int32{ + "TESTONLY_ENUM_UNSPECIFIED": 0, + "TESTONLY_ENUM_ALPHA": 1, + "TESTONLY_ENUM_BETA": 2, } ) -func (x SampleEnum) Enum() *SampleEnum { - p := new(SampleEnum) +func (x TestonlyEnum) Enum() *TestonlyEnum { + p := new(TestonlyEnum) *p = x return p } -func (x SampleEnum) String() string { +func (x TestonlyEnum) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } -func (SampleEnum) Descriptor() protoreflect.EnumDescriptor { - return file_hashable_hashable_test_proto_enumTypes[0].Descriptor() +func (TestonlyEnum) Descriptor() protoreflect.EnumDescriptor { + return file_hashable_internal_testonly_proto_enumTypes[0].Descriptor() } -func (SampleEnum) Type() protoreflect.EnumType { - return &file_hashable_hashable_test_proto_enumTypes[0] +func (TestonlyEnum) Type() protoreflect.EnumType { + return &file_hashable_internal_testonly_proto_enumTypes[0] } -func (x SampleEnum) Number() protoreflect.EnumNumber { +func (x TestonlyEnum) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } -// Deprecated: Use SampleEnum.Descriptor instead. -func (SampleEnum) EnumDescriptor() ([]byte, []int) { - return file_hashable_hashable_test_proto_rawDescGZIP(), []int{0} +// Deprecated: Use TestonlyEnum.Descriptor instead. +func (TestonlyEnum) EnumDescriptor() ([]byte, []int) { + return file_hashable_internal_testonly_proto_rawDescGZIP(), []int{0} } -type Nested struct { +type TestonlyNested struct { state protoimpl.MessageState `protogen:"open.v1"` // Types that are valid to be assigned to T: // - // *Nested_Note - // *Nested_Value - T isNested_T `protobuf_oneof:"t"` + // *TestonlyNested_Note + // *TestonlyNested_Value + T isTestonlyNested_T `protobuf_oneof:"t"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *Nested) Reset() { - *x = Nested{} - mi := &file_hashable_hashable_test_proto_msgTypes[0] +func (x *TestonlyNested) Reset() { + *x = TestonlyNested{} + mi := &file_hashable_internal_testonly_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *Nested) String() string { +func (x *TestonlyNested) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Nested) ProtoMessage() {} +func (*TestonlyNested) ProtoMessage() {} -func (x *Nested) ProtoReflect() protoreflect.Message { - mi := &file_hashable_hashable_test_proto_msgTypes[0] +func (x *TestonlyNested) ProtoReflect() protoreflect.Message { + mi := &file_hashable_internal_testonly_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -106,56 +107,56 @@ func (x *Nested) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Nested.ProtoReflect.Descriptor instead. -func (*Nested) Descriptor() ([]byte, []int) { - return file_hashable_hashable_test_proto_rawDescGZIP(), []int{0} +// Deprecated: Use TestonlyNested.ProtoReflect.Descriptor instead. +func (*TestonlyNested) Descriptor() ([]byte, []int) { + return file_hashable_internal_testonly_proto_rawDescGZIP(), []int{0} } -func (x *Nested) GetT() isNested_T { +func (x *TestonlyNested) GetT() isTestonlyNested_T { if x != nil { return x.T } return nil } -func (x *Nested) GetNote() string { +func (x *TestonlyNested) GetNote() string { if x != nil { - if x, ok := x.T.(*Nested_Note); ok { + if x, ok := x.T.(*TestonlyNested_Note); ok { return x.Note } } return "" } -func (x *Nested) GetValue() uint32 { +func (x *TestonlyNested) GetValue() uint32 { if x != nil { - if x, ok := x.T.(*Nested_Value); ok { + if x, ok := x.T.(*TestonlyNested_Value); ok { return x.Value } } return 0 } -type isNested_T interface { - isNested_T() +type isTestonlyNested_T interface { + isTestonlyNested_T() } -type Nested_Note struct { +type TestonlyNested_Note struct { Note string `protobuf:"bytes,1,opt,name=note,proto3,oneof"` } -type Nested_Value struct { +type TestonlyNested_Value struct { Value uint32 `protobuf:"varint,2,opt,name=value,proto3,oneof"` } -func (*Nested_Note) isNested_T() {} +func (*TestonlyNested_Note) isTestonlyNested_T() {} -func (*Nested_Value) isNested_T() {} +func (*TestonlyNested_Value) isTestonlyNested_T() {} -type AllKinds struct { +type TestonlyMsg struct { state protoimpl.MessageState `protogen:"open.v1"` BoolValue *bool `protobuf:"varint,1,opt,name=bool_value,json=boolValue,proto3,oneof" json:"bool_value,omitempty"` - EnumValue *SampleEnum `protobuf:"varint,2,opt,name=enum_value,json=enumValue,proto3,enum=test.SampleEnum,oneof" json:"enum_value,omitempty"` + EnumValue *TestonlyEnum `protobuf:"varint,2,opt,name=enum_value,json=enumValue,proto3,enum=test.TestonlyEnum,oneof" json:"enum_value,omitempty"` Int32Value *int32 `protobuf:"varint,3,opt,name=int32_value,json=int32Value,proto3,oneof" json:"int32_value,omitempty"` Int64Value *int64 `protobuf:"varint,4,opt,name=int64_value,json=int64Value,proto3,oneof" json:"int64_value,omitempty"` Sint32Value *int32 `protobuf:"zigzag32,5,opt,name=sint32_value,json=sint32Value,proto3,oneof" json:"sint32_value,omitempty"` @@ -168,11 +169,11 @@ type AllKinds struct { Sfixed64Value *int64 `protobuf:"fixed64,12,opt,name=sfixed64_value,json=sfixed64Value,proto3,oneof" json:"sfixed64_value,omitempty"` BytesValue []byte `protobuf:"bytes,13,opt,name=bytes_value,json=bytesValue,proto3,oneof" json:"bytes_value,omitempty"` StringValue *string `protobuf:"bytes,14,opt,name=string_value,json=stringValue,proto3,oneof" json:"string_value,omitempty"` - MessageValue *Nested `protobuf:"bytes,15,opt,name=message_value,json=messageValue,proto3,oneof" json:"message_value,omitempty"` + MessageValue *TestonlyNested `protobuf:"bytes,15,opt,name=message_value,json=messageValue,proto3,oneof" json:"message_value,omitempty"` RepeatedPackable []int64 `protobuf:"zigzag64,16,rep,packed,name=repeated_packable,json=repeatedPackable,proto3" json:"repeated_packable,omitempty"` RepeatedString []string `protobuf:"bytes,17,rep,name=repeated_string,json=repeatedString,proto3" json:"repeated_string,omitempty"` - RepeatedMessage []*Nested `protobuf:"bytes,18,rep,name=repeated_message,json=repeatedMessage,proto3" json:"repeated_message,omitempty"` - OptionalMessage *Nested `protobuf:"bytes,19,opt,name=optional_message,json=optionalMessage,proto3,oneof" json:"optional_message,omitempty"` + RepeatedMessage []*TestonlyNested `protobuf:"bytes,18,rep,name=repeated_message,json=repeatedMessage,proto3" json:"repeated_message,omitempty"` + OptionalMessage *TestonlyNested `protobuf:"bytes,19,opt,name=optional_message,json=optionalMessage,proto3,oneof" json:"optional_message,omitempty"` RepeatedPackableSingleton []uint32 `protobuf:"fixed32,20,rep,packed,name=repeated_packable_singleton,json=repeatedPackableSingleton,proto3" json:"repeated_packable_singleton,omitempty"` RepeatedBytes [][]byte `protobuf:"bytes,21,rep,name=repeated_bytes,json=repeatedBytes,proto3" json:"repeated_bytes,omitempty"` RepeatedPackableEmpty []uint64 `protobuf:"varint,22,rep,packed,name=repeated_packable_empty,json=repeatedPackableEmpty,proto3" json:"repeated_packable_empty,omitempty"` @@ -180,21 +181,21 @@ type AllKinds struct { sizeCache protoimpl.SizeCache } -func (x *AllKinds) Reset() { - *x = AllKinds{} - mi := &file_hashable_hashable_test_proto_msgTypes[1] +func (x *TestonlyMsg) Reset() { + *x = TestonlyMsg{} + mi := &file_hashable_internal_testonly_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *AllKinds) String() string { +func (x *TestonlyMsg) String() string { return protoimpl.X.MessageStringOf(x) } -func (*AllKinds) ProtoMessage() {} +func (*TestonlyMsg) ProtoMessage() {} -func (x *AllKinds) ProtoReflect() protoreflect.Message { - mi := &file_hashable_hashable_test_proto_msgTypes[1] +func (x *TestonlyMsg) ProtoReflect() protoreflect.Message { + mi := &file_hashable_internal_testonly_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -205,180 +206,180 @@ func (x *AllKinds) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use AllKinds.ProtoReflect.Descriptor instead. -func (*AllKinds) Descriptor() ([]byte, []int) { - return file_hashable_hashable_test_proto_rawDescGZIP(), []int{1} +// Deprecated: Use TestonlyMsg.ProtoReflect.Descriptor instead. +func (*TestonlyMsg) Descriptor() ([]byte, []int) { + return file_hashable_internal_testonly_proto_rawDescGZIP(), []int{1} } -func (x *AllKinds) GetBoolValue() bool { +func (x *TestonlyMsg) GetBoolValue() bool { if x != nil && x.BoolValue != nil { return *x.BoolValue } return false } -func (x *AllKinds) GetEnumValue() SampleEnum { +func (x *TestonlyMsg) GetEnumValue() TestonlyEnum { if x != nil && x.EnumValue != nil { return *x.EnumValue } - return SampleEnum_SAMPLE_ENUM_UNSPECIFIED + return TestonlyEnum_TESTONLY_ENUM_UNSPECIFIED } -func (x *AllKinds) GetInt32Value() int32 { +func (x *TestonlyMsg) GetInt32Value() int32 { if x != nil && x.Int32Value != nil { return *x.Int32Value } return 0 } -func (x *AllKinds) GetInt64Value() int64 { +func (x *TestonlyMsg) GetInt64Value() int64 { if x != nil && x.Int64Value != nil { return *x.Int64Value } return 0 } -func (x *AllKinds) GetSint32Value() int32 { +func (x *TestonlyMsg) GetSint32Value() int32 { if x != nil && x.Sint32Value != nil { return *x.Sint32Value } return 0 } -func (x *AllKinds) GetSint64Value() int64 { +func (x *TestonlyMsg) GetSint64Value() int64 { if x != nil && x.Sint64Value != nil { return *x.Sint64Value } return 0 } -func (x *AllKinds) GetUint32Value() uint32 { +func (x *TestonlyMsg) GetUint32Value() uint32 { if x != nil && x.Uint32Value != nil { return *x.Uint32Value } return 0 } -func (x *AllKinds) GetUint64Value() uint64 { +func (x *TestonlyMsg) GetUint64Value() uint64 { if x != nil && x.Uint64Value != nil { return *x.Uint64Value } return 0 } -func (x *AllKinds) GetFixed32Value() uint32 { +func (x *TestonlyMsg) GetFixed32Value() uint32 { if x != nil && x.Fixed32Value != nil { return *x.Fixed32Value } return 0 } -func (x *AllKinds) GetFixed64Value() uint64 { +func (x *TestonlyMsg) GetFixed64Value() uint64 { if x != nil && x.Fixed64Value != nil { return *x.Fixed64Value } return 0 } -func (x *AllKinds) GetSfixed32Value() int32 { +func (x *TestonlyMsg) GetSfixed32Value() int32 { if x != nil && x.Sfixed32Value != nil { return *x.Sfixed32Value } return 0 } -func (x *AllKinds) GetSfixed64Value() int64 { +func (x *TestonlyMsg) GetSfixed64Value() int64 { if x != nil && x.Sfixed64Value != nil { return *x.Sfixed64Value } return 0 } -func (x *AllKinds) GetBytesValue() []byte { +func (x *TestonlyMsg) GetBytesValue() []byte { if x != nil { return x.BytesValue } return nil } -func (x *AllKinds) GetStringValue() string { +func (x *TestonlyMsg) GetStringValue() string { if x != nil && x.StringValue != nil { return *x.StringValue } return "" } -func (x *AllKinds) GetMessageValue() *Nested { +func (x *TestonlyMsg) GetMessageValue() *TestonlyNested { if x != nil { return x.MessageValue } return nil } -func (x *AllKinds) GetRepeatedPackable() []int64 { +func (x *TestonlyMsg) GetRepeatedPackable() []int64 { if x != nil { return x.RepeatedPackable } return nil } -func (x *AllKinds) GetRepeatedString() []string { +func (x *TestonlyMsg) GetRepeatedString() []string { if x != nil { return x.RepeatedString } return nil } -func (x *AllKinds) GetRepeatedMessage() []*Nested { +func (x *TestonlyMsg) GetRepeatedMessage() []*TestonlyNested { if x != nil { return x.RepeatedMessage } return nil } -func (x *AllKinds) GetOptionalMessage() *Nested { +func (x *TestonlyMsg) GetOptionalMessage() *TestonlyNested { if x != nil { return x.OptionalMessage } return nil } -func (x *AllKinds) GetRepeatedPackableSingleton() []uint32 { +func (x *TestonlyMsg) GetRepeatedPackableSingleton() []uint32 { if x != nil { return x.RepeatedPackableSingleton } return nil } -func (x *AllKinds) GetRepeatedBytes() [][]byte { +func (x *TestonlyMsg) GetRepeatedBytes() [][]byte { if x != nil { return x.RepeatedBytes } return nil } -func (x *AllKinds) GetRepeatedPackableEmpty() []uint64 { +func (x *TestonlyMsg) GetRepeatedPackableEmpty() []uint64 { if x != nil { return x.RepeatedPackableEmpty } return nil } -var File_hashable_hashable_test_proto protoreflect.FileDescriptor +var File_hashable_internal_testonly_proto protoreflect.FileDescriptor -const file_hashable_hashable_test_proto_rawDesc = "" + +const file_hashable_internal_testonly_proto_rawDesc = "" + "\n" + - "\x1chashable/hashable_test.proto\x12\x04test\x1a\x17hashable/hashable.proto\"C\n" + - "\x06Nested\x12\x14\n" + + " hashable/internal/testonly.proto\x12\x04test\x1a\x17hashable/hashable.proto\"K\n" + + "\x0eTestonlyNested\x12\x14\n" + "\x04note\x18\x01 \x01(\tH\x00R\x04note\x12\x16\n" + "\x05value\x18\x02 \x01(\rH\x00R\x05value:\x06Ȉ\xe2\xab\f\x01B\x03\n" + - "\x01t\"\x8a\n" + + "\x01t\"\xa7\n" + "\n" + - "\bAllKinds\x12\"\n" + + "\vTestonlyMsg\x12\"\n" + "\n" + - "bool_value\x18\x01 \x01(\bH\x00R\tboolValue\x88\x01\x01\x124\n" + + "bool_value\x18\x01 \x01(\bH\x00R\tboolValue\x88\x01\x01\x126\n" + "\n" + - "enum_value\x18\x02 \x01(\x0e2\x10.test.SampleEnumH\x01R\tenumValue\x88\x01\x01\x12$\n" + + "enum_value\x18\x02 \x01(\x0e2\x12.test.TestonlyEnumH\x01R\tenumValue\x88\x01\x01\x12$\n" + "\vint32_value\x18\x03 \x01(\x05H\x02R\n" + "int32Value\x88\x01\x01\x12$\n" + "\vint64_value\x18\x04 \x01(\x03H\x03R\n" + @@ -395,12 +396,12 @@ const file_hashable_hashable_test_proto_rawDesc = "" + "\x0esfixed64_value\x18\f \x01(\x10H\vR\rsfixed64Value\x88\x01\x01\x12$\n" + "\vbytes_value\x18\r \x01(\fH\fR\n" + "bytesValue\x88\x01\x01\x12&\n" + - "\fstring_value\x18\x0e \x01(\tH\rR\vstringValue\x88\x01\x01\x126\n" + - "\rmessage_value\x18\x0f \x01(\v2\f.test.NestedH\x0eR\fmessageValue\x88\x01\x01\x12+\n" + + "\fstring_value\x18\x0e \x01(\tH\rR\vstringValue\x88\x01\x01\x12>\n" + + "\rmessage_value\x18\x0f \x01(\v2\x14.test.TestonlyNestedH\x0eR\fmessageValue\x88\x01\x01\x12+\n" + "\x11repeated_packable\x18\x10 \x03(\x12R\x10repeatedPackable\x12'\n" + - "\x0frepeated_string\x18\x11 \x03(\tR\x0erepeatedString\x127\n" + - "\x10repeated_message\x18\x12 \x03(\v2\f.test.NestedR\x0frepeatedMessage\x12<\n" + - "\x10optional_message\x18\x13 \x01(\v2\f.test.NestedH\x0fR\x0foptionalMessage\x88\x01\x01\x12>\n" + + "\x0frepeated_string\x18\x11 \x03(\tR\x0erepeatedString\x12?\n" + + "\x10repeated_message\x18\x12 \x03(\v2\x14.test.TestonlyNestedR\x0frepeatedMessage\x12D\n" + + "\x10optional_message\x18\x13 \x01(\v2\x14.test.TestonlyNestedH\x0fR\x0foptionalMessage\x88\x01\x01\x12>\n" + "\x1brepeated_packable_singleton\x18\x14 \x03(\aR\x19repeatedPackableSingleton\x12%\n" + "\x0erepeated_bytes\x18\x15 \x03(\fR\rrepeatedBytes\x126\n" + "\x17repeated_packable_empty\x18\x16 \x03(\x04R\x15repeatedPackableEmpty:\x06Ȉ\xe2\xab\f\x01B\r\n" + @@ -419,37 +420,36 @@ const file_hashable_hashable_test_proto_rawDesc = "" + "\f_bytes_valueB\x0f\n" + "\r_string_valueB\x10\n" + "\x0e_message_valueB\x13\n" + - "\x11_optional_message*V\n" + - "\n" + - "SampleEnum\x12\x1b\n" + - "\x17SAMPLE_ENUM_UNSPECIFIED\x10\x00\x12\x15\n" + - "\x11SAMPLE_ENUM_ALPHA\x10\x01\x12\x14\n" + - "\x10SAMPLE_ENUM_BETA\x10\x02B3Z1github.com/tendermint/tendermint/libs/hashable/pbb\x06proto3" + "\x11_optional_message*^\n" + + "\fTestonlyEnum\x12\x1d\n" + + "\x19TESTONLY_ENUM_UNSPECIFIED\x10\x00\x12\x17\n" + + "\x13TESTONLY_ENUM_ALPHA\x10\x01\x12\x16\n" + + "\x12TESTONLY_ENUM_BETA\x10\x02B test.SampleEnum - 1, // 1: test.AllKinds.message_value:type_name -> test.Nested - 1, // 2: test.AllKinds.repeated_message:type_name -> test.Nested - 1, // 3: test.AllKinds.optional_message:type_name -> test.Nested +var file_hashable_internal_testonly_proto_depIdxs = []int32{ + 0, // 0: test.TestonlyMsg.enum_value:type_name -> test.TestonlyEnum + 1, // 1: test.TestonlyMsg.message_value:type_name -> test.TestonlyNested + 1, // 2: test.TestonlyMsg.repeated_message:type_name -> test.TestonlyNested + 1, // 3: test.TestonlyMsg.optional_message:type_name -> test.TestonlyNested 4, // [4:4] is the sub-list for method output_type 4, // [4:4] is the sub-list for method input_type 4, // [4:4] is the sub-list for extension type_name @@ -457,33 +457,32 @@ var file_hashable_hashable_test_proto_depIdxs = []int32{ 0, // [0:4] is the sub-list for field type_name } -func init() { file_hashable_hashable_test_proto_init() } -func file_hashable_hashable_test_proto_init() { - if File_hashable_hashable_test_proto != nil { +func init() { file_hashable_internal_testonly_proto_init() } +func file_hashable_internal_testonly_proto_init() { + if File_hashable_internal_testonly_proto != nil { return } - file_hashable_hashable_proto_init() - file_hashable_hashable_test_proto_msgTypes[0].OneofWrappers = []any{ - (*Nested_Note)(nil), - (*Nested_Value)(nil), + file_hashable_internal_testonly_proto_msgTypes[0].OneofWrappers = []any{ + (*TestonlyNested_Note)(nil), + (*TestonlyNested_Value)(nil), } - file_hashable_hashable_test_proto_msgTypes[1].OneofWrappers = []any{} + file_hashable_internal_testonly_proto_msgTypes[1].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_hashable_hashable_test_proto_rawDesc), len(file_hashable_hashable_test_proto_rawDesc)), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_hashable_internal_testonly_proto_rawDesc), len(file_hashable_internal_testonly_proto_rawDesc)), NumEnums: 1, NumMessages: 2, NumExtensions: 0, NumServices: 0, }, - GoTypes: file_hashable_hashable_test_proto_goTypes, - DependencyIndexes: file_hashable_hashable_test_proto_depIdxs, - EnumInfos: file_hashable_hashable_test_proto_enumTypes, - MessageInfos: file_hashable_hashable_test_proto_msgTypes, + GoTypes: file_hashable_internal_testonly_proto_goTypes, + DependencyIndexes: file_hashable_internal_testonly_proto_depIdxs, + EnumInfos: file_hashable_internal_testonly_proto_enumTypes, + MessageInfos: file_hashable_internal_testonly_proto_msgTypes, }.Build() - File_hashable_hashable_test_proto = out.File - file_hashable_hashable_test_proto_goTypes = nil - file_hashable_hashable_test_proto_depIdxs = nil + File_hashable_internal_testonly_proto = out.File + file_hashable_internal_testonly_proto_goTypes = nil + file_hashable_internal_testonly_proto_depIdxs = nil } diff --git a/sei-tendermint/libs/hashable/hashable_test.proto b/sei-tendermint/libs/hashable/internal/testonly.proto similarity index 73% rename from sei-tendermint/libs/hashable/hashable_test.proto rename to sei-tendermint/libs/hashable/internal/testonly.proto index 359dbb76ad..dcd8b0cd54 100644 --- a/sei-tendermint/libs/hashable/hashable_test.proto +++ b/sei-tendermint/libs/hashable/internal/testonly.proto @@ -4,15 +4,15 @@ package test; import "hashable/hashable.proto"; -option go_package = "github.com/tendermint/tendermint/libs/hashable/pb"; +option go_package = "github.com/tendermint/tendermint/libs/hashable/internal/pb"; -enum SampleEnum { - SAMPLE_ENUM_UNSPECIFIED = 0; - SAMPLE_ENUM_ALPHA = 1; - SAMPLE_ENUM_BETA = 2; +enum TestonlyEnum { + TESTONLY_ENUM_UNSPECIFIED = 0; + TESTONLY_ENUM_ALPHA = 1; + TESTONLY_ENUM_BETA = 2; } -message Nested { +message TestonlyNested { option (hashable.hashable) = true; oneof t { string note = 1; @@ -20,11 +20,11 @@ message Nested { } } -message AllKinds { +message TestonlyMsg { option (hashable.hashable) = true; optional bool bool_value = 1; - optional SampleEnum enum_value = 2; + optional TestonlyEnum enum_value = 2; optional int32 int32_value = 3; optional int64 int64_value = 4; optional sint32 sint32_value = 5; @@ -37,11 +37,11 @@ message AllKinds { optional sfixed64 sfixed64_value = 12; optional bytes bytes_value = 13; optional string string_value = 14; - optional Nested message_value = 15; + optional TestonlyNested message_value = 15; repeated sint64 repeated_packable = 16; repeated string repeated_string = 17; - repeated Nested repeated_message = 18; - optional Nested optional_message = 19; + repeated TestonlyNested repeated_message = 18; + optional TestonlyNested optional_message = 19; repeated fixed32 repeated_packable_singleton = 20; repeated bytes repeated_bytes = 21; repeated uint64 repeated_packable_empty = 22; diff --git a/sei-tendermint/libs/hashable/pb/hashable_test.hashable.go b/sei-tendermint/libs/hashable/pb/hashable_test.hashable.go deleted file mode 100644 index 9ac28e5c0a..0000000000 --- a/sei-tendermint/libs/hashable/pb/hashable_test.hashable.go +++ /dev/null @@ -1,5 +0,0 @@ -// Code generated by buf_plugin. DO NOT EDIT. -package pb - -func (*Nested) IsHashable() {} -func (*AllKinds) IsHashable() {} From 97948963a81bcacdd4379671035f235205c06f32 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Mon, 15 Dec 2025 13:24:05 +0100 Subject: [PATCH 17/53] fmt --- sei-tendermint/libs/hashable/hashable_test.go | 2 +- sei-tendermint/libs/hashable/plugin/main.go | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/sei-tendermint/libs/hashable/hashable_test.go b/sei-tendermint/libs/hashable/hashable_test.go index 6219084fe9..3cc6420bc0 100644 --- a/sei-tendermint/libs/hashable/hashable_test.go +++ b/sei-tendermint/libs/hashable/hashable_test.go @@ -9,9 +9,9 @@ import ( "google.golang.org/protobuf/proto" + "github.com/tendermint/tendermint/libs/hashable/internal/pb" "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/libs/utils/require" - "github.com/tendermint/tendermint/libs/hashable/internal/pb" ) // Test checking that the canonical encoding is a valid proto encoding and that it is stable. diff --git a/sei-tendermint/libs/hashable/plugin/main.go b/sei-tendermint/libs/hashable/plugin/main.go index e71ea63447..b2696e7933 100644 --- a/sei-tendermint/libs/hashable/plugin/main.go +++ b/sei-tendermint/libs/hashable/plugin/main.go @@ -2,12 +2,12 @@ package main import ( "errors" + "flag" "fmt" "iter" "log" - "flag" - "strings" "path/filepath" + "strings" "google.golang.org/protobuf/compiler/protogen" "google.golang.org/protobuf/proto" @@ -21,7 +21,7 @@ import ( var flags flag.FlagSet -var moduleFlag = flags.String("module","","prefix to strip from the absolute generated file path. Same as in protoc-gen-go") +var moduleFlag = flags.String("module", "", "prefix to strip from the absolute generated file path. Same as in protoc-gen-go") func (d md) GetBoolOption(ext protoreflect.ExtensionTypeDescriptor) bool { options := d.Options().(*descriptorpb.MessageOptions).ProtoReflect() @@ -172,12 +172,12 @@ func generateHashableFiles(p *protogen.Plugin, descs mds) error { if len(targets) == 0 { continue } - genDir,err := filepath.Rel(*moduleFlag,string(file.GoImportPath)) - if err!=nil { - return fmt.Errorf("filepath.Rel(): %w",err) + genDir, err := filepath.Rel(*moduleFlag, string(file.GoImportPath)) + if err != nil { + return fmt.Errorf("filepath.Rel(): %w", err) } genFileName := strings.TrimSuffix(filepath.Base(file.Desc.Path()), ".proto") + ".hashable.go" - g := p.NewGeneratedFile(filepath.Join(genDir,genFileName), file.GoImportPath) + g := p.NewGeneratedFile(filepath.Join(genDir, genFileName), file.GoImportPath) g.P("// Code generated by buf_plugin. DO NOT EDIT.") g.P("package ", file.GoPackageName) g.P() @@ -189,5 +189,5 @@ func generateHashableFiles(p *protogen.Plugin, descs mds) error { } func main() { - protogen.Options{ParamFunc:flags.Set}.Run(run) + protogen.Options{ParamFunc: flags.Set}.Run(run) } From a82ac927851beaddb11793ea2c0fff9d0ab5ca8d Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Mon, 15 Dec 2025 14:14:15 +0100 Subject: [PATCH 18/53] moved under internal --- buf.yaml | 2 +- scripts/protoc.sh | 2 +- sei-tendermint/internal/buf.gen.yaml | 14 +++++++ .../{libs => internal}/hashable/hashable.go | 0 .../hashable/hashable.proto | 2 +- .../hashable/hashable_test.go | 0 .../hashable/internal/pb/testonly.hashable.go | 0 .../hashable/internal/pb/testonly.pb.go | 38 +++++++++---------- .../hashable/internal/testonly.proto | 4 +- .../hashable/pb/hashable.pb.go | 2 +- .../hashable/plugin/main.go | 0 sei-tendermint/libs/buf.gen.yaml | 14 ------- sei-tendermint/libs/buf.yaml | 19 ---------- 13 files changed, 39 insertions(+), 58 deletions(-) create mode 100644 sei-tendermint/internal/buf.gen.yaml rename sei-tendermint/{libs => internal}/hashable/hashable.go (100%) rename sei-tendermint/{libs => internal}/hashable/hashable.proto (82%) rename sei-tendermint/{libs => internal}/hashable/hashable_test.go (100%) rename sei-tendermint/{libs => internal}/hashable/internal/pb/testonly.hashable.go (100%) rename sei-tendermint/{libs => internal}/hashable/internal/pb/testonly.pb.go (91%) rename sei-tendermint/{libs => internal}/hashable/internal/testonly.proto (92%) rename sei-tendermint/{libs => internal}/hashable/pb/hashable.pb.go (96%) rename sei-tendermint/{libs => internal}/hashable/plugin/main.go (100%) delete mode 100644 sei-tendermint/libs/buf.gen.yaml delete mode 100644 sei-tendermint/libs/buf.yaml diff --git a/buf.yaml b/buf.yaml index b35af2f509..8ae16d29c3 100644 --- a/buf.yaml +++ b/buf.yaml @@ -8,7 +8,7 @@ modules: - path: sei-ibc-go/proto - path: sei-ibc-go/third_party/proto - path: sei-tendermint/proto - - path: sei-tendermint/proto_v2 + - path: sei-tendermint/internal - path: sei-wasmd/proto lint: diff --git a/scripts/protoc.sh b/scripts/protoc.sh index d2710006f8..09a2de5278 100755 --- a/scripts/protoc.sh +++ b/scripts/protoc.sh @@ -24,7 +24,7 @@ pushd "$(go env GOMODCACHE)/github.com/regen-network/cosmos-proto@v0.3.1" && popd go run github.com/bufbuild/buf/cmd/buf@v1.58.0 generate -go run github.com/bufbuild/buf/cmd/buf@v1.58.0 generate --template buf.gen_v2.yaml +go run github.com/bufbuild/buf/cmd/buf@v1.58.0 generate --template sei-tendermint/internal/buf.gen.yaml # We can't manipulate the outputs enough to eliminate the extra move-abouts. # So we just copy the files we want to the right places manually. diff --git a/sei-tendermint/internal/buf.gen.yaml b/sei-tendermint/internal/buf.gen.yaml new file mode 100644 index 0000000000..2dea7ea9ea --- /dev/null +++ b/sei-tendermint/internal/buf.gen.yaml @@ -0,0 +1,14 @@ +version: v2 +inputs: + - directory: ./sei-tendermint/internal +plugins: + - remote: buf.build/protocolbuffers/go:v1.36.10 + out: ./sei-tendermint/internal + opt: [module=github.com/tendermint/tendermint/internal] + - local: + - go + - run + - ./sei-tendermint/internal/hashable/plugin + strategy: all + out: ./sei-tendermint/internal + opt: [module=github.com/tendermint/tendermint/internal] diff --git a/sei-tendermint/libs/hashable/hashable.go b/sei-tendermint/internal/hashable/hashable.go similarity index 100% rename from sei-tendermint/libs/hashable/hashable.go rename to sei-tendermint/internal/hashable/hashable.go diff --git a/sei-tendermint/libs/hashable/hashable.proto b/sei-tendermint/internal/hashable/hashable.proto similarity index 82% rename from sei-tendermint/libs/hashable/hashable.proto rename to sei-tendermint/internal/hashable/hashable.proto index c3058eb9c3..f0c9b88654 100644 --- a/sei-tendermint/libs/hashable/hashable.proto +++ b/sei-tendermint/internal/hashable/hashable.proto @@ -4,7 +4,7 @@ package hashable; import "google/protobuf/descriptor.proto"; -option go_package = "github.com/tendermint/tendermint/libs/hashable/pb"; +option go_package = "github.com/tendermint/tendermint/internal/hashable/pb"; // hashable marks messages which support canonical protobuf serialization and therefore // are suitable for hashing. diff --git a/sei-tendermint/libs/hashable/hashable_test.go b/sei-tendermint/internal/hashable/hashable_test.go similarity index 100% rename from sei-tendermint/libs/hashable/hashable_test.go rename to sei-tendermint/internal/hashable/hashable_test.go diff --git a/sei-tendermint/libs/hashable/internal/pb/testonly.hashable.go b/sei-tendermint/internal/hashable/internal/pb/testonly.hashable.go similarity index 100% rename from sei-tendermint/libs/hashable/internal/pb/testonly.hashable.go rename to sei-tendermint/internal/hashable/internal/pb/testonly.hashable.go diff --git a/sei-tendermint/libs/hashable/internal/pb/testonly.pb.go b/sei-tendermint/internal/hashable/internal/pb/testonly.pb.go similarity index 91% rename from sei-tendermint/libs/hashable/internal/pb/testonly.pb.go rename to sei-tendermint/internal/hashable/internal/pb/testonly.pb.go index 75b0af83bd..9436e59893 100644 --- a/sei-tendermint/libs/hashable/internal/pb/testonly.pb.go +++ b/sei-tendermint/internal/hashable/internal/pb/testonly.pb.go @@ -7,7 +7,7 @@ package pb import ( - _ "github.com/tendermint/tendermint/libs/hashable/pb" + _ "github.com/tendermint/tendermint/internal/hashable/pb" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -156,7 +156,7 @@ func (*TestonlyNested_Value) isTestonlyNested_T() {} type TestonlyMsg struct { state protoimpl.MessageState `protogen:"open.v1"` BoolValue *bool `protobuf:"varint,1,opt,name=bool_value,json=boolValue,proto3,oneof" json:"bool_value,omitempty"` - EnumValue *TestonlyEnum `protobuf:"varint,2,opt,name=enum_value,json=enumValue,proto3,enum=test.TestonlyEnum,oneof" json:"enum_value,omitempty"` + EnumValue *TestonlyEnum `protobuf:"varint,2,opt,name=enum_value,json=enumValue,proto3,enum=internal.TestonlyEnum,oneof" json:"enum_value,omitempty"` Int32Value *int32 `protobuf:"varint,3,opt,name=int32_value,json=int32Value,proto3,oneof" json:"int32_value,omitempty"` Int64Value *int64 `protobuf:"varint,4,opt,name=int64_value,json=int64Value,proto3,oneof" json:"int64_value,omitempty"` Sint32Value *int32 `protobuf:"zigzag32,5,opt,name=sint32_value,json=sint32Value,proto3,oneof" json:"sint32_value,omitempty"` @@ -369,17 +369,17 @@ var File_hashable_internal_testonly_proto protoreflect.FileDescriptor const file_hashable_internal_testonly_proto_rawDesc = "" + "\n" + - " hashable/internal/testonly.proto\x12\x04test\x1a\x17hashable/hashable.proto\"K\n" + + " hashable/internal/testonly.proto\x12\binternal\x1a\x17hashable/hashable.proto\"K\n" + "\x0eTestonlyNested\x12\x14\n" + "\x04note\x18\x01 \x01(\tH\x00R\x04note\x12\x16\n" + "\x05value\x18\x02 \x01(\rH\x00R\x05value:\x06Ȉ\xe2\xab\f\x01B\x03\n" + - "\x01t\"\xa7\n" + + "\x01t\"\xb7\n" + "\n" + "\vTestonlyMsg\x12\"\n" + "\n" + - "bool_value\x18\x01 \x01(\bH\x00R\tboolValue\x88\x01\x01\x126\n" + + "bool_value\x18\x01 \x01(\bH\x00R\tboolValue\x88\x01\x01\x12:\n" + "\n" + - "enum_value\x18\x02 \x01(\x0e2\x12.test.TestonlyEnumH\x01R\tenumValue\x88\x01\x01\x12$\n" + + "enum_value\x18\x02 \x01(\x0e2\x16.internal.TestonlyEnumH\x01R\tenumValue\x88\x01\x01\x12$\n" + "\vint32_value\x18\x03 \x01(\x05H\x02R\n" + "int32Value\x88\x01\x01\x12$\n" + "\vint64_value\x18\x04 \x01(\x03H\x03R\n" + @@ -396,12 +396,12 @@ const file_hashable_internal_testonly_proto_rawDesc = "" + "\x0esfixed64_value\x18\f \x01(\x10H\vR\rsfixed64Value\x88\x01\x01\x12$\n" + "\vbytes_value\x18\r \x01(\fH\fR\n" + "bytesValue\x88\x01\x01\x12&\n" + - "\fstring_value\x18\x0e \x01(\tH\rR\vstringValue\x88\x01\x01\x12>\n" + - "\rmessage_value\x18\x0f \x01(\v2\x14.test.TestonlyNestedH\x0eR\fmessageValue\x88\x01\x01\x12+\n" + + "\fstring_value\x18\x0e \x01(\tH\rR\vstringValue\x88\x01\x01\x12B\n" + + "\rmessage_value\x18\x0f \x01(\v2\x18.internal.TestonlyNestedH\x0eR\fmessageValue\x88\x01\x01\x12+\n" + "\x11repeated_packable\x18\x10 \x03(\x12R\x10repeatedPackable\x12'\n" + - "\x0frepeated_string\x18\x11 \x03(\tR\x0erepeatedString\x12?\n" + - "\x10repeated_message\x18\x12 \x03(\v2\x14.test.TestonlyNestedR\x0frepeatedMessage\x12D\n" + - "\x10optional_message\x18\x13 \x01(\v2\x14.test.TestonlyNestedH\x0fR\x0foptionalMessage\x88\x01\x01\x12>\n" + + "\x0frepeated_string\x18\x11 \x03(\tR\x0erepeatedString\x12C\n" + + "\x10repeated_message\x18\x12 \x03(\v2\x18.internal.TestonlyNestedR\x0frepeatedMessage\x12H\n" + + "\x10optional_message\x18\x13 \x01(\v2\x18.internal.TestonlyNestedH\x0fR\x0foptionalMessage\x88\x01\x01\x12>\n" + "\x1brepeated_packable_singleton\x18\x14 \x03(\aR\x19repeatedPackableSingleton\x12%\n" + "\x0erepeated_bytes\x18\x15 \x03(\fR\rrepeatedBytes\x126\n" + "\x17repeated_packable_empty\x18\x16 \x03(\x04R\x15repeatedPackableEmpty:\x06Ȉ\xe2\xab\f\x01B\r\n" + @@ -424,7 +424,7 @@ const file_hashable_internal_testonly_proto_rawDesc = "" + "\fTestonlyEnum\x12\x1d\n" + "\x19TESTONLY_ENUM_UNSPECIFIED\x10\x00\x12\x17\n" + "\x13TESTONLY_ENUM_ALPHA\x10\x01\x12\x16\n" + - "\x12TESTONLY_ENUM_BETA\x10\x02Bgithub.com/tendermint/tendermint/internal/hashable/internal/pbb\x06proto3" var ( file_hashable_internal_testonly_proto_rawDescOnce sync.Once @@ -441,15 +441,15 @@ func file_hashable_internal_testonly_proto_rawDescGZIP() []byte { var file_hashable_internal_testonly_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_hashable_internal_testonly_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_hashable_internal_testonly_proto_goTypes = []any{ - (TestonlyEnum)(0), // 0: test.TestonlyEnum - (*TestonlyNested)(nil), // 1: test.TestonlyNested - (*TestonlyMsg)(nil), // 2: test.TestonlyMsg + (TestonlyEnum)(0), // 0: internal.TestonlyEnum + (*TestonlyNested)(nil), // 1: internal.TestonlyNested + (*TestonlyMsg)(nil), // 2: internal.TestonlyMsg } var file_hashable_internal_testonly_proto_depIdxs = []int32{ - 0, // 0: test.TestonlyMsg.enum_value:type_name -> test.TestonlyEnum - 1, // 1: test.TestonlyMsg.message_value:type_name -> test.TestonlyNested - 1, // 2: test.TestonlyMsg.repeated_message:type_name -> test.TestonlyNested - 1, // 3: test.TestonlyMsg.optional_message:type_name -> test.TestonlyNested + 0, // 0: internal.TestonlyMsg.enum_value:type_name -> internal.TestonlyEnum + 1, // 1: internal.TestonlyMsg.message_value:type_name -> internal.TestonlyNested + 1, // 2: internal.TestonlyMsg.repeated_message:type_name -> internal.TestonlyNested + 1, // 3: internal.TestonlyMsg.optional_message:type_name -> internal.TestonlyNested 4, // [4:4] is the sub-list for method output_type 4, // [4:4] is the sub-list for method input_type 4, // [4:4] is the sub-list for extension type_name diff --git a/sei-tendermint/libs/hashable/internal/testonly.proto b/sei-tendermint/internal/hashable/internal/testonly.proto similarity index 92% rename from sei-tendermint/libs/hashable/internal/testonly.proto rename to sei-tendermint/internal/hashable/internal/testonly.proto index dcd8b0cd54..aa34e166d4 100644 --- a/sei-tendermint/libs/hashable/internal/testonly.proto +++ b/sei-tendermint/internal/hashable/internal/testonly.proto @@ -1,10 +1,10 @@ syntax = "proto3"; -package test; +package internal; import "hashable/hashable.proto"; -option go_package = "github.com/tendermint/tendermint/libs/hashable/internal/pb"; +option go_package = "github.com/tendermint/tendermint/internal/hashable/internal/pb"; enum TestonlyEnum { TESTONLY_ENUM_UNSPECIFIED = 0; diff --git a/sei-tendermint/libs/hashable/pb/hashable.pb.go b/sei-tendermint/internal/hashable/pb/hashable.pb.go similarity index 96% rename from sei-tendermint/libs/hashable/pb/hashable.pb.go rename to sei-tendermint/internal/hashable/pb/hashable.pb.go index 6c0d6c5b83..ab876437a2 100644 --- a/sei-tendermint/libs/hashable/pb/hashable.pb.go +++ b/sei-tendermint/internal/hashable/pb/hashable.pb.go @@ -43,7 +43,7 @@ var File_hashable_hashable_proto protoreflect.FileDescriptor const file_hashable_hashable_proto_rawDesc = "" + "\n" + "\x17hashable/hashable.proto\x12\bhashable\x1a google/protobuf/descriptor.proto:?\n" + - "\bhashable\x12\x1f.google.protobuf.MessageOptions\x18\x89\xa1\xbc\xc5\x01 \x01(\bR\bhashableB3Z1github.com/tendermint/tendermint/libs/hashable/pbb\x06proto3" + "\bhashable\x12\x1f.google.protobuf.MessageOptions\x18\x89\xa1\xbc\xc5\x01 \x01(\bR\bhashableB7Z5github.com/tendermint/tendermint/internal/hashable/pbb\x06proto3" var file_hashable_hashable_proto_goTypes = []any{ (*descriptorpb.MessageOptions)(nil), // 0: google.protobuf.MessageOptions diff --git a/sei-tendermint/libs/hashable/plugin/main.go b/sei-tendermint/internal/hashable/plugin/main.go similarity index 100% rename from sei-tendermint/libs/hashable/plugin/main.go rename to sei-tendermint/internal/hashable/plugin/main.go diff --git a/sei-tendermint/libs/buf.gen.yaml b/sei-tendermint/libs/buf.gen.yaml deleted file mode 100644 index f8c52c837e..0000000000 --- a/sei-tendermint/libs/buf.gen.yaml +++ /dev/null @@ -1,14 +0,0 @@ -version: v2 -inputs: - - directory: ./ -plugins: - - remote: buf.build/protocolbuffers/go:v1.36.10 - out: ./ - opt: [module=github.com/tendermint/tendermint/libs] - - local: - - go - - run - - ./hashable/plugin - strategy: all - out: ./ - opt: [module=github.com/tendermint/tendermint/libs] diff --git a/sei-tendermint/libs/buf.yaml b/sei-tendermint/libs/buf.yaml deleted file mode 100644 index f83d4b1ddd..0000000000 --- a/sei-tendermint/libs/buf.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# For details on buf.yaml configuration, visit https://buf.build/docs/configuration/v2/buf-yaml -version: v2 -modules: - - path: ./ -lint: - use: - - BASIC - - FILE_LOWER_SNAKE_CASE - - UNARY_RPC - except: - - COMMENT_FIELD - - PACKAGE_VERSION_SUFFIX - - PACKAGE_SAME_DIRECTORY - - PACKAGE_DIRECTORY_MATCH - - PACKAGE_SAME_GO_PACKAGE -breaking: - use: - - WIRE - - WIRE_JSON From 50ae626f9073ef35054a5c2600b89fe48410e695 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Mon, 15 Dec 2025 14:17:58 +0100 Subject: [PATCH 19/53] comment fix --- sei-tendermint/internal/hashable/plugin/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sei-tendermint/internal/hashable/plugin/main.go b/sei-tendermint/internal/hashable/plugin/main.go index b2696e7933..b70fd36b5e 100644 --- a/sei-tendermint/internal/hashable/plugin/main.go +++ b/sei-tendermint/internal/hashable/plugin/main.go @@ -178,7 +178,7 @@ func generateHashableFiles(p *protogen.Plugin, descs mds) error { } genFileName := strings.TrimSuffix(filepath.Base(file.Desc.Path()), ".proto") + ".hashable.go" g := p.NewGeneratedFile(filepath.Join(genDir, genFileName), file.GoImportPath) - g.P("// Code generated by buf_plugin. DO NOT EDIT.") + g.P("// Code generated by sei-tendermint/hashable/plugin. DO NOT EDIT.") g.P("package ", file.GoPackageName) g.P() for _, m := range targets { From 51c83d6e5ad5c5108c1eb7c62d0dab06d65b629c Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Mon, 15 Dec 2025 16:18:58 +0100 Subject: [PATCH 20/53] ed25519 cleanup wip --- sei-tendermint/crypto/crypto.go | 6 + sei-tendermint/crypto/ed25519/bench_test.go | 79 +---- sei-tendermint/crypto/ed25519/ed25519.go | 228 ++++--------- sei-tendermint/crypto/ed25519/ed25519_test.go | 16 +- .../internal/roles/validator/msg.go | 27 ++ .../roles/validator/pb/validator.hashable.go | 4 + .../roles/validator/pb/validator.pb.go | 314 ++++++++++++++++++ .../internal/roles/validator/validator.proto | 30 ++ sei-tendermint/libs/utils/option.go | 8 + sei-tendermint/libs/utils/proto.go | 11 +- sei-tendermint/types/validation.go | 42 +-- 11 files changed, 503 insertions(+), 262 deletions(-) create mode 100644 sei-tendermint/internal/roles/validator/msg.go create mode 100644 sei-tendermint/internal/roles/validator/pb/validator.hashable.go create mode 100644 sei-tendermint/internal/roles/validator/pb/validator.pb.go create mode 100644 sei-tendermint/internal/roles/validator/validator.proto diff --git a/sei-tendermint/crypto/crypto.go b/sei-tendermint/crypto/crypto.go index ca46e44638..3517f15e4c 100644 --- a/sei-tendermint/crypto/crypto.go +++ b/sei-tendermint/crypto/crypto.go @@ -37,7 +37,13 @@ func Checksum(bz []byte) []byte { type PubKey = ed25519.PubKey type PrivKey = ed25519.PrivKey +type Sig = ed25519.Sig type BatchVerifier = ed25519.BatchVerifier +type ErrBadSig = ed25519.ErrBadSig + +func SigFromBytes(raw []byte) (Sig,error) { + return ed25519.SigFromBytes(raw) +} func NewBatchVerifier() *BatchVerifier { return ed25519.NewBatchVerifier() diff --git a/sei-tendermint/crypto/ed25519/bench_test.go b/sei-tendermint/crypto/ed25519/bench_test.go index cf5131076b..a51988fb54 100644 --- a/sei-tendermint/crypto/ed25519/bench_test.go +++ b/sei-tendermint/crypto/ed25519/bench_test.go @@ -2,84 +2,39 @@ package ed25519 import ( "fmt" - "io" "testing" - - "github.com/stretchr/testify/require" ) -type zeroReader struct{} - -func (zeroReader) Read(buf []byte) (int, error) { - for i := range buf { - buf[i] = 0 - } - return len(buf), nil -} - -func benchmarkKeyGeneration(b *testing.B, generateKey func(reader io.Reader) PrivKey) { - var zero zeroReader - for i := 0; i < b.N; i++ { - generateKey(zero) - } -} - -func benchmarkSigning(b *testing.B, priv PrivKey) { +func BenchmarkSigning(b *testing.B) { + priv := GenPrivKey() message := []byte("Hello, world!") - b.ResetTimer() - for i := 0; i < b.N; i++ { - _, err := priv.Sign(message) - if err != nil { - b.FailNow() - } + for b.Loop() { + priv.Sign(message) } } -func benchmarkVerification(b *testing.B, priv PrivKey) { +func BenchmarkVerification(b *testing.B) { + priv := GenPrivKey() pub := priv.PubKey() message := []byte("Hello, world!") - signature, err := priv.Sign(message) - if err != nil { - b.Fatal(err) - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - pub.VerifySignature(message, signature) + sig := priv.Sign(message) + for b.Loop() { + pub.Verify(message, sig) } } -func BenchmarkKeyGeneration(b *testing.B) { - benchmarkKeygenWrapper := func(reader io.Reader) PrivKey { - return genPrivKey(reader) - } - benchmarkKeyGeneration(b, benchmarkKeygenWrapper) -} - -func BenchmarkSigning(b *testing.B) { - priv := GenPrivKey() - benchmarkSigning(b, priv) -} - -func BenchmarkVerification(b *testing.B) { - priv := GenPrivKey() - benchmarkVerification(b, priv) -} - func BenchmarkVerifyBatch(b *testing.B) { msg := []byte("BatchVerifyTest") - for _, sigsCount := range []int{1, 8, 64, 1024} { - sigsCount := sigsCount b.Run(fmt.Sprintf("sig-count-%d", sigsCount), func(b *testing.B) { // Pre-generate all of the keys, and signatures, but do not // benchmark key-generation and signing. pubs := make([]PubKey, 0, sigsCount) - sigs := make([][]byte, 0, sigsCount) - for i := 0; i < sigsCount; i++ { + sigs := make([]Sig, 0, sigsCount) + for range sigsCount { priv := GenPrivKey() - sig, _ := priv.Sign(msg) pubs = append(pubs, priv.PubKey()) - sigs = append(sigs, sig) + sigs = append(sigs, priv.Sign(msg)) } b.ResetTimer() @@ -91,13 +46,11 @@ func BenchmarkVerifyBatch(b *testing.B) { // with BatchVerifier.Add(), which should be included // in the benchmark. v := NewBatchVerifier() - for i := 0; i < sigsCount; i++ { - err := v.Add(pubs[i], msg, sigs[i]) - require.NoError(b, err) + for i := range sigsCount { + v.Add(pubs[i], msg, sigs[i]) } - - if ok, _ := v.Verify(); !ok { - b.Fatal("signature set failed batch verification") + if err := v.Verify(); err!=nil { + b.Fatal(err) } } }) diff --git a/sei-tendermint/crypto/ed25519/ed25519.go b/sei-tendermint/crypto/ed25519/ed25519.go index 6723de7ad2..17ee96fd1d 100644 --- a/sei-tendermint/crypto/ed25519/ed25519.go +++ b/sei-tendermint/crypto/ed25519/ed25519.go @@ -1,12 +1,10 @@ package ed25519 import ( - "bytes" "crypto/rand" "crypto/sha256" - "crypto/subtle" - "errors" "fmt" + "errors" "io" "github.com/oasisprotocol/curve25519-voi/primitives/ed25519" @@ -17,206 +15,126 @@ import ( tmjson "github.com/tendermint/tendermint/libs/json" ) -//------------------------------------- - -var ( - // curve25519-voi's Ed25519 implementation supports configurable - // verification behavior, and tendermint uses the ZIP-215 verification - // semantics. - verifyOptions = &ed25519.Options{ - Verify: ed25519.VerifyOptionsZIP_215, - } +const PrivKeyName = "tendermint/PrivKeyEd25519" +const PubKeyName = "tendermint/PubKeyEd25519" +const KeyType = "ed25519" - cachingVerifier = cache.NewVerifier(cache.NewLRUCache(cacheSize)) -) +// cacheSize is the number of public keys that will be cached in +// an expanded format for repeated signature verification. +// +// TODO/perf: Either this should exclude single verification, or be +// tuned to `> validatorSize + maxTxnsPerBlock` to avoid cache +// thrashing. +const cacheSize = 4096 -const ( - PrivKeyName = "tendermint/PrivKeyEd25519" - PubKeyName = "tendermint/PubKeyEd25519" - // PubKeySize is is the size, in bytes, of public keys as used in this package. - PubKeySize = 32 - // PrivateKeySize is the size, in bytes, of private keys as used in this package. - PrivateKeySize = 64 - // Size of an Edwards25519 signature. Namely the size of a compressed - // Edwards25519 point, and a field element. Both of which are 32 bytes. - SignatureSize = 64 - // SeedSize is the size, in bytes, of private key seeds. These are the - // private key representations used by RFC 8032. - SeedSize = 32 - - KeyType = "ed25519" - - // cacheSize is the number of public keys that will be cached in - // an expanded format for repeated signature verification. - // - // TODO/perf: Either this should exclude single verification, or be - // tuned to `> validatorSize + maxTxnsPerBlock` to avoid cache - // thrashing. - cacheSize = 4096 -) +// curve25519-voi's Ed25519 implementation supports configurable +// verification behavior, and tendermint uses the ZIP-215 verification +// semantics. +var verifyOptions = &ed25519.Options{Verify: ed25519.VerifyOptionsZIP_215} +var cachingVerifier = cache.NewVerifier(cache.NewLRUCache(cacheSize)) func init() { tmjson.RegisterType(PubKey{}, PubKeyName) - tmjson.RegisterType(PrivKey{}, PrivKeyName) - jsontypes.MustRegister(PubKey{}) - jsontypes.MustRegister(PrivKey{}) } -type PrivKey []byte +type PrivKey struct { + raw ed25519.PrivateKey // ed25519.PrivateKey is a slice, therefore the secret will not be copied around. +} // TypeTag satisfies the jsontypes.Tagged interface. -func (PrivKey) TypeTag() string { return PrivKeyName } +func (k PrivKey) TypeTag() string { return PrivKeyName } // Bytes returns the privkey byte format. -func (privKey PrivKey) Bytes() []byte { - return []byte(privKey) -} +func (k PrivKey) SecretBytes() []byte { return k.raw } -// Sign produces a signature on the provided message. -// This assumes the privkey is wellformed in the golang format. -// The first 32 bytes should be random, -// corresponding to the normal ed25519 private key. -// The latter 32 bytes should be the compressed public key. -// If these conditions aren't met, Sign will panic or produce an -// incorrect signature. -func (privKey PrivKey) Sign(msg []byte) ([]byte, error) { - signatureBytes := ed25519.Sign(ed25519.PrivateKey(privKey), msg) - return signatureBytes, nil -} +// Sig represents signature. +type Sig [ed25519.SignatureSize]byte -// PubKey gets the corresponding public key from the private key. -// -// Panics if the private key is not initialized. -func (privKey PrivKey) PubKey() PubKey { - // If the latter 32 bytes of the privkey are all zero, privkey is not - // initialized. - initialized := false - for _, v := range privKey[32:] { - if v != 0 { - initialized = true - break - } +func SigFromBytes(raw []byte) (Sig,error) { + if len(raw)!=len(Sig{}) { + return Sig{},errors.New("invalid signature length") } - - if !initialized { - panic("Expected ed25519 PrivKey to include concatenated pubkey bytes") - } - - pubkeyBytes := make([]byte, PubKeySize) - copy(pubkeyBytes, privKey[32:]) - return PubKey(pubkeyBytes) + return Sig(raw),nil } -// Equals - you probably don't need to use this. -// Runs in constant time based on length of the keys. -func (privKey PrivKey) Equals(other PrivKey) bool { - return subtle.ConstantTimeCompare(privKey[:], other[:]) == 1 -} +// Sign signs a message with the key. +func (k PrivKey) Sign(msg []byte) Sig { return Sig(ed25519.Sign(k.raw, msg)) } -func (privKey PrivKey) Type() string { - return KeyType -} +// PubKey gets the corresponding public key from the private key. +func (k PrivKey) PubKey() PubKey { return PubKey(k.raw.Public().([]byte)) } -// GenPrivKey generates a new ed25519 private key. -// It uses OS randomness in conjunction with the current global random seed -// in tendermint/libs/common to generate the private key. -func GenPrivKey() PrivKey { - return genPrivKey(rand.Reader) -} +func (k PrivKey) Type() string { return KeyType } -// genPrivKey generates a new ed25519 private key using the provided reader. -func genPrivKey(rand io.Reader) PrivKey { - _, priv, err := ed25519.GenerateKey(rand) - if err != nil { +// GenPrivKey generates a new ed25519 private key from OS entropy. +func GenPrivKey() PrivKey { + var seed [ed25519.SeedSize]byte + if _,err := io.ReadFull(rand.Reader,seed[:]); err != nil { panic(err) } - - return PrivKey(priv) + return PrivKeyFromSeed(seed) } -// GenPrivKeyFromSecret hashes the secret with SHA2, and uses -// that 32 byte output to create the private key. -// NOTE: secret should be the output of a KDF like bcrypt, -// if it's derived from user input. -func GenPrivKeyFromSecret(secret []byte) PrivKey { - seed := sha256.Sum256(secret) - return PrivKey(ed25519.NewKeyFromSeed(seed[:])) +// PrivKeyFromSeed constructs a private key from seed. +func PrivKeyFromSeed(seed [ed25519.SeedSize]byte) PrivKey { + return PrivKey{ed25519.NewKeyFromSeed(seed[:])} } //------------------------------------- -// PubKeyEd25519 implements the Ed25519 signature scheme. -type PubKey []byte +// PubKey implements the Ed25519 signature scheme. +type PubKey [ed25519.PublicKeySize]byte // TypeTag satisfies the jsontypes.Tagged interface. func (PubKey) TypeTag() string { return PubKeyName } // Address is the SHA256-20 of the raw pubkey bytes. -func (pubKey PubKey) Address() tmbytes.HexBytes { - if len(pubKey) != PubKeySize { - panic("pubkey is incorrect size") - } - return addressHash(pubKey) +func (k PubKey) Address() tmbytes.HexBytes { + h := sha256.Sum256(k[:]) + return tmbytes.HexBytes(h[:20]) } // Bytes returns the PubKey byte format. -func (pubKey PubKey) Bytes() []byte { - return []byte(pubKey) -} +func (k PubKey) Bytes() []byte { return k[:] } -func (pubKey PubKey) VerifySignature(msg []byte, sig []byte) bool { - // make sure we use the same algorithm to sign - if len(sig) != SignatureSize { - return false +func (k PubKey) Verify(msg []byte, sig Sig) error { + if !cachingVerifier.VerifyWithOptions(k[:], msg, sig[:], verifyOptions) { + return errors.New("invalid signature") } - - return cachingVerifier.VerifyWithOptions(ed25519.PublicKey(pubKey), msg, sig, verifyOptions) + return nil } -func (pubKey PubKey) String() string { - return fmt.Sprintf("PubKeyEd25519{%X}", []byte(pubKey)) -} +func (k PubKey) String() string { return fmt.Sprintf("PubKeyEd25519{%X}", k[:]) } +func (k PubKey) Type() string { return KeyType } -func (pubKey PubKey) Type() string { - return KeyType -} +// BatchVerifier implements batch verification for ed25519. +type BatchVerifier struct { inner *ed25519.BatchVerifier } +func NewBatchVerifier() *BatchVerifier { return &BatchVerifier{ed25519.NewBatchVerifier()} } -func (pubKey PubKey) Equals(other PubKey) bool { - return bytes.Equal(pubKey[:], other[:]) +func (b *BatchVerifier) Add(key PubKey, msg []byte, sig Sig) { + cachingVerifier.AddWithOptions(b.inner, key[:], msg, sig[:], verifyOptions) } -// BatchVerifier implements batch verification for ed25519. -type BatchVerifier struct { - *ed25519.BatchVerifier +type ErrBadSig struct { + Idx int // Index of the first invalid signature. } -func NewBatchVerifier() *BatchVerifier { - return &BatchVerifier{ed25519.NewBatchVerifier()} +func (e ErrBadSig) Error() string { + return fmt.Sprintf("invalid %vth signature",e.Idx) } -func (b *BatchVerifier) Add(key PubKey, msg, signature []byte) error { - pkBytes := key.Bytes() - - if l := len(pkBytes); l != PubKeySize { - return fmt.Errorf("pubkey size is incorrect; expected: %d, got %d", PubKeySize, l) +// Verify verifies the batched signatures using OS entropy. +// If any signature is invalid, returns ErrBadSig with an index +// of the first invalid signature. +func (b *BatchVerifier) Verify() error { + ok,res := b.inner.Verify(rand.Reader) + if ok { + return nil } - - // check that the signature is the correct length - if len(signature) != SignatureSize { - return errors.New("invalid signature") + for idx,ok := range res { + if !ok { + return ErrBadSig{idx} + } } - - cachingVerifier.AddWithOptions(b.BatchVerifier, ed25519.PublicKey(pkBytes), msg, signature, verifyOptions) - - return nil -} - -func (b *BatchVerifier) Verify() (bool, []bool) { - return b.BatchVerifier.Verify(rand.Reader) -} - -func addressHash(bz []byte) tmbytes.HexBytes { - h := sha256.Sum256(bz) - return tmbytes.HexBytes(h[:20]) + panic("unreachable") } diff --git a/sei-tendermint/crypto/ed25519/ed25519_test.go b/sei-tendermint/crypto/ed25519/ed25519_test.go index a6acafc580..578667795d 100644 --- a/sei-tendermint/crypto/ed25519/ed25519_test.go +++ b/sei-tendermint/crypto/ed25519/ed25519_test.go @@ -16,17 +16,16 @@ func TestSignAndValidateEd25519(t *testing.T) { pubKey := privKey.PubKey() msg := crypto.CRandBytes(128) - sig, err := privKey.Sign(msg) - require.NoError(t, err) + sig := privKey.Sign(msg) // Test the signature - assert.True(t, pubKey.VerifySignature(msg, sig)) + assert.NoError(t, pubKey.Verify(msg, sig)) // Mutate the signature, just one bit. // TODO: Replace this with a much better fuzzer, tendermint/ed25519/issues/10 sig[7] ^= byte(0x01) - assert.False(t, pubKey.VerifySignature(msg, sig)) + assert.Error(t, pubKey.Verify(msg, sig)) } func TestBatchSafe(t *testing.T) { @@ -43,13 +42,8 @@ func TestBatchSafe(t *testing.T) { msg = []byte("egg") } - sig, err := priv.Sign(msg) - require.NoError(t, err) - - err = v.Add(pub, msg, sig) - require.NoError(t, err) + v.Add(pub, msg, priv.Sign(msg)) } - ok, _ := v.Verify() - require.True(t, ok) + require.NoError(t,v.Verify()) } diff --git a/sei-tendermint/internal/roles/validator/msg.go b/sei-tendermint/internal/roles/validator/msg.go new file mode 100644 index 0000000000..92dd907a8c --- /dev/null +++ b/sei-tendermint/internal/roles/validator/msg.go @@ -0,0 +1,27 @@ +package validator + +import ( + "github.com/tendermint/tendermint/libs/utils" + "github.com/tendermint/tendermint/crypto/ed25519" +) + +type Msg interface { isMsg() } + +type SessionID struct { + utils.ReadOnly + raw [10]byte +} + +func (s *SessionID) Raw() [10]byte { return s.raw } + +func (s *SessionID) isMsg() {} + +type Sig struct { + ed25519.Signature +} + +type Signed[M Msg] struct { + utils.ReadOnly + msg M + sig Sig +} diff --git a/sei-tendermint/internal/roles/validator/pb/validator.hashable.go b/sei-tendermint/internal/roles/validator/pb/validator.hashable.go new file mode 100644 index 0000000000..81d810592a --- /dev/null +++ b/sei-tendermint/internal/roles/validator/pb/validator.hashable.go @@ -0,0 +1,4 @@ +// Code generated by sei-tendermint/hashable/plugin. DO NOT EDIT. +package pb + +func (*Msg) IsHashable() {} diff --git a/sei-tendermint/internal/roles/validator/pb/validator.pb.go b/sei-tendermint/internal/roles/validator/pb/validator.pb.go new file mode 100644 index 0000000000..703295036a --- /dev/null +++ b/sei-tendermint/internal/roles/validator/pb/validator.pb.go @@ -0,0 +1,314 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.10 +// protoc (unknown) +// source: roles/validator/validator.proto + +package pb + +import ( + _ "github.com/tendermint/tendermint/internal/hashable/pb" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Msg struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Kind: + // + // *Msg_SessionId + Kind isMsg_Kind `protobuf_oneof:"kind"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Msg) Reset() { + *x = Msg{} + mi := &file_roles_validator_validator_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Msg) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Msg) ProtoMessage() {} + +func (x *Msg) ProtoReflect() protoreflect.Message { + mi := &file_roles_validator_validator_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Msg.ProtoReflect.Descriptor instead. +func (*Msg) Descriptor() ([]byte, []int) { + return file_roles_validator_validator_proto_rawDescGZIP(), []int{0} +} + +func (x *Msg) GetKind() isMsg_Kind { + if x != nil { + return x.Kind + } + return nil +} + +func (x *Msg) GetSessionId() []byte { + if x != nil { + if x, ok := x.Kind.(*Msg_SessionId); ok { + return x.SessionId + } + } + return nil +} + +type isMsg_Kind interface { + isMsg_Kind() +} + +type Msg_SessionId struct { + // Encrypted session key to sign in handshake to prove + // that we are a validator. + SessionId []byte `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3,oneof"` +} + +func (*Msg_SessionId) isMsg_Kind() {} + +type PublicKey struct { + state protoimpl.MessageState `protogen:"open.v1"` + Ed25519 []byte `protobuf:"bytes,1,opt,name=ed25519,proto3" json:"ed25519,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PublicKey) Reset() { + *x = PublicKey{} + mi := &file_roles_validator_validator_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PublicKey) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PublicKey) ProtoMessage() {} + +func (x *PublicKey) ProtoReflect() protoreflect.Message { + mi := &file_roles_validator_validator_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PublicKey.ProtoReflect.Descriptor instead. +func (*PublicKey) Descriptor() ([]byte, []int) { + return file_roles_validator_validator_proto_rawDescGZIP(), []int{1} +} + +func (x *PublicKey) GetEd25519() []byte { + if x != nil { + return x.Ed25519 + } + return nil +} + +type Signature struct { + state protoimpl.MessageState `protogen:"open.v1"` + Ed25519 []byte `protobuf:"bytes,1,opt,name=ed25519,proto3" json:"ed25519,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Signature) Reset() { + *x = Signature{} + mi := &file_roles_validator_validator_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Signature) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Signature) ProtoMessage() {} + +func (x *Signature) ProtoReflect() protoreflect.Message { + mi := &file_roles_validator_validator_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Signature.ProtoReflect.Descriptor instead. +func (*Signature) Descriptor() ([]byte, []int) { + return file_roles_validator_validator_proto_rawDescGZIP(), []int{2} +} + +func (x *Signature) GetEd25519() []byte { + if x != nil { + return x.Ed25519 + } + return nil +} + +type SignedMsg struct { + state protoimpl.MessageState `protogen:"open.v1"` + Msg *Msg `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"` + Key *PublicKey `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` + Sig *Signature `protobuf:"bytes,3,opt,name=sig,proto3" json:"sig,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SignedMsg) Reset() { + *x = SignedMsg{} + mi := &file_roles_validator_validator_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SignedMsg) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignedMsg) ProtoMessage() {} + +func (x *SignedMsg) ProtoReflect() protoreflect.Message { + mi := &file_roles_validator_validator_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignedMsg.ProtoReflect.Descriptor instead. +func (*SignedMsg) Descriptor() ([]byte, []int) { + return file_roles_validator_validator_proto_rawDescGZIP(), []int{3} +} + +func (x *SignedMsg) GetMsg() *Msg { + if x != nil { + return x.Msg + } + return nil +} + +func (x *SignedMsg) GetKey() *PublicKey { + if x != nil { + return x.Key + } + return nil +} + +func (x *SignedMsg) GetSig() *Signature { + if x != nil { + return x.Sig + } + return nil +} + +var File_roles_validator_validator_proto protoreflect.FileDescriptor + +const file_roles_validator_validator_proto_rawDesc = "" + + "\n" + + "\x1froles/validator/validator.proto\x12\x0froles.validator\x1a\x17hashable/hashable.proto\"6\n" + + "\x03Msg\x12\x1f\n" + + "\n" + + "session_id\x18\x01 \x01(\fH\x00R\tsessionId:\x06Ȉ\xe2\xab\f\x01B\x06\n" + + "\x04kind\"%\n" + + "\tPublicKey\x12\x18\n" + + "\aed25519\x18\x01 \x01(\fR\aed25519\"%\n" + + "\tSignature\x12\x18\n" + + "\aed25519\x18\x01 \x01(\fR\aed25519\"\x8f\x01\n" + + "\tSignedMsg\x12&\n" + + "\x03msg\x18\x01 \x01(\v2\x14.roles.validator.MsgR\x03msg\x12,\n" + + "\x03key\x18\x02 \x01(\v2\x1a.roles.validator.PublicKeyR\x03key\x12,\n" + + "\x03sig\x18\x03 \x01(\v2\x1a.roles.validator.SignatureR\x03sigB>Z roles.validator.Msg + 1, // 1: roles.validator.SignedMsg.key:type_name -> roles.validator.PublicKey + 2, // 2: roles.validator.SignedMsg.sig:type_name -> roles.validator.Signature + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_roles_validator_validator_proto_init() } +func file_roles_validator_validator_proto_init() { + if File_roles_validator_validator_proto != nil { + return + } + file_roles_validator_validator_proto_msgTypes[0].OneofWrappers = []any{ + (*Msg_SessionId)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_roles_validator_validator_proto_rawDesc), len(file_roles_validator_validator_proto_rawDesc)), + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_roles_validator_validator_proto_goTypes, + DependencyIndexes: file_roles_validator_validator_proto_depIdxs, + MessageInfos: file_roles_validator_validator_proto_msgTypes, + }.Build() + File_roles_validator_validator_proto = out.File + file_roles_validator_validator_proto_goTypes = nil + file_roles_validator_validator_proto_depIdxs = nil +} diff --git a/sei-tendermint/internal/roles/validator/validator.proto b/sei-tendermint/internal/roles/validator/validator.proto new file mode 100644 index 0000000000..cd180bb0c0 --- /dev/null +++ b/sei-tendermint/internal/roles/validator/validator.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; + +package roles.validator; + +import "hashable/hashable.proto"; + +option go_package = "github.com/tendermint/tendermint/internal/roles/validator/pb"; + +message Msg { + option (hashable.hashable) = true; + oneof kind { + // Encrypted session key to sign in handshake to prove + // that we are a validator. + bytes session_id = 1; + } +} + +message PublicKey { + bytes ed25519 = 1; +} + +message Signature { + bytes ed25519 = 1; +} + +message SignedMsg { + Msg msg = 1; + PublicKey key = 2; + Signature sig = 3; +} diff --git a/sei-tendermint/libs/utils/option.go b/sei-tendermint/libs/utils/option.go index 85fd6a471c..d72ab906f2 100644 --- a/sei-tendermint/libs/utils/option.go +++ b/sei-tendermint/libs/utils/option.go @@ -27,6 +27,7 @@ func (o Option[T]) Get() (T, bool) { return Zero[T](), false } + // IsPresent checks if the Option contains a value. func (o Option[T]) IsPresent() bool { return o.isPresent @@ -40,6 +41,13 @@ func (o *Option[T]) Or(def T) T { return def } +func (o Option[T]) OrPanic() T { + if o.isPresent { + return o.value + } + panic("value missing") +} + // MapOpt applies a function to the value if present, returning a new Option. func MapOpt[T, R any](o Option[T], f func(T) R) Option[R] { if o.isPresent { diff --git a/sei-tendermint/libs/utils/proto.go b/sei-tendermint/libs/utils/proto.go index bff1474408..aac3ee4981 100644 --- a/sei-tendermint/libs/utils/proto.go +++ b/sei-tendermint/libs/utils/proto.go @@ -4,10 +4,11 @@ import ( "errors" "fmt" "sync" - + "golang.org/x/exp/constraints" "github.com/gogo/protobuf/proto" ) + func ErrorAs[T error](err error) Option[T] { var target T if errors.As(err, &target) { @@ -16,14 +17,8 @@ func ErrorAs[T error](err error) Option[T] { return None[T]() } -// Int is a type constraint for integer types. -type Int interface { - ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uint | - ~int8 | ~int16 | ~int32 | ~int64 | ~int -} - // SafeCast casts between integer types, checking for overflows. -func SafeCast[To Int, From Int](v From) (x To, ok bool) { +func SafeCast[To constraints.Integer, From constraints.Integer](v From) (x To, ok bool) { x = To(v) // This can be further optimized by: // * making compiler detect if From -> To conversion is always safe diff --git a/sei-tendermint/types/validation.go b/sei-tendermint/types/validation.go index adf1fcff31..45e183140b 100644 --- a/sei-tendermint/types/validation.go +++ b/sei-tendermint/types/validation.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/libs/utils" tmmath "github.com/tendermint/tendermint/libs/math" ) @@ -205,9 +206,11 @@ func verifyCommitBatch( voteSignBytes := commit.VoteSignBytes(chainID, int32(idx)) // add the key, sig and message to the verifier - if err := bv.Add(val.PubKey, voteSignBytes, commitSig.Signature); err != nil { - return err + sig,err := crypto.SigFromBytes(commitSig.Signature) + if err!=nil { + return fmt.Errorf("crypto.SigFromBytes(): %w",err) } + bv.Add(val.PubKey, voteSignBytes, sig) batchSigIdxs = append(batchSigIdxs, idx) // If this signature counts then add the voting power of the validator @@ -230,28 +233,14 @@ func verifyCommitBatch( } // attempt to verify the batch. - ok, validSigs := bv.Verify() - if ok { - // success - return nil + if err := bv.Verify(); err!=nil { + err := utils.ErrorAs[crypto.ErrBadSig](err).OrPanic() + // go back from the batch index to the commit.Signatures index + idx := batchSigIdxs[err.Idx] + sig := commit.Signatures[idx] + return errBadSig{fmt.Errorf("wrong signature (#%d): %X", idx, sig)} } - - // one or more of the signatures is invalid, find and return the first - // invalid signature. - for i, ok := range validSigs { - if !ok { - // go back from the batch index to the commit.Signatures index - idx := batchSigIdxs[i] - sig := commit.Signatures[idx] - return errBadSig{fmt.Errorf("wrong signature (#%d): %X", idx, sig)} - } - } - - // execution reaching here is a bug, and one of the following has - // happened: - // * non-zero tallied voting power, empty batch (impossible?) - // * bv.Verify() returned `false, []bool{true, ..., true}` (BUG) - return fmt.Errorf("BUG: batch verification failed with no invalid signatures") + return nil } // Single Verification @@ -306,8 +295,11 @@ func verifyCommitSingle( } voteSignBytes = commit.VoteSignBytes(chainID, int32(idx)) - - if !val.PubKey.VerifySignature(voteSignBytes, commitSig.Signature) { + sig,err := crypto.SigFromBytes(commitSig.Signature) + if err!=nil { + return fmt.Errorf("crypto.SigFromBytes(): %w",err) + } + if err := val.PubKey.Verify(voteSignBytes, sig); err!=nil { return errBadSig{fmt.Errorf("wrong signature (#%d): %X", idx, commitSig.Signature)} } From e57107514ab23a873bcb24d6e33a391c76d937c6 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Mon, 15 Dec 2025 16:19:24 +0100 Subject: [PATCH 21/53] missing changes --- .../hashable/internal/pb/testonly.hashable.go | 2 +- .../hashable/internal/pb/testonly.pb.go | 34 +++++++++---------- .../internal/hashable/internal/testonly.proto | 2 +- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/sei-tendermint/internal/hashable/internal/pb/testonly.hashable.go b/sei-tendermint/internal/hashable/internal/pb/testonly.hashable.go index da8e144207..92a33a49f9 100644 --- a/sei-tendermint/internal/hashable/internal/pb/testonly.hashable.go +++ b/sei-tendermint/internal/hashable/internal/pb/testonly.hashable.go @@ -1,4 +1,4 @@ -// Code generated by buf_plugin. DO NOT EDIT. +// Code generated by sei-tendermint/hashable/plugin. DO NOT EDIT. package pb func (*TestonlyNested) IsHashable() {} diff --git a/sei-tendermint/internal/hashable/internal/pb/testonly.pb.go b/sei-tendermint/internal/hashable/internal/pb/testonly.pb.go index 9436e59893..f6620d2197 100644 --- a/sei-tendermint/internal/hashable/internal/pb/testonly.pb.go +++ b/sei-tendermint/internal/hashable/internal/pb/testonly.pb.go @@ -156,7 +156,7 @@ func (*TestonlyNested_Value) isTestonlyNested_T() {} type TestonlyMsg struct { state protoimpl.MessageState `protogen:"open.v1"` BoolValue *bool `protobuf:"varint,1,opt,name=bool_value,json=boolValue,proto3,oneof" json:"bool_value,omitempty"` - EnumValue *TestonlyEnum `protobuf:"varint,2,opt,name=enum_value,json=enumValue,proto3,enum=internal.TestonlyEnum,oneof" json:"enum_value,omitempty"` + EnumValue *TestonlyEnum `protobuf:"varint,2,opt,name=enum_value,json=enumValue,proto3,enum=hashable.internal.TestonlyEnum,oneof" json:"enum_value,omitempty"` Int32Value *int32 `protobuf:"varint,3,opt,name=int32_value,json=int32Value,proto3,oneof" json:"int32_value,omitempty"` Int64Value *int64 `protobuf:"varint,4,opt,name=int64_value,json=int64Value,proto3,oneof" json:"int64_value,omitempty"` Sint32Value *int32 `protobuf:"zigzag32,5,opt,name=sint32_value,json=sint32Value,proto3,oneof" json:"sint32_value,omitempty"` @@ -369,17 +369,17 @@ var File_hashable_internal_testonly_proto protoreflect.FileDescriptor const file_hashable_internal_testonly_proto_rawDesc = "" + "\n" + - " hashable/internal/testonly.proto\x12\binternal\x1a\x17hashable/hashable.proto\"K\n" + + " hashable/internal/testonly.proto\x12\x11hashable.internal\x1a\x17hashable/hashable.proto\"K\n" + "\x0eTestonlyNested\x12\x14\n" + "\x04note\x18\x01 \x01(\tH\x00R\x04note\x12\x16\n" + "\x05value\x18\x02 \x01(\rH\x00R\x05value:\x06Ȉ\xe2\xab\f\x01B\x03\n" + - "\x01t\"\xb7\n" + + "\x01t\"\xdb\n" + "\n" + "\vTestonlyMsg\x12\"\n" + "\n" + - "bool_value\x18\x01 \x01(\bH\x00R\tboolValue\x88\x01\x01\x12:\n" + + "bool_value\x18\x01 \x01(\bH\x00R\tboolValue\x88\x01\x01\x12C\n" + "\n" + - "enum_value\x18\x02 \x01(\x0e2\x16.internal.TestonlyEnumH\x01R\tenumValue\x88\x01\x01\x12$\n" + + "enum_value\x18\x02 \x01(\x0e2\x1f.hashable.internal.TestonlyEnumH\x01R\tenumValue\x88\x01\x01\x12$\n" + "\vint32_value\x18\x03 \x01(\x05H\x02R\n" + "int32Value\x88\x01\x01\x12$\n" + "\vint64_value\x18\x04 \x01(\x03H\x03R\n" + @@ -396,12 +396,12 @@ const file_hashable_internal_testonly_proto_rawDesc = "" + "\x0esfixed64_value\x18\f \x01(\x10H\vR\rsfixed64Value\x88\x01\x01\x12$\n" + "\vbytes_value\x18\r \x01(\fH\fR\n" + "bytesValue\x88\x01\x01\x12&\n" + - "\fstring_value\x18\x0e \x01(\tH\rR\vstringValue\x88\x01\x01\x12B\n" + - "\rmessage_value\x18\x0f \x01(\v2\x18.internal.TestonlyNestedH\x0eR\fmessageValue\x88\x01\x01\x12+\n" + + "\fstring_value\x18\x0e \x01(\tH\rR\vstringValue\x88\x01\x01\x12K\n" + + "\rmessage_value\x18\x0f \x01(\v2!.hashable.internal.TestonlyNestedH\x0eR\fmessageValue\x88\x01\x01\x12+\n" + "\x11repeated_packable\x18\x10 \x03(\x12R\x10repeatedPackable\x12'\n" + - "\x0frepeated_string\x18\x11 \x03(\tR\x0erepeatedString\x12C\n" + - "\x10repeated_message\x18\x12 \x03(\v2\x18.internal.TestonlyNestedR\x0frepeatedMessage\x12H\n" + - "\x10optional_message\x18\x13 \x01(\v2\x18.internal.TestonlyNestedH\x0fR\x0foptionalMessage\x88\x01\x01\x12>\n" + + "\x0frepeated_string\x18\x11 \x03(\tR\x0erepeatedString\x12L\n" + + "\x10repeated_message\x18\x12 \x03(\v2!.hashable.internal.TestonlyNestedR\x0frepeatedMessage\x12Q\n" + + "\x10optional_message\x18\x13 \x01(\v2!.hashable.internal.TestonlyNestedH\x0fR\x0foptionalMessage\x88\x01\x01\x12>\n" + "\x1brepeated_packable_singleton\x18\x14 \x03(\aR\x19repeatedPackableSingleton\x12%\n" + "\x0erepeated_bytes\x18\x15 \x03(\fR\rrepeatedBytes\x126\n" + "\x17repeated_packable_empty\x18\x16 \x03(\x04R\x15repeatedPackableEmpty:\x06Ȉ\xe2\xab\f\x01B\r\n" + @@ -441,15 +441,15 @@ func file_hashable_internal_testonly_proto_rawDescGZIP() []byte { var file_hashable_internal_testonly_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_hashable_internal_testonly_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_hashable_internal_testonly_proto_goTypes = []any{ - (TestonlyEnum)(0), // 0: internal.TestonlyEnum - (*TestonlyNested)(nil), // 1: internal.TestonlyNested - (*TestonlyMsg)(nil), // 2: internal.TestonlyMsg + (TestonlyEnum)(0), // 0: hashable.internal.TestonlyEnum + (*TestonlyNested)(nil), // 1: hashable.internal.TestonlyNested + (*TestonlyMsg)(nil), // 2: hashable.internal.TestonlyMsg } var file_hashable_internal_testonly_proto_depIdxs = []int32{ - 0, // 0: internal.TestonlyMsg.enum_value:type_name -> internal.TestonlyEnum - 1, // 1: internal.TestonlyMsg.message_value:type_name -> internal.TestonlyNested - 1, // 2: internal.TestonlyMsg.repeated_message:type_name -> internal.TestonlyNested - 1, // 3: internal.TestonlyMsg.optional_message:type_name -> internal.TestonlyNested + 0, // 0: hashable.internal.TestonlyMsg.enum_value:type_name -> hashable.internal.TestonlyEnum + 1, // 1: hashable.internal.TestonlyMsg.message_value:type_name -> hashable.internal.TestonlyNested + 1, // 2: hashable.internal.TestonlyMsg.repeated_message:type_name -> hashable.internal.TestonlyNested + 1, // 3: hashable.internal.TestonlyMsg.optional_message:type_name -> hashable.internal.TestonlyNested 4, // [4:4] is the sub-list for method output_type 4, // [4:4] is the sub-list for method input_type 4, // [4:4] is the sub-list for extension type_name diff --git a/sei-tendermint/internal/hashable/internal/testonly.proto b/sei-tendermint/internal/hashable/internal/testonly.proto index aa34e166d4..8e8c2ddc96 100644 --- a/sei-tendermint/internal/hashable/internal/testonly.proto +++ b/sei-tendermint/internal/hashable/internal/testonly.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -package internal; +package hashable.internal; import "hashable/hashable.proto"; From bf6e99999e5c36618f73d9be5cd01e9644da5911 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Mon, 15 Dec 2025 16:21:33 +0100 Subject: [PATCH 22/53] compilation fix --- sei-tendermint/internal/hashable/hashable_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sei-tendermint/internal/hashable/hashable_test.go b/sei-tendermint/internal/hashable/hashable_test.go index 3cc6420bc0..7254cc88fd 100644 --- a/sei-tendermint/internal/hashable/hashable_test.go +++ b/sei-tendermint/internal/hashable/hashable_test.go @@ -9,7 +9,7 @@ import ( "google.golang.org/protobuf/proto" - "github.com/tendermint/tendermint/libs/hashable/internal/pb" + "github.com/tendermint/tendermint/internal/hashable/internal/pb" "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/libs/utils/require" ) From 9a3edcb6045316cfd645ce4c05d9145fd666489a Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Mon, 15 Dec 2025 17:35:11 +0100 Subject: [PATCH 23/53] wip - what about non-validator mode? --- .../abci/example/kvstore/kvstore.go | 6 +- sei-tendermint/abci/types/pubkey.go | 9 +-- sei-tendermint/abci/types/types.go | 6 +- sei-tendermint/crypto/ed25519/ed25519.go | 16 +++-- sei-tendermint/crypto/encoding/codec.go | 20 ++---- sei-tendermint/internal/consensus/state.go | 23 ++++--- .../consensus/types/height_vote_set_test.go | 4 +- sei-tendermint/internal/evidence/verify.go | 4 +- .../internal/p2p/conn/secret_connection.go | 61 ++++++++----------- .../internal/roles/validator/msg.go | 4 +- sei-tendermint/internal/rpc/core/status.go | 14 ++--- .../internal/test/factory/commit.go | 8 ++- sei-tendermint/internal/test/factory/vote.go | 7 ++- sei-tendermint/node/node.go | 12 ++-- sei-tendermint/node/setup.go | 6 +- sei-tendermint/privval/file.go | 18 ++---- sei-tendermint/privval/grpc/client.go | 4 +- sei-tendermint/privval/grpc/server.go | 9 +-- sei-tendermint/privval/retry_signer_client.go | 6 +- sei-tendermint/privval/secret_connection.go | 40 +++++------- sei-tendermint/privval/signer_client.go | 8 +-- .../privval/signer_requestHandler.go | 6 +- sei-tendermint/test/e2e/pkg/testnet.go | 7 +-- sei-tendermint/test/e2e/runner/evidence.go | 4 +- sei-tendermint/test/e2e/runner/setup.go | 3 +- sei-tendermint/types/block.go | 18 +++--- sei-tendermint/types/evidence.go | 8 ++- sei-tendermint/types/priv_validator.go | 16 ++--- sei-tendermint/types/proposal.go | 21 +++---- sei-tendermint/types/protobuf.go | 8 +-- sei-tendermint/types/signable.go | 12 ---- sei-tendermint/types/test_util.go | 10 ++- sei-tendermint/types/validation.go | 12 +--- sei-tendermint/types/validator.go | 28 ++------- sei-tendermint/types/vote.go | 22 +++---- sei-tendermint/types/vote_set.go | 2 +- 36 files changed, 183 insertions(+), 279 deletions(-) delete mode 100644 sei-tendermint/types/signable.go diff --git a/sei-tendermint/abci/example/kvstore/kvstore.go b/sei-tendermint/abci/example/kvstore/kvstore.go index bd28d95070..5b7fc798e1 100644 --- a/sei-tendermint/abci/example/kvstore/kvstore.go +++ b/sei-tendermint/abci/example/kvstore/kvstore.go @@ -332,7 +332,7 @@ func MakeValSetChangeTx(pubkey cryptoproto.PublicKey, power int64) []byte { if err != nil { panic(err) } - pubStr := base64.StdEncoding.EncodeToString(pk.Bytes()) + pubStr := base64.StdEncoding.EncodeToString(pk[:]) return []byte(fmt.Sprintf("val:%s!%d", pubStr, power)) } @@ -380,7 +380,7 @@ func (app *Application) updateValidator(v types.ValidatorUpdate) *types.ExecTxRe if err != nil { panic(fmt.Errorf("can't decode public key: %w", err)) } - key := []byte("val:" + string(pubkey.Bytes())) + key := []byte("val:" + string(pubkey[:])) if v.Power == 0 { // remove validator @@ -389,7 +389,7 @@ func (app *Application) updateValidator(v types.ValidatorUpdate) *types.ExecTxRe panic(err) } if !hasKey { - pubStr := base64.StdEncoding.EncodeToString(pubkey.Bytes()) + pubStr := base64.StdEncoding.EncodeToString(pubkey[:]) return &types.ExecTxResult{ Code: code.CodeTypeUnauthorized, Log: fmt.Sprintf("Cannot remove non-existent validator %s", pubStr)} diff --git a/sei-tendermint/abci/types/pubkey.go b/sei-tendermint/abci/types/pubkey.go index 2b08dbbdbe..36d755bb5b 100644 --- a/sei-tendermint/abci/types/pubkey.go +++ b/sei-tendermint/abci/types/pubkey.go @@ -8,15 +8,8 @@ import ( ) func Ed25519ValidatorUpdate(pk []byte, power int64) ValidatorUpdate { - pke := ed25519.PubKey(pk) - - pkp, err := encoding.PubKeyToProto(pke) - if err != nil { - panic(err) - } - return ValidatorUpdate{ - PubKey: pkp, + PubKey: encoding.PubKeyToProto(ed25519.PubKey(pk)), Power: power, } } diff --git a/sei-tendermint/abci/types/types.go b/sei-tendermint/abci/types/types.go index 902833e087..c9bc0f8153 100644 --- a/sei-tendermint/abci/types/types.go +++ b/sei-tendermint/abci/types/types.go @@ -156,11 +156,7 @@ func (v *ValidatorUpdate) UnmarshalJSON(data []byte) error { if err := jsontypes.Unmarshal(vu.PubKey, &key); err != nil { return err } - pkey, err := encoding.PubKeyToProto(key) - if err != nil { - return err - } - v.PubKey = pkey + v.PubKey = encoding.PubKeyToProto(key) v.Power = vu.Power return nil } diff --git a/sei-tendermint/crypto/ed25519/ed25519.go b/sei-tendermint/crypto/ed25519/ed25519.go index 17ee96fd1d..ee451a005e 100644 --- a/sei-tendermint/crypto/ed25519/ed25519.go +++ b/sei-tendermint/crypto/ed25519/ed25519.go @@ -38,6 +38,8 @@ func init() { jsontypes.MustRegister(PubKey{}) } +type Seed [ed25519.SeedSize]byte + type PrivKey struct { raw ed25519.PrivateKey // ed25519.PrivateKey is a slice, therefore the secret will not be copied around. } @@ -68,7 +70,7 @@ func (k PrivKey) Type() string { return KeyType } // GenPrivKey generates a new ed25519 private key from OS entropy. func GenPrivKey() PrivKey { - var seed [ed25519.SeedSize]byte + var seed Seed if _,err := io.ReadFull(rand.Reader,seed[:]); err != nil { panic(err) } @@ -76,7 +78,7 @@ func GenPrivKey() PrivKey { } // PrivKeyFromSeed constructs a private key from seed. -func PrivKeyFromSeed(seed [ed25519.SeedSize]byte) PrivKey { +func PrivKeyFromSeed(seed Seed) PrivKey { return PrivKey{ed25519.NewKeyFromSeed(seed[:])} } @@ -85,6 +87,13 @@ func PrivKeyFromSeed(seed [ed25519.SeedSize]byte) PrivKey { // PubKey implements the Ed25519 signature scheme. type PubKey [ed25519.PublicKeySize]byte +func PubKeyFromBytes(raw []byte) (PubKey,error) { + if len(raw)!=len(PubKey{}) { + return PubKey{},errors.New("invalid signature length") + } + return PubKey(raw),nil +} + // TypeTag satisfies the jsontypes.Tagged interface. func (PubKey) TypeTag() string { return PubKeyName } @@ -94,9 +103,6 @@ func (k PubKey) Address() tmbytes.HexBytes { return tmbytes.HexBytes(h[:20]) } -// Bytes returns the PubKey byte format. -func (k PubKey) Bytes() []byte { return k[:] } - func (k PubKey) Verify(msg []byte, sig Sig) error { if !cachingVerifier.VerifyWithOptions(k[:], msg, sig[:], verifyOptions) { return errors.New("invalid signature") diff --git a/sei-tendermint/crypto/encoding/codec.go b/sei-tendermint/crypto/encoding/codec.go index c5891c4eef..e13a91f8ad 100644 --- a/sei-tendermint/crypto/encoding/codec.go +++ b/sei-tendermint/crypto/encoding/codec.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/internal/jsontypes" cryptoproto "github.com/tendermint/tendermint/proto/tendermint/crypto" ) @@ -15,26 +14,19 @@ func init() { } // PubKeyToProto takes crypto.PubKey and transforms it to a protobuf Pubkey -func PubKeyToProto(k crypto.PubKey) (cryptoproto.PublicKey, error) { - pk := make([]byte, len(k)) - copy(pk, k.Bytes()) - return cryptoproto.PublicKey{ - Sum: &cryptoproto.PublicKey_Ed25519{Ed25519: pk}, - }, nil +func PubKeyToProto(k crypto.PubKey) cryptoproto.PublicKey { + return cryptoproto.PublicKey{Sum: &cryptoproto.PublicKey_Ed25519{Ed25519: k[:]}} } // PubKeyFromProto takes a protobuf Pubkey and transforms it to a crypto.Pubkey func PubKeyFromProto(k cryptoproto.PublicKey) (crypto.PubKey, error) { switch k := k.Sum.(type) { case *cryptoproto.PublicKey_Ed25519: - if len(k.Ed25519) != ed25519.PubKeySize { - return nil, fmt.Errorf("invalid size for PubKeyEd25519. Got %d, expected %d", - len(k.Ed25519), ed25519.PubKeySize) + if got,want:=len(k.Ed25519),len(crypto.PubKey{}); got!=want { + return crypto.PubKey{}, fmt.Errorf("invalid size for PubKeyEd25519. Got %d, expected %d",got,want) } - pk := make(ed25519.PubKey, ed25519.PubKeySize) - copy(pk, k.Ed25519) - return pk, nil + return crypto.PubKey(k.Ed25519), nil default: - return nil, fmt.Errorf("fromproto: key type %v is not supported", k) + return crypto.PubKey{}, fmt.Errorf("fromproto: key type %v is not supported", k) } } diff --git a/sei-tendermint/internal/consensus/state.go b/sei-tendermint/internal/consensus/state.go index f34d043ada..ad99929972 100644 --- a/sei-tendermint/internal/consensus/state.go +++ b/sei-tendermint/internal/consensus/state.go @@ -1268,7 +1268,12 @@ func (cs *State) decideProposal(ctx context.Context, height int64, round int32, ctxto, cancel := context.WithTimeout(ctx, cs.state.ConsensusParams.Timeout.Propose) defer cancel() if err := privValidator.SignProposal(ctxto, cs.state.ChainID, p); err == nil { - proposal.Signature = p.Signature + sig,err := crypto.SigFromBytes(p.Signature) + if err!=nil { + cs.logger.Error("propose step; failed signing proposal", "height", height, "round", round, "err", err) + return + } + proposal.Signature = sig // send proposal and block parts on internal msg queue cs.sendInternalMessage(ctx, msgInfo{&ProposalMessage{proposal}, "", tmtime.Now()}) @@ -2147,13 +2152,11 @@ func (cs *State) defaultSetProposal(proposal *types.Proposal, recvTime time.Time p := proposal.ToProto() // Verify signature - if !cs.roundState.Validators().GetProposer().PubKey.VerifySignature( + if err:=cs.roundState.Validators().GetProposer().PubKey.Verify( types.ProposalSignBytes(cs.state.ChainID, p), proposal.Signature, - ) { + ); err!=nil { return ErrInvalidProposalSignature } - - proposal.Signature = p.Signature cs.roundState.SetProposal(proposal) cs.roundState.SetProposalReceiveTime(recvTime) cs.calculateProposalTimestampDifferenceMetric() @@ -2611,11 +2614,15 @@ func (cs *State) signVote( ctxto, cancel := context.WithTimeout(ctx, timeout) defer cancel() - err := privValidator.SignVote(ctxto, cs.state.ChainID, v) - vote.Signature = v.Signature + if err := privValidator.SignVote(ctxto, cs.state.ChainID, v); err!=nil { + return nil,err + } + sig,err := crypto.SigFromBytes(v.Signature) + if err!=nil { return nil,fmt.Errorf("crypto.SigFromBytes(): %w",err) } + vote.Signature = sig vote.Timestamp = v.Timestamp - return vote, err + return vote, nil } // sign the vote and publish on internalMsgQueue diff --git a/sei-tendermint/internal/consensus/types/height_vote_set_test.go b/sei-tendermint/internal/consensus/types/height_vote_set_test.go index 38a65bec6d..b92dfc7b98 100644 --- a/sei-tendermint/internal/consensus/types/height_vote_set_test.go +++ b/sei-tendermint/internal/consensus/types/height_vote_set_test.go @@ -86,7 +86,9 @@ func makeVoteHR( err = privVal.SignVote(ctx, chainID, v) require.NoError(t, err, "Error signing vote") - vote.Signature = v.Signature + sig,err := crypto.SigFromBytes(v.Signature) + require.NoError(t,err) + vote.Signature = sig return vote } diff --git a/sei-tendermint/internal/evidence/verify.go b/sei-tendermint/internal/evidence/verify.go index 9e8f87e65d..938f46be68 100644 --- a/sei-tendermint/internal/evidence/verify.go +++ b/sei-tendermint/internal/evidence/verify.go @@ -243,10 +243,10 @@ func VerifyDuplicateVote(e *types.DuplicateVoteEvidence, chainID string, valSet va := e.VoteA.ToProto() vb := e.VoteB.ToProto() // Signatures must be valid - if !pubKey.VerifySignature(types.VoteSignBytes(chainID, va), e.VoteA.Signature) { + if err := pubKey.Verify(types.VoteSignBytes(chainID, va), e.VoteA.Signature); err!=nil { return fmt.Errorf("verifying VoteA: %w", types.ErrVoteInvalidSignature) } - if !pubKey.VerifySignature(types.VoteSignBytes(chainID, vb), e.VoteB.Signature) { + if err := pubKey.Verify(types.VoteSignBytes(chainID, vb), e.VoteB.Signature); err!=nil { return fmt.Errorf("verifying VoteB: %w", types.ErrVoteInvalidSignature) } diff --git a/sei-tendermint/internal/p2p/conn/secret_connection.go b/sei-tendermint/internal/p2p/conn/secret_connection.go index e147d13066..6d60cc3a17 100644 --- a/sei-tendermint/internal/p2p/conn/secret_connection.go +++ b/sei-tendermint/internal/p2p/conn/secret_connection.go @@ -152,10 +152,7 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey ed25519.PrivKey) ( } // Sign the challenge bytes for authentication. - locSignature, err := signChallenge(&challenge, locPrivKey) - if err != nil { - return nil, err - } + locSignature := signChallenge(&challenge, locPrivKey) // Share (in secret) each other's pubkey & challenge signature authSigMsg, err := shareAuthSignature(sc, locPubKey, locSignature) @@ -165,8 +162,8 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey ed25519.PrivKey) ( remPubKey, remSignature := authSigMsg.Key, authSigMsg.Sig - if !remPubKey.VerifySignature(challenge[:], remSignature) { - return nil, errors.New("challenge verification failed") + if err:=remPubKey.Verify(challenge[:], remSignature); err!=nil { + return nil, fmt.Errorf("challenge verification failed: %w",err) } // We've authorized. @@ -297,7 +294,7 @@ func shareEphPubKey(conn io.ReadWriter, locEphPub *[32]byte) (remEphPub *[32]byt // Send our pubkey and receive theirs in tandem. var trs, _ = async.Parallel( - func(_ int) (val interface{}, abort bool, err error) { + func(_ int) (val any, abort bool, err error) { lc := *locEphPub _, err = protoio.NewDelimitedWriter(conn).WriteMsg(&gogotypes.BytesValue{Value: lc[:]}) if err != nil { @@ -305,7 +302,7 @@ func shareEphPubKey(conn io.ReadWriter, locEphPub *[32]byte) (remEphPub *[32]byt } return nil, false, nil }, - func(_ int) (val interface{}, abort bool, err error) { + func(_ int) (val any, abort bool, err error) { var bytes gogotypes.BytesValue _, err = protoio.NewDelimitedReader(conn, 1024*1024).ReadMsg(&bytes) if err != nil { @@ -383,55 +380,45 @@ func sort32(foo, bar *[32]byte) (lo, hi *[32]byte) { return } -func signChallenge(challenge *[32]byte, locPrivKey ed25519.PrivKey) ([]byte, error) { - signature, err := locPrivKey.Sign(challenge[:]) - if err != nil { - return nil, err - } - return signature, nil +func signChallenge(challenge *[32]byte, locPrivKey ed25519.PrivKey) ed25519.Sig { + return locPrivKey.Sign(challenge[:]) } type authSigMessage struct { Key ed25519.PubKey - Sig []byte + Sig ed25519.Sig } -func shareAuthSignature(sc io.ReadWriter, pubKey ed25519.PubKey, signature []byte) (recvMsg authSigMessage, err error) { - +func shareAuthSignature(sc io.ReadWriter, pubKey ed25519.PubKey, sig ed25519.Sig) (authSigMessage, error) { // Send our info and receive theirs in tandem. var trs, _ = async.Parallel( - func(_ int) (val interface{}, abort bool, err error) { - pk := tmproto.PublicKey{Sum: &tmproto.PublicKey_Ed25519{Ed25519: pubKey}} - _, err = protoio.NewDelimitedWriter(sc).WriteMsg(&tmp2p.AuthSigMessage{PubKey: pk, Sig: signature}) - if err != nil { - return nil, true, err // abort + func(_ int) (val any, abort bool, err error) { + pk := tmproto.PublicKey{Sum: &tmproto.PublicKey_Ed25519{Ed25519: pubKey[:]}} + if _, err := protoio.NewDelimitedWriter(sc).WriteMsg(&tmp2p.AuthSigMessage{PubKey: pk, Sig: sig[:]}); err != nil { + return nil, true, err } return nil, false, nil }, - func(_ int) (val interface{}, abort bool, err error) { + func(_ int) (val any, abort bool, err error) { var pba tmp2p.AuthSigMessage - _, err = protoio.NewDelimitedReader(sc, 1024*1024).ReadMsg(&pba) - if err != nil { - return nil, true, err // abort + if _, err := protoio.NewDelimitedReader(sc, 1024*1024).ReadMsg(&pba); err != nil { + return nil, true, err } - - pk := pba.PubKey.GetEd25519() - if len(pk) != ed25519.PubKeySize { - return nil, true, fmt.Errorf("invalid ed25519 key size") + key,err := ed25519.PubKeyFromBytes(pba.PubKey.GetEd25519()) + if err!=nil { + return nil, true, fmt.Errorf("ed25519.PubKeyFromBytes(): %w",err) } - - _recvMsg := authSigMessage{ - Key: ed25519.PubKey(pk), - Sig: pba.Sig, + sig,err := ed25519.SigFromBytes(pba.Sig) + if err!=nil { + return nil, true, fmt.Errorf("ed25519.SigFromBytes(): %w",err) } - return _recvMsg, false, nil + return authSigMessage{Key: key, Sig: sig}, false, nil }, ) // If error: if trs.FirstError() != nil { - err = trs.FirstError() - return + return authSigMessage{},trs.FirstError() } var _recvMsg = trs.FirstValue().(authSigMessage) diff --git a/sei-tendermint/internal/roles/validator/msg.go b/sei-tendermint/internal/roles/validator/msg.go index 92dd907a8c..9f534d947c 100644 --- a/sei-tendermint/internal/roles/validator/msg.go +++ b/sei-tendermint/internal/roles/validator/msg.go @@ -16,9 +16,7 @@ func (s *SessionID) Raw() [10]byte { return s.raw } func (s *SessionID) isMsg() {} -type Sig struct { - ed25519.Signature -} +type Sig struct { inner ed25519.Sig } type Signed[M Msg] struct { utils.ReadOnly diff --git a/sei-tendermint/internal/rpc/core/status.go b/sei-tendermint/internal/rpc/core/status.go index 870c134248..56c923952e 100644 --- a/sei-tendermint/internal/rpc/core/status.go +++ b/sei-tendermint/internal/rpc/core/status.go @@ -51,13 +51,10 @@ func (env *Environment) Status(ctx context.Context) (*coretypes.ResultStatus, er if val := env.validatorAtHeight(env.latestUncommittedHeight()); val != nil { votingPower = val.VotingPower } - validatorInfo := coretypes.ValidatorInfo{} - if env.PubKey != nil { - validatorInfo = coretypes.ValidatorInfo{ - Address: env.PubKey.Address(), - PubKey: env.PubKey, - VotingPower: votingPower, - } + validatorInfo := coretypes.ValidatorInfo{ + Address: env.PubKey.Address(), + PubKey: env.PubKey, + VotingPower: votingPower, } var applicationInfo coretypes.ApplicationInfo @@ -117,9 +114,6 @@ func (env *Environment) validatorAtHeight(h int64) *types.Validator { if env.ConsensusState == nil { return nil } - if env.PubKey == nil { - return nil - } privValAddress := env.PubKey.Address() // If we're still at height h, search in the current validator set. diff --git a/sei-tendermint/internal/test/factory/commit.go b/sei-tendermint/internal/test/factory/commit.go index 1a8691855e..c9a7b905c9 100644 --- a/sei-tendermint/internal/test/factory/commit.go +++ b/sei-tendermint/internal/test/factory/commit.go @@ -3,14 +3,16 @@ package factory import ( "context" "time" + "fmt" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/crypto" ) func MakeCommit(ctx context.Context, blockID types.BlockID, height int64, round int32, voteSet *types.VoteSet, validators []types.PrivValidator, now time.Time) (*types.Commit, error) { // all sign - for i := 0; i < len(validators); i++ { + for i := range validators { pubKey, err := validators[i].GetPubKey(ctx) if err != nil { return nil, err @@ -30,7 +32,9 @@ func MakeCommit(ctx context.Context, blockID types.BlockID, height int64, round if err := validators[i].SignVote(ctx, voteSet.ChainID(), v); err != nil { return nil, err } - vote.Signature = v.Signature + sig,err := crypto.SigFromBytes(v.Signature) + if err!=nil { return nil, fmt.Errorf("crypto.SigFromBytes(): %w",err) } + vote.Signature = sig if _, err := voteSet.AddVote(vote); err != nil { return nil, err } diff --git a/sei-tendermint/internal/test/factory/vote.go b/sei-tendermint/internal/test/factory/vote.go index fc63e8d681..a455e9bde1 100644 --- a/sei-tendermint/internal/test/factory/vote.go +++ b/sei-tendermint/internal/test/factory/vote.go @@ -3,9 +3,11 @@ package factory import ( "context" "time" + "fmt" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/crypto" ) func MakeVote( @@ -38,7 +40,8 @@ func MakeVote( if err := val.SignVote(ctx, chainID, vpb); err != nil { return nil, err } - - v.Signature = vpb.Signature + sig,err := crypto.SigFromBytes(vpb.Signature) + if err!=nil { return nil, fmt.Errorf("crypto.SigFromBytes(): %w",err) } + v.Signature = sig return v, nil } diff --git a/sei-tendermint/node/node.go b/sei-tendermint/node/node.go index 552da2a98c..b2e93e5f11 100644 --- a/sei-tendermint/node/node.go +++ b/sei-tendermint/node/node.go @@ -17,7 +17,6 @@ import ( abciclient "github.com/tendermint/tendermint/abci/client" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/internal/blocksync" "github.com/tendermint/tendermint/internal/consensus" "github.com/tendermint/tendermint/internal/eventbus" @@ -205,19 +204,16 @@ func makeNode( return nil, combineCloseError(err, makeCloser(closers)) } - var pubKey crypto.PubKey - pubKey, err = privValidator.GetPubKey(ctx) + pubKey, err := privValidator.GetPubKey(ctx) if err != nil { return nil, combineCloseError(fmt.Errorf("can't get pubkey: %w", err), makeCloser(closers)) } if cfg.Mode == config.ModeValidator { - if pubKey == nil { - return nil, combineCloseError( - errors.New("could not retrieve public key from private validator"), - makeCloser(closers)) - } + return nil, combineCloseError( + errors.New("could not retrieve public key from private validator"), + makeCloser(closers)) } // TODO construct node here: diff --git a/sei-tendermint/node/setup.go b/sei-tendermint/node/setup.go index 53b9742c03..ce80994b31 100644 --- a/sei-tendermint/node/setup.go +++ b/sei-tendermint/node/setup.go @@ -120,12 +120,12 @@ func logNodeStartupInfo(state sm.State, pubKey crypto.PubKey, logger log.Logger, if state.Validators.HasAddress(addr) { logger.Info("This node is a validator", "addr", addr, - "pubKey", pubKey.Bytes(), + "pubKey", pubKey[:], ) } else { logger.Info("This node is a validator (NOT in the active validator set)", "addr", addr, - "pubKey", pubKey.Bytes(), + "pubKey", pubKey[:], ) } } @@ -136,7 +136,7 @@ func onlyValidatorIsUs(state sm.State, pubKey crypto.PubKey) bool { return false } addr, _ := state.Validators.GetByIndex(0) - return pubKey != nil && bytes.Equal(pubKey.Address(), addr) + return bytes.Equal(pubKey.Address(), addr) } func createMempoolReactor( diff --git a/sei-tendermint/privval/file.go b/sei-tendermint/privval/file.go index aa5eca2f2a..b1691db3b6 100644 --- a/sei-tendermint/privval/file.go +++ b/sei-tendermint/privval/file.go @@ -396,14 +396,11 @@ func (pv *FilePV) signVote(chainID string, vote *tmproto.Vote) error { } // It passed the checks. Sign the vote - sig, err := pv.Key.PrivKey.Sign(signBytes) - if err != nil { - return err - } - if err := pv.saveSigned(height, round, step, signBytes, sig); err != nil { + sig := pv.Key.PrivKey.Sign(signBytes) + if err := pv.saveSigned(height, round, step, signBytes, sig[:]); err != nil { return err } - vote.Signature = sig + vote.Signature = sig[:] return nil } @@ -433,14 +430,11 @@ func (pv *FilePV) signProposal(chainID string, proposal *tmproto.Proposal) error } // It passed the checks. Sign the proposal - sig, err := pv.Key.PrivKey.Sign(signBytes) - if err != nil { - return err - } - if err := pv.saveSigned(height, round, step, signBytes, sig); err != nil { + sig := pv.Key.PrivKey.Sign(signBytes) + if err := pv.saveSigned(height, round, step, signBytes, sig[:]); err != nil { return err } - proposal.Signature = sig + proposal.Signature = sig[:] return nil } diff --git a/sei-tendermint/privval/grpc/client.go b/sei-tendermint/privval/grpc/client.go index f4c0b7d999..78e9aa22d2 100644 --- a/sei-tendermint/privval/grpc/client.go +++ b/sei-tendermint/privval/grpc/client.go @@ -59,12 +59,12 @@ func (sc *SignerClient) GetPubKey(ctx context.Context) (crypto.PubKey, error) { if err != nil { errStatus, _ := status.FromError(err) sc.logger.Error("SignerClient::GetPubKey", "err", errStatus.Message()) - return nil, errStatus.Err() + return crypto.PubKey{}, errStatus.Err() } pk, err := encoding.PubKeyFromProto(resp.PubKey) if err != nil { - return nil, err + return crypto.PubKey{}, err } return pk, nil diff --git a/sei-tendermint/privval/grpc/server.go b/sei-tendermint/privval/grpc/server.go index 40af824795..8a3de0faa9 100644 --- a/sei-tendermint/privval/grpc/server.go +++ b/sei-tendermint/privval/grpc/server.go @@ -41,15 +41,8 @@ func (ss *SignerServer) GetPubKey(ctx context.Context, req *privvalproto.PubKeyR if err != nil { return nil, status.Errorf(codes.NotFound, "error getting pubkey: %v", err) } - - pk, err := encoding.PubKeyToProto(pubKey) - if err != nil { - return nil, status.Errorf(codes.Internal, "error transitioning pubkey to proto: %v", err) - } - ss.logger.Info("SignerServer: GetPubKey Success") - - return &privvalproto.PubKeyResponse{PubKey: pk}, nil + return &privvalproto.PubKeyResponse{PubKey: encoding.PubKeyToProto(pubKey)}, nil } // SignVote receives a vote sign requests, attempts to sign it diff --git a/sei-tendermint/privval/retry_signer_client.go b/sei-tendermint/privval/retry_signer_client.go index 6dacc9a288..71b1dcdb85 100644 --- a/sei-tendermint/privval/retry_signer_client.go +++ b/sei-tendermint/privval/retry_signer_client.go @@ -59,16 +59,16 @@ func (sc *RetrySignerClient) GetPubKey(ctx context.Context) (crypto.PubKey, erro } // If remote signer errors, we don't retry. if _, ok := err.(*RemoteSignerError); ok { - return nil, err + return pk, err } select { case <-ctx.Done(): - return nil, ctx.Err() + return pk, ctx.Err() case <-t.C: t.Reset(sc.timeout) } } - return nil, fmt.Errorf("exhausted all attempts to get pubkey: %w", err) + return pk, fmt.Errorf("exhausted all attempts to get pubkey: %w", err) } func (sc *RetrySignerClient) SignVote(ctx context.Context, chainID string, vote *tmproto.Vote) error { diff --git a/sei-tendermint/privval/secret_connection.go b/sei-tendermint/privval/secret_connection.go index 96a4c8d95a..5cbb3f056b 100644 --- a/sei-tendermint/privval/secret_connection.go +++ b/sei-tendermint/privval/secret_connection.go @@ -162,10 +162,7 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey ed25519.PrivKey) ( } // Sign the challenge bytes for authentication. - locSignature, err := signChallenge(&challenge, locPrivKey) - if err != nil { - return nil, err - } + locSignature := signChallenge(&challenge, locPrivKey) // Share (in secret) each other's pubkey & challenge signature authSigMsg, err := shareAuthSignature(sc, locPubKey, locSignature) @@ -174,8 +171,8 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey ed25519.PrivKey) ( } remPubKey, remSignature := authSigMsg.Key, authSigMsg.Sig - if !remPubKey.VerifySignature(challenge[:], remSignature) { - return nil, errors.New("challenge verification failed") + if err:=remPubKey.Verify(challenge[:], remSignature); err!=nil { + return nil, fmt.Errorf("challenge verification failed: %w",err) } // We've authorized. @@ -396,26 +393,22 @@ func sort32(foo, bar *[32]byte) (lo, hi *[32]byte) { return } -func signChallenge(challenge *[32]byte, locPrivKey ed25519.PrivKey) ([]byte, error) { - signature, err := locPrivKey.Sign(challenge[:]) - if err != nil { - return nil, err - } - return signature, nil +func signChallenge(challenge *[32]byte, locPrivKey ed25519.PrivKey) ed25519.Sig { + return locPrivKey.Sign(challenge[:]) } type authSigMessage struct { Key ed25519.PubKey - Sig []byte + Sig ed25519.Sig } -func shareAuthSignature(sc io.ReadWriter, pubKey ed25519.PubKey, signature []byte) (recvMsg authSigMessage, err error) { +func shareAuthSignature(sc io.ReadWriter, pubKey ed25519.PubKey, signature ed25519.Sig) (recvMsg authSigMessage, err error) { // Send our info and receive theirs in tandem. var trs, _ = async.Parallel( func(_ int) (val interface{}, abort bool, err error) { - pk := tmproto.PublicKey{Sum: &tmproto.PublicKey_Ed25519{Ed25519: pubKey}} - _, err = protoio.NewDelimitedWriter(sc).WriteMsg(&tmprivval.AuthSigMessage{PubKey: pk, Sig: signature}) + pk := tmproto.PublicKey{Sum: &tmproto.PublicKey_Ed25519{Ed25519: pubKey[:]}} + _, err = protoio.NewDelimitedWriter(sc).WriteMsg(&tmprivval.AuthSigMessage{PubKey: pk, Sig: signature[:]}) if err != nil { return nil, true, err // abort } @@ -428,16 +421,15 @@ func shareAuthSignature(sc io.ReadWriter, pubKey ed25519.PubKey, signature []byt return nil, true, err // abort } - pk := pba.PubKey.GetEd25519() - if len(pk) != ed25519.PubKeySize { - return nil, true, fmt.Errorf("invalid ed25519 key size") + key,err := ed25519.PubKeyFromBytes(pba.PubKey.GetEd25519()) + if err!=nil { + return nil,true, fmt.Errorf("PubKey: %w",err) } - - _recvMsg := authSigMessage{ - Key: ed25519.PubKey(pk), - Sig: pba.Sig, + sig,err := ed25519.SigFromBytes(pba.Sig) + if err!=nil { + return nil,true,fmt.Errorf("Sig: %w",err) } - return _recvMsg, false, nil + return authSigMessage{key,sig}, false, nil }, ) diff --git a/sei-tendermint/privval/signer_client.go b/sei-tendermint/privval/signer_client.go index 10ce8bc75a..3a6f194d29 100644 --- a/sei-tendermint/privval/signer_client.go +++ b/sei-tendermint/privval/signer_client.go @@ -83,20 +83,20 @@ func (sc *SignerClient) Ping(ctx context.Context) error { func (sc *SignerClient) GetPubKey(ctx context.Context) (crypto.PubKey, error) { response, err := sc.endpoint.SendRequest(ctx, mustWrapMsg(&privvalproto.PubKeyRequest{ChainId: sc.chainID})) if err != nil { - return nil, fmt.Errorf("send: %w", err) + return crypto.PubKey{}, fmt.Errorf("send: %w", err) } resp := response.GetPubKeyResponse() if resp == nil { - return nil, ErrUnexpectedResponse + return crypto.PubKey{}, ErrUnexpectedResponse } if resp.Error != nil { - return nil, &RemoteSignerError{Code: int(resp.Error.Code), Description: resp.Error.Description} + return crypto.PubKey{}, &RemoteSignerError{Code: int(resp.Error.Code), Description: resp.Error.Description} } pk, err := encoding.PubKeyFromProto(resp.PubKey) if err != nil { - return nil, err + return crypto.PubKey{}, err } return pk, nil diff --git a/sei-tendermint/privval/signer_requestHandler.go b/sei-tendermint/privval/signer_requestHandler.go index d07c656208..b0908c50c6 100644 --- a/sei-tendermint/privval/signer_requestHandler.go +++ b/sei-tendermint/privval/signer_requestHandler.go @@ -37,11 +37,7 @@ func DefaultValidationRequestHandler( if err != nil { return res, err } - pk, err := encoding.PubKeyToProto(pubKey) - if err != nil { - return res, err - } - + pk := encoding.PubKeyToProto(pubKey) if err != nil { res = mustWrapMsg(&privvalproto.PubKeyResponse{ PubKey: cryptoproto.PublicKey{}, Error: &privvalproto.RemoteSignerError{Code: 0, Description: err.Error()}}) diff --git a/sei-tendermint/test/e2e/pkg/testnet.go b/sei-tendermint/test/e2e/pkg/testnet.go index 0e74a5859b..bb1b1cc8b4 100644 --- a/sei-tendermint/test/e2e/pkg/testnet.go +++ b/sei-tendermint/test/e2e/pkg/testnet.go @@ -481,16 +481,15 @@ func newKeyGenerator(seed int64) *keyGenerator { } func (g *keyGenerator) Generate(keyType string) crypto.PrivKey { - seed := make([]byte, ed25519.SeedSize) - - _, err := io.ReadFull(g.random, seed) + var seed ed25519.Seed + _, err := io.ReadFull(g.random, seed[:]) if err != nil { panic(err) // this shouldn't happen } if keyType != "" && keyType != "ed25519" { panic("KeyType not supported") } - return ed25519.GenPrivKeyFromSecret(seed) + return ed25519.PrivKeyFromSeed(seed) } // portGenerator generates local Docker proxy ports for each node. diff --git a/sei-tendermint/test/e2e/runner/evidence.go b/sei-tendermint/test/e2e/runner/evidence.go index 63c2442f59..3316a07c93 100644 --- a/sei-tendermint/test/e2e/runner/evidence.go +++ b/sei-tendermint/test/e2e/runner/evidence.go @@ -239,12 +239,12 @@ func getRandomValidatorIndex(privVals []types.MockPV, vals *types.ValidatorSet) func readPrivKey(keyFilePath string) (crypto.PrivKey, error) { keyJSONBytes, err := os.ReadFile(keyFilePath) if err != nil { - return nil, err + return crypto.PrivKey{}, err } pvKey := privval.FilePVKey{} err = json.Unmarshal(keyJSONBytes, &pvKey) if err != nil { - return nil, fmt.Errorf("error reading PrivValidator key from %v: %w", keyFilePath, err) + return crypto.PrivKey{}, fmt.Errorf("error reading PrivValidator key from %v: %w", keyFilePath, err) } return pvKey.PrivKey, nil diff --git a/sei-tendermint/test/e2e/runner/setup.go b/sei-tendermint/test/e2e/runner/setup.go index 0d2c389aea..271b876e4a 100644 --- a/sei-tendermint/test/e2e/runner/setup.go +++ b/sei-tendermint/test/e2e/runner/setup.go @@ -388,7 +388,8 @@ func MakeAppConfig(node *e2e.Node) ([]byte, error) { for height, validators := range node.Testnet.ValidatorUpdates { updateVals := map[string]int64{} for node, power := range validators { - updateVals[base64.StdEncoding.EncodeToString(node.PrivvalKey.PubKey().Bytes())] = power + key := node.PrivvalKey.PubKey() + updateVals[base64.StdEncoding.EncodeToString(key[:])] = power } validatorUpdates[fmt.Sprintf("%v", height)] = updateVals } diff --git a/sei-tendermint/types/block.go b/sei-tendermint/types/block.go index 4938de5374..b625ba182f 100644 --- a/sei-tendermint/types/block.go +++ b/sei-tendermint/types/block.go @@ -643,7 +643,7 @@ type CommitSig struct { BlockIDFlag BlockIDFlag `json:"block_id_flag"` ValidatorAddress Address `json:"validator_address"` Timestamp time.Time `json:"timestamp"` - Signature []byte `json:"signature"` + Signature crypto.Sig `json:"signature"` } func MaxCommitBytes(valCount int) int64 { @@ -668,7 +668,7 @@ func NewCommitSigAbsent() CommitSig { // 4. timestamp func (cs CommitSig) String() string { return fmt.Sprintf("CommitSig{%X by %X on %v @ %s}", - tmbytes.Fingerprint(cs.Signature), + tmbytes.Fingerprint(cs.Signature[:]), tmbytes.Fingerprint(cs.ValidatorAddress), cs.BlockIDFlag, CanonicalTime(cs.Timestamp)) @@ -720,12 +720,6 @@ func (cs CommitSig) ValidateBasic() error { ) } // NOTE: Timestamp validation is subtle and handled elsewhere. - if len(cs.Signature) == 0 { - return errors.New("signature is missing") - } - if len(cs.Signature) > MaxSignatureSize { - return fmt.Errorf("signature is too big (max: %d)", MaxSignatureSize) - } } return nil @@ -741,7 +735,7 @@ func (cs *CommitSig) ToProto() *tmproto.CommitSig { BlockIdFlag: tmproto.BlockIDFlag(cs.BlockIDFlag), ValidatorAddress: cs.ValidatorAddress, Timestamp: cs.Timestamp, - Signature: cs.Signature, + Signature: cs.Signature[:], } } @@ -751,7 +745,11 @@ func (cs *CommitSig) FromProto(csp tmproto.CommitSig) error { cs.BlockIDFlag = BlockIDFlag(csp.BlockIdFlag) cs.ValidatorAddress = csp.ValidatorAddress cs.Timestamp = csp.Timestamp - cs.Signature = csp.Signature + sig,err := crypto.SigFromBytes(csp.Signature) + if err!=nil { + return fmt.Errorf("Signature: %w",err) + } + cs.Signature = sig return cs.ValidateBasic() } diff --git a/sei-tendermint/types/evidence.go b/sei-tendermint/types/evidence.go index e0091a202b..cab7573b35 100644 --- a/sei-tendermint/types/evidence.go +++ b/sei-tendermint/types/evidence.go @@ -856,11 +856,15 @@ func NewMockDuplicateVoteEvidenceWithValidator(ctx context.Context, height int64 voteA := makeMockVote(height, 0, 0, pubKey.Address(), randBlockID(), time) vA := voteA.ToProto() _ = pv.SignVote(ctx, chainID, vA) - voteA.Signature = vA.Signature + if voteA.Signature,err = crypto.SigFromBytes(vA.Signature); err!=nil { + return nil,err + } voteB := makeMockVote(height, 0, 0, pubKey.Address(), randBlockID(), time) vB := voteB.ToProto() _ = pv.SignVote(ctx, chainID, vB) - voteB.Signature = vB.Signature + if voteB.Signature,err = crypto.SigFromBytes(vB.Signature); err!=nil { + return nil, err + } ev, err := NewDuplicateVoteEvidence(voteA, voteB, time, NewValidatorSet([]*Validator{val})) if err != nil { return nil, fmt.Errorf("constructing mock duplicate vote evidence: %w", err) diff --git a/sei-tendermint/types/priv_validator.go b/sei-tendermint/types/priv_validator.go index 5a9b27cb63..3375425440 100644 --- a/sei-tendermint/types/priv_validator.go +++ b/sei-tendermint/types/priv_validator.go @@ -90,11 +90,8 @@ func (pv MockPV) SignVote(ctx context.Context, chainID string, vote *tmproto.Vot } signBytes := VoteSignBytes(useChainID, vote) - sig, err := pv.PrivKey.Sign(signBytes) - if err != nil { - return err - } - vote.Signature = sig + sig := pv.PrivKey.Sign(signBytes) + vote.Signature = sig[:] return nil } @@ -106,11 +103,8 @@ func (pv MockPV) SignProposal(ctx context.Context, chainID string, proposal *tmp } signBytes := ProposalSignBytes(useChainID, proposal) - sig, err := pv.PrivKey.Sign(signBytes) - if err != nil { - return err - } - proposal.Signature = sig + sig := pv.PrivKey.Sign(signBytes) + proposal.Signature = sig[:] return nil } @@ -143,7 +137,7 @@ var ErroringMockPVErr = errors.New("erroringMockPV always returns an error") // Implements PrivValidator. func (pv *ErroringMockPV) GetPubKey(ctx context.Context) (crypto.PubKey, error) { - return nil, ErroringMockPVErr + return crypto.PubKey{}, ErroringMockPVErr } // Implements PrivValidator. diff --git a/sei-tendermint/types/proposal.go b/sei-tendermint/types/proposal.go index b8d4d27a05..1d05536726 100644 --- a/sei-tendermint/types/proposal.go +++ b/sei-tendermint/types/proposal.go @@ -7,6 +7,7 @@ import ( "time" "github.com/tendermint/tendermint/internal/libs/protoio" + "github.com/tendermint/tendermint/crypto" tmbytes "github.com/tendermint/tendermint/libs/bytes" tmtime "github.com/tendermint/tendermint/libs/time" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -30,7 +31,7 @@ type Proposal struct { POLRound int32 `json:"pol_round"` // -1 if null. BlockID BlockID `json:"block_id"` Timestamp time.Time `json:"timestamp"` - Signature []byte `json:"signature"` + Signature crypto.Sig `json:"signature"` TxKeys []TxKey `json:"tx_keys"` Header `json:"header"` LastCommit *Commit `json:"last_commit"` @@ -79,14 +80,6 @@ func (p *Proposal) ValidateBasic() error { } // NOTE: Timestamp validation is subtle and handled elsewhere. - - if len(p.Signature) == 0 { - return errors.New("signature is missing") - } - - if len(p.Signature) > MaxSignatureSize { - return fmt.Errorf("signature is too big (max: %d)", MaxSignatureSize) - } return nil } @@ -143,7 +136,7 @@ func (p *Proposal) String() string { p.Round, p.BlockID, p.POLRound, - tmbytes.Fingerprint(p.Signature), + tmbytes.Fingerprint(p.Signature[:]), CanonicalTime(p.Timestamp)) } @@ -178,7 +171,7 @@ func (p *Proposal) ToProto() *tmproto.Proposal { pb.Round = p.Round pb.PolRound = p.POLRound pb.Timestamp = p.Timestamp - pb.Signature = p.Signature + pb.Signature = p.Signature[:] txKeys := make([]*tmproto.TxKey, 0, len(p.TxKeys)) for _, txKey := range p.TxKeys { txKeys = append(txKeys, txKey.ToProto()) @@ -216,7 +209,11 @@ func ProposalFromProto(pp *tmproto.Proposal) (*Proposal, error) { p.Round = pp.Round p.POLRound = pp.PolRound p.Timestamp = pp.Timestamp - p.Signature = pp.Signature + sig,err := crypto.SigFromBytes(pp.Signature) + if err!=nil { + return nil, fmt.Errorf("Signature: %w",err) + } + p.Signature = sig txKeys, err := TxKeysListFromProto(pp.TxKeys) if err != nil { return nil, err diff --git a/sei-tendermint/types/protobuf.go b/sei-tendermint/types/protobuf.go index f82965fbf4..c59ccdee02 100644 --- a/sei-tendermint/types/protobuf.go +++ b/sei-tendermint/types/protobuf.go @@ -20,19 +20,13 @@ func (tm2pb) Validator(val *Validator) abci.Validator { } } -// XXX: panics on unknown pubkey type func (tm2pb) ValidatorUpdate(val *Validator) abci.ValidatorUpdate { - pk, err := encoding.PubKeyToProto(val.PubKey) - if err != nil { - panic(err) - } return abci.ValidatorUpdate{ - PubKey: pk, + PubKey: encoding.PubKeyToProto(val.PubKey), Power: val.VotingPower, } } -// XXX: panics on nil or unknown pubkey type func (tm2pb) ValidatorUpdates(vals *ValidatorSet) []abci.ValidatorUpdate { validators := make([]abci.ValidatorUpdate, vals.Size()) for i, val := range vals.Validators { diff --git a/sei-tendermint/types/signable.go b/sei-tendermint/types/signable.go deleted file mode 100644 index f1b71ca1b7..0000000000 --- a/sei-tendermint/types/signable.go +++ /dev/null @@ -1,12 +0,0 @@ -package types - -import ( - "github.com/tendermint/tendermint/crypto/ed25519" - tmmath "github.com/tendermint/tendermint/libs/math" -) - -var ( - // MaxSignatureSize is a maximum allowed signature size for the Proposal - // and Vote. - MaxSignatureSize = tmmath.MaxInt(ed25519.SignatureSize, 64) -) diff --git a/sei-tendermint/types/test_util.go b/sei-tendermint/types/test_util.go index e72e6ff4a7..c0a7b54995 100644 --- a/sei-tendermint/types/test_util.go +++ b/sei-tendermint/types/test_util.go @@ -5,6 +5,7 @@ import ( "fmt" "time" + "github.com/tendermint/tendermint/crypto" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) @@ -38,10 +39,13 @@ func MakeCommit(ctx context.Context, blockID BlockID, height int64, round int32, func signAddVote(ctx context.Context, privVal PrivValidator, vote *Vote, voteSet *VoteSet) (signed bool, err error) { v := vote.ToProto() - err = privVal.SignVote(ctx, voteSet.ChainID(), v) - if err != nil { + if err := privVal.SignVote(ctx, voteSet.ChainID(), v); err != nil { return false, err } - vote.Signature = v.Signature + sig,err := crypto.SigFromBytes(v.Signature) + if err!=nil { + return false, fmt.Errorf("SigFromBytes(): %w",err) + } + vote.Signature = sig return voteSet.AddVote(vote) } diff --git a/sei-tendermint/types/validation.go b/sei-tendermint/types/validation.go index 45e183140b..474488f9be 100644 --- a/sei-tendermint/types/validation.go +++ b/sei-tendermint/types/validation.go @@ -206,11 +206,7 @@ func verifyCommitBatch( voteSignBytes := commit.VoteSignBytes(chainID, int32(idx)) // add the key, sig and message to the verifier - sig,err := crypto.SigFromBytes(commitSig.Signature) - if err!=nil { - return fmt.Errorf("crypto.SigFromBytes(): %w",err) - } - bv.Add(val.PubKey, voteSignBytes, sig) + bv.Add(val.PubKey, voteSignBytes, commitSig.Signature) batchSigIdxs = append(batchSigIdxs, idx) // If this signature counts then add the voting power of the validator @@ -295,11 +291,7 @@ func verifyCommitSingle( } voteSignBytes = commit.VoteSignBytes(chainID, int32(idx)) - sig,err := crypto.SigFromBytes(commitSig.Signature) - if err!=nil { - return fmt.Errorf("crypto.SigFromBytes(): %w",err) - } - if err := val.PubKey.Verify(voteSignBytes, sig); err!=nil { + if err := val.PubKey.Verify(voteSignBytes, commitSig.Signature); err!=nil { return errBadSig{fmt.Errorf("wrong signature (#%d): %X", idx, commitSig.Signature)} } diff --git a/sei-tendermint/types/validator.go b/sei-tendermint/types/validator.go index 43977cb643..76120d297e 100644 --- a/sei-tendermint/types/validator.go +++ b/sei-tendermint/types/validator.go @@ -38,13 +38,11 @@ func (v Validator) MarshalJSON() ([]byte, error) { VotingPower: v.VotingPower, ProposerPriority: v.ProposerPriority, } - if v.PubKey != nil { - pk, err := jsontypes.Marshal(v.PubKey) - if err != nil { - return nil, err - } - val.PubKey = pk + pk, err := jsontypes.Marshal(v.PubKey) + if err != nil { + return nil, err } + val.PubKey = pk return json.Marshal(val) } @@ -77,10 +75,6 @@ func (v *Validator) ValidateBasic() error { if v == nil { return errors.New("nil validator") } - if v.PubKey == nil { - return errors.New("validator does not have a public key") - } - if v.VotingPower < 0 { return errors.New("validator has negative voting power") } @@ -154,11 +148,7 @@ func ValidatorListString(vals []*Validator) string { // as its redundant with the pubkey. This also excludes ProposerPriority // which changes every round. func (v *Validator) Bytes() []byte { - pk, err := encoding.PubKeyToProto(v.PubKey) - if err != nil { - panic(err) - } - + pk := encoding.PubKeyToProto(v.PubKey) pbv := tmproto.SimpleValidator{ PubKey: &pk, VotingPower: v.VotingPower, @@ -176,15 +166,9 @@ func (v *Validator) ToProto() (*tmproto.Validator, error) { if v == nil { return nil, errors.New("nil validator") } - - pk, err := encoding.PubKeyToProto(v.PubKey) - if err != nil { - return nil, err - } - return &tmproto.Validator{ Address: v.Address, - PubKey: pk, + PubKey: encoding.PubKeyToProto(v.PubKey), VotingPower: v.VotingPower, ProposerPriority: v.ProposerPriority, }, nil diff --git a/sei-tendermint/types/vote.go b/sei-tendermint/types/vote.go index 40f829182d..be2e2bd04f 100644 --- a/sei-tendermint/types/vote.go +++ b/sei-tendermint/types/vote.go @@ -55,7 +55,7 @@ type Vote struct { Timestamp time.Time `json:"timestamp"` ValidatorAddress Address `json:"validator_address"` ValidatorIndex int32 `json:"validator_index"` - Signature []byte `json:"signature"` + Signature crypto.Sig `json:"signature"` } // VoteFromProto attempts to convert the given serialization (Protobuf) type to @@ -67,7 +67,10 @@ func VoteFromProto(pv *tmproto.Vote) (*Vote, error) { if err != nil { return nil, err } - + sig,err := crypto.SigFromBytes(pv.Signature) + if err!=nil { + return nil,fmt.Errorf("Signature: %w",err) + } return &Vote{ Type: pv.Type, Height: pv.Height, @@ -76,7 +79,7 @@ func VoteFromProto(pv *tmproto.Vote) (*Vote, error) { Timestamp: pv.Timestamp, ValidatorAddress: pv.ValidatorAddress, ValidatorIndex: pv.ValidatorIndex, - Signature: pv.Signature, + Signature: sig, }, nil } @@ -162,7 +165,7 @@ func (vote *Vote) String() string { vote.Type, typeString, tmbytes.Fingerprint(vote.BlockID.Hash), - tmbytes.Fingerprint(vote.Signature), + tmbytes.Fingerprint(vote.Signature[:]), CanonicalTime(vote.Timestamp), ) } @@ -172,7 +175,7 @@ func (vote *Vote) verifyAndReturnProto(chainID string, pubKey crypto.PubKey) (*t return nil, ErrVoteInvalidValidatorAddress } v := vote.ToProto() - if !pubKey.VerifySignature(VoteSignBytes(chainID, v), vote.Signature) { + if err:=pubKey.Verify(VoteSignBytes(chainID, v), vote.Signature); err!=nil { return nil, ErrVoteInvalidSignature } return v, nil @@ -223,13 +226,6 @@ func (vote *Vote) ValidateBasic() error { if vote.ValidatorIndex < 0 { return errors.New("negative ValidatorIndex") } - if len(vote.Signature) == 0 { - return errors.New("signature is missing") - } - - if len(vote.Signature) > MaxSignatureSize { - return fmt.Errorf("signature is too big (max: %d)", MaxSignatureSize) - } return nil } @@ -248,7 +244,7 @@ func (vote *Vote) ToProto() *tmproto.Vote { Timestamp: vote.Timestamp, ValidatorAddress: vote.ValidatorAddress, ValidatorIndex: vote.ValidatorIndex, - Signature: vote.Signature, + Signature: vote.Signature[:], } } diff --git a/sei-tendermint/types/vote_set.go b/sei-tendermint/types/vote_set.go index d9171f0930..f9c32a04ea 100644 --- a/sei-tendermint/types/vote_set.go +++ b/sei-tendermint/types/vote_set.go @@ -183,7 +183,7 @@ func (voteSet *VoteSet) addVote(vote *Vote) (added bool, err error) { // If we already know of this vote, return false. if existing, ok := voteSet.getVote(valIndex, blockKey); ok { - if bytes.Equal(existing.Signature, vote.Signature) { + if existing.Signature==vote.Signature { return false, nil // duplicate } return false, fmt.Errorf("existing vote: %v; new vote: %v: %w", existing, vote, ErrVoteNonDeterministicSignature) From 28bd678e62c1ed6263c5d10a9dce8182698f4e45 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Mon, 15 Dec 2025 17:50:16 +0100 Subject: [PATCH 24/53] wip --- .../internal/consensus/common_test.go | 15 +++--- .../internal/consensus/invalid_test.go | 5 +- .../p2p/conn/secret_connection_test.go | 12 ++--- sei-tendermint/types/block_test.go | 51 +++++-------------- 4 files changed, 32 insertions(+), 51 deletions(-) diff --git a/sei-tendermint/internal/consensus/common_test.go b/sei-tendermint/internal/consensus/common_test.go index b573a6c627..f4cedcb62e 100644 --- a/sei-tendermint/internal/consensus/common_test.go +++ b/sei-tendermint/internal/consensus/common_test.go @@ -21,6 +21,7 @@ import ( "github.com/tendermint/tendermint/abci/example/kvstore" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/crypto" cstypes "github.com/tendermint/tendermint/internal/consensus/types" "github.com/tendermint/tendermint/internal/eventbus" "github.com/tendermint/tendermint/internal/mempool" @@ -140,14 +141,15 @@ func (vs *validatorStub) signVote( // ref: signVote in FilePV, the vote should use the previous vote info when the sign data is the same. if signDataIsEqual(vs.lastVote, v) { - v.Signature = vs.lastVote.Signature + v.Signature = vs.lastVote.Signature[:] v.Timestamp = vs.lastVote.Timestamp } - - vote.Signature = v.Signature + sig,err := crypto.SigFromBytes(v.Signature) + if err!=nil { return nil,err } + vote.Signature = sig vote.Timestamp = v.Timestamp - return vote, err + return vote, nil } // Sign vote for type/hash/header @@ -259,8 +261,9 @@ func decideProposal( proposal = types.NewProposal(height, round, polRound, propBlockID, block.Header.Time, block.GetTxKeys(), block.Header, block.LastCommit, block.Evidence, address) p := proposal.ToProto() require.NoError(t, vs.SignProposal(ctx, chainID, p)) - - proposal.Signature = p.Signature + sig,err := crypto.SigFromBytes(p.Signature) + require.NoError(t, err) + proposal.Signature = sig return } diff --git a/sei-tendermint/internal/consensus/invalid_test.go b/sei-tendermint/internal/consensus/invalid_test.go index 257875122b..fae62b8fc5 100644 --- a/sei-tendermint/internal/consensus/invalid_test.go +++ b/sei-tendermint/internal/consensus/invalid_test.go @@ -13,6 +13,7 @@ import ( "github.com/tendermint/tendermint/internal/eventbus" "github.com/tendermint/tendermint/internal/p2p" "github.com/tendermint/tendermint/libs/bytes" + "github.com/tendermint/tendermint/crypto" tmrand "github.com/tendermint/tendermint/libs/rand" tmtime "github.com/tendermint/tendermint/libs/time" "github.com/tendermint/tendermint/libs/utils" @@ -147,7 +148,9 @@ func invalidDoPrevoteFunc( p := precommit.ToProto() require.NoError(t, pv.SignVote(ctx, cs.state.ChainID, p)) - precommit.Signature = p.Signature + sig,err := crypto.SigFromBytes(p.Signature) + require.NoError(t,err) + precommit.Signature = sig t.Logf("disable priv val so we don't do normal votes") cs.privValidator = utils.None[types.PrivValidator]() cs.mtx.Unlock() diff --git a/sei-tendermint/internal/p2p/conn/secret_connection_test.go b/sei-tendermint/internal/p2p/conn/secret_connection_test.go index 42589702ff..18bc464284 100644 --- a/sei-tendermint/internal/p2p/conn/secret_connection_test.go +++ b/sei-tendermint/internal/p2p/conn/secret_connection_test.go @@ -307,10 +307,10 @@ func makeSecretConnPair(tb testing.TB) (fooSecConn, barSecConn *SecretConnection tb.Errorf("failed to establish SecretConnection for foo: %v", err) return nil, true, err } - remotePubBytes := fooSecConn.RemotePubKey() - if !remotePubBytes.Equals(barPubKey) { + remotePubKey := fooSecConn.RemotePubKey() + if remotePubKey != barPubKey { err = fmt.Errorf("unexpected fooSecConn.RemotePubKey. Expected %v, got %v", - barPubKey, fooSecConn.RemotePubKey()) + barPubKey, remotePubKey) tb.Error(err) return nil, true, err } @@ -322,10 +322,10 @@ func makeSecretConnPair(tb testing.TB) (fooSecConn, barSecConn *SecretConnection tb.Errorf("failed to establish SecretConnection for bar: %v", err) return nil, true, err } - remotePubBytes := barSecConn.RemotePubKey() - if !remotePubBytes.Equals(fooPubKey) { + remotePubKey := barSecConn.RemotePubKey() + if remotePubKey!=fooPubKey { err = fmt.Errorf("unexpected barSecConn.RemotePubKey. Expected %v, got %v", - fooPubKey, barSecConn.RemotePubKey()) + fooPubKey, remotePubKey) tb.Error(err) return nil, true, err } diff --git a/sei-tendermint/types/block_test.go b/sei-tendermint/types/block_test.go index 8e6bcbd8d8..7623243efa 100644 --- a/sei-tendermint/types/block_test.go +++ b/sei-tendermint/types/block_test.go @@ -7,6 +7,7 @@ import ( "crypto/rand" "encoding/hex" "math" + "io" mrand "math/rand" "os" "reflect" @@ -279,7 +280,7 @@ func TestCommitValidateBasic(t *testing.T) { expectErr bool }{ {"Random Commit", func(com *Commit) {}, false}, - {"Incorrect signature", func(com *Commit) { com.Signatures[0].Signature = []byte{0} }, false}, + {"Incorrect signature", func(com *Commit) { com.Signatures[0].Signature = crypto.Sig{} }, false}, {"Incorrect height", func(com *Commit) { com.Height = int64(-100) }, true}, {"Incorrect round", func(com *Commit) { com.Round = -100 }, true}, } @@ -300,11 +301,14 @@ func TestMaxCommitBytes(t *testing.T) { // year int, month Month, day, hour, min, sec, nsec int, loc *Location timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC) + sig := crypto.Sig{} + _,err := io.ReadFull(rand.Reader,sig[:]) + require.NoError(t,err) cs := CommitSig{ BlockIDFlag: BlockIDFlagNil, ValidatorAddress: crypto.AddressHash([]byte("validator_address")), Timestamp: timestamp, - Signature: crypto.CRandBytes(MaxSignatureSize), + Signature: sig, } pbSig := cs.ToProto() @@ -565,9 +569,10 @@ func TestVoteSetToCommit(t *testing.T) { Timestamp: time.Now(), } v := vote.ToProto() - err = vals[i].SignVote(ctx, voteSet.ChainID(), v) + require.NoError(t, vals[i].SignVote(ctx, voteSet.ChainID(), v)) + sig,err := crypto.SigFromBytes(v.Signature) require.NoError(t, err) - vote.Signature = v.Signature + vote.Signature = sig added, err := voteSet.AddVote(vote) require.NoError(t, err) require.True(t, added) @@ -941,7 +946,7 @@ func TestCommitSig_ValidateBasic(t *testing.T) { }, { "BlockIDFlagAbsent signatures present", - CommitSig{BlockIDFlag: BlockIDFlagAbsent, Signature: []byte{0xAA}}, + CommitSig{BlockIDFlag: BlockIDFlagAbsent, Signature: crypto.Sig{0xAA}}, true, "signature is present", }, { @@ -959,25 +964,16 @@ func TestCommitSig_ValidateBasic(t *testing.T) { CommitSig{ BlockIDFlag: BlockIDFlagCommit, ValidatorAddress: make([]byte, crypto.AddressSize), - Signature: make([]byte, 0), + Signature: crypto.Sig{}, }, true, "signature is missing", }, - { - "non-BlockIDFlagAbsent invalid signature (too large)", - CommitSig{ - BlockIDFlag: BlockIDFlagCommit, - ValidatorAddress: make([]byte, crypto.AddressSize), - Signature: make([]byte, MaxSignatureSize+1), - }, - true, "signature is too big", - }, { "non-BlockIDFlagAbsent valid", CommitSig{ BlockIDFlag: BlockIDFlagCommit, ValidatorAddress: make([]byte, crypto.AddressSize), - Signature: make([]byte, MaxSignatureSize), + Signature: crypto.Sig{}, }, false, "", }, @@ -1297,27 +1293,6 @@ func TestCommit_ValidateBasic(t *testing.T) { }, true, "no signatures in commit", }, - { - "invalid signature", - &Commit{ - Height: 1, - Round: 1, - BlockID: BlockID{ - Hash: make([]byte, crypto.HashSize), - PartSetHeader: PartSetHeader{ - Hash: make([]byte, crypto.HashSize), - }, - }, - Signatures: []CommitSig{ - { - BlockIDFlag: BlockIDFlagCommit, - ValidatorAddress: make([]byte, crypto.AddressSize), - Signature: make([]byte, MaxSignatureSize+1), - }, - }, - }, - true, "wrong CommitSig", - }, { "valid commit", &Commit{ @@ -1333,7 +1308,7 @@ func TestCommit_ValidateBasic(t *testing.T) { { BlockIDFlag: BlockIDFlagCommit, ValidatorAddress: make([]byte, crypto.AddressSize), - Signature: make([]byte, MaxSignatureSize), + Signature: crypto.Sig{}, }, }, }, From f007432c767464b929fb060b50e3c47082847bb2 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Tue, 16 Dec 2025 16:40:45 +0100 Subject: [PATCH 25/53] wip; json is shit --- sei-cosmos/client/rpc/status.go | 2 +- sei-cosmos/crypto/codec/tm.go | 9 +--- sei-cosmos/x/staking/teststaking/tm.go | 2 +- .../abci/example/kvstore/helpers.go | 17 +++----- .../abci/example/kvstore/kvstore.go | 3 +- sei-tendermint/abci/tests/server/client.go | 8 ++-- sei-tendermint/abci/types/pubkey.go | 15 ++----- sei-tendermint/crypto/ed25519/ed25519.go | 18 ++++++-- sei-tendermint/crypto/encoding/codec.go | 6 +-- .../internal/consensus/common_test.go | 10 +---- .../internal/consensus/invalid_test.go | 5 +-- .../internal/consensus/memory_limit_test.go | 10 ++++- .../internal/consensus/msgs_test.go | 4 +- .../internal/consensus/pbts_test.go | 3 +- .../internal/consensus/peer_state_test.go | 16 ++++---- .../internal/consensus/reactor_test.go | 5 +-- .../internal/consensus/replay_test.go | 23 +++++------ .../internal/consensus/state_test.go | 27 ++++++------ .../consensus/types/height_vote_set_test.go | 9 +--- sei-tendermint/internal/evidence/pool_test.go | 9 +++- .../internal/evidence/verify_test.go | 6 +-- .../internal/jsontypes/jsontypes.go | 1 + sei-tendermint/internal/libs/wal/log_test.go | 41 +++++++------------ sei-tendermint/internal/p2p/address_test.go | 3 +- .../p2p/conn/evil_secret_connection_test.go | 16 ++------ .../internal/p2p/peermanager_test.go | 4 +- sei-tendermint/internal/rpc/core/env.go | 3 +- sei-tendermint/internal/rpc/core/status.go | 31 +++++++------- .../internal/state/execution_test.go | 27 ++++++------ sei-tendermint/internal/state/helpers_test.go | 21 +++++----- sei-tendermint/internal/state/state_test.go | 21 ++++------ .../internal/state/validation_test.go | 2 +- sei-tendermint/internal/store/store_test.go | 8 +++- sei-tendermint/libs/utils/testonly.go | 11 +++++ sei-tendermint/light/helpers_test.go | 12 +----- sei-tendermint/node/node.go | 18 ++++---- sei-tendermint/node/node_test.go | 7 ++-- sei-tendermint/node/setup.go | 15 ++++--- sei-tendermint/privval/file_test.go | 6 +-- sei-tendermint/privval/grpc/server_test.go | 16 +++++--- sei-tendermint/privval/msgs_test.go | 7 ++-- sei-tendermint/privval/signer_client_test.go | 10 ++++- sei-tendermint/rpc/client/evidence_test.go | 6 +-- sei-tendermint/rpc/client/rpc_test.go | 40 +++++++++--------- sei-tendermint/rpc/coretypes/responses.go | 30 +++++++------- sei-tendermint/test/e2e/app/app.go | 3 +- .../fuzz/tests/p2p_secretconnection_test.go | 8 ++-- sei-tendermint/types/block_test.go | 4 +- sei-tendermint/types/evidence_test.go | 4 +- sei-tendermint/types/proposal_test.go | 32 +++++++-------- sei-tendermint/types/protobuf_test.go | 3 +- sei-tendermint/types/validation_test.go | 20 ++++----- sei-tendermint/types/validator_set_test.go | 6 +-- sei-tendermint/types/validator_test.go | 7 ---- sei-tendermint/types/vote_test.go | 29 +++++-------- 55 files changed, 317 insertions(+), 362 deletions(-) diff --git a/sei-cosmos/client/rpc/status.go b/sei-cosmos/client/rpc/status.go index 6f93cbf712..3f5561bf4a 100644 --- a/sei-cosmos/client/rpc/status.go +++ b/sei-cosmos/client/rpc/status.go @@ -53,7 +53,7 @@ func StatusCommand() *cobra.Command { var pk cryptotypes.PubKey // `status` has TM pubkeys, we need to convert them to our pubkeys. if status.ValidatorInfo.PubKey != nil { - pk, err = cryptocodec.FromTmPubKeyInterface(status.ValidatorInfo.PubKey) + pk, err = cryptocodec.FromTmPubKeyInterface(*status.ValidatorInfo.PubKey) if err != nil { return err } diff --git a/sei-cosmos/crypto/codec/tm.go b/sei-cosmos/crypto/codec/tm.go index 080ae6eb9a..3adc02dc8b 100644 --- a/sei-cosmos/crypto/codec/tm.go +++ b/sei-cosmos/crypto/codec/tm.go @@ -41,19 +41,14 @@ func ToTmProtoPublicKey(pk cryptotypes.PubKey) (tmprotocrypto.PublicKey, error) // FromTmPubKeyInterface converts TM's tmcrypto.PubKey to our own PubKey. func FromTmPubKeyInterface(tmPk tmcrypto.PubKey) (cryptotypes.PubKey, error) { - tmProtoPk, err := encoding.PubKeyToProto(tmPk) - if err != nil { - return nil, err - } - - return FromTmProtoPublicKey(tmProtoPk) + return FromTmProtoPublicKey(encoding.PubKeyToProto(tmPk)) } // ToTmPubKeyInterface converts our own PubKey to TM's tmcrypto.PubKey. func ToTmPubKeyInterface(pk cryptotypes.PubKey) (tmcrypto.PubKey, error) { tmProtoPk, err := ToTmProtoPublicKey(pk) if err != nil { - return nil, err + return tmcrypto.PubKey{}, err } return encoding.PubKeyFromProto(tmProtoPk) diff --git a/sei-cosmos/x/staking/teststaking/tm.go b/sei-cosmos/x/staking/teststaking/tm.go index e927c0e038..f81161f33b 100644 --- a/sei-cosmos/x/staking/teststaking/tm.go +++ b/sei-cosmos/x/staking/teststaking/tm.go @@ -13,7 +13,7 @@ import ( func GetTmConsPubKey(v types.Validator) (tmcrypto.PubKey, error) { pk, err := v.ConsPubKey() if err != nil { - return nil, err + return tmcrypto.PubKey{}, err } return cryptocodec.ToTmPubKeyInterface(pk) diff --git a/sei-tendermint/abci/example/kvstore/helpers.go b/sei-tendermint/abci/example/kvstore/helpers.go index 8a2a8a35b1..4ad499f87a 100644 --- a/sei-tendermint/abci/example/kvstore/helpers.go +++ b/sei-tendermint/abci/example/kvstore/helpers.go @@ -5,27 +5,20 @@ import ( mrand "math/rand" "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto" tmrand "github.com/tendermint/tendermint/libs/rand" ) -// RandVal creates one random validator, with a key derived -// from the input value -func RandVal(i int) types.ValidatorUpdate { - pubkey := tmrand.Bytes(32) - // Random value between [0, 2^16 - 1] - power := mrand.Uint32() & (1<<16 - 1) // nolint:gosec // G404: Use of weak random number generator - v := types.UpdateValidator(pubkey, int64(power), "") - return v -} - // RandVals returns a list of cnt validators for initializing // the application. Note that the keys are deterministically // derived from the index in the array, while the power is // random (Change this if not desired) func RandVals(cnt int) []types.ValidatorUpdate { res := make([]types.ValidatorUpdate, cnt) - for i := 0; i < cnt; i++ { - res[i] = RandVal(i) + for i := range res { + // Random value between [0, 2^16 - 1] + power := mrand.Uint32() & (1<<16 - 1) // nolint:gosec // G404: Use of weak random number generator + res[i] = types.UpdateValidator(crypto.PubKey(tmrand.Bytes(len(crypto.PubKey{}))), int64(power), "") } return res } diff --git a/sei-tendermint/abci/example/kvstore/kvstore.go b/sei-tendermint/abci/example/kvstore/kvstore.go index 5b7fc798e1..14f21720bc 100644 --- a/sei-tendermint/abci/example/kvstore/kvstore.go +++ b/sei-tendermint/abci/example/kvstore/kvstore.go @@ -17,6 +17,7 @@ import ( "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/libs/log" + "github.com/tendermint/tendermint/crypto" cryptoproto "github.com/tendermint/tendermint/proto/tendermint/crypto" "github.com/tendermint/tendermint/version" ) @@ -371,7 +372,7 @@ func (app *Application) execValidatorTx(tx []byte) *types.ExecTxResult { } // update - return app.updateValidator(types.UpdateValidator(pubkey, power, "")) + return app.updateValidator(types.UpdateValidator(crypto.PubKey(pubkey), power, "")) } // add, update, or remove a validator diff --git a/sei-tendermint/abci/tests/server/client.go b/sei-tendermint/abci/tests/server/client.go index 46deafcb03..03af5910da 100644 --- a/sei-tendermint/abci/tests/server/client.go +++ b/sei-tendermint/abci/tests/server/client.go @@ -10,13 +10,13 @@ import ( abciclient "github.com/tendermint/tendermint/abci/client" "github.com/tendermint/tendermint/abci/types" tmrand "github.com/tendermint/tendermint/libs/rand" + "github.com/tendermint/tendermint/crypto" ) func InitChain(ctx context.Context, client abciclient.Client) error { - total := 10 - vals := make([]types.ValidatorUpdate, total) - for i := 0; i < total; i++ { - pubkey := tmrand.Bytes(33) + vals := make([]types.ValidatorUpdate, 10) + for i := range vals { + pubkey := crypto.PubKey(tmrand.Bytes(len(crypto.PubKey{}))) // nolint:gosec // G404: Use of weak random number generator power := mrand.Int() vals[i] = types.UpdateValidator(pubkey, int64(power), "") diff --git a/sei-tendermint/abci/types/pubkey.go b/sei-tendermint/abci/types/pubkey.go index 36d755bb5b..c556e11f3b 100644 --- a/sei-tendermint/abci/types/pubkey.go +++ b/sei-tendermint/abci/types/pubkey.go @@ -1,22 +1,13 @@ package types import ( - fmt "fmt" - - "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/encoding" ) -func Ed25519ValidatorUpdate(pk []byte, power int64) ValidatorUpdate { +func UpdateValidator(pk crypto.PubKey, power int64, keyType string) ValidatorUpdate { return ValidatorUpdate{ - PubKey: encoding.PubKeyToProto(ed25519.PubKey(pk)), + PubKey: encoding.PubKeyToProto(pk), Power: power, } } - -func UpdateValidator(pk []byte, power int64, keyType string) ValidatorUpdate { - if keyType != "" && keyType != ed25519.KeyType { - panic(fmt.Sprintf("key type %s not supported", keyType)) - } - return Ed25519ValidatorUpdate(pk, power) -} diff --git a/sei-tendermint/crypto/ed25519/ed25519.go b/sei-tendermint/crypto/ed25519/ed25519.go index ee451a005e..382b608050 100644 --- a/sei-tendermint/crypto/ed25519/ed25519.go +++ b/sei-tendermint/crypto/ed25519/ed25519.go @@ -35,7 +35,9 @@ var cachingVerifier = cache.NewVerifier(cache.NewLRUCache(cacheSize)) func init() { tmjson.RegisterType(PubKey{}, PubKeyName) + tmjson.RegisterType(PrivKey{}, PubKeyName) jsontypes.MustRegister(PubKey{}) + jsontypes.MustRegister(PrivKey{}) } type Seed [ed25519.SeedSize]byte @@ -45,7 +47,7 @@ type PrivKey struct { } // TypeTag satisfies the jsontypes.Tagged interface. -func (k PrivKey) TypeTag() string { return PrivKeyName } +func (PrivKey) TypeTag() string { return PrivKeyName } // Bytes returns the privkey byte format. func (k PrivKey) SecretBytes() []byte { return k.raw } @@ -64,7 +66,7 @@ func SigFromBytes(raw []byte) (Sig,error) { func (k PrivKey) Sign(msg []byte) Sig { return Sig(ed25519.Sign(k.raw, msg)) } // PubKey gets the corresponding public key from the private key. -func (k PrivKey) PubKey() PubKey { return PubKey(k.raw.Public().([]byte)) } +func (k PrivKey) PubKey() PubKey { return PubKey(k.raw.Public().(ed25519.PublicKey)) } func (k PrivKey) Type() string { return KeyType } @@ -82,6 +84,14 @@ func PrivKeyFromSeed(seed Seed) PrivKey { return PrivKey{ed25519.NewKeyFromSeed(seed[:])} } +// GenPrivKeyFromSecret hashes the secret with SHA2, and uses +// that 32 byte output to create the private key. +// NOTE: secret should be the output of a KDF like bcrypt, +// if it's derived from user input. +func GenPrivKeyFromSecret(secret []byte) PrivKey { + return PrivKeyFromSeed(Seed(sha256.Sum256(secret))) +} + //------------------------------------- // PubKey implements the Ed25519 signature scheme. @@ -89,7 +99,7 @@ type PubKey [ed25519.PublicKeySize]byte func PubKeyFromBytes(raw []byte) (PubKey,error) { if len(raw)!=len(PubKey{}) { - return PubKey{},errors.New("invalid signature length") + return PubKey{},errors.New("invalid pubkey length") } return PubKey(raw),nil } @@ -105,7 +115,7 @@ func (k PubKey) Address() tmbytes.HexBytes { func (k PubKey) Verify(msg []byte, sig Sig) error { if !cachingVerifier.VerifyWithOptions(k[:], msg, sig[:], verifyOptions) { - return errors.New("invalid signature") + return errors.New("invalid signature") } return nil } diff --git a/sei-tendermint/crypto/encoding/codec.go b/sei-tendermint/crypto/encoding/codec.go index e13a91f8ad..b38d568a21 100644 --- a/sei-tendermint/crypto/encoding/codec.go +++ b/sei-tendermint/crypto/encoding/codec.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/internal/jsontypes" cryptoproto "github.com/tendermint/tendermint/proto/tendermint/crypto" ) @@ -22,10 +23,7 @@ func PubKeyToProto(k crypto.PubKey) cryptoproto.PublicKey { func PubKeyFromProto(k cryptoproto.PublicKey) (crypto.PubKey, error) { switch k := k.Sum.(type) { case *cryptoproto.PublicKey_Ed25519: - if got,want:=len(k.Ed25519),len(crypto.PubKey{}); got!=want { - return crypto.PubKey{}, fmt.Errorf("invalid size for PubKeyEd25519. Got %d, expected %d",got,want) - } - return crypto.PubKey(k.Ed25519), nil + return ed25519.PubKeyFromBytes(k.Ed25519) default: return crypto.PubKey{}, fmt.Errorf("fromproto: key type %v is not supported", k) } diff --git a/sei-tendermint/internal/consensus/common_test.go b/sei-tendermint/internal/consensus/common_test.go index f4cedcb62e..490523ca32 100644 --- a/sei-tendermint/internal/consensus/common_test.go +++ b/sei-tendermint/internal/consensus/common_test.go @@ -144,11 +144,8 @@ func (vs *validatorStub) signVote( v.Signature = vs.lastVote.Signature[:] v.Timestamp = vs.lastVote.Timestamp } - sig,err := crypto.SigFromBytes(v.Signature) - if err!=nil { return nil,err } - vote.Signature = sig + vote.Signature = crypto.Sig(v.Signature) vote.Timestamp = v.Timestamp - return vote, nil } @@ -261,10 +258,7 @@ func decideProposal( proposal = types.NewProposal(height, round, polRound, propBlockID, block.Header.Time, block.GetTxKeys(), block.Header, block.LastCommit, block.Evidence, address) p := proposal.ToProto() require.NoError(t, vs.SignProposal(ctx, chainID, p)) - sig,err := crypto.SigFromBytes(p.Signature) - require.NoError(t, err) - proposal.Signature = sig - + proposal.Signature = crypto.Sig(p.Signature) return } diff --git a/sei-tendermint/internal/consensus/invalid_test.go b/sei-tendermint/internal/consensus/invalid_test.go index fae62b8fc5..5e0fe90549 100644 --- a/sei-tendermint/internal/consensus/invalid_test.go +++ b/sei-tendermint/internal/consensus/invalid_test.go @@ -147,10 +147,7 @@ func invalidDoPrevoteFunc( p := precommit.ToProto() require.NoError(t, pv.SignVote(ctx, cs.state.ChainID, p)) - - sig,err := crypto.SigFromBytes(p.Signature) - require.NoError(t,err) - precommit.Signature = sig + precommit.Signature = crypto.Sig(p.Signature) t.Logf("disable priv val so we don't do normal votes") cs.privValidator = utils.None[types.PrivValidator]() cs.mtx.Unlock() diff --git a/sei-tendermint/internal/consensus/memory_limit_test.go b/sei-tendermint/internal/consensus/memory_limit_test.go index 61e193d8dd..ed5359a0c4 100644 --- a/sei-tendermint/internal/consensus/memory_limit_test.go +++ b/sei-tendermint/internal/consensus/memory_limit_test.go @@ -8,8 +8,16 @@ import ( "github.com/tendermint/tendermint/libs/log" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/crypto" ) +func makeSig(data string) crypto.Sig { + var sig crypto.Sig + n := min(len(sig),len(data)) + copy(sig[:n],[]byte(data[:n])) + return sig +} + func TestPeerStateMemoryLimits(t *testing.T) { logger := log.NewTestingLogger(t) peerID := types.NodeID("test-peer") @@ -47,7 +55,7 @@ func TestPeerStateMemoryLimits(t *testing.T) { POLRound: -1, BlockID: blockID, Timestamp: time.Now(), - Signature: []byte("test-signature"), + Signature: makeSig("test-signature"), } ps.SetHasProposal(proposal) if tc.expectError { diff --git a/sei-tendermint/internal/consensus/msgs_test.go b/sei-tendermint/internal/consensus/msgs_test.go index 2c84868824..f8a58dc4df 100644 --- a/sei-tendermint/internal/consensus/msgs_test.go +++ b/sei-tendermint/internal/consensus/msgs_test.go @@ -69,7 +69,7 @@ func TestMsgToProto(t *testing.T) { POLRound: 1, BlockID: bi, Timestamp: time.Now(), - Signature: tmrand.Bytes(20), + Signature: makeSig("test-sig"), Header: header, Evidence: types.EvidenceList{}, LastCommit: &types.Commit{Signatures: []types.CommitSig{}}, @@ -339,7 +339,7 @@ func TestConsMsgsVectors(t *testing.T) { POLRound: 1, BlockID: bi, Timestamp: date, - Signature: []byte("add_more_exclamation"), + Signature: makeSig("add_more_exclamation"), } pbProposal := proposal.ToProto() diff --git a/sei-tendermint/internal/consensus/pbts_test.go b/sei-tendermint/internal/consensus/pbts_test.go index 0ed1dfd9c2..48d3338e97 100644 --- a/sei-tendermint/internal/consensus/pbts_test.go +++ b/sei-tendermint/internal/consensus/pbts_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/abci/example/kvstore" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/internal/eventbus" tmpubsub "github.com/tendermint/tendermint/internal/pubsub" "github.com/tendermint/tendermint/internal/test/factory" @@ -224,7 +225,7 @@ func (p *pbtsTestHarness) nextHeight(ctx context.Context, t *testing.T, proposer } time.Sleep(time.Until(deliverTime)) - prop.Signature = tp.Signature + prop.Signature = crypto.Sig(tp.Signature) if err := p.observedState.SetProposalAndBlock(ctx, prop, b, ps, "peerID"); err != nil { t.Fatal(err) } diff --git a/sei-tendermint/internal/consensus/peer_state_test.go b/sei-tendermint/internal/consensus/peer_state_test.go index 9db8e15b86..24047d4377 100644 --- a/sei-tendermint/internal/consensus/peer_state_test.go +++ b/sei-tendermint/internal/consensus/peer_state_test.go @@ -141,7 +141,7 @@ func TestSetHasProposal(t *testing.T) { Hash: crypto.CRandBytes(crypto.HashSize), }, }, - Signature: []byte("signature"), + Signature: makeSig("signature"), } ps3.SetHasProposal(tooLargeTotalProposal) require.False(t, ps3.PRS.Proposal, "Proposal with too large Total should be silently ignored") @@ -159,7 +159,7 @@ func TestSetHasProposal(t *testing.T) { Hash: crypto.CRandBytes(crypto.HashSize), }, }, - Signature: []byte("signature"), + Signature: makeSig("signature"), } ps.SetHasProposal(validProposal) require.True(t, ps.PRS.Proposal, "Valid proposal should be accepted") @@ -178,7 +178,7 @@ func TestSetHasProposal(t *testing.T) { Hash: crypto.CRandBytes(crypto.HashSize), }, }, - Signature: []byte("signature"), + Signature: makeSig("signature"), } ps2.SetHasProposal(differentProposal) require.True(t, ps2.PRS.Proposal, "Proposal with matching height should be accepted") @@ -193,7 +193,7 @@ func TestSetHasProposalMemoryLimit(t *testing.T) { hash := crypto.CRandBytes(crypto.HashSize) // Create a dummy signature - sig := crypto.CRandBytes(types.MaxSignatureSize) + sig := makeSig("dummy-sig") // Create a proposal with a large PartSetHeader.Total proposal := &types.Proposal{ @@ -349,7 +349,7 @@ func TestSetHasProposalEdgeCases(t *testing.T) { }, }, Timestamp: time.Now(), - Signature: []byte("test-signature"), + Signature: makeSig("test-signature"), }, expectProposal: false, // Should silently ignore expectPanic: false, @@ -373,7 +373,7 @@ func TestSetHasProposalEdgeCases(t *testing.T) { }, }, Timestamp: time.Now(), - Signature: []byte("test-signature"), + Signature: makeSig("test-signature"), }, expectProposal: false, expectPanic: false, @@ -398,7 +398,7 @@ func TestSetHasProposalEdgeCases(t *testing.T) { }, }, Timestamp: time.Now(), - Signature: []byte("test-signature"), + Signature: makeSig("test-signature"), }, expectProposal: true, // Should remain true expectPanic: false, @@ -422,7 +422,7 @@ func TestSetHasProposalEdgeCases(t *testing.T) { }, }, Timestamp: time.Now(), - Signature: []byte("test-signature"), + Signature: makeSig("test-signature"), }, expectProposal: true, // Should be set expectPanic: false, diff --git a/sei-tendermint/internal/consensus/reactor_test.go b/sei-tendermint/internal/consensus/reactor_test.go index d3eb9db4c8..f78f37ea45 100644 --- a/sei-tendermint/internal/consensus/reactor_test.go +++ b/sei-tendermint/internal/consensus/reactor_test.go @@ -501,8 +501,7 @@ func TestReactorValidatorSetChanges(t *testing.T) { pv, _ := states[nodeIdx].privValidator.Get() key, err := pv.GetPubKey(ctx) require.NoError(t, err) - keyProto, err := encoding.PubKeyToProto(key) - require.NoError(t, err) + keyProto := encoding.PubKeyToProto(key) newPower := int64(rng.Intn(100000)) tx := kvstore.MakeValSetChangeTx(keyProto, newPower) require.NoError(t, finalizeTx(ctx, valSet, blocksSubs, states, tx)) @@ -537,7 +536,7 @@ func TestReactorMemoryLimitCoverage(t *testing.T) { }, }, Timestamp: time.Now(), - Signature: []byte("test-signature"), + Signature: makeSig("test-signature"), } // Test direct SetHasProposal call (this is what reactor calls) diff --git a/sei-tendermint/internal/consensus/replay_test.go b/sei-tendermint/internal/consensus/replay_test.go index 12c2b7ca5a..1e3f7860e7 100644 --- a/sei-tendermint/internal/consensus/replay_test.go +++ b/sei-tendermint/internal/consensus/replay_test.go @@ -37,6 +37,7 @@ import ( "github.com/tendermint/tendermint/privval" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/crypto" ) // These tests ensure we can always recover from failure at any part of the consensus process. @@ -342,8 +343,7 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite { pv, _ := css[nVals].privValidator.Get() newValidatorPubKey1, err := pv.GetPubKey(ctx) require.NoError(t, err) - valPubKey1ABCI, err := encoding.PubKeyToProto(newValidatorPubKey1) - require.NoError(t, err) + valPubKey1ABCI := encoding.PubKeyToProto(newValidatorPubKey1) newValidatorTx1 := kvstore.MakeValSetChangeTx(valPubKey1ABCI, testMinPower) err = assertMempool(t, css[0].txNotifier).CheckTx(ctx, newValidatorTx1, nil, mempool.TxInfo{}) assert.NoError(t, err) @@ -360,7 +360,7 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite { if err := vss[1].SignProposal(ctx, cfg.ChainID(), p); err != nil { t.Fatal("failed to sign bad proposal", err) } - proposal.Signature = p.Signature + proposal.Signature = crypto.Sig(p.Signature) // set the proposal block if err := css[0].SetProposalAndBlock(ctx, proposal, propBlock, propBlockParts, "some peer"); err != nil { @@ -379,8 +379,7 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite { pv, _ = css[nVals].privValidator.Get() updateValidatorPubKey1, err := pv.GetPubKey(ctx) require.NoError(t, err) - updatePubKey1ABCI, err := encoding.PubKeyToProto(updateValidatorPubKey1) - require.NoError(t, err) + updatePubKey1ABCI := encoding.PubKeyToProto(updateValidatorPubKey1) updateValidatorTx1 := kvstore.MakeValSetChangeTx(updatePubKey1ABCI, 25) err = assertMempool(t, css[0].txNotifier).CheckTx(ctx, updateValidatorTx1, nil, mempool.TxInfo{}) assert.NoError(t, err) @@ -396,7 +395,7 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite { if err := vss[2].SignProposal(ctx, cfg.ChainID(), p); err != nil { t.Fatal("failed to sign bad proposal", err) } - proposal.Signature = p.Signature + proposal.Signature = crypto.Sig(p.Signature) // set the proposal block if err := css[0].SetProposalAndBlock(ctx, proposal, propBlock, propBlockParts, "some peer"); err != nil { @@ -415,16 +414,14 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite { pv, _ = css[nVals+1].privValidator.Get() newValidatorPubKey2, err := pv.GetPubKey(ctx) require.NoError(t, err) - newVal2ABCI, err := encoding.PubKeyToProto(newValidatorPubKey2) - require.NoError(t, err) + newVal2ABCI := encoding.PubKeyToProto(newValidatorPubKey2) newValidatorTx2 := kvstore.MakeValSetChangeTx(newVal2ABCI, testMinPower) err = assertMempool(t, css[0].txNotifier).CheckTx(ctx, newValidatorTx2, nil, mempool.TxInfo{}) assert.NoError(t, err) pv, _ = css[nVals+2].privValidator.Get() newValidatorPubKey3, err := pv.GetPubKey(ctx) require.NoError(t, err) - newVal3ABCI, err := encoding.PubKeyToProto(newValidatorPubKey3) - require.NoError(t, err) + newVal3ABCI := encoding.PubKeyToProto(newValidatorPubKey3) newValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, testMinPower) err = assertMempool(t, css[0].txNotifier).CheckTx(ctx, newValidatorTx3, nil, mempool.TxInfo{}) assert.NoError(t, err) @@ -446,7 +443,7 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite { cssPubKey, err := pv.GetPubKey(ctx) require.NoError(t, err) - if vsPubKey.Equals(cssPubKey) { + if vsPubKey==cssPubKey { return i } } @@ -463,7 +460,7 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite { if err := vss[3].SignProposal(ctx, cfg.ChainID(), p); err != nil { t.Fatal("failed to sign bad proposal", err) } - proposal.Signature = p.Signature + proposal.Signature = crypto.Sig(p.Signature) // set the proposal block if err := css[0].SetProposalAndBlock(ctx, proposal, propBlock, propBlockParts, "some peer"); err != nil { @@ -536,7 +533,7 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite { if err := vss[1].SignProposal(ctx, cfg.ChainID(), p); err != nil { t.Fatal("failed to sign bad proposal", err) } - proposal.Signature = p.Signature + proposal.Signature = crypto.Sig(p.Signature) // set the proposal block if err := css[0].SetProposalAndBlock(ctx, proposal, propBlock, propBlockParts, "some peer"); err != nil { diff --git a/sei-tendermint/internal/consensus/state_test.go b/sei-tendermint/internal/consensus/state_test.go index 3df7ab3054..e217a2a0f7 100644 --- a/sei-tendermint/internal/consensus/state_test.go +++ b/sei-tendermint/internal/consensus/state_test.go @@ -250,10 +250,8 @@ func TestStateBadProposal(t *testing.T) { require.NoError(t, err) proposal := types.NewProposal(vs2.Height, round, -1, blockID, propBlock.Header.Time, propBlock.GetTxKeys(), propBlock.Header, propBlock.LastCommit, propBlock.Evidence, pubKey.Address()) p := proposal.ToProto() - err = vs2.SignProposal(ctx, config.ChainID(), p) - require.NoError(t, err) - - proposal.Signature = p.Signature + require.NoError(t,vs2.SignProposal(ctx, config.ChainID(), p)) + proposal.Signature = crypto.Sig(p.Signature) // set the proposal block err = cs1.SetProposalAndBlock(ctx, proposal, propBlock, propBlockParts, "some peer") @@ -308,9 +306,8 @@ func TestStateOversizedBlock(t *testing.T) { require.NoError(t, err) proposal := types.NewProposal(height, round, -1, blockID, propBlock.Header.Time, propBlock.GetTxKeys(), propBlock.Header, propBlock.LastCommit, propBlock.Evidence, pubKey.Address()) p := proposal.ToProto() - err = vs2.SignProposal(ctx, config.ChainID(), p) - require.NoError(t, err) - proposal.Signature = p.Signature + require.NoError(t, vs2.SignProposal(ctx, config.ChainID(), p)) + proposal.Signature = crypto.Sig(p.Signature) totalBytes := 0 for i := 0; i < int(propBlockParts.Total()); i++ { @@ -808,9 +805,9 @@ func TestStateLock_POLRelock(t *testing.T) { require.NoError(t, err) propR1 := types.NewProposal(height, round, cs1.roundState.ValidRound(), blockID, theBlock.Header.Time, theBlock.GetTxKeys(), theBlock.Header, theBlock.LastCommit, theBlock.Evidence, pubKey.Address()) p := propR1.ToProto() - err = vs2.SignProposal(ctx, cs1.state.ChainID, p) - require.NoError(t, err) - propR1.Signature = p.Signature + require.NoError(t, vs2.SignProposal(ctx, cs1.state.ChainID, p)) + propR1.Signature = crypto.Sig(p.Signature) + err = cs1.SetProposalAndBlock(ctx, propR1, theBlock, theBlockParts, "") require.NoError(t, err) @@ -1488,7 +1485,7 @@ func TestStateLock_POLSafety2(t *testing.T) { err = vs3.SignProposal(ctx, config.ChainID(), p) require.NoError(t, err) - newProp.Signature = p.Signature + newProp.Signature = crypto.Sig(p.Signature) err = cs1.SetProposalAndBlock(ctx, newProp, propBlock0, propBlockParts0, "some peer") require.NoError(t, err) @@ -1625,7 +1622,7 @@ func TestState_PrevotePOLFromPreviousRound(t *testing.T) { p := propR2.ToProto() err = vs3.SignProposal(ctx, cs1.state.ChainID, p) require.NoError(t, err) - propR2.Signature = p.Signature + propR2.Signature = crypto.Sig(p.Signature) // cs1 receives a proposal for D, the block that received a POL in round 1. err = cs1.SetProposalAndBlock(ctx, propR2, propBlockR1, propBlockR1Parts, "") @@ -2445,7 +2442,7 @@ func TestGossipTransactionKeyOnlyConfig(t *testing.T) { p := proposal.ToProto() err = vs2.SignProposal(ctx, config.ChainID(), p) require.NoError(t, err) - proposal.Signature = p.Signature + proposal.Signature = crypto.Sig(p.Signature) proposalMsg := ProposalMessage{&proposal} peerID, err := types.NewNodeID("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") @@ -2560,7 +2557,7 @@ func TestStateTimestamp_ProposalNotMatch(t *testing.T) { p := proposal.ToProto() err = vs2.SignProposal(ctx, config.ChainID(), p) require.NoError(t, err) - proposal.Signature = p.Signature + proposal.Signature = crypto.Sig(p.Signature) require.NoError(t, cs1.SetProposalAndBlock(ctx, proposal, propBlock, propBlockParts, "some peer")) startTestRound(ctx, cs1, height, round) @@ -2607,7 +2604,7 @@ func TestStateTimestamp_ProposalMatch(t *testing.T) { p := proposal.ToProto() err = vs2.SignProposal(ctx, config.ChainID(), p) require.NoError(t, err) - proposal.Signature = p.Signature + proposal.Signature = crypto.Sig(p.Signature) require.NoError(t, cs1.SetProposalAndBlock(ctx, proposal, propBlock, propBlockParts, "some peer")) startTestRound(ctx, cs1, height, round) diff --git a/sei-tendermint/internal/consensus/types/height_vote_set_test.go b/sei-tendermint/internal/consensus/types/height_vote_set_test.go index b92dfc7b98..e44cb4d785 100644 --- a/sei-tendermint/internal/consensus/types/height_vote_set_test.go +++ b/sei-tendermint/internal/consensus/types/height_vote_set_test.go @@ -83,12 +83,7 @@ func makeVoteHR( } v := vote.ToProto() - err = privVal.SignVote(ctx, chainID, v) - require.NoError(t, err, "Error signing vote") - - sig,err := crypto.SigFromBytes(v.Signature) - require.NoError(t,err) - vote.Signature = sig - + require.NoError(t, privVal.SignVote(ctx, chainID, v)) + vote.Signature = crypto.Sig(v.Signature) return vote } diff --git a/sei-tendermint/internal/evidence/pool_test.go b/sei-tendermint/internal/evidence/pool_test.go index 9eb2612bd2..f36f1382b1 100644 --- a/sei-tendermint/internal/evidence/pool_test.go +++ b/sei-tendermint/internal/evidence/pool_test.go @@ -11,6 +11,7 @@ import ( dbm "github.com/tendermint/tm-db" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/internal/eventbus" "github.com/tendermint/tendermint/internal/evidence" "github.com/tendermint/tendermint/internal/evidence/mocks" @@ -34,6 +35,12 @@ var ( defaultEvidenceMaxBytes int64 = 1000 ) +func makeEvidenceSignature(data []byte) crypto.Sig { + var sig crypto.Sig + copy(sig[:], data) + return sig +} + func startPool(t *testing.T, pool *evidence.Pool, store sm.Store) { t.Helper() state, err := store.Load() @@ -582,7 +589,7 @@ func makeCommit(height int64, valAddr []byte) *types.Commit { BlockIDFlag: types.BlockIDFlagCommit, ValidatorAddress: valAddr, Timestamp: defaultEvidenceTime, - Signature: []byte("Signature"), + Signature: makeEvidenceSignature([]byte("Signature")), }}, } } diff --git a/sei-tendermint/internal/evidence/verify_test.go b/sei-tendermint/internal/evidence/verify_test.go index d4751c9c6f..9af64742a6 100644 --- a/sei-tendermint/internal/evidence/verify_test.go +++ b/sei-tendermint/internal/evidence/verify_test.go @@ -421,8 +421,8 @@ func TestVerifyDuplicateVoteEvidence(t *testing.T) { err = val2.SignVote(ctx, chainID, bv) require.NoError(t, err) - vote1.Signature = v1.Signature - badVote.Signature = bv.Signature + vote1.Signature = crypto.Sig(v1.Signature) + badVote.Signature = crypto.Sig(bv.Signature) cases := []voteData{ {vote1, makeVote(ctx, t, val, chainID, 0, 10, 2, 1, blockID2, defaultEvidenceTime), true}, // different block ids @@ -605,7 +605,7 @@ func makeVote( vpb := v.ToProto() err = val.SignVote(ctx, chainID, vpb) require.NoError(t, err) - v.Signature = vpb.Signature + v.Signature = crypto.Sig(vpb.Signature) return v } diff --git a/sei-tendermint/internal/jsontypes/jsontypes.go b/sei-tendermint/internal/jsontypes/jsontypes.go index c10fcb6990..71c110660b 100644 --- a/sei-tendermint/internal/jsontypes/jsontypes.go +++ b/sei-tendermint/internal/jsontypes/jsontypes.go @@ -23,6 +23,7 @@ import ( // is used to distinguish objects of that type. type Tagged interface { TypeTag() string + Marshal() ([]byte,error) } // registry records the mapping from type tags to value types. diff --git a/sei-tendermint/internal/libs/wal/log_test.go b/sei-tendermint/internal/libs/wal/log_test.go index 55666fda71..41e4211b64 100644 --- a/sei-tendermint/internal/libs/wal/log_test.go +++ b/sei-tendermint/internal/libs/wal/log_test.go @@ -11,23 +11,10 @@ import ( "github.com/tendermint/tendermint/libs/utils/require" ) -func OrPanic(err error) { - if err != nil { - panic(err) - } -} - -func OrPanic1[T any](v T, err error) T { - if err != nil { - panic(err) - } - return v -} - func dump(l *Log) [][]byte { var entries [][]byte for offset := l.MinOffset(); offset <= 0; offset++ { - entries = append(entries, OrPanic1(l.ReadFile(offset))...) + entries = append(entries, utils.OrPanic1(l.ReadFile(offset))...) } return entries } @@ -36,7 +23,7 @@ func TestReadAfterAppend(t *testing.T) { headPath := path.Join(t.TempDir(), "testlog") cfg := &Config{} entry := []byte{25} - l := OrPanic1(OpenLog(headPath, cfg)) + l := utils.OrPanic1(OpenLog(headPath, cfg)) defer l.Close() // Append minimal amount of data. require.NoError(t, l.Append(entry)) @@ -52,7 +39,7 @@ func TestAppendRead(t *testing.T) { cfg := &Config{FileSizeLimit: 1000} var want [][]byte t.Logf("Open a log") - l := OrPanic1(OpenLog(headPath, cfg)) + l := utils.OrPanic1(OpenLog(headPath, cfg)) // Wrapped defer, since we assign to l multiple times. defer func() { l.Close() }() @@ -60,7 +47,7 @@ func TestAppendRead(t *testing.T) { t.Logf("ITERATION %v", it) if reopen { l.Close() - l = OrPanic1(OpenLog(headPath, cfg)) + l = utils.OrPanic1(OpenLog(headPath, cfg)) } t.Logf("Opening a log again should fail - previous instance holds a lock on it.") _, err := OpenLog(headPath, cfg) @@ -77,7 +64,7 @@ func TestAppendRead(t *testing.T) { t.Logf("Read entries.") if reopen { l.Close() - l = OrPanic1(OpenLog(headPath, cfg)) + l = utils.OrPanic1(OpenLog(headPath, cfg)) } require.NoError(t, utils.TestDiff(want, dump(l))) } @@ -90,7 +77,7 @@ func TestNoSync(t *testing.T) { headPath := path.Join(t.TempDir(), "testlog") cfg := &Config{FileSizeLimit: 1000} - l := OrPanic1(OpenLog(headPath, cfg)) + l := utils.OrPanic1(OpenLog(headPath, cfg)) defer l.Close() // Insert entries and sync in the middle. var want [][]byte @@ -106,7 +93,7 @@ func TestNoSync(t *testing.T) { l.Close() // Read Entries - expect entries at least to the sync point. - l = OrPanic1(OpenLog(headPath, cfg)) + l = utils.OrPanic1(OpenLog(headPath, cfg)) defer l.Close() got := dump(l) require.True(t, len(got) >= syncEntries) @@ -119,7 +106,7 @@ func TestTruncation(t *testing.T) { cfg := &Config{FileSizeLimit: 1000} // Insert entries. - l := OrPanic1(OpenLog(headPath, cfg)) + l := utils.OrPanic1(OpenLog(headPath, cfg)) defer l.Close() var want [][]byte for range 100 { @@ -136,7 +123,7 @@ func TestTruncation(t *testing.T) { require.NoError(t, os.Truncate(headPath, fi.Size()/2)) // Read Entries - expect a prefix. - l = OrPanic1(OpenLog(headPath, cfg)) + l = utils.OrPanic1(OpenLog(headPath, cfg)) defer l.Close() got := dump(l) require.NoError(t, utils.TestDiff(want[:len(got)], got)) @@ -150,7 +137,7 @@ func TestSizeLimitsAndOffsets(t *testing.T) { cfg := &Config{FileSizeLimit: 100, TotalSizeLimit: 3000} // Populate the log. - l := OrPanic1(OpenLog(headPath, cfg)) + l := utils.OrPanic1(OpenLog(headPath, cfg)) defer l.Close() minEntrySize := int64(10) maxEntrySize := int64(20) @@ -185,7 +172,7 @@ func TestSizeLimitsAndOffsets(t *testing.T) { require.True(t, total >= cfg.TotalSizeLimit-cfg.FileSizeLimit-maxEntrySize-headerSize) // Read the log, expect a suffix of entries. - l = OrPanic1(OpenLog(headPath, cfg)) + l = utils.OrPanic1(OpenLog(headPath, cfg)) defer l.Close() got := dump(l) require.NoError(t, utils.TestDiff(want[len(want)-len(got):], got)) @@ -202,10 +189,10 @@ func BenchmarkAppendSync(b *testing.B) { for range 10000 { entries = append(entries, utils.GenBytes(rng, rng.Intn(100)+1000)) } - l := OrPanic1(OpenLog(headPath, cfg)) + l := utils.OrPanic1(OpenLog(headPath, cfg)) defer l.Close() for i := 0; b.Loop(); i++ { - OrPanic(l.Append(entries[i%len(entries)])) - OrPanic(l.Sync()) + utils.OrPanic(l.Append(entries[i%len(entries)])) + utils.OrPanic(l.Sync()) } } diff --git a/sei-tendermint/internal/p2p/address_test.go b/sei-tendermint/internal/p2p/address_test.go index d1a6dccb3b..72fcf34f89 100644 --- a/sei-tendermint/internal/p2p/address_test.go +++ b/sei-tendermint/internal/p2p/address_test.go @@ -38,9 +38,8 @@ func TestNewNodeID(t *testing.T) { } func TestNewNodeIDFromPubKey(t *testing.T) { - privKey := ed25519.GenPrivKeyFromSecret([]byte("foo")) + privKey := ed25519.PrivKeyFromSeed(ed25519.Seed{43,55,33}) nodeID := types.NodeIDFromPubKey(privKey.PubKey()) - require.Equal(t, types.NodeID("045f5600654182cfeaccfe6cb19f0642e8a59898"), nodeID) require.NoError(t, nodeID.Validate()) } diff --git a/sei-tendermint/internal/p2p/conn/evil_secret_connection_test.go b/sei-tendermint/internal/p2p/conn/evil_secret_connection_test.go index 3ad61bb1ca..c7cd7bc84b 100644 --- a/sei-tendermint/internal/p2p/conn/evil_secret_connection_test.go +++ b/sei-tendermint/internal/p2p/conn/evil_secret_connection_test.go @@ -113,11 +113,8 @@ func (c *evilConn) Read(data []byte) (n int, err error) { case 1: signature := c.signChallenge() if !c.badAuthSignature { - pkpb, err := encoding.PubKeyToProto(c.privKey.PubKey()) - if err != nil { - panic(err) - } - bz, err := protoio.MarshalDelimited(&tmp2p.AuthSigMessage{PubKey: pkpb, Sig: signature}) + pkpb := encoding.PubKeyToProto(c.privKey.PubKey()) + bz, err := protoio.MarshalDelimited(&tmp2p.AuthSigMessage{PubKey: pkpb, Sig: signature[:]}) if err != nil { panic(err) } @@ -180,7 +177,7 @@ func (c *evilConn) Close() error { return nil } -func (c *evilConn) signChallenge() []byte { +func (c *evilConn) signChallenge() ed25519.Sig { // Sort by lexical order. loEphPub, hiEphPub := sort32(c.locEphPub, c.remEphPub) @@ -231,12 +228,7 @@ func (c *evilConn) signChallenge() []byte { c.buffer = b // Sign the challenge bytes for authentication. - locSignature, err := signChallenge(&challenge, c.privKey) - if err != nil { - panic(err) - } - - return locSignature + return signChallenge(&challenge, c.privKey) } // TestMakeSecretConnection creates an evil connection and tests that diff --git a/sei-tendermint/internal/p2p/peermanager_test.go b/sei-tendermint/internal/p2p/peermanager_test.go index f26f5e1719..3c357da83c 100644 --- a/sei-tendermint/internal/p2p/peermanager_test.go +++ b/sei-tendermint/internal/p2p/peermanager_test.go @@ -55,10 +55,10 @@ func makePeerManager(selfID types.NodeID, options *RouterOptions) *peerManager[* return newPeerManager[*fakeConn](selfID, options) } -var selfID = types.NodeIDFromPubKey(ed25519.GenPrivKeyFromSecret([]byte("selfID")).PubKey()) +var selfID = types.NodeIDFromPubKey(ed25519.PrivKeyFromSeed(ed25519.Seed{12,43}).PubKey()) func makeKey(rng utils.Rng) ed25519.PrivKey { - return ed25519.GenPrivKeyFromSecret(utils.GenBytes(rng, 32)) + return ed25519.PrivKeyFromSeed(ed25519.Seed(utils.GenBytes(rng, len(ed25519.Seed{})))) } func makeNodeID(rng utils.Rng) types.NodeID { diff --git a/sei-tendermint/internal/rpc/core/env.go b/sei-tendermint/internal/rpc/core/env.go index ed5ee13979..cbdc61037f 100644 --- a/sei-tendermint/internal/rpc/core/env.go +++ b/sei-tendermint/internal/rpc/core/env.go @@ -13,6 +13,7 @@ import ( abciclient "github.com/tendermint/tendermint/abci/client" "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/internal/blocksync" "github.com/tendermint/tendermint/internal/consensus" "github.com/tendermint/tendermint/internal/eventbus" @@ -86,7 +87,7 @@ type Environment struct { PeerManager peerManager // objects - PubKey crypto.PubKey + PubKey utils.Option[crypto.PubKey] GenDoc *types.GenesisDoc // cache the genesis structure EventSinks []indexer.EventSink EventBus *eventbus.EventBus // thread safe diff --git a/sei-tendermint/internal/rpc/core/status.go b/sei-tendermint/internal/rpc/core/status.go index 56c923952e..74f381bfa0 100644 --- a/sei-tendermint/internal/rpc/core/status.go +++ b/sei-tendermint/internal/rpc/core/status.go @@ -9,6 +9,7 @@ import ( tmbytes "github.com/tendermint/tendermint/libs/bytes" "github.com/tendermint/tendermint/rpc/coretypes" "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/libs/utils" ) // Status returns Tendermint status including node info, pubkey, latest block @@ -47,16 +48,10 @@ func (env *Environment) Status(ctx context.Context) (*coretypes.ResultStatus, er // Return the very last voting power, not the voting power of this validator // during the last block. - var votingPower int64 - if val := env.validatorAtHeight(env.latestUncommittedHeight()); val != nil { - votingPower = val.VotingPower + validatorInfo := coretypes.ValidatorInfo{PubKey: env.PubKey} + if val,ok := env.validatorAtHeight(env.latestUncommittedHeight()).Get(); ok { + validatorInfo.VotingPower = val.VotingPower } - validatorInfo := coretypes.ValidatorInfo{ - Address: env.PubKey.Address(), - PubKey: env.PubKey, - VotingPower: votingPower, - } - var applicationInfo coretypes.ApplicationInfo if abciInfo, err := env.ABCIInfo(ctx); err == nil { applicationInfo.Version = fmt.Sprint(abciInfo.Response.AppVersion) @@ -106,26 +101,32 @@ func (env *Environment) Status(ctx context.Context) (*coretypes.ResultStatus, er return result, nil } -func (env *Environment) validatorAtHeight(h int64) *types.Validator { +func (env *Environment) validatorAtHeight(h int64) utils.Option[*types.Validator] { + none := utils.None[*types.Validator]() + k,ok := env.PubKey.Get() + if !ok { return none } valsWithH, err := env.StateStore.LoadValidators(h) if err != nil { - return nil + return none } if env.ConsensusState == nil { - return nil + return none } - privValAddress := env.PubKey.Address() + privValAddress := k.Address() // If we're still at height h, search in the current validator set. lastBlockHeight, vals := env.ConsensusState.GetValidators() if lastBlockHeight == h { for _, val := range vals { if bytes.Equal(val.Address, privValAddress) { - return val + return utils.Some(val) } } } _, val := valsWithH.GetByAddress(privValAddress) - return val + if val!=nil { + return utils.Some(val) + } + return none } diff --git a/sei-tendermint/internal/state/execution_test.go b/sei-tendermint/internal/state/execution_test.go index cf2f404047..43df775843 100644 --- a/sei-tendermint/internal/state/execution_test.go +++ b/sei-tendermint/internal/state/execution_test.go @@ -207,7 +207,8 @@ func TestFinalizeBlockByzantineValidators(t *testing.T) { BlockIDFlag: types.BlockIDFlagNil, ValidatorAddress: crypto.AddressHash([]byte("validator_address")), Timestamp: defaultEvidenceTime, - Signature: crypto.CRandBytes(types.MaxSignatureSize)}}, + Signature: crypto.Sig(crypto.CRandBytes(len(crypto.Sig{}))), + }}, }, }, ValidatorSet: state.Validators, @@ -373,10 +374,8 @@ func TestProcessProposal(t *testing.T) { func TestValidateValidatorUpdates(t *testing.T) { pubkey1 := ed25519.GenPrivKey().PubKey() pubkey2 := ed25519.GenPrivKey().PubKey() - pk1, err := encoding.PubKeyToProto(pubkey1) - assert.NoError(t, err) - pk2, err := encoding.PubKeyToProto(pubkey2) - assert.NoError(t, err) + pk1 := encoding.PubKeyToProto(pubkey1) + pk2 := encoding.PubKeyToProto(pubkey2) defaultValidatorParams := types.ValidatorParams{PubKeyTypes: []string{types.ABCIPubKeyTypeEd25519}} @@ -432,10 +431,8 @@ func TestUpdateValidators(t *testing.T) { pubkey2 := ed25519.GenPrivKey().PubKey() val2 := types.NewValidator(pubkey2, 20) - pk, err := encoding.PubKeyToProto(pubkey1) - require.NoError(t, err) - pk2, err := encoding.PubKeyToProto(pubkey2) - require.NoError(t, err) + pk := encoding.PubKeyToProto(pubkey1) + pk2 := encoding.PubKeyToProto(pubkey2) testCases := []struct { name string @@ -553,8 +550,7 @@ func TestFinalizeBlockValidatorUpdates(t *testing.T) { blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()} pubkey := ed25519.GenPrivKey().PubKey() - pk, err := encoding.PubKeyToProto(pubkey) - require.NoError(t, err) + pk := encoding.PubKeyToProto(pubkey) app.ValidatorUpdates = []abci.ValidatorUpdate{ {PubKey: pk, Power: 10}, } @@ -618,8 +614,7 @@ func TestFinalizeBlockValidatorUpdatesResultingInEmptySet(t *testing.T) { require.NoError(t, err) blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()} - vp, err := encoding.PubKeyToProto(state.Validators.Validators[0].PubKey) - require.NoError(t, err) + vp := encoding.PubKeyToProto(state.Validators.Validators[0].PubKey) // Remove the only validator app.ValidatorUpdates = []abci.ValidatorUpdate{ {PubKey: vp, Power: 0}, @@ -998,3 +993,9 @@ func TestCreateProposalBlockPanicRecovery(t *testing.T) { // Verify mock expectations mp.AssertExpectations(t) } + +func makeStateSignature(data []byte) crypto.Sig { + var sig crypto.Sig + copy(sig[:], data) + return sig +} diff --git a/sei-tendermint/internal/state/helpers_test.go b/sei-tendermint/internal/state/helpers_test.go index 624ec2c630..45a1df81c1 100644 --- a/sei-tendermint/internal/state/helpers_test.go +++ b/sei-tendermint/internal/state/helpers_test.go @@ -1,7 +1,6 @@ package state_test import ( - "bytes" "context" "fmt" "math/rand" @@ -100,12 +99,17 @@ func makeValidCommit( }, votes } +func makePrivKey(i int) ed25519.PrivKey { + var seed ed25519.Seed + copy(seed[:],fmt.Sprintf("%d",i)) + return ed25519.PrivKeyFromSeed(seed) +} + func makeState(t *testing.T, nVals, height int) (sm.State, dbm.DB, map[string]types.PrivValidator) { vals := make([]types.GenesisValidator, nVals) privVals := make(map[string]types.PrivValidator, nVals) for i := 0; i < nVals; i++ { - secret := []byte(fmt.Sprintf("test%d", i)) - pk := ed25519.GenPrivKeyFromSecret(secret) + pk := makePrivKey(i) valAddr := pk.PubKey().Address() vals[i] = types.GenesisValidator{ Address: valAddr, @@ -153,11 +157,9 @@ func makeHeaderPartsResponsesValPubKeyChange( finalizeBlockResponses := &abci.ResponseFinalizeBlock{} // If the pubkey is new, remove the old and add the new. _, val := state.NextValidators.GetByIndex(0) - if !bytes.Equal(pubkey.Bytes(), val.PubKey.Bytes()) { - vPbPk, err := encoding.PubKeyToProto(val.PubKey) - require.NoError(t, err) - pbPk, err := encoding.PubKeyToProto(pubkey) - require.NoError(t, err) + if pubkey!=val.PubKey { + vPbPk := encoding.PubKeyToProto(val.PubKey) + pbPk := encoding.PubKeyToProto(pubkey) finalizeBlockResponses.ValidatorUpdates = []abci.ValidatorUpdate{ {PubKey: vPbPk, Power: 0}, @@ -181,8 +183,7 @@ func makeHeaderPartsResponsesValPowerChange( // If the pubkey is new, remove the old and add the new. _, val := state.NextValidators.GetByIndex(0) if val.VotingPower != power { - vPbPk, err := encoding.PubKeyToProto(val.PubKey) - require.NoError(t, err) + vPbPk := encoding.PubKeyToProto(val.PubKey) finalizeBlockResponses.ValidatorUpdates = []abci.ValidatorUpdate{ {PubKey: vPbPk, Power: power}, diff --git a/sei-tendermint/internal/state/state_test.go b/sei-tendermint/internal/state/state_test.go index 5dbe6b52fa..6146d447b6 100644 --- a/sei-tendermint/internal/state/state_test.go +++ b/sei-tendermint/internal/state/state_test.go @@ -117,12 +117,10 @@ func TestFinalizeBlockResponsesSaveLoad1(t *testing.T) { finalizeBlockResponses.TxResults[0] = &abci.ExecTxResult{Data: []byte("foo"), Events: nil} finalizeBlockResponses.TxResults[1] = &abci.ExecTxResult{Data: []byte("bar"), Log: "ok", Events: nil} - pbpk, err := encoding.PubKeyToProto(ed25519.GenPrivKey().PubKey()) - require.NoError(t, err) + pbpk := encoding.PubKeyToProto(ed25519.GenPrivKey().PubKey()) finalizeBlockResponses.ValidatorUpdates = []abci.ValidatorUpdate{{PubKey: pbpk, Power: 10}} - err = stateStore.SaveFinalizeBlockResponses(block.Height, finalizeBlockResponses) - require.NoError(t, err) + require.NoError(t, stateStore.SaveFinalizeBlockResponses(block.Height, finalizeBlockResponses)) loadedFinalizeBlockResponses, err := stateStore.LoadFinalizeBlockResponses(block.Height) require.NoError(t, err) assert.Equal(t, finalizeBlockResponses, loadedFinalizeBlockResponses, @@ -476,8 +474,7 @@ func TestProposerPriorityDoesNotGetResetToZero(t *testing.T) { // add a validator val2PubKey := ed25519.GenPrivKey().PubKey() val2VotingPower := int64(100) - fvp, err := encoding.PubKeyToProto(val2PubKey) - require.NoError(t, err) + fvp := encoding.PubKeyToProto(val2PubKey) updateAddVal := abci.ValidatorUpdate{PubKey: fvp, Power: val2VotingPower} validatorUpdates, err = types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{updateAddVal}) @@ -604,8 +601,7 @@ func TestProposerPriorityProposerAlternates(t *testing.T) { // add a validator with the same voting power as the first val2PubKey := ed25519.GenPrivKey().PubKey() - fvp, err := encoding.PubKeyToProto(val2PubKey) - require.NoError(t, err) + fvp := encoding.PubKeyToProto(val2PubKey) updateAddVal := abci.ValidatorUpdate{PubKey: fvp, Power: val1VotingPower} validatorUpdates, err = types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{updateAddVal}) assert.NoError(t, err) @@ -804,8 +800,7 @@ func TestLargeGenesisValidator(t *testing.T) { // see: https://github.com/tendermint/tendermint/issues/2960 firstAddedValPubKey := ed25519.GenPrivKey().PubKey() firstAddedValVotingPower := int64(10) - fvp, err := encoding.PubKeyToProto(firstAddedValPubKey) - require.NoError(t, err) + fvp := encoding.PubKeyToProto(firstAddedValPubKey) firstAddedVal := abci.ValidatorUpdate{PubKey: fvp, Power: firstAddedValVotingPower} validatorUpdates, err := types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{firstAddedVal}) assert.NoError(t, err) @@ -863,8 +858,7 @@ func TestLargeGenesisValidator(t *testing.T) { // add 10 validators with the same voting power as the one added directly after genesis: for i := 0; i < 10; i++ { addedPubKey := ed25519.GenPrivKey().PubKey() - ap, err := encoding.PubKeyToProto(addedPubKey) - require.NoError(t, err) + ap := encoding.PubKeyToProto(addedPubKey) addedVal := abci.ValidatorUpdate{PubKey: ap, Power: firstAddedValVotingPower} validatorUpdates, err := types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{addedVal}) assert.NoError(t, err) @@ -886,8 +880,7 @@ func TestLargeGenesisValidator(t *testing.T) { require.Equal(t, 10+2, len(state.NextValidators.Validators)) // remove genesis validator: - gp, err := encoding.PubKeyToProto(genesisPubKey) - require.NoError(t, err) + gp := encoding.PubKeyToProto(genesisPubKey) removeGenesisVal := abci.ValidatorUpdate{PubKey: gp, Power: 0} fb = &abci.ResponseFinalizeBlock{ ValidatorUpdates: []abci.ValidatorUpdate{removeGenesisVal}, diff --git a/sei-tendermint/internal/state/validation_test.go b/sei-tendermint/internal/state/validation_test.go index 6ef9d245c5..39ff32ad4a 100644 --- a/sei-tendermint/internal/state/validation_test.go +++ b/sei-tendermint/internal/state/validation_test.go @@ -265,7 +265,7 @@ func TestValidateBlockCommit(t *testing.T) { err = badPrivVal.SignVote(ctx, chainID, b) require.NoError(t, err, "height %d", height) - goodVote.Signature, badVote.Signature = g.Signature, b.Signature + goodVote.Signature, badVote.Signature = crypto.Sig(g.Signature), crypto.Sig(b.Signature) wrongSigsCommit = &types.Commit{ Height: goodVote.Height, diff --git a/sei-tendermint/internal/store/store_test.go b/sei-tendermint/internal/store/store_test.go index 76bc7f049d..f45ab3e09e 100644 --- a/sei-tendermint/internal/store/store_test.go +++ b/sei-tendermint/internal/store/store_test.go @@ -33,7 +33,7 @@ func makeTestCommit(height int64, timestamp time.Time) *types.Commit { BlockIDFlag: types.BlockIDFlagCommit, ValidatorAddress: tmrand.Bytes(crypto.AddressSize), Timestamp: timestamp, - Signature: []byte("Signature"), + Signature: makeStoreSignature([]byte("Signature")), }} return &types.Commit{ Height: height, @@ -45,6 +45,12 @@ func makeTestCommit(height int64, timestamp time.Time) *types.Commit { } } +func makeStoreSignature(data []byte) crypto.Sig { + var sig crypto.Sig + copy(sig[:], data) + return sig +} + func makeStateAndBlockStore(dir string) (sm.State, *BlockStore, cleanupFunc, error) { cfg, err := config.ResetTestRoot(dir, "blockchain_reactor_test") if err != nil { diff --git a/sei-tendermint/libs/utils/testonly.go b/sei-tendermint/libs/utils/testonly.go index 23a1faa8be..4b35ad59b8 100644 --- a/sei-tendermint/libs/utils/testonly.go +++ b/sei-tendermint/libs/utils/testonly.go @@ -48,6 +48,17 @@ var cmpOpts = []cmp.Option{ cmp.Comparer(cmpComparer[big.Int]), } +func OrPanic(err error) { + if err!=nil { + panic(err) + } +} + +func OrPanic1[T any](v T, err error) T { + OrPanic(err) + return v +} + // TestDiff generates a human-readable diff between two objects. func TestDiff[T any](want, got T) error { if diff := cmp.Diff(want, got, cmpOpts...); diff != "" { diff --git a/sei-tendermint/light/helpers_test.go b/sei-tendermint/light/helpers_test.go index 9187cc3c30..1959d1595a 100644 --- a/sei-tendermint/light/helpers_test.go +++ b/sei-tendermint/light/helpers_test.go @@ -5,7 +5,6 @@ import ( "time" "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" @@ -57,7 +56,7 @@ func (pkz privKeys) signHeader(t testing.TB, header *types.Header, valSet *types t.Helper() commitSigs := make([]types.CommitSig, len(pkz)) - for i := 0; i < len(pkz); i++ { + for i := range commitSigs { commitSigs[i] = types.NewCommitSigAbsent() } @@ -94,15 +93,8 @@ func makeVote(t testing.TB, header *types.Header, valset *types.ValidatorSet, ke Type: tmproto.PrecommitType, BlockID: blockID, } - - v := vote.ToProto() // Sign it - signBytes := types.VoteSignBytes(header.ChainID, v) - sig, err := key.Sign(signBytes) - require.NoError(t, err) - - vote.Signature = sig - + vote.Signature = key.Sign(types.VoteSignBytes(header.ChainID, vote.ToProto())) return vote } diff --git a/sei-tendermint/node/node.go b/sei-tendermint/node/node.go index b2e93e5f11..c63c6189df 100644 --- a/sei-tendermint/node/node.go +++ b/sei-tendermint/node/node.go @@ -17,6 +17,7 @@ import ( abciclient "github.com/tendermint/tendermint/abci/client" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/internal/blocksync" "github.com/tendermint/tendermint/internal/consensus" "github.com/tendermint/tendermint/internal/eventbus" @@ -204,18 +205,15 @@ func makeNode( return nil, combineCloseError(err, makeCloser(closers)) } - pubKey, err := privValidator.GetPubKey(ctx) - if err != nil { - return nil, combineCloseError(fmt.Errorf("can't get pubkey: %w", err), - makeCloser(closers)) - } - + pubKey := utils.None[crypto.PubKey]() if cfg.Mode == config.ModeValidator { - return nil, combineCloseError( - errors.New("could not retrieve public key from private validator"), - makeCloser(closers)) + key, err := privValidator.GetPubKey(ctx) + if err != nil { + return nil, combineCloseError(fmt.Errorf("can't get pubkey: %w", err), + makeCloser(closers)) + } + pubKey = utils.Some(key) } - // TODO construct node here: node := &nodeImpl{ config: cfg, diff --git a/sei-tendermint/node/node_test.go b/sei-tendermint/node/node_test.go index 2ea9ee39b0..20b96c0362 100644 --- a/sei-tendermint/node/node_test.go +++ b/sei-tendermint/node/node_test.go @@ -468,10 +468,9 @@ func TestMaxProposalBlockSize(t *testing.T) { assert.NoError(t, err) // now produce more txs than what a normal block can hold with 10 smaller txs // At the end of the test, only the single big tx should be added - for i := 0; i < 10; i++ { + for range 10 { tx := tmrand.Bytes(10) - err = mp.CheckTx(ctx, tx, nil, mempool.TxInfo{}) - assert.NoError(t, err) + assert.NoError(t, mp.CheckTx(ctx, tx, nil, mempool.TxInfo{})) } eventBus := eventbus.NewDefault(logger) @@ -537,7 +536,7 @@ func TestMaxProposalBlockSize(t *testing.T) { } vpb := vote.ToProto() require.NoError(t, privVals[i].SignVote(ctx, state.ChainID, vpb)) - vote.Signature = vpb.Signature + vote.Signature = crypto.Sig(vpb.Signature) added, err := voteSet.AddVote(vote) require.NoError(t, err) diff --git a/sei-tendermint/node/setup.go b/sei-tendermint/node/setup.go index ce80994b31..f22084ed75 100644 --- a/sei-tendermint/node/setup.go +++ b/sei-tendermint/node/setup.go @@ -94,7 +94,7 @@ func initDBs( return blockStore, stateDB, makeCloser(closers), nil } -func logNodeStartupInfo(state sm.State, pubKey crypto.PubKey, logger log.Logger, mode string) { +func logNodeStartupInfo(state sm.State, pubKey utils.Option[crypto.PubKey], logger log.Logger, mode string) { // Log the version info. logger.Info("Version info", "tmVersion", version.TMVersion, @@ -115,28 +115,31 @@ func logNodeStartupInfo(state sm.State, pubKey crypto.PubKey, logger log.Logger, case config.ModeFull: logger.Info("This node is a fullnode") case config.ModeValidator: - addr := pubKey.Address() + k := pubKey.OrPanic() + addr := k.Address() // Log whether this node is a validator or an observer if state.Validators.HasAddress(addr) { logger.Info("This node is a validator", "addr", addr, - "pubKey", pubKey[:], + "pubKey", k[:], ) } else { logger.Info("This node is a validator (NOT in the active validator set)", "addr", addr, - "pubKey", pubKey[:], + "pubKey", k[:], ) } } } -func onlyValidatorIsUs(state sm.State, pubKey crypto.PubKey) bool { +func onlyValidatorIsUs(state sm.State, pubKey utils.Option[crypto.PubKey]) bool { + k,ok := pubKey.Get() + if !ok { return false } if state.Validators.Size() > 1 { return false } addr, _ := state.Validators.GetByIndex(0) - return bytes.Equal(pubKey.Address(), addr) + return bytes.Equal(k.Address(), addr) } func createMempoolReactor( diff --git a/sei-tendermint/privval/file_test.go b/sei-tendermint/privval/file_test.go index a2decc77c0..156a268b0c 100644 --- a/sei-tendermint/privval/file_test.go +++ b/sei-tendermint/privval/file_test.go @@ -111,10 +111,8 @@ func TestUnmarshalValidatorKey(t *testing.T) { privKey := ed25519.GenPrivKey() pubKey := privKey.PubKey() addr := pubKey.Address() - pubBytes := pubKey.Bytes() - privBytes := privKey.Bytes() - pubB64 := base64.StdEncoding.EncodeToString(pubBytes) - privB64 := base64.StdEncoding.EncodeToString(privBytes) + pubB64 := base64.StdEncoding.EncodeToString(pubKey[:]) + privB64 := base64.StdEncoding.EncodeToString(privKey.SecretBytes()) serialized := fmt.Sprintf(`{ "address": "%s", diff --git a/sei-tendermint/privval/grpc/server_test.go b/sei-tendermint/privval/grpc/server_test.go index 92bb42d751..200a65c04e 100644 --- a/sei-tendermint/privval/grpc/server_test.go +++ b/sei-tendermint/privval/grpc/server_test.go @@ -18,6 +18,12 @@ import ( const ChainID = "123" +func makeSig(data []byte) crypto.Sig { + var sig crypto.Sig + copy(sig[:], data) + return sig +} + func TestGetPubKey(t *testing.T) { testCases := []struct { @@ -43,7 +49,7 @@ func TestGetPubKey(t *testing.T) { } else { pk, err := tc.pv.GetPubKey(ctx) require.NoError(t, err) - assert.Equal(t, resp.PubKey.GetEd25519(), pk.Bytes()) + require.Equal(t, resp.PubKey, pk) } }) } @@ -88,7 +94,7 @@ func TestSignVote(t *testing.T) { Timestamp: ts, ValidatorAddress: valAddr, ValidatorIndex: 1, - Signature: []byte("signed"), + Signature: makeSig([]byte("signed")), }, want: &types.Vote{ Type: tmproto.PrecommitType, Height: 1, @@ -97,7 +103,7 @@ func TestSignVote(t *testing.T) { Timestamp: ts, ValidatorAddress: valAddr, ValidatorIndex: 1, - Signature: []byte("signed"), + Signature: makeSig([]byte("signed")), }, err: true}, } @@ -158,7 +164,7 @@ func TestSignProposal(t *testing.T) { POLRound: 2, BlockID: types.BlockID{Hash: hash, PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2}}, Timestamp: ts, - Signature: []byte("signed"), + Signature: makeSig([]byte("signed")), }, want: &types.Proposal{ Type: tmproto.ProposalType, Height: 1, @@ -166,7 +172,7 @@ func TestSignProposal(t *testing.T) { POLRound: 2, BlockID: types.BlockID{Hash: hash, PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2}}, Timestamp: ts, - Signature: []byte("signed"), + Signature: makeSig([]byte("signed")), }, err: true}, } diff --git a/sei-tendermint/privval/msgs_test.go b/sei-tendermint/privval/msgs_test.go index 9105f5987c..04b167a40f 100644 --- a/sei-tendermint/privval/msgs_test.go +++ b/sei-tendermint/privval/msgs_test.go @@ -39,7 +39,7 @@ func exampleProposal() *types.Proposal { Round: 2, Timestamp: stamp, POLRound: 2, - Signature: []byte("it's a signature"), + Signature: makeSig([]byte("it's a signature")), BlockID: types.BlockID{ Hash: crypto.Checksum([]byte("blockID_hash")), PartSetHeader: types.PartSetHeader{ @@ -51,9 +51,8 @@ func exampleProposal() *types.Proposal { } func TestPrivvalVectors(t *testing.T) { - pk := ed25519.GenPrivKeyFromSecret([]byte("it's a secret")).PubKey() - ppk, err := encoding.PubKeyToProto(pk) - require.NoError(t, err) + pk := ed25519.PrivKeyFromSeed(ed25519.Seed{1,2,3,4}).PubKey() + ppk := encoding.PubKeyToProto(pk) // Generate a simple vote vote := exampleVote() diff --git a/sei-tendermint/privval/signer_client_test.go b/sei-tendermint/privval/signer_client_test.go index a293b6378f..11f639d94e 100644 --- a/sei-tendermint/privval/signer_client_test.go +++ b/sei-tendermint/privval/signer_client_test.go @@ -62,6 +62,12 @@ func getSignerTestCases(ctx context.Context, t *testing.T, logger log.Logger) [] return testCases } +func makeSig(data []byte) crypto.Sig { + var sig crypto.Sig + copy(sig[:], data) + return sig +} + func TestSignerClose(t *testing.T) { t.Cleanup(leaktest.Check(t)) @@ -329,7 +335,7 @@ func TestSignerSignProposalErrors(t *testing.T) { POLRound: 2, BlockID: types.BlockID{Hash: hash, PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2}}, Timestamp: ts, - Signature: []byte("signature"), + Signature: makeSig([]byte("signature")), } err := tc.signerClient.SignProposal(ctx, tc.chainID, proposal.ToProto()) @@ -368,7 +374,7 @@ func TestSignerSignVoteErrors(t *testing.T) { Timestamp: ts, ValidatorAddress: valAddr, ValidatorIndex: 1, - Signature: []byte("signature"), + Signature: makeSig([]byte("signature")), } // Replace signer service privval with one that always fails diff --git a/sei-tendermint/rpc/client/evidence_test.go b/sei-tendermint/rpc/client/evidence_test.go index 0096d09240..b2cfb85169 100644 --- a/sei-tendermint/rpc/client/evidence_test.go +++ b/sei-tendermint/rpc/client/evidence_test.go @@ -26,11 +26,9 @@ func newEvidence(t *testing.T, val *privval.FilePV, v := vote.ToProto() v2 := vote2.ToProto() - vote.Signature, err = val.Key.PrivKey.Sign(types.VoteSignBytes(chainID, v)) - require.NoError(t, err) + vote.Signature = val.Key.PrivKey.Sign(types.VoteSignBytes(chainID, v)) - vote2.Signature, err = val.Key.PrivKey.Sign(types.VoteSignBytes(chainID, v2)) - require.NoError(t, err) + vote2.Signature = val.Key.PrivKey.Sign(types.VoteSignBytes(chainID, v2)) validator := types.NewValidator(val.Key.PubKey, 10) valSet := types.NewValidatorSet([]*types.Validator{validator}) diff --git a/sei-tendermint/rpc/client/rpc_test.go b/sei-tendermint/rpc/client/rpc_test.go index 6b7a2a0ff0..ed8b1bb52e 100644 --- a/sei-tendermint/rpc/client/rpc_test.go +++ b/sei-tendermint/rpc/client/rpc_test.go @@ -13,10 +13,10 @@ import ( "time" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/libs/utils/require" "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/internal/mempool" rpccore "github.com/tendermint/tendermint/internal/rpc/core" @@ -303,7 +303,7 @@ func TestClientMethodCalls(t *testing.T) { res, err := c.ABCIQuery(ctx, "/key", k) qres := res.Response if assert.NoError(t, err) && assert.True(t, qres.IsOK()) { - assert.EqualValues(t, v, qres.Value) + assert.Equal(t, v, qres.Value) } }) t.Run("AppCalls", func(t *testing.T) { @@ -336,21 +336,21 @@ func TestClientMethodCalls(t *testing.T) { qres := _qres.Response if assert.True(t, qres.IsOK()) { assert.Equal(t, k, qres.Key) - assert.EqualValues(t, v, qres.Value) + assert.Equal(t, v, qres.Value) } // make sure we can lookup the tx with proof ptx, err := c.Tx(ctx, bres.Hash, true) require.NoError(t, err) - assert.EqualValues(t, txh, ptx.Height) - assert.EqualValues(t, tx, ptx.Tx) + assert.Equal(t, txh, ptx.Height) + assert.Equal(t, tx, ptx.Tx) // and we can even check the block is added block, err := c.Block(ctx, &apph) require.NoError(t, err) appHash := block.Block.Header.AppHash assert.True(t, len(appHash) > 0) - assert.EqualValues(t, apph, block.Block.Header.Height) + assert.Equal(t, apph, block.Block.Header.Height) blockByHash, err := c.BlockByHash(ctx, block.BlockID.Hash) require.NoError(t, err) @@ -371,7 +371,7 @@ func TestClientMethodCalls(t *testing.T) { assert.Equal(t, txh, blockResults.Height) if assert.Equal(t, 1, len(blockResults.TxsResults)) { // check success code - assert.EqualValues(t, 0, blockResults.TxsResults[0].Code) + assert.Equal(t, 0, blockResults.TxsResults[0].Code) } // check blockchain info, now that we know there is info @@ -380,7 +380,7 @@ func TestClientMethodCalls(t *testing.T) { assert.True(t, info.LastHeight >= apph) if assert.Equal(t, 1, len(info.BlockMetas)) { lastMeta := info.BlockMetas[0] - assert.EqualValues(t, apph, lastMeta.Header.Height) + assert.Equal(t, apph, lastMeta.Header.Height) blockData := block.Block assert.Equal(t, blockData.Header.AppHash, lastMeta.Header.AppHash) assert.Equal(t, block.BlockID, lastMeta.BlockID) @@ -457,7 +457,7 @@ func TestClientMethodCalls(t *testing.T) { require.Equal(t, initMempoolSize+1, pool.Size()) txs := pool.ReapMaxTxs(len(tx)) - require.EqualValues(t, tx, txs[0]) + require.Equal(t, tx, txs[0]) pool.Flush() }) t.Run("CheckTx", func(t *testing.T) { @@ -548,9 +548,7 @@ func TestClientMethodCalls(t *testing.T) { err = client.WaitForHeight(ctx, c, status.SyncInfo.LatestBlockHeight+2, nil) require.NoError(t, err) - ed25519pub := pv.Key.PubKey - rawpub := ed25519pub.Bytes() - result2, err := c.ABCIQuery(ctx, "/val", rawpub) + result2, err := c.ABCIQuery(ctx, "/val", pv.Key.PubKey[:]) require.NoError(t, err) qres := result2.Response require.True(t, qres.IsOK()) @@ -562,7 +560,7 @@ func TestClientMethodCalls(t *testing.T) { pk, err := encoding.PubKeyFromProto(v.PubKey) require.NoError(t, err) - require.EqualValues(t, rawpub, pk, "Stored PubKey not equal with expected, value %v", string(qres.Value)) + require.Equal(t, pv.Key.PubKey, pk, "Stored PubKey not equal with expected, value %v", string(qres.Value)) require.Equal(t, int64(9), v.Power, "Stored Power not equal with expected, value %v", string(qres.Value)) for _, fake := range fakes { @@ -716,15 +714,15 @@ func TestClientMethodCallsAdvanced(t *testing.T) { require.Error(t, err) } else { require.NoError(t, err, "%+v", err) - assert.EqualValues(t, txHeight, ptx.Height) - assert.EqualValues(t, tx, ptx.Tx) + assert.Equal(t, txHeight, ptx.Height) + assert.Equal(t, tx, ptx.Tx) assert.Zero(t, ptx.Index) assert.True(t, ptx.TxResult.IsOK()) - assert.EqualValues(t, txHash, ptx.Hash) + assert.Equal(t, txHash, ptx.Hash) // time to verify the proof proof := ptx.Proof - if tc.prove && assert.EqualValues(t, tx, proof.Data) { + if tc.prove && assert.Equal(t, tx, proof.Data) { assert.NoError(t, proof.Proof.Verify(proof.RootHash, txHash)) } } @@ -779,14 +777,14 @@ func TestClientMethodCallsAdvanced(t *testing.T) { require.Equal(t, find.Hash, result.Txs[0].Hash) ptx := result.Txs[0] - assert.EqualValues(t, find.Height, ptx.Height) - assert.EqualValues(t, find.Tx, ptx.Tx) + assert.Equal(t, find.Height, ptx.Height) + assert.Equal(t, find.Tx, ptx.Tx) assert.Zero(t, ptx.Index) assert.True(t, ptx.TxResult.IsOK()) - assert.EqualValues(t, find.Hash, ptx.Hash) + assert.Equal(t, find.Hash, ptx.Hash) // time to verify the proof - if assert.EqualValues(t, find.Tx, ptx.Proof.Data) { + if assert.Equal(t, find.Tx, ptx.Proof.Data) { assert.NoError(t, ptx.Proof.Proof.Verify(ptx.Proof.RootHash, find.Hash)) } diff --git a/sei-tendermint/rpc/coretypes/responses.go b/sei-tendermint/rpc/coretypes/responses.go index cce419b559..a3b47bfa14 100644 --- a/sei-tendermint/rpc/coretypes/responses.go +++ b/sei-tendermint/rpc/coretypes/responses.go @@ -124,8 +124,7 @@ type ApplicationInfo struct { // Info about the node's validator type ValidatorInfo struct { - Address bytes.HexBytes - PubKey crypto.PubKey + PubKey utils.Option[crypto.PubKey] VotingPower int64 } @@ -136,24 +135,27 @@ type validatorInfoJSON struct { } func (v ValidatorInfo) MarshalJSON() ([]byte, error) { - pk, err := jsontypes.Marshal(v.PubKey) - if err != nil { - return nil, err + j := validatorInfoJSON{VotingPower: v.VotingPower} + if k,ok:=v.PubKey.Get(); ok { + pk, err := k.MarshalJSON() + if err != nil { + return nil, err + } + j.PubKey = pk + j.Address = k.Address() } - return json.Marshal(validatorInfoJSON{ - Address: v.Address, PubKey: pk, VotingPower: v.VotingPower, - }) + return json.Marshal(j) } func (v *ValidatorInfo) UnmarshalJSON(data []byte) error { var val validatorInfoJSON - if err := json.Unmarshal(data, &val); err != nil { - return err - } - if err := jsontypes.Unmarshal(val.PubKey, &v.PubKey); err != nil { - return err + if len(val.PubKey)!=0 { + var pk crypto.PubKey + if err := encoding.Unmarshal(val.PubKey, &pk); err != nil { + return err + } + val.PubKey = utils.Some(pk) } - v.Address = val.Address v.VotingPower = val.VotingPower return nil } diff --git a/sei-tendermint/test/e2e/app/app.go b/sei-tendermint/test/e2e/app/app.go index 83d0f9b5b6..fab3a865d6 100644 --- a/sei-tendermint/test/e2e/app/app.go +++ b/sei-tendermint/test/e2e/app/app.go @@ -17,6 +17,7 @@ import ( "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/version" + "github.com/tendermint/tendermint/crypto" ) // Application is an ABCI application for use by end-to-end tests. It is a @@ -388,7 +389,7 @@ func (app *Application) validatorUpdates(height uint64) (abci.ValidatorUpdates, if err != nil { return nil, fmt.Errorf("invalid base64 pubkey value %q: %w", keyString, err) } - valUpdates = append(valUpdates, abci.UpdateValidator(keyBytes, int64(power), app.cfg.KeyType)) + valUpdates = append(valUpdates, abci.UpdateValidator(crypto.PubKey(keyBytes), int64(power), app.cfg.KeyType)) } // the validator updates could be returned in arbitrary order, diff --git a/sei-tendermint/test/fuzz/tests/p2p_secretconnection_test.go b/sei-tendermint/test/fuzz/tests/p2p_secretconnection_test.go index 65f268a7bf..7567d687c8 100644 --- a/sei-tendermint/test/fuzz/tests/p2p_secretconnection_test.go +++ b/sei-tendermint/test/fuzz/tests/p2p_secretconnection_test.go @@ -92,14 +92,14 @@ func makeSecretConnPair() (fooSecConn, barSecConn *sc.SecretConnection) { // Make connections from both sides in parallel. var trs, ok = async.Parallel( - func(_ int) (val interface{}, abort bool, err error) { + func(_ int) (val any, abort bool, err error) { fooSecConn, err = sc.MakeSecretConnection(fooConn, fooPrvKey) if err != nil { log.Printf("failed to establish SecretConnection for foo: %v", err) return nil, true, err } remotePubBytes := fooSecConn.RemotePubKey() - if !remotePubBytes.Equals(barPubKey) { + if remotePubBytes!=barPubKey { err = fmt.Errorf("unexpected fooSecConn.RemotePubKey. Expected %v, got %v", barPubKey, fooSecConn.RemotePubKey()) log.Print(err) @@ -107,14 +107,14 @@ func makeSecretConnPair() (fooSecConn, barSecConn *sc.SecretConnection) { } return nil, false, nil }, - func(_ int) (val interface{}, abort bool, err error) { + func(_ int) (val any, abort bool, err error) { barSecConn, err = sc.MakeSecretConnection(barConn, barPrvKey) if barSecConn == nil { log.Printf("failed to establish SecretConnection for bar: %v", err) return nil, true, err } remotePubBytes := barSecConn.RemotePubKey() - if !remotePubBytes.Equals(fooPubKey) { + if remotePubBytes!=fooPubKey { err = fmt.Errorf("unexpected barSecConn.RemotePubKey. Expected %v, got %v", fooPubKey, barSecConn.RemotePubKey()) log.Print(err) diff --git a/sei-tendermint/types/block_test.go b/sei-tendermint/types/block_test.go index 7623243efa..82bd462bd3 100644 --- a/sei-tendermint/types/block_test.go +++ b/sei-tendermint/types/block_test.go @@ -570,9 +570,7 @@ func TestVoteSetToCommit(t *testing.T) { } v := vote.ToProto() require.NoError(t, vals[i].SignVote(ctx, voteSet.ChainID(), v)) - sig,err := crypto.SigFromBytes(v.Signature) - require.NoError(t, err) - vote.Signature = sig + vote.Signature = crypto.Sig(v.Signature) added, err := voteSet.AddVote(vote) require.NoError(t, err) require.True(t, added) diff --git a/sei-tendermint/types/evidence_test.go b/sei-tendermint/types/evidence_test.go index f4bbe93885..c3ac752cbe 100644 --- a/sei-tendermint/types/evidence_test.go +++ b/sei-tendermint/types/evidence_test.go @@ -313,7 +313,7 @@ func makeVote( err = val.SignVote(ctx, chainID, vpb) require.NoError(t, err) - v.Signature = vpb.Signature + v.Signature = crypto.Sig(vpb.Signature) return v } @@ -383,7 +383,7 @@ func TestEvidenceVectors(t *testing.T) { // Votes for duplicateEvidence val := NewMockPV() - val.PrivKey = ed25519.GenPrivKeyFromSecret([]byte("it's a secret")) // deterministic key + val.PrivKey = ed25519.PrivKeyFromSeed(ed25519.Seed{1,2,3,4}) // deterministic key blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash"))) blockID2 := makeBlockID(crypto.Checksum([]byte("blockhash2")), math.MaxInt32, crypto.Checksum([]byte("partshash"))) const chainID = "mychain" diff --git a/sei-tendermint/types/proposal_test.go b/sei-tendermint/types/proposal_test.go index 16f1ec9b8a..62a3e22338 100644 --- a/sei-tendermint/types/proposal_test.go +++ b/sei-tendermint/types/proposal_test.go @@ -39,6 +39,13 @@ func generateHeader() Header { LastResultsHash: make([]byte, crypto.HashSize), } } + +func makeSig(data []byte) crypto.Sig { + var sig crypto.Sig + copy(sig[:], data) + return sig +} + func getTestProposal(t testing.TB) *Proposal { t.Helper() @@ -88,13 +95,11 @@ func TestProposalVerifySignature(t *testing.T) { signBytes := ProposalSignBytes("test_chain_id", p) // sign it - err = privVal.SignProposal(ctx, "test_chain_id", p) - require.NoError(t, err) - prop.Signature = p.Signature + require.NoError(t, privVal.SignProposal(ctx, "test_chain_id", p)) + prop.Signature = crypto.Sig(p.Signature) // verify the same proposal - valid := pubKey.VerifySignature(signBytes, prop.Signature) - require.True(t, valid) + require.NoError(t,pubKey.Verify(signBytes, prop.Signature)) // serialize, deserialize and verify again.... newProp := new(tmproto.Proposal) @@ -112,8 +117,7 @@ func TestProposalVerifySignature(t *testing.T) { // verify the transmitted proposal newSignBytes := ProposalSignBytes("test_chain_id", pb) require.Equal(t, string(signBytes), string(newSignBytes)) - valid = pubKey.VerifySignature(newSignBytes, np.Signature) - require.True(t, valid) + require.NoError(t,pubKey.Verify(newSignBytes, np.Signature)) } func BenchmarkProposalWriteSignBytes(b *testing.B) { @@ -156,7 +160,7 @@ func BenchmarkProposalVerifySignature(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - pubKey.VerifySignature(ProposalSignBytes("test_chain_id", pbp), testProposal.Signature) + pubKey.Verify(ProposalSignBytes("test_chain_id", pbp), testProposal.Signature) } } @@ -177,10 +181,7 @@ func TestProposalValidateBasic(t *testing.T) { p.BlockID = BlockID{[]byte{1, 2, 3}, PartSetHeader{111, []byte("blockparts")}} }, true}, {"Invalid Signature", func(p *Proposal) { - p.Signature = make([]byte, 0) - }, true}, - {"Too big Signature", func(p *Proposal) { - p.Signature = make([]byte, MaxSignatureSize+1) + p.Signature = crypto.Sig{} }, true}, } blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash"))) @@ -197,9 +198,8 @@ func TestProposalValidateBasic(t *testing.T) { blockID, tmtime.Now(), txKeys, generateHeader(), &Commit{}, EvidenceList{}, pubKey.Address()) p := prop.ToProto() - err = privVal.SignProposal(ctx, "test_chain_id", p) - prop.Signature = p.Signature - require.NoError(t, err) + require.NoError(t, privVal.SignProposal(ctx, "test_chain_id", p)) + prop.Signature = crypto.Sig(p.Signature) tc.malleateProposal(prop) assert.Equal(t, tc.expectErr, prop.ValidateBasic() != nil, "Validate Basic had an unexpected result") }) @@ -209,7 +209,7 @@ func TestProposalValidateBasic(t *testing.T) { func TestProposalProtoBuf(t *testing.T) { var txKeys []TxKey proposal := NewProposal(1, 2, 3, makeBlockID([]byte("hash"), 2, []byte("part_set_hash")), tmtime.Now(), txKeys, generateHeader(), &Commit{Signatures: []CommitSig{}}, EvidenceList{}, crypto.Address("testaddr")) - proposal.Signature = []byte("sig") + proposal.Signature = makeSig([]byte("sig")) proposal2 := NewProposal(1, 2, 3, BlockID{}, tmtime.Now(), txKeys, generateHeader(), &Commit{Signatures: []CommitSig{}}, EvidenceList{}, crypto.Address("testaddr")) testCases := []struct { diff --git a/sei-tendermint/types/protobuf_test.go b/sei-tendermint/types/protobuf_test.go index c482153c17..37e4607a13 100644 --- a/sei-tendermint/types/protobuf_test.go +++ b/sei-tendermint/types/protobuf_test.go @@ -19,8 +19,7 @@ func TestABCIPubKey(t *testing.T) { } func testABCIPubKey(t *testing.T, pk crypto.PubKey) error { - abciPubKey, err := encoding.PubKeyToProto(pk) - require.NoError(t, err) + abciPubKey := encoding.PubKeyToProto(pk) pk2, err := encoding.PubKeyFromProto(abciPubKey) require.NoError(t, err) require.Equal(t, pk, pk2) diff --git a/sei-tendermint/types/validation_test.go b/sei-tendermint/types/validation_test.go index 412c9a0788..b96af3459a 100644 --- a/sei-tendermint/types/validation_test.go +++ b/sei-tendermint/types/validation_test.go @@ -7,7 +7,8 @@ import ( "time" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/libs/utils/require" + "github.com/tendermint/tendermint/crypto" tmmath "github.com/tendermint/tendermint/libs/math" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -116,7 +117,7 @@ func TestValidatorSet_VerifyCommit_All(t *testing.T) { v := vote.ToProto() require.NoError(t, vals[vi%len(vals)].SignVote(ctx, tc.chainID, v)) - vote.Signature = v.Signature + vote.Signature = crypto.Sig(v.Signature) sigs[vi] = vote.CommitSig() @@ -175,9 +176,8 @@ func TestValidatorSet_VerifyCommit_CheckAllSignatures(t *testing.T) { // malleate 4th signature vote := voteSet.GetByIndex(3) v := vote.ToProto() - err = vals[3].SignVote(ctx, "CentaurusA", v) - require.NoError(t, err) - vote.Signature = v.Signature + require.NoError(t, vals[3].SignVote(ctx, "CentaurusA", v)) + vote.Signature = crypto.Sig(v.Signature) commit.Signatures[3] = vote.CommitSig() err = valSet.VerifyCommit(chainID, blockID, h, commit) @@ -204,9 +204,8 @@ func TestValidatorSet_VerifyCommitLight_ReturnsAsSoonAsMajorityOfVotingPowerSign // malleate 4th signature (3 signatures are enough for 2/3+) vote := voteSet.GetByIndex(3) v := vote.ToProto() - err = vals[3].SignVote(ctx, "CentaurusA", v) - require.NoError(t, err) - vote.Signature = v.Signature + require.NoError(t, vals[3].SignVote(ctx, "CentaurusA", v)) + vote.Signature = crypto.Sig(v.Signature) commit.Signatures[3] = vote.CommitSig() err = valSet.VerifyCommitLight(chainID, blockID, h, commit) @@ -230,9 +229,8 @@ func TestValidatorSet_VerifyCommitLightTrusting_ReturnsAsSoonAsTrustLevelOfVotin // malleate 3rd signature (2 signatures are enough for 1/3+ trust level) vote := voteSet.GetByIndex(2) v := vote.ToProto() - err = vals[2].SignVote(ctx, "CentaurusA", v) - require.NoError(t, err) - vote.Signature = v.Signature + require.NoError(t, vals[2].SignVote(ctx, "CentaurusA", v)) + vote.Signature = crypto.Sig(v.Signature) commit.Signatures[2] = vote.CommitSig() err = valSet.VerifyCommitLightTrusting(chainID, commit, tmmath.Fraction{Numerator: 1, Denominator: 3}) diff --git a/sei-tendermint/types/validator_set_test.go b/sei-tendermint/types/validator_set_test.go index 1a72d41b7c..f24049eea2 100644 --- a/sei-tendermint/types/validator_set_test.go +++ b/sei-tendermint/types/validator_set_test.go @@ -403,9 +403,7 @@ func newValidator(address []byte, power int64) *Validator { } func randPubKey() crypto.PubKey { - pubKey := make(ed25519.PubKey, ed25519.PubKeySize) - copy(pubKey, tmrand.Bytes(32)) - return ed25519.PubKey(tmrand.Bytes(32)) + return crypto.PubKey(tmrand.Bytes(len(crypto.PubKey{}))) } func randModuloValidator(totalVotingPower int64) *Validator { @@ -1636,7 +1634,7 @@ func deterministicValidatorSet(ctx context.Context, t *testing.T) (*ValidatorSet for i := 0; i < 10; i++ { // val, privValidator := DeterministicValidator(ed25519.PrivKey([]byte(deterministicKeys[i]))) - val, privValidator := deterministicValidator(ctx, t, ed25519.GenPrivKeyFromSecret([]byte(fmt.Sprintf("key: %x", i)))) + val, privValidator := deterministicValidator(ctx, t, ed25519.PrivKeyFromSeed(ed25519.Seed{byte(i)})) valz[i] = val privValidators[i] = privValidator } diff --git a/sei-tendermint/types/validator_test.go b/sei-tendermint/types/validator_test.go index a0ff719a00..fee5792d20 100644 --- a/sei-tendermint/types/validator_test.go +++ b/sei-tendermint/types/validator_test.go @@ -64,13 +64,6 @@ func TestValidatorValidateBasic(t *testing.T) { err: true, msg: "nil validator", }, - { - val: &Validator{ - PubKey: nil, - }, - err: true, - msg: "validator does not have a public key", - }, { val: NewValidator(pubKey, -1), err: true, diff --git a/sei-tendermint/types/vote_test.go b/sei-tendermint/types/vote_test.go index 0fb8fe5389..b2ad25e37b 100644 --- a/sei-tendermint/types/vote_test.go +++ b/sei-tendermint/types/vote_test.go @@ -7,9 +7,10 @@ import ( "github.com/gogo/protobuf/proto" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/libs/utils" + "github.com/tendermint/tendermint/libs/utils/require" "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/internal/libs/protoio" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -159,25 +160,20 @@ func TestVoteVerifySignature(t *testing.T) { signBytes := VoteSignBytes("test_chain_id", v) // sign it - err = privVal.SignVote(ctx, "test_chain_id", v) - require.NoError(t, err) + require.NoError(t, privVal.SignVote(ctx, "test_chain_id", v)) // verify the same vote - valid := pubkey.VerifySignature(VoteSignBytes("test_chain_id", v), v.Signature) - require.True(t, valid) + require.NoError(t,pubkey.Verify(VoteSignBytes("test_chain_id", v), crypto.Sig(v.Signature))) // serialize, deserialize and verify again.... precommit := new(tmproto.Vote) - bs, err := proto.Marshal(v) - require.NoError(t, err) - err = proto.Unmarshal(bs, precommit) - require.NoError(t, err) + bs := utils.OrPanic1(proto.Marshal(v)) + require.NoError(t, proto.Unmarshal(bs, precommit)) // verify the transmitted vote newSignBytes := VoteSignBytes("test_chain_id", precommit) - require.Equal(t, string(signBytes), string(newSignBytes)) - valid = pubkey.VerifySignature(newSignBytes, precommit.Signature) - require.True(t, valid) + require.NoError(t, utils.TestDiff(signBytes, newSignBytes)) + require.NoError(t, pubkey.Verify(newSignBytes, crypto.Sig(precommit.Signature))) } func TestIsVoteTypeValid(t *testing.T) { @@ -233,7 +229,7 @@ func signVote(ctx context.Context, t *testing.T, pv PrivValidator, chainID strin v := vote.ToProto() require.NoError(t, pv.SignVote(ctx, chainID, v)) - vote.Signature = v.Signature + vote.Signature = crypto.Sig(v.Signature) } func TestValidVotes(t *testing.T) { @@ -268,8 +264,6 @@ func TestInvalidVotes(t *testing.T) { {"invalid block ID", func(v *Vote) { v.BlockID = BlockID{[]byte{1, 2, 3}, PartSetHeader{111, []byte("blockparts")}} }}, {"invalid address", func(v *Vote) { v.ValidatorAddress = make([]byte, 1) }}, {"invalid validator index", func(v *Vote) { v.ValidatorIndex = -1 }}, - {"invalid signature", func(v *Vote) { v.Signature = nil }}, - {"oversized signature", func(v *Vote) { v.Signature = make([]byte, MaxSignatureSize+1) }}, } for _, tc := range testCases { prevote := examplePrevote(t) @@ -290,9 +284,8 @@ func TestVoteProtobuf(t *testing.T) { privVal := NewMockPV() vote := examplePrecommit(t) v := vote.ToProto() - err := privVal.SignVote(ctx, "test_chain_id", v) - vote.Signature = v.Signature - require.NoError(t, err) + require.NoError(t, privVal.SignVote(ctx, "test_chain_id", v)) + vote.Signature = crypto.Sig(v.Signature) testCases := []struct { msg string From 111028ee4419e0f23a739d585b717f489f2ed6ca Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Wed, 17 Dec 2025 13:53:48 +0100 Subject: [PATCH 26/53] crypto test --- .../crypto/keys/sr25519/internal/privkey.go | 14 +--- sei-tendermint/crypto/crypto_test.go | 68 +++++++++++++++++++ sei-tendermint/crypto/ed25519/ed25519.go | 13 +++- .../internal/jsontypes/jsontypes.go | 5 +- sei-tendermint/libs/json/encoder.go | 6 +- sei-tendermint/node/node.go | 1 - 6 files changed, 86 insertions(+), 21 deletions(-) create mode 100644 sei-tendermint/crypto/crypto_test.go diff --git a/sei-cosmos/crypto/keys/sr25519/internal/privkey.go b/sei-cosmos/crypto/keys/sr25519/internal/privkey.go index 33a691e752..36d4a7cf4e 100644 --- a/sei-cosmos/crypto/keys/sr25519/internal/privkey.go +++ b/sei-cosmos/crypto/keys/sr25519/internal/privkey.go @@ -10,17 +10,9 @@ import ( "github.com/oasisprotocol/curve25519-voi/primitives/sr25519" ) -var ( - signingCtx = sr25519.NewSigningContext([]byte{}) -) - -const ( - PrivKeyName = "tendermint/PrivKeySr25519" - // PrivKeySize is the size of a sr25519 signature in bytes. - PrivKeySize = sr25519.MiniSecretKeySize +var signingCtx = sr25519.NewSigningContext([]byte{}) - KeyType = "sr25519" -) +const KeyType = "sr25519" // PrivKey implements crypto.PrivKey. type PrivKey struct { @@ -28,8 +20,6 @@ type PrivKey struct { kp *sr25519.KeyPair } -// TypeTag satisfies the jsontypes.Tagged interface. -func (PrivKey) TypeTag() string { return PrivKeyName } func (privKey PrivKey) Type() string { return KeyType } // Bytes returns the byte-encoded PrivKey. diff --git a/sei-tendermint/crypto/crypto_test.go b/sei-tendermint/crypto/crypto_test.go new file mode 100644 index 0000000000..fb65b16ad0 --- /dev/null +++ b/sei-tendermint/crypto/crypto_test.go @@ -0,0 +1,68 @@ +package crypto + +import ( + "crypto/sha256" + "encoding/hex" + "testing" + + "github.com/tendermint/tendermint/libs/utils" + "github.com/tendermint/tendermint/crypto/ed25519" + tmjson "github.com/tendermint/tendermint/libs/json" + "github.com/tendermint/tendermint/internal/jsontypes" +) + +type msgNorm struct { + Pub,Priv,PubPtr,PrivPtr PubKey +} + +type msgWithKeys struct { + Pub PubKey + Priv PrivKey + PubPtr *PubKey + PrivPtr *PrivKey +} + +func (m msgWithKeys) Normalize() msgNorm { + return msgNorm {m.Pub,m.Priv.PubKey(),*m.PubPtr,m.PrivPtr.PubKey()} +} + + +func TestKeyJSON(t *testing.T) { + secret := []byte("tm-test-key-json-seed") + want := ed25519.GenPrivKeyFromSecret(secret) + const privKeyJSONHash = "f36adf0dc679100837e9819a73ccefdf073b5a2129db8d200a4262bfd47cd883" + const pubKeyJSONHash = "0b0b97c108fbd1305b323676bc33dc5c9309fb947d5cd29f88e9dce1457c6362" + + t.Log("Test secret key encoding.") + privJSON := utils.OrPanic1(tmjson.Marshal(want)) + utils.OrPanic(utils.TestDiff(hexHash(privJSON), privKeyJSONHash)) + privJSON = utils.OrPanic1(jsontypes.Marshal(want)) + utils.OrPanic(utils.TestDiff(hexHash(privJSON), privKeyJSONHash)) + var got PrivKey + utils.OrPanic(tmjson.Unmarshal(privJSON, &got)) + utils.OrPanic(utils.TestDiff(want.PubKey(),got.PubKey())) + + t.Log("Test public key encoding.") + pubJSON := utils.OrPanic1(tmjson.Marshal(want.PubKey())) + utils.OrPanic(utils.TestDiff(hexHash(pubJSON), pubKeyJSONHash)) + pubJSON = utils.OrPanic1(tmjson.Marshal(want.PubKey())) + utils.OrPanic(utils.TestDiff(hexHash(pubJSON), pubKeyJSONHash)) + var gotPubKey PubKey + utils.OrPanic(tmjson.Unmarshal(pubJSON, &gotPubKey)) + utils.OrPanic(utils.TestDiff(want.PubKey(),gotPubKey)) + + t.Log("Test nested key encoding.") + // Only tmjson makes sense here, because jsontypes applies only to top level messages. + msgWant := msgWithKeys{want.PubKey(),want,utils.Alloc(want.PubKey()),&want} + msgJSON := utils.OrPanic1(tmjson.Marshal(msgWant)) + t.Logf("msgJSON = %v",string(msgJSON)) + utils.OrPanic(utils.TestDiff(hexHash(pubJSON), "0b0b97c108fbd1305b323676bc33dc5c9309fb947d5cd29f88e9dce1457c6362")) + var msgGot msgWithKeys + utils.OrPanic(tmjson.Unmarshal(msgJSON,&msgGot)) + utils.OrPanic(utils.TestDiff(msgWant.Normalize(),msgGot.Normalize())) +} + +func hexHash(data []byte) string { + hash := sha256.Sum256(data) + return hex.EncodeToString(hash[:]) +} diff --git a/sei-tendermint/crypto/ed25519/ed25519.go b/sei-tendermint/crypto/ed25519/ed25519.go index 382b608050..5dbcf504c4 100644 --- a/sei-tendermint/crypto/ed25519/ed25519.go +++ b/sei-tendermint/crypto/ed25519/ed25519.go @@ -6,6 +6,7 @@ import ( "fmt" "errors" "io" + "encoding/json" "github.com/oasisprotocol/curve25519-voi/primitives/ed25519" "github.com/oasisprotocol/curve25519-voi/primitives/ed25519/extra/cache" @@ -35,7 +36,7 @@ var cachingVerifier = cache.NewVerifier(cache.NewLRUCache(cacheSize)) func init() { tmjson.RegisterType(PubKey{}, PubKeyName) - tmjson.RegisterType(PrivKey{}, PubKeyName) + tmjson.RegisterType(PrivKey{}, PrivKeyName) jsontypes.MustRegister(PubKey{}) jsontypes.MustRegister(PrivKey{}) } @@ -47,7 +48,7 @@ type PrivKey struct { } // TypeTag satisfies the jsontypes.Tagged interface. -func (PrivKey) TypeTag() string { return PrivKeyName } +func (k PrivKey) TypeTag() string { return PrivKeyName } // Bytes returns the privkey byte format. func (k PrivKey) SecretBytes() []byte { return k.raw } @@ -92,6 +93,14 @@ func GenPrivKeyFromSecret(secret []byte) PrivKey { return PrivKeyFromSeed(Seed(sha256.Sum256(secret))) } +func (k PrivKey) MarshalJSON() ([]byte,error) { + return json.Marshal(k.raw) +} + +func (k *PrivKey) UnmarshalJSON(j []byte) error { + return json.Unmarshal(j,&k.raw) +} + //------------------------------------- // PubKey implements the Ed25519 signature scheme. diff --git a/sei-tendermint/internal/jsontypes/jsontypes.go b/sei-tendermint/internal/jsontypes/jsontypes.go index 71c110660b..2f8179b86a 100644 --- a/sei-tendermint/internal/jsontypes/jsontypes.go +++ b/sei-tendermint/internal/jsontypes/jsontypes.go @@ -23,7 +23,6 @@ import ( // is used to distinguish objects of that type. type Tagged interface { TypeTag() string - Marshal() ([]byte,error) } // registry records the mapping from type tags to value types. @@ -79,7 +78,7 @@ func Marshal(v Tagged) ([]byte, error) { func Unmarshal(data []byte, v any) error { // Verify that the target is some kind of pointer. target := reflect.ValueOf(v) - if target.Kind() != reflect.Ptr { + if target.Kind() != reflect.Pointer { return fmt.Errorf("target %T is not a pointer", v) } else if target.IsZero() { return fmt.Errorf("target is a nil %T", v) @@ -102,7 +101,7 @@ func Unmarshal(data []byte, v any) error { } if typ.AssignableTo(baseType) { // ok: registered type is directly assignable to the target - } else if typ.Kind() == reflect.Ptr && typ.Elem().AssignableTo(baseType) { + } else if typ.Kind() == reflect.Pointer && typ.Elem().AssignableTo(baseType) { typ = typ.Elem() // ok: registered type is a pointer to a value assignable to the target } else { diff --git a/sei-tendermint/libs/json/encoder.go b/sei-tendermint/libs/json/encoder.go index cd404d9bfd..f857a20471 100644 --- a/sei-tendermint/libs/json/encoder.go +++ b/sei-tendermint/libs/json/encoder.go @@ -66,7 +66,7 @@ func encodeReflect(w io.Writer, rv reflect.Value) error { } // Recursively dereference if pointer. - for rv.Kind() == reflect.Ptr { + for rv.Kind() == reflect.Pointer { if rv.IsNil() { return writeStr(w, "null") } @@ -137,7 +137,7 @@ func encodeReflectList(w io.Writer, rv reflect.Value) error { if err := writeStr(w, "["); err != nil { return err } - for i := 0; i < length; i++ { + for i := range length { if err := encodeReflect(w, rv.Index(i)); err != nil { return err } @@ -214,7 +214,7 @@ func encodeReflectStruct(w io.Writer, rv reflect.Value) error { func encodeReflectInterface(w io.Writer, rv reflect.Value) error { // Get concrete value and dereference pointers. - for rv.Kind() == reflect.Ptr || rv.Kind() == reflect.Interface { + for rv.Kind() == reflect.Pointer || rv.Kind() == reflect.Interface { if rv.IsNil() { return writeStr(w, "null") } diff --git a/sei-tendermint/node/node.go b/sei-tendermint/node/node.go index c63c6189df..5a35372436 100644 --- a/sei-tendermint/node/node.go +++ b/sei-tendermint/node/node.go @@ -2,7 +2,6 @@ package node import ( "context" - "errors" "fmt" "net" "net/http" From 788f2c7c4db80dc3d9e1c85b79bbea7a42da2cbb Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Wed, 17 Dec 2025 16:28:59 +0100 Subject: [PATCH 27/53] cleanup of typeRegistry --- .../cmd/tendermint/commands/show_validator.go | 4 +- sei-tendermint/crypto/crypto_test.go | 39 +----- sei-tendermint/crypto/ed25519/ed25519.go | 3 - sei-tendermint/libs/json/decoder.go | 68 +---------- sei-tendermint/libs/json/decoder_test.go | 111 +++++++----------- sei-tendermint/libs/json/encoder.go | 36 +----- sei-tendermint/libs/json/encoder_test.go | 17 +-- sei-tendermint/libs/json/helpers_test.go | 15 --- sei-tendermint/libs/json/types.go | 109 ----------------- 9 files changed, 55 insertions(+), 347 deletions(-) delete mode 100644 sei-tendermint/libs/json/types.go diff --git a/sei-tendermint/cmd/tendermint/commands/show_validator.go b/sei-tendermint/cmd/tendermint/commands/show_validator.go index 60e664797d..a0e8d75666 100644 --- a/sei-tendermint/cmd/tendermint/commands/show_validator.go +++ b/sei-tendermint/cmd/tendermint/commands/show_validator.go @@ -8,7 +8,7 @@ import ( "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto" - tmjson "github.com/tendermint/tendermint/libs/json" + "github.com/tendermint/tendermint/internal/jsontypes" "github.com/tendermint/tendermint/libs/log" tmnet "github.com/tendermint/tendermint/libs/net" tmos "github.com/tendermint/tendermint/libs/os" @@ -70,7 +70,7 @@ func MakeShowValidatorCommand(conf *config.Config, logger log.Logger) *cobra.Com } } - bz, err := tmjson.Marshal(pubKey) + bz, err := jsontypes.Marshal(pubKey) if err != nil { return fmt.Errorf("failed to marshal private validator pubkey: %w", err) } diff --git a/sei-tendermint/crypto/crypto_test.go b/sei-tendermint/crypto/crypto_test.go index fb65b16ad0..bf45b9c0b9 100644 --- a/sei-tendermint/crypto/crypto_test.go +++ b/sei-tendermint/crypto/crypto_test.go @@ -7,26 +7,9 @@ import ( "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/crypto/ed25519" - tmjson "github.com/tendermint/tendermint/libs/json" "github.com/tendermint/tendermint/internal/jsontypes" ) -type msgNorm struct { - Pub,Priv,PubPtr,PrivPtr PubKey -} - -type msgWithKeys struct { - Pub PubKey - Priv PrivKey - PubPtr *PubKey - PrivPtr *PrivKey -} - -func (m msgWithKeys) Normalize() msgNorm { - return msgNorm {m.Pub,m.Priv.PubKey(),*m.PubPtr,m.PrivPtr.PubKey()} -} - - func TestKeyJSON(t *testing.T) { secret := []byte("tm-test-key-json-seed") want := ed25519.GenPrivKeyFromSecret(secret) @@ -34,32 +17,18 @@ func TestKeyJSON(t *testing.T) { const pubKeyJSONHash = "0b0b97c108fbd1305b323676bc33dc5c9309fb947d5cd29f88e9dce1457c6362" t.Log("Test secret key encoding.") - privJSON := utils.OrPanic1(tmjson.Marshal(want)) - utils.OrPanic(utils.TestDiff(hexHash(privJSON), privKeyJSONHash)) - privJSON = utils.OrPanic1(jsontypes.Marshal(want)) + privJSON := utils.OrPanic1(jsontypes.Marshal(want)) utils.OrPanic(utils.TestDiff(hexHash(privJSON), privKeyJSONHash)) var got PrivKey - utils.OrPanic(tmjson.Unmarshal(privJSON, &got)) + utils.OrPanic(jsontypes.Unmarshal(privJSON, &got)) utils.OrPanic(utils.TestDiff(want.PubKey(),got.PubKey())) t.Log("Test public key encoding.") - pubJSON := utils.OrPanic1(tmjson.Marshal(want.PubKey())) - utils.OrPanic(utils.TestDiff(hexHash(pubJSON), pubKeyJSONHash)) - pubJSON = utils.OrPanic1(tmjson.Marshal(want.PubKey())) + pubJSON := utils.OrPanic1(jsontypes.Marshal(want.PubKey())) utils.OrPanic(utils.TestDiff(hexHash(pubJSON), pubKeyJSONHash)) var gotPubKey PubKey - utils.OrPanic(tmjson.Unmarshal(pubJSON, &gotPubKey)) + utils.OrPanic(jsontypes.Unmarshal(pubJSON, &gotPubKey)) utils.OrPanic(utils.TestDiff(want.PubKey(),gotPubKey)) - - t.Log("Test nested key encoding.") - // Only tmjson makes sense here, because jsontypes applies only to top level messages. - msgWant := msgWithKeys{want.PubKey(),want,utils.Alloc(want.PubKey()),&want} - msgJSON := utils.OrPanic1(tmjson.Marshal(msgWant)) - t.Logf("msgJSON = %v",string(msgJSON)) - utils.OrPanic(utils.TestDiff(hexHash(pubJSON), "0b0b97c108fbd1305b323676bc33dc5c9309fb947d5cd29f88e9dce1457c6362")) - var msgGot msgWithKeys - utils.OrPanic(tmjson.Unmarshal(msgJSON,&msgGot)) - utils.OrPanic(utils.TestDiff(msgWant.Normalize(),msgGot.Normalize())) } func hexHash(data []byte) string { diff --git a/sei-tendermint/crypto/ed25519/ed25519.go b/sei-tendermint/crypto/ed25519/ed25519.go index 5dbcf504c4..863f8ba3f8 100644 --- a/sei-tendermint/crypto/ed25519/ed25519.go +++ b/sei-tendermint/crypto/ed25519/ed25519.go @@ -13,7 +13,6 @@ import ( "github.com/tendermint/tendermint/internal/jsontypes" tmbytes "github.com/tendermint/tendermint/libs/bytes" - tmjson "github.com/tendermint/tendermint/libs/json" ) const PrivKeyName = "tendermint/PrivKeyEd25519" @@ -35,8 +34,6 @@ var verifyOptions = &ed25519.Options{Verify: ed25519.VerifyOptionsZIP_215} var cachingVerifier = cache.NewVerifier(cache.NewLRUCache(cacheSize)) func init() { - tmjson.RegisterType(PubKey{}, PubKeyName) - tmjson.RegisterType(PrivKey{}, PrivKeyName) jsontypes.MustRegister(PubKey{}) jsontypes.MustRegister(PrivKey{}) } diff --git a/sei-tendermint/libs/json/decoder.go b/sei-tendermint/libs/json/decoder.go index 86ff27d393..ae516eefde 100644 --- a/sei-tendermint/libs/json/decoder.go +++ b/sei-tendermint/libs/json/decoder.go @@ -23,17 +23,7 @@ func decode(bz []byte, v interface{}) error { if rv.Kind() != reflect.Ptr { return errors.New("must decode into a pointer") } - rv = rv.Elem() - - // If this is a registered type, defer to interface decoder regardless of whether the input is - // an interface or a bare value. This retains Amino's behavior, but is inconsistent with - // behavior in structs where an interface field will get the type wrapper while a bare value - // field will not. - if typeRegistry.name(rv.Type()) != "" { - return decodeReflectInterface(bz, rv) - } - - return decodeReflect(bz, rv) + return decodeReflect(bz, rv.Elem()) } func decodeReflect(bz []byte, rv reflect.Value) error { @@ -82,7 +72,7 @@ func decodeReflect(bz []byte, rv reflect.Value) error { return decodeReflectStruct(bz, rv) case reflect.Interface: - return decodeReflectInterface(bz, rv) + return fmt.Errorf("decoding interfaces is not supported") // For 64-bit integers, unwrap expected string and defer to stdlib for integer decoding. case reflect.Int64, reflect.Int, reflect.Uint64, reflect.Uint: @@ -201,60 +191,6 @@ func decodeReflectStruct(bz []byte, rv reflect.Value) error { return nil } -func decodeReflectInterface(bz []byte, rv reflect.Value) error { - if !rv.CanAddr() { - return errors.New("interface value not addressable") - } - - // Decode the interface wrapper. - wrapper := interfaceWrapper{} - if err := json.Unmarshal(bz, &wrapper); err != nil { - return err - } - if wrapper.Type == "" { - return errors.New("interface type cannot be empty") - } - if len(wrapper.Value) == 0 { - return errors.New("interface value cannot be empty") - } - - // Dereference-and-construct pointers, to handle nested pointers. - for rv.Kind() == reflect.Ptr { - if rv.IsNil() { - rv.Set(reflect.New(rv.Type().Elem())) - } - rv = rv.Elem() - } - - // Look up the interface type, and construct a concrete value. - rt, returnPtr := typeRegistry.lookup(wrapper.Type) - if rt == nil { - return fmt.Errorf("unknown type %q", wrapper.Type) - } - - cptr := reflect.New(rt) - crv := cptr.Elem() - if err := decodeReflect(wrapper.Value, crv); err != nil { - return err - } - - // This makes sure interface implementations with pointer receivers (e.g. func (c *Car)) are - // constructed as pointers behind the interface. The types must be registered as pointers with - // RegisterType(). - if rv.Type().Kind() == reflect.Interface && returnPtr { - if !cptr.Type().AssignableTo(rv.Type()) { - return fmt.Errorf("invalid type %q for this value", wrapper.Type) - } - rv.Set(cptr) - } else { - if !crv.Type().AssignableTo(rv.Type()) { - return fmt.Errorf("invalid type %q for this value", wrapper.Type) - } - rv.Set(crv) - } - return nil -} - func decodeStdlib(bz []byte, rv reflect.Value) error { if !rv.CanAddr() && rv.Kind() != reflect.Ptr { return errors.New("value must be addressable or pointer") diff --git a/sei-tendermint/libs/json/decoder_test.go b/sei-tendermint/libs/json/decoder_test.go index 97b2bf710f..ab41e9a7cd 100644 --- a/sei-tendermint/libs/json/decoder_test.go +++ b/sei-tendermint/libs/json/decoder_test.go @@ -21,63 +21,49 @@ func TestUnmarshal(t *testing.T) { testcases := map[string]struct { json string - value interface{} + value any err bool }{ - "bool true": {"true", true, false}, - "bool false": {"false", false, false}, - "float32": {"3.14", float32(3.14), false}, - "float64": {"3.14", float64(3.14), false}, - "int32": {`32`, int32(32), false}, - "int32 string": {`"32"`, int32(32), true}, - "int32 ptr": {`32`, &i32, false}, - "int64": {`"64"`, int64(64), false}, - "int64 noend": {`"64`, int64(64), true}, - "int64 number": {`64`, int64(64), true}, - "int64 ptr": {`"64"`, &i64, false}, - "int64 ptr nil": {`null`, i64Nil, false}, - "string": {`"foo"`, "foo", false}, - "string noend": {`"foo`, "foo", true}, - "string ptr": {`"string"`, &str, false}, - "slice byte": {`"AQID"`, []byte{1, 2, 3}, false}, - "slice bytes": {`["AQID"]`, [][]byte{{1, 2, 3}}, false}, - "slice int32": {`[1,2,3]`, []int32{1, 2, 3}, false}, - "slice int64": {`["1","2","3"]`, []int64{1, 2, 3}, false}, - "slice int64 number": {`[1,2,3]`, []int64{1, 2, 3}, true}, - "slice int64 ptr": {`["64"]`, []*int64{&i64}, false}, - "slice int64 empty": {`[]`, []int64(nil), false}, - "slice int64 null": {`null`, []int64(nil), false}, - "array byte": {`"AQID"`, [3]byte{1, 2, 3}, false}, - "array byte large": {`"AQID"`, [4]byte{1, 2, 3, 4}, true}, - "array byte small": {`"AQID"`, [2]byte{1, 2}, true}, - "array int32": {`[1,2,3]`, [3]int32{1, 2, 3}, false}, - "array int64": {`["1","2","3"]`, [3]int64{1, 2, 3}, false}, - "array int64 number": {`[1,2,3]`, [3]int64{1, 2, 3}, true}, - "array int64 large": {`["1","2","3"]`, [4]int64{1, 2, 3, 4}, true}, - "array int64 small": {`["1","2","3"]`, [2]int64{1, 2}, true}, - "map bytes": {`{"b":"AQID"}`, map[string][]byte{"b": {1, 2, 3}}, false}, - "map int32": {`{"a":1,"b":2}`, map[string]int32{"a": 1, "b": 2}, false}, - "map int64": {`{"a":"1","b":"2"}`, map[string]int64{"a": 1, "b": 2}, false}, - "map int64 empty": {`{}`, map[string]int64{}, false}, - "map int64 null": {`null`, map[string]int64(nil), false}, - "map int key": {`{}`, map[int]int{}, true}, - "time": {`"2020-06-03T17:35:30Z"`, time.Date(2020, 6, 3, 17, 35, 30, 0, time.UTC), false}, - "time non-utc": {`"2020-06-03T17:35:30+02:00"`, time.Time{}, true}, - "time nozone": {`"2020-06-03T17:35:30"`, time.Time{}, true}, - "car": {`{"type":"vehicle/car","value":{"Wheels":4}}`, Car{Wheels: 4}, false}, - "car ptr": {`{"type":"vehicle/car","value":{"Wheels":4}}`, &Car{Wheels: 4}, false}, - "car iface": {`{"type":"vehicle/car","value":{"Wheels":4}}`, Vehicle(&Car{Wheels: 4}), false}, - "boat": {`{"type":"vehicle/boat","value":{"Sail":true}}`, Boat{Sail: true}, false}, - "boat ptr": {`{"type":"vehicle/boat","value":{"Sail":true}}`, &Boat{Sail: true}, false}, - "boat iface": {`{"type":"vehicle/boat","value":{"Sail":true}}`, Vehicle(Boat{Sail: true}), false}, - "boat into car": {`{"type":"vehicle/boat","value":{"Sail":true}}`, Car{}, true}, - "boat into car iface": {`{"type":"vehicle/boat","value":{"Sail":true}}`, Vehicle(&Car{}), true}, - "shoes": {`{"type":"vehicle/shoes","value":{"Soles":"rubber"}}`, Car{}, true}, - "shoes ptr": {`{"type":"vehicle/shoes","value":{"Soles":"rubber"}}`, &Car{}, true}, - "shoes iface": {`{"type":"vehicle/shoes","value":{"Soles":"rubbes"}}`, Vehicle(&Car{}), true}, - "key public": {`{"type":"key/public","value":"AQIDBAUGBwg="}`, PublicKey{1, 2, 3, 4, 5, 6, 7, 8}, false}, - "key wrong": {`{"type":"key/public","value":"AQIDBAUGBwg="}`, PrivateKey{1, 2, 3, 4, 5, 6, 7, 8}, true}, - "key into car": {`{"type":"key/public","value":"AQIDBAUGBwg="}`, Vehicle(&Car{}), true}, + "bool true": {"true", true, false}, + "bool false": {"false", false, false}, + "float32": {"3.14", float32(3.14), false}, + "float64": {"3.14", float64(3.14), false}, + "int32": {`32`, int32(32), false}, + "int32 string": {`"32"`, int32(32), true}, + "int32 ptr": {`32`, &i32, false}, + "int64": {`"64"`, int64(64), false}, + "int64 noend": {`"64`, int64(64), true}, + "int64 number": {`64`, int64(64), true}, + "int64 ptr": {`"64"`, &i64, false}, + "int64 ptr nil": {`null`, i64Nil, false}, + "string": {`"foo"`, "foo", false}, + "string noend": {`"foo`, "foo", true}, + "string ptr": {`"string"`, &str, false}, + "slice byte": {`"AQID"`, []byte{1, 2, 3}, false}, + "slice bytes": {`["AQID"]`, [][]byte{{1, 2, 3}}, false}, + "slice int32": {`[1,2,3]`, []int32{1, 2, 3}, false}, + "slice int64": {`["1","2","3"]`, []int64{1, 2, 3}, false}, + "slice int64 number": {`[1,2,3]`, []int64{1, 2, 3}, true}, + "slice int64 ptr": {`["64"]`, []*int64{&i64}, false}, + "slice int64 empty": {`[]`, []int64(nil), false}, + "slice int64 null": {`null`, []int64(nil), false}, + "array byte": {`"AQID"`, [3]byte{1, 2, 3}, false}, + "array byte large": {`"AQID"`, [4]byte{1, 2, 3, 4}, true}, + "array byte small": {`"AQID"`, [2]byte{1, 2}, true}, + "array int32": {`[1,2,3]`, [3]int32{1, 2, 3}, false}, + "array int64": {`["1","2","3"]`, [3]int64{1, 2, 3}, false}, + "array int64 number": {`[1,2,3]`, [3]int64{1, 2, 3}, true}, + "array int64 large": {`["1","2","3"]`, [4]int64{1, 2, 3, 4}, true}, + "array int64 small": {`["1","2","3"]`, [2]int64{1, 2}, true}, + "map bytes": {`{"b":"AQID"}`, map[string][]byte{"b": {1, 2, 3}}, false}, + "map int32": {`{"a":1,"b":2}`, map[string]int32{"a": 1, "b": 2}, false}, + "map int64": {`{"a":"1","b":"2"}`, map[string]int64{"a": 1, "b": 2}, false}, + "map int64 empty": {`{}`, map[string]int64{}, false}, + "map int64 null": {`null`, map[string]int64(nil), false}, + "map int key": {`{}`, map[int]int{}, true}, + "time": {`"2020-06-03T17:35:30Z"`, time.Date(2020, 6, 3, 17, 35, 30, 0, time.UTC), false}, + "time non-utc": {`"2020-06-03T17:35:30+02:00"`, time.Time{}, true}, + "time nozone": {`"2020-06-03T17:35:30"`, time.Time{}, true}, "tags": { `{"name":"name","OmitEmpty":"foo","Hidden":"bar","tags":{"name":"child"}}`, Tags{JSONName: "name", OmitEmpty: "foo", Tags: &Tags{JSONName: "child"}}, @@ -96,15 +82,11 @@ func TestUnmarshal(t *testing.T) { "Time":"2020-06-02T16:05:13.004346374Z", "Car":{"Wheels":4}, "Boat":{"Sail":true}, - "Vehicles":[ - {"type":"vehicle/car","value":{"Wheels":4}}, - {"type":"vehicle/boat","value":{"Sail":true}} - ], "Child":{ "Bool":false, "Float64":0, "Int32":0, "Int64":"0", "Int64Ptr":null, "String":"child", "StringPtrPtr":null, "Bytes":null, "Time":"0001-01-01T00:00:00Z", - "Car":null, "Boat":{"Sail":false}, "Vehicles":null, "Child":null + "Car":null, "Boat":{"Sail":false}, "Child":null }, "private": "foo", "unknown": "bar" }`, @@ -112,18 +94,11 @@ func TestUnmarshal(t *testing.T) { Bool: true, Float64: 3.14, Int32: 32, Int64: 64, Int64Ptr: &i64, String: "foo", StringPtrPtr: &strPtr, Bytes: []byte{1, 2, 3}, Time: time.Date(2020, 6, 2, 16, 5, 13, 4346374, time.UTC), - Car: &Car{Wheels: 4}, Boat: Boat{Sail: true}, Vehicles: []Vehicle{ - Vehicle(&Car{Wheels: 4}), - Vehicle(Boat{Sail: true}), - }, + Car: &Car{Wheels: 4}, Boat: Boat{Sail: true}, Child: &Struct{Bool: false, String: "child"}, }, false, }, - "struct key into vehicle": {`{"Vehicles":[ - {"type":"vehicle/car","value":{"Wheels":4}}, - {"type":"key/public","value":"MTIzNDU2Nzg="} - ]}`, Struct{}, true}, "struct ptr null": {`null`, structNil, false}, "custom value": {`{"Value":"foo"}`, CustomValue{}, false}, "custom ptr": {`"foo"`, &CustomPtr{Value: "custom"}, false}, diff --git a/sei-tendermint/libs/json/encoder.go b/sei-tendermint/libs/json/encoder.go index f857a20471..8d1c24f71c 100644 --- a/sei-tendermint/libs/json/encoder.go +++ b/sei-tendermint/libs/json/encoder.go @@ -48,15 +48,6 @@ func encode(w io.Writer, v any) error { return writeStr(w, "null") } rv := reflect.ValueOf(v) - - // If this is a registered type, defer to interface encoder regardless of whether the input is - // an interface or a bare value. This retains Amino's behavior, but is inconsistent with - // behavior in structs where an interface field will get the type wrapper while a bare value - // field will not. - if typeRegistry.name(rv.Type()) != "" { - return encodeReflectInterface(w, rv) - } - return encodeReflect(w, rv) } @@ -90,7 +81,7 @@ func encodeReflect(w io.Writer, rv reflect.Value) error { switch rv.Type().Kind() { // Complex types must be recursively encoded. case reflect.Interface: - return encodeReflectInterface(w, rv) + return fmt.Errorf("encoding interfaces is not supported") case reflect.Array, reflect.Slice: return encodeReflectList(w, rv) @@ -212,31 +203,6 @@ func encodeReflectStruct(w io.Writer, rv reflect.Value) error { return writeStr(w, "}") } -func encodeReflectInterface(w io.Writer, rv reflect.Value) error { - // Get concrete value and dereference pointers. - for rv.Kind() == reflect.Pointer || rv.Kind() == reflect.Interface { - if rv.IsNil() { - return writeStr(w, "null") - } - rv = rv.Elem() - } - - // Look up the name of the concrete type - name := typeRegistry.name(rv.Type()) - if name == "" { - return fmt.Errorf("cannot encode unregistered type %v", rv.Type()) - } - - // Write value wrapped in interface envelope - if err := writeStr(w, fmt.Sprintf(`{"type":%q,"value":`, name)); err != nil { - return err - } - if err := encodeReflect(w, rv); err != nil { - return err - } - return writeStr(w, "}") -} - func encodeStdlib(w io.Writer, v any) error { // Doesn't stream the output because that adds a newline, as per: // https://golang.org/pkg/encoding/json/#Encoder.Encode diff --git a/sei-tendermint/libs/json/encoder_test.go b/sei-tendermint/libs/json/encoder_test.go index 8de611c9ef..d6af582cb4 100644 --- a/sei-tendermint/libs/json/encoder_test.go +++ b/sei-tendermint/libs/json/encoder_test.go @@ -19,7 +19,7 @@ func TestMarshal(t *testing.T) { boat := Boat{Sail: true} testcases := map[string]struct { - value interface{} + value any output string }{ "nil": {nil, `null`}, @@ -50,14 +50,7 @@ func TestMarshal(t *testing.T) { "map nil": {map[string]int64(nil), `{}`}, // retain Amino compatibility "map empty": {map[string]int64{}, `{}`}, "map int64": {map[string]int64{"a": 1, "b": 2, "c": 3}, `{"a":"1","b":"2","c":"3"}`}, - "car": {car, `{"type":"vehicle/car","value":{"Wheels":4}}`}, - "car value": {*car, `{"type":"vehicle/car","value":{"Wheels":4}}`}, - "car iface": {Vehicle(car), `{"type":"vehicle/car","value":{"Wheels":4}}`}, "car nil": {(*Car)(nil), `null`}, - "boat": {boat, `{"type":"vehicle/boat","value":{"Sail":true}}`}, - "boat ptr": {&boat, `{"type":"vehicle/boat","value":{"Sail":true}}`}, - "boat iface": {Vehicle(boat), `{"type":"vehicle/boat","value":{"Sail":true}}`}, - "key public": {PublicKey{1, 2, 3, 4, 5, 6, 7, 8}, `{"type":"key/public","value":"AQIDBAUGBwg="}`}, "tags": { Tags{JSONName: "name", OmitEmpty: "foo", Hidden: "bar", Tags: &Tags{JSONName: "child"}}, `{"name":"name","OmitEmpty":"foo","tags":{"name":"child"}}`, @@ -71,7 +64,7 @@ func TestMarshal(t *testing.T) { Struct{ Bool: true, Float64: 3.14, Int32: 32, Int64: 64, Int64Ptr: &i64, String: "foo", StringPtrPtr: &sPtr, Bytes: []byte{1, 2, 3}, - Time: ti, Car: car, Boat: boat, Vehicles: []Vehicle{car, boat}, + Time: ti, Car: car, Boat: boat, Child: &Struct{Bool: false, String: "child"}, private: "private", }, `{ @@ -80,15 +73,11 @@ func TestMarshal(t *testing.T) { "Time":"2020-06-02T16:05:13.004346374Z", "Car":{"Wheels":4}, "Boat":{"Sail":true}, - "Vehicles":[ - {"type":"vehicle/car","value":{"Wheels":4}}, - {"type":"vehicle/boat","value":{"Sail":true}} - ], "Child":{ "Bool":false, "Float64":0, "Int32":0, "Int64":"0", "Int64Ptr":null, "String":"child", "StringPtrPtr":null, "Bytes":null, "Time":"0001-01-01T00:00:00Z", - "Car":null, "Boat":{"Sail":false}, "Vehicles":null, "Child":null + "Car":null, "Boat":{"Sail":false}, "Child":null } }`, }, diff --git a/sei-tendermint/libs/json/helpers_test.go b/sei-tendermint/libs/json/helpers_test.go index ccb3c00388..969a23fbba 100644 --- a/sei-tendermint/libs/json/helpers_test.go +++ b/sei-tendermint/libs/json/helpers_test.go @@ -2,22 +2,8 @@ package json_test import ( "time" - - "github.com/tendermint/tendermint/libs/json" ) -// Register Car, an instance of the Vehicle interface. -func init() { - json.RegisterType(&Car{}, "vehicle/car") - json.RegisterType(Boat{}, "vehicle/boat") - json.RegisterType(PublicKey{}, "key/public") - json.RegisterType(PrivateKey{}, "key/private") -} - -type Vehicle interface { - Drive() error -} - // Car is a pointer implementation of Vehicle. type Car struct { Wheels int32 @@ -85,7 +71,6 @@ type Struct struct { Time time.Time Car *Car Boat Boat - Vehicles []Vehicle Child *Struct private string } diff --git a/sei-tendermint/libs/json/types.go b/sei-tendermint/libs/json/types.go deleted file mode 100644 index 13f20d2bc9..0000000000 --- a/sei-tendermint/libs/json/types.go +++ /dev/null @@ -1,109 +0,0 @@ -package json - -import ( - "errors" - "fmt" - "reflect" - - tmsync "github.com/tendermint/tendermint/libs/sync" -) - -var ( - // typeRegistry contains globally registered types for JSON encoding/decoding. - typeRegistry = newTypes() -) - -// RegisterType registers a type for Amino-compatible interface encoding in the global type -// registry. These types will be encoded with a type wrapper `{"type":"","value":}` -// regardless of which interface they are wrapped in (if any). If the type is a pointer, it will -// still be valid both for value and pointer types, but decoding into an interface will generate -// the a value or pointer based on the registered type. -// -// Should only be called in init() functions, as it panics on error. -func RegisterType(_type interface{}, name string) { - if _type == nil { - panic("cannot register nil type") - } - err := typeRegistry.register(name, reflect.ValueOf(_type).Type()) - if err != nil { - panic(err) - } -} - -// typeInfo contains type information. -type typeInfo struct { - name string - rt reflect.Type - returnPtr bool -} - -// types is a type registry. It is safe for concurrent use. -type types struct { - tmsync.RWMutex - byType map[reflect.Type]*typeInfo - byName map[string]*typeInfo -} - -// newTypes creates a new type registry. -func newTypes() types { - return types{ - byType: map[reflect.Type]*typeInfo{}, - byName: map[string]*typeInfo{}, - } -} - -// registers the given type with the given name. The name and type must not be registered already. -func (t *types) register(name string, rt reflect.Type) error { - if name == "" { - return errors.New("name cannot be empty") - } - // If this is a pointer type, we recursively resolve until we get a bare type, but register that - // we should return pointers. - returnPtr := false - for rt.Kind() == reflect.Ptr { - returnPtr = true - rt = rt.Elem() - } - tInfo := &typeInfo{ - name: name, - rt: rt, - returnPtr: returnPtr, - } - - t.Lock() - defer t.Unlock() - if _, ok := t.byName[tInfo.name]; ok { - return fmt.Errorf("a type with name %q is already registered", name) - } - if _, ok := t.byType[tInfo.rt]; ok { - return fmt.Errorf("the type %v is already registered", rt) - } - t.byName[name] = tInfo - t.byType[rt] = tInfo - return nil -} - -// lookup looks up a type from a name, or nil if not registered. -func (t *types) lookup(name string) (reflect.Type, bool) { - t.RLock() - defer t.RUnlock() - tInfo := t.byName[name] - if tInfo == nil { - return nil, false - } - return tInfo.rt, tInfo.returnPtr -} - -// name looks up the name of a type, or empty if not registered. Unwraps pointers as necessary. -func (t *types) name(rt reflect.Type) string { - for rt.Kind() == reflect.Ptr { - rt = rt.Elem() - } - t.RLock() - defer t.RUnlock() - tInfo := t.byType[rt] - if tInfo == nil { - return "" - } - return tInfo.name -} From 09a5926b725e83d316358982e32329d4b270d9ce Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Wed, 17 Dec 2025 16:46:49 +0100 Subject: [PATCH 28/53] test for sig --- sei-tendermint/crypto/crypto_test.go | 25 +++++++++++++++++------ sei-tendermint/crypto/ed25519/ed25519.go | 10 --------- sei-tendermint/crypto/ed25519/json.go | 26 ++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 16 deletions(-) create mode 100644 sei-tendermint/crypto/ed25519/json.go diff --git a/sei-tendermint/crypto/crypto_test.go b/sei-tendermint/crypto/crypto_test.go index bf45b9c0b9..94bb58b286 100644 --- a/sei-tendermint/crypto/crypto_test.go +++ b/sei-tendermint/crypto/crypto_test.go @@ -6,8 +6,10 @@ import ( "testing" "github.com/tendermint/tendermint/libs/utils" + "github.com/tendermint/tendermint/libs/utils/require" "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/internal/jsontypes" + tmjson "github.com/tendermint/tendermint/libs/json" ) func TestKeyJSON(t *testing.T) { @@ -15,20 +17,31 @@ func TestKeyJSON(t *testing.T) { want := ed25519.GenPrivKeyFromSecret(secret) const privKeyJSONHash = "f36adf0dc679100837e9819a73ccefdf073b5a2129db8d200a4262bfd47cd883" const pubKeyJSONHash = "0b0b97c108fbd1305b323676bc33dc5c9309fb947d5cd29f88e9dce1457c6362" + const sigJSONHash = "dd48379c6c07eb1e36b188ea0cf35772a697c1a45ad4d47986ca819262743b71" t.Log("Test secret key encoding.") privJSON := utils.OrPanic1(jsontypes.Marshal(want)) - utils.OrPanic(utils.TestDiff(hexHash(privJSON), privKeyJSONHash)) + require.Equal(t,hexHash(privJSON), privKeyJSONHash) var got PrivKey - utils.OrPanic(jsontypes.Unmarshal(privJSON, &got)) - utils.OrPanic(utils.TestDiff(want.PubKey(),got.PubKey())) + require.NoError(t,jsontypes.Unmarshal(privJSON, &got)) + require.Equal(t,want.PubKey(),got.PubKey()) t.Log("Test public key encoding.") pubJSON := utils.OrPanic1(jsontypes.Marshal(want.PubKey())) - utils.OrPanic(utils.TestDiff(hexHash(pubJSON), pubKeyJSONHash)) + t.Logf("pubJSON = %v",string(pubJSON)) + require.Equal(t,hexHash(pubJSON), pubKeyJSONHash) var gotPubKey PubKey - utils.OrPanic(jsontypes.Unmarshal(pubJSON, &gotPubKey)) - utils.OrPanic(utils.TestDiff(want.PubKey(),gotPubKey)) + require.NoError(t,jsontypes.Unmarshal(pubJSON, &gotPubKey)) + require.Equal(t,want.PubKey(),gotPubKey) + + t.Log("Test signature encoding.") + wantSig := want.Sign([]byte{1,2,3}) + sigJSON := utils.OrPanic1(tmjson.Marshal(wantSig)) + t.Logf("sigJSON = %v",string(sigJSON)) + require.Equal(t,hexHash(sigJSON), sigJSONHash) + var gotSig Sig + require.NoError(t,tmjson.Unmarshal(sigJSON, &gotSig)) + require.Equal(t,wantSig,gotSig) } func hexHash(data []byte) string { diff --git a/sei-tendermint/crypto/ed25519/ed25519.go b/sei-tendermint/crypto/ed25519/ed25519.go index 863f8ba3f8..d432058500 100644 --- a/sei-tendermint/crypto/ed25519/ed25519.go +++ b/sei-tendermint/crypto/ed25519/ed25519.go @@ -6,7 +6,6 @@ import ( "fmt" "errors" "io" - "encoding/json" "github.com/oasisprotocol/curve25519-voi/primitives/ed25519" "github.com/oasisprotocol/curve25519-voi/primitives/ed25519/extra/cache" @@ -90,15 +89,6 @@ func GenPrivKeyFromSecret(secret []byte) PrivKey { return PrivKeyFromSeed(Seed(sha256.Sum256(secret))) } -func (k PrivKey) MarshalJSON() ([]byte,error) { - return json.Marshal(k.raw) -} - -func (k *PrivKey) UnmarshalJSON(j []byte) error { - return json.Unmarshal(j,&k.raw) -} - -//------------------------------------- // PubKey implements the Ed25519 signature scheme. type PubKey [ed25519.PublicKeySize]byte diff --git a/sei-tendermint/crypto/ed25519/json.go b/sei-tendermint/crypto/ed25519/json.go new file mode 100644 index 0000000000..1836a0a620 --- /dev/null +++ b/sei-tendermint/crypto/ed25519/json.go @@ -0,0 +1,26 @@ +package ed25519 + +import ( + "encoding/json" +) + +func (k PrivKey) MarshalJSON() ([]byte,error) { + return json.Marshal(k.raw) +} + +func (k *PrivKey) UnmarshalJSON(j []byte) error { + return json.Unmarshal(j,&k.raw) +} + +func (k PubKey) MarshalJSON() ([]byte,error) { + return json.Marshal(k[:]) +} + +func (k *PubKey) UnmarshalJSON(j []byte) error { + var raw []byte + if err:=json.Unmarshal(j,&raw); err!=nil { return err } + x,err := PubKeyFromBytes(raw) + if err!=nil { return err } + *k = x + return nil +} From 45766d70b38438cedde42eca8c9044a30c4960ba Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Wed, 17 Dec 2025 17:15:03 +0100 Subject: [PATCH 29/53] fmt --- sei-cosmos/client/rpc/status.go | 8 +- sei-cosmos/server/in_place.go | 371 ------------------ sei-cosmos/server/util.go | 3 - .../abci/example/kvstore/kvstore.go | 2 +- sei-tendermint/abci/tests/server/client.go | 2 +- sei-tendermint/crypto/crypto.go | 2 +- sei-tendermint/crypto/crypto_test.go | 77 ++-- sei-tendermint/crypto/ed25519/bench_test.go | 2 +- sei-tendermint/crypto/ed25519/ed25519.go | 38 +- sei-tendermint/crypto/ed25519/ed25519_test.go | 2 +- sei-tendermint/crypto/ed25519/json.go | 33 +- .../internal/consensus/invalid_test.go | 2 +- .../internal/consensus/memory_limit_test.go | 6 +- .../internal/consensus/reactor_test.go | 2 +- .../internal/consensus/replay_test.go | 4 +- sei-tendermint/internal/consensus/state.go | 22 +- .../internal/consensus/state_test.go | 2 +- sei-tendermint/internal/evidence/verify.go | 4 +- sei-tendermint/internal/p2p/address_test.go | 2 +- .../internal/p2p/conn/secret_connection.go | 18 +- .../p2p/conn/secret_connection_test.go | 2 +- .../internal/p2p/peermanager_test.go | 2 +- .../internal/roles/validator/msg.go | 6 +- sei-tendermint/internal/rpc/core/env.go | 2 +- sei-tendermint/internal/rpc/core/status.go | 12 +- sei-tendermint/internal/state/helpers_test.go | 6 +- .../internal/test/factory/commit.go | 12 +- sei-tendermint/internal/test/factory/vote.go | 10 +- sei-tendermint/libs/utils/option.go | 1 - sei-tendermint/libs/utils/proto.go | 5 +- sei-tendermint/libs/utils/testonly.go | 2 +- sei-tendermint/node/setup.go | 6 +- sei-tendermint/privval/msgs_test.go | 2 +- sei-tendermint/privval/secret_connection.go | 18 +- sei-tendermint/rpc/client/rpc_test.go | 2 +- sei-tendermint/rpc/coretypes/responses.go | 11 +- sei-tendermint/test/e2e/app/app.go | 2 +- .../fuzz/tests/p2p_secretconnection_test.go | 4 +- sei-tendermint/types/block.go | 8 +- sei-tendermint/types/block_test.go | 6 +- sei-tendermint/types/evidence.go | 6 +- sei-tendermint/types/evidence_test.go | 2 +- sei-tendermint/types/proposal.go | 22 +- sei-tendermint/types/proposal_test.go | 4 +- sei-tendermint/types/test_util.go | 6 +- sei-tendermint/types/validation.go | 6 +- sei-tendermint/types/validation_test.go | 2 +- sei-tendermint/types/vote.go | 8 +- sei-tendermint/types/vote_set.go | 2 +- sei-tendermint/types/vote_test.go | 6 +- 50 files changed, 226 insertions(+), 559 deletions(-) delete mode 100644 sei-cosmos/server/in_place.go diff --git a/sei-cosmos/client/rpc/status.go b/sei-cosmos/client/rpc/status.go index 3f5561bf4a..bd9a92a18e 100644 --- a/sei-cosmos/client/rpc/status.go +++ b/sei-cosmos/client/rpc/status.go @@ -50,10 +50,12 @@ func StatusCommand() *cobra.Command { return err } + var addr cryptotypes.Address var pk cryptotypes.PubKey // `status` has TM pubkeys, we need to convert them to our pubkeys. - if status.ValidatorInfo.PubKey != nil { - pk, err = cryptocodec.FromTmPubKeyInterface(*status.ValidatorInfo.PubKey) + if k, ok := status.ValidatorInfo.PubKey.Get(); ok { + addr = k.Address() + pk, err = cryptocodec.FromTmPubKeyInterface(k) if err != nil { return err } @@ -63,7 +65,7 @@ func StatusCommand() *cobra.Command { NodeInfo: status.NodeInfo, SyncInfo: status.SyncInfo, ValidatorInfo: validatorInfo{ - Address: status.ValidatorInfo.Address, + Address: addr, PubKey: pk, VotingPower: status.ValidatorInfo.VotingPower, }, diff --git a/sei-cosmos/server/in_place.go b/sei-cosmos/server/in_place.go deleted file mode 100644 index f843cedab6..0000000000 --- a/sei-cosmos/server/in_place.go +++ /dev/null @@ -1,371 +0,0 @@ -package server - -import ( - "bufio" - "context" - "fmt" - "io" - "os" - "path/filepath" - "runtime/debug" - "strings" - "time" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" - "github.com/cosmos/cosmos-sdk/server/config" - "github.com/cosmos/cosmos-sdk/server/types" - "github.com/cosmos/cosmos-sdk/telemetry" - "github.com/spf13/cobra" - abciclient "github.com/tendermint/tendermint/abci/client" - abci "github.com/tendermint/tendermint/abci/types" - tmcfg "github.com/tendermint/tendermint/config" - tmexport "github.com/tendermint/tendermint/export" - tmjson "github.com/tendermint/tendermint/libs/json" - "github.com/tendermint/tendermint/libs/log" - "github.com/tendermint/tendermint/node" - "github.com/tendermint/tendermint/privval" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - tmtypes "github.com/tendermint/tendermint/types" - dbm "github.com/tendermint/tm-db" - "go.opentelemetry.io/otel/sdk/trace" -) - -const ( - KeyIsTestnet = "is-testnet" - KeyNewChainID = "new-chain-ID" - KeyNewValAddr = "new-validator-addr" - KeyUserPubKey = "user-pub-key" - FlagShutdownGrace = "shutdown-grace" -) - -// Copied from osmosis-lab/cosmos-sdk -// -// InPlaceTestnetCreator utilizes the provided chainID and operatorAddress as well as the local private validator key to -// control the network represented in the data folder. This is useful to create testnets nearly identical to your -// mainnet environment. -func InPlaceTestnetCreator(testnetAppCreator types.AppCreator, defaultNodeHome string) *cobra.Command { - cmd := &cobra.Command{ - Use: "in-place-testnet [newChainID] [newOperatorAddress]", - Short: "Create and start a testnet from current local state", - Long: `Create and start a testnet from current local state. -After utilizing this command the network will start. If the network is stopped, -the normal "start" command should be used. Re-using this command on state that -has already been modified by this command could result in unexpected behavior. - -Additionally, the first block may take up to one minute to be committed, depending -on how old the block is. For instance, if a snapshot was taken weeks ago and we want -to turn this into a testnet, it is possible lots of pending state needs to be committed -(expiring locks, etc.). It is recommended that you should wait for this block to be committed -before stopping the daemon. - -If the --trigger-testnet-upgrade flag is set, the upgrade handler specified by the flag will be run -on the first block of the testnet. - -Regardless of whether the flag is set or not, if any new stores are introduced in the daemon being run, -those stores will be registered in order to prevent panics. Therefore, you only need to set the flag if -you want to test the upgrade handler itself. -`, - Example: "in-place-testnet localsei", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - defer func() { - if e := recover(); e != nil { - debug.PrintStack() - panic(e) - } - }() - serverCtx := GetServerContextFromCmd(cmd) - _, err := GetPruningOptionsFromFlags(serverCtx.Viper) - if err != nil { - return err - } - - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - newChainID := args[0] - - skipConfirmation, _ := cmd.Flags().GetBool("skip-confirmation") - - if !skipConfirmation { - // Confirmation prompt to prevent accidental modification of state. - reader := bufio.NewReader(os.Stdin) - fmt.Println("This operation will modify state in your data folder and cannot be undone. Do you want to continue? (y/n)") - text, _ := reader.ReadString('\n') - response := strings.TrimSpace(strings.ToLower(text)) - if response != "y" && response != "yes" { - fmt.Println("Operation canceled.") - return nil - } - } - - // Set testnet keys to be used by the application. - // This is done to prevent changes to existing start API. - serverCtx.Viper.Set(KeyIsTestnet, true) - serverCtx.Viper.Set(KeyNewChainID, newChainID) - - config, _ := config.GetConfig(serverCtx.Viper) - apiMetrics, err := telemetry.New(config.Telemetry) - if err != nil { - return fmt.Errorf("failed to initialize telemetry: %w", err) - } - restartCoolDownDuration := time.Second * time.Duration(serverCtx.Config.SelfRemediation.RestartCooldownSeconds) - // Set the first restart time to be now - restartCoolDownDuration so that the first restart can trigger whenever - canRestartAfter := time.Now().Add(-restartCoolDownDuration) - err = startInProcess( - serverCtx, - clientCtx, - func(l log.Logger, d dbm.DB, w io.Writer, c *tmcfg.Config, ao types.AppOptions) types.Application { - testApp, err := testnetify(serverCtx, testnetAppCreator, d, w) - if err != nil { - panic(err) - } - return testApp - }, - []trace.TracerProviderOption{}, - node.DefaultMetricsProvider(serverCtx.Config.Instrumentation)(clientCtx.ChainID), - apiMetrics, - canRestartAfter, - ) - - serverCtx.Logger.Debug("received quit signal") - graceDuration, _ := cmd.Flags().GetDuration(FlagShutdownGrace) - if graceDuration > 0 { - serverCtx.Logger.Info("graceful shutdown start", FlagShutdownGrace, graceDuration) - <-time.After(graceDuration) - serverCtx.Logger.Info("graceful shutdown complete") - } - - return err - }, - } - - addStartNodeFlags(cmd, defaultNodeHome) - cmd.Flags().Bool("skip-confirmation", false, "Skip the confirmation prompt") - return cmd -} - -// testnetify modifies both state and blockStore, allowing the provided operator address and local validator key to control the network -// that the state in the data folder represents. The chainID of the local genesis file is modified to match the provided chainID. -func testnetify(ctx *Context, testnetAppCreator types.AppCreator, db dbm.DB, traceWriter io.Writer) (types.Application, error) { - config := ctx.Config - - newChainID, ok := ctx.Viper.Get(KeyNewChainID).(string) - if !ok { - return nil, fmt.Errorf("expected string for key %s", KeyNewChainID) - } - - // Modify app genesis chain ID and save to genesis file. - genFilePath := config.GenesisFile() - genDoc, err := tmtypes.GenesisDocFromFile(config.GenesisFile()) - if err != nil { - panic(err) - } - genDoc.ChainID = newChainID - - if err := genDoc.ValidateAndComplete(); err != nil { - panic(err) - } - if err := genDoc.SaveAs(genFilePath); err != nil { - panic(err) - } - - // Regenerate addrbook.json to prevent peers on old network from causing error logs. - addrBookPath := filepath.Join(config.RootDir, "config", "addrbook.json") - if err := os.Remove(addrBookPath); err != nil && !os.IsNotExist(err) { - return nil, fmt.Errorf("failed to remove existing addrbook.json: %w", err) - } - - emptyAddrBook := []byte("{}") - if err := os.WriteFile(addrBookPath, emptyAddrBook, 0o600); err != nil { - return nil, fmt.Errorf("failed to create empty addrbook.json: %w", err) - } - - // Initialize blockStore and stateDB. - blockStoreDB, err := tmcfg.DefaultDBProvider(&tmcfg.DBContext{ID: "blockstore", Config: config}) - if err != nil { - panic(err) - } - blockStore := tmexport.NewBlockStore(blockStoreDB) - - stateDB, err := tmcfg.DefaultDBProvider(&tmcfg.DBContext{ID: "state", Config: config}) - if err != nil { - panic(err) - } - - privValidator, err := privval.LoadOrGenFilePV(ctx.Config.PrivValidator.KeyFile(), ctx.Config.PrivValidator.StateFile()) - if err != nil { - panic(err) - } - userPubKey, err := privValidator.GetPubKey(context.Background()) - if err != nil { - panic(err) - } - validatorAddress := userPubKey.Address() - - stateStore := tmexport.NewStore(stateDB) - - state, err := node.LoadStateFromDBOrGenesisDocProvider(stateStore, genDoc) - if err != nil { - panic(err) - } - - blockStore.Close() - stateDB.Close() - - ctx.Viper.Set(KeyNewValAddr, validatorAddress) - ctx.Viper.Set(KeyUserPubKey, userPubKey) - ctx.Viper.Set(FlagChainID, newChainID) - testnetApp := testnetAppCreator(ctx.Logger, db, traceWriter, ctx.Config, ctx.Viper) - - // We need to create a temporary proxyApp to get the initial state of the application. - // Depending on how the node was stopped, the application height can differ from the blockStore height. - // This height difference changes how we go about modifying the state. - localClient := abciclient.NewLocalClient(ctx.Logger, testnetApp) - res, err := localClient.Info(context.Background(), &abci.RequestInfo{}) - if err != nil { - return nil, fmt.Errorf("error calling Info: %v", err) - } - - blockStoreDB, err = tmcfg.DefaultDBProvider(&tmcfg.DBContext{ID: "blockstore", Config: config}) - if err != nil { - panic(err) - } - blockStore = tmexport.NewBlockStore(blockStoreDB) - - stateDB, err = tmcfg.DefaultDBProvider(&tmcfg.DBContext{ID: "state", Config: config}) - if err != nil { - panic(err) - } - - stateStore = tmexport.NewStore(stateDB) - - defer blockStore.Close() - defer stateStore.Close() - - appHash := res.LastBlockAppHash - appHeight := res.LastBlockHeight - - var block *tmtypes.Block - switch { - case appHeight == blockStore.Height(): - block = blockStore.LoadBlock(blockStore.Height()) - // If the state's last blockstore height does not match the app and blockstore height, we likely stopped with the halt height flag. - if state.LastBlockHeight != appHeight { - state.LastBlockHeight = appHeight - block.AppHash = appHash - state.AppHash = appHash - } else { - // Node was likely stopped via SIGTERM, delete the next block's seen commit - err := blockStoreDB.Delete([]byte(fmt.Sprintf("SC:%v", blockStore.Height()+1))) - if err != nil { - panic(err) - } - } - case blockStore.Height() > state.LastBlockHeight: - // This state usually occurs when we gracefully stop the node. - err = blockStore.DeleteLatestBlock() - if err != nil { - panic(err) - } - block = blockStore.LoadBlock(blockStore.Height()) - default: - // If there is any other state, we just load the block - block = blockStore.LoadBlock(blockStore.Height()) - } - - block.ChainID = newChainID - state.ChainID = newChainID - - block.LastBlockID = state.LastBlockID - block.LastCommit.BlockID = state.LastBlockID - - // Create a vote from our validator - vote := tmtypes.Vote{ - Type: tmproto.PrecommitType, - Height: state.LastBlockHeight, - Round: 0, - BlockID: state.LastBlockID, - Timestamp: time.Now(), - ValidatorAddress: validatorAddress, - ValidatorIndex: 0, - Signature: []byte{}, - } - - // Sign the vote, and copy the proto changes from the act of signing to the vote itself - voteProto := vote.ToProto() - privValidator.LastSignState.Round = 0 - privValidator.LastSignState.Step = 0 - if privValidator.LastSignState.Height > state.LastBlockHeight { - privValidator.LastSignState.Height = state.LastBlockHeight - } - err = privValidator.SignVote(context.Background(), newChainID, voteProto) - if err != nil { - panic(err) - } - vote.Signature = voteProto.Signature - vote.Timestamp = voteProto.Timestamp - - // Modify the block's lastCommit to be signed only by our validator - block.LastCommit.Signatures[0].ValidatorAddress = validatorAddress - block.LastCommit.Signatures[0].Signature = vote.Signature - block.LastCommit.Signatures = []tmtypes.CommitSig{block.LastCommit.Signatures[0]} - - seenCommit := tmtypes.Commit{} - seenCommit.Height = state.LastBlockHeight - seenCommit.Round = vote.Round - seenCommit.BlockID = state.LastBlockID - seenCommit.Round = vote.Round - seenCommit.Signatures = []tmtypes.CommitSig{{}} - seenCommit.Signatures[0].BlockIDFlag = tmtypes.BlockIDFlagCommit - seenCommit.Signatures[0].Signature = vote.Signature - seenCommit.Signatures[0].ValidatorAddress = validatorAddress - seenCommit.Signatures[0].Timestamp = vote.Timestamp - err = blockStore.SaveSeenCommit(state.LastBlockHeight, &seenCommit) - if err != nil { - panic(err) - } - - // Create ValidatorSet struct containing just our valdiator. - newVal := &tmtypes.Validator{ - Address: validatorAddress, - PubKey: userPubKey, - VotingPower: 900000000000000, - } - newValSet := &tmtypes.ValidatorSet{ - Validators: []*tmtypes.Validator{newVal}, - Proposer: newVal, - } - - // Replace all valSets in state to be the valSet with just our validator. - state.Validators = newValSet - state.LastValidators = newValSet - state.NextValidators = newValSet - state.LastHeightValidatorsChanged = blockStore.Height() - - err = stateStore.Save(state) - if err != nil { - panic(err) - } - - // Modfiy Validators stateDB entry. - stateStore.SaveValidatorSets(blockStore.Height()-1, blockStore.Height()-1, newValSet) - stateStore.SaveValidatorSets(blockStore.Height(), blockStore.Height(), newValSet) - stateStore.SaveValidatorSets(blockStore.Height()+1, blockStore.Height()+1, newValSet) - - // Since we modified the chainID, we set the new genesisDoc in the stateDB. - b, err := tmjson.Marshal(genDoc) - if err != nil { - panic(err) - } - if err := stateDB.SetSync([]byte("genesisDoc"), b); err != nil { - panic(err) - } - - testnetApp.InplaceTestnetInitialize(&ed25519.PubKey{Key: userPubKey.Bytes()}) - - return testnetApp, err -} diff --git a/sei-cosmos/server/util.go b/sei-cosmos/server/util.go index 60a1c5b078..937029caff 100644 --- a/sei-cosmos/server/util.go +++ b/sei-cosmos/server/util.go @@ -340,8 +340,6 @@ func AddCommands( startCmd := StartCmd(appCreator, defaultNodeHome, tracerProviderOptions) addStartFlags(startCmd) - inPlaceTestnetCmd := InPlaceTestnetCreator(appCreator, defaultNodeHome) - addStartFlags(inPlaceTestnetCmd) rootCmd.AddCommand( startCmd, @@ -350,7 +348,6 @@ func AddCommands( version.NewVersionCommand(), NewRollbackCmd(appCreator, defaultNodeHome), LatestVersionCmd(defaultNodeHome), - inPlaceTestnetCmd, ) } diff --git a/sei-tendermint/abci/example/kvstore/kvstore.go b/sei-tendermint/abci/example/kvstore/kvstore.go index 14f21720bc..339d875c2b 100644 --- a/sei-tendermint/abci/example/kvstore/kvstore.go +++ b/sei-tendermint/abci/example/kvstore/kvstore.go @@ -15,9 +15,9 @@ import ( "github.com/tendermint/tendermint/abci/example/code" "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/libs/log" - "github.com/tendermint/tendermint/crypto" cryptoproto "github.com/tendermint/tendermint/proto/tendermint/crypto" "github.com/tendermint/tendermint/version" ) diff --git a/sei-tendermint/abci/tests/server/client.go b/sei-tendermint/abci/tests/server/client.go index 03af5910da..6d2778be85 100644 --- a/sei-tendermint/abci/tests/server/client.go +++ b/sei-tendermint/abci/tests/server/client.go @@ -9,8 +9,8 @@ import ( abciclient "github.com/tendermint/tendermint/abci/client" "github.com/tendermint/tendermint/abci/types" - tmrand "github.com/tendermint/tendermint/libs/rand" "github.com/tendermint/tendermint/crypto" + tmrand "github.com/tendermint/tendermint/libs/rand" ) func InitChain(ctx context.Context, client abciclient.Client) error { diff --git a/sei-tendermint/crypto/crypto.go b/sei-tendermint/crypto/crypto.go index 3517f15e4c..52936fa426 100644 --- a/sei-tendermint/crypto/crypto.go +++ b/sei-tendermint/crypto/crypto.go @@ -41,7 +41,7 @@ type Sig = ed25519.Sig type BatchVerifier = ed25519.BatchVerifier type ErrBadSig = ed25519.ErrBadSig -func SigFromBytes(raw []byte) (Sig,error) { +func SigFromBytes(raw []byte) (Sig, error) { return ed25519.SigFromBytes(raw) } diff --git a/sei-tendermint/crypto/crypto_test.go b/sei-tendermint/crypto/crypto_test.go index 94bb58b286..b3b3b2f6cd 100644 --- a/sei-tendermint/crypto/crypto_test.go +++ b/sei-tendermint/crypto/crypto_test.go @@ -3,48 +3,57 @@ package crypto import ( "crypto/sha256" "encoding/hex" + "encoding/json" "testing" - "github.com/tendermint/tendermint/libs/utils" - "github.com/tendermint/tendermint/libs/utils/require" "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/internal/jsontypes" - tmjson "github.com/tendermint/tendermint/libs/json" + "github.com/tendermint/tendermint/libs/utils/require" ) -func TestKeyJSON(t *testing.T) { - secret := []byte("tm-test-key-json-seed") - want := ed25519.GenPrivKeyFromSecret(secret) - const privKeyJSONHash = "f36adf0dc679100837e9819a73ccefdf073b5a2129db8d200a4262bfd47cd883" - const pubKeyJSONHash = "0b0b97c108fbd1305b323676bc33dc5c9309fb947d5cd29f88e9dce1457c6362" - const sigJSONHash = "dd48379c6c07eb1e36b188ea0cf35772a697c1a45ad4d47986ca819262743b71" - - t.Log("Test secret key encoding.") - privJSON := utils.OrPanic1(jsontypes.Marshal(want)) - require.Equal(t,hexHash(privJSON), privKeyJSONHash) - var got PrivKey - require.NoError(t,jsontypes.Unmarshal(privJSON, &got)) - require.Equal(t,want.PubKey(),got.PubKey()) - - t.Log("Test public key encoding.") - pubJSON := utils.OrPanic1(jsontypes.Marshal(want.PubKey())) - t.Logf("pubJSON = %v",string(pubJSON)) - require.Equal(t,hexHash(pubJSON), pubKeyJSONHash) - var gotPubKey PubKey - require.NoError(t,jsontypes.Unmarshal(pubJSON, &gotPubKey)) - require.Equal(t,want.PubKey(),gotPubKey) - - t.Log("Test signature encoding.") - wantSig := want.Sign([]byte{1,2,3}) - sigJSON := utils.OrPanic1(tmjson.Marshal(wantSig)) - t.Logf("sigJSON = %v",string(sigJSON)) - require.Equal(t,hexHash(sigJSON), sigJSONHash) - var gotSig Sig - require.NoError(t,tmjson.Unmarshal(sigJSON, &gotSig)) - require.Equal(t,wantSig,gotSig) -} +var privKey = ed25519.GenPrivKeyFromSecret([]byte("tm-test-key-json-seed")) func hexHash(data []byte) string { hash := sha256.Sum256(data) return hex.EncodeToString(hash[:]) } + +// tests if hash(jsontypes.Marshal(want)) == wantHash +// returns jsontypes.Unmarshal(jsontypes.Marshal(want)) +func testTaggedJSON[T jsontypes.Tagged](t *testing.T, want T, wantHash string) T { + t.Helper() + raw, err := jsontypes.Marshal(want) + require.NoError(t, err) + t.Logf("%T -> %v", want, string(raw)) + require.Equal(t, wantHash, hexHash(raw)) + var got T + require.NoError(t, jsontypes.Unmarshal(raw, &got)) + return got +} + +func TestTaggedJSON(t *testing.T) { + pubKey := privKey.PubKey() + require.Equal(t, pubKey, testTaggedJSON(t, privKey, "f36adf0dc679100837e9819a73ccefdf073b5a2129db8d200a4262bfd47cd883").PubKey()) + require.Equal(t, pubKey, testTaggedJSON(t, pubKey, "0b0b97c108fbd1305b323676bc33dc5c9309fb947d5cd29f88e9dce1457c6362")) +} + +// tests if hash(json.Marshal(want)) == wantHash +// returns json.Unmarshal(json.Marshal(want)) +func testJSON[T any](t *testing.T, want T, wantHash string) T { + t.Helper() + raw, err := json.Marshal(want) + require.NoError(t, err) + t.Logf("%T -> %v", want, string(raw)) + require.Equal(t, wantHash, hexHash(raw)) + var got T + require.NoError(t, json.Unmarshal(raw, &got)) + return got +} + +func TestJSON(t *testing.T) { + pubKey := privKey.PubKey() + sig := privKey.Sign([]byte{1, 2, 3}) + require.Equal(t, pubKey, testJSON(t, privKey, "ecaae500bfb3a28fe1f6108cb7c18743e0242d37c8e41ddd672d8c62563bec1b").PubKey()) + require.Equal(t, pubKey, testJSON(t, pubKey, "f7874c043989887e8cfa6a3a3c1dd22432f95745481123e29201ebd21bc4d844")) + require.Equal(t, sig, testJSON(t, sig, "dd48379c6c07eb1e36b188ea0cf35772a697c1a45ad4d47986ca819262743b71")) +} diff --git a/sei-tendermint/crypto/ed25519/bench_test.go b/sei-tendermint/crypto/ed25519/bench_test.go index a51988fb54..3df746d155 100644 --- a/sei-tendermint/crypto/ed25519/bench_test.go +++ b/sei-tendermint/crypto/ed25519/bench_test.go @@ -49,7 +49,7 @@ func BenchmarkVerifyBatch(b *testing.B) { for i := range sigsCount { v.Add(pubs[i], msg, sigs[i]) } - if err := v.Verify(); err!=nil { + if err := v.Verify(); err != nil { b.Fatal(err) } } diff --git a/sei-tendermint/crypto/ed25519/ed25519.go b/sei-tendermint/crypto/ed25519/ed25519.go index d432058500..9df0837c24 100644 --- a/sei-tendermint/crypto/ed25519/ed25519.go +++ b/sei-tendermint/crypto/ed25519/ed25519.go @@ -3,8 +3,8 @@ package ed25519 import ( "crypto/rand" "crypto/sha256" - "fmt" "errors" + "fmt" "io" "github.com/oasisprotocol/curve25519-voi/primitives/ed25519" @@ -15,7 +15,7 @@ import ( ) const PrivKeyName = "tendermint/PrivKeyEd25519" -const PubKeyName = "tendermint/PubKeyEd25519" +const PubKeyName = "tendermint/PubKeyEd25519" const KeyType = "ed25519" // cacheSize is the number of public keys that will be cached in @@ -40,7 +40,7 @@ func init() { type Seed [ed25519.SeedSize]byte type PrivKey struct { - raw ed25519.PrivateKey // ed25519.PrivateKey is a slice, therefore the secret will not be copied around. + raw ed25519.PrivateKey // ed25519.PrivateKey is a slice, therefore the secret will not be copied around. } // TypeTag satisfies the jsontypes.Tagged interface. @@ -52,14 +52,14 @@ func (k PrivKey) SecretBytes() []byte { return k.raw } // Sig represents signature. type Sig [ed25519.SignatureSize]byte -func SigFromBytes(raw []byte) (Sig,error) { - if len(raw)!=len(Sig{}) { - return Sig{},errors.New("invalid signature length") +func SigFromBytes(raw []byte) (Sig, error) { + if len(raw) != len(Sig{}) { + return Sig{}, errors.New("invalid signature length") } - return Sig(raw),nil + return Sig(raw), nil } -// Sign signs a message with the key. +// Sign signs a message with the key. func (k PrivKey) Sign(msg []byte) Sig { return Sig(ed25519.Sign(k.raw, msg)) } // PubKey gets the corresponding public key from the private key. @@ -70,7 +70,7 @@ func (k PrivKey) Type() string { return KeyType } // GenPrivKey generates a new ed25519 private key from OS entropy. func GenPrivKey() PrivKey { var seed Seed - if _,err := io.ReadFull(rand.Reader,seed[:]); err != nil { + if _, err := io.ReadFull(rand.Reader, seed[:]); err != nil { panic(err) } return PrivKeyFromSeed(seed) @@ -89,15 +89,14 @@ func GenPrivKeyFromSecret(secret []byte) PrivKey { return PrivKeyFromSeed(Seed(sha256.Sum256(secret))) } - // PubKey implements the Ed25519 signature scheme. type PubKey [ed25519.PublicKeySize]byte -func PubKeyFromBytes(raw []byte) (PubKey,error) { - if len(raw)!=len(PubKey{}) { - return PubKey{},errors.New("invalid pubkey length") +func PubKeyFromBytes(raw []byte) (PubKey, error) { + if len(raw) != len(PubKey{}) { + return PubKey{}, errors.New("invalid pubkey length") } - return PubKey(raw),nil + return PubKey(raw), nil } // TypeTag satisfies the jsontypes.Tagged interface. @@ -117,10 +116,11 @@ func (k PubKey) Verify(msg []byte, sig Sig) error { } func (k PubKey) String() string { return fmt.Sprintf("PubKeyEd25519{%X}", k[:]) } -func (k PubKey) Type() string { return KeyType } +func (k PubKey) Type() string { return KeyType } // BatchVerifier implements batch verification for ed25519. -type BatchVerifier struct { inner *ed25519.BatchVerifier } +type BatchVerifier struct{ inner *ed25519.BatchVerifier } + func NewBatchVerifier() *BatchVerifier { return &BatchVerifier{ed25519.NewBatchVerifier()} } func (b *BatchVerifier) Add(key PubKey, msg []byte, sig Sig) { @@ -132,18 +132,18 @@ type ErrBadSig struct { } func (e ErrBadSig) Error() string { - return fmt.Sprintf("invalid %vth signature",e.Idx) + return fmt.Sprintf("invalid %vth signature", e.Idx) } // Verify verifies the batched signatures using OS entropy. // If any signature is invalid, returns ErrBadSig with an index // of the first invalid signature. func (b *BatchVerifier) Verify() error { - ok,res := b.inner.Verify(rand.Reader) + ok, res := b.inner.Verify(rand.Reader) if ok { return nil } - for idx,ok := range res { + for idx, ok := range res { if !ok { return ErrBadSig{idx} } diff --git a/sei-tendermint/crypto/ed25519/ed25519_test.go b/sei-tendermint/crypto/ed25519/ed25519_test.go index 578667795d..f5858b2e04 100644 --- a/sei-tendermint/crypto/ed25519/ed25519_test.go +++ b/sei-tendermint/crypto/ed25519/ed25519_test.go @@ -45,5 +45,5 @@ func TestBatchSafe(t *testing.T) { v.Add(pub, msg, priv.Sign(msg)) } - require.NoError(t,v.Verify()) + require.NoError(t, v.Verify()) } diff --git a/sei-tendermint/crypto/ed25519/json.go b/sei-tendermint/crypto/ed25519/json.go index 1836a0a620..41dc77c333 100644 --- a/sei-tendermint/crypto/ed25519/json.go +++ b/sei-tendermint/crypto/ed25519/json.go @@ -4,23 +4,44 @@ import ( "encoding/json" ) -func (k PrivKey) MarshalJSON() ([]byte,error) { +func (k PrivKey) MarshalJSON() ([]byte, error) { return json.Marshal(k.raw) } func (k *PrivKey) UnmarshalJSON(j []byte) error { - return json.Unmarshal(j,&k.raw) + return json.Unmarshal(j, &k.raw) } -func (k PubKey) MarshalJSON() ([]byte,error) { +func (k PubKey) MarshalJSON() ([]byte, error) { return json.Marshal(k[:]) } func (k *PubKey) UnmarshalJSON(j []byte) error { var raw []byte - if err:=json.Unmarshal(j,&raw); err!=nil { return err } - x,err := PubKeyFromBytes(raw) - if err!=nil { return err } + if err := json.Unmarshal(j, &raw); err != nil { + return err + } + x, err := PubKeyFromBytes(raw) + if err != nil { + return err + } *k = x return nil } + +func (s Sig) MarshalJSON() ([]byte, error) { + return json.Marshal(s[:]) +} + +func (s *Sig) UnmarshalJSON(j []byte) error { + var raw []byte + if err := json.Unmarshal(j, &raw); err != nil { + return err + } + x, err := SigFromBytes(raw) + if err != nil { + return err + } + *s = x + return nil +} diff --git a/sei-tendermint/internal/consensus/invalid_test.go b/sei-tendermint/internal/consensus/invalid_test.go index 5e0fe90549..3dd1252efc 100644 --- a/sei-tendermint/internal/consensus/invalid_test.go +++ b/sei-tendermint/internal/consensus/invalid_test.go @@ -10,10 +10,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/internal/eventbus" "github.com/tendermint/tendermint/internal/p2p" "github.com/tendermint/tendermint/libs/bytes" - "github.com/tendermint/tendermint/crypto" tmrand "github.com/tendermint/tendermint/libs/rand" tmtime "github.com/tendermint/tendermint/libs/time" "github.com/tendermint/tendermint/libs/utils" diff --git a/sei-tendermint/internal/consensus/memory_limit_test.go b/sei-tendermint/internal/consensus/memory_limit_test.go index ed5359a0c4..3791b794bd 100644 --- a/sei-tendermint/internal/consensus/memory_limit_test.go +++ b/sei-tendermint/internal/consensus/memory_limit_test.go @@ -5,16 +5,16 @@ import ( "time" "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/libs/log" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/crypto" ) func makeSig(data string) crypto.Sig { var sig crypto.Sig - n := min(len(sig),len(data)) - copy(sig[:n],[]byte(data[:n])) + n := min(len(sig), len(data)) + copy(sig[:n], []byte(data[:n])) return sig } diff --git a/sei-tendermint/internal/consensus/reactor_test.go b/sei-tendermint/internal/consensus/reactor_test.go index f78f37ea45..0e75cfc5cd 100644 --- a/sei-tendermint/internal/consensus/reactor_test.go +++ b/sei-tendermint/internal/consensus/reactor_test.go @@ -501,7 +501,7 @@ func TestReactorValidatorSetChanges(t *testing.T) { pv, _ := states[nodeIdx].privValidator.Get() key, err := pv.GetPubKey(ctx) require.NoError(t, err) - keyProto := encoding.PubKeyToProto(key) + keyProto := encoding.PubKeyToProto(key) newPower := int64(rng.Intn(100000)) tx := kvstore.MakeValSetChangeTx(keyProto, newPower) require.NoError(t, finalizeTx(ctx, valSet, blocksSubs, states, tx)) diff --git a/sei-tendermint/internal/consensus/replay_test.go b/sei-tendermint/internal/consensus/replay_test.go index 1e3f7860e7..e7f54501b1 100644 --- a/sei-tendermint/internal/consensus/replay_test.go +++ b/sei-tendermint/internal/consensus/replay_test.go @@ -20,6 +20,7 @@ import ( "github.com/tendermint/tendermint/abci/example/kvstore" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/internal/eventbus" "github.com/tendermint/tendermint/internal/mempool" @@ -37,7 +38,6 @@ import ( "github.com/tendermint/tendermint/privval" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/crypto" ) // These tests ensure we can always recover from failure at any part of the consensus process. @@ -443,7 +443,7 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite { cssPubKey, err := pv.GetPubKey(ctx) require.NoError(t, err) - if vsPubKey==cssPubKey { + if vsPubKey == cssPubKey { return i } } diff --git a/sei-tendermint/internal/consensus/state.go b/sei-tendermint/internal/consensus/state.go index ad99929972..2d97ef953f 100644 --- a/sei-tendermint/internal/consensus/state.go +++ b/sei-tendermint/internal/consensus/state.go @@ -1268,12 +1268,12 @@ func (cs *State) decideProposal(ctx context.Context, height int64, round int32, ctxto, cancel := context.WithTimeout(ctx, cs.state.ConsensusParams.Timeout.Propose) defer cancel() if err := privValidator.SignProposal(ctxto, cs.state.ChainID, p); err == nil { - sig,err := crypto.SigFromBytes(p.Signature) - if err!=nil { + sig, err := crypto.SigFromBytes(p.Signature) + if err != nil { cs.logger.Error("propose step; failed signing proposal", "height", height, "round", round, "err", err) return } - proposal.Signature = sig + proposal.Signature = sig // send proposal and block parts on internal msg queue cs.sendInternalMessage(ctx, msgInfo{&ProposalMessage{proposal}, "", tmtime.Now()}) @@ -2152,9 +2152,9 @@ func (cs *State) defaultSetProposal(proposal *types.Proposal, recvTime time.Time p := proposal.ToProto() // Verify signature - if err:=cs.roundState.Validators().GetProposer().PubKey.Verify( + if err := cs.roundState.Validators().GetProposer().PubKey.Verify( types.ProposalSignBytes(cs.state.ChainID, p), proposal.Signature, - ); err!=nil { + ); err != nil { return ErrInvalidProposalSignature } cs.roundState.SetProposal(proposal) @@ -2614,15 +2614,17 @@ func (cs *State) signVote( ctxto, cancel := context.WithTimeout(ctx, timeout) defer cancel() - if err := privValidator.SignVote(ctxto, cs.state.ChainID, v); err!=nil { - return nil,err + if err := privValidator.SignVote(ctxto, cs.state.ChainID, v); err != nil { + return nil, err + } + sig, err := crypto.SigFromBytes(v.Signature) + if err != nil { + return nil, fmt.Errorf("crypto.SigFromBytes(): %w", err) } - sig,err := crypto.SigFromBytes(v.Signature) - if err!=nil { return nil,fmt.Errorf("crypto.SigFromBytes(): %w",err) } vote.Signature = sig vote.Timestamp = v.Timestamp - return vote, nil + return vote, nil } // sign the vote and publish on internalMsgQueue diff --git a/sei-tendermint/internal/consensus/state_test.go b/sei-tendermint/internal/consensus/state_test.go index e217a2a0f7..34fa1eea96 100644 --- a/sei-tendermint/internal/consensus/state_test.go +++ b/sei-tendermint/internal/consensus/state_test.go @@ -250,7 +250,7 @@ func TestStateBadProposal(t *testing.T) { require.NoError(t, err) proposal := types.NewProposal(vs2.Height, round, -1, blockID, propBlock.Header.Time, propBlock.GetTxKeys(), propBlock.Header, propBlock.LastCommit, propBlock.Evidence, pubKey.Address()) p := proposal.ToProto() - require.NoError(t,vs2.SignProposal(ctx, config.ChainID(), p)) + require.NoError(t, vs2.SignProposal(ctx, config.ChainID(), p)) proposal.Signature = crypto.Sig(p.Signature) // set the proposal block diff --git a/sei-tendermint/internal/evidence/verify.go b/sei-tendermint/internal/evidence/verify.go index 938f46be68..a3276e39a3 100644 --- a/sei-tendermint/internal/evidence/verify.go +++ b/sei-tendermint/internal/evidence/verify.go @@ -243,10 +243,10 @@ func VerifyDuplicateVote(e *types.DuplicateVoteEvidence, chainID string, valSet va := e.VoteA.ToProto() vb := e.VoteB.ToProto() // Signatures must be valid - if err := pubKey.Verify(types.VoteSignBytes(chainID, va), e.VoteA.Signature); err!=nil { + if err := pubKey.Verify(types.VoteSignBytes(chainID, va), e.VoteA.Signature); err != nil { return fmt.Errorf("verifying VoteA: %w", types.ErrVoteInvalidSignature) } - if err := pubKey.Verify(types.VoteSignBytes(chainID, vb), e.VoteB.Signature); err!=nil { + if err := pubKey.Verify(types.VoteSignBytes(chainID, vb), e.VoteB.Signature); err != nil { return fmt.Errorf("verifying VoteB: %w", types.ErrVoteInvalidSignature) } diff --git a/sei-tendermint/internal/p2p/address_test.go b/sei-tendermint/internal/p2p/address_test.go index 72fcf34f89..fbed1bab3e 100644 --- a/sei-tendermint/internal/p2p/address_test.go +++ b/sei-tendermint/internal/p2p/address_test.go @@ -38,7 +38,7 @@ func TestNewNodeID(t *testing.T) { } func TestNewNodeIDFromPubKey(t *testing.T) { - privKey := ed25519.PrivKeyFromSeed(ed25519.Seed{43,55,33}) + privKey := ed25519.PrivKeyFromSeed(ed25519.Seed{43, 55, 33}) nodeID := types.NodeIDFromPubKey(privKey.PubKey()) require.NoError(t, nodeID.Validate()) } diff --git a/sei-tendermint/internal/p2p/conn/secret_connection.go b/sei-tendermint/internal/p2p/conn/secret_connection.go index 6d60cc3a17..28d2a36500 100644 --- a/sei-tendermint/internal/p2p/conn/secret_connection.go +++ b/sei-tendermint/internal/p2p/conn/secret_connection.go @@ -162,8 +162,8 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey ed25519.PrivKey) ( remPubKey, remSignature := authSigMsg.Key, authSigMsg.Sig - if err:=remPubKey.Verify(challenge[:], remSignature); err!=nil { - return nil, fmt.Errorf("challenge verification failed: %w",err) + if err := remPubKey.Verify(challenge[:], remSignature); err != nil { + return nil, fmt.Errorf("challenge verification failed: %w", err) } // We've authorized. @@ -404,13 +404,13 @@ func shareAuthSignature(sc io.ReadWriter, pubKey ed25519.PubKey, sig ed25519.Sig if _, err := protoio.NewDelimitedReader(sc, 1024*1024).ReadMsg(&pba); err != nil { return nil, true, err } - key,err := ed25519.PubKeyFromBytes(pba.PubKey.GetEd25519()) - if err!=nil { - return nil, true, fmt.Errorf("ed25519.PubKeyFromBytes(): %w",err) + key, err := ed25519.PubKeyFromBytes(pba.PubKey.GetEd25519()) + if err != nil { + return nil, true, fmt.Errorf("ed25519.PubKeyFromBytes(): %w", err) } - sig,err := ed25519.SigFromBytes(pba.Sig) - if err!=nil { - return nil, true, fmt.Errorf("ed25519.SigFromBytes(): %w",err) + sig, err := ed25519.SigFromBytes(pba.Sig) + if err != nil { + return nil, true, fmt.Errorf("ed25519.SigFromBytes(): %w", err) } return authSigMessage{Key: key, Sig: sig}, false, nil }, @@ -418,7 +418,7 @@ func shareAuthSignature(sc io.ReadWriter, pubKey ed25519.PubKey, sig ed25519.Sig // If error: if trs.FirstError() != nil { - return authSigMessage{},trs.FirstError() + return authSigMessage{}, trs.FirstError() } var _recvMsg = trs.FirstValue().(authSigMessage) diff --git a/sei-tendermint/internal/p2p/conn/secret_connection_test.go b/sei-tendermint/internal/p2p/conn/secret_connection_test.go index 18bc464284..2f06745d34 100644 --- a/sei-tendermint/internal/p2p/conn/secret_connection_test.go +++ b/sei-tendermint/internal/p2p/conn/secret_connection_test.go @@ -323,7 +323,7 @@ func makeSecretConnPair(tb testing.TB) (fooSecConn, barSecConn *SecretConnection return nil, true, err } remotePubKey := barSecConn.RemotePubKey() - if remotePubKey!=fooPubKey { + if remotePubKey != fooPubKey { err = fmt.Errorf("unexpected barSecConn.RemotePubKey. Expected %v, got %v", fooPubKey, remotePubKey) tb.Error(err) diff --git a/sei-tendermint/internal/p2p/peermanager_test.go b/sei-tendermint/internal/p2p/peermanager_test.go index 3c357da83c..31a3eba2e1 100644 --- a/sei-tendermint/internal/p2p/peermanager_test.go +++ b/sei-tendermint/internal/p2p/peermanager_test.go @@ -55,7 +55,7 @@ func makePeerManager(selfID types.NodeID, options *RouterOptions) *peerManager[* return newPeerManager[*fakeConn](selfID, options) } -var selfID = types.NodeIDFromPubKey(ed25519.PrivKeyFromSeed(ed25519.Seed{12,43}).PubKey()) +var selfID = types.NodeIDFromPubKey(ed25519.PrivKeyFromSeed(ed25519.Seed{12, 43}).PubKey()) func makeKey(rng utils.Rng) ed25519.PrivKey { return ed25519.PrivKeyFromSeed(ed25519.Seed(utils.GenBytes(rng, len(ed25519.Seed{})))) diff --git a/sei-tendermint/internal/roles/validator/msg.go b/sei-tendermint/internal/roles/validator/msg.go index 9f534d947c..cb3e698324 100644 --- a/sei-tendermint/internal/roles/validator/msg.go +++ b/sei-tendermint/internal/roles/validator/msg.go @@ -1,11 +1,11 @@ package validator import ( - "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/libs/utils" ) -type Msg interface { isMsg() } +type Msg interface{ isMsg() } type SessionID struct { utils.ReadOnly @@ -16,7 +16,7 @@ func (s *SessionID) Raw() [10]byte { return s.raw } func (s *SessionID) isMsg() {} -type Sig struct { inner ed25519.Sig } +type Sig struct{ inner ed25519.Sig } type Signed[M Msg] struct { utils.ReadOnly diff --git a/sei-tendermint/internal/rpc/core/env.go b/sei-tendermint/internal/rpc/core/env.go index cbdc61037f..94e1e7439f 100644 --- a/sei-tendermint/internal/rpc/core/env.go +++ b/sei-tendermint/internal/rpc/core/env.go @@ -13,7 +13,6 @@ import ( abciclient "github.com/tendermint/tendermint/abci/client" "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/internal/blocksync" "github.com/tendermint/tendermint/internal/consensus" "github.com/tendermint/tendermint/internal/eventbus" @@ -28,6 +27,7 @@ import ( tmjson "github.com/tendermint/tendermint/libs/json" "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/strings" + "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/rpc/coretypes" rpcserver "github.com/tendermint/tendermint/rpc/jsonrpc/server" "github.com/tendermint/tendermint/types" diff --git a/sei-tendermint/internal/rpc/core/status.go b/sei-tendermint/internal/rpc/core/status.go index 74f381bfa0..f46eca9670 100644 --- a/sei-tendermint/internal/rpc/core/status.go +++ b/sei-tendermint/internal/rpc/core/status.go @@ -7,9 +7,9 @@ import ( "time" tmbytes "github.com/tendermint/tendermint/libs/bytes" + "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/rpc/coretypes" "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/libs/utils" ) // Status returns Tendermint status including node info, pubkey, latest block @@ -49,7 +49,7 @@ func (env *Environment) Status(ctx context.Context) (*coretypes.ResultStatus, er // Return the very last voting power, not the voting power of this validator // during the last block. validatorInfo := coretypes.ValidatorInfo{PubKey: env.PubKey} - if val,ok := env.validatorAtHeight(env.latestUncommittedHeight()).Get(); ok { + if val, ok := env.validatorAtHeight(env.latestUncommittedHeight()).Get(); ok { validatorInfo.VotingPower = val.VotingPower } var applicationInfo coretypes.ApplicationInfo @@ -103,8 +103,10 @@ func (env *Environment) Status(ctx context.Context) (*coretypes.ResultStatus, er func (env *Environment) validatorAtHeight(h int64) utils.Option[*types.Validator] { none := utils.None[*types.Validator]() - k,ok := env.PubKey.Get() - if !ok { return none } + k, ok := env.PubKey.Get() + if !ok { + return none + } valsWithH, err := env.StateStore.LoadValidators(h) if err != nil { return none @@ -125,7 +127,7 @@ func (env *Environment) validatorAtHeight(h int64) utils.Option[*types.Validator } _, val := valsWithH.GetByAddress(privValAddress) - if val!=nil { + if val != nil { return utils.Some(val) } return none diff --git a/sei-tendermint/internal/state/helpers_test.go b/sei-tendermint/internal/state/helpers_test.go index 45a1df81c1..929c9909de 100644 --- a/sei-tendermint/internal/state/helpers_test.go +++ b/sei-tendermint/internal/state/helpers_test.go @@ -101,7 +101,7 @@ func makeValidCommit( func makePrivKey(i int) ed25519.PrivKey { var seed ed25519.Seed - copy(seed[:],fmt.Sprintf("%d",i)) + copy(seed[:], fmt.Sprintf("%d", i)) return ed25519.PrivKeyFromSeed(seed) } @@ -109,7 +109,7 @@ func makeState(t *testing.T, nVals, height int) (sm.State, dbm.DB, map[string]ty vals := make([]types.GenesisValidator, nVals) privVals := make(map[string]types.PrivValidator, nVals) for i := 0; i < nVals; i++ { - pk := makePrivKey(i) + pk := makePrivKey(i) valAddr := pk.PubKey().Address() vals[i] = types.GenesisValidator{ Address: valAddr, @@ -157,7 +157,7 @@ func makeHeaderPartsResponsesValPubKeyChange( finalizeBlockResponses := &abci.ResponseFinalizeBlock{} // If the pubkey is new, remove the old and add the new. _, val := state.NextValidators.GetByIndex(0) - if pubkey!=val.PubKey { + if pubkey != val.PubKey { vPbPk := encoding.PubKeyToProto(val.PubKey) pbPk := encoding.PubKeyToProto(pubkey) diff --git a/sei-tendermint/internal/test/factory/commit.go b/sei-tendermint/internal/test/factory/commit.go index c9a7b905c9..3929dafdd3 100644 --- a/sei-tendermint/internal/test/factory/commit.go +++ b/sei-tendermint/internal/test/factory/commit.go @@ -2,12 +2,12 @@ package factory import ( "context" - "time" "fmt" + "time" + "github.com/tendermint/tendermint/crypto" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/crypto" ) func MakeCommit(ctx context.Context, blockID types.BlockID, height int64, round int32, voteSet *types.VoteSet, validators []types.PrivValidator, now time.Time) (*types.Commit, error) { @@ -32,9 +32,11 @@ func MakeCommit(ctx context.Context, blockID types.BlockID, height int64, round if err := validators[i].SignVote(ctx, voteSet.ChainID(), v); err != nil { return nil, err } - sig,err := crypto.SigFromBytes(v.Signature) - if err!=nil { return nil, fmt.Errorf("crypto.SigFromBytes(): %w",err) } - vote.Signature = sig + sig, err := crypto.SigFromBytes(v.Signature) + if err != nil { + return nil, fmt.Errorf("crypto.SigFromBytes(): %w", err) + } + vote.Signature = sig if _, err := voteSet.AddVote(vote); err != nil { return nil, err } diff --git a/sei-tendermint/internal/test/factory/vote.go b/sei-tendermint/internal/test/factory/vote.go index a455e9bde1..5ac1d5620c 100644 --- a/sei-tendermint/internal/test/factory/vote.go +++ b/sei-tendermint/internal/test/factory/vote.go @@ -2,12 +2,12 @@ package factory import ( "context" - "time" "fmt" + "time" + "github.com/tendermint/tendermint/crypto" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/crypto" ) func MakeVote( @@ -40,8 +40,10 @@ func MakeVote( if err := val.SignVote(ctx, chainID, vpb); err != nil { return nil, err } - sig,err := crypto.SigFromBytes(vpb.Signature) - if err!=nil { return nil, fmt.Errorf("crypto.SigFromBytes(): %w",err) } + sig, err := crypto.SigFromBytes(vpb.Signature) + if err != nil { + return nil, fmt.Errorf("crypto.SigFromBytes(): %w", err) + } v.Signature = sig return v, nil } diff --git a/sei-tendermint/libs/utils/option.go b/sei-tendermint/libs/utils/option.go index d72ab906f2..210ba32ee5 100644 --- a/sei-tendermint/libs/utils/option.go +++ b/sei-tendermint/libs/utils/option.go @@ -27,7 +27,6 @@ func (o Option[T]) Get() (T, bool) { return Zero[T](), false } - // IsPresent checks if the Option contains a value. func (o Option[T]) IsPresent() bool { return o.isPresent diff --git a/sei-tendermint/libs/utils/proto.go b/sei-tendermint/libs/utils/proto.go index aac3ee4981..a2bd14f315 100644 --- a/sei-tendermint/libs/utils/proto.go +++ b/sei-tendermint/libs/utils/proto.go @@ -3,12 +3,11 @@ package utils import ( "errors" "fmt" - "sync" - "golang.org/x/exp/constraints" "github.com/gogo/protobuf/proto" + "golang.org/x/exp/constraints" + "sync" ) - func ErrorAs[T error](err error) Option[T] { var target T if errors.As(err, &target) { diff --git a/sei-tendermint/libs/utils/testonly.go b/sei-tendermint/libs/utils/testonly.go index 4b35ad59b8..aab2ac4f68 100644 --- a/sei-tendermint/libs/utils/testonly.go +++ b/sei-tendermint/libs/utils/testonly.go @@ -49,7 +49,7 @@ var cmpOpts = []cmp.Option{ } func OrPanic(err error) { - if err!=nil { + if err != nil { panic(err) } } diff --git a/sei-tendermint/node/setup.go b/sei-tendermint/node/setup.go index f22084ed75..e1ac7d8356 100644 --- a/sei-tendermint/node/setup.go +++ b/sei-tendermint/node/setup.go @@ -133,8 +133,10 @@ func logNodeStartupInfo(state sm.State, pubKey utils.Option[crypto.PubKey], logg } func onlyValidatorIsUs(state sm.State, pubKey utils.Option[crypto.PubKey]) bool { - k,ok := pubKey.Get() - if !ok { return false } + k, ok := pubKey.Get() + if !ok { + return false + } if state.Validators.Size() > 1 { return false } diff --git a/sei-tendermint/privval/msgs_test.go b/sei-tendermint/privval/msgs_test.go index 04b167a40f..23608e08cf 100644 --- a/sei-tendermint/privval/msgs_test.go +++ b/sei-tendermint/privval/msgs_test.go @@ -51,7 +51,7 @@ func exampleProposal() *types.Proposal { } func TestPrivvalVectors(t *testing.T) { - pk := ed25519.PrivKeyFromSeed(ed25519.Seed{1,2,3,4}).PubKey() + pk := ed25519.PrivKeyFromSeed(ed25519.Seed{1, 2, 3, 4}).PubKey() ppk := encoding.PubKeyToProto(pk) // Generate a simple vote diff --git a/sei-tendermint/privval/secret_connection.go b/sei-tendermint/privval/secret_connection.go index 5cbb3f056b..9e73a7004e 100644 --- a/sei-tendermint/privval/secret_connection.go +++ b/sei-tendermint/privval/secret_connection.go @@ -171,8 +171,8 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey ed25519.PrivKey) ( } remPubKey, remSignature := authSigMsg.Key, authSigMsg.Sig - if err:=remPubKey.Verify(challenge[:], remSignature); err!=nil { - return nil, fmt.Errorf("challenge verification failed: %w",err) + if err := remPubKey.Verify(challenge[:], remSignature); err != nil { + return nil, fmt.Errorf("challenge verification failed: %w", err) } // We've authorized. @@ -421,15 +421,15 @@ func shareAuthSignature(sc io.ReadWriter, pubKey ed25519.PubKey, signature ed255 return nil, true, err // abort } - key,err := ed25519.PubKeyFromBytes(pba.PubKey.GetEd25519()) - if err!=nil { - return nil,true, fmt.Errorf("PubKey: %w",err) + key, err := ed25519.PubKeyFromBytes(pba.PubKey.GetEd25519()) + if err != nil { + return nil, true, fmt.Errorf("PubKey: %w", err) } - sig,err := ed25519.SigFromBytes(pba.Sig) - if err!=nil { - return nil,true,fmt.Errorf("Sig: %w",err) + sig, err := ed25519.SigFromBytes(pba.Sig) + if err != nil { + return nil, true, fmt.Errorf("Sig: %w", err) } - return authSigMessage{key,sig}, false, nil + return authSigMessage{key, sig}, false, nil }, ) diff --git a/sei-tendermint/rpc/client/rpc_test.go b/sei-tendermint/rpc/client/rpc_test.go index ed8b1bb52e..7c0d953b70 100644 --- a/sei-tendermint/rpc/client/rpc_test.go +++ b/sei-tendermint/rpc/client/rpc_test.go @@ -16,7 +16,6 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/libs/utils/require" "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/internal/mempool" rpccore "github.com/tendermint/tendermint/internal/rpc/core" @@ -24,6 +23,7 @@ import ( "github.com/tendermint/tendermint/libs/log" tmmath "github.com/tendermint/tendermint/libs/math" "github.com/tendermint/tendermint/libs/service" + "github.com/tendermint/tendermint/libs/utils/require" "github.com/tendermint/tendermint/privval" "github.com/tendermint/tendermint/rpc/client" rpchttp "github.com/tendermint/tendermint/rpc/client/http" diff --git a/sei-tendermint/rpc/coretypes/responses.go b/sei-tendermint/rpc/coretypes/responses.go index a3b47bfa14..4bc184f037 100644 --- a/sei-tendermint/rpc/coretypes/responses.go +++ b/sei-tendermint/rpc/coretypes/responses.go @@ -11,6 +11,7 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/internal/jsontypes" "github.com/tendermint/tendermint/libs/bytes" + "github.com/tendermint/tendermint/libs/utils" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/types" ) @@ -136,8 +137,8 @@ type validatorInfoJSON struct { func (v ValidatorInfo) MarshalJSON() ([]byte, error) { j := validatorInfoJSON{VotingPower: v.VotingPower} - if k,ok:=v.PubKey.Get(); ok { - pk, err := k.MarshalJSON() + if k, ok := v.PubKey.Get(); ok { + pk, err := jsontypes.Marshal(k) if err != nil { return nil, err } @@ -149,12 +150,12 @@ func (v ValidatorInfo) MarshalJSON() ([]byte, error) { func (v *ValidatorInfo) UnmarshalJSON(data []byte) error { var val validatorInfoJSON - if len(val.PubKey)!=0 { + if len(val.PubKey) != 0 { var pk crypto.PubKey - if err := encoding.Unmarshal(val.PubKey, &pk); err != nil { + if err := jsontypes.Unmarshal(val.PubKey, &pk); err != nil { return err } - val.PubKey = utils.Some(pk) + v.PubKey = utils.Some(pk) } v.VotingPower = val.VotingPower return nil diff --git a/sei-tendermint/test/e2e/app/app.go b/sei-tendermint/test/e2e/app/app.go index fab3a865d6..4bda48a04c 100644 --- a/sei-tendermint/test/e2e/app/app.go +++ b/sei-tendermint/test/e2e/app/app.go @@ -14,10 +14,10 @@ import ( "github.com/tendermint/tendermint/abci/example/code" abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/version" - "github.com/tendermint/tendermint/crypto" ) // Application is an ABCI application for use by end-to-end tests. It is a diff --git a/sei-tendermint/test/fuzz/tests/p2p_secretconnection_test.go b/sei-tendermint/test/fuzz/tests/p2p_secretconnection_test.go index 7567d687c8..972acdf80e 100644 --- a/sei-tendermint/test/fuzz/tests/p2p_secretconnection_test.go +++ b/sei-tendermint/test/fuzz/tests/p2p_secretconnection_test.go @@ -99,7 +99,7 @@ func makeSecretConnPair() (fooSecConn, barSecConn *sc.SecretConnection) { return nil, true, err } remotePubBytes := fooSecConn.RemotePubKey() - if remotePubBytes!=barPubKey { + if remotePubBytes != barPubKey { err = fmt.Errorf("unexpected fooSecConn.RemotePubKey. Expected %v, got %v", barPubKey, fooSecConn.RemotePubKey()) log.Print(err) @@ -114,7 +114,7 @@ func makeSecretConnPair() (fooSecConn, barSecConn *sc.SecretConnection) { return nil, true, err } remotePubBytes := barSecConn.RemotePubKey() - if remotePubBytes!=fooPubKey { + if remotePubBytes != fooPubKey { err = fmt.Errorf("unexpected barSecConn.RemotePubKey. Expected %v, got %v", fooPubKey, barSecConn.RemotePubKey()) log.Print(err) diff --git a/sei-tendermint/types/block.go b/sei-tendermint/types/block.go index b625ba182f..0e2c9e439e 100644 --- a/sei-tendermint/types/block.go +++ b/sei-tendermint/types/block.go @@ -745,11 +745,11 @@ func (cs *CommitSig) FromProto(csp tmproto.CommitSig) error { cs.BlockIDFlag = BlockIDFlag(csp.BlockIdFlag) cs.ValidatorAddress = csp.ValidatorAddress cs.Timestamp = csp.Timestamp - sig,err := crypto.SigFromBytes(csp.Signature) - if err!=nil { - return fmt.Errorf("Signature: %w",err) + sig, err := crypto.SigFromBytes(csp.Signature) + if err != nil { + return fmt.Errorf("Signature: %w", err) } - cs.Signature = sig + cs.Signature = sig return cs.ValidateBasic() } diff --git a/sei-tendermint/types/block_test.go b/sei-tendermint/types/block_test.go index 82bd462bd3..80a9be8aec 100644 --- a/sei-tendermint/types/block_test.go +++ b/sei-tendermint/types/block_test.go @@ -6,8 +6,8 @@ import ( "context" "crypto/rand" "encoding/hex" - "math" "io" + "math" mrand "math/rand" "os" "reflect" @@ -302,8 +302,8 @@ func TestMaxCommitBytes(t *testing.T) { timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC) sig := crypto.Sig{} - _,err := io.ReadFull(rand.Reader,sig[:]) - require.NoError(t,err) + _, err := io.ReadFull(rand.Reader, sig[:]) + require.NoError(t, err) cs := CommitSig{ BlockIDFlag: BlockIDFlagNil, ValidatorAddress: crypto.AddressHash([]byte("validator_address")), diff --git a/sei-tendermint/types/evidence.go b/sei-tendermint/types/evidence.go index cab7573b35..e7731bb8aa 100644 --- a/sei-tendermint/types/evidence.go +++ b/sei-tendermint/types/evidence.go @@ -856,13 +856,13 @@ func NewMockDuplicateVoteEvidenceWithValidator(ctx context.Context, height int64 voteA := makeMockVote(height, 0, 0, pubKey.Address(), randBlockID(), time) vA := voteA.ToProto() _ = pv.SignVote(ctx, chainID, vA) - if voteA.Signature,err = crypto.SigFromBytes(vA.Signature); err!=nil { - return nil,err + if voteA.Signature, err = crypto.SigFromBytes(vA.Signature); err != nil { + return nil, err } voteB := makeMockVote(height, 0, 0, pubKey.Address(), randBlockID(), time) vB := voteB.ToProto() _ = pv.SignVote(ctx, chainID, vB) - if voteB.Signature,err = crypto.SigFromBytes(vB.Signature); err!=nil { + if voteB.Signature, err = crypto.SigFromBytes(vB.Signature); err != nil { return nil, err } ev, err := NewDuplicateVoteEvidence(voteA, voteB, time, NewValidatorSet([]*Validator{val})) diff --git a/sei-tendermint/types/evidence_test.go b/sei-tendermint/types/evidence_test.go index c3ac752cbe..50dedbe190 100644 --- a/sei-tendermint/types/evidence_test.go +++ b/sei-tendermint/types/evidence_test.go @@ -383,7 +383,7 @@ func TestEvidenceVectors(t *testing.T) { // Votes for duplicateEvidence val := NewMockPV() - val.PrivKey = ed25519.PrivKeyFromSeed(ed25519.Seed{1,2,3,4}) // deterministic key + val.PrivKey = ed25519.PrivKeyFromSeed(ed25519.Seed{1, 2, 3, 4}) // deterministic key blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash"))) blockID2 := makeBlockID(crypto.Checksum([]byte("blockhash2")), math.MaxInt32, crypto.Checksum([]byte("partshash"))) const chainID = "mychain" diff --git a/sei-tendermint/types/proposal.go b/sei-tendermint/types/proposal.go index 1d05536726..d0b4fb517f 100644 --- a/sei-tendermint/types/proposal.go +++ b/sei-tendermint/types/proposal.go @@ -6,8 +6,8 @@ import ( "math/bits" "time" - "github.com/tendermint/tendermint/internal/libs/protoio" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/internal/libs/protoio" tmbytes "github.com/tendermint/tendermint/libs/bytes" tmtime "github.com/tendermint/tendermint/libs/time" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -26,13 +26,13 @@ var ( // If POLRound >= 0, then BlockID corresponds to the block that is locked in POLRound. type Proposal struct { Type tmproto.SignedMsgType - Height int64 `json:"height,string"` - Round int32 `json:"round"` // there can not be greater than 2_147_483_647 rounds - POLRound int32 `json:"pol_round"` // -1 if null. - BlockID BlockID `json:"block_id"` - Timestamp time.Time `json:"timestamp"` - Signature crypto.Sig `json:"signature"` - TxKeys []TxKey `json:"tx_keys"` + Height int64 `json:"height,string"` + Round int32 `json:"round"` // there can not be greater than 2_147_483_647 rounds + POLRound int32 `json:"pol_round"` // -1 if null. + BlockID BlockID `json:"block_id"` + Timestamp time.Time `json:"timestamp"` + Signature crypto.Sig `json:"signature"` + TxKeys []TxKey `json:"tx_keys"` Header `json:"header"` LastCommit *Commit `json:"last_commit"` Evidence EvidenceList `json:"evidence"` @@ -209,9 +209,9 @@ func ProposalFromProto(pp *tmproto.Proposal) (*Proposal, error) { p.Round = pp.Round p.POLRound = pp.PolRound p.Timestamp = pp.Timestamp - sig,err := crypto.SigFromBytes(pp.Signature) - if err!=nil { - return nil, fmt.Errorf("Signature: %w",err) + sig, err := crypto.SigFromBytes(pp.Signature) + if err != nil { + return nil, fmt.Errorf("Signature: %w", err) } p.Signature = sig txKeys, err := TxKeysListFromProto(pp.TxKeys) diff --git a/sei-tendermint/types/proposal_test.go b/sei-tendermint/types/proposal_test.go index 62a3e22338..1f666f03ed 100644 --- a/sei-tendermint/types/proposal_test.go +++ b/sei-tendermint/types/proposal_test.go @@ -99,7 +99,7 @@ func TestProposalVerifySignature(t *testing.T) { prop.Signature = crypto.Sig(p.Signature) // verify the same proposal - require.NoError(t,pubKey.Verify(signBytes, prop.Signature)) + require.NoError(t, pubKey.Verify(signBytes, prop.Signature)) // serialize, deserialize and verify again.... newProp := new(tmproto.Proposal) @@ -117,7 +117,7 @@ func TestProposalVerifySignature(t *testing.T) { // verify the transmitted proposal newSignBytes := ProposalSignBytes("test_chain_id", pb) require.Equal(t, string(signBytes), string(newSignBytes)) - require.NoError(t,pubKey.Verify(newSignBytes, np.Signature)) + require.NoError(t, pubKey.Verify(newSignBytes, np.Signature)) } func BenchmarkProposalWriteSignBytes(b *testing.B) { diff --git a/sei-tendermint/types/test_util.go b/sei-tendermint/types/test_util.go index c0a7b54995..724bc9ce4f 100644 --- a/sei-tendermint/types/test_util.go +++ b/sei-tendermint/types/test_util.go @@ -42,9 +42,9 @@ func signAddVote(ctx context.Context, privVal PrivValidator, vote *Vote, voteSet if err := privVal.SignVote(ctx, voteSet.ChainID(), v); err != nil { return false, err } - sig,err := crypto.SigFromBytes(v.Signature) - if err!=nil { - return false, fmt.Errorf("SigFromBytes(): %w",err) + sig, err := crypto.SigFromBytes(v.Signature) + if err != nil { + return false, fmt.Errorf("SigFromBytes(): %w", err) } vote.Signature = sig return voteSet.AddVote(vote) diff --git a/sei-tendermint/types/validation.go b/sei-tendermint/types/validation.go index 474488f9be..8664caed86 100644 --- a/sei-tendermint/types/validation.go +++ b/sei-tendermint/types/validation.go @@ -5,8 +5,8 @@ import ( "fmt" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/libs/utils" tmmath "github.com/tendermint/tendermint/libs/math" + "github.com/tendermint/tendermint/libs/utils" ) const batchVerifyThreshold = 2 @@ -229,7 +229,7 @@ func verifyCommitBatch( } // attempt to verify the batch. - if err := bv.Verify(); err!=nil { + if err := bv.Verify(); err != nil { err := utils.ErrorAs[crypto.ErrBadSig](err).OrPanic() // go back from the batch index to the commit.Signatures index idx := batchSigIdxs[err.Idx] @@ -291,7 +291,7 @@ func verifyCommitSingle( } voteSignBytes = commit.VoteSignBytes(chainID, int32(idx)) - if err := val.PubKey.Verify(voteSignBytes, commitSig.Signature); err!=nil { + if err := val.PubKey.Verify(voteSignBytes, commitSig.Signature); err != nil { return errBadSig{fmt.Errorf("wrong signature (#%d): %X", idx, commitSig.Signature)} } diff --git a/sei-tendermint/types/validation_test.go b/sei-tendermint/types/validation_test.go index b96af3459a..e5fd3b8f05 100644 --- a/sei-tendermint/types/validation_test.go +++ b/sei-tendermint/types/validation_test.go @@ -7,8 +7,8 @@ import ( "time" "github.com/stretchr/testify/assert" - "github.com/tendermint/tendermint/libs/utils/require" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/libs/utils/require" tmmath "github.com/tendermint/tendermint/libs/math" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" diff --git a/sei-tendermint/types/vote.go b/sei-tendermint/types/vote.go index be2e2bd04f..2fca636f79 100644 --- a/sei-tendermint/types/vote.go +++ b/sei-tendermint/types/vote.go @@ -67,9 +67,9 @@ func VoteFromProto(pv *tmproto.Vote) (*Vote, error) { if err != nil { return nil, err } - sig,err := crypto.SigFromBytes(pv.Signature) - if err!=nil { - return nil,fmt.Errorf("Signature: %w",err) + sig, err := crypto.SigFromBytes(pv.Signature) + if err != nil { + return nil, fmt.Errorf("Signature: %w", err) } return &Vote{ Type: pv.Type, @@ -175,7 +175,7 @@ func (vote *Vote) verifyAndReturnProto(chainID string, pubKey crypto.PubKey) (*t return nil, ErrVoteInvalidValidatorAddress } v := vote.ToProto() - if err:=pubKey.Verify(VoteSignBytes(chainID, v), vote.Signature); err!=nil { + if err := pubKey.Verify(VoteSignBytes(chainID, v), vote.Signature); err != nil { return nil, ErrVoteInvalidSignature } return v, nil diff --git a/sei-tendermint/types/vote_set.go b/sei-tendermint/types/vote_set.go index f9c32a04ea..4b679dc83e 100644 --- a/sei-tendermint/types/vote_set.go +++ b/sei-tendermint/types/vote_set.go @@ -183,7 +183,7 @@ func (voteSet *VoteSet) addVote(vote *Vote) (added bool, err error) { // If we already know of this vote, return false. if existing, ok := voteSet.getVote(valIndex, blockKey); ok { - if existing.Signature==vote.Signature { + if existing.Signature == vote.Signature { return false, nil // duplicate } return false, fmt.Errorf("existing vote: %v; new vote: %v: %w", existing, vote, ErrVoteNonDeterministicSignature) diff --git a/sei-tendermint/types/vote_test.go b/sei-tendermint/types/vote_test.go index b2ad25e37b..de1eb8eba7 100644 --- a/sei-tendermint/types/vote_test.go +++ b/sei-tendermint/types/vote_test.go @@ -9,10 +9,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/libs/utils" - "github.com/tendermint/tendermint/libs/utils/require" "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/internal/libs/protoio" + "github.com/tendermint/tendermint/libs/utils" + "github.com/tendermint/tendermint/libs/utils/require" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) @@ -163,7 +163,7 @@ func TestVoteVerifySignature(t *testing.T) { require.NoError(t, privVal.SignVote(ctx, "test_chain_id", v)) // verify the same vote - require.NoError(t,pubkey.Verify(VoteSignBytes("test_chain_id", v), crypto.Sig(v.Signature))) + require.NoError(t, pubkey.Verify(VoteSignBytes("test_chain_id", v), crypto.Sig(v.Signature))) // serialize, deserialize and verify again.... precommit := new(tmproto.Vote) From b0ce59f73af61d0b7c3df60af590ddcdc30edc46 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Wed, 17 Dec 2025 17:55:32 +0100 Subject: [PATCH 30/53] copied from sei-v3 --- .../crypto/keys/ed25519/ed25519_test.go | 10 +- sei-tendermint/crypto/crypto.go | 8 +- sei-tendermint/crypto/crypto_test.go | 10 +- sei-tendermint/crypto/ed25519/bench_test.go | 16 +- sei-tendermint/crypto/ed25519/conv.go | 72 ++++++++ sei-tendermint/crypto/ed25519/ed25519.go | 158 +++++++++--------- sei-tendermint/crypto/ed25519/ed25519_test.go | 23 ++- sei-tendermint/crypto/ed25519/json.go | 53 ++++-- sei-tendermint/crypto/encoding/codec.go | 4 +- 9 files changed, 225 insertions(+), 129 deletions(-) create mode 100644 sei-tendermint/crypto/ed25519/conv.go diff --git a/sei-cosmos/crypto/keys/ed25519/ed25519_test.go b/sei-cosmos/crypto/keys/ed25519/ed25519_test.go index 83622ee430..30954f8e9c 100644 --- a/sei-cosmos/crypto/keys/ed25519/ed25519_test.go +++ b/sei-cosmos/crypto/keys/ed25519/ed25519_test.go @@ -139,7 +139,7 @@ func TestMarshalAmino(t *testing.T) { testCases := []struct { desc string msg codec.AminoMarshaler - typ interface{} + typ any expBinary []byte expJSON string }{ @@ -190,14 +190,14 @@ func TestMarshalAmino_BackwardsCompatibility(t *testing.T) { tmPrivKey := tmed25519.GenPrivKey() tmPubKey := tmPrivKey.PubKey() // Create our own keys, with the same private key as Tendermint's. - privKey := &ed25519.PrivKey{Key: []byte(tmPrivKey)} + privKey := &ed25519.PrivKey{Key: tmPrivKey.SecretBytes()} pubKey := privKey.PubKey().(*ed25519.PubKey) testCases := []struct { desc string - tmKey interface{} - ourKey interface{} - marshalFn func(o interface{}) ([]byte, error) + tmKey any + ourKey any + marshalFn func(o any) ([]byte, error) }{ { "ed25519 private key, binary", diff --git a/sei-tendermint/crypto/crypto.go b/sei-tendermint/crypto/crypto.go index 52936fa426..d883f0258c 100644 --- a/sei-tendermint/crypto/crypto.go +++ b/sei-tendermint/crypto/crypto.go @@ -35,14 +35,14 @@ func Checksum(bz []byte) []byte { return h[:] } -type PubKey = ed25519.PubKey -type PrivKey = ed25519.PrivKey -type Sig = ed25519.Sig +type PubKey = ed25519.PublicKey +type PrivKey = ed25519.SecretKey +type Sig = ed25519.Signature type BatchVerifier = ed25519.BatchVerifier type ErrBadSig = ed25519.ErrBadSig func SigFromBytes(raw []byte) (Sig, error) { - return ed25519.SigFromBytes(raw) + return ed25519.SignatureFromBytes(raw) } func NewBatchVerifier() *BatchVerifier { diff --git a/sei-tendermint/crypto/crypto_test.go b/sei-tendermint/crypto/crypto_test.go index b3b3b2f6cd..fc5b9194d3 100644 --- a/sei-tendermint/crypto/crypto_test.go +++ b/sei-tendermint/crypto/crypto_test.go @@ -11,7 +11,7 @@ import ( "github.com/tendermint/tendermint/libs/utils/require" ) -var privKey = ed25519.GenPrivKeyFromSecret([]byte("tm-test-key-json-seed")) +var privKey = ed25519.TestSecretKey([]byte("tm-test-key-json-seed")) func hexHash(data []byte) string { hash := sha256.Sum256(data) @@ -32,8 +32,8 @@ func testTaggedJSON[T jsontypes.Tagged](t *testing.T, want T, wantHash string) T } func TestTaggedJSON(t *testing.T) { - pubKey := privKey.PubKey() - require.Equal(t, pubKey, testTaggedJSON(t, privKey, "f36adf0dc679100837e9819a73ccefdf073b5a2129db8d200a4262bfd47cd883").PubKey()) + pubKey := privKey.Public() + require.Equal(t, pubKey, testTaggedJSON(t, privKey, "f36adf0dc679100837e9819a73ccefdf073b5a2129db8d200a4262bfd47cd883").Public()) require.Equal(t, pubKey, testTaggedJSON(t, pubKey, "0b0b97c108fbd1305b323676bc33dc5c9309fb947d5cd29f88e9dce1457c6362")) } @@ -51,9 +51,9 @@ func testJSON[T any](t *testing.T, want T, wantHash string) T { } func TestJSON(t *testing.T) { - pubKey := privKey.PubKey() + pubKey := privKey.Public() sig := privKey.Sign([]byte{1, 2, 3}) - require.Equal(t, pubKey, testJSON(t, privKey, "ecaae500bfb3a28fe1f6108cb7c18743e0242d37c8e41ddd672d8c62563bec1b").PubKey()) + require.Equal(t, pubKey, testJSON(t, privKey, "ecaae500bfb3a28fe1f6108cb7c18743e0242d37c8e41ddd672d8c62563bec1b").Public()) require.Equal(t, pubKey, testJSON(t, pubKey, "f7874c043989887e8cfa6a3a3c1dd22432f95745481123e29201ebd21bc4d844")) require.Equal(t, sig, testJSON(t, sig, "dd48379c6c07eb1e36b188ea0cf35772a697c1a45ad4d47986ca819262743b71")) } diff --git a/sei-tendermint/crypto/ed25519/bench_test.go b/sei-tendermint/crypto/ed25519/bench_test.go index 3df746d155..c74d3cf46c 100644 --- a/sei-tendermint/crypto/ed25519/bench_test.go +++ b/sei-tendermint/crypto/ed25519/bench_test.go @@ -6,7 +6,7 @@ import ( ) func BenchmarkSigning(b *testing.B) { - priv := GenPrivKey() + priv := TestSecretKey([]byte("test")) message := []byte("Hello, world!") for b.Loop() { priv.Sign(message) @@ -14,8 +14,8 @@ func BenchmarkSigning(b *testing.B) { } func BenchmarkVerification(b *testing.B) { - priv := GenPrivKey() - pub := priv.PubKey() + priv := TestSecretKey([]byte("test")) + pub := priv.Public() message := []byte("Hello, world!") sig := priv.Sign(message) for b.Loop() { @@ -29,11 +29,11 @@ func BenchmarkVerifyBatch(b *testing.B) { b.Run(fmt.Sprintf("sig-count-%d", sigsCount), func(b *testing.B) { // Pre-generate all of the keys, and signatures, but do not // benchmark key-generation and signing. - pubs := make([]PubKey, 0, sigsCount) - sigs := make([]Sig, 0, sigsCount) - for range sigsCount { - priv := GenPrivKey() - pubs = append(pubs, priv.PubKey()) + pubs := make([]PublicKey, 0, sigsCount) + sigs := make([]Signature, 0, sigsCount) + for i := range sigsCount { + priv := TestSecretKey(fmt.Appendf(nil,"test-%v",i)) + pubs = append(pubs, priv.Public()) sigs = append(sigs, priv.Sign(msg)) } b.ResetTimer() diff --git a/sei-tendermint/crypto/ed25519/conv.go b/sei-tendermint/crypto/ed25519/conv.go new file mode 100644 index 0000000000..c0e09ae5e4 --- /dev/null +++ b/sei-tendermint/crypto/ed25519/conv.go @@ -0,0 +1,72 @@ +package ed25519 + +import ( + "crypto/ed25519" + "crypto/sha256" + "encoding/hex" + "errors" + "fmt" + "strings" + tmbytes "github.com/tendermint/tendermint/libs/bytes" +) + +// Bytes converts the public key or signature to bytes. +func (k PublicKey) Bytes() []byte { return k.key[:] } + +// Bytes converts the signature to bytes. +func (s Signature) Bytes() []byte { return s.sig[:] } + +// PublicKeyFromBytes constructs a public key from bytes. +func PublicKeyFromBytes(key []byte) (PublicKey, error) { + if got, want := len(key), ed25519.PublicKeySize; got != want { + return PublicKey{}, fmt.Errorf("ed25519: bad public key length: got %d, want %d", got, want) + } + return PublicKey{key: ([ed25519.PublicKeySize]byte)(key)}, nil +} + +// SignatureFromBytes constructs a signature from bytes. +func SignatureFromBytes(sig []byte) (Signature, error) { + if got, want := len(sig), ed25519.SignatureSize; got != want { + return Signature{}, fmt.Errorf("ed25519: bad signature length: got %d, want %d", got, want) + } + return Signature{sig: ([ed25519.SignatureSize]byte)(sig)}, nil +} + +// String returns a string representation. +func (k PublicKey) String() string { return fmt.Sprintf("ed25519:public:%x", k.key[:]) } + +// String returns a log-safe representation of the secret key. +func (k SecretKey) String() string { return fmt.Sprintf("", k.Public()) } + +// String returns a string representation. +func (s Signature) String() string { return fmt.Sprintf("ed25519:sig:%x", s.sig[:]) } + +// GoString returns a strings representation. +func (k PublicKey) GoString() string { return k.String() } + +// GoString returns a log-safe representation of the secret key. +func (k SecretKey) GoString() string { return k.String() } + +// GoString returns a strings representation. +func (s Signature) GoString() string { return s.String() } + +// PublicKeyFromString constructs a public key from a string representation. +func PublicKeyFromString(s string) (PublicKey, error) { + s2 := strings.TrimPrefix(s, "ed25519:public:") + if s == s2 { + return PublicKey{}, errors.New("bad prefix") + } + b, err := hex.DecodeString(s2) + if err != nil { + return PublicKey{}, fmt.Errorf("hex.DecodeString: %w", err) + } + return PublicKeyFromBytes(b) +} + +// Address is the SHA256-20 of the raw pubkey bytes. +func (k PublicKey) Address() tmbytes.HexBytes { + h := sha256.Sum256(k.Bytes()) + return tmbytes.HexBytes(h[:20]) +} + + diff --git a/sei-tendermint/crypto/ed25519/ed25519.go b/sei-tendermint/crypto/ed25519/ed25519.go index 9df0837c24..c86fe58490 100644 --- a/sei-tendermint/crypto/ed25519/ed25519.go +++ b/sei-tendermint/crypto/ed25519/ed25519.go @@ -3,20 +3,23 @@ package ed25519 import ( "crypto/rand" "crypto/sha256" - "errors" "fmt" - "io" + "bytes" + "runtime" "github.com/oasisprotocol/curve25519-voi/primitives/ed25519" "github.com/oasisprotocol/curve25519-voi/primitives/ed25519/extra/cache" - "github.com/tendermint/tendermint/internal/jsontypes" - tmbytes "github.com/tendermint/tendermint/libs/bytes" + "github.com/tendermint/tendermint/libs/utils" ) -const PrivKeyName = "tendermint/PrivKeyEd25519" -const PubKeyName = "tendermint/PubKeyEd25519" -const KeyType = "ed25519" +type ErrBadSig struct { + Idx int // Index of the first invalid signature. +} + +func (e ErrBadSig) Error() string { + return fmt.Sprintf("invalid %vth signature", e.Idx) +} // cacheSize is the number of public keys that will be cached in // an expanded format for repeated signature verification. @@ -32,107 +35,102 @@ const cacheSize = 4096 var verifyOptions = &ed25519.Options{Verify: ed25519.VerifyOptionsZIP_215} var cachingVerifier = cache.NewVerifier(cache.NewLRUCache(cacheSize)) -func init() { - jsontypes.MustRegister(PubKey{}) - jsontypes.MustRegister(PrivKey{}) +// SecretKey represents a secret key in the Ed25519 signature scheme. +type SecretKey struct { + // This is a pointer to avoid copying the secret all over the memory. + // This is a pointer to pointer, so that runtime.AddCleanup can actually work: + // Cleanup requires the referenced pointer to be unreachable, even from + // the cleanup function. + key **[ed25519.PrivateKeySize]byte + // Comparing the secrets is not allowed. + // If you have to, compare the public keys instead. + _ utils.NoCompare } -type Seed [ed25519.SeedSize]byte - -type PrivKey struct { - raw ed25519.PrivateKey // ed25519.PrivateKey is a slice, therefore the secret will not be copied around. +// SecretKeyFromSecretBytes constructs a secret key from a raw secret material. +// WARNING: this function zeroes the content of the input slice. +func SecretKeyFromSecretBytes(b []byte) (SecretKey, error) { + if got, want := len(b), ed25519.PrivateKeySize; got != want { + return SecretKey{}, fmt.Errorf("ed25519: bad private key length: got %d, want %d", got, want) + } + raw := utils.Alloc([ed25519.PrivateKeySize]byte(b)) + runtime.AddCleanup(&raw, func(int) { + // Zero the memory to avoid leaking the secret. + for i := range raw { + raw[i] = 0 + } + }, 0) + key := SecretKey{key: &raw} + // Zero the input slice to avoid leaking the secret. + for i := range b { + b[i] = 0 + } + return key, nil } -// TypeTag satisfies the jsontypes.Tagged interface. -func (k PrivKey) TypeTag() string { return PrivKeyName } - -// Bytes returns the privkey byte format. -func (k PrivKey) SecretBytes() []byte { return k.raw } - -// Sig represents signature. -type Sig [ed25519.SignatureSize]byte - -func SigFromBytes(raw []byte) (Sig, error) { - if len(raw) != len(Sig{}) { - return Sig{}, errors.New("invalid signature length") +// TestSecretKey generates a testonly secret key. +func TestSecretKey(seed []byte) SecretKey { + h := sha256.Sum256(seed) + key, err := SecretKeyFromSecretBytes(ed25519.NewKeyFromSeed(h[:])) + if err != nil { + panic(err) } - return Sig(raw), nil + return key } -// Sign signs a message with the key. -func (k PrivKey) Sign(msg []byte) Sig { return Sig(ed25519.Sign(k.raw, msg)) } - -// PubKey gets the corresponding public key from the private key. -func (k PrivKey) PubKey() PubKey { return PubKey(k.raw.Public().(ed25519.PublicKey)) } - -func (k PrivKey) Type() string { return KeyType } - -// GenPrivKey generates a new ed25519 private key from OS entropy. -func GenPrivKey() PrivKey { - var seed Seed - if _, err := io.ReadFull(rand.Reader, seed[:]); err != nil { - panic(err) +// GenerateSecretKey generates a new secret key using a cryptographically secure random number generator. +func GenerateSecretKey() (SecretKey, error) { + var seed [ed25519.PrivateKeySize]byte + if _, err := rand.Read(seed[:]); err != nil { + return SecretKey{}, err } - return PrivKeyFromSeed(seed) + return SecretKeyFromSecretBytes(ed25519.NewKeyFromSeed(seed[:])) } -// PrivKeyFromSeed constructs a private key from seed. -func PrivKeyFromSeed(seed Seed) PrivKey { - return PrivKey{ed25519.NewKeyFromSeed(seed[:])} +// Public returns the public key corresponding to the secret key. +func (k SecretKey) Public() PublicKey { + p := ed25519.PrivateKey((*k.key)[:]).Public().(ed25519.PublicKey) + return PublicKey{key: [ed25519.PublicKeySize]byte(p)} } -// GenPrivKeyFromSecret hashes the secret with SHA2, and uses -// that 32 byte output to create the private key. -// NOTE: secret should be the output of a KDF like bcrypt, -// if it's derived from user input. -func GenPrivKeyFromSecret(secret []byte) PrivKey { - return PrivKeyFromSeed(Seed(sha256.Sum256(secret))) +// PublicKey represents a public key in the Ed25519 signature scheme. +type PublicKey struct { + utils.ReadOnly + key [ed25519.PublicKeySize]byte } -// PubKey implements the Ed25519 signature scheme. -type PubKey [ed25519.PublicKeySize]byte +// Signature represents a signature in the Ed25519 signature scheme. +type Signature struct { + utils.ReadOnly + sig [ed25519.SignatureSize]byte +} -func PubKeyFromBytes(raw []byte) (PubKey, error) { - if len(raw) != len(PubKey{}) { - return PubKey{}, errors.New("invalid pubkey length") +// Sign signs a message using the secret key. +func (k SecretKey) Sign(message []byte) Signature { + return Signature{ + sig: [ed25519.SignatureSize]byte(ed25519.Sign((*k.key)[:], message)), } - return PubKey(raw), nil } -// TypeTag satisfies the jsontypes.Tagged interface. -func (PubKey) TypeTag() string { return PubKeyName } - -// Address is the SHA256-20 of the raw pubkey bytes. -func (k PubKey) Address() tmbytes.HexBytes { - h := sha256.Sum256(k[:]) - return tmbytes.HexBytes(h[:20]) +// Compare defines a total order on public keys. +func (k PublicKey) Compare(other PublicKey) int { + return bytes.Compare(k.key[:], other.key[:]) } -func (k PubKey) Verify(msg []byte, sig Sig) error { - if !cachingVerifier.VerifyWithOptions(k[:], msg, sig[:], verifyOptions) { - return errors.New("invalid signature") +// Verify verifies a signature using the public key. +func (k PublicKey) Verify(msg []byte, sig Signature) error { + if !ed25519.VerifyWithOptions(k.key[:], msg, sig.sig[:], verifyOptions) { + return ErrBadSig{} } return nil } - -func (k PubKey) String() string { return fmt.Sprintf("PubKeyEd25519{%X}", k[:]) } -func (k PubKey) Type() string { return KeyType } - // BatchVerifier implements batch verification for ed25519. type BatchVerifier struct{ inner *ed25519.BatchVerifier } func NewBatchVerifier() *BatchVerifier { return &BatchVerifier{ed25519.NewBatchVerifier()} } -func (b *BatchVerifier) Add(key PubKey, msg []byte, sig Sig) { - cachingVerifier.AddWithOptions(b.inner, key[:], msg, sig[:], verifyOptions) -} - -type ErrBadSig struct { - Idx int // Index of the first invalid signature. -} - -func (e ErrBadSig) Error() string { - return fmt.Sprintf("invalid %vth signature", e.Idx) +func (b *BatchVerifier) Add(key PublicKey, msg []byte, sig Signature) { + cachingVerifier.AddWithOptions(b.inner, key.key[:], msg, sig.sig[:], verifyOptions) } // Verify verifies the batched signatures using OS entropy. diff --git a/sei-tendermint/crypto/ed25519/ed25519_test.go b/sei-tendermint/crypto/ed25519/ed25519_test.go index f5858b2e04..01f206f2e9 100644 --- a/sei-tendermint/crypto/ed25519/ed25519_test.go +++ b/sei-tendermint/crypto/ed25519/ed25519_test.go @@ -1,21 +1,18 @@ -package ed25519_test +package ed25519 import ( "testing" + "fmt" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/libs/utils/require" ) func TestSignAndValidateEd25519(t *testing.T) { - - privKey := ed25519.GenPrivKey() - pubKey := privKey.PubKey() - - msg := crypto.CRandBytes(128) + privKey := TestSecretKey([]byte("test")) + pubKey := privKey.Public() + msg := []byte("message") sig := privKey.Sign(msg) // Test the signature @@ -23,17 +20,17 @@ func TestSignAndValidateEd25519(t *testing.T) { // Mutate the signature, just one bit. // TODO: Replace this with a much better fuzzer, tendermint/ed25519/issues/10 - sig[7] ^= byte(0x01) + sig.sig[7] ^= byte(0x01) assert.Error(t, pubKey.Verify(msg, sig)) } func TestBatchSafe(t *testing.T) { - v := ed25519.NewBatchVerifier() + v := NewBatchVerifier() for i := 0; i <= 38; i++ { - priv := ed25519.GenPrivKey() - pub := priv.PubKey() + priv := TestSecretKey(fmt.Appendf(nil,"test-%v",i)) + pub := priv.Public() var msg []byte if i%2 == 0 { diff --git a/sei-tendermint/crypto/ed25519/json.go b/sei-tendermint/crypto/ed25519/json.go index 41dc77c333..53f5ec82c7 100644 --- a/sei-tendermint/crypto/ed25519/json.go +++ b/sei-tendermint/crypto/ed25519/json.go @@ -2,26 +2,55 @@ package ed25519 import ( "encoding/json" + "github.com/tendermint/tendermint/internal/jsontypes" ) -func (k PrivKey) MarshalJSON() ([]byte, error) { - return json.Marshal(k.raw) +const SecretKeyName = "tendermint/PrivKeyEd25519" +const PublicKeyName = "tendermint/PubKeyEd25519" +const KeyType = "ed25519" + +func init() { + jsontypes.MustRegister(PublicKey{}) + jsontypes.MustRegister(SecretKey{}) +} + + +func (k SecretKey) TypeTag() string { return SecretKeyName } +func (k SecretKey) Type() string { return KeyType } + +func (k PublicKey) TypeTag() string { return PublicKeyName } +func (k PublicKey) Type() string { return KeyType } + +// WARNING: this is very BAD that one can leak a secret by embedding +// a private key in some struct and then calling json.Marshal on it. +// TODO(gprusak): get rid of it. +func (k SecretKey) MarshalJSON() ([]byte, error) { + return json.Marshal((*k.key)[:]) } -func (k *PrivKey) UnmarshalJSON(j []byte) error { - return json.Unmarshal(j, &k.raw) +func (k *SecretKey) UnmarshalJSON(j []byte) error { + var raw []byte + if err := json.Unmarshal(j, &raw); err != nil { + return err + } + x, err := SecretKeyFromSecretBytes(raw) + if err != nil { + return err + } + *k = x + return nil } -func (k PubKey) MarshalJSON() ([]byte, error) { - return json.Marshal(k[:]) +func (k PublicKey) MarshalJSON() ([]byte, error) { + return json.Marshal(k.Bytes()) } -func (k *PubKey) UnmarshalJSON(j []byte) error { +func (k *PublicKey) UnmarshalJSON(j []byte) error { var raw []byte if err := json.Unmarshal(j, &raw); err != nil { return err } - x, err := PubKeyFromBytes(raw) + x, err := PublicKeyFromBytes(raw) if err != nil { return err } @@ -29,16 +58,16 @@ func (k *PubKey) UnmarshalJSON(j []byte) error { return nil } -func (s Sig) MarshalJSON() ([]byte, error) { - return json.Marshal(s[:]) +func (s Signature) MarshalJSON() ([]byte, error) { + return json.Marshal(s.Bytes()) } -func (s *Sig) UnmarshalJSON(j []byte) error { +func (s *Signature) UnmarshalJSON(j []byte) error { var raw []byte if err := json.Unmarshal(j, &raw); err != nil { return err } - x, err := SigFromBytes(raw) + x, err := SignatureFromBytes(raw) if err != nil { return err } diff --git a/sei-tendermint/crypto/encoding/codec.go b/sei-tendermint/crypto/encoding/codec.go index b38d568a21..210979e4d6 100644 --- a/sei-tendermint/crypto/encoding/codec.go +++ b/sei-tendermint/crypto/encoding/codec.go @@ -16,14 +16,14 @@ func init() { // PubKeyToProto takes crypto.PubKey and transforms it to a protobuf Pubkey func PubKeyToProto(k crypto.PubKey) cryptoproto.PublicKey { - return cryptoproto.PublicKey{Sum: &cryptoproto.PublicKey_Ed25519{Ed25519: k[:]}} + return cryptoproto.PublicKey{Sum: &cryptoproto.PublicKey_Ed25519{Ed25519: k.Bytes()}} } // PubKeyFromProto takes a protobuf Pubkey and transforms it to a crypto.Pubkey func PubKeyFromProto(k cryptoproto.PublicKey) (crypto.PubKey, error) { switch k := k.Sum.(type) { case *cryptoproto.PublicKey_Ed25519: - return ed25519.PubKeyFromBytes(k.Ed25519) + return ed25519.PublicKeyFromBytes(k.Ed25519) default: return crypto.PubKey{}, fmt.Errorf("fromproto: key type %v is not supported", k) } From ba9aeddd75eae4251c0b093f4d78204a018e5a37 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Wed, 17 Dec 2025 17:57:14 +0100 Subject: [PATCH 31/53] test --- sei-tendermint/crypto/ed25519/ed25519_test.go | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/sei-tendermint/crypto/ed25519/ed25519_test.go b/sei-tendermint/crypto/ed25519/ed25519_test.go index 01f206f2e9..79a5921cc3 100644 --- a/sei-tendermint/crypto/ed25519/ed25519_test.go +++ b/sei-tendermint/crypto/ed25519/ed25519_test.go @@ -3,26 +3,23 @@ package ed25519 import ( "testing" "fmt" - - "github.com/stretchr/testify/assert" - "github.com/tendermint/tendermint/libs/utils/require" ) -func TestSignAndValidateEd25519(t *testing.T) { - privKey := TestSecretKey([]byte("test")) - pubKey := privKey.Public() - msg := []byte("message") - sig := privKey.Sign(msg) - - // Test the signature - assert.NoError(t, pubKey.Verify(msg, sig)) - - // Mutate the signature, just one bit. - // TODO: Replace this with a much better fuzzer, tendermint/ed25519/issues/10 - sig.sig[7] ^= byte(0x01) - - assert.Error(t, pubKey.Verify(msg, sig)) +func TestSign(t *testing.T) { + var keys []SecretKey + for i := range byte(3) { + keys = append(keys, TestSecretKey([]byte{i})) + } + t.Logf("keys = %+v", keys) + msg := []byte("test message") + for i := range keys { + for j := range keys { + if wantErr, err := i != j, keys[j].Public().Verify(msg, keys[i].Sign(msg)); wantErr != (err != nil) { + t.Errorf("keys[%d].Verify(keys[%d].Sign()) = %v, wantErr = %v", j, i, err, wantErr) + } + } + } } func TestBatchSafe(t *testing.T) { From afcacab01f3cc1bddd2a58f87d120d6e2eb39019 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Wed, 17 Dec 2025 18:18:03 +0100 Subject: [PATCH 32/53] codex --- .../abci/example/kvstore/helpers.go | 8 ++++- .../abci/example/kvstore/kvstore.go | 17 +++++++---- sei-tendermint/abci/tests/server/client.go | 7 ++++- .../internal/p2p/conn/secret_connection.go | 30 +++++++++---------- sei-tendermint/internal/p2p/router.go | 2 +- sei-tendermint/internal/p2p/testonly.go | 5 ++-- .../internal/roles/validator/msg.go | 2 +- sei-tendermint/node/setup.go | 4 +-- sei-tendermint/privval/file.go | 22 +++++++++----- sei-tendermint/privval/secret_connection.go | 26 ++++++++-------- sei-tendermint/privval/socket_listeners.go | 4 +-- sei-tendermint/privval/utils.go | 6 +++- sei-tendermint/test/e2e/app/app.go | 8 +++-- sei-tendermint/test/e2e/node/main.go | 6 +++- sei-tendermint/test/e2e/pkg/testnet.go | 9 +++--- sei-tendermint/test/e2e/runner/evidence.go | 4 +-- sei-tendermint/test/e2e/runner/setup.go | 15 ++++++---- sei-tendermint/types/block.go | 15 +++++----- sei-tendermint/types/node_key.go | 9 ++++-- sei-tendermint/types/params.go | 2 +- sei-tendermint/types/priv_validator.go | 18 +++++++---- sei-tendermint/types/proposal.go | 4 +-- sei-tendermint/types/vote.go | 4 +-- 23 files changed, 139 insertions(+), 88 deletions(-) diff --git a/sei-tendermint/abci/example/kvstore/helpers.go b/sei-tendermint/abci/example/kvstore/helpers.go index 4ad499f87a..a287a2f8ed 100644 --- a/sei-tendermint/abci/example/kvstore/helpers.go +++ b/sei-tendermint/abci/example/kvstore/helpers.go @@ -6,6 +6,7 @@ import ( "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" tmrand "github.com/tendermint/tendermint/libs/rand" ) @@ -18,7 +19,12 @@ func RandVals(cnt int) []types.ValidatorUpdate { for i := range res { // Random value between [0, 2^16 - 1] power := mrand.Uint32() & (1<<16 - 1) // nolint:gosec // G404: Use of weak random number generator - res[i] = types.UpdateValidator(crypto.PubKey(tmrand.Bytes(len(crypto.PubKey{}))), int64(power), "") + keyBytes := tmrand.Bytes(len(crypto.PubKey{}.Bytes())) + pubKey, err := ed25519.PublicKeyFromBytes(keyBytes) + if err != nil { + panic(err) + } + res[i] = types.UpdateValidator(pubKey, int64(power), "") } return res } diff --git a/sei-tendermint/abci/example/kvstore/kvstore.go b/sei-tendermint/abci/example/kvstore/kvstore.go index 339d875c2b..4c219f8db1 100644 --- a/sei-tendermint/abci/example/kvstore/kvstore.go +++ b/sei-tendermint/abci/example/kvstore/kvstore.go @@ -15,7 +15,7 @@ import ( "github.com/tendermint/tendermint/abci/example/code" "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/libs/log" cryptoproto "github.com/tendermint/tendermint/proto/tendermint/crypto" @@ -333,7 +333,7 @@ func MakeValSetChangeTx(pubkey cryptoproto.PublicKey, power int64) []byte { if err != nil { panic(err) } - pubStr := base64.StdEncoding.EncodeToString(pk[:]) + pubStr := base64.StdEncoding.EncodeToString(pk.Bytes()) return []byte(fmt.Sprintf("val:%s!%d", pubStr, power)) } @@ -372,7 +372,14 @@ func (app *Application) execValidatorTx(tx []byte) *types.ExecTxResult { } // update - return app.updateValidator(types.UpdateValidator(crypto.PubKey(pubkey), power, "")) + key, err := ed25519.PublicKeyFromBytes(pubkey) + if err != nil { + return &types.ExecTxResult{ + Code: code.CodeTypeEncodingError, + Log: fmt.Sprintf("can't decode ed25519 key: %v", err), + } + } + return app.updateValidator(types.UpdateValidator(key, power, "")) } // add, update, or remove a validator @@ -381,7 +388,7 @@ func (app *Application) updateValidator(v types.ValidatorUpdate) *types.ExecTxRe if err != nil { panic(fmt.Errorf("can't decode public key: %w", err)) } - key := []byte("val:" + string(pubkey[:])) + key := []byte("val:" + string(pubkey.Bytes())) if v.Power == 0 { // remove validator @@ -390,7 +397,7 @@ func (app *Application) updateValidator(v types.ValidatorUpdate) *types.ExecTxRe panic(err) } if !hasKey { - pubStr := base64.StdEncoding.EncodeToString(pubkey[:]) + pubStr := base64.StdEncoding.EncodeToString(pubkey.Bytes()) return &types.ExecTxResult{ Code: code.CodeTypeUnauthorized, Log: fmt.Sprintf("Cannot remove non-existent validator %s", pubStr)} diff --git a/sei-tendermint/abci/tests/server/client.go b/sei-tendermint/abci/tests/server/client.go index 6d2778be85..2b7f4bcb73 100644 --- a/sei-tendermint/abci/tests/server/client.go +++ b/sei-tendermint/abci/tests/server/client.go @@ -10,13 +10,18 @@ import ( abciclient "github.com/tendermint/tendermint/abci/client" "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" tmrand "github.com/tendermint/tendermint/libs/rand" ) func InitChain(ctx context.Context, client abciclient.Client) error { vals := make([]types.ValidatorUpdate, 10) for i := range vals { - pubkey := crypto.PubKey(tmrand.Bytes(len(crypto.PubKey{}))) + keyBytes := tmrand.Bytes(len(crypto.PubKey{}.Bytes())) + pubkey, err := ed25519.PublicKeyFromBytes(keyBytes) + if err != nil { + return err + } // nolint:gosec // G404: Use of weak random number generator power := mrand.Int() vals[i] = types.UpdateValidator(pubkey, int64(power), "") diff --git a/sei-tendermint/internal/p2p/conn/secret_connection.go b/sei-tendermint/internal/p2p/conn/secret_connection.go index 28d2a36500..5988976ed9 100644 --- a/sei-tendermint/internal/p2p/conn/secret_connection.go +++ b/sei-tendermint/internal/p2p/conn/secret_connection.go @@ -65,7 +65,7 @@ type SecretConnection struct { recvAead cipher.AEAD sendAead cipher.AEAD - remPubKey ed25519.PubKey + remPubKey ed25519.PublicKey conn io.ReadWriteCloser // net.Conn must be thread safe: @@ -88,10 +88,8 @@ type SecretConnection struct { // Returns nil if there is an error in handshake. // Caller should call conn.Close() // See docs/sts-final.pdf for more information. -func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey ed25519.PrivKey) (*SecretConnection, error) { - var ( - locPubKey = locPrivKey.PubKey() - ) +func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey ed25519.SecretKey) (*SecretConnection, error) { + locPubKey := locPrivKey.Public() // Generate ephemeral keys for perfect forward secrecy. locEphPub, locEphPriv := genEphKeys() @@ -172,7 +170,7 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey ed25519.PrivKey) ( } // RemotePubKey returns authenticated remote pubkey -func (sc *SecretConnection) RemotePubKey() ed25519.PubKey { +func (sc *SecretConnection) RemotePubKey() ed25519.PublicKey { return sc.remPubKey } @@ -380,21 +378,21 @@ func sort32(foo, bar *[32]byte) (lo, hi *[32]byte) { return } -func signChallenge(challenge *[32]byte, locPrivKey ed25519.PrivKey) ed25519.Sig { +func signChallenge(challenge *[32]byte, locPrivKey ed25519.SecretKey) ed25519.Signature { return locPrivKey.Sign(challenge[:]) } type authSigMessage struct { - Key ed25519.PubKey - Sig ed25519.Sig + Key ed25519.PublicKey + Sig ed25519.Signature } -func shareAuthSignature(sc io.ReadWriter, pubKey ed25519.PubKey, sig ed25519.Sig) (authSigMessage, error) { +func shareAuthSignature(sc io.ReadWriter, pubKey ed25519.PublicKey, sig ed25519.Signature) (authSigMessage, error) { // Send our info and receive theirs in tandem. var trs, _ = async.Parallel( func(_ int) (val any, abort bool, err error) { - pk := tmproto.PublicKey{Sum: &tmproto.PublicKey_Ed25519{Ed25519: pubKey[:]}} - if _, err := protoio.NewDelimitedWriter(sc).WriteMsg(&tmp2p.AuthSigMessage{PubKey: pk, Sig: sig[:]}); err != nil { + pk := tmproto.PublicKey{Sum: &tmproto.PublicKey_Ed25519{Ed25519: pubKey.Bytes()}} + if _, err := protoio.NewDelimitedWriter(sc).WriteMsg(&tmp2p.AuthSigMessage{PubKey: pk, Sig: sig.Bytes()}); err != nil { return nil, true, err } return nil, false, nil @@ -404,13 +402,13 @@ func shareAuthSignature(sc io.ReadWriter, pubKey ed25519.PubKey, sig ed25519.Sig if _, err := protoio.NewDelimitedReader(sc, 1024*1024).ReadMsg(&pba); err != nil { return nil, true, err } - key, err := ed25519.PubKeyFromBytes(pba.PubKey.GetEd25519()) + key, err := ed25519.PublicKeyFromBytes(pba.PubKey.GetEd25519()) if err != nil { - return nil, true, fmt.Errorf("ed25519.PubKeyFromBytes(): %w", err) + return nil, true, fmt.Errorf("ed25519.PublicKeyFromBytes(): %w", err) } - sig, err := ed25519.SigFromBytes(pba.Sig) + sig, err := ed25519.SignatureFromBytes(pba.Sig) if err != nil { - return nil, true, fmt.Errorf("ed25519.SigFromBytes(): %w", err) + return nil, true, fmt.Errorf("ed25519.SignatureFromBytes(): %w", err) } return authSigMessage{Key: key, Sig: sig}, false, nil }, diff --git a/sei-tendermint/internal/p2p/router.go b/sei-tendermint/internal/p2p/router.go index dae58e7e37..481302f845 100644 --- a/sei-tendermint/internal/p2p/router.go +++ b/sei-tendermint/internal/p2p/router.go @@ -72,7 +72,7 @@ func NewRouter( if err := options.Validate(); err != nil { return nil, err } - selfID := types.NodeIDFromPubKey(privKey.PubKey()) + selfID := types.NodeIDFromPubKey(privKey.Public()) peerManager := newPeerManager[*Connection](selfID, options) peerDB, err := newPeerDB(db, options.maxPeers()) if err != nil { diff --git a/sei-tendermint/internal/p2p/testonly.go b/sei-tendermint/internal/p2p/testonly.go index c726e66b14..b73273ef27 100644 --- a/sei-tendermint/internal/p2p/testonly.go +++ b/sei-tendermint/internal/p2p/testonly.go @@ -278,8 +278,9 @@ func (n *TestNode) Disconnect(ctx context.Context, target types.NodeID) { // running peer manager, but does not add it to the existing // network. Callers are responsible for updating peering relationships. func (n *TestNetwork) MakeNode(t *testing.T, opts TestNodeOptions) *TestNode { - privKey := ed25519.GenPrivKey() - nodeID := types.NodeIDFromPubKey(privKey.PubKey()) + privKey, err := ed25519.GenerateSecretKey() + require.NoError(t, err) + nodeID := types.NodeIDFromPubKey(privKey.Public()) logger := n.logger.With("node", nodeID[:5]) routerOpts := &RouterOptions{ diff --git a/sei-tendermint/internal/roles/validator/msg.go b/sei-tendermint/internal/roles/validator/msg.go index cb3e698324..26e609401e 100644 --- a/sei-tendermint/internal/roles/validator/msg.go +++ b/sei-tendermint/internal/roles/validator/msg.go @@ -16,7 +16,7 @@ func (s *SessionID) Raw() [10]byte { return s.raw } func (s *SessionID) isMsg() {} -type Sig struct{ inner ed25519.Sig } +type Sig struct{ inner ed25519.Signature } type Signed[M Msg] struct { utils.ReadOnly diff --git a/sei-tendermint/node/setup.go b/sei-tendermint/node/setup.go index e1ac7d8356..001596bb40 100644 --- a/sei-tendermint/node/setup.go +++ b/sei-tendermint/node/setup.go @@ -121,12 +121,12 @@ func logNodeStartupInfo(state sm.State, pubKey utils.Option[crypto.PubKey], logg if state.Validators.HasAddress(addr) { logger.Info("This node is a validator", "addr", addr, - "pubKey", k[:], + "pubKey", k.Bytes(), ) } else { logger.Info("This node is a validator (NOT in the active validator set)", "addr", addr, - "pubKey", k[:], + "pubKey", k.Bytes(), ) } } diff --git a/sei-tendermint/privval/file.go b/sei-tendermint/privval/file.go index b1691db3b6..fb7cd67acd 100644 --- a/sei-tendermint/privval/file.go +++ b/sei-tendermint/privval/file.go @@ -197,8 +197,8 @@ var _ types.PrivValidator = (*FilePV)(nil) func NewFilePV(privKey crypto.PrivKey, keyFilePath, stateFilePath string) *FilePV { return &FilePV{ Key: FilePVKey{ - Address: privKey.PubKey().Address(), - PubKey: privKey.PubKey(), + Address: privKey.Public().Address(), + PubKey: privKey.Public(), PrivKey: privKey, filePath: keyFilePath, }, @@ -215,7 +215,11 @@ func GenFilePV(keyFilePath, stateFilePath, keyType string) (*FilePV, error) { if keyType != "" && keyType != types.ABCIPubKeyTypeEd25519 { return nil, fmt.Errorf("key type: %s is not supported", keyType) } - return NewFilePV(ed25519.GenPrivKey(), keyFilePath, stateFilePath), nil + privKey, err := ed25519.GenerateSecretKey() + if err != nil { + return nil, err + } + return NewFilePV(privKey, keyFilePath, stateFilePath), nil } // LoadFilePV loads a FilePV from the filePaths. The FilePV handles double @@ -244,7 +248,7 @@ func loadFilePV(keyFilePath, stateFilePath string, loadState bool) (*FilePV, err } // overwrite pubkey and address for convenience - pvKey.PubKey = pvKey.PrivKey.PubKey() + pvKey.PubKey = pvKey.PrivKey.Public() pvKey.Address = pvKey.PubKey.Address() pvKey.filePath = keyFilePath @@ -397,10 +401,11 @@ func (pv *FilePV) signVote(chainID string, vote *tmproto.Vote) error { // It passed the checks. Sign the vote sig := pv.Key.PrivKey.Sign(signBytes) - if err := pv.saveSigned(height, round, step, signBytes, sig[:]); err != nil { + sigBytes := sig.Bytes() + if err := pv.saveSigned(height, round, step, signBytes, sigBytes); err != nil { return err } - vote.Signature = sig[:] + vote.Signature = sigBytes return nil } @@ -431,10 +436,11 @@ func (pv *FilePV) signProposal(chainID string, proposal *tmproto.Proposal) error // It passed the checks. Sign the proposal sig := pv.Key.PrivKey.Sign(signBytes) - if err := pv.saveSigned(height, round, step, signBytes, sig[:]); err != nil { + sigBytes := sig.Bytes() + if err := pv.saveSigned(height, round, step, signBytes, sigBytes); err != nil { return err } - proposal.Signature = sig[:] + proposal.Signature = sigBytes return nil } diff --git a/sei-tendermint/privval/secret_connection.go b/sei-tendermint/privval/secret_connection.go index 9e73a7004e..5264fddc6d 100644 --- a/sei-tendermint/privval/secret_connection.go +++ b/sei-tendermint/privval/secret_connection.go @@ -69,7 +69,7 @@ type SecretConnection struct { recvAead cipher.AEAD sendAead cipher.AEAD - remPubKey ed25519.PubKey + remPubKey ed25519.PublicKey conn io.ReadWriteCloser // net.Conn must be thread safe: @@ -92,10 +92,8 @@ type SecretConnection struct { // Returns nil if there is an error in handshake. // Caller should call conn.Close() // See docs/sts-final.pdf for more information. -func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey ed25519.PrivKey) (*SecretConnection, error) { - var ( - locPubKey = locPrivKey.PubKey() - ) +func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey ed25519.SecretKey) (*SecretConnection, error) { + locPubKey := locPrivKey.Public() // Generate ephemeral keys for perfect forward secrecy. locEphPub, locEphPriv, err := genEphKeys() @@ -181,7 +179,7 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey ed25519.PrivKey) ( } // RemotePubKey returns authenticated remote pubkey -func (sc *SecretConnection) RemotePubKey() ed25519.PubKey { +func (sc *SecretConnection) RemotePubKey() ed25519.PublicKey { return sc.remPubKey } @@ -393,22 +391,22 @@ func sort32(foo, bar *[32]byte) (lo, hi *[32]byte) { return } -func signChallenge(challenge *[32]byte, locPrivKey ed25519.PrivKey) ed25519.Sig { +func signChallenge(challenge *[32]byte, locPrivKey ed25519.SecretKey) ed25519.Signature { return locPrivKey.Sign(challenge[:]) } type authSigMessage struct { - Key ed25519.PubKey - Sig ed25519.Sig + Key ed25519.PublicKey + Sig ed25519.Signature } -func shareAuthSignature(sc io.ReadWriter, pubKey ed25519.PubKey, signature ed25519.Sig) (recvMsg authSigMessage, err error) { +func shareAuthSignature(sc io.ReadWriter, pubKey ed25519.PublicKey, signature ed25519.Signature) (recvMsg authSigMessage, err error) { // Send our info and receive theirs in tandem. var trs, _ = async.Parallel( func(_ int) (val interface{}, abort bool, err error) { - pk := tmproto.PublicKey{Sum: &tmproto.PublicKey_Ed25519{Ed25519: pubKey[:]}} - _, err = protoio.NewDelimitedWriter(sc).WriteMsg(&tmprivval.AuthSigMessage{PubKey: pk, Sig: signature[:]}) + pk := tmproto.PublicKey{Sum: &tmproto.PublicKey_Ed25519{Ed25519: pubKey.Bytes()}} + _, err = protoio.NewDelimitedWriter(sc).WriteMsg(&tmprivval.AuthSigMessage{PubKey: pk, Sig: signature.Bytes()}) if err != nil { return nil, true, err // abort } @@ -421,11 +419,11 @@ func shareAuthSignature(sc io.ReadWriter, pubKey ed25519.PubKey, signature ed255 return nil, true, err // abort } - key, err := ed25519.PubKeyFromBytes(pba.PubKey.GetEd25519()) + key, err := ed25519.PublicKeyFromBytes(pba.PubKey.GetEd25519()) if err != nil { return nil, true, fmt.Errorf("PubKey: %w", err) } - sig, err := ed25519.SigFromBytes(pba.Sig) + sig, err := ed25519.SignatureFromBytes(pba.Sig) if err != nil { return nil, true, fmt.Errorf("Sig: %w", err) } diff --git a/sei-tendermint/privval/socket_listeners.go b/sei-tendermint/privval/socket_listeners.go index 953c56bfe3..0c08310f6f 100644 --- a/sei-tendermint/privval/socket_listeners.go +++ b/sei-tendermint/privval/socket_listeners.go @@ -43,7 +43,7 @@ var _ net.Listener = (*TCPListener)(nil) type TCPListener struct { *net.TCPListener - secretConnKey ed25519.PrivKey + secretConnKey ed25519.SecretKey timeoutAccept time.Duration timeoutReadWrite time.Duration @@ -51,7 +51,7 @@ type TCPListener struct { // NewTCPListener returns a listener that accepts authenticated encrypted connections // using the given secretConnKey and the default timeout values. -func NewTCPListener(ln net.Listener, secretConnKey ed25519.PrivKey) *TCPListener { +func NewTCPListener(ln net.Listener, secretConnKey ed25519.SecretKey) *TCPListener { return &TCPListener{ TCPListener: ln.(*net.TCPListener), secretConnKey: secretConnKey, diff --git a/sei-tendermint/privval/utils.go b/sei-tendermint/privval/utils.go index a2cbbf5014..6de012ae5e 100644 --- a/sei-tendermint/privval/utils.go +++ b/sei-tendermint/privval/utils.go @@ -43,7 +43,11 @@ func NewSignerListener(listenAddr string, logger log.Logger) (*SignerListenerEnd listener = NewUnixListener(ln) case "tcp": // TODO: persist this key so external signer can actually authenticate us - listener = NewTCPListener(ln, ed25519.GenPrivKey()) + privKey, err := ed25519.GenerateSecretKey() + if err != nil { + return nil, err + } + listener = NewTCPListener(ln, privKey) default: panic("invalid protocol: " + protocol) // semantically unreachable } diff --git a/sei-tendermint/test/e2e/app/app.go b/sei-tendermint/test/e2e/app/app.go index 4bda48a04c..b65de0a1b9 100644 --- a/sei-tendermint/test/e2e/app/app.go +++ b/sei-tendermint/test/e2e/app/app.go @@ -14,7 +14,7 @@ import ( "github.com/tendermint/tendermint/abci/example/code" abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/version" @@ -389,7 +389,11 @@ func (app *Application) validatorUpdates(height uint64) (abci.ValidatorUpdates, if err != nil { return nil, fmt.Errorf("invalid base64 pubkey value %q: %w", keyString, err) } - valUpdates = append(valUpdates, abci.UpdateValidator(crypto.PubKey(keyBytes), int64(power), app.cfg.KeyType)) + pubKey, err := ed25519.PublicKeyFromBytes(keyBytes) + if err != nil { + return nil, fmt.Errorf("invalid ed25519 pubkey value %q: %w", keyString, err) + } + valUpdates = append(valUpdates, abci.UpdateValidator(pubKey, int64(power), app.cfg.KeyType)) } // the validator updates could be returned in arbitrary order, diff --git a/sei-tendermint/test/e2e/node/main.go b/sei-tendermint/test/e2e/node/main.go index 360671231d..391e2150bb 100644 --- a/sei-tendermint/test/e2e/node/main.go +++ b/sei-tendermint/test/e2e/node/main.go @@ -227,7 +227,11 @@ func startSigner(ctx context.Context, logger log.Logger, cfg *Config) error { var dialFn privval.SocketDialer switch protocol { case "tcp": - dialFn = privval.DialTCPFn(address, 3*time.Second, ed25519.GenPrivKey()) + privKey, err := ed25519.GenerateSecretKey() + if err != nil { + return err + } + dialFn = privval.DialTCPFn(address, 3*time.Second, privKey) case "unix": dialFn = privval.DialUnixFn(address) case "grpc": diff --git a/sei-tendermint/test/e2e/pkg/testnet.go b/sei-tendermint/test/e2e/pkg/testnet.go index bb1b1cc8b4..25ba1da4a2 100644 --- a/sei-tendermint/test/e2e/pkg/testnet.go +++ b/sei-tendermint/test/e2e/pkg/testnet.go @@ -444,7 +444,8 @@ func (n Node) AddressP2P(withID bool) string { } addr := fmt.Sprintf("%v:26656", ip) if withID { - addr = fmt.Sprintf("%x@%v", n.NodeKey.PubKey().Address().Bytes(), addr) + pubKey := n.NodeKey.Public() + addr = fmt.Sprintf("%x@%v", pubKey.Address().Bytes(), addr) } return addr } @@ -481,15 +482,15 @@ func newKeyGenerator(seed int64) *keyGenerator { } func (g *keyGenerator) Generate(keyType string) crypto.PrivKey { - var seed ed25519.Seed - _, err := io.ReadFull(g.random, seed[:]) + seed := make([]byte, 32) + _, err := io.ReadFull(g.random, seed) if err != nil { panic(err) // this shouldn't happen } if keyType != "" && keyType != "ed25519" { panic("KeyType not supported") } - return ed25519.PrivKeyFromSeed(seed) + return ed25519.TestSecretKey(seed) } // portGenerator generates local Docker proxy ports for each node. diff --git a/sei-tendermint/test/e2e/runner/evidence.go b/sei-tendermint/test/e2e/runner/evidence.go index 3316a07c93..0db664c4c2 100644 --- a/sei-tendermint/test/e2e/runner/evidence.go +++ b/sei-tendermint/test/e2e/runner/evidence.go @@ -228,7 +228,7 @@ func generateDuplicateVoteEvidence( func getRandomValidatorIndex(privVals []types.MockPV, vals *types.ValidatorSet) (types.MockPV, int32, error) { for _, idx := range rand.Perm(len(privVals)) { pv := privVals[idx] - valIdx, _ := vals.GetByAddress(pv.PrivKey.PubKey().Address()) + valIdx, _ := vals.GetByAddress(pv.PrivKey.Public().Address()) if valIdx >= 0 { return pv, valIdx, nil } @@ -307,7 +307,7 @@ func mutateValidatorSet(ctx context.Context, privVals []types.MockPV, vals *type for idx, val := range newVals.Validators { found := false for _, p := range append(privVals, newPrivVal.(types.MockPV)) { - if bytes.Equal(p.PrivKey.PubKey().Address(), val.Address) { + if bytes.Equal(p.PrivKey.Public().Address(), val.Address) { pv[idx] = p found = true break diff --git a/sei-tendermint/test/e2e/runner/setup.go b/sei-tendermint/test/e2e/runner/setup.go index 271b876e4a..ae2a179ea2 100644 --- a/sei-tendermint/test/e2e/runner/setup.go +++ b/sei-tendermint/test/e2e/runner/setup.go @@ -122,7 +122,11 @@ func Setup(logger log.Logger, testnet *e2e.Testnet) error { // Set up a dummy validator. Tendermint requires a file PV even when not used, so we // give it a dummy such that it will fail if it actually tries to use it. - err = (privval.NewFilePV(ed25519.GenPrivKey(), + dummyKey, err := ed25519.GenerateSecretKey() + if err != nil { + return err + } + err = (privval.NewFilePV(dummyKey, filepath.Join(nodeDir, PrivvalDummyKeyFile), filepath.Join(nodeDir, PrivvalDummyStateFile), )).Save() @@ -209,10 +213,11 @@ func MakeGenesis(testnet *e2e.Testnet) (types.GenesisDoc, error) { genesis.ConsensusParams.Evidence.MaxAgeNumBlocks = e2e.EvidenceAgeHeight genesis.ConsensusParams.Evidence.MaxAgeDuration = e2e.EvidenceAgeTime for validator, power := range testnet.Validators { + pubKey := validator.PrivvalKey.Public() genesis.Validators = append(genesis.Validators, types.GenesisValidator{ Name: validator.Name, - Address: validator.PrivvalKey.PubKey().Address(), - PubKey: validator.PrivvalKey.PubKey(), + Address: pubKey.Address(), + PubKey: pubKey, Power: power, }) } @@ -388,8 +393,8 @@ func MakeAppConfig(node *e2e.Node) ([]byte, error) { for height, validators := range node.Testnet.ValidatorUpdates { updateVals := map[string]int64{} for node, power := range validators { - key := node.PrivvalKey.PubKey() - updateVals[base64.StdEncoding.EncodeToString(key[:])] = power + key := node.PrivvalKey.Public() + updateVals[base64.StdEncoding.EncodeToString(key.Bytes())] = power } validatorUpdates[fmt.Sprintf("%v", height)] = updateVals } diff --git a/sei-tendermint/types/block.go b/sei-tendermint/types/block.go index 0e2c9e439e..40e3c868fd 100644 --- a/sei-tendermint/types/block.go +++ b/sei-tendermint/types/block.go @@ -640,10 +640,11 @@ const ( // CommitSig is a part of the Vote included in a Commit. type CommitSig struct { - BlockIDFlag BlockIDFlag `json:"block_id_flag"` - ValidatorAddress Address `json:"validator_address"` - Timestamp time.Time `json:"timestamp"` - Signature crypto.Sig `json:"signature"` + BlockIDFlag BlockIDFlag `json:"block_id_flag"` + // WARNING: all fields below should be zeroed if BlockIDFlag == BlockIDFlagAbsent + ValidatorAddress Address `json:"validator_address"` + Timestamp time.Time `json:"timestamp"` + Signature crypto.Sig `json:"signature"` } func MaxCommitBytes(valCount int) int64 { @@ -668,7 +669,7 @@ func NewCommitSigAbsent() CommitSig { // 4. timestamp func (cs CommitSig) String() string { return fmt.Sprintf("CommitSig{%X by %X on %v @ %s}", - tmbytes.Fingerprint(cs.Signature[:]), + tmbytes.Fingerprint(cs.Signature.Bytes()), tmbytes.Fingerprint(cs.ValidatorAddress), cs.BlockIDFlag, CanonicalTime(cs.Timestamp)) @@ -709,7 +710,7 @@ func (cs CommitSig) ValidateBasic() error { if !cs.Timestamp.IsZero() { return errors.New("time is present") } - if len(cs.Signature) != 0 { + if cs.Signature != (crypto.Sig{}) { return errors.New("signature is present") } default: @@ -735,7 +736,7 @@ func (cs *CommitSig) ToProto() *tmproto.CommitSig { BlockIdFlag: tmproto.BlockIDFlag(cs.BlockIDFlag), ValidatorAddress: cs.ValidatorAddress, Timestamp: cs.Timestamp, - Signature: cs.Signature[:], + Signature: cs.Signature.Bytes(), } } diff --git a/sei-tendermint/types/node_key.go b/sei-tendermint/types/node_key.go index 927e17065d..32fd264b51 100644 --- a/sei-tendermint/types/node_key.go +++ b/sei-tendermint/types/node_key.go @@ -53,7 +53,7 @@ func (nk *NodeKey) UnmarshalJSON(data []byte) error { // PubKey returns the peer's PubKey func (nk NodeKey) PubKey() crypto.PubKey { - return nk.PrivKey.PubKey() + return nk.PrivKey.Public() } // SaveAs persists the NodeKey to filePath. @@ -87,9 +87,12 @@ func LoadOrGenNodeKey(filePath string) (NodeKey, error) { // GenNodeKey generates a new node key. func GenNodeKey() NodeKey { - privKey := ed25519.GenPrivKey() + privKey, err := ed25519.GenerateSecretKey() + if err != nil { + panic(err) + } return NodeKey{ - ID: NodeIDFromPubKey(privKey.PubKey()), + ID: NodeIDFromPubKey(privKey.Public()), PrivKey: privKey, } } diff --git a/sei-tendermint/types/params.go b/sei-tendermint/types/params.go index 978e1a0c86..8f0f572f85 100644 --- a/sei-tendermint/types/params.go +++ b/sei-tendermint/types/params.go @@ -26,7 +26,7 @@ const ( ) var ABCIPubKeyTypesToNames = map[string]string{ - ABCIPubKeyTypeEd25519: ed25519.PubKeyName, + ABCIPubKeyTypeEd25519: ed25519.PublicKeyName, } // ConsensusParams contains consensus critical parameters that determine the diff --git a/sei-tendermint/types/priv_validator.go b/sei-tendermint/types/priv_validator.go index 3375425440..7c6fd79da8 100644 --- a/sei-tendermint/types/priv_validator.go +++ b/sei-tendermint/types/priv_validator.go @@ -67,7 +67,7 @@ type MockPV struct { } func NewMockPV() MockPV { - return MockPV{ed25519.GenPrivKey(), false, false} + return MockPV{mustGenerateSecretKey(), false, false} } // NewMockPVWithParams allows one to create a MockPV instance, but with finer @@ -79,7 +79,7 @@ func NewMockPVWithParams(privKey crypto.PrivKey, breakProposalSigning, breakVote // Implements PrivValidator. func (pv MockPV) GetPubKey(ctx context.Context) (crypto.PubKey, error) { - return pv.PrivKey.PubKey(), nil + return pv.PrivKey.Public(), nil } // Implements PrivValidator. @@ -91,7 +91,7 @@ func (pv MockPV) SignVote(ctx context.Context, chainID string, vote *tmproto.Vot signBytes := VoteSignBytes(useChainID, vote) sig := pv.PrivKey.Sign(signBytes) - vote.Signature = sig[:] + vote.Signature = sig.Bytes() return nil } @@ -104,7 +104,7 @@ func (pv MockPV) SignProposal(ctx context.Context, chainID string, proposal *tmp signBytes := ProposalSignBytes(useChainID, proposal) sig := pv.PrivKey.Sign(signBytes) - proposal.Signature = sig[:] + proposal.Signature = sig.Bytes() return nil } @@ -153,5 +153,13 @@ func (pv *ErroringMockPV) SignProposal(ctx context.Context, chainID string, prop // NewErroringMockPV returns a MockPV that fails on each signing request. Again, for testing only. func NewErroringMockPV() *ErroringMockPV { - return &ErroringMockPV{MockPV{ed25519.GenPrivKey(), false, false}} + return &ErroringMockPV{MockPV{mustGenerateSecretKey(), false, false}} +} + +func mustGenerateSecretKey() crypto.PrivKey { + key, err := ed25519.GenerateSecretKey() + if err != nil { + panic(err) + } + return key } diff --git a/sei-tendermint/types/proposal.go b/sei-tendermint/types/proposal.go index d0b4fb517f..d50aeeee13 100644 --- a/sei-tendermint/types/proposal.go +++ b/sei-tendermint/types/proposal.go @@ -136,7 +136,7 @@ func (p *Proposal) String() string { p.Round, p.BlockID, p.POLRound, - tmbytes.Fingerprint(p.Signature[:]), + tmbytes.Fingerprint(p.Signature.Bytes()), CanonicalTime(p.Timestamp)) } @@ -171,7 +171,7 @@ func (p *Proposal) ToProto() *tmproto.Proposal { pb.Round = p.Round pb.PolRound = p.POLRound pb.Timestamp = p.Timestamp - pb.Signature = p.Signature[:] + pb.Signature = p.Signature.Bytes() txKeys := make([]*tmproto.TxKey, 0, len(p.TxKeys)) for _, txKey := range p.TxKeys { txKeys = append(txKeys, txKey.ToProto()) diff --git a/sei-tendermint/types/vote.go b/sei-tendermint/types/vote.go index 2fca636f79..78dbb948f2 100644 --- a/sei-tendermint/types/vote.go +++ b/sei-tendermint/types/vote.go @@ -165,7 +165,7 @@ func (vote *Vote) String() string { vote.Type, typeString, tmbytes.Fingerprint(vote.BlockID.Hash), - tmbytes.Fingerprint(vote.Signature[:]), + tmbytes.Fingerprint(vote.Signature.Bytes()), CanonicalTime(vote.Timestamp), ) } @@ -244,7 +244,7 @@ func (vote *Vote) ToProto() *tmproto.Vote { Timestamp: vote.Timestamp, ValidatorAddress: vote.ValidatorAddress, ValidatorIndex: vote.ValidatorIndex, - Signature: vote.Signature[:], + Signature: vote.Signature.Bytes(), } } From 025fd158b04cbcd722599660b2e8778ea877aa39 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Thu, 18 Dec 2025 10:33:16 +0100 Subject: [PATCH 33/53] codex tests --- sei-tendermint/crypto/ed25519/ed25519.go | 16 +++++++++----- .../internal/consensus/common_test.go | 6 +++--- .../internal/consensus/invalid_test.go | 2 +- .../internal/consensus/memory_limit_test.go | 8 +++---- .../internal/consensus/pbts_test.go | 3 ++- .../internal/consensus/replay_test.go | 8 +++---- .../internal/consensus/state_test.go | 16 +++++++------- .../consensus/types/height_vote_set_test.go | 3 ++- sei-tendermint/internal/evidence/pool_test.go | 15 ++++++------- .../internal/evidence/verify_test.go | 7 ++++--- .../internal/mempool/reactor_test.go | 4 ++-- sei-tendermint/internal/p2p/address_test.go | 4 ++-- .../p2p/conn/evil_secret_connection_test.go | 10 ++++----- .../p2p/conn/secret_connection_test.go | 10 ++++----- .../internal/p2p/peermanager_test.go | 8 +++---- .../internal/p2p/pex/reactor_test.go | 2 +- sei-tendermint/internal/p2p/testonly.go | 3 +-- sei-tendermint/internal/p2p/transport_test.go | 2 +- .../internal/state/execution_test.go | 19 +++++++---------- sei-tendermint/internal/state/helpers_test.go | 14 ++++++------- sei-tendermint/internal/state/state_test.go | 20 +++++++++--------- sei-tendermint/internal/state/store_test.go | 2 +- .../internal/state/validation_test.go | 8 +++++-- sei-tendermint/internal/store/store_test.go | 11 ++++------ sei-tendermint/light/helpers_test.go | 6 +++--- sei-tendermint/node/node_test.go | 9 ++++---- sei-tendermint/privval/file.go | 5 +---- sei-tendermint/privval/file_test.go | 14 ++++++++----- sei-tendermint/privval/grpc/client_test.go | 2 +- sei-tendermint/privval/grpc/server_test.go | 15 ++++++------- sei-tendermint/privval/msgs_test.go | 2 +- sei-tendermint/privval/signer_client_test.go | 11 ++++------ .../privval/signer_listener_endpoint_test.go | 4 ++-- sei-tendermint/privval/socket_dialers_test.go | 6 +++--- .../privval/socket_listeners_test.go | 14 ++----------- sei-tendermint/privval/utils.go | 6 +----- sei-tendermint/rpc/client/rpc_test.go | 2 +- sei-tendermint/test/e2e/node/main.go | 5 +---- sei-tendermint/test/e2e/runner/setup.go | 5 +---- .../test/e2e/tests/validator_test.go | 6 +++--- .../fuzz/tests/p2p_secretconnection_test.go | 8 +++---- sei-tendermint/types/block.go | 1 + sei-tendermint/types/block_test.go | 21 ++++++++++++------- sei-tendermint/types/evidence_test.go | 5 +++-- sei-tendermint/types/genesis_test.go | 4 ++-- sei-tendermint/types/node_info_test.go | 2 +- sei-tendermint/types/node_key.go | 5 +---- sei-tendermint/types/priv_validator.go | 12 ++--------- sei-tendermint/types/proposal_test.go | 15 +++++-------- sei-tendermint/types/protobuf_test.go | 6 +++--- sei-tendermint/types/validation_test.go | 9 ++++---- sei-tendermint/types/validator_set_test.go | 12 +++++------ sei-tendermint/types/vote_test.go | 11 +++++----- 53 files changed, 196 insertions(+), 228 deletions(-) diff --git a/sei-tendermint/crypto/ed25519/ed25519.go b/sei-tendermint/crypto/ed25519/ed25519.go index c86fe58490..c1d4eb9f90 100644 --- a/sei-tendermint/crypto/ed25519/ed25519.go +++ b/sei-tendermint/crypto/ed25519/ed25519.go @@ -79,12 +79,18 @@ func TestSecretKey(seed []byte) SecretKey { } // GenerateSecretKey generates a new secret key using a cryptographically secure random number generator. -func GenerateSecretKey() (SecretKey, error) { - var seed [ed25519.PrivateKeySize]byte - if _, err := rand.Read(seed[:]); err != nil { - return SecretKey{}, err +func GenerateSecretKey() SecretKey { + var seed [ed25519.PrivateKeySize]byte + // rand.Read is documented to never return an error. + if _, err := rand.Read(seed[:]); err != nil { panic(err) } + // Generated key is always valid. + key, err := SecretKeyFromSecretBytes(ed25519.NewKeyFromSeed(seed[:])) + if err!=nil { panic(err) } + // Zeroize the seed after generation. + for i := range seed { + seed[i] = 0 } - return SecretKeyFromSecretBytes(ed25519.NewKeyFromSeed(seed[:])) + return key } // Public returns the public key corresponding to the secret key. diff --git a/sei-tendermint/internal/consensus/common_test.go b/sei-tendermint/internal/consensus/common_test.go index 490523ca32..f2b7db5674 100644 --- a/sei-tendermint/internal/consensus/common_test.go +++ b/sei-tendermint/internal/consensus/common_test.go @@ -141,10 +141,10 @@ func (vs *validatorStub) signVote( // ref: signVote in FilePV, the vote should use the previous vote info when the sign data is the same. if signDataIsEqual(vs.lastVote, v) { - v.Signature = vs.lastVote.Signature[:] + v.Signature = vs.lastVote.Signature.Bytes() v.Timestamp = vs.lastVote.Timestamp } - vote.Signature = crypto.Sig(v.Signature) + vote.Signature = utils.OrPanic1(crypto.SigFromBytes(v.Signature)) vote.Timestamp = v.Timestamp return vote, nil } @@ -258,7 +258,7 @@ func decideProposal( proposal = types.NewProposal(height, round, polRound, propBlockID, block.Header.Time, block.GetTxKeys(), block.Header, block.LastCommit, block.Evidence, address) p := proposal.ToProto() require.NoError(t, vs.SignProposal(ctx, chainID, p)) - proposal.Signature = crypto.Sig(p.Signature) + proposal.Signature = utils.OrPanic1(crypto.SigFromBytes(p.Signature)) return } diff --git a/sei-tendermint/internal/consensus/invalid_test.go b/sei-tendermint/internal/consensus/invalid_test.go index 3dd1252efc..327c74d336 100644 --- a/sei-tendermint/internal/consensus/invalid_test.go +++ b/sei-tendermint/internal/consensus/invalid_test.go @@ -147,7 +147,7 @@ func invalidDoPrevoteFunc( p := precommit.ToProto() require.NoError(t, pv.SignVote(ctx, cs.state.ChainID, p)) - precommit.Signature = crypto.Sig(p.Signature) + precommit.Signature = utils.OrPanic1(crypto.SigFromBytes(p.Signature)) t.Logf("disable priv val so we don't do normal votes") cs.privValidator = utils.None[types.PrivValidator]() cs.mtx.Unlock() diff --git a/sei-tendermint/internal/consensus/memory_limit_test.go b/sei-tendermint/internal/consensus/memory_limit_test.go index 3791b794bd..51e7a9f2b6 100644 --- a/sei-tendermint/internal/consensus/memory_limit_test.go +++ b/sei-tendermint/internal/consensus/memory_limit_test.go @@ -6,16 +6,16 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/libs/log" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/types" ) +var testKey = ed25519.TestSecretKey([]byte("test")) + func makeSig(data string) crypto.Sig { - var sig crypto.Sig - n := min(len(sig), len(data)) - copy(sig[:n], []byte(data[:n])) - return sig + return testKey.Sign([]byte(data)) } func TestPeerStateMemoryLimits(t *testing.T) { diff --git a/sei-tendermint/internal/consensus/pbts_test.go b/sei-tendermint/internal/consensus/pbts_test.go index 48d3338e97..bcec5f43cb 100644 --- a/sei-tendermint/internal/consensus/pbts_test.go +++ b/sei-tendermint/internal/consensus/pbts_test.go @@ -16,6 +16,7 @@ import ( "github.com/tendermint/tendermint/internal/test/factory" "github.com/tendermint/tendermint/libs/log" tmtimemocks "github.com/tendermint/tendermint/libs/time/mocks" + "github.com/tendermint/tendermint/libs/utils" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/types" ) @@ -225,7 +226,7 @@ func (p *pbtsTestHarness) nextHeight(ctx context.Context, t *testing.T, proposer } time.Sleep(time.Until(deliverTime)) - prop.Signature = crypto.Sig(tp.Signature) + prop.Signature = utils.OrPanic1(crypto.SigFromBytes(tp.Signature)) if err := p.observedState.SetProposalAndBlock(ctx, prop, b, ps, "peerID"); err != nil { t.Fatal(err) } diff --git a/sei-tendermint/internal/consensus/replay_test.go b/sei-tendermint/internal/consensus/replay_test.go index e7f54501b1..a63ea8a2f3 100644 --- a/sei-tendermint/internal/consensus/replay_test.go +++ b/sei-tendermint/internal/consensus/replay_test.go @@ -360,7 +360,7 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite { if err := vss[1].SignProposal(ctx, cfg.ChainID(), p); err != nil { t.Fatal("failed to sign bad proposal", err) } - proposal.Signature = crypto.Sig(p.Signature) + proposal.Signature = utils.OrPanic1(crypto.SigFromBytes(p.Signature)) // set the proposal block if err := css[0].SetProposalAndBlock(ctx, proposal, propBlock, propBlockParts, "some peer"); err != nil { @@ -395,7 +395,7 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite { if err := vss[2].SignProposal(ctx, cfg.ChainID(), p); err != nil { t.Fatal("failed to sign bad proposal", err) } - proposal.Signature = crypto.Sig(p.Signature) + proposal.Signature = utils.OrPanic1(crypto.SigFromBytes(p.Signature)) // set the proposal block if err := css[0].SetProposalAndBlock(ctx, proposal, propBlock, propBlockParts, "some peer"); err != nil { @@ -460,7 +460,7 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite { if err := vss[3].SignProposal(ctx, cfg.ChainID(), p); err != nil { t.Fatal("failed to sign bad proposal", err) } - proposal.Signature = crypto.Sig(p.Signature) + proposal.Signature = utils.OrPanic1(crypto.SigFromBytes(p.Signature)) // set the proposal block if err := css[0].SetProposalAndBlock(ctx, proposal, propBlock, propBlockParts, "some peer"); err != nil { @@ -533,7 +533,7 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite { if err := vss[1].SignProposal(ctx, cfg.ChainID(), p); err != nil { t.Fatal("failed to sign bad proposal", err) } - proposal.Signature = crypto.Sig(p.Signature) + proposal.Signature = utils.OrPanic1(crypto.SigFromBytes(p.Signature)) // set the proposal block if err := css[0].SetProposalAndBlock(ctx, proposal, propBlock, propBlockParts, "some peer"); err != nil { diff --git a/sei-tendermint/internal/consensus/state_test.go b/sei-tendermint/internal/consensus/state_test.go index 34fa1eea96..e5f37b1d2f 100644 --- a/sei-tendermint/internal/consensus/state_test.go +++ b/sei-tendermint/internal/consensus/state_test.go @@ -251,7 +251,7 @@ func TestStateBadProposal(t *testing.T) { proposal := types.NewProposal(vs2.Height, round, -1, blockID, propBlock.Header.Time, propBlock.GetTxKeys(), propBlock.Header, propBlock.LastCommit, propBlock.Evidence, pubKey.Address()) p := proposal.ToProto() require.NoError(t, vs2.SignProposal(ctx, config.ChainID(), p)) - proposal.Signature = crypto.Sig(p.Signature) + proposal.Signature = utils.OrPanic1(crypto.SigFromBytes(p.Signature)) // set the proposal block err = cs1.SetProposalAndBlock(ctx, proposal, propBlock, propBlockParts, "some peer") @@ -307,7 +307,7 @@ func TestStateOversizedBlock(t *testing.T) { proposal := types.NewProposal(height, round, -1, blockID, propBlock.Header.Time, propBlock.GetTxKeys(), propBlock.Header, propBlock.LastCommit, propBlock.Evidence, pubKey.Address()) p := proposal.ToProto() require.NoError(t, vs2.SignProposal(ctx, config.ChainID(), p)) - proposal.Signature = crypto.Sig(p.Signature) + proposal.Signature = utils.OrPanic1(crypto.SigFromBytes(p.Signature)) totalBytes := 0 for i := 0; i < int(propBlockParts.Total()); i++ { @@ -806,7 +806,7 @@ func TestStateLock_POLRelock(t *testing.T) { propR1 := types.NewProposal(height, round, cs1.roundState.ValidRound(), blockID, theBlock.Header.Time, theBlock.GetTxKeys(), theBlock.Header, theBlock.LastCommit, theBlock.Evidence, pubKey.Address()) p := propR1.ToProto() require.NoError(t, vs2.SignProposal(ctx, cs1.state.ChainID, p)) - propR1.Signature = crypto.Sig(p.Signature) + propR1.Signature = utils.OrPanic1(crypto.SigFromBytes(p.Signature)) err = cs1.SetProposalAndBlock(ctx, propR1, theBlock, theBlockParts, "") require.NoError(t, err) @@ -1485,7 +1485,7 @@ func TestStateLock_POLSafety2(t *testing.T) { err = vs3.SignProposal(ctx, config.ChainID(), p) require.NoError(t, err) - newProp.Signature = crypto.Sig(p.Signature) + newProp.Signature = utils.OrPanic1(crypto.SigFromBytes(p.Signature)) err = cs1.SetProposalAndBlock(ctx, newProp, propBlock0, propBlockParts0, "some peer") require.NoError(t, err) @@ -1622,7 +1622,7 @@ func TestState_PrevotePOLFromPreviousRound(t *testing.T) { p := propR2.ToProto() err = vs3.SignProposal(ctx, cs1.state.ChainID, p) require.NoError(t, err) - propR2.Signature = crypto.Sig(p.Signature) + propR2.Signature = utils.OrPanic1(crypto.SigFromBytes(p.Signature)) // cs1 receives a proposal for D, the block that received a POL in round 1. err = cs1.SetProposalAndBlock(ctx, propR2, propBlockR1, propBlockR1Parts, "") @@ -2442,7 +2442,7 @@ func TestGossipTransactionKeyOnlyConfig(t *testing.T) { p := proposal.ToProto() err = vs2.SignProposal(ctx, config.ChainID(), p) require.NoError(t, err) - proposal.Signature = crypto.Sig(p.Signature) + proposal.Signature = utils.OrPanic1(crypto.SigFromBytes(p.Signature)) proposalMsg := ProposalMessage{&proposal} peerID, err := types.NewNodeID("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") @@ -2557,7 +2557,7 @@ func TestStateTimestamp_ProposalNotMatch(t *testing.T) { p := proposal.ToProto() err = vs2.SignProposal(ctx, config.ChainID(), p) require.NoError(t, err) - proposal.Signature = crypto.Sig(p.Signature) + proposal.Signature = utils.OrPanic1(crypto.SigFromBytes(p.Signature)) require.NoError(t, cs1.SetProposalAndBlock(ctx, proposal, propBlock, propBlockParts, "some peer")) startTestRound(ctx, cs1, height, round) @@ -2604,7 +2604,7 @@ func TestStateTimestamp_ProposalMatch(t *testing.T) { p := proposal.ToProto() err = vs2.SignProposal(ctx, config.ChainID(), p) require.NoError(t, err) - proposal.Signature = crypto.Sig(p.Signature) + proposal.Signature = utils.OrPanic1(crypto.SigFromBytes(p.Signature)) require.NoError(t, cs1.SetProposalAndBlock(ctx, proposal, propBlock, propBlockParts, "some peer")) startTestRound(ctx, cs1, height, round) diff --git a/sei-tendermint/internal/consensus/types/height_vote_set_test.go b/sei-tendermint/internal/consensus/types/height_vote_set_test.go index e44cb4d785..2eacfb7216 100644 --- a/sei-tendermint/internal/consensus/types/height_vote_set_test.go +++ b/sei-tendermint/internal/consensus/types/height_vote_set_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/internal/test/factory" tmrand "github.com/tendermint/tendermint/libs/rand" @@ -84,6 +85,6 @@ func makeVoteHR( v := vote.ToProto() require.NoError(t, privVal.SignVote(ctx, chainID, v)) - vote.Signature = crypto.Sig(v.Signature) + vote.Signature = utils.OrPanic1(crypto.SigFromBytes(v.Signature)) return vote } diff --git a/sei-tendermint/internal/evidence/pool_test.go b/sei-tendermint/internal/evidence/pool_test.go index f36f1382b1..a03aa18300 100644 --- a/sei-tendermint/internal/evidence/pool_test.go +++ b/sei-tendermint/internal/evidence/pool_test.go @@ -12,6 +12,7 @@ import ( dbm "github.com/tendermint/tm-db" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/internal/eventbus" "github.com/tendermint/tendermint/internal/evidence" "github.com/tendermint/tendermint/internal/evidence/mocks" @@ -35,10 +36,10 @@ var ( defaultEvidenceMaxBytes int64 = 1000 ) +var testKey = ed25519.TestSecretKey([]byte("test")) + func makeEvidenceSignature(data []byte) crypto.Sig { - var sig crypto.Sig - copy(sig[:], data) - return sig + return testKey.Sign(data) } func startPool(t *testing.T, pool *evidence.Pool, store sm.Store) { @@ -181,7 +182,7 @@ func TestReportConflictingVotes(t *testing.T) { pool, pv, _ := defaultTestPool(ctx, t, height) - val := types.NewValidator(pv.PrivKey.PubKey(), 10) + val := types.NewValidator(pv.PrivKey.Public(), 10) ev, err := types.NewMockDuplicateVoteEvidenceWithValidator(ctx, height+1, defaultEvidenceTime, pv, evidenceChainID) require.NoError(t, err) @@ -250,7 +251,7 @@ func TestEvidencePoolUpdate(t *testing.T) { evidenceChainID, ) require.NoError(t, err) - lastCommit := makeCommit(height, val.PrivKey.PubKey().Address()) + lastCommit := makeCommit(height, val.PrivKey.Public().Address()) block := types.MakeBlock(height+1, []types.Tx{}, lastCommit, []types.Evidence{ev}) // update state (partially) @@ -444,7 +445,7 @@ func TestRecoverPendingEvidence(t *testing.T) { height := int64(10) val := types.NewMockPV() - valAddress := val.PrivKey.PubKey().Address() + valAddress := val.PrivKey.Public().Address() evidenceDB := dbm.NewMemDB() stateStore := initializeValidatorState(ctx, t, val, height) @@ -597,7 +598,7 @@ func makeCommit(height int64, valAddr []byte) *types.Commit { func defaultTestPool(ctx context.Context, t *testing.T, height int64) (*evidence.Pool, types.MockPV, *eventbus.EventBus) { t.Helper() val := types.NewMockPV() - valAddress := val.PrivKey.PubKey().Address() + valAddress := val.PrivKey.Public().Address() evidenceDB := dbm.NewMemDB() stateStore := initializeValidatorState(ctx, t, val, height) state, err := stateStore.Load() diff --git a/sei-tendermint/internal/evidence/verify_test.go b/sei-tendermint/internal/evidence/verify_test.go index 9af64742a6..6a0b00c6ee 100644 --- a/sei-tendermint/internal/evidence/verify_test.go +++ b/sei-tendermint/internal/evidence/verify_test.go @@ -18,6 +18,7 @@ import ( smmocks "github.com/tendermint/tendermint/internal/state/mocks" "github.com/tendermint/tendermint/internal/test/factory" "github.com/tendermint/tendermint/libs/log" + "github.com/tendermint/tendermint/libs/utils" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/types" ) @@ -421,8 +422,8 @@ func TestVerifyDuplicateVoteEvidence(t *testing.T) { err = val2.SignVote(ctx, chainID, bv) require.NoError(t, err) - vote1.Signature = crypto.Sig(v1.Signature) - badVote.Signature = crypto.Sig(bv.Signature) + vote1.Signature = utils.OrPanic1(crypto.SigFromBytes(v1.Signature)) + badVote.Signature = utils.OrPanic1(crypto.SigFromBytes(bv.Signature)) cases := []voteData{ {vote1, makeVote(ctx, t, val, chainID, 0, 10, 2, 1, blockID2, defaultEvidenceTime), true}, // different block ids @@ -605,7 +606,7 @@ func makeVote( vpb := v.ToProto() err = val.SignVote(ctx, chainID, vpb) require.NoError(t, err) - v.Signature = crypto.Sig(vpb.Signature) + v.Signature = utils.OrPanic1(crypto.SigFromBytes(vpb.Signature)) return v } diff --git a/sei-tendermint/internal/mempool/reactor_test.go b/sei-tendermint/internal/mempool/reactor_test.go index 262c1f4a69..7f9eb1ccf3 100644 --- a/sei-tendermint/internal/mempool/reactor_test.go +++ b/sei-tendermint/internal/mempool/reactor_test.go @@ -326,8 +326,8 @@ func TestDontExhaustMaxActiveIDs(t *testing.T) { // ensure the reactor does not panic (i.e. exhaust active IDs) for range MaxActiveIDs + 1 { - privKey := ed25519.GenPrivKey() - peerID := types.NodeIDFromPubKey(privKey.PubKey()) + privKey := ed25519.GenerateSecretKey() + peerID := types.NodeIDFromPubKey(privKey.Public()) rts.reactors[nodeID].processPeerUpdate(ctx, p2p.PeerUpdate{ Status: p2p.PeerStatusUp, NodeID: peerID, diff --git a/sei-tendermint/internal/p2p/address_test.go b/sei-tendermint/internal/p2p/address_test.go index fbed1bab3e..6a522545a3 100644 --- a/sei-tendermint/internal/p2p/address_test.go +++ b/sei-tendermint/internal/p2p/address_test.go @@ -38,8 +38,8 @@ func TestNewNodeID(t *testing.T) { } func TestNewNodeIDFromPubKey(t *testing.T) { - privKey := ed25519.PrivKeyFromSeed(ed25519.Seed{43, 55, 33}) - nodeID := types.NodeIDFromPubKey(privKey.PubKey()) + privKey := ed25519.TestSecretKey([]byte{43, 55, 33}) + nodeID := types.NodeIDFromPubKey(privKey.Public()) require.NoError(t, nodeID.Validate()) } diff --git a/sei-tendermint/internal/p2p/conn/evil_secret_connection_test.go b/sei-tendermint/internal/p2p/conn/evil_secret_connection_test.go index c7cd7bc84b..0c5b68daf9 100644 --- a/sei-tendermint/internal/p2p/conn/evil_secret_connection_test.go +++ b/sei-tendermint/internal/p2p/conn/evil_secret_connection_test.go @@ -58,7 +58,7 @@ type evilConn struct { } func newEvilConn(shareEphKey, badEphKey, shareAuthSignature, badAuthSignature bool) *evilConn { - privKey := ed25519.GenPrivKey() + privKey := ed25519.GenerateSecretKey() locEphPub, locEphPriv := genEphKeys() var rep [32]byte c := &evilConn{ @@ -113,8 +113,8 @@ func (c *evilConn) Read(data []byte) (n int, err error) { case 1: signature := c.signChallenge() if !c.badAuthSignature { - pkpb := encoding.PubKeyToProto(c.privKey.PubKey()) - bz, err := protoio.MarshalDelimited(&tmp2p.AuthSigMessage{PubKey: pkpb, Sig: signature[:]}) + pkpb := encoding.PubKeyToProto(c.privKey.Public()) + bz, err := protoio.MarshalDelimited(&tmp2p.AuthSigMessage{PubKey: pkpb, Sig: signature.Bytes()}) if err != nil { panic(err) } @@ -177,7 +177,7 @@ func (c *evilConn) Close() error { return nil } -func (c *evilConn) signChallenge() ed25519.Sig { +func (c *evilConn) signChallenge() ed25519.Signature { // Sort by lexical order. loEphPub, hiEphPub := sort32(c.locEphPub, c.remEphPub) @@ -248,7 +248,7 @@ func TestMakeSecretConnection(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - privKey := ed25519.GenPrivKey() + privKey := ed25519.GenerateSecretKey() _, err := MakeSecretConnection(tc.conn, privKey) if tc.errMsg != "" { if assert.Error(t, err) { diff --git a/sei-tendermint/internal/p2p/conn/secret_connection_test.go b/sei-tendermint/internal/p2p/conn/secret_connection_test.go index 2f06745d34..032b75bcfe 100644 --- a/sei-tendermint/internal/p2p/conn/secret_connection_test.go +++ b/sei-tendermint/internal/p2p/conn/secret_connection_test.go @@ -110,7 +110,7 @@ func TestSecretConnectionReadWrite(t *testing.T) { genNodeRunner := func(id string, nodeConn kvstoreConn, nodeWrites []string, nodeReads *[]string) async.Task { return func(_ int) (interface{}, bool, error) { // Initiate cryptographic private key and secret connection trhough nodeConn. - nodePrvKey := ed25519.GenPrivKey() + nodePrvKey := ed25519.GenerateSecretKey() nodeSecretConn, err := MakeSecretConnection(nodeConn, nodePrvKey) if err != nil { t.Errorf("failed to establish SecretConnection for node: %v", err) @@ -293,10 +293,10 @@ func makeKVStoreConnPair() (fooConn, barConn kvstoreConn) { func makeSecretConnPair(tb testing.TB) (fooSecConn, barSecConn *SecretConnection) { var ( fooConn, barConn = makeKVStoreConnPair() - fooPrvKey = ed25519.GenPrivKey() - fooPubKey = fooPrvKey.PubKey() - barPrvKey = ed25519.GenPrivKey() - barPubKey = barPrvKey.PubKey() + fooPrvKey = ed25519.GenerateSecretKey() + fooPubKey = fooPrvKey.Public() + barPrvKey = ed25519.GenerateSecretKey() + barPubKey = barPrvKey.Public() ) // Make connections from both sides in parallel. diff --git a/sei-tendermint/internal/p2p/peermanager_test.go b/sei-tendermint/internal/p2p/peermanager_test.go index 31a3eba2e1..22f3f2527a 100644 --- a/sei-tendermint/internal/p2p/peermanager_test.go +++ b/sei-tendermint/internal/p2p/peermanager_test.go @@ -55,14 +55,14 @@ func makePeerManager(selfID types.NodeID, options *RouterOptions) *peerManager[* return newPeerManager[*fakeConn](selfID, options) } -var selfID = types.NodeIDFromPubKey(ed25519.PrivKeyFromSeed(ed25519.Seed{12, 43}).PubKey()) +var selfID = types.NodeIDFromPubKey(ed25519.TestSecretKey([]byte{12, 43}).Public()) -func makeKey(rng utils.Rng) ed25519.PrivKey { - return ed25519.PrivKeyFromSeed(ed25519.Seed(utils.GenBytes(rng, len(ed25519.Seed{})))) +func makeKey(rng utils.Rng) ed25519.SecretKey { + return ed25519.TestSecretKey(utils.GenBytes(rng, 32)) } func makeNodeID(rng utils.Rng) types.NodeID { - return types.NodeIDFromPubKey(makeKey(rng).PubKey()) + return types.NodeIDFromPubKey(makeKey(rng).Public()) } func makeAddrFor(rng utils.Rng, id types.NodeID) NodeAddress { diff --git a/sei-tendermint/internal/p2p/pex/reactor_test.go b/sei-tendermint/internal/p2p/pex/reactor_test.go index bc3e3fd7e3..eebd954b2e 100644 --- a/sei-tendermint/internal/p2p/pex/reactor_test.go +++ b/sei-tendermint/internal/p2p/pex/reactor_test.go @@ -521,5 +521,5 @@ func (r *reactorTestSuite) addAddresses(t *testing.T, node int, addrIDs []int) { } func randomNodeID() types.NodeID { - return types.NodeIDFromPubKey(ed25519.GenPrivKey().PubKey()) + return types.NodeIDFromPubKey(ed25519.GenerateSecretKey().Public()) } diff --git a/sei-tendermint/internal/p2p/testonly.go b/sei-tendermint/internal/p2p/testonly.go index b73273ef27..08c196a7e4 100644 --- a/sei-tendermint/internal/p2p/testonly.go +++ b/sei-tendermint/internal/p2p/testonly.go @@ -278,8 +278,7 @@ func (n *TestNode) Disconnect(ctx context.Context, target types.NodeID) { // running peer manager, but does not add it to the existing // network. Callers are responsible for updating peering relationships. func (n *TestNetwork) MakeNode(t *testing.T, opts TestNodeOptions) *TestNode { - privKey, err := ed25519.GenerateSecretKey() - require.NoError(t, err) + privKey := ed25519.GenerateSecretKey() nodeID := types.NodeIDFromPubKey(privKey.Public()) logger := n.logger.With("node", nodeID[:5]) diff --git a/sei-tendermint/internal/p2p/transport_test.go b/sei-tendermint/internal/p2p/transport_test.go index 2417889066..5f342e5580 100644 --- a/sei-tendermint/internal/p2p/transport_test.go +++ b/sei-tendermint/internal/p2p/transport_test.go @@ -22,7 +22,7 @@ import ( ) func makeInfo(key crypto.PrivKey) types.NodeInfo { - nodeID := types.NodeIDFromPubKey(key.PubKey()) + nodeID := types.NodeIDFromPubKey(key.Public()) peerInfo := types.NodeInfo{ NodeID: nodeID, ListenAddr: "127.0.0.1:1239", diff --git a/sei-tendermint/internal/state/execution_test.go b/sei-tendermint/internal/state/execution_test.go index 43df775843..846592c4c3 100644 --- a/sei-tendermint/internal/state/execution_test.go +++ b/sei-tendermint/internal/state/execution_test.go @@ -28,6 +28,7 @@ import ( "github.com/tendermint/tendermint/internal/store" "github.com/tendermint/tendermint/internal/test/factory" "github.com/tendermint/tendermint/libs/log" + "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/version" ) @@ -207,7 +208,7 @@ func TestFinalizeBlockByzantineValidators(t *testing.T) { BlockIDFlag: types.BlockIDFlagNil, ValidatorAddress: crypto.AddressHash([]byte("validator_address")), Timestamp: defaultEvidenceTime, - Signature: crypto.Sig(crypto.CRandBytes(len(crypto.Sig{}))), + Signature: utils.OrPanic1(crypto.SigFromBytes(crypto.CRandBytes(64))), }}, }, }, @@ -372,8 +373,8 @@ func TestProcessProposal(t *testing.T) { } func TestValidateValidatorUpdates(t *testing.T) { - pubkey1 := ed25519.GenPrivKey().PubKey() - pubkey2 := ed25519.GenPrivKey().PubKey() + pubkey1 := ed25519.GenerateSecretKey().Public() + pubkey2 := ed25519.GenerateSecretKey().Public() pk1 := encoding.PubKeyToProto(pubkey1) pk2 := encoding.PubKeyToProto(pubkey2) @@ -426,9 +427,9 @@ func TestValidateValidatorUpdates(t *testing.T) { } func TestUpdateValidators(t *testing.T) { - pubkey1 := ed25519.GenPrivKey().PubKey() + pubkey1 := ed25519.GenerateSecretKey().Public() val1 := types.NewValidator(pubkey1, 10) - pubkey2 := ed25519.GenPrivKey().PubKey() + pubkey2 := ed25519.GenerateSecretKey().Public() val2 := types.NewValidator(pubkey2, 20) pk := encoding.PubKeyToProto(pubkey1) @@ -549,7 +550,7 @@ func TestFinalizeBlockValidatorUpdates(t *testing.T) { require.NoError(t, err) blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()} - pubkey := ed25519.GenPrivKey().PubKey() + pubkey := ed25519.GenerateSecretKey().Public() pk := encoding.PubKeyToProto(pubkey) app.ValidatorUpdates = []abci.ValidatorUpdate{ {PubKey: pk, Power: 10}, @@ -993,9 +994,3 @@ func TestCreateProposalBlockPanicRecovery(t *testing.T) { // Verify mock expectations mp.AssertExpectations(t) } - -func makeStateSignature(data []byte) crypto.Sig { - var sig crypto.Sig - copy(sig[:], data) - return sig -} diff --git a/sei-tendermint/internal/state/helpers_test.go b/sei-tendermint/internal/state/helpers_test.go index 929c9909de..31c6552b25 100644 --- a/sei-tendermint/internal/state/helpers_test.go +++ b/sei-tendermint/internal/state/helpers_test.go @@ -99,10 +99,8 @@ func makeValidCommit( }, votes } -func makePrivKey(i int) ed25519.PrivKey { - var seed ed25519.Seed - copy(seed[:], fmt.Sprintf("%d", i)) - return ed25519.PrivKeyFromSeed(seed) +func makePrivKey(i int) ed25519.SecretKey { + return ed25519.TestSecretKey(fmt.Appendf(nil,"%d", i)) } func makeState(t *testing.T, nVals, height int) (sm.State, dbm.DB, map[string]types.PrivValidator) { @@ -110,10 +108,10 @@ func makeState(t *testing.T, nVals, height int) (sm.State, dbm.DB, map[string]ty privVals := make(map[string]types.PrivValidator, nVals) for i := 0; i < nVals; i++ { pk := makePrivKey(i) - valAddr := pk.PubKey().Address() + valAddr := pk.Public().Address() vals[i] = types.GenesisValidator{ Address: valAddr, - PubKey: pk.PubKey(), + PubKey: pk.Public(), Power: 1000, Name: fmt.Sprintf("test%d", i), } @@ -142,7 +140,7 @@ func makeState(t *testing.T, nVals, height int) (sm.State, dbm.DB, map[string]ty func genValSet(size int) *types.ValidatorSet { vals := make([]*types.Validator, size) for i := 0; i < size; i++ { - vals[i] = types.NewValidator(ed25519.GenPrivKey().PubKey(), 10) + vals[i] = types.NewValidator(ed25519.GenerateSecretKey().Public(), 10) } return types.NewValidatorSet(vals) } @@ -207,7 +205,7 @@ func makeHeaderPartsResponsesParams( } func randomGenesisDoc() *types.GenesisDoc { - pubkey := ed25519.GenPrivKey().PubKey() + pubkey := ed25519.GenerateSecretKey().Public() return &types.GenesisDoc{ GenesisTime: tmtime.Now(), ChainID: "abc", diff --git a/sei-tendermint/internal/state/state_test.go b/sei-tendermint/internal/state/state_test.go index 6146d447b6..34a1d7c456 100644 --- a/sei-tendermint/internal/state/state_test.go +++ b/sei-tendermint/internal/state/state_test.go @@ -117,7 +117,7 @@ func TestFinalizeBlockResponsesSaveLoad1(t *testing.T) { finalizeBlockResponses.TxResults[0] = &abci.ExecTxResult{Data: []byte("foo"), Events: nil} finalizeBlockResponses.TxResults[1] = &abci.ExecTxResult{Data: []byte("bar"), Log: "ok", Events: nil} - pbpk := encoding.PubKeyToProto(ed25519.GenPrivKey().PubKey()) + pbpk := encoding.PubKeyToProto(ed25519.GenerateSecretKey().Public()) finalizeBlockResponses.ValidatorUpdates = []abci.ValidatorUpdate{{PubKey: pbpk, Power: 10}} require.NoError(t, stateStore.SaveFinalizeBlockResponses(block.Height, finalizeBlockResponses)) @@ -393,7 +393,7 @@ func genValSetWithPowers(powers []int64) *types.ValidatorSet { totalVotePower := int64(0) for i := 0; i < size; i++ { totalVotePower += powers[i] - val := types.NewValidator(ed25519.GenPrivKey().PubKey(), powers[i]) + val := types.NewValidator(ed25519.GenerateSecretKey().Public(), powers[i]) val.ProposerPriority = mrand.Int63() vals[i] = val } @@ -444,7 +444,7 @@ func TestProposerPriorityDoesNotGetResetToZero(t *testing.T) { tearDown, _, state := setupTestCase(t) defer tearDown(t) val1VotingPower := int64(10) - val1PubKey := ed25519.GenPrivKey().PubKey() + val1PubKey := ed25519.GenerateSecretKey().Public() val1 := &types.Validator{Address: val1PubKey.Address(), PubKey: val1PubKey, VotingPower: val1VotingPower} state.Validators = types.NewValidatorSet([]*types.Validator{val1}) @@ -472,7 +472,7 @@ func TestProposerPriorityDoesNotGetResetToZero(t *testing.T) { assert.Equal(t, 0+val1VotingPower-curTotal, updatedState.NextValidators.Validators[0].ProposerPriority) // add a validator - val2PubKey := ed25519.GenPrivKey().PubKey() + val2PubKey := ed25519.GenerateSecretKey().Public() val2VotingPower := int64(100) fvp := encoding.PubKeyToProto(val2PubKey) @@ -567,7 +567,7 @@ func TestProposerPriorityProposerAlternates(t *testing.T) { tearDown, _, state := setupTestCase(t) defer tearDown(t) val1VotingPower := int64(10) - val1PubKey := ed25519.GenPrivKey().PubKey() + val1PubKey := ed25519.GenerateSecretKey().Public() val1 := &types.Validator{Address: val1PubKey.Address(), PubKey: val1PubKey, VotingPower: val1VotingPower} // reset state validators to above validator @@ -600,7 +600,7 @@ func TestProposerPriorityProposerAlternates(t *testing.T) { assert.Equal(t, val1PubKey.Address(), updatedState.NextValidators.Proposer.Address) // add a validator with the same voting power as the first - val2PubKey := ed25519.GenPrivKey().PubKey() + val2PubKey := ed25519.GenerateSecretKey().Public() fvp := encoding.PubKeyToProto(val2PubKey) updateAddVal := abci.ValidatorUpdate{PubKey: fvp, Power: val1VotingPower} validatorUpdates, err = types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{updateAddVal}) @@ -752,7 +752,7 @@ func TestLargeGenesisValidator(t *testing.T) { defer tearDown(t) genesisVotingPower := types.MaxTotalVotingPower / 1000 - genesisPubKey := ed25519.GenPrivKey().PubKey() + genesisPubKey := ed25519.GenerateSecretKey().Public() // fmt.Println("genesis addr: ", genesisPubKey.Address()) genesisVal := &types.Validator{ Address: genesisPubKey.Address(), @@ -798,7 +798,7 @@ func TestLargeGenesisValidator(t *testing.T) { // let the genesis validator "unbond", // see how long it takes until the effect wears off and both begin to alternate // see: https://github.com/tendermint/tendermint/issues/2960 - firstAddedValPubKey := ed25519.GenPrivKey().PubKey() + firstAddedValPubKey := ed25519.GenerateSecretKey().Public() firstAddedValVotingPower := int64(10) fvp := encoding.PubKeyToProto(firstAddedValPubKey) firstAddedVal := abci.ValidatorUpdate{PubKey: fvp, Power: firstAddedValVotingPower} @@ -857,7 +857,7 @@ func TestLargeGenesisValidator(t *testing.T) { // add 10 validators with the same voting power as the one added directly after genesis: for i := 0; i < 10; i++ { - addedPubKey := ed25519.GenPrivKey().PubKey() + addedPubKey := ed25519.GenerateSecretKey().Public() ap := encoding.PubKeyToProto(addedPubKey) addedVal := abci.ValidatorUpdate{PubKey: ap, Power: firstAddedValVotingPower} validatorUpdates, err := types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{addedVal}) @@ -1005,7 +1005,7 @@ func TestManyValidatorChangesSaveLoad(t *testing.T) { _, valOld := state.Validators.GetByIndex(0) var pubkeyOld = valOld.PubKey - pubkey := ed25519.GenPrivKey().PubKey() + pubkey := ed25519.GenerateSecretKey().Public() // Swap the first validator with a new one (validator set size stays the same). header, blockID, responses := makeHeaderPartsResponsesValPubKeyChange(t, state, pubkey) diff --git a/sei-tendermint/internal/state/store_test.go b/sei-tendermint/internal/state/store_test.go index 7c0a1ad9e1..c6908a1c85 100644 --- a/sei-tendermint/internal/state/store_test.go +++ b/sei-tendermint/internal/state/store_test.go @@ -191,7 +191,7 @@ func TestPruneStates(t *testing.T) { db := dbm.NewMemDB() stateStore := sm.NewStore(db) - pk := ed25519.GenPrivKey().PubKey() + pk := ed25519.GenerateSecretKey().Public() // Generate a bunch of state data. Validators change for heights ending with 3, and // parameters when ending with 5. diff --git a/sei-tendermint/internal/state/validation_test.go b/sei-tendermint/internal/state/validation_test.go index 39ff32ad4a..a70ce9c17a 100644 --- a/sei-tendermint/internal/state/validation_test.go +++ b/sei-tendermint/internal/state/validation_test.go @@ -24,6 +24,7 @@ import ( testfactory "github.com/tendermint/tendermint/internal/test/factory" "github.com/tendermint/tendermint/libs/log" tmtime "github.com/tendermint/tendermint/libs/time" + "github.com/tendermint/tendermint/libs/utils" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/types" ) @@ -97,7 +98,9 @@ func TestValidateBlockHeader(t *testing.T) { {"LastResultsHash wrong", func(block *types.Block) { block.LastResultsHash = wrongHash }}, {"EvidenceHash wrong", func(block *types.Block) { block.EvidenceHash = wrongHash }}, - {"Proposer wrong", func(block *types.Block) { block.ProposerAddress = ed25519.GenPrivKey().PubKey().Address() }}, + {"Proposer wrong", func(block *types.Block) { + block.ProposerAddress = ed25519.GenerateSecretKey().Public().Address() + }}, {"Proposer invalid", func(block *types.Block) { block.ProposerAddress = []byte("wrong size") }}, {"first LastCommit contains signatures", func(block *types.Block) { @@ -265,7 +268,8 @@ func TestValidateBlockCommit(t *testing.T) { err = badPrivVal.SignVote(ctx, chainID, b) require.NoError(t, err, "height %d", height) - goodVote.Signature, badVote.Signature = crypto.Sig(g.Signature), crypto.Sig(b.Signature) + goodVote.Signature = utils.OrPanic1(crypto.SigFromBytes(g.Signature)) + badVote.Signature = utils.OrPanic1(crypto.SigFromBytes(b.Signature)) wrongSigsCommit = &types.Commit{ Height: goodVote.Height, diff --git a/sei-tendermint/internal/store/store_test.go b/sei-tendermint/internal/store/store_test.go index f45ab3e09e..c8aaa38443 100644 --- a/sei-tendermint/internal/store/store_test.go +++ b/sei-tendermint/internal/store/store_test.go @@ -14,6 +14,7 @@ import ( "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" sm "github.com/tendermint/tendermint/internal/state" "github.com/tendermint/tendermint/internal/state/test/factory" tmrand "github.com/tendermint/tendermint/libs/rand" @@ -22,6 +23,8 @@ import ( "github.com/tendermint/tendermint/version" ) +var testKey = ed25519.TestSecretKey([]byte("test")) + // A cleanupFunc cleans up any config / test files created for a particular // test. type cleanupFunc func() @@ -33,7 +36,7 @@ func makeTestCommit(height int64, timestamp time.Time) *types.Commit { BlockIDFlag: types.BlockIDFlagCommit, ValidatorAddress: tmrand.Bytes(crypto.AddressSize), Timestamp: timestamp, - Signature: makeStoreSignature([]byte("Signature")), + Signature: testKey.Sign([]byte("Signature")), }} return &types.Commit{ Height: height, @@ -45,12 +48,6 @@ func makeTestCommit(height int64, timestamp time.Time) *types.Commit { } } -func makeStoreSignature(data []byte) crypto.Sig { - var sig crypto.Sig - copy(sig[:], data) - return sig -} - func makeStateAndBlockStore(dir string) (sm.State, *BlockStore, cleanupFunc, error) { cfg, err := config.ResetTestRoot(dir, "blockchain_reactor_test") if err != nil { diff --git a/sei-tendermint/light/helpers_test.go b/sei-tendermint/light/helpers_test.go index 1959d1595a..7464b2d2ba 100644 --- a/sei-tendermint/light/helpers_test.go +++ b/sei-tendermint/light/helpers_test.go @@ -28,7 +28,7 @@ type privKeys []crypto.PrivKey func genPrivKeys(n int) privKeys { res := make(privKeys, n) for i := range res { - res[i] = ed25519.GenPrivKey() + res[i] = ed25519.GenerateSecretKey() } return res } @@ -46,7 +46,7 @@ func (pkz privKeys) Extend(n int) privKeys { func (pkz privKeys) ToValidators(init, inc int64) *types.ValidatorSet { res := make([]*types.Validator, len(pkz)) for i, k := range pkz { - res[i] = types.NewValidator(k.PubKey(), init+int64(i)*inc) + res[i] = types.NewValidator(k.Public(), init+int64(i)*inc) } return types.NewValidatorSet(res) } @@ -82,7 +82,7 @@ func (pkz privKeys) signHeader(t testing.TB, header *types.Header, valSet *types func makeVote(t testing.TB, header *types.Header, valset *types.ValidatorSet, key crypto.PrivKey, blockID types.BlockID) *types.Vote { t.Helper() - addr := key.PubKey().Address() + addr := key.Public().Address() idx, _ := valset.GetByAddress(addr) vote := &types.Vote{ ValidatorAddress: addr, diff --git a/sei-tendermint/node/node_test.go b/sei-tendermint/node/node_test.go index 20b96c0362..94a9b42943 100644 --- a/sei-tendermint/node/node_test.go +++ b/sei-tendermint/node/node_test.go @@ -34,6 +34,7 @@ import ( tmrand "github.com/tendermint/tendermint/libs/rand" "github.com/tendermint/tendermint/libs/service" tmtime "github.com/tendermint/tendermint/libs/time" + "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/privval" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/types" @@ -162,7 +163,7 @@ func TestNodeSetPrivValTCP(t *testing.T) { defer os.RemoveAll(cfg.RootDir) cfg.PrivValidator.ListenAddr = addr - dialer := privval.DialTCPFn(addr, 100*time.Millisecond, ed25519.GenPrivKey()) + dialer := privval.DialTCPFn(addr, 100*time.Millisecond, ed25519.GenerateSecretKey()) dialerEndpoint := privval.NewSignerDialerEndpoint(logger, dialer) privval.SignerDialerEndpointTimeoutReadWrite(100 * time.Millisecond)(dialerEndpoint) @@ -536,7 +537,7 @@ func TestMaxProposalBlockSize(t *testing.T) { } vpb := vote.ToProto() require.NoError(t, privVals[i].SignVote(ctx, state.ChainID, vpb)) - vote.Signature = crypto.Sig(vpb.Signature) + vote.Signature = utils.OrPanic1(crypto.SigFromBytes(vpb.Signature)) added, err := voteSet.AddVote(vote) require.NoError(t, err) @@ -711,8 +712,8 @@ func state(t *testing.T, nVals int, height int64) (sm.State, dbm.DB, []types.Pri privVal := types.NewMockPV() privVals[i] = privVal vals[i] = types.GenesisValidator{ - Address: privVal.PrivKey.PubKey().Address(), - PubKey: privVal.PrivKey.PubKey(), + Address: privVal.PrivKey.Public().Address(), + PubKey: privVal.PrivKey.Public(), Power: 1000, Name: fmt.Sprintf("test%d", i), } diff --git a/sei-tendermint/privval/file.go b/sei-tendermint/privval/file.go index fb7cd67acd..205dc0de28 100644 --- a/sei-tendermint/privval/file.go +++ b/sei-tendermint/privval/file.go @@ -215,10 +215,7 @@ func GenFilePV(keyFilePath, stateFilePath, keyType string) (*FilePV, error) { if keyType != "" && keyType != types.ABCIPubKeyTypeEd25519 { return nil, fmt.Errorf("key type: %s is not supported", keyType) } - privKey, err := ed25519.GenerateSecretKey() - if err != nil { - return nil, err - } + privKey := ed25519.GenerateSecretKey() return NewFilePV(privKey, keyFilePath, stateFilePath), nil } diff --git a/sei-tendermint/privval/file_test.go b/sei-tendermint/privval/file_test.go index 156a268b0c..6b16775260 100644 --- a/sei-tendermint/privval/file_test.go +++ b/sei-tendermint/privval/file_test.go @@ -108,11 +108,15 @@ func TestUnmarshalValidatorState(t *testing.T) { func TestUnmarshalValidatorKey(t *testing.T) { // create some fixed values - privKey := ed25519.GenPrivKey() - pubKey := privKey.PubKey() + privKey := ed25519.GenerateSecretKey() + pubKey := privKey.Public() addr := pubKey.Address() - pubB64 := base64.StdEncoding.EncodeToString(pubKey[:]) - privB64 := base64.StdEncoding.EncodeToString(privKey.SecretBytes()) + pubB64 := base64.StdEncoding.EncodeToString(pubKey.Bytes()) + privJSON, err := json.Marshal(privKey) + require.NoError(t, err) + var privBytes []byte + require.NoError(t, json.Unmarshal(privJSON, &privBytes)) + privB64 := base64.StdEncoding.EncodeToString(privBytes) serialized := fmt.Sprintf(`{ "address": "%s", @@ -127,7 +131,7 @@ func TestUnmarshalValidatorKey(t *testing.T) { }`, addr, pubB64, privB64) val := FilePVKey{} - err := tmjson.Unmarshal([]byte(serialized), &val) + err = tmjson.Unmarshal([]byte(serialized), &val) require.NoError(t, err) // make sure the values match diff --git a/sei-tendermint/privval/grpc/client_test.go b/sei-tendermint/privval/grpc/client_test.go index cd2f6ba3b4..4b4fc64517 100644 --- a/sei-tendermint/privval/grpc/client_test.go +++ b/sei-tendermint/privval/grpc/client_test.go @@ -60,7 +60,7 @@ func TestSignerClient_GetPubKey(t *testing.T) { pk, err := client.GetPubKey(ctx) require.NoError(t, err) - assert.Equal(t, mockPV.PrivKey.PubKey(), pk) + assert.Equal(t, mockPV.PrivKey.Public(), pk) } func TestSignerClient_SignVote(t *testing.T) { diff --git a/sei-tendermint/privval/grpc/server_test.go b/sei-tendermint/privval/grpc/server_test.go index 200a65c04e..4feb642e2a 100644 --- a/sei-tendermint/privval/grpc/server_test.go +++ b/sei-tendermint/privval/grpc/server_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/libs/log" tmrand "github.com/tendermint/tendermint/libs/rand" tmgrpc "github.com/tendermint/tendermint/privval/grpc" @@ -18,11 +19,7 @@ import ( const ChainID = "123" -func makeSig(data []byte) crypto.Sig { - var sig crypto.Sig - copy(sig[:], data) - return sig -} +var testKey = ed25519.TestSecretKey([]byte("test")) func TestGetPubKey(t *testing.T) { @@ -94,7 +91,7 @@ func TestSignVote(t *testing.T) { Timestamp: ts, ValidatorAddress: valAddr, ValidatorIndex: 1, - Signature: makeSig([]byte("signed")), + Signature: testKey.Sign([]byte("signed")), }, want: &types.Vote{ Type: tmproto.PrecommitType, Height: 1, @@ -103,7 +100,7 @@ func TestSignVote(t *testing.T) { Timestamp: ts, ValidatorAddress: valAddr, ValidatorIndex: 1, - Signature: makeSig([]byte("signed")), + Signature: testKey.Sign([]byte("signed")), }, err: true}, } @@ -164,7 +161,7 @@ func TestSignProposal(t *testing.T) { POLRound: 2, BlockID: types.BlockID{Hash: hash, PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2}}, Timestamp: ts, - Signature: makeSig([]byte("signed")), + Signature: testKey.Sign([]byte("signed")), }, want: &types.Proposal{ Type: tmproto.ProposalType, Height: 1, @@ -172,7 +169,7 @@ func TestSignProposal(t *testing.T) { POLRound: 2, BlockID: types.BlockID{Hash: hash, PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2}}, Timestamp: ts, - Signature: makeSig([]byte("signed")), + Signature: testKey.Sign([]byte("signed")), }, err: true}, } diff --git a/sei-tendermint/privval/msgs_test.go b/sei-tendermint/privval/msgs_test.go index 23608e08cf..ea19c774fa 100644 --- a/sei-tendermint/privval/msgs_test.go +++ b/sei-tendermint/privval/msgs_test.go @@ -51,7 +51,7 @@ func exampleProposal() *types.Proposal { } func TestPrivvalVectors(t *testing.T) { - pk := ed25519.PrivKeyFromSeed(ed25519.Seed{1, 2, 3, 4}).PubKey() + pk := ed25519.TestSecretKey([]byte{1, 2, 3, 4}).Public() ppk := encoding.PubKeyToProto(pk) // Generate a simple vote diff --git a/sei-tendermint/privval/signer_client_test.go b/sei-tendermint/privval/signer_client_test.go index 11f639d94e..3c0113ad8a 100644 --- a/sei-tendermint/privval/signer_client_test.go +++ b/sei-tendermint/privval/signer_client_test.go @@ -11,6 +11,7 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/libs/log" tmrand "github.com/tendermint/tendermint/libs/rand" cryptoproto "github.com/tendermint/tendermint/proto/tendermint/crypto" @@ -62,11 +63,7 @@ func getSignerTestCases(ctx context.Context, t *testing.T, logger log.Logger) [] return testCases } -func makeSig(data []byte) crypto.Sig { - var sig crypto.Sig - copy(sig[:], data) - return sig -} +var testKey = ed25519.TestSecretKey([]byte("test")) func TestSignerClose(t *testing.T) { t.Cleanup(leaktest.Check(t)) @@ -335,7 +332,7 @@ func TestSignerSignProposalErrors(t *testing.T) { POLRound: 2, BlockID: types.BlockID{Hash: hash, PartSetHeader: types.PartSetHeader{Hash: hash, Total: 2}}, Timestamp: ts, - Signature: makeSig([]byte("signature")), + Signature: testKey.Sign([]byte("signature")), } err := tc.signerClient.SignProposal(ctx, tc.chainID, proposal.ToProto()) @@ -374,7 +371,7 @@ func TestSignerSignVoteErrors(t *testing.T) { Timestamp: ts, ValidatorAddress: valAddr, ValidatorIndex: 1, - Signature: makeSig([]byte("signature")), + Signature: testKey.Sign([]byte("signature")), } // Replace signer service privval with one that always fails diff --git a/sei-tendermint/privval/signer_listener_endpoint_test.go b/sei-tendermint/privval/signer_listener_endpoint_test.go index 8419530da7..81d71b76bf 100644 --- a/sei-tendermint/privval/signer_listener_endpoint_test.go +++ b/sei-tendermint/privval/signer_listener_endpoint_test.go @@ -69,7 +69,7 @@ func TestSignerRemoteRetryTCPOnly(t *testing.T) { }(ln, attemptCh) dialerEndpoint := NewSignerDialerEndpoint(logger, - DialTCPFn(ln.Addr().String(), testTimeoutReadWrite, ed25519.GenPrivKey()), + DialTCPFn(ln.Addr().String(), testTimeoutReadWrite, ed25519.GenerateSecretKey()), ) SignerDialerEndpointTimeoutReadWrite(time.Millisecond)(dialerEndpoint) SignerDialerEndpointConnRetries(retries)(dialerEndpoint) @@ -160,7 +160,7 @@ func newSignerListenerEndpoint(t *testing.T, logger log.Logger, addr string, tim UnixListenerTimeoutReadWrite(timeoutReadWrite)(unixLn) listener = unixLn } else { - tcpLn := NewTCPListener(ln, ed25519.GenPrivKey()) + tcpLn := NewTCPListener(ln, ed25519.GenerateSecretKey()) TCPListenerTimeoutAccept(testTimeoutAccept)(tcpLn) TCPListenerTimeoutReadWrite(timeoutReadWrite)(tcpLn) listener = tcpLn diff --git a/sei-tendermint/privval/socket_dialers_test.go b/sei-tendermint/privval/socket_dialers_test.go index 7ec8fe30f6..3ef8a4886e 100644 --- a/sei-tendermint/privval/socket_dialers_test.go +++ b/sei-tendermint/privval/socket_dialers_test.go @@ -30,7 +30,7 @@ func getDialerTestCases(t *testing.T) []dialerTestCase { return []dialerTestCase{ { addr: tcpAddr, - dialer: DialTCPFn(tcpAddr, testTimeoutReadWrite, ed25519.GenPrivKey()), + dialer: DialTCPFn(tcpAddr, testTimeoutReadWrite, ed25519.GenerateSecretKey()), }, { addr: unixAddr, @@ -42,7 +42,7 @@ func getDialerTestCases(t *testing.T) []dialerTestCase { func TestIsConnTimeoutForFundamentalTimeouts(t *testing.T) { // Generate a networking timeout tcpAddr := getFreeLocalhostAddrPort(t) - dialer := DialTCPFn(tcpAddr, time.Millisecond, ed25519.GenPrivKey()) + dialer := DialTCPFn(tcpAddr, time.Millisecond, ed25519.GenerateSecretKey()) _, err := dialer() assert.Error(t, err) assert.True(t, IsConnTimeout(err)) @@ -50,7 +50,7 @@ func TestIsConnTimeoutForFundamentalTimeouts(t *testing.T) { func TestIsConnTimeoutForWrappedConnTimeouts(t *testing.T) { tcpAddr := getFreeLocalhostAddrPort(t) - dialer := DialTCPFn(tcpAddr, time.Millisecond, ed25519.GenPrivKey()) + dialer := DialTCPFn(tcpAddr, time.Millisecond, ed25519.GenerateSecretKey()) _, err := dialer() assert.Error(t, err) err = fmt.Errorf("%v: %w", err, ErrConnectionTimeout) diff --git a/sei-tendermint/privval/socket_listeners_test.go b/sei-tendermint/privval/socket_listeners_test.go index ff9c24cab9..4255ca334c 100644 --- a/sei-tendermint/privval/socket_listeners_test.go +++ b/sei-tendermint/privval/socket_listeners_test.go @@ -9,16 +9,6 @@ import ( "github.com/tendermint/tendermint/crypto/ed25519" ) -//------------------------------------------- -// helper funcs - -func newPrivKey() ed25519.PrivKey { - return ed25519.GenPrivKey() -} - -//------------------------------------------- -// tests - type listenerTestCase struct { description string // For test reporting purposes. listener net.Listener @@ -47,13 +37,13 @@ func tcpListenerTestCase(t *testing.T, timeoutAccept, timeoutReadWrite time.Dura t.Fatal(err) } - tcpLn := NewTCPListener(ln, newPrivKey()) + tcpLn := NewTCPListener(ln, ed25519.GenerateSecretKey()) TCPListenerTimeoutAccept(timeoutAccept)(tcpLn) TCPListenerTimeoutReadWrite(timeoutReadWrite)(tcpLn) return listenerTestCase{ description: "TCP", listener: tcpLn, - dialer: DialTCPFn(ln.Addr().String(), testTimeoutReadWrite, newPrivKey()), + dialer: DialTCPFn(ln.Addr().String(), testTimeoutReadWrite, ed25519.GenerateSecretKey()), } } diff --git a/sei-tendermint/privval/utils.go b/sei-tendermint/privval/utils.go index 6de012ae5e..2d345e05a0 100644 --- a/sei-tendermint/privval/utils.go +++ b/sei-tendermint/privval/utils.go @@ -43,11 +43,7 @@ func NewSignerListener(listenAddr string, logger log.Logger) (*SignerListenerEnd listener = NewUnixListener(ln) case "tcp": // TODO: persist this key so external signer can actually authenticate us - privKey, err := ed25519.GenerateSecretKey() - if err != nil { - return nil, err - } - listener = NewTCPListener(ln, privKey) + listener = NewTCPListener(ln, ed25519.GenerateSecretKey()) default: panic("invalid protocol: " + protocol) // semantically unreachable } diff --git a/sei-tendermint/rpc/client/rpc_test.go b/sei-tendermint/rpc/client/rpc_test.go index 7c0d953b70..3cb97ffd28 100644 --- a/sei-tendermint/rpc/client/rpc_test.go +++ b/sei-tendermint/rpc/client/rpc_test.go @@ -548,7 +548,7 @@ func TestClientMethodCalls(t *testing.T) { err = client.WaitForHeight(ctx, c, status.SyncInfo.LatestBlockHeight+2, nil) require.NoError(t, err) - result2, err := c.ABCIQuery(ctx, "/val", pv.Key.PubKey[:]) + result2, err := c.ABCIQuery(ctx, "/val", pv.Key.PubKey.Bytes()) require.NoError(t, err) qres := result2.Response require.True(t, qres.IsOK()) diff --git a/sei-tendermint/test/e2e/node/main.go b/sei-tendermint/test/e2e/node/main.go index 391e2150bb..063e010286 100644 --- a/sei-tendermint/test/e2e/node/main.go +++ b/sei-tendermint/test/e2e/node/main.go @@ -227,10 +227,7 @@ func startSigner(ctx context.Context, logger log.Logger, cfg *Config) error { var dialFn privval.SocketDialer switch protocol { case "tcp": - privKey, err := ed25519.GenerateSecretKey() - if err != nil { - return err - } + privKey := ed25519.GenerateSecretKey() dialFn = privval.DialTCPFn(address, 3*time.Second, privKey) case "unix": dialFn = privval.DialUnixFn(address) diff --git a/sei-tendermint/test/e2e/runner/setup.go b/sei-tendermint/test/e2e/runner/setup.go index ae2a179ea2..e32bfd1371 100644 --- a/sei-tendermint/test/e2e/runner/setup.go +++ b/sei-tendermint/test/e2e/runner/setup.go @@ -122,10 +122,7 @@ func Setup(logger log.Logger, testnet *e2e.Testnet) error { // Set up a dummy validator. Tendermint requires a file PV even when not used, so we // give it a dummy such that it will fail if it actually tries to use it. - dummyKey, err := ed25519.GenerateSecretKey() - if err != nil { - return err - } + dummyKey := ed25519.GenerateSecretKey() err = (privval.NewFilePV(dummyKey, filepath.Join(nodeDir, PrivvalDummyKeyFile), filepath.Join(nodeDir, PrivvalDummyStateFile), diff --git a/sei-tendermint/test/e2e/tests/validator_test.go b/sei-tendermint/test/e2e/tests/validator_test.go index 6d7e68c68d..faac2782e6 100644 --- a/sei-tendermint/test/e2e/tests/validator_test.go +++ b/sei-tendermint/test/e2e/tests/validator_test.go @@ -67,7 +67,7 @@ func TestValidator_Propose(t *testing.T) { if node.Mode != e2e.ModeValidator { return } - address := node.PrivvalKey.PubKey().Address() + address := node.PrivvalKey.Public().Address() valSchedule := newValidatorSchedule(*node.Testnet) expectCount := 0 @@ -100,7 +100,7 @@ func TestValidator_Sign(t *testing.T) { if node.Mode != e2e.ModeValidator { return } - address := node.PrivvalKey.PubKey().Address() + address := node.PrivvalKey.Public().Address() valSchedule := newValidatorSchedule(*node.Testnet) expectCount := 0 @@ -172,7 +172,7 @@ func (s *validatorSchedule) Increment(heights int64) error { func makeVals(valMap map[*e2e.Node]int64) []*types.Validator { vals := make([]*types.Validator, 0, len(valMap)) for node, power := range valMap { - vals = append(vals, types.NewValidator(node.PrivvalKey.PubKey(), power)) + vals = append(vals, types.NewValidator(node.PrivvalKey.Public(), power)) } return vals } diff --git a/sei-tendermint/test/fuzz/tests/p2p_secretconnection_test.go b/sei-tendermint/test/fuzz/tests/p2p_secretconnection_test.go index 972acdf80e..7c7cb38ed8 100644 --- a/sei-tendermint/test/fuzz/tests/p2p_secretconnection_test.go +++ b/sei-tendermint/test/fuzz/tests/p2p_secretconnection_test.go @@ -84,10 +84,10 @@ func makeKVStoreConnPair() (fooConn, barConn kvstoreConn) { func makeSecretConnPair() (fooSecConn, barSecConn *sc.SecretConnection) { var ( fooConn, barConn = makeKVStoreConnPair() - fooPrvKey = ed25519.GenPrivKey() - fooPubKey = fooPrvKey.PubKey() - barPrvKey = ed25519.GenPrivKey() - barPubKey = barPrvKey.PubKey() + fooPrvKey = ed25519.GenerateSecretKey() + fooPubKey = fooPrvKey.Public() + barPrvKey = ed25519.GenerateSecretKey() + barPubKey = barPrvKey.Public() ) // Make connections from both sides in parallel. diff --git a/sei-tendermint/types/block.go b/sei-tendermint/types/block.go index 40e3c868fd..637d7059a7 100644 --- a/sei-tendermint/types/block.go +++ b/sei-tendermint/types/block.go @@ -721,6 +721,7 @@ func (cs CommitSig) ValidateBasic() error { ) } // NOTE: Timestamp validation is subtle and handled elsewhere. + // TODO: check that signature is present } return nil diff --git a/sei-tendermint/types/block_test.go b/sei-tendermint/types/block_test.go index 80a9be8aec..4e8f224342 100644 --- a/sei-tendermint/types/block_test.go +++ b/sei-tendermint/types/block_test.go @@ -19,11 +19,13 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/merkle" "github.com/tendermint/tendermint/libs/bits" "github.com/tendermint/tendermint/libs/bytes" tmrand "github.com/tendermint/tendermint/libs/rand" tmtime "github.com/tendermint/tendermint/libs/time" + "github.com/tendermint/tendermint/libs/utils" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" tmversion "github.com/tendermint/tendermint/proto/tendermint/version" "github.com/tendermint/tendermint/version" @@ -34,6 +36,8 @@ func TestMain(m *testing.M) { os.Exit(code) } +var testKey = ed25519.TestSecretKey([]byte("test")) + func TestBlockAddEvidence(t *testing.T) { ctx := t.Context() @@ -280,7 +284,7 @@ func TestCommitValidateBasic(t *testing.T) { expectErr bool }{ {"Random Commit", func(com *Commit) {}, false}, - {"Incorrect signature", func(com *Commit) { com.Signatures[0].Signature = crypto.Sig{} }, false}, + {"Incorrect signature", func(com *Commit) { com.Signatures[0].Signature = testKey.Sign(nil) }, false}, {"Incorrect height", func(com *Commit) { com.Height = int64(-100) }, true}, {"Incorrect round", func(com *Commit) { com.Round = -100 }, true}, } @@ -301,9 +305,10 @@ func TestMaxCommitBytes(t *testing.T) { // year int, month Month, day, hour, min, sec, nsec int, loc *Location timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC) - sig := crypto.Sig{} - _, err := io.ReadFull(rand.Reader, sig[:]) + sigBytes := make([]byte, 64) + _, err := io.ReadFull(rand.Reader, sigBytes) require.NoError(t, err) + sig := testKey.Sign(sigBytes) cs := CommitSig{ BlockIDFlag: BlockIDFlagNil, ValidatorAddress: crypto.AddressHash([]byte("validator_address")), @@ -570,7 +575,7 @@ func TestVoteSetToCommit(t *testing.T) { } v := vote.ToProto() require.NoError(t, vals[i].SignVote(ctx, voteSet.ChainID(), v)) - vote.Signature = crypto.Sig(v.Signature) + vote.Signature = utils.OrPanic1(crypto.SigFromBytes(v.Signature)) added, err := voteSet.AddVote(vote) require.NoError(t, err) require.True(t, added) @@ -944,7 +949,7 @@ func TestCommitSig_ValidateBasic(t *testing.T) { }, { "BlockIDFlagAbsent signatures present", - CommitSig{BlockIDFlag: BlockIDFlagAbsent, Signature: crypto.Sig{0xAA}}, + CommitSig{BlockIDFlag: BlockIDFlagAbsent, Signature: testKey.Sign([]byte{0xAA})}, true, "signature is present", }, { @@ -962,7 +967,7 @@ func TestCommitSig_ValidateBasic(t *testing.T) { CommitSig{ BlockIDFlag: BlockIDFlagCommit, ValidatorAddress: make([]byte, crypto.AddressSize), - Signature: crypto.Sig{}, + Signature: testKey.Sign(nil), }, true, "signature is missing", }, @@ -971,7 +976,7 @@ func TestCommitSig_ValidateBasic(t *testing.T) { CommitSig{ BlockIDFlag: BlockIDFlagCommit, ValidatorAddress: make([]byte, crypto.AddressSize), - Signature: crypto.Sig{}, + Signature: testKey.Sign(nil), }, false, "", }, @@ -1306,7 +1311,7 @@ func TestCommit_ValidateBasic(t *testing.T) { { BlockIDFlag: BlockIDFlagCommit, ValidatorAddress: make([]byte, crypto.AddressSize), - Signature: crypto.Sig{}, + Signature: testKey.Sign(nil), }, }, }, diff --git a/sei-tendermint/types/evidence_test.go b/sei-tendermint/types/evidence_test.go index 50dedbe190..41a0a7b535 100644 --- a/sei-tendermint/types/evidence_test.go +++ b/sei-tendermint/types/evidence_test.go @@ -14,6 +14,7 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" tmrand "github.com/tendermint/tendermint/libs/rand" + "github.com/tendermint/tendermint/libs/utils" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/version" ) @@ -313,7 +314,7 @@ func makeVote( err = val.SignVote(ctx, chainID, vpb) require.NoError(t, err) - v.Signature = crypto.Sig(vpb.Signature) + v.Signature = utils.OrPanic1(crypto.SigFromBytes(vpb.Signature)) return v } @@ -383,7 +384,7 @@ func TestEvidenceVectors(t *testing.T) { // Votes for duplicateEvidence val := NewMockPV() - val.PrivKey = ed25519.PrivKeyFromSeed(ed25519.Seed{1, 2, 3, 4}) // deterministic key + val.PrivKey = ed25519.TestSecretKey([]byte{1, 2, 3, 4}) // deterministic key blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash"))) blockID2 := makeBlockID(crypto.Checksum([]byte("blockhash2")), math.MaxInt32, crypto.Checksum([]byte("partshash"))) const chainID = "mychain" diff --git a/sei-tendermint/types/genesis_test.go b/sei-tendermint/types/genesis_test.go index 7223581118..527b5d93b9 100644 --- a/sei-tendermint/types/genesis_test.go +++ b/sei-tendermint/types/genesis_test.go @@ -89,7 +89,7 @@ func TestBasicGenesisDoc(t *testing.T) { _, err := GenesisDocFromJSON(genDocBytes) assert.NoError(t, err, "expected no error for good genDoc json") - pubkey := ed25519.GenPrivKey().PubKey() + pubkey := ed25519.GenerateSecretKey().Public() // create a base gendoc from struct baseGenDoc := &GenesisDoc{ ChainID: "abc", @@ -165,7 +165,7 @@ func TestGenesisValidatorHash(t *testing.T) { } func randomGenesisDoc() *GenesisDoc { - pubkey := ed25519.GenPrivKey().PubKey() + pubkey := ed25519.GenerateSecretKey().Public() return &GenesisDoc{ GenesisTime: tmtime.Now(), ChainID: "abc", diff --git a/sei-tendermint/types/node_info_test.go b/sei-tendermint/types/node_info_test.go index 0fdbcc96a7..2bfb2fbcb4 100644 --- a/sei-tendermint/types/node_info_test.go +++ b/sei-tendermint/types/node_info_test.go @@ -101,7 +101,7 @@ func TestNodeInfoValidate(t *testing.T) { } func testNodeID() NodeID { - return NodeIDFromPubKey(ed25519.GenPrivKey().PubKey()) + return NodeIDFromPubKey(ed25519.GenerateSecretKey().Public()) } func testNodeInfo(t *testing.T, id NodeID, name string) NodeInfo { diff --git a/sei-tendermint/types/node_key.go b/sei-tendermint/types/node_key.go index 32fd264b51..e930dfaf2b 100644 --- a/sei-tendermint/types/node_key.go +++ b/sei-tendermint/types/node_key.go @@ -87,10 +87,7 @@ func LoadOrGenNodeKey(filePath string) (NodeKey, error) { // GenNodeKey generates a new node key. func GenNodeKey() NodeKey { - privKey, err := ed25519.GenerateSecretKey() - if err != nil { - panic(err) - } + privKey := ed25519.GenerateSecretKey() return NodeKey{ ID: NodeIDFromPubKey(privKey.Public()), PrivKey: privKey, diff --git a/sei-tendermint/types/priv_validator.go b/sei-tendermint/types/priv_validator.go index 7c6fd79da8..fac6643bce 100644 --- a/sei-tendermint/types/priv_validator.go +++ b/sei-tendermint/types/priv_validator.go @@ -67,7 +67,7 @@ type MockPV struct { } func NewMockPV() MockPV { - return MockPV{mustGenerateSecretKey(), false, false} + return MockPV{ed25519.GenerateSecretKey(), false, false} } // NewMockPVWithParams allows one to create a MockPV instance, but with finer @@ -153,13 +153,5 @@ func (pv *ErroringMockPV) SignProposal(ctx context.Context, chainID string, prop // NewErroringMockPV returns a MockPV that fails on each signing request. Again, for testing only. func NewErroringMockPV() *ErroringMockPV { - return &ErroringMockPV{MockPV{mustGenerateSecretKey(), false, false}} -} - -func mustGenerateSecretKey() crypto.PrivKey { - key, err := ed25519.GenerateSecretKey() - if err != nil { - panic(err) - } - return key + return &ErroringMockPV{MockPV{ed25519.GenerateSecretKey(), false, false}} } diff --git a/sei-tendermint/types/proposal_test.go b/sei-tendermint/types/proposal_test.go index 1f666f03ed..0ce742f786 100644 --- a/sei-tendermint/types/proposal_test.go +++ b/sei-tendermint/types/proposal_test.go @@ -15,6 +15,7 @@ import ( "github.com/tendermint/tendermint/internal/libs/protoio" tmrand "github.com/tendermint/tendermint/libs/rand" tmtime "github.com/tendermint/tendermint/libs/time" + "github.com/tendermint/tendermint/libs/utils" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) @@ -40,12 +41,6 @@ func generateHeader() Header { } } -func makeSig(data []byte) crypto.Sig { - var sig crypto.Sig - copy(sig[:], data) - return sig -} - func getTestProposal(t testing.TB) *Proposal { t.Helper() @@ -96,7 +91,7 @@ func TestProposalVerifySignature(t *testing.T) { // sign it require.NoError(t, privVal.SignProposal(ctx, "test_chain_id", p)) - prop.Signature = crypto.Sig(p.Signature) + prop.Signature = utils.OrPanic1(crypto.SigFromBytes(p.Signature)) // verify the same proposal require.NoError(t, pubKey.Verify(signBytes, prop.Signature)) @@ -181,7 +176,7 @@ func TestProposalValidateBasic(t *testing.T) { p.BlockID = BlockID{[]byte{1, 2, 3}, PartSetHeader{111, []byte("blockparts")}} }, true}, {"Invalid Signature", func(p *Proposal) { - p.Signature = crypto.Sig{} + p.Signature = testKey.Sign(nil) }, true}, } blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash"))) @@ -199,7 +194,7 @@ func TestProposalValidateBasic(t *testing.T) { generateHeader(), &Commit{}, EvidenceList{}, pubKey.Address()) p := prop.ToProto() require.NoError(t, privVal.SignProposal(ctx, "test_chain_id", p)) - prop.Signature = crypto.Sig(p.Signature) + prop.Signature = utils.OrPanic1(crypto.SigFromBytes(p.Signature)) tc.malleateProposal(prop) assert.Equal(t, tc.expectErr, prop.ValidateBasic() != nil, "Validate Basic had an unexpected result") }) @@ -209,7 +204,7 @@ func TestProposalValidateBasic(t *testing.T) { func TestProposalProtoBuf(t *testing.T) { var txKeys []TxKey proposal := NewProposal(1, 2, 3, makeBlockID([]byte("hash"), 2, []byte("part_set_hash")), tmtime.Now(), txKeys, generateHeader(), &Commit{Signatures: []CommitSig{}}, EvidenceList{}, crypto.Address("testaddr")) - proposal.Signature = makeSig([]byte("sig")) + proposal.Signature = testKey.Sign([]byte("sig")) proposal2 := NewProposal(1, 2, 3, BlockID{}, tmtime.Now(), txKeys, generateHeader(), &Commit{Signatures: []CommitSig{}}, EvidenceList{}, crypto.Address("testaddr")) testCases := []struct { diff --git a/sei-tendermint/types/protobuf_test.go b/sei-tendermint/types/protobuf_test.go index 37e4607a13..f931da0f69 100644 --- a/sei-tendermint/types/protobuf_test.go +++ b/sei-tendermint/types/protobuf_test.go @@ -13,7 +13,7 @@ import ( ) func TestABCIPubKey(t *testing.T) { - pkEd := ed25519.GenPrivKey().PubKey() + pkEd := ed25519.GenerateSecretKey().Public() err := testABCIPubKey(t, pkEd) assert.NoError(t, err) } @@ -27,7 +27,7 @@ func testABCIPubKey(t *testing.T, pk crypto.PubKey) error { } func TestABCIValidators(t *testing.T) { - pkEd := ed25519.GenPrivKey().PubKey() + pkEd := ed25519.GenerateSecretKey().Public() // correct validator tmValExpected := NewValidator(pkEd, 10) @@ -52,7 +52,7 @@ func TestABCIValidators(t *testing.T) { } func TestABCIValidatorWithoutPubKey(t *testing.T) { - pkEd := ed25519.GenPrivKey().PubKey() + pkEd := ed25519.GenerateSecretKey().Public() abciVal := TM2PB.Validator(NewValidator(pkEd, 10)) diff --git a/sei-tendermint/types/validation_test.go b/sei-tendermint/types/validation_test.go index e5fd3b8f05..84e8d31f4d 100644 --- a/sei-tendermint/types/validation_test.go +++ b/sei-tendermint/types/validation_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/libs/utils/require" tmmath "github.com/tendermint/tendermint/libs/math" @@ -117,7 +118,7 @@ func TestValidatorSet_VerifyCommit_All(t *testing.T) { v := vote.ToProto() require.NoError(t, vals[vi%len(vals)].SignVote(ctx, tc.chainID, v)) - vote.Signature = crypto.Sig(v.Signature) + vote.Signature = utils.OrPanic1(crypto.SigFromBytes(v.Signature)) sigs[vi] = vote.CommitSig() @@ -177,7 +178,7 @@ func TestValidatorSet_VerifyCommit_CheckAllSignatures(t *testing.T) { vote := voteSet.GetByIndex(3) v := vote.ToProto() require.NoError(t, vals[3].SignVote(ctx, "CentaurusA", v)) - vote.Signature = crypto.Sig(v.Signature) + vote.Signature = utils.OrPanic1(crypto.SigFromBytes(v.Signature)) commit.Signatures[3] = vote.CommitSig() err = valSet.VerifyCommit(chainID, blockID, h, commit) @@ -205,7 +206,7 @@ func TestValidatorSet_VerifyCommitLight_ReturnsAsSoonAsMajorityOfVotingPowerSign vote := voteSet.GetByIndex(3) v := vote.ToProto() require.NoError(t, vals[3].SignVote(ctx, "CentaurusA", v)) - vote.Signature = crypto.Sig(v.Signature) + vote.Signature = utils.OrPanic1(crypto.SigFromBytes(v.Signature)) commit.Signatures[3] = vote.CommitSig() err = valSet.VerifyCommitLight(chainID, blockID, h, commit) @@ -230,7 +231,7 @@ func TestValidatorSet_VerifyCommitLightTrusting_ReturnsAsSoonAsTrustLevelOfVotin vote := voteSet.GetByIndex(2) v := vote.ToProto() require.NoError(t, vals[2].SignVote(ctx, "CentaurusA", v)) - vote.Signature = crypto.Sig(v.Signature) + vote.Signature = utils.OrPanic1(crypto.SigFromBytes(v.Signature)) commit.Signatures[2] = vote.CommitSig() err = valSet.VerifyCommitLightTrusting(chainID, commit, tmmath.Fraction{Numerator: 1, Denominator: 3}) diff --git a/sei-tendermint/types/validator_set_test.go b/sei-tendermint/types/validator_set_test.go index f24049eea2..ebcf1272c7 100644 --- a/sei-tendermint/types/validator_set_test.go +++ b/sei-tendermint/types/validator_set_test.go @@ -18,7 +18,6 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" tmmath "github.com/tendermint/tendermint/libs/math" - tmrand "github.com/tendermint/tendermint/libs/rand" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) @@ -208,8 +207,8 @@ func BenchmarkValidatorSetCopy(b *testing.B) { b.StopTimer() vset := NewValidatorSet([]*Validator{}) for i := 0; i < 1000; i++ { - privKey := ed25519.GenPrivKey() - pubKey := privKey.PubKey() + privKey := ed25519.GenerateSecretKey() + pubKey := privKey.Public() val := NewValidator(pubKey, 10) err := vset.UpdateWithChangeSet([]*Validator{val}) require.NoError(b, err) @@ -348,7 +347,7 @@ func TestProposerSelection3(t *testing.T) { proposerOrder := make([]*Validator, 4) for i := 0; i < 4; i++ { // need to give all validators to have keys - pk := ed25519.GenPrivKey().PubKey() + pk := ed25519.GenerateSecretKey().Public() vset.Validators[i].PubKey = pk proposerOrder[i] = vset.GetProposer() vset.IncrementProposerPriority(1) @@ -403,7 +402,7 @@ func newValidator(address []byte, power int64) *Validator { } func randPubKey() crypto.PubKey { - return crypto.PubKey(tmrand.Bytes(len(crypto.PubKey{}))) + return ed25519.GenerateSecretKey().Public() } func randModuloValidator(totalVotingPower int64) *Validator { @@ -1633,8 +1632,7 @@ func deterministicValidatorSet(ctx context.Context, t *testing.T) (*ValidatorSet t.Helper() for i := 0; i < 10; i++ { - // val, privValidator := DeterministicValidator(ed25519.PrivKey([]byte(deterministicKeys[i]))) - val, privValidator := deterministicValidator(ctx, t, ed25519.PrivKeyFromSeed(ed25519.Seed{byte(i)})) + val, privValidator := deterministicValidator(ctx, t, ed25519.TestSecretKey([]byte{byte(i)})) valz[i] = val privValidators[i] = privValidator } diff --git a/sei-tendermint/types/vote_test.go b/sei-tendermint/types/vote_test.go index de1eb8eba7..3cdcbb2695 100644 --- a/sei-tendermint/types/vote_test.go +++ b/sei-tendermint/types/vote_test.go @@ -163,7 +163,7 @@ func TestVoteVerifySignature(t *testing.T) { require.NoError(t, privVal.SignVote(ctx, "test_chain_id", v)) // verify the same vote - require.NoError(t, pubkey.Verify(VoteSignBytes("test_chain_id", v), crypto.Sig(v.Signature))) + require.NoError(t, pubkey.Verify(VoteSignBytes("test_chain_id", v), utils.OrPanic1(crypto.SigFromBytes(v.Signature)))) // serialize, deserialize and verify again.... precommit := new(tmproto.Vote) @@ -173,7 +173,7 @@ func TestVoteVerifySignature(t *testing.T) { // verify the transmitted vote newSignBytes := VoteSignBytes("test_chain_id", precommit) require.NoError(t, utils.TestDiff(signBytes, newSignBytes)) - require.NoError(t, pubkey.Verify(newSignBytes, crypto.Sig(precommit.Signature))) + require.NoError(t, pubkey.Verify(newSignBytes, utils.OrPanic1(crypto.SigFromBytes(precommit.Signature)))) } func TestIsVoteTypeValid(t *testing.T) { @@ -188,7 +188,6 @@ func TestIsVoteTypeValid(t *testing.T) { } for _, tt := range tc { - tt := tt t.Run(tt.name, func(st *testing.T) { if rs := IsVoteTypeValid(tt.in); rs != tt.out { t.Errorf("got unexpected Vote type. Expected:\n%v\nGot:\n%v", rs, tt.out) @@ -207,7 +206,7 @@ func TestVoteVerify(t *testing.T) { vote := examplePrevote(t) vote.ValidatorAddress = pubkey.Address() - err = vote.Verify("test_chain_id", ed25519.GenPrivKey().PubKey()) + err = vote.Verify("test_chain_id", ed25519.GenerateSecretKey().Public()) if assert.Error(t, err) { assert.Equal(t, ErrVoteInvalidValidatorAddress, err) } @@ -229,7 +228,7 @@ func signVote(ctx context.Context, t *testing.T, pv PrivValidator, chainID strin v := vote.ToProto() require.NoError(t, pv.SignVote(ctx, chainID, v)) - vote.Signature = crypto.Sig(v.Signature) + vote.Signature = utils.OrPanic1(crypto.SigFromBytes(v.Signature)) } func TestValidVotes(t *testing.T) { @@ -285,7 +284,7 @@ func TestVoteProtobuf(t *testing.T) { vote := examplePrecommit(t) v := vote.ToProto() require.NoError(t, privVal.SignVote(ctx, "test_chain_id", v)) - vote.Signature = crypto.Sig(v.Signature) + vote.Signature = utils.OrPanic1(crypto.SigFromBytes(v.Signature)) testCases := []struct { msg string From 72a985f9b58e9e85574ea71c9103fe38bcd140e7 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Thu, 18 Dec 2025 11:17:49 +0100 Subject: [PATCH 34/53] optional sig --- sei-tendermint/internal/consensus/state.go | 2 +- sei-tendermint/internal/evidence/verify.go | 12 ++++- .../internal/test/factory/commit.go | 3 +- sei-tendermint/internal/test/factory/vote.go | 3 +- sei-tendermint/privval/msgs_test.go | 2 +- sei-tendermint/types/block.go | 45 ++++++++++++------- sei-tendermint/types/evidence.go | 16 ++++--- sei-tendermint/types/test_util.go | 3 +- sei-tendermint/types/validation.go | 10 ++++- sei-tendermint/types/vote.go | 35 +++++++++++---- 10 files changed, 92 insertions(+), 39 deletions(-) diff --git a/sei-tendermint/internal/consensus/state.go b/sei-tendermint/internal/consensus/state.go index 2d97ef953f..08fcd36353 100644 --- a/sei-tendermint/internal/consensus/state.go +++ b/sei-tendermint/internal/consensus/state.go @@ -2621,7 +2621,7 @@ func (cs *State) signVote( if err != nil { return nil, fmt.Errorf("crypto.SigFromBytes(): %w", err) } - vote.Signature = sig + vote.Signature = utils.Some(sig) vote.Timestamp = v.Timestamp return vote, nil diff --git a/sei-tendermint/internal/evidence/verify.go b/sei-tendermint/internal/evidence/verify.go index a3276e39a3..627f4878c5 100644 --- a/sei-tendermint/internal/evidence/verify.go +++ b/sei-tendermint/internal/evidence/verify.go @@ -243,10 +243,18 @@ func VerifyDuplicateVote(e *types.DuplicateVoteEvidence, chainID string, valSet va := e.VoteA.ToProto() vb := e.VoteB.ToProto() // Signatures must be valid - if err := pubKey.Verify(types.VoteSignBytes(chainID, va), e.VoteA.Signature); err != nil { + sigA,ok := e.VoteA.Signature.Get() + if !ok { + return errors.New("VoteA.Signature missing") + } + sigB,ok := e.VoteB.Signature.Get() + if !ok { + return errors.New("VoteB.Signature missing") + } + if err := pubKey.Verify(types.VoteSignBytes(chainID, va), sigA); err != nil { return fmt.Errorf("verifying VoteA: %w", types.ErrVoteInvalidSignature) } - if err := pubKey.Verify(types.VoteSignBytes(chainID, vb), e.VoteB.Signature); err != nil { + if err := pubKey.Verify(types.VoteSignBytes(chainID, vb), sigB); err != nil { return fmt.Errorf("verifying VoteB: %w", types.ErrVoteInvalidSignature) } diff --git a/sei-tendermint/internal/test/factory/commit.go b/sei-tendermint/internal/test/factory/commit.go index 3929dafdd3..1fe5b30a40 100644 --- a/sei-tendermint/internal/test/factory/commit.go +++ b/sei-tendermint/internal/test/factory/commit.go @@ -6,6 +6,7 @@ import ( "time" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/libs/utils" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/types" ) @@ -36,7 +37,7 @@ func MakeCommit(ctx context.Context, blockID types.BlockID, height int64, round if err != nil { return nil, fmt.Errorf("crypto.SigFromBytes(): %w", err) } - vote.Signature = sig + vote.Signature = utils.Some(sig) if _, err := voteSet.AddVote(vote); err != nil { return nil, err } diff --git a/sei-tendermint/internal/test/factory/vote.go b/sei-tendermint/internal/test/factory/vote.go index 5ac1d5620c..92a583382a 100644 --- a/sei-tendermint/internal/test/factory/vote.go +++ b/sei-tendermint/internal/test/factory/vote.go @@ -6,6 +6,7 @@ import ( "time" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/libs/utils" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/types" ) @@ -44,6 +45,6 @@ func MakeVote( if err != nil { return nil, fmt.Errorf("crypto.SigFromBytes(): %w", err) } - v.Signature = sig + v.Signature = utils.Some(sig) return v, nil } diff --git a/sei-tendermint/privval/msgs_test.go b/sei-tendermint/privval/msgs_test.go index ea19c774fa..af5b02f0af 100644 --- a/sei-tendermint/privval/msgs_test.go +++ b/sei-tendermint/privval/msgs_test.go @@ -39,7 +39,7 @@ func exampleProposal() *types.Proposal { Round: 2, Timestamp: stamp, POLRound: 2, - Signature: makeSig([]byte("it's a signature")), + Signature: testKey.Sign([]byte("it's a signature")), BlockID: types.BlockID{ Hash: crypto.Checksum([]byte("blockID_hash")), PartSetHeader: types.PartSetHeader{ diff --git a/sei-tendermint/types/block.go b/sei-tendermint/types/block.go index 637d7059a7..f9a1ca249a 100644 --- a/sei-tendermint/types/block.go +++ b/sei-tendermint/types/block.go @@ -18,7 +18,7 @@ import ( tmbytes "github.com/tendermint/tendermint/libs/bytes" tmmath "github.com/tendermint/tendermint/libs/math" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - "github.com/tendermint/tendermint/utils" + "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/version" ) @@ -245,7 +245,10 @@ func (b *Block) ToReqBeginBlock(vals []*Validator) abci.RequestBeginBlock { SignedLastBlock: commitSig.BlockIDFlag != BlockIDFlagAbsent, }) } - abciEvidence := b.Evidence.ToABCI() + var byzantineValidators []abci.Evidence + for _,e := range b.Evidence.ToABCI() { + byzantineValidators = append(byzantineValidators,abci.Evidence(e)) + } return abci.RequestBeginBlock{ Hash: b.hash, Header: *tmHeader, @@ -253,9 +256,7 @@ func (b *Block) ToReqBeginBlock(vals []*Validator) abci.RequestBeginBlock { Round: b.LastCommit.Round, Votes: votes, }, - ByzantineValidators: utils.Map(abciEvidence, func(e abci.Misbehavior) abci.Evidence { - return abci.Evidence(e) - }), + ByzantineValidators: byzantineValidators, } } @@ -644,7 +645,7 @@ type CommitSig struct { // WARNING: all fields below should be zeroed if BlockIDFlag == BlockIDFlagAbsent ValidatorAddress Address `json:"validator_address"` Timestamp time.Time `json:"timestamp"` - Signature crypto.Sig `json:"signature"` + Signature utils.Option[crypto.Sig] `json:"signature"` } func MaxCommitBytes(valCount int) int64 { @@ -668,8 +669,12 @@ func NewCommitSigAbsent() CommitSig { // 3. block ID flag // 4. timestamp func (cs CommitSig) String() string { + var sigBytes []byte + if sig,ok := cs.Signature.Get(); ok { + sigBytes = sig.Bytes() + } return fmt.Sprintf("CommitSig{%X by %X on %v @ %s}", - tmbytes.Fingerprint(cs.Signature.Bytes()), + tmbytes.Fingerprint(sigBytes), tmbytes.Fingerprint(cs.ValidatorAddress), cs.BlockIDFlag, CanonicalTime(cs.Timestamp)) @@ -710,7 +715,7 @@ func (cs CommitSig) ValidateBasic() error { if !cs.Timestamp.IsZero() { return errors.New("time is present") } - if cs.Signature != (crypto.Sig{}) { + if cs.Signature.IsPresent() { return errors.New("signature is present") } default: @@ -720,8 +725,10 @@ func (cs CommitSig) ValidateBasic() error { len(cs.ValidatorAddress), ) } + if !cs.Signature.IsPresent() { + return errors.New("signature is missing") + } // NOTE: Timestamp validation is subtle and handled elsewhere. - // TODO: check that signature is present } return nil @@ -732,12 +739,15 @@ func (cs *CommitSig) ToProto() *tmproto.CommitSig { if cs == nil { return nil } - + var signature []byte + if sig,ok := cs.Signature.Get(); ok { + signature = sig.Bytes() + } return &tmproto.CommitSig{ BlockIdFlag: tmproto.BlockIDFlag(cs.BlockIDFlag), ValidatorAddress: cs.ValidatorAddress, Timestamp: cs.Timestamp, - Signature: cs.Signature.Bytes(), + Signature: signature, } } @@ -747,11 +757,16 @@ func (cs *CommitSig) FromProto(csp tmproto.CommitSig) error { cs.BlockIDFlag = BlockIDFlag(csp.BlockIdFlag) cs.ValidatorAddress = csp.ValidatorAddress cs.Timestamp = csp.Timestamp - sig, err := crypto.SigFromBytes(csp.Signature) - if err != nil { - return fmt.Errorf("Signature: %w", err) + + if len(csp.Signature)>0 { + sig, err := crypto.SigFromBytes(csp.Signature) + if err != nil { + return fmt.Errorf("Signature: %w", err) + } + cs.Signature = utils.Some(sig) + } else { + cs.Signature = utils.None[crypto.Sig]() } - cs.Signature = sig return cs.ValidateBasic() } diff --git a/sei-tendermint/types/evidence.go b/sei-tendermint/types/evidence.go index e7731bb8aa..d7277940ef 100644 --- a/sei-tendermint/types/evidence.go +++ b/sei-tendermint/types/evidence.go @@ -13,6 +13,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/crypto/merkle" "github.com/tendermint/tendermint/internal/jsontypes" tmmath "github.com/tendermint/tendermint/libs/math" @@ -855,16 +856,17 @@ func NewMockDuplicateVoteEvidenceWithValidator(ctx context.Context, height int64 val := NewValidator(pubKey, 10) voteA := makeMockVote(height, 0, 0, pubKey.Address(), randBlockID(), time) vA := voteA.ToProto() - _ = pv.SignVote(ctx, chainID, vA) - if voteA.Signature, err = crypto.SigFromBytes(vA.Signature); err != nil { - return nil, err - } + if err:=pv.SignVote(ctx, chainID, vA); err!=nil { return nil,err } + sig,err := crypto.SigFromBytes(vA.Signature) + if err != nil { return nil, err } + voteA.Signature = utils.Some(sig) + voteB := makeMockVote(height, 0, 0, pubKey.Address(), randBlockID(), time) vB := voteB.ToProto() _ = pv.SignVote(ctx, chainID, vB) - if voteB.Signature, err = crypto.SigFromBytes(vB.Signature); err != nil { - return nil, err - } + sig,err = crypto.SigFromBytes(vB.Signature) + if err != nil { return nil, err } + voteB.Signature = utils.Some(sig) ev, err := NewDuplicateVoteEvidence(voteA, voteB, time, NewValidatorSet([]*Validator{val})) if err != nil { return nil, fmt.Errorf("constructing mock duplicate vote evidence: %w", err) diff --git a/sei-tendermint/types/test_util.go b/sei-tendermint/types/test_util.go index 724bc9ce4f..53982cd510 100644 --- a/sei-tendermint/types/test_util.go +++ b/sei-tendermint/types/test_util.go @@ -6,6 +6,7 @@ import ( "time" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/libs/utils" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) @@ -46,6 +47,6 @@ func signAddVote(ctx context.Context, privVal PrivValidator, vote *Vote, voteSet if err != nil { return false, fmt.Errorf("SigFromBytes(): %w", err) } - vote.Signature = sig + vote.Signature = utils.Some(sig) return voteSet.AddVote(vote) } diff --git a/sei-tendermint/types/validation.go b/sei-tendermint/types/validation.go index 8664caed86..4217c4f629 100644 --- a/sei-tendermint/types/validation.go +++ b/sei-tendermint/types/validation.go @@ -206,7 +206,9 @@ func verifyCommitBatch( voteSignBytes := commit.VoteSignBytes(chainID, int32(idx)) // add the key, sig and message to the verifier - bv.Add(val.PubKey, voteSignBytes, commitSig.Signature) + sig,ok := commitSig.Signature.Get() + if !ok { return fmt.Errorf("missing signature at idx %v",idx) } + bv.Add(val.PubKey, voteSignBytes, sig) batchSigIdxs = append(batchSigIdxs, idx) // If this signature counts then add the voting power of the validator @@ -291,7 +293,11 @@ func verifyCommitSingle( } voteSignBytes = commit.VoteSignBytes(chainID, int32(idx)) - if err := val.PubKey.Verify(voteSignBytes, commitSig.Signature); err != nil { + sig,ok := commitSig.Signature.Get() + if !ok { + return fmt.Errorf("missing signature at idx %v",idx) + } + if err := val.PubKey.Verify(voteSignBytes, sig); err != nil { return errBadSig{fmt.Errorf("wrong signature (#%d): %X", idx, commitSig.Signature)} } diff --git a/sei-tendermint/types/vote.go b/sei-tendermint/types/vote.go index 78dbb948f2..28a0b44463 100644 --- a/sei-tendermint/types/vote.go +++ b/sei-tendermint/types/vote.go @@ -7,6 +7,7 @@ import ( "time" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/internal/libs/protoio" tmbytes "github.com/tendermint/tendermint/libs/bytes" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -55,7 +56,7 @@ type Vote struct { Timestamp time.Time `json:"timestamp"` ValidatorAddress Address `json:"validator_address"` ValidatorIndex int32 `json:"validator_index"` - Signature crypto.Sig `json:"signature"` + Signature utils.Option[crypto.Sig] `json:"signature"` } // VoteFromProto attempts to convert the given serialization (Protobuf) type to @@ -67,9 +68,13 @@ func VoteFromProto(pv *tmproto.Vote) (*Vote, error) { if err != nil { return nil, err } - sig, err := crypto.SigFromBytes(pv.Signature) - if err != nil { - return nil, fmt.Errorf("Signature: %w", err) + signature := utils.None[crypto.Sig]() + if len(pv.Signature)>0 { + sig, err := crypto.SigFromBytes(pv.Signature) + if err != nil { + return nil, fmt.Errorf("Signature: %w", err) + } + signature = utils.Some(sig) } return &Vote{ Type: pv.Type, @@ -79,7 +84,7 @@ func VoteFromProto(pv *tmproto.Vote) (*Vote, error) { Timestamp: pv.Timestamp, ValidatorAddress: pv.ValidatorAddress, ValidatorIndex: pv.ValidatorIndex, - Signature: sig, + Signature: signature, }, nil } @@ -157,6 +162,11 @@ func (vote *Vote) String() string { panic("Unknown vote type") } + var sigBytes []byte + if sig,ok := vote.Signature.Get(); ok { + sigBytes = sig.Bytes() + } + return fmt.Sprintf("Vote{index=%v:%X %v/%02d/%v(%v) %X %X @ %s}", vote.ValidatorIndex, vote.ValidatorAddress, @@ -165,7 +175,7 @@ func (vote *Vote) String() string { vote.Type, typeString, tmbytes.Fingerprint(vote.BlockID.Hash), - tmbytes.Fingerprint(vote.Signature.Bytes()), + tmbytes.Fingerprint(sigBytes), CanonicalTime(vote.Timestamp), ) } @@ -175,7 +185,11 @@ func (vote *Vote) verifyAndReturnProto(chainID string, pubKey crypto.PubKey) (*t return nil, ErrVoteInvalidValidatorAddress } v := vote.ToProto() - if err := pubKey.Verify(VoteSignBytes(chainID, v), vote.Signature); err != nil { + sig,ok := vote.Signature.Get() + if !ok { + return nil, errors.New("signature missing") + } + if err := pubKey.Verify(VoteSignBytes(chainID, v), sig); err != nil { return nil, ErrVoteInvalidSignature } return v, nil @@ -236,6 +250,11 @@ func (vote *Vote) ToProto() *tmproto.Vote { return nil } + var signature []byte + if sig,ok := vote.Signature.Get(); ok { + signature = sig.Bytes() + } + return &tmproto.Vote{ Type: vote.Type, Height: vote.Height, @@ -244,7 +263,7 @@ func (vote *Vote) ToProto() *tmproto.Vote { Timestamp: vote.Timestamp, ValidatorAddress: vote.ValidatorAddress, ValidatorIndex: vote.ValidatorIndex, - Signature: vote.Signature.Bytes(), + Signature: signature, } } From 5b90ba995e28d1e2b668d5de00d3ebf12048bd28 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Thu, 18 Dec 2025 11:31:28 +0100 Subject: [PATCH 35/53] codex tests --- sei-tendermint/internal/consensus/common_test.go | 8 ++++++-- sei-tendermint/internal/consensus/invalid_test.go | 2 +- .../consensus/types/height_vote_set_test.go | 4 ++-- sei-tendermint/internal/evidence/pool_test.go | 3 ++- sei-tendermint/internal/evidence/verify_test.go | 6 +++--- sei-tendermint/internal/state/execution_test.go | 2 +- sei-tendermint/internal/state/validation_test.go | 4 ++-- sei-tendermint/node/node_test.go | 2 +- sei-tendermint/privval/grpc/server_test.go | 5 +++-- sei-tendermint/privval/signer_client_test.go | 3 ++- sei-tendermint/rpc/client/evidence_test.go | 5 +++-- sei-tendermint/types/block_test.go | 14 +++++++------- sei-tendermint/types/evidence_test.go | 2 +- sei-tendermint/types/validation.go | 10 +++++----- sei-tendermint/types/validation_test.go | 8 ++++---- sei-tendermint/types/vote_test.go | 4 ++-- 16 files changed, 45 insertions(+), 37 deletions(-) diff --git a/sei-tendermint/internal/consensus/common_test.go b/sei-tendermint/internal/consensus/common_test.go index f2b7db5674..154a699850 100644 --- a/sei-tendermint/internal/consensus/common_test.go +++ b/sei-tendermint/internal/consensus/common_test.go @@ -141,10 +141,14 @@ func (vs *validatorStub) signVote( // ref: signVote in FilePV, the vote should use the previous vote info when the sign data is the same. if signDataIsEqual(vs.lastVote, v) { - v.Signature = vs.lastVote.Signature.Bytes() + sig, ok := vs.lastVote.Signature.Get() + if !ok { + panic("last vote missing signature") + } + v.Signature = sig.Bytes() v.Timestamp = vs.lastVote.Timestamp } - vote.Signature = utils.OrPanic1(crypto.SigFromBytes(v.Signature)) + vote.Signature = utils.Some(utils.OrPanic1(crypto.SigFromBytes(v.Signature))) vote.Timestamp = v.Timestamp return vote, nil } diff --git a/sei-tendermint/internal/consensus/invalid_test.go b/sei-tendermint/internal/consensus/invalid_test.go index 327c74d336..bfddd6cbd8 100644 --- a/sei-tendermint/internal/consensus/invalid_test.go +++ b/sei-tendermint/internal/consensus/invalid_test.go @@ -147,7 +147,7 @@ func invalidDoPrevoteFunc( p := precommit.ToProto() require.NoError(t, pv.SignVote(ctx, cs.state.ChainID, p)) - precommit.Signature = utils.OrPanic1(crypto.SigFromBytes(p.Signature)) + precommit.Signature = utils.Some(utils.OrPanic1(crypto.SigFromBytes(p.Signature))) t.Logf("disable priv val so we don't do normal votes") cs.privValidator = utils.None[types.PrivValidator]() cs.mtx.Unlock() diff --git a/sei-tendermint/internal/consensus/types/height_vote_set_test.go b/sei-tendermint/internal/consensus/types/height_vote_set_test.go index 2eacfb7216..b7ce709aff 100644 --- a/sei-tendermint/internal/consensus/types/height_vote_set_test.go +++ b/sei-tendermint/internal/consensus/types/height_vote_set_test.go @@ -7,11 +7,11 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/internal/test/factory" tmrand "github.com/tendermint/tendermint/libs/rand" tmtime "github.com/tendermint/tendermint/libs/time" + "github.com/tendermint/tendermint/libs/utils" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/types" ) @@ -85,6 +85,6 @@ func makeVoteHR( v := vote.ToProto() require.NoError(t, privVal.SignVote(ctx, chainID, v)) - vote.Signature = utils.OrPanic1(crypto.SigFromBytes(v.Signature)) + vote.Signature = utils.Some(utils.OrPanic1(crypto.SigFromBytes(v.Signature))) return vote } diff --git a/sei-tendermint/internal/evidence/pool_test.go b/sei-tendermint/internal/evidence/pool_test.go index a03aa18300..bc01a5a61c 100644 --- a/sei-tendermint/internal/evidence/pool_test.go +++ b/sei-tendermint/internal/evidence/pool_test.go @@ -22,6 +22,7 @@ import ( "github.com/tendermint/tendermint/internal/store" "github.com/tendermint/tendermint/internal/test/factory" "github.com/tendermint/tendermint/libs/log" + "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/version" @@ -590,7 +591,7 @@ func makeCommit(height int64, valAddr []byte) *types.Commit { BlockIDFlag: types.BlockIDFlagCommit, ValidatorAddress: valAddr, Timestamp: defaultEvidenceTime, - Signature: makeEvidenceSignature([]byte("Signature")), + Signature: utils.Some(makeEvidenceSignature([]byte("Signature"))), }}, } } diff --git a/sei-tendermint/internal/evidence/verify_test.go b/sei-tendermint/internal/evidence/verify_test.go index 6a0b00c6ee..4cb0300607 100644 --- a/sei-tendermint/internal/evidence/verify_test.go +++ b/sei-tendermint/internal/evidence/verify_test.go @@ -422,8 +422,8 @@ func TestVerifyDuplicateVoteEvidence(t *testing.T) { err = val2.SignVote(ctx, chainID, bv) require.NoError(t, err) - vote1.Signature = utils.OrPanic1(crypto.SigFromBytes(v1.Signature)) - badVote.Signature = utils.OrPanic1(crypto.SigFromBytes(bv.Signature)) + vote1.Signature = utils.Some(utils.OrPanic1(crypto.SigFromBytes(v1.Signature))) + badVote.Signature = utils.Some(utils.OrPanic1(crypto.SigFromBytes(bv.Signature))) cases := []voteData{ {vote1, makeVote(ctx, t, val, chainID, 0, 10, 2, 1, blockID2, defaultEvidenceTime), true}, // different block ids @@ -606,7 +606,7 @@ func makeVote( vpb := v.ToProto() err = val.SignVote(ctx, chainID, vpb) require.NoError(t, err) - v.Signature = utils.OrPanic1(crypto.SigFromBytes(vpb.Signature)) + v.Signature = utils.Some(utils.OrPanic1(crypto.SigFromBytes(vpb.Signature))) return v } diff --git a/sei-tendermint/internal/state/execution_test.go b/sei-tendermint/internal/state/execution_test.go index 846592c4c3..dbd6d9eff6 100644 --- a/sei-tendermint/internal/state/execution_test.go +++ b/sei-tendermint/internal/state/execution_test.go @@ -208,7 +208,7 @@ func TestFinalizeBlockByzantineValidators(t *testing.T) { BlockIDFlag: types.BlockIDFlagNil, ValidatorAddress: crypto.AddressHash([]byte("validator_address")), Timestamp: defaultEvidenceTime, - Signature: utils.OrPanic1(crypto.SigFromBytes(crypto.CRandBytes(64))), + Signature: utils.Some(utils.OrPanic1(crypto.SigFromBytes(crypto.CRandBytes(64)))), }}, }, }, diff --git a/sei-tendermint/internal/state/validation_test.go b/sei-tendermint/internal/state/validation_test.go index a70ce9c17a..20e78fd7e9 100644 --- a/sei-tendermint/internal/state/validation_test.go +++ b/sei-tendermint/internal/state/validation_test.go @@ -268,8 +268,8 @@ func TestValidateBlockCommit(t *testing.T) { err = badPrivVal.SignVote(ctx, chainID, b) require.NoError(t, err, "height %d", height) - goodVote.Signature = utils.OrPanic1(crypto.SigFromBytes(g.Signature)) - badVote.Signature = utils.OrPanic1(crypto.SigFromBytes(b.Signature)) + goodVote.Signature = utils.Some(utils.OrPanic1(crypto.SigFromBytes(g.Signature))) + badVote.Signature = utils.Some(utils.OrPanic1(crypto.SigFromBytes(b.Signature))) wrongSigsCommit = &types.Commit{ Height: goodVote.Height, diff --git a/sei-tendermint/node/node_test.go b/sei-tendermint/node/node_test.go index 94a9b42943..1699d726a3 100644 --- a/sei-tendermint/node/node_test.go +++ b/sei-tendermint/node/node_test.go @@ -537,7 +537,7 @@ func TestMaxProposalBlockSize(t *testing.T) { } vpb := vote.ToProto() require.NoError(t, privVals[i].SignVote(ctx, state.ChainID, vpb)) - vote.Signature = utils.OrPanic1(crypto.SigFromBytes(vpb.Signature)) + vote.Signature = utils.Some(utils.OrPanic1(crypto.SigFromBytes(vpb.Signature))) added, err := voteSet.AddVote(vote) require.NoError(t, err) diff --git a/sei-tendermint/privval/grpc/server_test.go b/sei-tendermint/privval/grpc/server_test.go index 4feb642e2a..7b9d3bca51 100644 --- a/sei-tendermint/privval/grpc/server_test.go +++ b/sei-tendermint/privval/grpc/server_test.go @@ -11,6 +11,7 @@ import ( "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/libs/log" tmrand "github.com/tendermint/tendermint/libs/rand" + "github.com/tendermint/tendermint/libs/utils" tmgrpc "github.com/tendermint/tendermint/privval/grpc" privvalproto "github.com/tendermint/tendermint/proto/tendermint/privval" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -91,7 +92,7 @@ func TestSignVote(t *testing.T) { Timestamp: ts, ValidatorAddress: valAddr, ValidatorIndex: 1, - Signature: testKey.Sign([]byte("signed")), + Signature: utils.Some(testKey.Sign([]byte("signed"))), }, want: &types.Vote{ Type: tmproto.PrecommitType, Height: 1, @@ -100,7 +101,7 @@ func TestSignVote(t *testing.T) { Timestamp: ts, ValidatorAddress: valAddr, ValidatorIndex: 1, - Signature: testKey.Sign([]byte("signed")), + Signature: utils.Some(testKey.Sign([]byte("signed"))), }, err: true}, } diff --git a/sei-tendermint/privval/signer_client_test.go b/sei-tendermint/privval/signer_client_test.go index 3c0113ad8a..7b08c6ce69 100644 --- a/sei-tendermint/privval/signer_client_test.go +++ b/sei-tendermint/privval/signer_client_test.go @@ -14,6 +14,7 @@ import ( "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/libs/log" tmrand "github.com/tendermint/tendermint/libs/rand" + "github.com/tendermint/tendermint/libs/utils" cryptoproto "github.com/tendermint/tendermint/proto/tendermint/crypto" privvalproto "github.com/tendermint/tendermint/proto/tendermint/privval" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -371,7 +372,7 @@ func TestSignerSignVoteErrors(t *testing.T) { Timestamp: ts, ValidatorAddress: valAddr, ValidatorIndex: 1, - Signature: testKey.Sign([]byte("signature")), + Signature: utils.Some(testKey.Sign([]byte("signature"))), } // Replace signer service privval with one that always fails diff --git a/sei-tendermint/rpc/client/evidence_test.go b/sei-tendermint/rpc/client/evidence_test.go index b2cfb85169..87e0f6b29e 100644 --- a/sei-tendermint/rpc/client/evidence_test.go +++ b/sei-tendermint/rpc/client/evidence_test.go @@ -9,6 +9,7 @@ import ( "github.com/tendermint/tendermint/crypto" tmrand "github.com/tendermint/tendermint/libs/rand" + "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/privval" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/rpc/client" @@ -26,9 +27,9 @@ func newEvidence(t *testing.T, val *privval.FilePV, v := vote.ToProto() v2 := vote2.ToProto() - vote.Signature = val.Key.PrivKey.Sign(types.VoteSignBytes(chainID, v)) + vote.Signature = utils.Some(val.Key.PrivKey.Sign(types.VoteSignBytes(chainID, v))) - vote2.Signature = val.Key.PrivKey.Sign(types.VoteSignBytes(chainID, v2)) + vote2.Signature = utils.Some(val.Key.PrivKey.Sign(types.VoteSignBytes(chainID, v2))) validator := types.NewValidator(val.Key.PubKey, 10) valSet := types.NewValidatorSet([]*types.Validator{validator}) diff --git a/sei-tendermint/types/block_test.go b/sei-tendermint/types/block_test.go index 4e8f224342..05d2d80d50 100644 --- a/sei-tendermint/types/block_test.go +++ b/sei-tendermint/types/block_test.go @@ -284,7 +284,7 @@ func TestCommitValidateBasic(t *testing.T) { expectErr bool }{ {"Random Commit", func(com *Commit) {}, false}, - {"Incorrect signature", func(com *Commit) { com.Signatures[0].Signature = testKey.Sign(nil) }, false}, + {"Incorrect signature", func(com *Commit) { com.Signatures[0].Signature = utils.Some(testKey.Sign(nil)) }, false}, {"Incorrect height", func(com *Commit) { com.Height = int64(-100) }, true}, {"Incorrect round", func(com *Commit) { com.Round = -100 }, true}, } @@ -313,7 +313,7 @@ func TestMaxCommitBytes(t *testing.T) { BlockIDFlag: BlockIDFlagNil, ValidatorAddress: crypto.AddressHash([]byte("validator_address")), Timestamp: timestamp, - Signature: sig, + Signature: utils.Some(sig), } pbSig := cs.ToProto() @@ -575,7 +575,7 @@ func TestVoteSetToCommit(t *testing.T) { } v := vote.ToProto() require.NoError(t, vals[i].SignVote(ctx, voteSet.ChainID(), v)) - vote.Signature = utils.OrPanic1(crypto.SigFromBytes(v.Signature)) + vote.Signature = utils.Some(utils.OrPanic1(crypto.SigFromBytes(v.Signature))) added, err := voteSet.AddVote(vote) require.NoError(t, err) require.True(t, added) @@ -949,7 +949,7 @@ func TestCommitSig_ValidateBasic(t *testing.T) { }, { "BlockIDFlagAbsent signatures present", - CommitSig{BlockIDFlag: BlockIDFlagAbsent, Signature: testKey.Sign([]byte{0xAA})}, + CommitSig{BlockIDFlag: BlockIDFlagAbsent, Signature: utils.Some(testKey.Sign([]byte{0xAA}))}, true, "signature is present", }, { @@ -967,7 +967,7 @@ func TestCommitSig_ValidateBasic(t *testing.T) { CommitSig{ BlockIDFlag: BlockIDFlagCommit, ValidatorAddress: make([]byte, crypto.AddressSize), - Signature: testKey.Sign(nil), + Signature: utils.Some(testKey.Sign(nil)), }, true, "signature is missing", }, @@ -976,7 +976,7 @@ func TestCommitSig_ValidateBasic(t *testing.T) { CommitSig{ BlockIDFlag: BlockIDFlagCommit, ValidatorAddress: make([]byte, crypto.AddressSize), - Signature: testKey.Sign(nil), + Signature: utils.Some(testKey.Sign(nil)), }, false, "", }, @@ -1311,7 +1311,7 @@ func TestCommit_ValidateBasic(t *testing.T) { { BlockIDFlag: BlockIDFlagCommit, ValidatorAddress: make([]byte, crypto.AddressSize), - Signature: testKey.Sign(nil), + Signature: utils.Some(testKey.Sign(nil)), }, }, }, diff --git a/sei-tendermint/types/evidence_test.go b/sei-tendermint/types/evidence_test.go index 41a0a7b535..dc49cef434 100644 --- a/sei-tendermint/types/evidence_test.go +++ b/sei-tendermint/types/evidence_test.go @@ -314,7 +314,7 @@ func makeVote( err = val.SignVote(ctx, chainID, vpb) require.NoError(t, err) - v.Signature = utils.OrPanic1(crypto.SigFromBytes(vpb.Signature)) + v.Signature = utils.Some(utils.OrPanic1(crypto.SigFromBytes(vpb.Signature))) return v } diff --git a/sei-tendermint/types/validation.go b/sei-tendermint/types/validation.go index 4217c4f629..c87e362e71 100644 --- a/sei-tendermint/types/validation.go +++ b/sei-tendermint/types/validation.go @@ -11,7 +11,7 @@ import ( const batchVerifyThreshold = 2 -func shouldBatchVerify(vals *ValidatorSet, commit *Commit) bool { +func shouldBatchVerify(commit *Commit) bool { return len(commit.Signatures) >= batchVerifyThreshold } @@ -42,7 +42,7 @@ func VerifyCommit(chainID string, vals *ValidatorSet, blockID BlockID, count := func(c CommitSig) bool { return c.BlockIDFlag == BlockIDFlagCommit } // attempt to batch verify - if shouldBatchVerify(vals, commit) { + if shouldBatchVerify(commit) { return verifyCommitBatch(chainID, vals, commit, votingPowerNeeded, ignore, count, true, true) } @@ -75,7 +75,7 @@ func VerifyCommitLight(chainID string, vals *ValidatorSet, blockID BlockID, count := func(c CommitSig) bool { return true } // attempt to batch verify - if shouldBatchVerify(vals, commit) { + if shouldBatchVerify(commit) { return verifyCommitBatch(chainID, vals, commit, votingPowerNeeded, ignore, count, false, true) } @@ -121,7 +121,7 @@ func VerifyCommitLightTrusting(chainID string, vals *ValidatorSet, commit *Commi // attempt to batch verify commit. As the validator set doesn't necessarily // correspond with the validator set that signed the block we need to look // up by address rather than index. - if shouldBatchVerify(vals, commit) { + if shouldBatchVerify(commit) { return verifyCommitBatch(chainID, vals, commit, votingPowerNeeded, ignore, count, false, false) } @@ -298,7 +298,7 @@ func verifyCommitSingle( return fmt.Errorf("missing signature at idx %v",idx) } if err := val.PubKey.Verify(voteSignBytes, sig); err != nil { - return errBadSig{fmt.Errorf("wrong signature (#%d): %X", idx, commitSig.Signature)} + return errBadSig{fmt.Errorf("wrong signature (#%d): %v", idx, sig)} } // If this signature counts then add the voting power of the validator diff --git a/sei-tendermint/types/validation_test.go b/sei-tendermint/types/validation_test.go index 84e8d31f4d..adfb37e4f6 100644 --- a/sei-tendermint/types/validation_test.go +++ b/sei-tendermint/types/validation_test.go @@ -118,7 +118,7 @@ func TestValidatorSet_VerifyCommit_All(t *testing.T) { v := vote.ToProto() require.NoError(t, vals[vi%len(vals)].SignVote(ctx, tc.chainID, v)) - vote.Signature = utils.OrPanic1(crypto.SigFromBytes(v.Signature)) + vote.Signature = utils.Some(utils.OrPanic1(crypto.SigFromBytes(v.Signature))) sigs[vi] = vote.CommitSig() @@ -178,7 +178,7 @@ func TestValidatorSet_VerifyCommit_CheckAllSignatures(t *testing.T) { vote := voteSet.GetByIndex(3) v := vote.ToProto() require.NoError(t, vals[3].SignVote(ctx, "CentaurusA", v)) - vote.Signature = utils.OrPanic1(crypto.SigFromBytes(v.Signature)) + vote.Signature = utils.Some(utils.OrPanic1(crypto.SigFromBytes(v.Signature))) commit.Signatures[3] = vote.CommitSig() err = valSet.VerifyCommit(chainID, blockID, h, commit) @@ -206,7 +206,7 @@ func TestValidatorSet_VerifyCommitLight_ReturnsAsSoonAsMajorityOfVotingPowerSign vote := voteSet.GetByIndex(3) v := vote.ToProto() require.NoError(t, vals[3].SignVote(ctx, "CentaurusA", v)) - vote.Signature = utils.OrPanic1(crypto.SigFromBytes(v.Signature)) + vote.Signature = utils.Some(utils.OrPanic1(crypto.SigFromBytes(v.Signature))) commit.Signatures[3] = vote.CommitSig() err = valSet.VerifyCommitLight(chainID, blockID, h, commit) @@ -231,7 +231,7 @@ func TestValidatorSet_VerifyCommitLightTrusting_ReturnsAsSoonAsTrustLevelOfVotin vote := voteSet.GetByIndex(2) v := vote.ToProto() require.NoError(t, vals[2].SignVote(ctx, "CentaurusA", v)) - vote.Signature = utils.OrPanic1(crypto.SigFromBytes(v.Signature)) + vote.Signature = utils.Some(utils.OrPanic1(crypto.SigFromBytes(v.Signature))) commit.Signatures[2] = vote.CommitSig() err = valSet.VerifyCommitLightTrusting(chainID, commit, tmmath.Fraction{Numerator: 1, Denominator: 3}) diff --git a/sei-tendermint/types/vote_test.go b/sei-tendermint/types/vote_test.go index 3cdcbb2695..feccb607cd 100644 --- a/sei-tendermint/types/vote_test.go +++ b/sei-tendermint/types/vote_test.go @@ -228,7 +228,7 @@ func signVote(ctx context.Context, t *testing.T, pv PrivValidator, chainID strin v := vote.ToProto() require.NoError(t, pv.SignVote(ctx, chainID, v)) - vote.Signature = utils.OrPanic1(crypto.SigFromBytes(v.Signature)) + vote.Signature = utils.Some(utils.OrPanic1(crypto.SigFromBytes(v.Signature))) } func TestValidVotes(t *testing.T) { @@ -284,7 +284,7 @@ func TestVoteProtobuf(t *testing.T) { vote := examplePrecommit(t) v := vote.ToProto() require.NoError(t, privVal.SignVote(ctx, "test_chain_id", v)) - vote.Signature = utils.OrPanic1(crypto.SigFromBytes(v.Signature)) + vote.Signature = utils.Some(utils.OrPanic1(crypto.SigFromBytes(v.Signature))) testCases := []struct { msg string From cd7ed89a673d6edba9e61b1ac5ee1a41fa189677 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Thu, 18 Dec 2025 11:51:05 +0100 Subject: [PATCH 36/53] tests wip --- sei-tendermint/crypto/ed25519/ed25519.go | 2 +- sei-tendermint/types/validator.go | 7 ++++-- sei-tendermint/types/validator_set.go | 6 +++-- sei-tendermint/types/validator_set_test.go | 29 ++++++++-------------- sei-tendermint/types/vote.go | 2 +- 5 files changed, 22 insertions(+), 24 deletions(-) diff --git a/sei-tendermint/crypto/ed25519/ed25519.go b/sei-tendermint/crypto/ed25519/ed25519.go index c1d4eb9f90..116aa38158 100644 --- a/sei-tendermint/crypto/ed25519/ed25519.go +++ b/sei-tendermint/crypto/ed25519/ed25519.go @@ -80,7 +80,7 @@ func TestSecretKey(seed []byte) SecretKey { // GenerateSecretKey generates a new secret key using a cryptographically secure random number generator. func GenerateSecretKey() SecretKey { - var seed [ed25519.PrivateKeySize]byte + var seed [ed25519.SeedSize]byte // rand.Read is documented to never return an error. if _, err := rand.Read(seed[:]); err != nil { panic(err) } // Generated key is always valid. diff --git a/sei-tendermint/types/validator.go b/sei-tendermint/types/validator.go index 76120d297e..2d12db2ea1 100644 --- a/sei-tendermint/types/validator.go +++ b/sei-tendermint/types/validator.go @@ -70,17 +70,20 @@ func NewValidator(pubKey crypto.PubKey, votingPower int64) *Validator { } } +var ErrNilValidator = errors.New("nil validator") +var ErrBadAddressSize = errors.New("validator address has bad size") + // ValidateBasic performs basic validation. func (v *Validator) ValidateBasic() error { if v == nil { - return errors.New("nil validator") + return ErrNilValidator } if v.VotingPower < 0 { return errors.New("validator has negative voting power") } if len(v.Address) != crypto.AddressSize { - return fmt.Errorf("validator address is the wrong size: %v", v.Address) + return fmt.Errorf("%w: %v", ErrBadAddressSize, v.Address) } return nil diff --git a/sei-tendermint/types/validator_set.go b/sei-tendermint/types/validator_set.go index 92b0cee17c..bc7dc6abaf 100644 --- a/sei-tendermint/types/validator_set.go +++ b/sei-tendermint/types/validator_set.go @@ -84,9 +84,11 @@ func NewValidatorSet(valz []*Validator) *ValidatorSet { return vals } +var ErrValidatorSetEmpty = errors.New("validator set is nil or empty") + func (vals *ValidatorSet) ValidateBasic() error { if vals.IsNilOrEmpty() { - return errors.New("validator set is nil or empty") + return ErrValidatorSetEmpty } for idx, val := range vals.Validators { @@ -96,7 +98,7 @@ func (vals *ValidatorSet) ValidateBasic() error { } if err := vals.Proposer.ValidateBasic(); err != nil { - return fmt.Errorf("proposer failed validate basic, error: %w", err) + return fmt.Errorf("Proposer: %w", err) } for _, val := range vals.Validators { diff --git a/sei-tendermint/types/validator_set_test.go b/sei-tendermint/types/validator_set_test.go index ebcf1272c7..8913bfc961 100644 --- a/sei-tendermint/types/validator_set_test.go +++ b/sei-tendermint/types/validator_set_test.go @@ -11,11 +11,13 @@ import ( "testing" "testing/quick" "time" + "errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/crypto/ed25519" tmmath "github.com/tendermint/tendermint/libs/math" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -91,59 +93,50 @@ func TestValidatorSetValidateBasic(t *testing.T) { testCases := []struct { vals ValidatorSet - err bool - msg string + err utils.Option[error] }{ { vals: ValidatorSet{}, - err: true, - msg: "validator set is nil or empty", + err: utils.Some(ErrValidatorSetEmpty), }, { vals: ValidatorSet{ Validators: []*Validator{}, }, - err: true, - msg: "validator set is nil or empty", + err: utils.Some(ErrValidatorSetEmpty), }, { vals: ValidatorSet{ Validators: []*Validator{val}, }, - err: true, - msg: "proposer failed validate basic, error: nil validator", + err: utils.Some(ErrNilValidator), }, { vals: ValidatorSet{ Validators: []*Validator{badVal}, + Proposer: val, }, - err: true, - msg: "invalid validator #0: validator does not have a public key", + err: utils.Some(ErrBadAddressSize), }, { vals: ValidatorSet{ Validators: []*Validator{val}, Proposer: val, }, - err: false, - msg: "", }, { vals: ValidatorSet{ Validators: []*Validator{val}, Proposer: val2, }, - err: true, - msg: ErrProposerNotInVals.Error(), + err: utils.Some(ErrProposerNotInVals), }, } for _, tc := range testCases { err := tc.vals.ValidateBasic() - if tc.err { - if assert.Error(t, err) { - assert.Equal(t, tc.msg, err.Error()) - } + if wantErr,ok := tc.err.Get(); ok { + assert.True(t, errors.Is(err,wantErr)) } else { assert.NoError(t, err) } diff --git a/sei-tendermint/types/vote.go b/sei-tendermint/types/vote.go index 28a0b44463..3b1207a5ff 100644 --- a/sei-tendermint/types/vote.go +++ b/sei-tendermint/types/vote.go @@ -187,7 +187,7 @@ func (vote *Vote) verifyAndReturnProto(chainID string, pubKey crypto.PubKey) (*t v := vote.ToProto() sig,ok := vote.Signature.Get() if !ok { - return nil, errors.New("signature missing") + return nil, ErrVoteInvalidSignature } if err := pubKey.Verify(VoteSignBytes(chainID, v), sig); err != nil { return nil, ErrVoteInvalidSignature From a9975f768efbdbaff615dc4cd1f90c741ad2676f Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Thu, 18 Dec 2025 12:59:48 +0100 Subject: [PATCH 37/53] tendermint tests pass --- .../internal/consensus/msgs_test.go | 5 +- sei-tendermint/internal/store/store_test.go | 3 +- sei-tendermint/light/helpers_test.go | 3 +- sei-tendermint/privval/grpc/server_test.go | 5 +- sei-tendermint/privval/msgs_test.go | 6 +- sei-tendermint/rpc/client/http/http.go | 2 +- sei-tendermint/rpc/client/rpc_test.go | 187 ++++++++---------- sei-tendermint/types/block_test.go | 49 +++-- sei-tendermint/types/evidence_test.go | 3 +- sei-tendermint/types/proposal_test.go | 17 +- sei-tendermint/types/validator.go | 3 +- sei-tendermint/types/validator_set_test.go | 19 +- sei-tendermint/types/validator_test.go | 27 +-- 13 files changed, 155 insertions(+), 174 deletions(-) diff --git a/sei-tendermint/internal/consensus/msgs_test.go b/sei-tendermint/internal/consensus/msgs_test.go index f8a58dc4df..147e556fcf 100644 --- a/sei-tendermint/internal/consensus/msgs_test.go +++ b/sei-tendermint/internal/consensus/msgs_test.go @@ -69,7 +69,7 @@ func TestMsgToProto(t *testing.T) { POLRound: 1, BlockID: bi, Timestamp: time.Now(), - Signature: makeSig("test-sig"), + Signature: testKey.Sign([]byte("somedata")), Header: header, Evidence: types.EvidenceList{}, LastCommit: &types.Commit{Signatures: []types.CommitSig{}}, @@ -339,9 +339,10 @@ func TestConsMsgsVectors(t *testing.T) { POLRound: 1, BlockID: bi, Timestamp: date, - Signature: makeSig("add_more_exclamation"), } pbProposal := proposal.ToProto() + // We populate the signature with invalid data to match the hash. + pbProposal.Signature = []byte("add_more_exclamation") v := &types.Vote{ ValidatorAddress: []byte("add_more_exclamation"), diff --git a/sei-tendermint/internal/store/store_test.go b/sei-tendermint/internal/store/store_test.go index c8aaa38443..3ddbb824eb 100644 --- a/sei-tendermint/internal/store/store_test.go +++ b/sei-tendermint/internal/store/store_test.go @@ -19,6 +19,7 @@ import ( "github.com/tendermint/tendermint/internal/state/test/factory" tmrand "github.com/tendermint/tendermint/libs/rand" tmtime "github.com/tendermint/tendermint/libs/time" + "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/version" ) @@ -36,7 +37,7 @@ func makeTestCommit(height int64, timestamp time.Time) *types.Commit { BlockIDFlag: types.BlockIDFlagCommit, ValidatorAddress: tmrand.Bytes(crypto.AddressSize), Timestamp: timestamp, - Signature: testKey.Sign([]byte("Signature")), + Signature: utils.Some(testKey.Sign([]byte("Signature"))), }} return &types.Commit{ Height: height, diff --git a/sei-tendermint/light/helpers_test.go b/sei-tendermint/light/helpers_test.go index 7464b2d2ba..548fc5ac8f 100644 --- a/sei-tendermint/light/helpers_test.go +++ b/sei-tendermint/light/helpers_test.go @@ -12,6 +12,7 @@ import ( provider_mocks "github.com/tendermint/tendermint/light/provider/mocks" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/version" ) @@ -94,7 +95,7 @@ func makeVote(t testing.TB, header *types.Header, valset *types.ValidatorSet, ke BlockID: blockID, } // Sign it - vote.Signature = key.Sign(types.VoteSignBytes(header.ChainID, vote.ToProto())) + vote.Signature = utils.Some(key.Sign(types.VoteSignBytes(header.ChainID, vote.ToProto()))) return vote } diff --git a/sei-tendermint/privval/grpc/server_test.go b/sei-tendermint/privval/grpc/server_test.go index 7b9d3bca51..f4b036a8eb 100644 --- a/sei-tendermint/privval/grpc/server_test.go +++ b/sei-tendermint/privval/grpc/server_test.go @@ -5,13 +5,14 @@ import ( "time" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/libs/log" + "github.com/tendermint/tendermint/libs/utils/require" tmrand "github.com/tendermint/tendermint/libs/rand" "github.com/tendermint/tendermint/libs/utils" + "github.com/tendermint/tendermint/crypto/encoding" tmgrpc "github.com/tendermint/tendermint/privval/grpc" privvalproto "github.com/tendermint/tendermint/proto/tendermint/privval" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -47,7 +48,7 @@ func TestGetPubKey(t *testing.T) { } else { pk, err := tc.pv.GetPubKey(ctx) require.NoError(t, err) - require.Equal(t, resp.PubKey, pk) + require.Equal(t, resp.PubKey, encoding.PubKeyToProto(pk)) } }) } diff --git a/sei-tendermint/privval/msgs_test.go b/sei-tendermint/privval/msgs_test.go index af5b02f0af..77a01a8329 100644 --- a/sei-tendermint/privval/msgs_test.go +++ b/sei-tendermint/privval/msgs_test.go @@ -39,7 +39,6 @@ func exampleProposal() *types.Proposal { Round: 2, Timestamp: stamp, POLRound: 2, - Signature: testKey.Sign([]byte("it's a signature")), BlockID: types.BlockID{ Hash: crypto.Checksum([]byte("blockID_hash")), PartSetHeader: types.PartSetHeader{ @@ -51,7 +50,8 @@ func exampleProposal() *types.Proposal { } func TestPrivvalVectors(t *testing.T) { - pk := ed25519.TestSecretKey([]byte{1, 2, 3, 4}).Public() + // WARNING: this key has to be stable for hashes to match. + pk := ed25519.TestSecretKey([]byte("it's a secret")).Public() ppk := encoding.PubKeyToProto(pk) // Generate a simple vote @@ -61,6 +61,8 @@ func TestPrivvalVectors(t *testing.T) { // Generate a simple proposal proposal := exampleProposal() proposalpb := proposal.ToProto() + // we set invalid signature for the hashes to match. + proposalpb.Signature = []byte("it's a signature") // Create a Reuseable remote error remoteError := &privproto.RemoteSignerError{Code: 1, Description: "it's a error"} diff --git a/sei-tendermint/rpc/client/http/http.go b/sei-tendermint/rpc/client/http/http.go index 915a42bbbb..9191f8ec7e 100644 --- a/sei-tendermint/rpc/client/http/http.go +++ b/sei-tendermint/rpc/client/http/http.go @@ -173,7 +173,7 @@ func (c *HTTP) NewBatch() *BatchHTTP { // compilation of the batched requests and send them off using the client as a // single request. On success, this returns a list of the deserialized results // from each request in the sent batch. -func (b *BatchHTTP) Send(ctx context.Context) ([]interface{}, error) { +func (b *BatchHTTP) Send(ctx context.Context) ([]any, error) { return b.rpcBatch.Send(ctx) } diff --git a/sei-tendermint/rpc/client/rpc_test.go b/sei-tendermint/rpc/client/rpc_test.go index 3cb97ffd28..ee61d410d6 100644 --- a/sei-tendermint/rpc/client/rpc_test.go +++ b/sei-tendermint/rpc/client/rpc_test.go @@ -24,11 +24,11 @@ import ( tmmath "github.com/tendermint/tendermint/libs/math" "github.com/tendermint/tendermint/libs/service" "github.com/tendermint/tendermint/libs/utils/require" + "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/privval" "github.com/tendermint/tendermint/rpc/client" rpchttp "github.com/tendermint/tendermint/rpc/client/http" rpclocal "github.com/tendermint/tendermint/rpc/client/local" - "github.com/tendermint/tendermint/rpc/coretypes" rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client" "github.com/tendermint/tendermint/types" ) @@ -125,13 +125,13 @@ func TestClientOperations(t *testing.T) { require.NoError(t, err, "%+v", err) defer resp.Body.Close() - assert.Equal(t, resp.Header.Get("Access-Control-Allow-Origin"), origin) + require.Equal(t, resp.Header.Get("Access-Control-Allow-Origin"), origin) }) t.Run("Batching", func(t *testing.T) { t.Run("JSONRPCCalls", func(t *testing.T) { logger := log.NewTestingLogger(t) c := getHTTPClient(t, logger, conf) - testBatchedJSONRPCCalls(ctx, t, c) + testBatchedJSONRPCCalls(ctx, c) }) t.Run("JSONRPCCallsCancellation", func(t *testing.T) { _, _, tx1 := MakeTxKV() @@ -171,11 +171,11 @@ func TestClientOperations(t *testing.T) { var wg sync.WaitGroup c := getHTTPClient(t, logger, conf) - for i := 0; i < 50; i++ { + for range 50 { wg.Add(1) go func() { defer wg.Done() - testBatchedJSONRPCCalls(ctx, t, c) + testBatchedJSONRPCCalls(ctx, c) }() } wg.Wait() @@ -201,7 +201,7 @@ func TestClientMethodCalls(t *testing.T) { t.Run("Status", func(t *testing.T) { status, err := c.Status(t.Context()) require.NoError(t, err, "%d: %+v", i, err) - assert.Equal(t, conf.Moniker, status.NodeInfo.Moniker) + require.Equal(t, conf.Moniker, status.NodeInfo.Moniker) }) t.Run("Info", func(t *testing.T) { ctx := t.Context() @@ -211,16 +211,16 @@ func TestClientMethodCalls(t *testing.T) { status, err := c.Status(ctx) require.NoError(t, err) - assert.GreaterOrEqual(t, status.SyncInfo.LatestBlockHeight, info.Response.LastBlockHeight) - assert.True(t, strings.Contains(info.Response.Data, "size")) + require.GreaterOrEqual(t, status.SyncInfo.LatestBlockHeight, info.Response.LastBlockHeight) + require.True(t, strings.Contains(info.Response.Data, "size")) }) t.Run("NetInfo", func(t *testing.T) { nc, ok := c.(client.NetworkClient) require.True(t, ok, "%d", i) netinfo, err := nc.NetInfo(t.Context()) require.NoError(t, err, "%d: %+v", i, err) - assert.True(t, netinfo.Listening) - assert.Equal(t, 0, len(netinfo.Peers)) + require.True(t, netinfo.Listening) + require.Equal(t, 0, len(netinfo.Peers)) }) t.Run("DumpConsensusState", func(t *testing.T) { // FIXME: fix server so it doesn't panic on invalid input @@ -228,8 +228,8 @@ func TestClientMethodCalls(t *testing.T) { require.True(t, ok, "%d", i) cons, err := nc.DumpConsensusState(t.Context()) require.NoError(t, err, "%d: %+v", i, err) - assert.NotEmpty(t, cons.RoundState) - assert.Empty(t, cons.Peers) + require.NotEmpty(t, cons.RoundState) + require.Empty(t, cons.Peers) }) t.Run("ConsensusState", func(t *testing.T) { // FIXME: fix server so it doesn't panic on invalid input @@ -237,7 +237,7 @@ func TestClientMethodCalls(t *testing.T) { require.True(t, ok, "%d", i) cons, err := nc.ConsensusState(t.Context()) require.NoError(t, err, "%d: %+v", i, err) - assert.NotEmpty(t, cons.RoundState) + require.NotEmpty(t, cons.RoundState) }) t.Run("Health", func(t *testing.T) { nc, ok := c.(client.NetworkClient) @@ -264,8 +264,8 @@ func TestClientMethodCalls(t *testing.T) { val := vals.Validators[0] // make sure the current set is also the genesis set - assert.Equal(t, gval.Power, val.VotingPower) - assert.Equal(t, gval.PubKey, val.PubKey) + require.Equal(t, gval.Power, val.VotingPower) + require.Equal(t, gval.PubKey, val.PubKey) }) t.Run("GenesisChunked", func(t *testing.T) { ctx := t.Context() @@ -303,7 +303,7 @@ func TestClientMethodCalls(t *testing.T) { res, err := c.ABCIQuery(ctx, "/key", k) qres := res.Response if assert.NoError(t, err) && assert.True(t, qres.IsOK()) { - assert.Equal(t, v, qres.Value) + require.Equal(t, v, qres.Value) } }) t.Run("AppCalls", func(t *testing.T) { @@ -335,22 +335,22 @@ func TestClientMethodCalls(t *testing.T) { require.NoError(t, err) qres := _qres.Response if assert.True(t, qres.IsOK()) { - assert.Equal(t, k, qres.Key) - assert.Equal(t, v, qres.Value) + require.Equal(t, k, qres.Key) + require.Equal(t, v, qres.Value) } // make sure we can lookup the tx with proof ptx, err := c.Tx(ctx, bres.Hash, true) require.NoError(t, err) - assert.Equal(t, txh, ptx.Height) - assert.Equal(t, tx, ptx.Tx) + require.Equal(t, txh, ptx.Height) + require.Equal(t, tx, ptx.Tx) // and we can even check the block is added block, err := c.Block(ctx, &apph) require.NoError(t, err) appHash := block.Block.Header.AppHash - assert.True(t, len(appHash) > 0) - assert.Equal(t, apph, block.Block.Header.Height) + require.True(t, len(appHash) > 0) + require.Equal(t, apph, block.Block.Header.Height) blockByHash, err := c.BlockByHash(ctx, block.BlockID.Hash) require.NoError(t, err) @@ -368,42 +368,42 @@ func TestClientMethodCalls(t *testing.T) { // now check the results blockResults, err := c.BlockResults(ctx, &txh) require.NoError(t, err, "%d: %+v", i, err) - assert.Equal(t, txh, blockResults.Height) + require.Equal(t, txh, blockResults.Height) if assert.Equal(t, 1, len(blockResults.TxsResults)) { // check success code - assert.Equal(t, 0, blockResults.TxsResults[0].Code) + require.Equal(t, 0, blockResults.TxsResults[0].Code) } // check blockchain info, now that we know there is info info, err := c.BlockchainInfo(ctx, apph, apph) require.NoError(t, err) - assert.True(t, info.LastHeight >= apph) + require.True(t, info.LastHeight >= apph) if assert.Equal(t, 1, len(info.BlockMetas)) { lastMeta := info.BlockMetas[0] - assert.Equal(t, apph, lastMeta.Header.Height) + require.Equal(t, apph, lastMeta.Header.Height) blockData := block.Block - assert.Equal(t, blockData.Header.AppHash, lastMeta.Header.AppHash) - assert.Equal(t, block.BlockID, lastMeta.BlockID) + require.Equal(t, blockData.Header.AppHash, lastMeta.Header.AppHash) + require.Equal(t, block.BlockID, lastMeta.BlockID) } // and get the corresponding commit with the same apphash commit, err := c.Commit(ctx, &apph) require.NoError(t, err) cappHash := commit.Header.AppHash - assert.Equal(t, appHash, cappHash) - assert.NotNil(t, commit.Commit) + require.Equal(t, appHash, cappHash) + require.NotNil(t, commit.Commit) // compare the commits (note Commit(2) has commit from Block(3)) h = apph - 1 commit2, err := c.Commit(ctx, &h) require.NoError(t, err) - assert.Equal(t, block.Block.LastCommitHash, commit2.Commit.Hash()) + require.Equal(t, block.Block.LastCommitHash, commit2.Commit.Hash()) // and we got a proof that works! _pres, err := c.ABCIQueryWithOptions(ctx, "/key", k, client.ABCIQueryOptions{Prove: true}) require.NoError(t, err) pres := _pres.Response - assert.True(t, pres.IsOK()) + require.True(t, pres.IsOK()) // XXX Test proof }) @@ -415,26 +415,26 @@ func TestClientMethodCalls(t *testing.T) { res, err := c.BlockchainInfo(ctx, 0, 0) require.NoError(t, err, "%d: %+v", i, err) - assert.True(t, res.LastHeight > 0) - assert.True(t, len(res.BlockMetas) > 0) + require.True(t, res.LastHeight > 0) + require.True(t, len(res.BlockMetas) > 0) res, err = c.BlockchainInfo(ctx, 1, 1) require.NoError(t, err, "%d: %+v", i, err) - assert.True(t, res.LastHeight > 0) - assert.True(t, len(res.BlockMetas) == 1) + require.True(t, res.LastHeight > 0) + require.True(t, len(res.BlockMetas) == 1) res, err = c.BlockchainInfo(ctx, 1, 10000) require.NoError(t, err, "%d: %+v", i, err) - assert.True(t, res.LastHeight > 0) - assert.True(t, len(res.BlockMetas) < 100) + require.True(t, res.LastHeight > 0) + require.True(t, len(res.BlockMetas) < 100) for _, m := range res.BlockMetas { - assert.NotNil(t, m) + require.NotNil(t, m) } res, err = c.BlockchainInfo(ctx, 10000, 1) require.Error(t, err) - assert.Nil(t, res) - assert.Contains(t, err.Error(), "can't be greater than max") + require.Nil(t, res) + require.Contains(t, err.Error(), "can't be greater than max") }) t.Run("BroadcastTxCommit", func(t *testing.T) { ctx := t.Context() @@ -466,9 +466,9 @@ func TestClientMethodCalls(t *testing.T) { res, err := c.CheckTx(ctx, tx) require.NoError(t, err) - assert.Equal(t, abci.CodeTypeOK, res.Code) + require.Equal(t, abci.CodeTypeOK, res.Code) - assert.Equal(t, 0, pool.Size(), "mempool must be empty") + require.Equal(t, 0, pool.Size(), "mempool must be empty") }) t.Run("Events", func(t *testing.T) { t.Run("Header", func(t *testing.T) { @@ -495,7 +495,7 @@ func TestClientMethodCalls(t *testing.T) { }) var firstBlockHeight int64 - for i := int64(0); i < 3; i++ { + for i := range int64(3) { event := <-eventCh blockEvent, ok := event.Data.(types.LegacyEventDataNewBlock) @@ -541,7 +541,7 @@ func TestClientMethodCalls(t *testing.T) { result, err := c.BroadcastEvidence(ctx, correct) require.NoError(t, err, "BroadcastEvidence(%s) failed", correct) - assert.Equal(t, correct.Hash(), result.Hash, "expected result hash to match evidence hash") + require.Equal(t, correct.Hash(), result.Hash, "expected result hash to match evidence hash") status, err := c.Status(ctx) require.NoError(t, err) @@ -603,7 +603,7 @@ func TestClientMethodCallsAdvanced(t *testing.T) { // populate mempool with 5 tx txs := make([]types.Tx, 5) ch := make(chan error, 5) - for i := 0; i < 5; i++ { + for i := range 5 { _, _, tx := MakeTxKV() txs[i] = tx @@ -612,7 +612,7 @@ func TestClientMethodCallsAdvanced(t *testing.T) { require.NoError(t, err) } // wait for tx to arrive in mempoool. - for i := 0; i < 5; i++ { + for range 5 { select { case <-ch: case <-time.After(5 * time.Second): @@ -714,16 +714,17 @@ func TestClientMethodCallsAdvanced(t *testing.T) { require.Error(t, err) } else { require.NoError(t, err, "%+v", err) - assert.Equal(t, txHeight, ptx.Height) - assert.Equal(t, tx, ptx.Tx) - assert.Zero(t, ptx.Index) - assert.True(t, ptx.TxResult.IsOK()) - assert.Equal(t, txHash, ptx.Hash) + require.Equal(t, txHeight, ptx.Height) + require.Equal(t, tx, ptx.Tx) + require.Zero(t, ptx.Index) + require.True(t, ptx.TxResult.IsOK()) + require.Equal(t, txHash, ptx.Hash) // time to verify the proof proof := ptx.Proof - if tc.prove && assert.Equal(t, tx, proof.Data) { - assert.NoError(t, proof.Proof.Verify(proof.RootHash, txHash)) + if tc.prove { + require.Equal(t, tx, proof.Data) + require.NoError(t, proof.Proof.Verify(proof.RootHash, txHash)) } } }) @@ -752,7 +753,7 @@ func TestClientMethodCallsAdvanced(t *testing.T) { c := getHTTPClient(t, logger, conf) // first we broadcast a few txs - for i := 0; i < 10; i++ { + for range 10 { _, _, tx := MakeTxKV() _, err := c.BroadcastTxSync(ctx, tx) require.NoError(t, err) @@ -777,15 +778,15 @@ func TestClientMethodCallsAdvanced(t *testing.T) { require.Equal(t, find.Hash, result.Txs[0].Hash) ptx := result.Txs[0] - assert.Equal(t, find.Height, ptx.Height) - assert.Equal(t, find.Tx, ptx.Tx) - assert.Zero(t, ptx.Index) - assert.True(t, ptx.TxResult.IsOK()) - assert.Equal(t, find.Hash, ptx.Hash) + require.Equal(t, find.Height, ptx.Height) + require.Equal(t, find.Tx, ptx.Tx) + require.Zero(t, ptx.Index) + require.True(t, ptx.TxResult.IsOK()) + require.Equal(t, find.Hash, ptx.Hash) // time to verify the proof if assert.Equal(t, find.Tx, ptx.Proof.Data) { - assert.NoError(t, ptx.Proof.Proof.Verify(ptx.Proof.RootHash, find.Hash)) + require.NoError(t, ptx.Proof.Proof.Verify(ptx.Proof.RootHash, find.Hash)) } // query by height @@ -872,51 +873,25 @@ func TestClientMethodCallsAdvanced(t *testing.T) { }) } -func testBatchedJSONRPCCalls(ctx context.Context, t *testing.T, c *rpchttp.HTTP) { - k1, v1, tx1 := MakeTxKV() - k2, v2, tx2 := MakeTxKV() +// WARNING: this function is called in subgoroutines to it shouldn't use testing.T. +func testBatchedJSONRPCCalls(ctx context.Context, c *rpchttp.HTTP) { + k1,_, tx1 := MakeTxKV() + k2,_, tx2 := MakeTxKV() batch := c.NewBatch() - r1, err := batch.BroadcastTxCommit(ctx, tx1) - require.NoError(t, err) - r2, err := batch.BroadcastTxCommit(ctx, tx2) - require.NoError(t, err) - require.Equal(t, 2, batch.Count()) - bresults, err := batch.Send(ctx) - require.NoError(t, err) - require.Len(t, bresults, 2) - require.Equal(t, 0, batch.Count()) - - bresult1, ok := bresults[0].(*coretypes.ResultBroadcastTxCommit) - require.True(t, ok) - require.Equal(t, *bresult1, *r1) - bresult2, ok := bresults[1].(*coretypes.ResultBroadcastTxCommit) - require.True(t, ok) - require.Equal(t, *bresult2, *r2) - apph := tmmath.MaxInt64(bresult1.Height, bresult2.Height) + 1 - - err = client.WaitForHeight(ctx, c, apph, nil) - require.NoError(t, err) - - q1, err := batch.ABCIQuery(ctx, "/key", k1) - require.NoError(t, err) - q2, err := batch.ABCIQuery(ctx, "/key", k2) - require.NoError(t, err) - require.Equal(t, 2, batch.Count()) - qresults, err := batch.Send(ctx) - require.NoError(t, err) - require.Len(t, qresults, 2) - require.Equal(t, 0, batch.Count()) - - qresult1, ok := qresults[0].(*coretypes.ResultABCIQuery) - require.True(t, ok) - require.Equal(t, *qresult1, *q1) - qresult2, ok := qresults[1].(*coretypes.ResultABCIQuery) - require.True(t, ok) - require.Equal(t, *qresult2, *q2) - - require.Equal(t, qresult1.Response.Key, k1) - require.Equal(t, qresult2.Response.Key, k2) - require.Equal(t, qresult1.Response.Value, v1) - require.Equal(t, qresult2.Response.Value, v2) + r1 := utils.OrPanic1(batch.BroadcastTxCommit(ctx, tx1)) + r2 := utils.OrPanic1(batch.BroadcastTxCommit(ctx, tx2)) + utils.OrPanic(utils.TestDiff(2, batch.Count())) + bresults := utils.OrPanic1(batch.Send(ctx)) + utils.OrPanic(utils.TestDiff(bresults, []any{r1,r2})) + utils.OrPanic(utils.TestDiff(0, batch.Count())) + apph := tmmath.MaxInt64(r1.Height, r2.Height) + 1 + + utils.OrPanic(client.WaitForHeight(ctx, c, apph, nil)) + + q1 := utils.OrPanic1(batch.ABCIQuery(ctx, "/key", k1)) + q2 := utils.OrPanic1(batch.ABCIQuery(ctx, "/key", k2)) + utils.OrPanic(utils.TestDiff(2, batch.Count())) + qresults := utils.OrPanic1(batch.Send(ctx)) + utils.OrPanic(utils.TestDiff(qresults, []any{q1,q2})) } diff --git a/sei-tendermint/types/block_test.go b/sei-tendermint/types/block_test.go index 11dbf54b1a..02ea18be35 100644 --- a/sei-tendermint/types/block_test.go +++ b/sei-tendermint/types/block_test.go @@ -6,7 +6,6 @@ import ( "context" "crypto/rand" "encoding/hex" - "io" "math" mrand "math/rand" "os" @@ -117,7 +116,6 @@ func TestBlockValidateBasic(t *testing.T) { }, true}, } for i, tc := range testCases { - i := i t.Run(tc.testName, func(t *testing.T) { block := MakeBlock(h, txs, commit, evList) block.ProposerAddress = valSet.GetProposer().Address @@ -284,7 +282,7 @@ func TestCommitHash(t *testing.T) { BlockIDFlag: BlockIDFlagCommit, ValidatorAddress: crypto.AddressHash([]byte("validator1")), Timestamp: time.Now(), - Signature: crypto.CRandBytes(64), + Signature: utils.Some(testKey.Sign([]byte("data"))), } baseCommit := &Commit{ @@ -346,7 +344,7 @@ func TestCommitHash(t *testing.T) { BlockIDFlag: BlockIDFlagCommit, ValidatorAddress: crypto.AddressHash([]byte("validator2")), // Different validator Timestamp: time.Now(), - Signature: crypto.CRandBytes(64), + Signature: utils.Some(testKey.Sign([]byte("other-data"))), } differentSigCommit := &Commit{ Height: 100, @@ -371,7 +369,7 @@ func TestCommitValidateBasic(t *testing.T) { expectErr bool }{ {"Random Commit", func(com *Commit) {}, false}, - {"Incorrect signature", func(com *Commit) { com.Signatures[0].Signature = utils.Some(testKey.Sign(nil)) }, false}, + {"Incorrect signature", func(com *Commit) { com.Signatures[0].Signature = utils.Some(testKey.Sign([]byte("whatever"))) }, false}, {"Incorrect height", func(com *Commit) { com.Height = int64(-100) }, true}, {"Incorrect round", func(com *Commit) { com.Round = -100 }, true}, } @@ -382,7 +380,8 @@ func TestCommitValidateBasic(t *testing.T) { com := randCommit(ctx, t, time.Now()) tc.malleateCommit(com) - assert.Equal(t, tc.expectErr, com.ValidateBasic() != nil, "Validate Basic had an unexpected result") + err := com.ValidateBasic() + assert.Equal(t, tc.expectErr, err != nil, "Validate Basic had an unexpected result: %v",err) }) } } @@ -392,15 +391,11 @@ func TestMaxCommitBytes(t *testing.T) { // year int, month Month, day, hour, min, sec, nsec int, loc *Location timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC) - sigBytes := make([]byte, 64) - _, err := io.ReadFull(rand.Reader, sigBytes) - require.NoError(t, err) - sig := testKey.Sign(sigBytes) cs := CommitSig{ BlockIDFlag: BlockIDFlagNil, ValidatorAddress: crypto.AddressHash([]byte("validator_address")), Timestamp: timestamp, - Signature: utils.Some(sig), + Signature: utils.Some(testKey.Sign([]byte("data"))), } pbSig := cs.ToProto() @@ -529,7 +524,7 @@ func TestMaxHeaderBytes(t *testing.T) { // Each supplementary character takes 4 bytes. // http://www.i18nguy.com/unicode/supplementary-test.html maxChainID := "" - for i := 0; i < MaxChainIDLen; i++ { + for range MaxChainIDLen { maxChainID += "𠜎" } @@ -648,7 +643,7 @@ func TestVoteSetToCommit(t *testing.T) { valSet, vals := randValidatorPrivValSet(ctx, t, 10, 1) voteSet := NewVoteSet("test_chain_id", 3, 1, tmproto.PrecommitType, valSet) - for i := 0; i < len(vals); i++ { + for i := range vals { pubKey, err := vals[i].GetPubKey(ctx) require.NoError(t, err) vote := &Vote{ @@ -926,7 +921,6 @@ func TestHeaderProto(t *testing.T) { } for _, tt := range tc { - tt := tt t.Run(tt.msg, func(t *testing.T) { pb := tt.h1.ToProto() h, err := HeaderFromProto(pb) @@ -1054,7 +1048,7 @@ func TestCommitSig_ValidateBasic(t *testing.T) { CommitSig{ BlockIDFlag: BlockIDFlagCommit, ValidatorAddress: make([]byte, crypto.AddressSize), - Signature: utils.Some(testKey.Sign(nil)), + Signature: utils.None[crypto.Sig](), }, true, "signature is missing", }, @@ -1063,7 +1057,7 @@ func TestCommitSig_ValidateBasic(t *testing.T) { CommitSig{ BlockIDFlag: BlockIDFlagCommit, ValidatorAddress: make([]byte, crypto.AddressSize), - Signature: utils.Some(testKey.Sign(nil)), + Signature: utils.Some(testKey.Sign([]byte("data"))), }, false, "", }, @@ -1383,6 +1377,27 @@ func TestCommit_ValidateBasic(t *testing.T) { }, true, "no signatures in commit", }, + { + "invalid signature", + &Commit{ + Height: 1, + Round: 1, + BlockID: BlockID{ + Hash: make([]byte, crypto.HashSize), + PartSetHeader: PartSetHeader{ + Hash: make([]byte, crypto.HashSize), + }, + }, + Signatures: []CommitSig{ + { + BlockIDFlag: BlockIDFlagCommit, + ValidatorAddress: make([]byte, crypto.AddressSize), + Signature: utils.None[crypto.Sig](), + }, + }, + }, + true, "wrong CommitSig", + }, { "valid commit", &Commit{ @@ -1398,7 +1413,7 @@ func TestCommit_ValidateBasic(t *testing.T) { { BlockIDFlag: BlockIDFlagCommit, ValidatorAddress: make([]byte, crypto.AddressSize), - Signature: utils.Some(testKey.Sign(nil)), + Signature: utils.Some(testKey.Sign([]byte("data"))), }, }, }, diff --git a/sei-tendermint/types/evidence_test.go b/sei-tendermint/types/evidence_test.go index dc49cef434..4ce9288251 100644 --- a/sei-tendermint/types/evidence_test.go +++ b/sei-tendermint/types/evidence_test.go @@ -384,7 +384,8 @@ func TestEvidenceVectors(t *testing.T) { // Votes for duplicateEvidence val := NewMockPV() - val.PrivKey = ed25519.TestSecretKey([]byte{1, 2, 3, 4}) // deterministic key + // WARNING: this key has to be stable, otherwise hashes break. + val.PrivKey = ed25519.TestSecretKey([]byte("it's a secret")) blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash"))) blockID2 := makeBlockID(crypto.Checksum([]byte("blockhash2")), math.MaxInt32, crypto.Checksum([]byte("partshash"))) const chainID = "mychain" diff --git a/sei-tendermint/types/proposal_test.go b/sei-tendermint/types/proposal_test.go index 0ce742f786..127969bf56 100644 --- a/sei-tendermint/types/proposal_test.go +++ b/sei-tendermint/types/proposal_test.go @@ -117,23 +117,16 @@ func TestProposalVerifySignature(t *testing.T) { func BenchmarkProposalWriteSignBytes(b *testing.B) { pbp := getTestProposal(b).ToProto() - - b.ResetTimer() - - for i := 0; i < b.N; i++ { + for b.Loop() { ProposalSignBytes("test_chain_id", pbp) } } func BenchmarkProposalSign(b *testing.B) { ctx := b.Context() - privVal := NewMockPV() - pbp := getTestProposal(b).ToProto() - b.ResetTimer() - - for i := 0; i < b.N; i++ { + for b.Loop() { err := privVal.SignProposal(ctx, "test_chain_id", pbp) if err != nil { b.Error(err) @@ -175,9 +168,6 @@ func TestProposalValidateBasic(t *testing.T) { {"Invalid BlockId", func(p *Proposal) { p.BlockID = BlockID{[]byte{1, 2, 3}, PartSetHeader{111, []byte("blockparts")}} }, true}, - {"Invalid Signature", func(p *Proposal) { - p.Signature = testKey.Sign(nil) - }, true}, } blockID := makeBlockID(crypto.Checksum([]byte("blockhash")), math.MaxInt32, crypto.Checksum([]byte("partshash"))) @@ -196,7 +186,8 @@ func TestProposalValidateBasic(t *testing.T) { require.NoError(t, privVal.SignProposal(ctx, "test_chain_id", p)) prop.Signature = utils.OrPanic1(crypto.SigFromBytes(p.Signature)) tc.malleateProposal(prop) - assert.Equal(t, tc.expectErr, prop.ValidateBasic() != nil, "Validate Basic had an unexpected result") + err = prop.ValidateBasic() + assert.Equal(t, tc.expectErr, err != nil, "Validate Basic had an unexpected result: %v",err) }) } } diff --git a/sei-tendermint/types/validator.go b/sei-tendermint/types/validator.go index 2d12db2ea1..06e21170e6 100644 --- a/sei-tendermint/types/validator.go +++ b/sei-tendermint/types/validator.go @@ -71,6 +71,7 @@ func NewValidator(pubKey crypto.PubKey, votingPower int64) *Validator { } var ErrNilValidator = errors.New("nil validator") +var ErrNegativeVotingPower = errors.New("validator has negative voting power") var ErrBadAddressSize = errors.New("validator address has bad size") // ValidateBasic performs basic validation. @@ -79,7 +80,7 @@ func (v *Validator) ValidateBasic() error { return ErrNilValidator } if v.VotingPower < 0 { - return errors.New("validator has negative voting power") + return ErrNegativeVotingPower } if len(v.Address) != crypto.AddressSize { diff --git a/sei-tendermint/types/validator_set_test.go b/sei-tendermint/types/validator_set_test.go index 8913bfc961..db7b5862e0 100644 --- a/sei-tendermint/types/validator_set_test.go +++ b/sei-tendermint/types/validator_set_test.go @@ -197,18 +197,16 @@ func TestIncrementProposerPriorityPositiveTimes(t *testing.T) { } func BenchmarkValidatorSetCopy(b *testing.B) { - b.StopTimer() vset := NewValidatorSet([]*Validator{}) - for i := 0; i < 1000; i++ { + for range 1000 { privKey := ed25519.GenerateSecretKey() pubKey := privKey.Public() val := NewValidator(pubKey, 10) err := vset.UpdateWithChangeSet([]*Validator{val}) require.NoError(b, err) } - b.StartTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { vset.Copy() } } @@ -222,7 +220,7 @@ func TestProposerSelection1(t *testing.T) { newValidator([]byte("baz"), 330), }) var proposers []string - for i := 0; i < 99; i++ { + for range 99 { val := vset.GetProposer() proposers = append(proposers, string(val.Address)) vset.IncrementProposerPriority(1) @@ -338,7 +336,7 @@ func TestProposerSelection3(t *testing.T) { }) proposerOrder := make([]*Validator, 4) - for i := 0; i < 4; i++ { + for i := range 4 { // need to give all validators to have keys pk := ed25519.GenerateSecretKey().Public() vset.Validators[i].PubKey = pk @@ -424,7 +422,7 @@ func randValidator(ctx context.Context, randPower bool, minPower int64) (*Valida func randModuloValidatorSet(numValidators int) *ValidatorSet { validators := make([]*Validator, numValidators) totalVotingPower := int64(0) - for i := 0; i < numValidators; i++ { + for i := range numValidators { validators[i] = randModuloValidator(totalVotingPower) totalVotingPower += validators[i].VotingPower } @@ -826,7 +824,7 @@ func toTestValList(valList []*Validator) []testVal { func testValSet(nVals int, power int64) []testVal { vals := make([]testVal, nVals) - for i := 0; i < nVals; i++ { + for i := range nVals { vals[i] = testVal{fmt.Sprintf("v%d", i+1), power} } return vals @@ -1624,8 +1622,9 @@ func deterministicValidatorSet(ctx context.Context, t *testing.T) (*ValidatorSet t.Helper() - for i := 0; i < 10; i++ { - val, privValidator := deterministicValidator(ctx, t, ed25519.TestSecretKey([]byte{byte(i)})) + for i := range 10 { + // WARNING: this key has to be stable, otherwise hashes break. + val, privValidator := deterministicValidator(ctx, t, ed25519.TestSecretKey(fmt.Appendf(nil,"key: %x", i))) valz[i] = val privValidators[i] = privValidator } diff --git a/sei-tendermint/types/validator_test.go b/sei-tendermint/types/validator_test.go index fee5792d20..e6117f7284 100644 --- a/sei-tendermint/types/validator_test.go +++ b/sei-tendermint/types/validator_test.go @@ -3,11 +3,13 @@ package types import ( "context" "testing" + "errors" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/libs/utils" + "github.com/tendermint/tendermint/libs/utils/require" ) func TestValidatorProtoBuf(t *testing.T) { @@ -51,48 +53,39 @@ func TestValidatorValidateBasic(t *testing.T) { pubKey, _ := priv.GetPubKey(ctx) testCases := []struct { val *Validator - err bool - msg string + err utils.Option[error] }{ { val: NewValidator(pubKey, 1), - err: false, - msg: "", }, { val: nil, - err: true, - msg: "nil validator", + err: utils.Some(ErrNilValidator), }, { val: NewValidator(pubKey, -1), - err: true, - msg: "validator has negative voting power", + err: utils.Some(ErrNegativeVotingPower), }, { val: &Validator{ PubKey: pubKey, Address: nil, }, - err: true, - msg: "validator address is the wrong size: ", + err: utils.Some(ErrBadAddressSize), }, { val: &Validator{ PubKey: pubKey, Address: []byte{'a'}, }, - err: true, - msg: "validator address is the wrong size: 61", + err: utils.Some(ErrBadAddressSize), }, } for _, tc := range testCases { err := tc.val.ValidateBasic() - if tc.err { - if assert.Error(t, err) { - assert.Equal(t, tc.msg, err.Error()) - } + if wantErr,ok := tc.err.Get(); ok { + assert.True(t, errors.Is(err,wantErr)) } else { assert.NoError(t, err) } From e866fc292bb466174a41a1809245bb55329f49ab Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Thu, 18 Dec 2025 13:24:51 +0100 Subject: [PATCH 38/53] all tests compile --- app/apptesting/test_suite.go | 4 ++-- sei-cosmos/crypto/keys/ed25519/ed25519_test.go | 4 ++-- sei-cosmos/server/rollback_test.go | 4 ++-- sei-cosmos/x/genutil/utils.go | 2 +- sei-ibc-go/testing/chain.go | 4 +++- sei-ibc-go/testing/mock/privval_test.go | 10 +++++----- sei-tendermint/crypto/ed25519/ed25519.go | 7 +++++++ sei-wasmd/x/wasm/ibctesting/chain.go | 3 ++- sei-wasmd/x/wasm/keeper/test_common.go | 4 ++-- sei-wasmd/x/wasm/module_test.go | 4 ++-- x/tokenfactory/types/msgs_test.go | 12 ++++++------ 11 files changed, 34 insertions(+), 24 deletions(-) diff --git a/app/apptesting/test_suite.go b/app/apptesting/test_suite.go index 12de421d03..8d88be906a 100644 --- a/app/apptesting/test_suite.go +++ b/app/apptesting/test_suite.go @@ -165,7 +165,7 @@ func (s *KeeperTestHelper) BuildTx( func CreateRandomAccounts(numAccts int) []sdk.AccAddress { testAddrs := make([]sdk.AccAddress, numAccts) for i := 0; i < numAccts; i++ { - pk := ed25519.GenPrivKey().PubKey() + pk := ed25519.GenerateSecretKey().Public() testAddrs[i] = sdk.AccAddress(pk.Address()) } @@ -173,7 +173,7 @@ func CreateRandomAccounts(numAccts int) []sdk.AccAddress { } func GenerateTestAddrs() (string, string) { - pk1 := ed25519.GenPrivKey().PubKey() + pk1 := ed25519.GenerateSecretKey().Public() validAddr := sdk.AccAddress(pk1.Address()).String() invalidAddr := sdk.AccAddress("invalid").String() return validAddr, invalidAddr diff --git a/sei-cosmos/crypto/keys/ed25519/ed25519_test.go b/sei-cosmos/crypto/keys/ed25519/ed25519_test.go index 30954f8e9c..9e0699e1ab 100644 --- a/sei-cosmos/crypto/keys/ed25519/ed25519_test.go +++ b/sei-cosmos/crypto/keys/ed25519/ed25519_test.go @@ -187,8 +187,8 @@ func TestMarshalAmino(t *testing.T) { func TestMarshalAmino_BackwardsCompatibility(t *testing.T) { aminoCdc := codec.NewLegacyAmino() // Create Tendermint keys. - tmPrivKey := tmed25519.GenPrivKey() - tmPubKey := tmPrivKey.PubKey() + tmPrivKey := tmed25519.GenerateSecretKey() + tmPubKey := tmPrivKey.Public() // Create our own keys, with the same private key as Tendermint's. privKey := &ed25519.PrivKey{Key: tmPrivKey.SecretBytes()} pubKey := privKey.PubKey().(*ed25519.PubKey) diff --git a/sei-cosmos/server/rollback_test.go b/sei-cosmos/server/rollback_test.go index 1536a01f21..21f1b1e2ba 100644 --- a/sei-cosmos/server/rollback_test.go +++ b/sei-cosmos/server/rollback_test.go @@ -157,8 +157,8 @@ func setupTendermintStateDB(t *testing.T, tempDir string, height int64) *tmconfi // Create a simple validator set for testing // We need at least one validator for rollback to work - valPrivKey := ed25519.GenPrivKey() - valPubKey := valPrivKey.PubKey() + valPrivKey := ed25519.GenerateSecretKey() + valPubKey := valPrivKey.Public() validator := &tmtypes.Validator{ Address: valPubKey.Address(), PubKey: valPubKey, diff --git a/sei-cosmos/x/genutil/utils.go b/sei-cosmos/x/genutil/utils.go index 5b0bab809e..b6679dc6b2 100644 --- a/sei-cosmos/x/genutil/utils.go +++ b/sei-cosmos/x/genutil/utils.go @@ -82,7 +82,7 @@ func InitializeNodeValidatorFilesFromMnemonic(config *cfg.Config, mnemonic strin if len(mnemonic) == 0 { filePV, _ = privval.LoadOrGenFilePV(pvKeyFile, pvStateFile) } else { - privKey := tmed25519.GenPrivKeyFromSecret([]byte(mnemonic)) + privKey := tmed25519.TestSecretKey([]byte(mnemonic)) filePV = privval.NewFilePV(privKey, pvKeyFile, pvStateFile) } diff --git a/sei-ibc-go/testing/chain.go b/sei-ibc-go/testing/chain.go index f88c975b4d..25030a1261 100644 --- a/sei-ibc-go/testing/chain.go +++ b/sei-ibc-go/testing/chain.go @@ -30,6 +30,8 @@ import ( tmproto "github.com/tendermint/tendermint/proto/tendermint/types" tmtypes "github.com/tendermint/tendermint/types" tmversion "github.com/tendermint/tendermint/version" + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/libs/utils" clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" commitmenttypes "github.com/cosmos/ibc-go/v3/modules/core/23-commitment/types" @@ -490,7 +492,7 @@ func (chain *TestChain) CreateTMClientHeader(chainID string, blockHeight int64, v := vote.ToProto() err := privVal.SignVote(chain.T.Context(), chainID, v) require.NoError(chain.T, err) - vote.Signature = v.Signature + vote.Signature = utils.Some(utils.OrPanic1(crypto.SigFromBytes(v.Signature))) voteSet.AddVote(vote) } diff --git a/sei-ibc-go/testing/mock/privval_test.go b/sei-ibc-go/testing/mock/privval_test.go index 4b64b7924f..4bb1dd2186 100644 --- a/sei-ibc-go/testing/mock/privval_test.go +++ b/sei-ibc-go/testing/mock/privval_test.go @@ -3,9 +3,11 @@ package mock_test import ( "testing" - "github.com/stretchr/testify/require" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" tmtypes "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/libs/utils" + "github.com/tendermint/tendermint/libs/utils/require" + "github.com/tendermint/tendermint/crypto" "github.com/cosmos/ibc-go/v3/testing/mock" ) @@ -27,8 +29,7 @@ func TestSignVote(t *testing.T) { pv.SignVote(t.Context(), chainID, vote) msg := tmtypes.VoteSignBytes(chainID, vote) - ok := pk.VerifySignature(msg, vote.Signature) - require.True(t, ok) + require.NoError(t, pk.Verify(msg, utils.OrPanic1(crypto.SigFromBytes(vote.Signature)))) } func TestSignProposal(t *testing.T) { @@ -39,6 +40,5 @@ func TestSignProposal(t *testing.T) { pv.SignProposal(t.Context(), chainID, proposal) msg := tmtypes.ProposalSignBytes(chainID, proposal) - ok := pk.VerifySignature(msg, proposal.Signature) - require.True(t, ok) + require.NoError(t,pk.Verify(msg, utils.OrPanic1(crypto.SigFromBytes(proposal.Signature)))) } diff --git a/sei-tendermint/crypto/ed25519/ed25519.go b/sei-tendermint/crypto/ed25519/ed25519.go index 116aa38158..2571601d8c 100644 --- a/sei-tendermint/crypto/ed25519/ed25519.go +++ b/sei-tendermint/crypto/ed25519/ed25519.go @@ -47,6 +47,13 @@ type SecretKey struct { _ utils.NoCompare } +// WARNING: this function should only be used when persisting the private key. +// TODO(gprusak): this should return a read-only slice - in particular, +// SecretKeyFromSecretBytes(k.SecretBytes()) would wipe k currently. +func (k SecretKey) SecretBytes() []byte { + return (*k.key)[:] +} + // SecretKeyFromSecretBytes constructs a secret key from a raw secret material. // WARNING: this function zeroes the content of the input slice. func SecretKeyFromSecretBytes(b []byte) (SecretKey, error) { diff --git a/sei-wasmd/x/wasm/ibctesting/chain.go b/sei-wasmd/x/wasm/ibctesting/chain.go index c5ce896d3a..27fd84f934 100644 --- a/sei-wasmd/x/wasm/ibctesting/chain.go +++ b/sei-wasmd/x/wasm/ibctesting/chain.go @@ -34,6 +34,7 @@ import ( "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/crypto/tmhash" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" tmtypes "github.com/tendermint/tendermint/types" @@ -485,7 +486,7 @@ func (chain *TestChain) CreateTMClientHeader(chainID string, blockHeight int64, v := vote.ToProto() err := privVal.SignVote(context.Background(), chainID, v) require.NoError(chain.t, err) - vote.Signature = v.Signature + vote.Signature = utils.Some(utils.OrPanic1(crypto.SigFromBytes(v.Signature))) voteSet.AddVote(vote) } diff --git a/sei-wasmd/x/wasm/keeper/test_common.go b/sei-wasmd/x/wasm/keeper/test_common.go index 4664b5fe68..07c04f774d 100644 --- a/sei-wasmd/x/wasm/keeper/test_common.go +++ b/sei-wasmd/x/wasm/keeper/test_common.go @@ -720,8 +720,8 @@ func keyPubAddr() (crypto.PrivKey, crypto.PubKey, sdk.AccAddress) { seed := make([]byte, 8) binary.BigEndian.PutUint64(seed, keyCounter) - key := ed25519.GenPrivKeyFromSecret(seed) - pub := key.PubKey() + key := ed25519.TestSecretKey(seed) + pub := key.Public() addr := sdk.AccAddress(pub.Address()) return key, pub, addr } diff --git a/sei-wasmd/x/wasm/module_test.go b/sei-wasmd/x/wasm/module_test.go index 8501df3486..962e797e69 100644 --- a/sei-wasmd/x/wasm/module_test.go +++ b/sei-wasmd/x/wasm/module_test.go @@ -48,8 +48,8 @@ func setupTest(t *testing.T) testData { } func keyPubAddr() (crypto.PrivKey, crypto.PubKey, sdk.AccAddress) { - key := ed25519.GenPrivKey() - pub := key.PubKey() + key := ed25519.GenerateSecretKey() + pub := key.Public() addr := sdk.AccAddress(pub.Address()) return key, pub, addr } diff --git a/x/tokenfactory/types/msgs_test.go b/x/tokenfactory/types/msgs_test.go index 981c3f0424..a3b58dab82 100644 --- a/x/tokenfactory/types/msgs_test.go +++ b/x/tokenfactory/types/msgs_test.go @@ -16,7 +16,7 @@ import ( // TestMsgCreateDenom tests if valid/invalid create denom messages are properly validated/invalidated func TestMsgCreateDenom(t *testing.T) { // generate a private/public key pair and get the respective address - pk1 := ed25519.GenPrivKey().PubKey() + pk1 := ed25519.GenerateSecretKey().Public() addr1 := sdk.AccAddress(pk1.Address()) // make a proper createDenom message @@ -80,7 +80,7 @@ func TestMsgCreateDenom(t *testing.T) { func TestMsgUpdateDenom(t *testing.T) { // generate a private/public key pair and get the respective address - pk1 := ed25519.GenPrivKey().PubKey() + pk1 := ed25519.GenerateSecretKey().Public() addr1 := sdk.AccAddress(pk1.Address()) // make a proper createDenom message @@ -146,7 +146,7 @@ func TestMsgUpdateDenom(t *testing.T) { // TestMsgMint tests if valid/invalid create denom messages are properly validated/invalidated func TestMsgMint(t *testing.T) { // generate a private/public key pair and get the respective address - pk1 := ed25519.GenPrivKey().PubKey() + pk1 := ed25519.GenerateSecretKey().Public() addr1 := sdk.AccAddress(pk1.Address()) // make a proper mint message @@ -219,7 +219,7 @@ func TestMsgMint(t *testing.T) { // TestMsgBurn tests if valid/invalid create denom messages are properly validated/invalidated func TestMsgBurn(t *testing.T) { // generate a private/public key pair and get the respective address - pk1 := ed25519.GenPrivKey().PubKey() + pk1 := ed25519.GenerateSecretKey().Public() addr1 := sdk.AccAddress(pk1.Address()) // make a proper burn message @@ -289,9 +289,9 @@ func TestMsgBurn(t *testing.T) { // TestMsgChangeAdmin tests if valid/invalid create denom messages are properly validated/invalidated func TestMsgChangeAdmin(t *testing.T) { // generate a private/public key pair and get the respective address - pk1 := ed25519.GenPrivKey().PubKey() + pk1 := ed25519.GenerateSecretKey().Public() addr1 := sdk.AccAddress(pk1.Address()) - pk2 := ed25519.GenPrivKey().PubKey() + pk2 := ed25519.GenerateSecretKey().Public() addr2 := sdk.AccAddress(pk2.Address()) tokenFactoryDenom := fmt.Sprintf("factory/%s/bitcoin", addr1.String()) From e0043d071023c9d320feab1364f6172c25c9b234 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Thu, 18 Dec 2025 13:25:43 +0100 Subject: [PATCH 39/53] fmt --- sei-tendermint/crypto/ed25519/bench_test.go | 2 +- sei-tendermint/crypto/ed25519/conv.go | 4 +-- sei-tendermint/crypto/ed25519/ed25519.go | 13 ++++++--- sei-tendermint/crypto/ed25519/ed25519_test.go | 4 +-- sei-tendermint/crypto/ed25519/json.go | 5 ++-- sei-tendermint/internal/evidence/verify.go | 4 +-- sei-tendermint/internal/state/helpers_test.go | 2 +- sei-tendermint/light/helpers_test.go | 2 +- sei-tendermint/privval/grpc/server_test.go | 4 +-- sei-tendermint/rpc/client/rpc_test.go | 10 +++---- sei-tendermint/types/block.go | 20 ++++++------- sei-tendermint/types/block_test.go | 2 +- sei-tendermint/types/evidence.go | 18 ++++++++---- sei-tendermint/types/proposal_test.go | 2 +- sei-tendermint/types/validation.go | 10 ++++--- sei-tendermint/types/validator.go | 2 +- sei-tendermint/types/validator_set_test.go | 10 +++---- sei-tendermint/types/validator_test.go | 6 ++-- sei-tendermint/types/vote.go | 28 +++++++++---------- 19 files changed, 79 insertions(+), 69 deletions(-) diff --git a/sei-tendermint/crypto/ed25519/bench_test.go b/sei-tendermint/crypto/ed25519/bench_test.go index c74d3cf46c..341897e058 100644 --- a/sei-tendermint/crypto/ed25519/bench_test.go +++ b/sei-tendermint/crypto/ed25519/bench_test.go @@ -32,7 +32,7 @@ func BenchmarkVerifyBatch(b *testing.B) { pubs := make([]PublicKey, 0, sigsCount) sigs := make([]Signature, 0, sigsCount) for i := range sigsCount { - priv := TestSecretKey(fmt.Appendf(nil,"test-%v",i)) + priv := TestSecretKey(fmt.Appendf(nil, "test-%v", i)) pubs = append(pubs, priv.Public()) sigs = append(sigs, priv.Sign(msg)) } diff --git a/sei-tendermint/crypto/ed25519/conv.go b/sei-tendermint/crypto/ed25519/conv.go index c0e09ae5e4..99f2b4db9e 100644 --- a/sei-tendermint/crypto/ed25519/conv.go +++ b/sei-tendermint/crypto/ed25519/conv.go @@ -6,8 +6,8 @@ import ( "encoding/hex" "errors" "fmt" - "strings" tmbytes "github.com/tendermint/tendermint/libs/bytes" + "strings" ) // Bytes converts the public key or signature to bytes. @@ -68,5 +68,3 @@ func (k PublicKey) Address() tmbytes.HexBytes { h := sha256.Sum256(k.Bytes()) return tmbytes.HexBytes(h[:20]) } - - diff --git a/sei-tendermint/crypto/ed25519/ed25519.go b/sei-tendermint/crypto/ed25519/ed25519.go index 2571601d8c..5f304c4936 100644 --- a/sei-tendermint/crypto/ed25519/ed25519.go +++ b/sei-tendermint/crypto/ed25519/ed25519.go @@ -1,10 +1,10 @@ package ed25519 import ( + "bytes" "crypto/rand" "crypto/sha256" "fmt" - "bytes" "runtime" "github.com/oasisprotocol/curve25519-voi/primitives/ed25519" @@ -87,12 +87,16 @@ func TestSecretKey(seed []byte) SecretKey { // GenerateSecretKey generates a new secret key using a cryptographically secure random number generator. func GenerateSecretKey() SecretKey { - var seed [ed25519.SeedSize]byte + var seed [ed25519.SeedSize]byte // rand.Read is documented to never return an error. - if _, err := rand.Read(seed[:]); err != nil { panic(err) } + if _, err := rand.Read(seed[:]); err != nil { + panic(err) + } // Generated key is always valid. key, err := SecretKeyFromSecretBytes(ed25519.NewKeyFromSeed(seed[:])) - if err!=nil { panic(err) } + if err != nil { + panic(err) + } // Zeroize the seed after generation. for i := range seed { seed[i] = 0 @@ -137,6 +141,7 @@ func (k PublicKey) Verify(msg []byte, sig Signature) error { } return nil } + // BatchVerifier implements batch verification for ed25519. type BatchVerifier struct{ inner *ed25519.BatchVerifier } diff --git a/sei-tendermint/crypto/ed25519/ed25519_test.go b/sei-tendermint/crypto/ed25519/ed25519_test.go index 79a5921cc3..3357e1e652 100644 --- a/sei-tendermint/crypto/ed25519/ed25519_test.go +++ b/sei-tendermint/crypto/ed25519/ed25519_test.go @@ -1,9 +1,9 @@ package ed25519 import ( - "testing" "fmt" "github.com/tendermint/tendermint/libs/utils/require" + "testing" ) func TestSign(t *testing.T) { @@ -26,7 +26,7 @@ func TestBatchSafe(t *testing.T) { v := NewBatchVerifier() for i := 0; i <= 38; i++ { - priv := TestSecretKey(fmt.Appendf(nil,"test-%v",i)) + priv := TestSecretKey(fmt.Appendf(nil, "test-%v", i)) pub := priv.Public() var msg []byte diff --git a/sei-tendermint/crypto/ed25519/json.go b/sei-tendermint/crypto/ed25519/json.go index 53f5ec82c7..d2f8d7a1cc 100644 --- a/sei-tendermint/crypto/ed25519/json.go +++ b/sei-tendermint/crypto/ed25519/json.go @@ -14,12 +14,11 @@ func init() { jsontypes.MustRegister(SecretKey{}) } - func (k SecretKey) TypeTag() string { return SecretKeyName } -func (k SecretKey) Type() string { return KeyType } +func (k SecretKey) Type() string { return KeyType } func (k PublicKey) TypeTag() string { return PublicKeyName } -func (k PublicKey) Type() string { return KeyType } +func (k PublicKey) Type() string { return KeyType } // WARNING: this is very BAD that one can leak a secret by embedding // a private key in some struct and then calling json.Marshal on it. diff --git a/sei-tendermint/internal/evidence/verify.go b/sei-tendermint/internal/evidence/verify.go index 627f4878c5..bc81c0f237 100644 --- a/sei-tendermint/internal/evidence/verify.go +++ b/sei-tendermint/internal/evidence/verify.go @@ -243,11 +243,11 @@ func VerifyDuplicateVote(e *types.DuplicateVoteEvidence, chainID string, valSet va := e.VoteA.ToProto() vb := e.VoteB.ToProto() // Signatures must be valid - sigA,ok := e.VoteA.Signature.Get() + sigA, ok := e.VoteA.Signature.Get() if !ok { return errors.New("VoteA.Signature missing") } - sigB,ok := e.VoteB.Signature.Get() + sigB, ok := e.VoteB.Signature.Get() if !ok { return errors.New("VoteB.Signature missing") } diff --git a/sei-tendermint/internal/state/helpers_test.go b/sei-tendermint/internal/state/helpers_test.go index 31c6552b25..91d351ff43 100644 --- a/sei-tendermint/internal/state/helpers_test.go +++ b/sei-tendermint/internal/state/helpers_test.go @@ -100,7 +100,7 @@ func makeValidCommit( } func makePrivKey(i int) ed25519.SecretKey { - return ed25519.TestSecretKey(fmt.Appendf(nil,"%d", i)) + return ed25519.TestSecretKey(fmt.Appendf(nil, "%d", i)) } func makeState(t *testing.T, nVals, height int) (sm.State, dbm.DB, map[string]types.PrivValidator) { diff --git a/sei-tendermint/light/helpers_test.go b/sei-tendermint/light/helpers_test.go index 548fc5ac8f..1a095c4365 100644 --- a/sei-tendermint/light/helpers_test.go +++ b/sei-tendermint/light/helpers_test.go @@ -9,10 +9,10 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" tmtime "github.com/tendermint/tendermint/libs/time" + "github.com/tendermint/tendermint/libs/utils" provider_mocks "github.com/tendermint/tendermint/light/provider/mocks" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/version" ) diff --git a/sei-tendermint/privval/grpc/server_test.go b/sei-tendermint/privval/grpc/server_test.go index f4b036a8eb..ed79468c6c 100644 --- a/sei-tendermint/privval/grpc/server_test.go +++ b/sei-tendermint/privval/grpc/server_test.go @@ -8,11 +8,11 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/libs/log" - "github.com/tendermint/tendermint/libs/utils/require" tmrand "github.com/tendermint/tendermint/libs/rand" "github.com/tendermint/tendermint/libs/utils" - "github.com/tendermint/tendermint/crypto/encoding" + "github.com/tendermint/tendermint/libs/utils/require" tmgrpc "github.com/tendermint/tendermint/privval/grpc" privvalproto "github.com/tendermint/tendermint/proto/tendermint/privval" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" diff --git a/sei-tendermint/rpc/client/rpc_test.go b/sei-tendermint/rpc/client/rpc_test.go index ee61d410d6..b8c3c5cac5 100644 --- a/sei-tendermint/rpc/client/rpc_test.go +++ b/sei-tendermint/rpc/client/rpc_test.go @@ -23,8 +23,8 @@ import ( "github.com/tendermint/tendermint/libs/log" tmmath "github.com/tendermint/tendermint/libs/math" "github.com/tendermint/tendermint/libs/service" - "github.com/tendermint/tendermint/libs/utils/require" "github.com/tendermint/tendermint/libs/utils" + "github.com/tendermint/tendermint/libs/utils/require" "github.com/tendermint/tendermint/privval" "github.com/tendermint/tendermint/rpc/client" rpchttp "github.com/tendermint/tendermint/rpc/client/http" @@ -875,15 +875,15 @@ func TestClientMethodCallsAdvanced(t *testing.T) { // WARNING: this function is called in subgoroutines to it shouldn't use testing.T. func testBatchedJSONRPCCalls(ctx context.Context, c *rpchttp.HTTP) { - k1,_, tx1 := MakeTxKV() - k2,_, tx2 := MakeTxKV() + k1, _, tx1 := MakeTxKV() + k2, _, tx2 := MakeTxKV() batch := c.NewBatch() r1 := utils.OrPanic1(batch.BroadcastTxCommit(ctx, tx1)) r2 := utils.OrPanic1(batch.BroadcastTxCommit(ctx, tx2)) utils.OrPanic(utils.TestDiff(2, batch.Count())) bresults := utils.OrPanic1(batch.Send(ctx)) - utils.OrPanic(utils.TestDiff(bresults, []any{r1,r2})) + utils.OrPanic(utils.TestDiff(bresults, []any{r1, r2})) utils.OrPanic(utils.TestDiff(0, batch.Count())) apph := tmmath.MaxInt64(r1.Height, r2.Height) + 1 @@ -893,5 +893,5 @@ func testBatchedJSONRPCCalls(ctx context.Context, c *rpchttp.HTTP) { q2 := utils.OrPanic1(batch.ABCIQuery(ctx, "/key", k2)) utils.OrPanic(utils.TestDiff(2, batch.Count())) qresults := utils.OrPanic1(batch.Send(ctx)) - utils.OrPanic(utils.TestDiff(qresults, []any{q1,q2})) + utils.OrPanic(utils.TestDiff(qresults, []any{q1, q2})) } diff --git a/sei-tendermint/types/block.go b/sei-tendermint/types/block.go index 3833bf6027..a7a43ec839 100644 --- a/sei-tendermint/types/block.go +++ b/sei-tendermint/types/block.go @@ -17,8 +17,8 @@ import ( "github.com/tendermint/tendermint/libs/bits" tmbytes "github.com/tendermint/tendermint/libs/bytes" tmmath "github.com/tendermint/tendermint/libs/math" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/libs/utils" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/version" ) @@ -246,8 +246,8 @@ func (b *Block) ToReqBeginBlock(vals []*Validator) abci.RequestBeginBlock { }) } var byzantineValidators []abci.Evidence - for _,e := range b.Evidence.ToABCI() { - byzantineValidators = append(byzantineValidators,abci.Evidence(e)) + for _, e := range b.Evidence.ToABCI() { + byzantineValidators = append(byzantineValidators, abci.Evidence(e)) } return abci.RequestBeginBlock{ Hash: b.hash, @@ -256,7 +256,7 @@ func (b *Block) ToReqBeginBlock(vals []*Validator) abci.RequestBeginBlock { Round: b.LastCommit.Round, Votes: votes, }, - ByzantineValidators: byzantineValidators, + ByzantineValidators: byzantineValidators, } } @@ -643,8 +643,8 @@ const ( type CommitSig struct { BlockIDFlag BlockIDFlag `json:"block_id_flag"` // WARNING: all fields below should be zeroed if BlockIDFlag == BlockIDFlagAbsent - ValidatorAddress Address `json:"validator_address"` - Timestamp time.Time `json:"timestamp"` + ValidatorAddress Address `json:"validator_address"` + Timestamp time.Time `json:"timestamp"` Signature utils.Option[crypto.Sig] `json:"signature"` } @@ -670,7 +670,7 @@ func NewCommitSigAbsent() CommitSig { // 4. timestamp func (cs CommitSig) String() string { var sigBytes []byte - if sig,ok := cs.Signature.Get(); ok { + if sig, ok := cs.Signature.Get(); ok { sigBytes = sig.Bytes() } return fmt.Sprintf("CommitSig{%X by %X on %v @ %s}", @@ -740,7 +740,7 @@ func (cs *CommitSig) ToProto() *tmproto.CommitSig { return nil } var signature []byte - if sig,ok := cs.Signature.Get(); ok { + if sig, ok := cs.Signature.Get(); ok { signature = sig.Bytes() } return &tmproto.CommitSig{ @@ -757,8 +757,8 @@ func (cs *CommitSig) FromProto(csp tmproto.CommitSig) error { cs.BlockIDFlag = BlockIDFlag(csp.BlockIdFlag) cs.ValidatorAddress = csp.ValidatorAddress cs.Timestamp = csp.Timestamp - - if len(csp.Signature)>0 { + + if len(csp.Signature) > 0 { sig, err := crypto.SigFromBytes(csp.Signature) if err != nil { return fmt.Errorf("Signature: %w", err) diff --git a/sei-tendermint/types/block_test.go b/sei-tendermint/types/block_test.go index 02ea18be35..3d10be46f2 100644 --- a/sei-tendermint/types/block_test.go +++ b/sei-tendermint/types/block_test.go @@ -381,7 +381,7 @@ func TestCommitValidateBasic(t *testing.T) { tc.malleateCommit(com) err := com.ValidateBasic() - assert.Equal(t, tc.expectErr, err != nil, "Validate Basic had an unexpected result: %v",err) + assert.Equal(t, tc.expectErr, err != nil, "Validate Basic had an unexpected result: %v", err) }) } } diff --git a/sei-tendermint/types/evidence.go b/sei-tendermint/types/evidence.go index d7277940ef..68b203e611 100644 --- a/sei-tendermint/types/evidence.go +++ b/sei-tendermint/types/evidence.go @@ -13,11 +13,11 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/crypto/merkle" "github.com/tendermint/tendermint/internal/jsontypes" tmmath "github.com/tendermint/tendermint/libs/math" tmrand "github.com/tendermint/tendermint/libs/rand" + "github.com/tendermint/tendermint/libs/utils" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) @@ -856,16 +856,22 @@ func NewMockDuplicateVoteEvidenceWithValidator(ctx context.Context, height int64 val := NewValidator(pubKey, 10) voteA := makeMockVote(height, 0, 0, pubKey.Address(), randBlockID(), time) vA := voteA.ToProto() - if err:=pv.SignVote(ctx, chainID, vA); err!=nil { return nil,err } - sig,err := crypto.SigFromBytes(vA.Signature) - if err != nil { return nil, err } + if err := pv.SignVote(ctx, chainID, vA); err != nil { + return nil, err + } + sig, err := crypto.SigFromBytes(vA.Signature) + if err != nil { + return nil, err + } voteA.Signature = utils.Some(sig) voteB := makeMockVote(height, 0, 0, pubKey.Address(), randBlockID(), time) vB := voteB.ToProto() _ = pv.SignVote(ctx, chainID, vB) - sig,err = crypto.SigFromBytes(vB.Signature) - if err != nil { return nil, err } + sig, err = crypto.SigFromBytes(vB.Signature) + if err != nil { + return nil, err + } voteB.Signature = utils.Some(sig) ev, err := NewDuplicateVoteEvidence(voteA, voteB, time, NewValidatorSet([]*Validator{val})) if err != nil { diff --git a/sei-tendermint/types/proposal_test.go b/sei-tendermint/types/proposal_test.go index 127969bf56..8a9c9bdfc2 100644 --- a/sei-tendermint/types/proposal_test.go +++ b/sei-tendermint/types/proposal_test.go @@ -187,7 +187,7 @@ func TestProposalValidateBasic(t *testing.T) { prop.Signature = utils.OrPanic1(crypto.SigFromBytes(p.Signature)) tc.malleateProposal(prop) err = prop.ValidateBasic() - assert.Equal(t, tc.expectErr, err != nil, "Validate Basic had an unexpected result: %v",err) + assert.Equal(t, tc.expectErr, err != nil, "Validate Basic had an unexpected result: %v", err) }) } } diff --git a/sei-tendermint/types/validation.go b/sei-tendermint/types/validation.go index c87e362e71..f18389a72c 100644 --- a/sei-tendermint/types/validation.go +++ b/sei-tendermint/types/validation.go @@ -206,8 +206,10 @@ func verifyCommitBatch( voteSignBytes := commit.VoteSignBytes(chainID, int32(idx)) // add the key, sig and message to the verifier - sig,ok := commitSig.Signature.Get() - if !ok { return fmt.Errorf("missing signature at idx %v",idx) } + sig, ok := commitSig.Signature.Get() + if !ok { + return fmt.Errorf("missing signature at idx %v", idx) + } bv.Add(val.PubKey, voteSignBytes, sig) batchSigIdxs = append(batchSigIdxs, idx) @@ -293,9 +295,9 @@ func verifyCommitSingle( } voteSignBytes = commit.VoteSignBytes(chainID, int32(idx)) - sig,ok := commitSig.Signature.Get() + sig, ok := commitSig.Signature.Get() if !ok { - return fmt.Errorf("missing signature at idx %v",idx) + return fmt.Errorf("missing signature at idx %v", idx) } if err := val.PubKey.Verify(voteSignBytes, sig); err != nil { return errBadSig{fmt.Errorf("wrong signature (#%d): %v", idx, sig)} diff --git a/sei-tendermint/types/validator.go b/sei-tendermint/types/validator.go index 06e21170e6..6d16d74a56 100644 --- a/sei-tendermint/types/validator.go +++ b/sei-tendermint/types/validator.go @@ -72,7 +72,7 @@ func NewValidator(pubKey crypto.PubKey, votingPower int64) *Validator { var ErrNilValidator = errors.New("nil validator") var ErrNegativeVotingPower = errors.New("validator has negative voting power") -var ErrBadAddressSize = errors.New("validator address has bad size") +var ErrBadAddressSize = errors.New("validator address has bad size") // ValidateBasic performs basic validation. func (v *Validator) ValidateBasic() error { diff --git a/sei-tendermint/types/validator_set_test.go b/sei-tendermint/types/validator_set_test.go index db7b5862e0..251885d983 100644 --- a/sei-tendermint/types/validator_set_test.go +++ b/sei-tendermint/types/validator_set_test.go @@ -3,6 +3,7 @@ package types import ( "bytes" "context" + "errors" "fmt" "math" "math/rand" @@ -11,15 +12,14 @@ import ( "testing" "testing/quick" "time" - "errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/crypto/ed25519" tmmath "github.com/tendermint/tendermint/libs/math" + "github.com/tendermint/tendermint/libs/utils" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) @@ -135,8 +135,8 @@ func TestValidatorSetValidateBasic(t *testing.T) { for _, tc := range testCases { err := tc.vals.ValidateBasic() - if wantErr,ok := tc.err.Get(); ok { - assert.True(t, errors.Is(err,wantErr)) + if wantErr, ok := tc.err.Get(); ok { + assert.True(t, errors.Is(err, wantErr)) } else { assert.NoError(t, err) } @@ -1624,7 +1624,7 @@ func deterministicValidatorSet(ctx context.Context, t *testing.T) (*ValidatorSet for i := range 10 { // WARNING: this key has to be stable, otherwise hashes break. - val, privValidator := deterministicValidator(ctx, t, ed25519.TestSecretKey(fmt.Appendf(nil,"key: %x", i))) + val, privValidator := deterministicValidator(ctx, t, ed25519.TestSecretKey(fmt.Appendf(nil, "key: %x", i))) valz[i] = val privValidators[i] = privValidator } diff --git a/sei-tendermint/types/validator_test.go b/sei-tendermint/types/validator_test.go index e6117f7284..9a2b88cab9 100644 --- a/sei-tendermint/types/validator_test.go +++ b/sei-tendermint/types/validator_test.go @@ -2,8 +2,8 @@ package types import ( "context" - "testing" "errors" + "testing" "github.com/stretchr/testify/assert" @@ -84,8 +84,8 @@ func TestValidatorValidateBasic(t *testing.T) { for _, tc := range testCases { err := tc.val.ValidateBasic() - if wantErr,ok := tc.err.Get(); ok { - assert.True(t, errors.Is(err,wantErr)) + if wantErr, ok := tc.err.Get(); ok { + assert.True(t, errors.Is(err, wantErr)) } else { assert.NoError(t, err) } diff --git a/sei-tendermint/types/vote.go b/sei-tendermint/types/vote.go index 3b1207a5ff..e9540184c1 100644 --- a/sei-tendermint/types/vote.go +++ b/sei-tendermint/types/vote.go @@ -7,9 +7,9 @@ import ( "time" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/internal/libs/protoio" tmbytes "github.com/tendermint/tendermint/libs/bytes" + "github.com/tendermint/tendermint/libs/utils" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) @@ -49,14 +49,14 @@ type Address = crypto.Address // Vote represents a prevote, precommit, or commit vote from validators for // consensus. type Vote struct { - Type tmproto.SignedMsgType `json:"type"` - Height int64 `json:"height,string"` - Round int32 `json:"round"` // assume there will not be greater than 2_147_483_647 rounds - BlockID BlockID `json:"block_id"` // zero if vote is nil. - Timestamp time.Time `json:"timestamp"` - ValidatorAddress Address `json:"validator_address"` - ValidatorIndex int32 `json:"validator_index"` - Signature utils.Option[crypto.Sig] `json:"signature"` + Type tmproto.SignedMsgType `json:"type"` + Height int64 `json:"height,string"` + Round int32 `json:"round"` // assume there will not be greater than 2_147_483_647 rounds + BlockID BlockID `json:"block_id"` // zero if vote is nil. + Timestamp time.Time `json:"timestamp"` + ValidatorAddress Address `json:"validator_address"` + ValidatorIndex int32 `json:"validator_index"` + Signature utils.Option[crypto.Sig] `json:"signature"` } // VoteFromProto attempts to convert the given serialization (Protobuf) type to @@ -69,7 +69,7 @@ func VoteFromProto(pv *tmproto.Vote) (*Vote, error) { return nil, err } signature := utils.None[crypto.Sig]() - if len(pv.Signature)>0 { + if len(pv.Signature) > 0 { sig, err := crypto.SigFromBytes(pv.Signature) if err != nil { return nil, fmt.Errorf("Signature: %w", err) @@ -163,7 +163,7 @@ func (vote *Vote) String() string { } var sigBytes []byte - if sig,ok := vote.Signature.Get(); ok { + if sig, ok := vote.Signature.Get(); ok { sigBytes = sig.Bytes() } @@ -185,9 +185,9 @@ func (vote *Vote) verifyAndReturnProto(chainID string, pubKey crypto.PubKey) (*t return nil, ErrVoteInvalidValidatorAddress } v := vote.ToProto() - sig,ok := vote.Signature.Get() + sig, ok := vote.Signature.Get() if !ok { - return nil, ErrVoteInvalidSignature + return nil, ErrVoteInvalidSignature } if err := pubKey.Verify(VoteSignBytes(chainID, v), sig); err != nil { return nil, ErrVoteInvalidSignature @@ -251,7 +251,7 @@ func (vote *Vote) ToProto() *tmproto.Vote { } var signature []byte - if sig,ok := vote.Signature.Get(); ok { + if sig, ok := vote.Signature.Get(); ok { signature = sig.Bytes() } From 7aacf5b4b4f709b2ddda75a458224264bdf994e4 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Thu, 18 Dec 2025 13:44:48 +0100 Subject: [PATCH 40/53] moved roles to separate pr --- .../internal/roles/validator/msg.go | 25 -- .../roles/validator/pb/validator.hashable.go | 4 - .../roles/validator/pb/validator.pb.go | 314 ------------------ .../internal/roles/validator/validator.proto | 30 -- 4 files changed, 373 deletions(-) delete mode 100644 sei-tendermint/internal/roles/validator/msg.go delete mode 100644 sei-tendermint/internal/roles/validator/pb/validator.hashable.go delete mode 100644 sei-tendermint/internal/roles/validator/pb/validator.pb.go delete mode 100644 sei-tendermint/internal/roles/validator/validator.proto diff --git a/sei-tendermint/internal/roles/validator/msg.go b/sei-tendermint/internal/roles/validator/msg.go deleted file mode 100644 index 26e609401e..0000000000 --- a/sei-tendermint/internal/roles/validator/msg.go +++ /dev/null @@ -1,25 +0,0 @@ -package validator - -import ( - "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/libs/utils" -) - -type Msg interface{ isMsg() } - -type SessionID struct { - utils.ReadOnly - raw [10]byte -} - -func (s *SessionID) Raw() [10]byte { return s.raw } - -func (s *SessionID) isMsg() {} - -type Sig struct{ inner ed25519.Signature } - -type Signed[M Msg] struct { - utils.ReadOnly - msg M - sig Sig -} diff --git a/sei-tendermint/internal/roles/validator/pb/validator.hashable.go b/sei-tendermint/internal/roles/validator/pb/validator.hashable.go deleted file mode 100644 index 81d810592a..0000000000 --- a/sei-tendermint/internal/roles/validator/pb/validator.hashable.go +++ /dev/null @@ -1,4 +0,0 @@ -// Code generated by sei-tendermint/hashable/plugin. DO NOT EDIT. -package pb - -func (*Msg) IsHashable() {} diff --git a/sei-tendermint/internal/roles/validator/pb/validator.pb.go b/sei-tendermint/internal/roles/validator/pb/validator.pb.go deleted file mode 100644 index 703295036a..0000000000 --- a/sei-tendermint/internal/roles/validator/pb/validator.pb.go +++ /dev/null @@ -1,314 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.36.10 -// protoc (unknown) -// source: roles/validator/validator.proto - -package pb - -import ( - _ "github.com/tendermint/tendermint/internal/hashable/pb" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" - unsafe "unsafe" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Msg struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Types that are valid to be assigned to Kind: - // - // *Msg_SessionId - Kind isMsg_Kind `protobuf_oneof:"kind"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Msg) Reset() { - *x = Msg{} - mi := &file_roles_validator_validator_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Msg) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Msg) ProtoMessage() {} - -func (x *Msg) ProtoReflect() protoreflect.Message { - mi := &file_roles_validator_validator_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Msg.ProtoReflect.Descriptor instead. -func (*Msg) Descriptor() ([]byte, []int) { - return file_roles_validator_validator_proto_rawDescGZIP(), []int{0} -} - -func (x *Msg) GetKind() isMsg_Kind { - if x != nil { - return x.Kind - } - return nil -} - -func (x *Msg) GetSessionId() []byte { - if x != nil { - if x, ok := x.Kind.(*Msg_SessionId); ok { - return x.SessionId - } - } - return nil -} - -type isMsg_Kind interface { - isMsg_Kind() -} - -type Msg_SessionId struct { - // Encrypted session key to sign in handshake to prove - // that we are a validator. - SessionId []byte `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3,oneof"` -} - -func (*Msg_SessionId) isMsg_Kind() {} - -type PublicKey struct { - state protoimpl.MessageState `protogen:"open.v1"` - Ed25519 []byte `protobuf:"bytes,1,opt,name=ed25519,proto3" json:"ed25519,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *PublicKey) Reset() { - *x = PublicKey{} - mi := &file_roles_validator_validator_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *PublicKey) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PublicKey) ProtoMessage() {} - -func (x *PublicKey) ProtoReflect() protoreflect.Message { - mi := &file_roles_validator_validator_proto_msgTypes[1] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PublicKey.ProtoReflect.Descriptor instead. -func (*PublicKey) Descriptor() ([]byte, []int) { - return file_roles_validator_validator_proto_rawDescGZIP(), []int{1} -} - -func (x *PublicKey) GetEd25519() []byte { - if x != nil { - return x.Ed25519 - } - return nil -} - -type Signature struct { - state protoimpl.MessageState `protogen:"open.v1"` - Ed25519 []byte `protobuf:"bytes,1,opt,name=ed25519,proto3" json:"ed25519,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Signature) Reset() { - *x = Signature{} - mi := &file_roles_validator_validator_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Signature) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Signature) ProtoMessage() {} - -func (x *Signature) ProtoReflect() protoreflect.Message { - mi := &file_roles_validator_validator_proto_msgTypes[2] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Signature.ProtoReflect.Descriptor instead. -func (*Signature) Descriptor() ([]byte, []int) { - return file_roles_validator_validator_proto_rawDescGZIP(), []int{2} -} - -func (x *Signature) GetEd25519() []byte { - if x != nil { - return x.Ed25519 - } - return nil -} - -type SignedMsg struct { - state protoimpl.MessageState `protogen:"open.v1"` - Msg *Msg `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"` - Key *PublicKey `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` - Sig *Signature `protobuf:"bytes,3,opt,name=sig,proto3" json:"sig,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *SignedMsg) Reset() { - *x = SignedMsg{} - mi := &file_roles_validator_validator_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *SignedMsg) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SignedMsg) ProtoMessage() {} - -func (x *SignedMsg) ProtoReflect() protoreflect.Message { - mi := &file_roles_validator_validator_proto_msgTypes[3] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SignedMsg.ProtoReflect.Descriptor instead. -func (*SignedMsg) Descriptor() ([]byte, []int) { - return file_roles_validator_validator_proto_rawDescGZIP(), []int{3} -} - -func (x *SignedMsg) GetMsg() *Msg { - if x != nil { - return x.Msg - } - return nil -} - -func (x *SignedMsg) GetKey() *PublicKey { - if x != nil { - return x.Key - } - return nil -} - -func (x *SignedMsg) GetSig() *Signature { - if x != nil { - return x.Sig - } - return nil -} - -var File_roles_validator_validator_proto protoreflect.FileDescriptor - -const file_roles_validator_validator_proto_rawDesc = "" + - "\n" + - "\x1froles/validator/validator.proto\x12\x0froles.validator\x1a\x17hashable/hashable.proto\"6\n" + - "\x03Msg\x12\x1f\n" + - "\n" + - "session_id\x18\x01 \x01(\fH\x00R\tsessionId:\x06Ȉ\xe2\xab\f\x01B\x06\n" + - "\x04kind\"%\n" + - "\tPublicKey\x12\x18\n" + - "\aed25519\x18\x01 \x01(\fR\aed25519\"%\n" + - "\tSignature\x12\x18\n" + - "\aed25519\x18\x01 \x01(\fR\aed25519\"\x8f\x01\n" + - "\tSignedMsg\x12&\n" + - "\x03msg\x18\x01 \x01(\v2\x14.roles.validator.MsgR\x03msg\x12,\n" + - "\x03key\x18\x02 \x01(\v2\x1a.roles.validator.PublicKeyR\x03key\x12,\n" + - "\x03sig\x18\x03 \x01(\v2\x1a.roles.validator.SignatureR\x03sigB>Z roles.validator.Msg - 1, // 1: roles.validator.SignedMsg.key:type_name -> roles.validator.PublicKey - 2, // 2: roles.validator.SignedMsg.sig:type_name -> roles.validator.Signature - 3, // [3:3] is the sub-list for method output_type - 3, // [3:3] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name -} - -func init() { file_roles_validator_validator_proto_init() } -func file_roles_validator_validator_proto_init() { - if File_roles_validator_validator_proto != nil { - return - } - file_roles_validator_validator_proto_msgTypes[0].OneofWrappers = []any{ - (*Msg_SessionId)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_roles_validator_validator_proto_rawDesc), len(file_roles_validator_validator_proto_rawDesc)), - NumEnums: 0, - NumMessages: 4, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_roles_validator_validator_proto_goTypes, - DependencyIndexes: file_roles_validator_validator_proto_depIdxs, - MessageInfos: file_roles_validator_validator_proto_msgTypes, - }.Build() - File_roles_validator_validator_proto = out.File - file_roles_validator_validator_proto_goTypes = nil - file_roles_validator_validator_proto_depIdxs = nil -} diff --git a/sei-tendermint/internal/roles/validator/validator.proto b/sei-tendermint/internal/roles/validator/validator.proto deleted file mode 100644 index cd180bb0c0..0000000000 --- a/sei-tendermint/internal/roles/validator/validator.proto +++ /dev/null @@ -1,30 +0,0 @@ -syntax = "proto3"; - -package roles.validator; - -import "hashable/hashable.proto"; - -option go_package = "github.com/tendermint/tendermint/internal/roles/validator/pb"; - -message Msg { - option (hashable.hashable) = true; - oneof kind { - // Encrypted session key to sign in handshake to prove - // that we are a validator. - bytes session_id = 1; - } -} - -message PublicKey { - bytes ed25519 = 1; -} - -message Signature { - bytes ed25519 = 1; -} - -message SignedMsg { - Msg msg = 1; - PublicKey key = 2; - Signature sig = 3; -} From 408f6b4c575b248a742e090ae2f92d98b9793082 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Thu, 18 Dec 2025 13:50:45 +0100 Subject: [PATCH 41/53] gofmt --- sei-ibc-go/testing/chain.go | 4 ++-- sei-ibc-go/testing/mock/privval_test.go | 8 ++++---- sei-wasmd/x/wasm/ibctesting/chain.go | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/sei-ibc-go/testing/chain.go b/sei-ibc-go/testing/chain.go index 0253d3ada7..7cc4b1febb 100644 --- a/sei-ibc-go/testing/chain.go +++ b/sei-ibc-go/testing/chain.go @@ -27,12 +27,12 @@ import ( ibckeeper "github.com/sei-protocol/sei-chain/sei-ibc-go/modules/core/keeper" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/tmhash" + "github.com/tendermint/tendermint/libs/utils" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" tmtypes "github.com/tendermint/tendermint/types" tmversion "github.com/tendermint/tendermint/version" - "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/libs/utils" clienttypes "github.com/sei-protocol/sei-chain/sei-ibc-go/modules/core/02-client/types" commitmenttypes "github.com/sei-protocol/sei-chain/sei-ibc-go/modules/core/23-commitment/types" diff --git a/sei-ibc-go/testing/mock/privval_test.go b/sei-ibc-go/testing/mock/privval_test.go index 73336f7dcf..aa5aac9b50 100644 --- a/sei-ibc-go/testing/mock/privval_test.go +++ b/sei-ibc-go/testing/mock/privval_test.go @@ -3,11 +3,11 @@ package mock_test import ( "testing" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - tmtypes "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/libs/utils/require" - "github.com/tendermint/tendermint/crypto" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + tmtypes "github.com/tendermint/tendermint/types" "github.com/sei-protocol/sei-chain/sei-ibc-go/testing/mock" ) @@ -40,5 +40,5 @@ func TestSignProposal(t *testing.T) { pv.SignProposal(t.Context(), chainID, proposal) msg := tmtypes.ProposalSignBytes(chainID, proposal) - require.NoError(t,pk.Verify(msg, utils.OrPanic1(crypto.SigFromBytes(proposal.Signature)))) + require.NoError(t, pk.Verify(msg, utils.OrPanic1(crypto.SigFromBytes(proposal.Signature)))) } diff --git a/sei-wasmd/x/wasm/ibctesting/chain.go b/sei-wasmd/x/wasm/ibctesting/chain.go index ef7fe622ce..27c0162d45 100644 --- a/sei-wasmd/x/wasm/ibctesting/chain.go +++ b/sei-wasmd/x/wasm/ibctesting/chain.go @@ -35,8 +35,8 @@ import ( "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/crypto/tmhash" + "github.com/tendermint/tendermint/libs/utils" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" tmtypes "github.com/tendermint/tendermint/types" tmversion "github.com/tendermint/tendermint/version" From 469c57da58dc43d5e5c6b80cb77ad889ea4e336a Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Thu, 18 Dec 2025 15:02:34 +0100 Subject: [PATCH 42/53] stupid encoder --- sei-tendermint/crypto/ed25519/amino.go | 28 ++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 sei-tendermint/crypto/ed25519/amino.go diff --git a/sei-tendermint/crypto/ed25519/amino.go b/sei-tendermint/crypto/ed25519/amino.go new file mode 100644 index 0000000000..e2229701f1 --- /dev/null +++ b/sei-tendermint/crypto/ed25519/amino.go @@ -0,0 +1,28 @@ +package ed25519 + +// Another way to leak a secret. Needed for LegacyAminoEncoding. +func (k SecretKey) MarshalAmino() ([]byte, error) { + return k.SecretBytes(), nil +} + +func (k *SecretKey) UnmarshalAmino(secretBytes []byte) error { + x, err := SecretKeyFromSecretBytes(secretBytes) + if err != nil { + return err + } + *k = x + return nil +} + +func (k PublicKey) MarshalAmino() ([]byte, error) { + return k.Bytes(), nil +} + +func (k *PublicKey) UnmarshalAmino(bytes []byte) error { + x, err := PublicKeyFromBytes(bytes) + if err != nil { + return err + } + *k = x + return nil +} From b9c22b93118827940f89b28d1b58f19d092c10e4 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Thu, 18 Dec 2025 15:42:27 +0100 Subject: [PATCH 43/53] cachingVerifier --- sei-tendermint/crypto/ed25519/ed25519.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sei-tendermint/crypto/ed25519/ed25519.go b/sei-tendermint/crypto/ed25519/ed25519.go index 5f304c4936..b17f3dda4f 100644 --- a/sei-tendermint/crypto/ed25519/ed25519.go +++ b/sei-tendermint/crypto/ed25519/ed25519.go @@ -136,7 +136,7 @@ func (k PublicKey) Compare(other PublicKey) int { // Verify verifies a signature using the public key. func (k PublicKey) Verify(msg []byte, sig Signature) error { - if !ed25519.VerifyWithOptions(k.key[:], msg, sig.sig[:], verifyOptions) { + if !cachingVerifier.VerifyWithOptions(k.key[:], msg, sig.sig[:], verifyOptions) { return ErrBadSig{} } return nil From adfabe952635cd11c92ba82fb8dd8fd2b5d691b0 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Fri, 19 Dec 2025 12:03:35 +0100 Subject: [PATCH 44/53] Revert "moved roles to separate pr" This reverts commit 7aacf5b4b4f709b2ddda75a458224264bdf994e4. --- .../internal/roles/validator/msg.go | 25 ++ .../roles/validator/pb/validator.hashable.go | 4 + .../roles/validator/pb/validator.pb.go | 314 ++++++++++++++++++ .../internal/roles/validator/validator.proto | 30 ++ 4 files changed, 373 insertions(+) create mode 100644 sei-tendermint/internal/roles/validator/msg.go create mode 100644 sei-tendermint/internal/roles/validator/pb/validator.hashable.go create mode 100644 sei-tendermint/internal/roles/validator/pb/validator.pb.go create mode 100644 sei-tendermint/internal/roles/validator/validator.proto diff --git a/sei-tendermint/internal/roles/validator/msg.go b/sei-tendermint/internal/roles/validator/msg.go new file mode 100644 index 0000000000..26e609401e --- /dev/null +++ b/sei-tendermint/internal/roles/validator/msg.go @@ -0,0 +1,25 @@ +package validator + +import ( + "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/libs/utils" +) + +type Msg interface{ isMsg() } + +type SessionID struct { + utils.ReadOnly + raw [10]byte +} + +func (s *SessionID) Raw() [10]byte { return s.raw } + +func (s *SessionID) isMsg() {} + +type Sig struct{ inner ed25519.Signature } + +type Signed[M Msg] struct { + utils.ReadOnly + msg M + sig Sig +} diff --git a/sei-tendermint/internal/roles/validator/pb/validator.hashable.go b/sei-tendermint/internal/roles/validator/pb/validator.hashable.go new file mode 100644 index 0000000000..81d810592a --- /dev/null +++ b/sei-tendermint/internal/roles/validator/pb/validator.hashable.go @@ -0,0 +1,4 @@ +// Code generated by sei-tendermint/hashable/plugin. DO NOT EDIT. +package pb + +func (*Msg) IsHashable() {} diff --git a/sei-tendermint/internal/roles/validator/pb/validator.pb.go b/sei-tendermint/internal/roles/validator/pb/validator.pb.go new file mode 100644 index 0000000000..703295036a --- /dev/null +++ b/sei-tendermint/internal/roles/validator/pb/validator.pb.go @@ -0,0 +1,314 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.10 +// protoc (unknown) +// source: roles/validator/validator.proto + +package pb + +import ( + _ "github.com/tendermint/tendermint/internal/hashable/pb" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Msg struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Kind: + // + // *Msg_SessionId + Kind isMsg_Kind `protobuf_oneof:"kind"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Msg) Reset() { + *x = Msg{} + mi := &file_roles_validator_validator_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Msg) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Msg) ProtoMessage() {} + +func (x *Msg) ProtoReflect() protoreflect.Message { + mi := &file_roles_validator_validator_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Msg.ProtoReflect.Descriptor instead. +func (*Msg) Descriptor() ([]byte, []int) { + return file_roles_validator_validator_proto_rawDescGZIP(), []int{0} +} + +func (x *Msg) GetKind() isMsg_Kind { + if x != nil { + return x.Kind + } + return nil +} + +func (x *Msg) GetSessionId() []byte { + if x != nil { + if x, ok := x.Kind.(*Msg_SessionId); ok { + return x.SessionId + } + } + return nil +} + +type isMsg_Kind interface { + isMsg_Kind() +} + +type Msg_SessionId struct { + // Encrypted session key to sign in handshake to prove + // that we are a validator. + SessionId []byte `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3,oneof"` +} + +func (*Msg_SessionId) isMsg_Kind() {} + +type PublicKey struct { + state protoimpl.MessageState `protogen:"open.v1"` + Ed25519 []byte `protobuf:"bytes,1,opt,name=ed25519,proto3" json:"ed25519,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PublicKey) Reset() { + *x = PublicKey{} + mi := &file_roles_validator_validator_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PublicKey) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PublicKey) ProtoMessage() {} + +func (x *PublicKey) ProtoReflect() protoreflect.Message { + mi := &file_roles_validator_validator_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PublicKey.ProtoReflect.Descriptor instead. +func (*PublicKey) Descriptor() ([]byte, []int) { + return file_roles_validator_validator_proto_rawDescGZIP(), []int{1} +} + +func (x *PublicKey) GetEd25519() []byte { + if x != nil { + return x.Ed25519 + } + return nil +} + +type Signature struct { + state protoimpl.MessageState `protogen:"open.v1"` + Ed25519 []byte `protobuf:"bytes,1,opt,name=ed25519,proto3" json:"ed25519,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Signature) Reset() { + *x = Signature{} + mi := &file_roles_validator_validator_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Signature) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Signature) ProtoMessage() {} + +func (x *Signature) ProtoReflect() protoreflect.Message { + mi := &file_roles_validator_validator_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Signature.ProtoReflect.Descriptor instead. +func (*Signature) Descriptor() ([]byte, []int) { + return file_roles_validator_validator_proto_rawDescGZIP(), []int{2} +} + +func (x *Signature) GetEd25519() []byte { + if x != nil { + return x.Ed25519 + } + return nil +} + +type SignedMsg struct { + state protoimpl.MessageState `protogen:"open.v1"` + Msg *Msg `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"` + Key *PublicKey `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` + Sig *Signature `protobuf:"bytes,3,opt,name=sig,proto3" json:"sig,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SignedMsg) Reset() { + *x = SignedMsg{} + mi := &file_roles_validator_validator_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SignedMsg) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignedMsg) ProtoMessage() {} + +func (x *SignedMsg) ProtoReflect() protoreflect.Message { + mi := &file_roles_validator_validator_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignedMsg.ProtoReflect.Descriptor instead. +func (*SignedMsg) Descriptor() ([]byte, []int) { + return file_roles_validator_validator_proto_rawDescGZIP(), []int{3} +} + +func (x *SignedMsg) GetMsg() *Msg { + if x != nil { + return x.Msg + } + return nil +} + +func (x *SignedMsg) GetKey() *PublicKey { + if x != nil { + return x.Key + } + return nil +} + +func (x *SignedMsg) GetSig() *Signature { + if x != nil { + return x.Sig + } + return nil +} + +var File_roles_validator_validator_proto protoreflect.FileDescriptor + +const file_roles_validator_validator_proto_rawDesc = "" + + "\n" + + "\x1froles/validator/validator.proto\x12\x0froles.validator\x1a\x17hashable/hashable.proto\"6\n" + + "\x03Msg\x12\x1f\n" + + "\n" + + "session_id\x18\x01 \x01(\fH\x00R\tsessionId:\x06Ȉ\xe2\xab\f\x01B\x06\n" + + "\x04kind\"%\n" + + "\tPublicKey\x12\x18\n" + + "\aed25519\x18\x01 \x01(\fR\aed25519\"%\n" + + "\tSignature\x12\x18\n" + + "\aed25519\x18\x01 \x01(\fR\aed25519\"\x8f\x01\n" + + "\tSignedMsg\x12&\n" + + "\x03msg\x18\x01 \x01(\v2\x14.roles.validator.MsgR\x03msg\x12,\n" + + "\x03key\x18\x02 \x01(\v2\x1a.roles.validator.PublicKeyR\x03key\x12,\n" + + "\x03sig\x18\x03 \x01(\v2\x1a.roles.validator.SignatureR\x03sigB>Z roles.validator.Msg + 1, // 1: roles.validator.SignedMsg.key:type_name -> roles.validator.PublicKey + 2, // 2: roles.validator.SignedMsg.sig:type_name -> roles.validator.Signature + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_roles_validator_validator_proto_init() } +func file_roles_validator_validator_proto_init() { + if File_roles_validator_validator_proto != nil { + return + } + file_roles_validator_validator_proto_msgTypes[0].OneofWrappers = []any{ + (*Msg_SessionId)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_roles_validator_validator_proto_rawDesc), len(file_roles_validator_validator_proto_rawDesc)), + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_roles_validator_validator_proto_goTypes, + DependencyIndexes: file_roles_validator_validator_proto_depIdxs, + MessageInfos: file_roles_validator_validator_proto_msgTypes, + }.Build() + File_roles_validator_validator_proto = out.File + file_roles_validator_validator_proto_goTypes = nil + file_roles_validator_validator_proto_depIdxs = nil +} diff --git a/sei-tendermint/internal/roles/validator/validator.proto b/sei-tendermint/internal/roles/validator/validator.proto new file mode 100644 index 0000000000..cd180bb0c0 --- /dev/null +++ b/sei-tendermint/internal/roles/validator/validator.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; + +package roles.validator; + +import "hashable/hashable.proto"; + +option go_package = "github.com/tendermint/tendermint/internal/roles/validator/pb"; + +message Msg { + option (hashable.hashable) = true; + oneof kind { + // Encrypted session key to sign in handshake to prove + // that we are a validator. + bytes session_id = 1; + } +} + +message PublicKey { + bytes ed25519 = 1; +} + +message Signature { + bytes ed25519 = 1; +} + +message SignedMsg { + Msg msg = 1; + PublicKey key = 2; + Signature sig = 3; +} From b2ef6a7da835354bed7698df39c8ef24fc4251aa Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Fri, 19 Dec 2025 15:21:10 +0100 Subject: [PATCH 45/53] partial refactor of SecretConnection --- .../internal/p2p/conn/connection.go | 4 +- .../p2p/conn/evil_secret_connection_test.go | 16 +- .../internal/p2p/conn/secret_connection.go | 435 ++++++++---------- .../p2p/conn/secret_connection_test.go | 54 +-- .../proto/tendermint/p2p/conn.proto | 1 + 5 files changed, 233 insertions(+), 277 deletions(-) diff --git a/sei-tendermint/internal/p2p/conn/connection.go b/sei-tendermint/internal/p2p/conn/connection.go index 571a9ced2e..02a50aed92 100644 --- a/sei-tendermint/internal/p2p/conn/connection.go +++ b/sei-tendermint/internal/p2p/conn/connection.go @@ -103,7 +103,7 @@ initialization of the connection. type MConnection struct { logger log.Logger - conn net.Conn + conn *SecretConnection sendQueue utils.Watch[*sendQueue] recvPong utils.Mutex[*utils.AtomicSend[bool]] recvCh chan mConnMessage @@ -180,7 +180,7 @@ func (q *sendQueue) setFlush(t time.Time) { // NewMConnection wraps net.Conn and creates multiplex connection with a config func NewMConnection( logger log.Logger, - conn net.Conn, + conn *SecretConnection, chDescs []*ChannelDescriptor, config MConnConfig, ) *MConnection { diff --git a/sei-tendermint/internal/p2p/conn/evil_secret_connection_test.go b/sei-tendermint/internal/p2p/conn/evil_secret_connection_test.go index 0c5b68daf9..cee54f5213 100644 --- a/sei-tendermint/internal/p2p/conn/evil_secret_connection_test.go +++ b/sei-tendermint/internal/p2p/conn/evil_secret_connection_test.go @@ -5,6 +5,7 @@ import ( "errors" "io" "testing" + "net" gogotypes "github.com/gogo/protobuf/types" "github.com/oasisprotocol/curve25519-voi/primitives/merlin" @@ -12,6 +13,7 @@ import ( "golang.org/x/crypto/chacha20poly1305" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/internal/libs/protoio" @@ -19,6 +21,7 @@ import ( ) type buffer struct { + net.Conn next bytes.Buffer } @@ -39,7 +42,7 @@ func (b *buffer) Close() error { } type evilConn struct { - secretConn *SecretConnection + *SecretConnection buffer *buffer locEphPub *[32]byte @@ -118,7 +121,7 @@ func (c *evilConn) Read(data []byte) (n int, err error) { if err != nil { panic(err) } - n, err = c.secretConn.Write(bz) + n, err = c.SecretConnection.Write(bz) if err != nil { panic(err) } @@ -131,7 +134,7 @@ func (c *evilConn) Read(data []byte) (n int, err error) { if err != nil { panic(err) } - n, err = c.secretConn.Write(bz) + n, err = c.SecretConnection.Write(bz) if err != nil { panic(err) } @@ -217,11 +220,10 @@ func (c *evilConn) signChallenge() ed25519.Signature { } b := &buffer{} - c.secretConn = &SecretConnection{ + c.SecretConnection = &SecretConnection{ conn: b, - recvBuffer: nil, - recvNonce: new([aeadNonceSize]byte), - sendNonce: new([aeadNonceSize]byte), + recvState: utils.NewMutex(&recvState{}), + sendNonce: utils.NewMutex(&nonce{}), recvAead: recvAead, sendAead: sendAead, } diff --git a/sei-tendermint/internal/p2p/conn/secret_connection.go b/sei-tendermint/internal/p2p/conn/secret_connection.go index 5988976ed9..5cd797b535 100644 --- a/sei-tendermint/internal/p2p/conn/secret_connection.go +++ b/sei-tendermint/internal/p2p/conn/secret_connection.go @@ -11,8 +11,9 @@ import ( "io" "math" "net" - "sync" "time" + "cmp" + "context" gogotypes "github.com/gogo/protobuf/types" pool "github.com/libp2p/go-buffer-pool" @@ -22,8 +23,10 @@ import ( "golang.org/x/crypto/hkdf" "golang.org/x/crypto/nacl/box" - "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/internal/libs/async" + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/encoding" + "github.com/tendermint/tendermint/libs/utils" + "github.com/tendermint/tendermint/libs/utils/scope" "github.com/tendermint/tendermint/internal/libs/protoio" tmproto "github.com/tendermint/tendermint/proto/tendermint/crypto" tmp2p "github.com/tendermint/tendermint/proto/tendermint/p2p" @@ -50,6 +53,30 @@ var ( secretConnKeyAndChallengeGen = []byte("TENDERMINT_SECRET_CONNECTION_KEY_AND_CHALLENGE_GEN") ) +type nonce [aeadNonceSize]byte + +// Increment nonce little-endian by 1 with wraparound. +// Due to chacha20poly1305 expecting a 12 byte nonce we do not use the first four +// bytes. We only increment a 64 bit unsigned int in the remaining 8 bytes +// (little-endian in nonce[4:]). +func (n *nonce) inc() { + counter := binary.LittleEndian.Uint64(n[4:]) + if counter == math.MaxUint64 { + // Terminates the session and makes sure the nonce would not re-used. + // See https://github.com/tendermint/tendermint/issues/3531 + panic("can't increase nonce without overflow") + } + counter++ + binary.LittleEndian.PutUint64(n[4:], counter) +} + +type recvState struct { + buffer []byte + nonce nonce +} + +type Challenge [32]byte + // SecretConnection implements net.Conn. // It is an implementation of the STS protocol. // See https://github.com/tendermint/tendermint/blob/0.1/docs/sts-final.pdf for @@ -60,27 +87,13 @@ var ( // Otherwise they are vulnerable to MITM. // (TODO(ismail): see also https://github.com/tendermint/tendermint/issues/3010) type SecretConnection struct { - - // immutable + challenge Challenge recvAead cipher.AEAD sendAead cipher.AEAD - - remPubKey ed25519.PublicKey - conn io.ReadWriteCloser - - // net.Conn must be thread safe: - // https://golang.org/pkg/net/#Conn. - // Since we have internal mutable state, - // we need mtxs. But recv and send states - // are independent, so we can use two mtxs. - // All .Read are covered by recvMtx, - // all .Write are covered by sendMtx. - recvMtx sync.Mutex - recvBuffer []byte - recvNonce *[aeadNonceSize]byte - - sendMtx sync.Mutex - sendNonce *[aeadNonceSize]byte + remPubKey crypto.PubKey + conn net.Conn + recvState utils.Mutex[*recvState] + sendNonce utils.Mutex[*nonce] } // MakeSecretConnection performs handshake and returns a new authenticated @@ -88,47 +101,42 @@ type SecretConnection struct { // Returns nil if there is an error in handshake. // Caller should call conn.Close() // See docs/sts-final.pdf for more information. -func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey ed25519.SecretKey) (*SecretConnection, error) { - locPubKey := locPrivKey.Public() - +func MakeSecretConnection(ctx context.Context, conn net.Conn, locPrivKey crypto.PrivKey) (*SecretConnection, error) { // Generate ephemeral keys for perfect forward secrecy. locEphPub, locEphPriv := genEphKeys() // Write local ephemeral pubkey and receive one too. // NOTE: every 32-byte string is accepted as a Curve25519 public key (see // DJB's Curve25519 paper: http://cr.yp.to/ecdh/curve25519-20060209.pdf) - remEphPub, err := shareEphPubKey(conn, locEphPub) + remEphPub, err := shareEphPubKey(ctx, conn, locEphPub) if err != nil { return nil, err } // Sort by lexical order. - loEphPub, hiEphPub := sort32(locEphPub, remEphPub) + pubs := utils.Slice(locEphPub,remEphPub) + if bytes.Compare(pubs[0][:],pubs[1][:]) > 0 { + pubs[0],pubs[1] = pubs[1],pubs[0] + } transcript := merlin.NewTranscript("TENDERMINT_SECRET_CONNECTION_TRANSCRIPT_HASH") - transcript.AppendMessage(labelEphemeralLowerPublicKey, loEphPub[:]) - transcript.AppendMessage(labelEphemeralUpperPublicKey, hiEphPub[:]) - - // Check if the local ephemeral public key was the least, lexicographically - // sorted. - locIsLeast := bytes.Equal(locEphPub[:], loEphPub[:]) + transcript.AppendMessage(labelEphemeralLowerPublicKey, pubs[0][:]) + transcript.AppendMessage(labelEphemeralUpperPublicKey, pubs[1][:]) // Compute common diffie hellman secret using X25519. dhSecret, err := computeDHSecret(remEphPub, locEphPriv) if err != nil { return nil, err } - transcript.AppendMessage(labelDHSecret, dhSecret[:]) // Generate the secret used for receiving, sending, challenge via HKDF-SHA2 // on the transcript state (which itself also uses HKDF-SHA2 to derive a key // from the dhSecret). - recvSecret, sendSecret := deriveSecrets(dhSecret, locIsLeast) + recvSecret, sendSecret := deriveSecrets(dhSecret, locEphPub==pubs[0]) - const challengeSize = 32 - var challenge [challengeSize]byte + var challenge Challenge transcript.ExtractBytes(challenge[:], labelSecretConnectionMac) sendAead, err := chacha20poly1305.New(sendSecret[:]) @@ -141,19 +149,16 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey ed25519.SecretKey) } sc := &SecretConnection{ - conn: conn, - recvBuffer: nil, - recvNonce: new([aeadNonceSize]byte), - sendNonce: new([aeadNonceSize]byte), recvAead: recvAead, - sendAead: sendAead, + sendAead: sendAead, + challenge: challenge, + conn: conn, + recvState: utils.NewMutex(&recvState{}), + sendNonce: utils.NewMutex(&nonce{}), } - // Sign the challenge bytes for authentication. - locSignature := signChallenge(&challenge, locPrivKey) - // Share (in secret) each other's pubkey & challenge signature - authSigMsg, err := shareAuthSignature(sc, locPubKey, locSignature) + authSigMsg, err := sc.shareAuthSignature(ctx,locPrivKey) if err != nil { return nil, err } @@ -170,162 +175,141 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey ed25519.SecretKey) } // RemotePubKey returns authenticated remote pubkey -func (sc *SecretConnection) RemotePubKey() ed25519.PublicKey { +func (sc *SecretConnection) RemotePubKey() crypto.PubKey { return sc.remPubKey } // Writes encrypted frames of `totalFrameSize + aeadSizeOverhead`. // CONTRACT: data smaller than dataMaxSize is written atomically. func (sc *SecretConnection) Write(data []byte) (n int, err error) { - sc.sendMtx.Lock() - defer sc.sendMtx.Unlock() - - for 0 < len(data) { - if err := func() error { - var sealedFrame = pool.Get(aeadSizeOverhead + totalFrameSize) - var frame = pool.Get(totalFrameSize) - defer func() { - pool.Put(sealedFrame) - pool.Put(frame) - }() - var chunk []byte - if dataMaxSize < len(data) { - chunk = data[:dataMaxSize] - data = data[dataMaxSize:] - } else { - chunk = data - data = nil - } - chunkLength := len(chunk) - binary.LittleEndian.PutUint32(frame, uint32(chunkLength)) - copy(frame[dataLenSize:], chunk) - - // encrypt the frame - sc.sendAead.Seal(sealedFrame[:0], sc.sendNonce[:], frame, nil) - incrNonce(sc.sendNonce) - // end encryption - - _, err = sc.conn.Write(sealedFrame) - if err != nil { - return err + for nonce := range sc.sendNonce.Lock() { + for 0 < len(data) { + if err := func() error { + var sealedFrame = pool.Get(aeadSizeOverhead + totalFrameSize) + var frame = pool.Get(totalFrameSize) + defer func() { + pool.Put(sealedFrame) + pool.Put(frame) + }() + var chunk []byte + if dataMaxSize < len(data) { + chunk = data[:dataMaxSize] + data = data[dataMaxSize:] + } else { + chunk = data + data = nil + } + chunkLength := len(chunk) + binary.LittleEndian.PutUint32(frame, uint32(chunkLength)) + copy(frame[dataLenSize:], chunk) + + // encrypt the frame + sc.sendAead.Seal(sealedFrame[:0], nonce[:], frame, nil) + nonce.inc() + // end encryption + + _, err = sc.conn.Write(sealedFrame) + if err != nil { + return err + } + n += len(chunk) + return nil + }(); err != nil { + return n, err } - n += len(chunk) - return nil - }(); err != nil { - return n, err } + return n, err } - return n, err + panic("unreachable") } // CONTRACT: data smaller than dataMaxSize is read atomically. func (sc *SecretConnection) Read(data []byte) (n int, err error) { - sc.recvMtx.Lock() - defer sc.recvMtx.Unlock() - - // read off and update the recvBuffer, if non-empty - if 0 < len(sc.recvBuffer) { - n = copy(data, sc.recvBuffer) - sc.recvBuffer = sc.recvBuffer[n:] - return - } + for recvState := range sc.recvState.Lock() { + // read off and update the recvBuffer, if non-empty + if 0 < len(recvState.buffer) { + n = copy(data, recvState.buffer) + recvState.buffer = recvState.buffer[n:] + return + } - // read off the conn - var sealedFrame = pool.Get(aeadSizeOverhead + totalFrameSize) - defer pool.Put(sealedFrame) - _, err = io.ReadFull(sc.conn, sealedFrame) - if err != nil { - return - } + // read off the conn + var sealedFrame = pool.Get(aeadSizeOverhead + totalFrameSize) + defer pool.Put(sealedFrame) + _, err = io.ReadFull(sc.conn, sealedFrame) + if err != nil { + return + } - // decrypt the frame. - // reads and updates the sc.recvNonce - var frame = pool.Get(totalFrameSize) - defer pool.Put(frame) - _, err = sc.recvAead.Open(frame[:0], sc.recvNonce[:], sealedFrame, nil) - if err != nil { - return n, fmt.Errorf("failed to decrypt SecretConnection: %w", err) - } - incrNonce(sc.recvNonce) - // end decryption - - // copy checkLength worth into data, - // set recvBuffer to the rest. - var chunkLength = binary.LittleEndian.Uint32(frame) // read the first four bytes - if chunkLength > dataMaxSize { - return 0, errors.New("chunkLength is greater than dataMaxSize") - } - var chunk = frame[dataLenSize : dataLenSize+chunkLength] - n = copy(data, chunk) - if n < len(chunk) { - sc.recvBuffer = make([]byte, len(chunk)-n) - copy(sc.recvBuffer, chunk[n:]) + // decrypt the frame. + // reads and updates the sc.recvNonce + var frame = pool.Get(totalFrameSize) + defer pool.Put(frame) + _, err = sc.recvAead.Open(frame[:0], recvState.nonce[:], sealedFrame, nil) + if err != nil { + return n, fmt.Errorf("failed to decrypt SecretConnection: %w", err) + } + recvState.nonce.inc() + // end decryption + + // copy checkLength worth into data, + // set recvBuffer to the rest. + var chunkLength = binary.LittleEndian.Uint32(frame) // read the first four bytes + if chunkLength > dataMaxSize { + return 0, errors.New("chunkLength is greater than dataMaxSize") + } + var chunk = frame[dataLenSize : dataLenSize+chunkLength] + n = copy(data, chunk) + if n < len(chunk) { + recvState.buffer = make([]byte, len(chunk)-n) + copy(recvState.buffer, chunk[n:]) + } + return n, err } - return n, err + panic("unreachable") } // Implements net.Conn func (sc *SecretConnection) Close() error { return sc.conn.Close() } -func (sc *SecretConnection) LocalAddr() net.Addr { return sc.conn.(net.Conn).LocalAddr() } -func (sc *SecretConnection) RemoteAddr() net.Addr { return sc.conn.(net.Conn).RemoteAddr() } -func (sc *SecretConnection) SetDeadline(t time.Time) error { return sc.conn.(net.Conn).SetDeadline(t) } -func (sc *SecretConnection) SetReadDeadline(t time.Time) error { - return sc.conn.(net.Conn).SetReadDeadline(t) -} -func (sc *SecretConnection) SetWriteDeadline(t time.Time) error { - return sc.conn.(net.Conn).SetWriteDeadline(t) -} +func (sc *SecretConnection) LocalAddr() net.Addr { return sc.conn.LocalAddr() } +func (sc *SecretConnection) RemoteAddr() net.Addr { return sc.conn.RemoteAddr() } +func (sc *SecretConnection) SetDeadline(t time.Time) error { return sc.conn.SetDeadline(t) } +func (sc *SecretConnection) SetReadDeadline(t time.Time) error { return sc.conn.SetReadDeadline(t) } +func (sc *SecretConnection) SetWriteDeadline(t time.Time) error { return sc.conn.SetWriteDeadline(t) } + +type ephPublic [32]byte +type ephPrivate *[32]byte -func genEphKeys() (ephPub, ephPriv *[32]byte) { - var err error +func genEphKeys() (ephPublic, ephPrivate) { // TODO: Probably not a problem but ask Tony: different from the rust implementation (uses x25519-dalek), // we do not "clamp" the private key scalar: // see: https://github.com/dalek-cryptography/x25519-dalek/blob/34676d336049df2bba763cc076a75e47ae1f170f/src/x25519.rs#L56-L74 - ephPub, ephPriv, err = box.GenerateKey(crand.Reader) - if err != nil { - panic("Could not generate ephemeral key-pair") + public, secret, err := box.GenerateKey(crand.Reader) + if err!=nil { + panic(fmt.Errorf("Could not generate ephemeral key-pair: %w",err)) } - return + return *public, secret } -func shareEphPubKey(conn io.ReadWriter, locEphPub *[32]byte) (remEphPub *[32]byte, err error) { - - // Send our pubkey and receive theirs in tandem. - var trs, _ = async.Parallel( - func(_ int) (val any, abort bool, err error) { - lc := *locEphPub - _, err = protoio.NewDelimitedWriter(conn).WriteMsg(&gogotypes.BytesValue{Value: lc[:]}) - if err != nil { - return nil, true, err // abort - } - return nil, false, nil - }, - func(_ int) (val any, abort bool, err error) { - var bytes gogotypes.BytesValue - _, err = protoio.NewDelimitedReader(conn, 1024*1024).ReadMsg(&bytes) - if err != nil { - return nil, true, err // abort - } - - var _remEphPub [32]byte - copy(_remEphPub[:], bytes.Value) - return _remEphPub, false, nil - }, - ) - - // If error: - if trs.FirstError() != nil { - err = trs.FirstError() - return - } - - // Otherwise: - var _remEphPub = trs.FirstValue().([32]byte) - return &_remEphPub, nil +func shareEphPubKey(ctx context.Context, conn io.ReadWriter, locEphPub ephPublic) (ephPublic, error) { + return scope.Run1(ctx, func(ctx context.Context, s scope.Scope) (ephPublic,error) { + s.Spawn(func() error { + _, err := protoio.NewDelimitedWriter(conn).WriteMsg(&gogotypes.BytesValue{Value: locEphPub[:]}) + return err + }) + var bytes gogotypes.BytesValue + if _, err := protoio.NewDelimitedReader(conn, 1024*1024).ReadMsg(&bytes); err!=nil { + return ephPublic{},err + } + if len(bytes.Value)!=len(ephPublic{}) { + return ephPublic{},errors.New("bad ephemeral key size") + } + return ephPublic(bytes.Value),nil + }) } func deriveSecrets( - dhSecret *[32]byte, + dhSecret [32]byte, locIsLeast bool, ) (recvSecret, sendSecret *[aeadKeySize]byte) { hash := sha256.New @@ -357,85 +341,52 @@ func deriveSecrets( // computeDHSecret computes a Diffie-Hellman shared secret key // from our own local private key and the other's public key. -func computeDHSecret(remPubKey, locPrivKey *[32]byte) (*[32]byte, error) { - shrKey, err := curve25519.X25519(locPrivKey[:], remPubKey[:]) +func computeDHSecret(remPubKey ephPublic, locPrivKey ephPrivate) ([32]byte, error) { + dhs, err := curve25519.X25519(locPrivKey[:], remPubKey[:]) if err != nil { - return nil, err + return [32]byte{}, err } - var shrKeyArray [32]byte - copy(shrKeyArray[:], shrKey) - return &shrKeyArray, nil -} - -func sort32(foo, bar *[32]byte) (lo, hi *[32]byte) { - if bytes.Compare(foo[:], bar[:]) < 0 { - lo = foo - hi = bar - } else { - lo = bar - hi = foo - } - return -} - -func signChallenge(challenge *[32]byte, locPrivKey ed25519.SecretKey) ed25519.Signature { - return locPrivKey.Sign(challenge[:]) + return [32]byte(dhs), nil } type authSigMessage struct { - Key ed25519.PublicKey - Sig ed25519.Signature + Key crypto.PubKey + Sig crypto.Sig } -func shareAuthSignature(sc io.ReadWriter, pubKey ed25519.PublicKey, sig ed25519.Signature) (authSigMessage, error) { - // Send our info and receive theirs in tandem. - var trs, _ = async.Parallel( - func(_ int) (val any, abort bool, err error) { - pk := tmproto.PublicKey{Sum: &tmproto.PublicKey_Ed25519{Ed25519: pubKey.Bytes()}} - if _, err := protoio.NewDelimitedWriter(sc).WriteMsg(&tmp2p.AuthSigMessage{PubKey: pk, Sig: sig.Bytes()}); err != nil { - return nil, true, err - } - return nil, false, nil - }, - func(_ int) (val any, abort bool, err error) { - var pba tmp2p.AuthSigMessage - if _, err := protoio.NewDelimitedReader(sc, 1024*1024).ReadMsg(&pba); err != nil { - return nil, true, err - } - key, err := ed25519.PublicKeyFromBytes(pba.PubKey.GetEd25519()) - if err != nil { - return nil, true, fmt.Errorf("ed25519.PublicKeyFromBytes(): %w", err) - } - sig, err := ed25519.SignatureFromBytes(pba.Sig) - if err != nil { - return nil, true, fmt.Errorf("ed25519.SignatureFromBytes(): %w", err) - } - return authSigMessage{Key: key, Sig: sig}, false, nil - }, - ) - - // If error: - if trs.FirstError() != nil { - return authSigMessage{}, trs.FirstError() +func (m *authSigMessage) ToProto() *tmp2p.AuthSigMessage { + return &tmp2p.AuthSigMessage { + PubKey: encoding.PubKeyToProto(m.Key), + Sig: m.Sig.Bytes(), } - - var _recvMsg = trs.FirstValue().(authSigMessage) - return _recvMsg, nil } -//-------------------------------------------------------------------------------- - -// Increment nonce little-endian by 1 with wraparound. -// Due to chacha20poly1305 expecting a 12 byte nonce we do not use the first four -// bytes. We only increment a 64 bit unsigned int in the remaining 8 bytes -// (little-endian in nonce[4:]). -func incrNonce(nonce *[aeadNonceSize]byte) { - counter := binary.LittleEndian.Uint64(nonce[4:]) - if counter == math.MaxUint64 { - // Terminates the session and makes sure the nonce would not re-used. - // See https://github.com/tendermint/tendermint/issues/3531 - panic("can't increase nonce without overflow") +func authSigMessageFromProto(p *tmp2p.AuthSigMessage) (*authSigMessage,error) { + key, err := encoding.PubKeyFromProto(p.PubKey) + if err != nil { + return nil,fmt.Errorf("PubKey: %w", err) } - counter++ - binary.LittleEndian.PutUint64(nonce[4:], counter) + sig, err := crypto.SigFromBytes(p.Sig) + if err != nil { + return nil,fmt.Errorf("Sig: %w", err) + } + return &authSigMessage{key,sig},nil +} + +func (sc *SecretConnection) shareAuthSignature(ctx context.Context, privKey crypto.PrivKey) (*authSigMessage, error) { + // Send our info and receive theirs in tandem. + return scope.Run1(ctx, func(ctx context.Context, s scope.Scope) (*authSigMessage,error) { + s.Spawn(func() error { + sig := privKey.Sign(sc.challenge[:]) + pk := tmproto.PublicKey{Sum: &tmproto.PublicKey_Ed25519{Ed25519: privKey.Public().Bytes()}} + msg := &tmp2p.AuthSigMessage{PubKey: pk, Sig: sig.Bytes()} + _,err := protoio.NewDelimitedWriter(sc).WriteMsg(msg) + return err + }) + var pba tmp2p.AuthSigMessage + if _, err := protoio.NewDelimitedReader(sc, 1024*1024).ReadMsg(&pba); err != nil { + return nil,err + } + return authSigMessageFromProto(&pba) + }) } diff --git a/sei-tendermint/internal/p2p/conn/secret_connection_test.go b/sei-tendermint/internal/p2p/conn/secret_connection_test.go index 032b75bcfe..09b569dc34 100644 --- a/sei-tendermint/internal/p2p/conn/secret_connection_test.go +++ b/sei-tendermint/internal/p2p/conn/secret_connection_test.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "log" + "net" mrand "math/rand" "os" "path/filepath" @@ -28,13 +29,18 @@ import ( var update = flag.Bool("update", false, "update .golden files") type kvstoreConn struct { - *io.PipeReader - *io.PipeWriter + net.Conn + reader *io.PipeReader + writer *io.PipeWriter } +func (drw kvstoreConn) Read(data []byte) (n int, err error) { return drw.reader.Read(data) } +func (drw kvstoreConn) Write(data []byte) (n int, err error) { return drw.writer.Write(data) } + + func (drw kvstoreConn) Close() (err error) { - err2 := drw.PipeWriter.CloseWithError(io.EOF) - err1 := drw.PipeReader.Close() + err2 := drw.writer.CloseWithError(io.EOF) + err1 := drw.reader.Close() if err2 != nil { return err } @@ -101,14 +107,14 @@ func TestSecretConnectionReadWrite(t *testing.T) { fooReads, barReads := []string{}, []string{} // Pre-generate the things to write (for foo & bar) - for i := 0; i < 100; i++ { + for range 100 { fooWrites = append(fooWrites, tmrand.Str((mrand.Int()%(dataMaxSize*5))+1)) barWrites = append(barWrites, tmrand.Str((mrand.Int()%(dataMaxSize*5))+1)) } // A helper that will run with (fooConn, fooWrites, fooReads) and vice versa - genNodeRunner := func(id string, nodeConn kvstoreConn, nodeWrites []string, nodeReads *[]string) async.Task { - return func(_ int) (interface{}, bool, error) { + genNodeRunner := func(nodeConn kvstoreConn, nodeWrites []string, nodeReads *[]string) async.Task { + return func(_ int) (any, bool, error) { // Initiate cryptographic private key and secret connection trhough nodeConn. nodePrvKey := ed25519.GenerateSecretKey() nodeSecretConn, err := MakeSecretConnection(nodeConn, nodePrvKey) @@ -118,7 +124,7 @@ func TestSecretConnectionReadWrite(t *testing.T) { } // In parallel, handle some reads and writes. var trs, ok = async.Parallel( - func(_ int) (interface{}, bool, error) { + func(_ int) (any, bool, error) { // Node writes: for _, nodeWrite := range nodeWrites { n, err := nodeSecretConn.Write([]byte(nodeWrite)) @@ -132,19 +138,19 @@ func TestSecretConnectionReadWrite(t *testing.T) { return nil, true, err } } - if err := nodeConn.PipeWriter.Close(); err != nil { + if err := nodeConn.writer.Close(); err != nil { t.Error(err) return nil, true, err } return nil, false, nil }, - func(_ int) (interface{}, bool, error) { + func(_ int) (any, bool, error) { // Node reads: readBuffer := make([]byte, dataMaxSize) for { n, err := nodeSecretConn.Read(readBuffer) if err == io.EOF { - if err := nodeConn.PipeReader.Close(); err != nil { + if err := nodeConn.reader.Close(); err != nil { t.Error(err) return nil, true, err } @@ -171,8 +177,8 @@ func TestSecretConnectionReadWrite(t *testing.T) { // Run foo & bar in parallel var trs, ok = async.Parallel( - genNodeRunner("foo", fooConn, fooWrites, &fooReads), - genNodeRunner("bar", barConn, barWrites, &barReads), + genNodeRunner(fooConn, fooWrites, &fooReads), + genNodeRunner(barConn, barWrites, &barReads), ) require.Nil(t, trs.FirstError()) require.True(t, ok, "unexpected task abortion") @@ -246,7 +252,7 @@ func TestDeriveSecretsAndChallengeGolden(t *testing.T) { func writeLots(t *testing.T, wg *sync.WaitGroup, conn io.Writer, txt string, n int) { defer wg.Done() - for i := 0; i < n; i++ { + for range n { _, err := conn.Write([]byte(txt)) if err != nil { t.Errorf("failed to write to fooSecConn: %v", err) @@ -257,7 +263,7 @@ func writeLots(t *testing.T, wg *sync.WaitGroup, conn io.Writer, txt string, n i func readLots(t *testing.T, wg *sync.WaitGroup, conn io.Reader, n int) { readBuffer := make([]byte, dataMaxSize) - for i := 0; i < n; i++ { + for range n { _, err := conn.Read(readBuffer) assert.NoError(t, err) } @@ -269,7 +275,7 @@ func readLots(t *testing.T, wg *sync.WaitGroup, conn io.Reader, n int) { // Hex(diffie_hellman_secret), loc_is_least, Hex(recvSecret), Hex(sendSecret), Hex(challenge) func createGoldenTestVectors() string { data := "" - for i := 0; i < 32; i++ { + for range 32 { randSecretVector := tmrand.Bytes(32) randSecret := new([32]byte) copy((*randSecret)[:], randSecretVector) @@ -287,7 +293,7 @@ func createGoldenTestVectors() string { func makeKVStoreConnPair() (fooConn, barConn kvstoreConn) { barReader, fooWriter := io.Pipe() fooReader, barWriter := io.Pipe() - return kvstoreConn{fooReader, fooWriter}, kvstoreConn{barReader, barWriter} + return kvstoreConn{reader:fooReader, writer:fooWriter}, kvstoreConn{reader:barReader, writer:barWriter} } func makeSecretConnPair(tb testing.TB) (fooSecConn, barSecConn *SecretConnection) { @@ -301,7 +307,7 @@ func makeSecretConnPair(tb testing.TB) (fooSecConn, barSecConn *SecretConnection // Make connections from both sides in parallel. var trs, ok = async.Parallel( - func(_ int) (val interface{}, abort bool, err error) { + func(_ int) (val any, abort bool, err error) { fooSecConn, err = MakeSecretConnection(fooConn, fooPrvKey) if err != nil { tb.Errorf("failed to establish SecretConnection for foo: %v", err) @@ -316,7 +322,7 @@ func makeSecretConnPair(tb testing.TB) (fooSecConn, barSecConn *SecretConnection } return nil, false, nil }, - func(_ int) (val interface{}, abort bool, err error) { + func(_ int) (val any, abort bool, err error) { barSecConn, err = MakeSecretConnection(barConn, barPrvKey) if barSecConn == nil { tb.Errorf("failed to establish SecretConnection for bar: %v", err) @@ -372,8 +378,7 @@ func BenchmarkWriteSecretConnection(b *testing.B) { } }() - b.StartTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { idx := mrand.Intn(len(fooWriteBytes)) _, err := fooSecConn.Write(fooWriteBytes[idx]) if err != nil { @@ -381,7 +386,6 @@ func BenchmarkWriteSecretConnection(b *testing.B) { return } } - b.StopTimer() if err := fooSecConn.Close(); err != nil { b.Error(err) @@ -407,7 +411,7 @@ func BenchmarkReadSecretConnection(b *testing.B) { fooWriteBytes = append(fooWriteBytes, tmrand.Bytes(size)) } go func() { - for i := 0; i < b.N; i++ { + for i := range b.N { idx := mrand.Intn(len(fooWriteBytes)) _, err := fooSecConn.Write(fooWriteBytes[idx]) if err != nil { @@ -417,8 +421,7 @@ func BenchmarkReadSecretConnection(b *testing.B) { } }() - b.StartTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { readBuffer := make([]byte, dataMaxSize) _, err := barSecConn.Read(readBuffer) @@ -428,7 +431,6 @@ func BenchmarkReadSecretConnection(b *testing.B) { b.Fatalf("Failed to read from barSecConn: %v", err) } } - b.StopTimer() } type closer interface { diff --git a/sei-tendermint/proto/tendermint/p2p/conn.proto b/sei-tendermint/proto/tendermint/p2p/conn.proto index 807c2a50ee..46c4cebf89 100644 --- a/sei-tendermint/proto/tendermint/p2p/conn.proto +++ b/sei-tendermint/proto/tendermint/p2p/conn.proto @@ -28,4 +28,5 @@ message Packet { message AuthSigMessage { tendermint.crypto.PublicKey pub_key = 1 [(gogoproto.nullable) = false]; bytes sig = 2; + // Supported P2P features. } From 1cd257d3b4dcea9c557f912bd3b271f0e57b1b9b Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Mon, 22 Dec 2025 13:16:59 +0100 Subject: [PATCH 46/53] slight refactor of secret connection --- .../internal/p2p/conn/connection.go | 4 +- .../internal/p2p/conn/connection_test.go | 3 +- .../p2p/conn/evil_secret_connection_test.go | 124 ++---- .../internal/p2p/conn/secret_connection.go | 283 ++++++-------- .../p2p/conn/secret_connection_test.go | 370 ++++++------------ sei-tendermint/internal/p2p/transport.go | 2 +- 6 files changed, 285 insertions(+), 501 deletions(-) diff --git a/sei-tendermint/internal/p2p/conn/connection.go b/sei-tendermint/internal/p2p/conn/connection.go index 02a50aed92..571a9ced2e 100644 --- a/sei-tendermint/internal/p2p/conn/connection.go +++ b/sei-tendermint/internal/p2p/conn/connection.go @@ -103,7 +103,7 @@ initialization of the connection. type MConnection struct { logger log.Logger - conn *SecretConnection + conn net.Conn sendQueue utils.Watch[*sendQueue] recvPong utils.Mutex[*utils.AtomicSend[bool]] recvCh chan mConnMessage @@ -180,7 +180,7 @@ func (q *sendQueue) setFlush(t time.Time) { // NewMConnection wraps net.Conn and creates multiplex connection with a config func NewMConnection( logger log.Logger, - conn *SecretConnection, + conn net.Conn, chDescs []*ChannelDescriptor, config MConnConfig, ) *MConnection { diff --git a/sei-tendermint/internal/p2p/conn/connection_test.go b/sei-tendermint/internal/p2p/conn/connection_test.go index f493ed3463..37ccf411ff 100644 --- a/sei-tendermint/internal/p2p/conn/connection_test.go +++ b/sei-tendermint/internal/p2p/conn/connection_test.go @@ -36,8 +36,7 @@ func newMConnectionWithCh( cfg := DefaultMConnConfig() cfg.PingInterval = 250 * time.Millisecond cfg.PongTimeout = 500 * time.Millisecond - c := NewMConnection(log.NewNopLogger(), conn, chDescs, cfg) - return c + return NewMConnection(log.NewNopLogger(), conn, chDescs, cfg) } func mayDisconnectAfterDone(ctx context.Context, err error) error { diff --git a/sei-tendermint/internal/p2p/conn/evil_secret_connection_test.go b/sei-tendermint/internal/p2p/conn/evil_secret_connection_test.go index cee54f5213..6ff93016c3 100644 --- a/sei-tendermint/internal/p2p/conn/evil_secret_connection_test.go +++ b/sei-tendermint/internal/p2p/conn/evil_secret_connection_test.go @@ -4,19 +4,17 @@ import ( "bytes" "errors" "io" - "testing" "net" + "testing" gogotypes "github.com/gogo/protobuf/types" - "github.com/oasisprotocol/curve25519-voi/primitives/merlin" - "github.com/stretchr/testify/assert" - "golang.org/x/crypto/chacha20poly1305" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/internal/libs/protoio" + "github.com/tendermint/tendermint/libs/utils" + "github.com/tendermint/tendermint/libs/utils/require" tmp2p "github.com/tendermint/tendermint/proto/tendermint/p2p" ) @@ -43,12 +41,11 @@ func (b *buffer) Close() error { type evilConn struct { *SecretConnection - buffer *buffer + buffer *buffer - locEphPub *[32]byte - locEphPriv *[32]byte - remEphPub *[32]byte - privKey crypto.PrivKey + loc ephSecret + rem ephPublic + privKey crypto.PrivKey readStep int writeStep int @@ -61,22 +58,14 @@ type evilConn struct { } func newEvilConn(shareEphKey, badEphKey, shareAuthSignature, badAuthSignature bool) *evilConn { - privKey := ed25519.GenerateSecretKey() - locEphPub, locEphPriv := genEphKeys() - var rep [32]byte - c := &evilConn{ - locEphPub: locEphPub, - locEphPriv: locEphPriv, - remEphPub: &rep, - privKey: privKey, - + return &evilConn{ + loc: genEphKey(), + privKey: ed25519.GenerateSecretKey(), shareEphKey: shareEphKey, badEphKey: badEphKey, shareAuthSignature: shareAuthSignature, badAuthSignature: badAuthSignature, } - - return c } func (c *evilConn) Read(data []byte) (n int, err error) { @@ -87,8 +76,7 @@ func (c *evilConn) Read(data []byte) (n int, err error) { switch c.readStep { case 0: if !c.badEphKey { - lc := *c.locEphPub - bz, err := protoio.MarshalDelimited(&gogotypes.BytesValue{Value: lc[:]}) + bz, err := protoio.MarshalDelimited(&gogotypes.BytesValue{Value: c.loc.public[:]}) if err != nil { panic(err) } @@ -153,16 +141,9 @@ func (c *evilConn) Read(data []byte) (n int, err error) { func (c *evilConn) Write(data []byte) (n int, err error) { switch c.writeStep { case 0: - var ( - bytes gogotypes.BytesValue - remEphPub [32]byte - ) - err := protoio.UnmarshalDelimited(data, &bytes) - if err != nil { - panic(err) - } - copy(remEphPub[:], bytes.Value) - c.remEphPub = &remEphPub + var bytes gogotypes.BytesValue + utils.OrPanic(protoio.UnmarshalDelimited(data, &bytes)) + c.rem = ephPublic(bytes.Value) c.writeStep = 1 if !c.shareAuthSignature { c.writeStep = 2 @@ -181,83 +162,36 @@ func (c *evilConn) Close() error { } func (c *evilConn) signChallenge() ed25519.Signature { - // Sort by lexical order. - loEphPub, hiEphPub := sort32(c.locEphPub, c.remEphPub) - - transcript := merlin.NewTranscript("TENDERMINT_SECRET_CONNECTION_TRANSCRIPT_HASH") - - transcript.AppendMessage(labelEphemeralLowerPublicKey, loEphPub[:]) - transcript.AppendMessage(labelEphemeralUpperPublicKey, hiEphPub[:]) - - // Check if the local ephemeral public key was the least, lexicographically - // sorted. - locIsLeast := bytes.Equal(c.locEphPub[:], loEphPub[:]) - - // Compute common diffie hellman secret using X25519. - dhSecret, err := computeDHSecret(c.remEphPub, c.locEphPriv) - if err != nil { - panic(err) - } - - transcript.AppendMessage(labelDHSecret, dhSecret[:]) - - // Generate the secret used for receiving, sending, challenge via HKDF-SHA2 - // on the transcript state (which itself also uses HKDF-SHA2 to derive a key - // from the dhSecret). - recvSecret, sendSecret := deriveSecrets(dhSecret, locIsLeast) - - const challengeSize = 32 - var challenge [challengeSize]byte - transcript.ExtractBytes(challenge[:], labelSecretConnectionMac) - - sendAead, err := chacha20poly1305.New(sendSecret[:]) - if err != nil { - panic(errors.New("invalid send SecretConnection Key")) - } - recvAead, err := chacha20poly1305.New(recvSecret[:]) - if err != nil { - panic(errors.New("invalid receive SecretConnection Key")) - } - b := &buffer{} - c.SecretConnection = &SecretConnection{ - conn: b, - recvState: utils.NewMutex(&recvState{}), - sendNonce: utils.NewMutex(&nonce{}), - recvAead: recvAead, - sendAead: sendAead, - } + c.SecretConnection = newSecretConnection(b, c.loc, c.rem) c.buffer = b - - // Sign the challenge bytes for authentication. - return signChallenge(&challenge, c.privKey) + return c.privKey.Sign(c.challenge[:]) } // TestMakeSecretConnection creates an evil connection and tests that // MakeSecretConnection errors at different stages. func TestMakeSecretConnection(t *testing.T) { testCases := []struct { - name string - conn *evilConn - errMsg string + name string + conn *evilConn + err utils.Option[error] }{ - {"refuse to share ethimeral key", newEvilConn(false, false, false, false), "EOF"}, - {"share bad ethimeral key", newEvilConn(true, true, false, false), "wrong wireType"}, - {"refuse to share auth signature", newEvilConn(true, false, false, false), "EOF"}, - {"share bad auth signature", newEvilConn(true, false, true, true), "failed to decrypt SecretConnection"}, - {"all good", newEvilConn(true, false, true, false), ""}, + {"refuse to share ephemeral key", newEvilConn(false, false, false, false), utils.Some(errDH)}, + {"share bad ephemeral key", newEvilConn(true, true, false, false), utils.Some(errDH)}, + {"refuse to share auth signature", newEvilConn(true, false, false, false), utils.Some(io.EOF)}, + {"share bad auth signature", newEvilConn(true, false, true, true), utils.Some(errAEAD)}, + {"all good", newEvilConn(true, false, true, false), utils.None[error]()}, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + ctx := t.Context() privKey := ed25519.GenerateSecretKey() - _, err := MakeSecretConnection(tc.conn, privKey) - if tc.errMsg != "" { - if assert.Error(t, err) { - assert.Contains(t, err.Error(), tc.errMsg) - } + _, err := MakeSecretConnection(ctx, tc.conn, privKey) + if wantErr, ok := tc.err.Get(); ok { + require.True(t, errors.Is(err, wantErr), "got %v, want %v", err, wantErr) } else { - assert.NoError(t, err) + require.NoError(t, err) } }) } diff --git a/sei-tendermint/internal/p2p/conn/secret_connection.go b/sei-tendermint/internal/p2p/conn/secret_connection.go index 5cd797b535..ac7af42992 100644 --- a/sei-tendermint/internal/p2p/conn/secret_connection.go +++ b/sei-tendermint/internal/p2p/conn/secret_connection.go @@ -2,6 +2,7 @@ package conn import ( "bytes" + "context" "crypto/cipher" crand "crypto/rand" "crypto/sha256" @@ -12,8 +13,6 @@ import ( "math" "net" "time" - "cmp" - "context" gogotypes "github.com/gogo/protobuf/types" pool "github.com/libp2p/go-buffer-pool" @@ -25,10 +24,9 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/encoding" + "github.com/tendermint/tendermint/internal/libs/protoio" "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/libs/utils/scope" - "github.com/tendermint/tendermint/internal/libs/protoio" - tmproto "github.com/tendermint/tendermint/proto/tendermint/crypto" tmp2p "github.com/tendermint/tendermint/proto/tendermint/p2p" ) @@ -38,7 +36,6 @@ const ( dataMaxSize = 1024 totalFrameSize = dataMaxSize + dataLenSize aeadSizeOverhead = 16 // overhead of poly 1305 authentication tag - aeadKeySize = chacha20poly1305.KeySize aeadNonceSize = chacha20poly1305.NonceSize labelEphemeralLowerPublicKey = "EPHEMERAL_LOWER_PUBLIC_KEY" @@ -47,11 +44,8 @@ const ( labelSecretConnectionMac = "SECRET_CONNECTION_MAC" ) -var ( - ErrSmallOrderRemotePubKey = errors.New("detected low order point from remote peer") - - secretConnKeyAndChallengeGen = []byte("TENDERMINT_SECRET_CONNECTION_KEY_AND_CHALLENGE_GEN") -) +var ErrSmallOrderRemotePubKey = errors.New("detected low order point from remote peer") +var secretConnKeyAndChallengeGen = []byte("TENDERMINT_SECRET_CONNECTION_KEY_AND_CHALLENGE_GEN") type nonce [aeadNonceSize]byte @@ -70,13 +64,17 @@ func (n *nonce) inc() { binary.LittleEndian.PutUint64(n[4:], counter) } +type sendState struct { + cipher cipher.AEAD + nonce nonce +} + type recvState struct { + cipher cipher.AEAD buffer []byte - nonce nonce + nonce nonce } -type Challenge [32]byte - // SecretConnection implements net.Conn. // It is an implementation of the STS protocol. // See https://github.com/tendermint/tendermint/blob/0.1/docs/sts-final.pdf for @@ -87,102 +85,86 @@ type Challenge [32]byte // Otherwise they are vulnerable to MITM. // (TODO(ismail): see also https://github.com/tendermint/tendermint/issues/3010) type SecretConnection struct { - challenge Challenge - recvAead cipher.AEAD - sendAead cipher.AEAD - remPubKey crypto.PubKey - conn net.Conn + conn net.Conn + challenge [32]byte recvState utils.Mutex[*recvState] - sendNonce utils.Mutex[*nonce] + sendState utils.Mutex[*sendState] + remPubKey crypto.PubKey } -// MakeSecretConnection performs handshake and returns a new authenticated -// SecretConnection. -// Returns nil if there is an error in handshake. -// Caller should call conn.Close() -// See docs/sts-final.pdf for more information. -func MakeSecretConnection(ctx context.Context, conn net.Conn, locPrivKey crypto.PrivKey) (*SecretConnection, error) { - // Generate ephemeral keys for perfect forward secrecy. - locEphPub, locEphPriv := genEphKeys() - - // Write local ephemeral pubkey and receive one too. - // NOTE: every 32-byte string is accepted as a Curve25519 public key (see - // DJB's Curve25519 paper: http://cr.yp.to/ecdh/curve25519-20060209.pdf) - remEphPub, err := shareEphPubKey(ctx, conn, locEphPub) - if err != nil { - return nil, err - } - - // Sort by lexical order. - pubs := utils.Slice(locEphPub,remEphPub) - if bytes.Compare(pubs[0][:],pubs[1][:]) > 0 { - pubs[0],pubs[1] = pubs[1],pubs[0] +func newSecretConnection(conn net.Conn, loc ephSecret, rem ephPublic) *SecretConnection { + pubs := utils.Slice(loc.public, rem) + if bytes.Compare(pubs[0][:], pubs[1][:]) > 0 { + pubs[0], pubs[1] = pubs[1], pubs[0] } - transcript := merlin.NewTranscript("TENDERMINT_SECRET_CONNECTION_TRANSCRIPT_HASH") - transcript.AppendMessage(labelEphemeralLowerPublicKey, pubs[0][:]) transcript.AppendMessage(labelEphemeralUpperPublicKey, pubs[1][:]) - - // Compute common diffie hellman secret using X25519. - dhSecret, err := computeDHSecret(remEphPub, locEphPriv) - if err != nil { - return nil, err - } - transcript.AppendMessage(labelDHSecret, dhSecret[:]) + dh := loc.DhSecret(rem) + transcript.AppendMessage(labelDHSecret, dh[:]) + var challenge [32]byte + transcript.ExtractBytes(challenge[:], labelSecretConnectionMac) // Generate the secret used for receiving, sending, challenge via HKDF-SHA2 // on the transcript state (which itself also uses HKDF-SHA2 to derive a key // from the dhSecret). - recvSecret, sendSecret := deriveSecrets(dhSecret, locEphPub==pubs[0]) - - var challenge Challenge - transcript.ExtractBytes(challenge[:], labelSecretConnectionMac) - - sendAead, err := chacha20poly1305.New(sendSecret[:]) - if err != nil { - return nil, errors.New("invalid send SecretConnection Key") - } - recvAead, err := chacha20poly1305.New(recvSecret[:]) - if err != nil { - return nil, errors.New("invalid receive SecretConnection Key") + aead := dh.AeadSecrets(loc.public == pubs[0]) + return &SecretConnection{ + conn: conn, + challenge: challenge, + recvState: utils.NewMutex(&recvState{cipher: aead.recv.Cipher()}), + sendState: utils.NewMutex(&sendState{cipher: aead.send.Cipher()}), } +} - sc := &SecretConnection{ - recvAead: recvAead, - sendAead: sendAead, - challenge: challenge, - conn: conn, - recvState: utils.NewMutex(&recvState{}), - sendNonce: utils.NewMutex(&nonce{}), - } +// MakeSecretConnection performs handshake and returns a new authenticated +// SecretConnection. +// Returns nil if there is an error in handshake. +// Caller should call conn.Close() +// See docs/sts-final.pdf for more information. +func MakeSecretConnection(ctx context.Context, conn net.Conn, locPrivKey crypto.PrivKey) (*SecretConnection, error) { + // Generate ephemeral key for perfect forward secrecy. + loc := genEphKey() - // Share (in secret) each other's pubkey & challenge signature - authSigMsg, err := sc.shareAuthSignature(ctx,locPrivKey) + // Write local ephemeral pubkey and receive one too. + // NOTE: every 32-byte string is accepted as a Curve25519 public key (see + // DJB's Curve25519 paper: http://cr.yp.to/ecdh/curve25519-20060209.pdf) + rem, err := shareEphPubKey(ctx, conn, loc.public) if err != nil { return nil, err } + sc := newSecretConnection(conn, loc, rem) - remPubKey, remSignature := authSigMsg.Key, authSigMsg.Sig - - if err := remPubKey.Verify(challenge[:], remSignature); err != nil { - return nil, fmt.Errorf("challenge verification failed: %w", err) - } - - // We've authorized. - sc.remPubKey = remPubKey - return sc, nil + return scope.Run1(ctx, func(ctx context.Context, s scope.Scope) (*SecretConnection, error) { + // Share (in secret) each other's pubkey & challenge signature + s.Spawn(func() error { + loc := authSigMessage{locPrivKey.Public(), locPrivKey.Sign(sc.challenge[:])} + _, err := protoio.NewDelimitedWriter(sc).WriteMsg(loc.ToProto()) + return err + }) + var pba tmp2p.AuthSigMessage + if _, err := protoio.NewDelimitedReader(sc, 1024*1024).ReadMsg(&pba); err != nil { + return nil, err + } + rem, err := authSigMessageFromProto(&pba) + if err != nil { + return nil, fmt.Errorf("authSigMessageFromProto(): %w", err) + } + if err := rem.Key.Verify(sc.challenge[:], rem.Sig); err != nil { + return nil, fmt.Errorf("challenge verification failed: %w", err) + } + sc.remPubKey = rem.Key + return sc, nil + }) } // RemotePubKey returns authenticated remote pubkey -func (sc *SecretConnection) RemotePubKey() crypto.PubKey { - return sc.remPubKey -} +func (sc *SecretConnection) RemotePubKey() crypto.PubKey { return sc.remPubKey } // Writes encrypted frames of `totalFrameSize + aeadSizeOverhead`. // CONTRACT: data smaller than dataMaxSize is written atomically. func (sc *SecretConnection) Write(data []byte) (n int, err error) { - for nonce := range sc.sendNonce.Lock() { + for sendState := range sc.sendState.Lock() { for 0 < len(data) { if err := func() error { var sealedFrame = pool.Get(aeadSizeOverhead + totalFrameSize) @@ -204,8 +186,8 @@ func (sc *SecretConnection) Write(data []byte) (n int, err error) { copy(frame[dataLenSize:], chunk) // encrypt the frame - sc.sendAead.Seal(sealedFrame[:0], nonce[:], frame, nil) - nonce.inc() + sendState.cipher.Seal(sealedFrame[:0], sendState.nonce[:], frame, nil) + sendState.nonce.inc() // end encryption _, err = sc.conn.Write(sealedFrame) @@ -223,6 +205,8 @@ func (sc *SecretConnection) Write(data []byte) (n int, err error) { panic("unreachable") } +var errAEAD = errors.New("decoding failed") + // CONTRACT: data smaller than dataMaxSize is read atomically. func (sc *SecretConnection) Read(data []byte) (n int, err error) { for recvState := range sc.recvState.Lock() { @@ -245,9 +229,9 @@ func (sc *SecretConnection) Read(data []byte) (n int, err error) { // reads and updates the sc.recvNonce var frame = pool.Get(totalFrameSize) defer pool.Put(frame) - _, err = sc.recvAead.Open(frame[:0], recvState.nonce[:], sealedFrame, nil) + _, err = recvState.cipher.Open(frame[:0], recvState.nonce[:], sealedFrame, nil) if err != nil { - return n, fmt.Errorf("failed to decrypt SecretConnection: %w", err) + return n, fmt.Errorf("%w: %v", errAEAD, err) } recvState.nonce.inc() // end decryption @@ -270,83 +254,82 @@ func (sc *SecretConnection) Read(data []byte) (n int, err error) { } // Implements net.Conn -func (sc *SecretConnection) Close() error { return sc.conn.Close() } -func (sc *SecretConnection) LocalAddr() net.Addr { return sc.conn.LocalAddr() } -func (sc *SecretConnection) RemoteAddr() net.Addr { return sc.conn.RemoteAddr() } -func (sc *SecretConnection) SetDeadline(t time.Time) error { return sc.conn.SetDeadline(t) } -func (sc *SecretConnection) SetReadDeadline(t time.Time) error { return sc.conn.SetReadDeadline(t) } +func (sc *SecretConnection) Close() error { return sc.conn.Close() } +func (sc *SecretConnection) LocalAddr() net.Addr { return sc.conn.LocalAddr() } +func (sc *SecretConnection) RemoteAddr() net.Addr { return sc.conn.RemoteAddr() } +func (sc *SecretConnection) SetDeadline(t time.Time) error { return sc.conn.SetDeadline(t) } +func (sc *SecretConnection) SetReadDeadline(t time.Time) error { return sc.conn.SetReadDeadline(t) } func (sc *SecretConnection) SetWriteDeadline(t time.Time) error { return sc.conn.SetWriteDeadline(t) } type ephPublic [32]byte -type ephPrivate *[32]byte -func genEphKeys() (ephPublic, ephPrivate) { +type ephSecret struct { + secret [32]byte + public ephPublic +} + +func genEphKey() ephSecret { // TODO: Probably not a problem but ask Tony: different from the rust implementation (uses x25519-dalek), // we do not "clamp" the private key scalar: // see: https://github.com/dalek-cryptography/x25519-dalek/blob/34676d336049df2bba763cc076a75e47ae1f170f/src/x25519.rs#L56-L74 public, secret, err := box.GenerateKey(crand.Reader) - if err!=nil { - panic(fmt.Errorf("Could not generate ephemeral key-pair: %w",err)) + if err != nil { + panic(fmt.Errorf("Could not generate ephemeral key-pair: %w", err)) + } + return ephSecret{ + secret: *secret, + public: *public, } - return *public, secret } +var errDH = errors.New("DH handshake failed") + func shareEphPubKey(ctx context.Context, conn io.ReadWriter, locEphPub ephPublic) (ephPublic, error) { - return scope.Run1(ctx, func(ctx context.Context, s scope.Scope) (ephPublic,error) { + return scope.Run1(ctx, func(ctx context.Context, s scope.Scope) (ephPublic, error) { s.Spawn(func() error { _, err := protoio.NewDelimitedWriter(conn).WriteMsg(&gogotypes.BytesValue{Value: locEphPub[:]}) return err }) var bytes gogotypes.BytesValue - if _, err := protoio.NewDelimitedReader(conn, 1024*1024).ReadMsg(&bytes); err!=nil { - return ephPublic{},err + if _, err := protoio.NewDelimitedReader(conn, 1024*1024).ReadMsg(&bytes); err != nil { + return ephPublic{}, fmt.Errorf("%w: %v", errDH, err) } - if len(bytes.Value)!=len(ephPublic{}) { - return ephPublic{},errors.New("bad ephemeral key size") + if len(bytes.Value) != len(ephPublic{}) { + return ephPublic{}, fmt.Errorf("%w: bad ephemeral key size", errDH) } - return ephPublic(bytes.Value),nil + return ephPublic(bytes.Value), nil }) } -func deriveSecrets( - dhSecret [32]byte, - locIsLeast bool, -) (recvSecret, sendSecret *[aeadKeySize]byte) { - hash := sha256.New - hkdf := hkdf.New(hash, dhSecret[:], nil, secretConnKeyAndChallengeGen) - // get enough data for 2 aead keys, and a 32 byte challenge - res := new([2*aeadKeySize + 32]byte) - _, err := io.ReadFull(hkdf, res[:]) - if err != nil { - panic(err) - } +type dhSecret [32]byte +type aeadSecret [chacha20poly1305.KeySize]byte - recvSecret = new([aeadKeySize]byte) - sendSecret = new([aeadKeySize]byte) +type aeadSecrets struct { + send aeadSecret + recv aeadSecret +} + +func (s aeadSecret) Cipher() cipher.AEAD { + // Never returns an error on input of correct size. + return utils.OrPanic1(chacha20poly1305.New(s[:])) +} - // bytes 0 through aeadKeySize - 1 are one aead key. - // bytes aeadKeySize through 2*aeadKeySize -1 are another aead key. - // which key corresponds to sending and receiving key depends on whether - // the local key is less than the remote key. +func (s dhSecret) AeadSecrets(locIsLeast bool) aeadSecrets { + hkdf := hkdf.New(sha256.New, s[:], nil, secretConnKeyAndChallengeGen) + aead := aeadSecrets{} + // hkdf reader never returns an error. + utils.OrPanic1(io.ReadFull(hkdf, aead.send[:])) + utils.OrPanic1(io.ReadFull(hkdf, aead.recv[:])) if locIsLeast { - copy(recvSecret[:], res[0:aeadKeySize]) - copy(sendSecret[:], res[aeadKeySize:aeadKeySize*2]) - } else { - copy(sendSecret[:], res[0:aeadKeySize]) - copy(recvSecret[:], res[aeadKeySize:aeadKeySize*2]) + aead.send, aead.recv = aead.recv, aead.send } - - return + return aead } // computeDHSecret computes a Diffie-Hellman shared secret key // from our own local private key and the other's public key. -func computeDHSecret(remPubKey ephPublic, locPrivKey ephPrivate) ([32]byte, error) { - dhs, err := curve25519.X25519(locPrivKey[:], remPubKey[:]) - if err != nil { - return [32]byte{}, err - } - return [32]byte(dhs), nil +func (s ephSecret) DhSecret(remPubKey ephPublic) dhSecret { + return dhSecret(utils.OrPanic1(curve25519.X25519(s.secret[:], remPubKey[:]))) } type authSigMessage struct { @@ -355,38 +338,20 @@ type authSigMessage struct { } func (m *authSigMessage) ToProto() *tmp2p.AuthSigMessage { - return &tmp2p.AuthSigMessage { + return &tmp2p.AuthSigMessage{ PubKey: encoding.PubKeyToProto(m.Key), - Sig: m.Sig.Bytes(), + Sig: m.Sig.Bytes(), } } -func authSigMessageFromProto(p *tmp2p.AuthSigMessage) (*authSigMessage,error) { +func authSigMessageFromProto(p *tmp2p.AuthSigMessage) (*authSigMessage, error) { key, err := encoding.PubKeyFromProto(p.PubKey) if err != nil { - return nil,fmt.Errorf("PubKey: %w", err) + return nil, fmt.Errorf("PubKey: %w", err) } sig, err := crypto.SigFromBytes(p.Sig) if err != nil { - return nil,fmt.Errorf("Sig: %w", err) + return nil, fmt.Errorf("Sig: %w", err) } - return &authSigMessage{key,sig},nil -} - -func (sc *SecretConnection) shareAuthSignature(ctx context.Context, privKey crypto.PrivKey) (*authSigMessage, error) { - // Send our info and receive theirs in tandem. - return scope.Run1(ctx, func(ctx context.Context, s scope.Scope) (*authSigMessage,error) { - s.Spawn(func() error { - sig := privKey.Sign(sc.challenge[:]) - pk := tmproto.PublicKey{Sum: &tmproto.PublicKey_Ed25519{Ed25519: privKey.Public().Bytes()}} - msg := &tmp2p.AuthSigMessage{PubKey: pk, Sig: sig.Bytes()} - _,err := protoio.NewDelimitedWriter(sc).WriteMsg(msg) - return err - }) - var pba tmp2p.AuthSigMessage - if _, err := protoio.NewDelimitedReader(sc, 1024*1024).ReadMsg(&pba); err != nil { - return nil,err - } - return authSigMessageFromProto(&pba) - }) + return &authSigMessage{key, sig}, nil } diff --git a/sei-tendermint/internal/p2p/conn/secret_connection_test.go b/sei-tendermint/internal/p2p/conn/secret_connection_test.go index 09b569dc34..91a1978aa6 100644 --- a/sei-tendermint/internal/p2p/conn/secret_connection_test.go +++ b/sei-tendermint/internal/p2p/conn/secret_connection_test.go @@ -2,26 +2,25 @@ package conn import ( "bufio" + "context" "encoding/hex" + "errors" "flag" "fmt" "io" - "log" - "net" mrand "math/rand" + "net" "os" "path/filepath" "strconv" "strings" - "sync" "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/internal/libs/async" tmrand "github.com/tendermint/tendermint/libs/rand" + "github.com/tendermint/tendermint/libs/utils" + "github.com/tendermint/tendermint/libs/utils/require" + "github.com/tendermint/tendermint/libs/utils/scope" ) // Run go test -update from within this module @@ -34,10 +33,9 @@ type kvstoreConn struct { writer *io.PipeWriter } -func (drw kvstoreConn) Read(data []byte) (n int, err error) { return drw.reader.Read(data) } +func (drw kvstoreConn) Read(data []byte) (n int, err error) { return drw.reader.Read(data) } func (drw kvstoreConn) Write(data []byte) (n int, err error) { return drw.writer.Write(data) } - func (drw kvstoreConn) Close() (err error) { err2 := drw.writer.CloseWithError(io.EOF) err1 := drw.reader.Close() @@ -49,172 +47,98 @@ func (drw kvstoreConn) Close() (err error) { func TestSecretConnectionHandshake(t *testing.T) { fooSecConn, barSecConn := makeSecretConnPair(t) - if err := fooSecConn.Close(); err != nil { - t.Error(err) - } - if err := barSecConn.Close(); err != nil { - t.Error(err) - } + require.NoError(t, fooSecConn.Close()) + require.NoError(t, barSecConn.Close()) } -func TestConcurrentWrite(t *testing.T) { - fooSecConn, barSecConn := makeSecretConnPair(t) - fooWriteText := tmrand.Str(dataMaxSize) - - // write from two routines. - // should be safe from race according to net.Conn: - // https://golang.org/pkg/net/#Conn - n := 100 - wg := new(sync.WaitGroup) - wg.Add(3) - go writeLots(t, wg, fooSecConn, fooWriteText, n) - go writeLots(t, wg, fooSecConn, fooWriteText, n) - - // Consume reads from bar's reader - readLots(t, wg, barSecConn, n*2) - wg.Wait() - - if err := fooSecConn.Close(); err != nil { - t.Error(err) - } -} - -func TestConcurrentRead(t *testing.T) { - fooSecConn, barSecConn := makeSecretConnPair(t) - fooWriteText := tmrand.Str(dataMaxSize) - n := 100 +func TestConcurrentReadWrite(t *testing.T) { + ctx := t.Context() + sc1, sc2 := makeSecretConnPair(t) + rng := utils.TestRng() + fooWriteText := utils.GenBytes(rng, dataMaxSize) + n := 100 * dataMaxSize // read from two routines. // should be safe from race according to net.Conn: // https://golang.org/pkg/net/#Conn - wg := new(sync.WaitGroup) - wg.Add(3) - go readLots(t, wg, fooSecConn, n/2) - go readLots(t, wg, fooSecConn, n/2) - - // write to bar - writeLots(t, wg, barSecConn, fooWriteText, n) - wg.Wait() - - if err := fooSecConn.Close(); err != nil { - t.Error(err) - } + err := scope.Run(ctx, func(ctx context.Context, s scope.Scope) error { + s.Spawn(func() error { return readLots(sc1, n) }) + s.Spawn(func() error { return readLots(sc1, n) }) + s.Spawn(func() error { return writeLots(sc2, fooWriteText, n) }) + s.Spawn(func() error { return writeLots(sc2, fooWriteText, n) }) + return nil + }) + require.NoError(t, err) + require.NoError(t, sc1.Close()) + require.NoError(t, sc2.Close()) } func TestSecretConnectionReadWrite(t *testing.T) { - fooConn, barConn := makeKVStoreConnPair() - fooWrites, barWrites := []string{}, []string{} - fooReads, barReads := []string{}, []string{} - - // Pre-generate the things to write (for foo & bar) - for range 100 { - fooWrites = append(fooWrites, tmrand.Str((mrand.Int()%(dataMaxSize*5))+1)) - barWrites = append(barWrites, tmrand.Str((mrand.Int()%(dataMaxSize*5))+1)) - } - - // A helper that will run with (fooConn, fooWrites, fooReads) and vice versa - genNodeRunner := func(nodeConn kvstoreConn, nodeWrites []string, nodeReads *[]string) async.Task { - return func(_ int) (any, bool, error) { - // Initiate cryptographic private key and secret connection trhough nodeConn. - nodePrvKey := ed25519.GenerateSecretKey() - nodeSecretConn, err := MakeSecretConnection(nodeConn, nodePrvKey) - if err != nil { - t.Errorf("failed to establish SecretConnection for node: %v", err) - return nil, true, err - } - // In parallel, handle some reads and writes. - var trs, ok = async.Parallel( - func(_ int) (any, bool, error) { - // Node writes: - for _, nodeWrite := range nodeWrites { - n, err := nodeSecretConn.Write([]byte(nodeWrite)) + ctx := t.Context() + c1, c2 := makeKVStoreConnPair() + writes := utils.NewMutex(map[ed25519.PublicKey][]byte{}) + reads := utils.NewMutex(map[ed25519.PublicKey][]byte{}) + rng := utils.TestRng() + err := scope.Run(ctx, func(ctx context.Context, s scope.Scope) error { + for _, c := range utils.Slice(c1, c2) { + s.Spawn(func() error { + k := ed25519.GenerateSecretKey() + sc, err := MakeSecretConnection(ctx, c, k) + if err != nil { + return fmt.Errorf("MakeSecretConnection(): %w", err) + } + // In parallel, handle some reads and writes. + s.Spawn(func() error { + var ws []byte + for range 100 { + w := utils.GenBytes(rng, rng.Intn(dataMaxSize*5)+1) + ws = append(ws, w...) + n, err := sc.Write(w) if err != nil { - t.Errorf("failed to write to nodeSecretConn: %v", err) - return nil, true, err + return fmt.Errorf("failed to write to nodeSecretConn: %w", err) } - if n != len(nodeWrite) { - err = fmt.Errorf("failed to write all bytes. Expected %v, wrote %v", len(nodeWrite), n) - t.Error(err) - return nil, true, err + if n != len(w) { + return fmt.Errorf("failed to write all bytes. Expected %v, wrote %v", len(w), n) } } - if err := nodeConn.writer.Close(); err != nil { - t.Error(err) - return nil, true, err + for writes := range writes.Lock() { + writes[k.Public()] = ws } - return nil, false, nil - }, - func(_ int) (any, bool, error) { - // Node reads: + return c.writer.Close() + }) + s.Spawn(func() error { + var rs []byte readBuffer := make([]byte, dataMaxSize) for { - n, err := nodeSecretConn.Read(readBuffer) - if err == io.EOF { - if err := nodeConn.reader.Close(); err != nil { - t.Error(err) - return nil, true, err + n, err := sc.Read(readBuffer) + if err != nil { + if errors.Is(err, io.EOF) { + for reads := range reads.Lock() { + reads[sc.RemotePubKey()] = rs + } + return c.reader.Close() } - return nil, false, nil - } else if err != nil { - t.Errorf("failed to read from nodeSecretConn: %v", err) - return nil, true, err + return fmt.Errorf("failed to read from nodeSecretConn: %w", err) + } + if n == 0 { + return fmt.Errorf("Read() is nonblocking") } - *nodeReads = append(*nodeReads, string(readBuffer[:n])) + rs = append(rs, readBuffer[:n]...) } - }, - ) - assert.True(t, ok, "Unexpected task abortion") - - // If error: - if trs.FirstError() != nil { - return nil, true, trs.FirstError() - } - - // Otherwise: - return nil, false, nil + }) + return nil + }) } - } - - // Run foo & bar in parallel - var trs, ok = async.Parallel( - genNodeRunner(fooConn, fooWrites, &fooReads), - genNodeRunner(barConn, barWrites, &barReads), - ) - require.Nil(t, trs.FirstError()) - require.True(t, ok, "unexpected task abortion") - - // A helper to ensure that the writes and reads match. - // Additionally, small writes (<= dataMaxSize) must be atomically read. - compareWritesReads := func(writes []string, reads []string) { - for { - // Pop next write & corresponding reads - var read, write = "", writes[0] - var readCount = 0 - for _, readChunk := range reads { - read += readChunk - readCount++ - if len(write) <= len(read) { - break - } - if len(write) <= dataMaxSize { - break // atomicity of small writes - } - } - // Compare - if write != read { - t.Errorf("expected to read %X, got %X", write, read) - } - // Iterate - writes = writes[1:] - reads = reads[readCount:] - if len(writes) == 0 { - break + return nil + }) + require.NoError(t, err) + for reads := range reads.Lock() { + for writes := range writes.Lock() { + for k, want := range writes { + require.Equal(t, want, reads[k]) } } } - - compareWritesReads(fooWrites, barReads) - compareWritesReads(barWrites, fooReads) } func TestDeriveSecretsAndChallengeGolden(t *testing.T) { @@ -225,18 +149,14 @@ func TestDeriveSecretsAndChallengeGolden(t *testing.T) { require.NoError(t, os.WriteFile(goldenFilepath, []byte(data), 0644)) } f, err := os.Open(goldenFilepath) - if err != nil { - log.Fatal(err) - } - t.Cleanup(closeAll(t, f)) + require.NoError(t, err) + defer f.Close() scanner := bufio.NewScanner(f) for scanner.Scan() { line := scanner.Text() params := strings.Split(line, ",") - randSecretVector, err := hex.DecodeString(params[0]) + dh, err := hex.DecodeString(params[0]) require.NoError(t, err) - randSecret := new([32]byte) - copy((*randSecret)[:], randSecretVector) locIsLeast, err := strconv.ParseBool(params[1]) require.NoError(t, err) expectedRecvSecret, err := hex.DecodeString(params[2]) @@ -244,30 +164,33 @@ func TestDeriveSecretsAndChallengeGolden(t *testing.T) { expectedSendSecret, err := hex.DecodeString(params[3]) require.NoError(t, err) - recvSecret, sendSecret := deriveSecrets(randSecret, locIsLeast) - require.Equal(t, expectedRecvSecret, (*recvSecret)[:], "Recv Secrets aren't equal") - require.Equal(t, expectedSendSecret, (*sendSecret)[:], "Send Secrets aren't equal") + aead := dhSecret(dh).AeadSecrets(locIsLeast) + require.Equal(t, aeadSecret(expectedRecvSecret), aead.recv, "Recv Secrets aren't equal") + require.Equal(t, aeadSecret(expectedSendSecret), aead.send, "Send Secrets aren't equal") } } -func writeLots(t *testing.T, wg *sync.WaitGroup, conn io.Writer, txt string, n int) { - defer wg.Done() - for range n { - _, err := conn.Write([]byte(txt)) - if err != nil { - t.Errorf("failed to write to fooSecConn: %v", err) - return +func writeLots(sc *SecretConnection, data []byte, total int) error { + for total > 0 { + n := min(len(data), total) + total -= n + if _, err := sc.Write(data[:n]); err != nil { + return err } } + return nil } -func readLots(t *testing.T, wg *sync.WaitGroup, conn io.Reader, n int) { - readBuffer := make([]byte, dataMaxSize) - for range n { - _, err := conn.Read(readBuffer) - assert.NoError(t, err) +func readLots(sc *SecretConnection, total int) error { + for total > 0 { + readBuffer := make([]byte, min(dataMaxSize, total)) + n, err := sc.Read(readBuffer) + if err != nil { + return err + } + total -= n } - wg.Done() + return nil } // Creates the data for a test vector file. @@ -276,15 +199,13 @@ func readLots(t *testing.T, wg *sync.WaitGroup, conn io.Reader, n int) { func createGoldenTestVectors() string { data := "" for range 32 { - randSecretVector := tmrand.Bytes(32) - randSecret := new([32]byte) - copy((*randSecret)[:], randSecretVector) - data += hex.EncodeToString((*randSecret)[:]) + "," + dh := dhSecret(tmrand.Bytes(len(dhSecret{}))) + data += hex.EncodeToString(dh[:]) + "," locIsLeast := mrand.Int63()%2 == 0 data += strconv.FormatBool(locIsLeast) + "," - recvSecret, sendSecret := deriveSecrets(randSecret, locIsLeast) - data += hex.EncodeToString((*recvSecret)[:]) + "," - data += hex.EncodeToString((*sendSecret)[:]) + "," + aead := dh.AeadSecrets(locIsLeast) + data += hex.EncodeToString(aead.recv[:]) + "," + data += hex.EncodeToString(aead.send[:]) + "," } return data } @@ -293,56 +214,35 @@ func createGoldenTestVectors() string { func makeKVStoreConnPair() (fooConn, barConn kvstoreConn) { barReader, fooWriter := io.Pipe() fooReader, barWriter := io.Pipe() - return kvstoreConn{reader:fooReader, writer:fooWriter}, kvstoreConn{reader:barReader, writer:barWriter} + return kvstoreConn{reader: fooReader, writer: fooWriter}, kvstoreConn{reader: barReader, writer: barWriter} } -func makeSecretConnPair(tb testing.TB) (fooSecConn, barSecConn *SecretConnection) { - var ( - fooConn, barConn = makeKVStoreConnPair() - fooPrvKey = ed25519.GenerateSecretKey() - fooPubKey = fooPrvKey.Public() - barPrvKey = ed25519.GenerateSecretKey() - barPubKey = barPrvKey.Public() - ) +func makeSecretConnPair(tb testing.TB) (sc1 *SecretConnection, sc2 *SecretConnection) { + ctx := tb.Context() + c1, c2 := makeKVStoreConnPair() + k1 := ed25519.GenerateSecretKey() + k2 := ed25519.GenerateSecretKey() // Make connections from both sides in parallel. - var trs, ok = async.Parallel( - func(_ int) (val any, abort bool, err error) { - fooSecConn, err = MakeSecretConnection(fooConn, fooPrvKey) - if err != nil { - tb.Errorf("failed to establish SecretConnection for foo: %v", err) - return nil, true, err - } - remotePubKey := fooSecConn.RemotePubKey() - if remotePubKey != barPubKey { - err = fmt.Errorf("unexpected fooSecConn.RemotePubKey. Expected %v, got %v", - barPubKey, remotePubKey) - tb.Error(err) - return nil, true, err - } - return nil, false, nil - }, - func(_ int) (val any, abort bool, err error) { - barSecConn, err = MakeSecretConnection(barConn, barPrvKey) - if barSecConn == nil { - tb.Errorf("failed to establish SecretConnection for bar: %v", err) - return nil, true, err - } - remotePubKey := barSecConn.RemotePubKey() - if remotePubKey != fooPubKey { - err = fmt.Errorf("unexpected barSecConn.RemotePubKey. Expected %v, got %v", - fooPubKey, remotePubKey) - tb.Error(err) - return nil, true, err - } - return nil, false, nil - }, - ) - - require.Nil(tb, trs.FirstError()) - require.True(tb, ok, "Unexpected task abortion") - - return fooSecConn, barSecConn + err := scope.Run(ctx, func(ctx context.Context, s scope.Scope) error { + s.Spawn(func() error { + var err error + sc1, err = MakeSecretConnection(ctx, c1, k1) + return err + }) + s.Spawn(func() error { + var err error + sc2, err = MakeSecretConnection(ctx, c2, k2) + return err + }) + return nil + }) + if err != nil { + tb.Fatal(err) + } + require.Equal(tb, k1.Public(), sc2.RemotePubKey()) + require.Equal(tb, k2.Public(), sc1.RemotePubKey()) + return sc1, sc2 } // Benchmarks @@ -432,17 +332,3 @@ func BenchmarkReadSecretConnection(b *testing.B) { } } } - -type closer interface { - Close() error -} - -func closeAll(t *testing.T, closers ...closer) func() { - return func() { - for _, s := range closers { - if err := s.Close(); err != nil { - t.Log(err) - } - } - } -} diff --git a/sei-tendermint/internal/p2p/transport.go b/sei-tendermint/internal/p2p/transport.go index b055c62f7e..bc48f1753b 100644 --- a/sei-tendermint/internal/p2p/transport.go +++ b/sei-tendermint/internal/p2p/transport.go @@ -84,7 +84,7 @@ func (r *Router) handshake(ctx context.Context, tcpConn *net.TCPConn, dialAddr u return nil }) var err error - secretConn, err := conn.MakeSecretConnection(tcpConn, r.privKey) + secretConn, err := conn.MakeSecretConnection(ctx, tcpConn, r.privKey) if err != nil { return nil, err } From cf932f1239b08a8162edd42733aba44dfaa7972f Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Mon, 22 Dec 2025 14:19:19 +0100 Subject: [PATCH 47/53] dst for ed25519 --- sei-tendermint/crypto/ed25519/ed25519.go | 49 +++++++++++++++-- sei-tendermint/crypto/ed25519/ed25519_test.go | 54 ++++++++++++++++--- 2 files changed, 92 insertions(+), 11 deletions(-) diff --git a/sei-tendermint/crypto/ed25519/ed25519.go b/sei-tendermint/crypto/ed25519/ed25519.go index b17f3dda4f..9b0d7d073f 100644 --- a/sei-tendermint/crypto/ed25519/ed25519.go +++ b/sei-tendermint/crypto/ed25519/ed25519.go @@ -32,7 +32,7 @@ const cacheSize = 4096 // curve25519-voi's Ed25519 implementation supports configurable // verification behavior, and tendermint uses the ZIP-215 verification // semantics. -var verifyOptions = &ed25519.Options{Verify: ed25519.VerifyOptionsZIP_215} +var verifyOptions = ed25519.VerifyOptionsZIP_215 var cachingVerifier = cache.NewVerifier(cache.NewLRUCache(cacheSize)) // SecretKey represents a secret key in the Ed25519 signature scheme. @@ -129,26 +129,65 @@ func (k SecretKey) Sign(message []byte) Signature { } } +// Domain separation tag. +type Tag struct{ tag string } + +func NewTag(tag string) (Tag, error) { + if len(tag) > ed25519.ContextMaxSize { + return Tag{}, fmt.Errorf("len(%q) = %v, want <= %v", tag, len(tag), ed25519.ContextMaxSize) + } + return Tag{tag}, nil +} + +// SignWithTag signs a message with a domain separation tag. +// It is safe to assume that signatures for messages with different tags do not collide. +// It is also safe to assume that Sign() signatures do not collide with SignWithTag() signatures. +// It is secure to use the same secret key for signing with both Sign() and SignWithTag() [https://datatracker.ietf.org/doc/html/rfc8032#section-8.6]. +func (k SecretKey) SignWithTag(tag Tag, msg []byte) Signature { + opts := &ed25519.Options{Context: tag.tag} + // Returns no error if opts.Context is of correct size. + sig := utils.OrPanic1(ed25519.PrivateKey((*k.key)[:]).Sign(nil, msg, opts)) + return Signature{sig: [ed25519.SignatureSize]byte(sig)} +} + // Compare defines a total order on public keys. func (k PublicKey) Compare(other PublicKey) int { return bytes.Compare(k.key[:], other.key[:]) } -// Verify verifies a signature using the public key. +// Verify verifies a signature. func (k PublicKey) Verify(msg []byte, sig Signature) error { - if !cachingVerifier.VerifyWithOptions(k.key[:], msg, sig.sig[:], verifyOptions) { + opts := &ed25519.Options{Verify: verifyOptions} + if !cachingVerifier.VerifyWithOptions(k.key[:], msg, sig.sig[:], opts) { + return ErrBadSig{} + } + return nil +} + +// Verify verifies a signature, given domain separation tag. +func (k PublicKey) VerifyWithTag(tag Tag, msg []byte, sig Signature) error { + opts := &ed25519.Options{Context: tag.tag, Verify: verifyOptions} + if !cachingVerifier.VerifyWithOptions(k.key[:], msg, sig.sig[:], opts) { return ErrBadSig{} } return nil } // BatchVerifier implements batch verification for ed25519. -type BatchVerifier struct{ inner *ed25519.BatchVerifier } +type BatchVerifier struct { + inner *ed25519.BatchVerifier +} func NewBatchVerifier() *BatchVerifier { return &BatchVerifier{ed25519.NewBatchVerifier()} } func (b *BatchVerifier) Add(key PublicKey, msg []byte, sig Signature) { - cachingVerifier.AddWithOptions(b.inner, key.key[:], msg, sig.sig[:], verifyOptions) + opts := &ed25519.Options{Verify: verifyOptions} + cachingVerifier.AddWithOptions(b.inner, key.key[:], msg, sig.sig[:], opts) +} + +func (b *BatchVerifier) AddWithTag(key PublicKey, tag Tag, msg []byte, sig Signature) { + opts := &ed25519.Options{Context: tag.tag, Verify: verifyOptions} + cachingVerifier.AddWithOptions(b.inner, key.key[:], msg, sig.sig[:], opts) } // Verify verifies the batched signatures using OS entropy. diff --git a/sei-tendermint/crypto/ed25519/ed25519_test.go b/sei-tendermint/crypto/ed25519/ed25519_test.go index 3357e1e652..2ad4769e02 100644 --- a/sei-tendermint/crypto/ed25519/ed25519_test.go +++ b/sei-tendermint/crypto/ed25519/ed25519_test.go @@ -2,6 +2,7 @@ package ed25519 import ( "fmt" + "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/libs/utils/require" "testing" ) @@ -22,22 +23,63 @@ func TestSign(t *testing.T) { } } -func TestBatchSafe(t *testing.T) { +func TestSignWithTag(t *testing.T) { + var keys []SecretKey + for i := range byte(3) { + keys = append(keys, TestSecretKey([]byte{i})) + } + t.Logf("keys = %+v", keys) + msg := []byte("test message") + tag := utils.OrPanic1(NewTag("testTag")) + for i := range keys { + for j := range keys { + if wantErr, err := i != j, keys[j].Public().VerifyWithTag(tag, msg, keys[i].SignWithTag(tag, msg)); wantErr != (err != nil) { + t.Errorf("keys[%d].Verify(keys[%d].Sign()) = %v, wantErr = %v", j, i, err, wantErr) + } + } + } +} + +func TestDomainSeparation(t *testing.T) { + msg := []byte("test message") + tag1 := utils.OrPanic1(NewTag("testTag")) + tag2 := utils.OrPanic1(NewTag("testTag2")) + k := TestSecretKey([]byte{34, 33}) + sigs := map[utils.Option[Tag]]Signature{} + sigs[utils.Some(tag1)] = k.SignWithTag(tag1, msg) + sigs[utils.Some(tag2)] = k.SignWithTag(tag2, msg) + sigs[utils.None[Tag]()] = k.Sign(msg) + for _, tag := range utils.Slice(utils.Some(tag1), utils.Some(tag2), utils.None[Tag]()) { + for wantTag, sig := range sigs { + var err error + if tag, ok := tag.Get(); ok { + err = k.Public().VerifyWithTag(tag, msg, sig) + } else { + err = k.Public().Verify(msg, sig) + } + require.Equal(t, err == nil, tag == wantTag, "err = %v", err) + } + } +} + +func TestBatchVerifier(t *testing.T) { v := NewBatchVerifier() + tag := utils.OrPanic1(NewTag("testTag")) - for i := 0; i <= 38; i++ { + for i := range 100 { priv := TestSecretKey(fmt.Appendf(nil, "test-%v", i)) pub := priv.Public() - var msg []byte if i%2 == 0 { msg = []byte("easter") } else { msg = []byte("egg") } - - v.Add(pub, msg, priv.Sign(msg)) + if i%3 == 0 { + v.AddWithTag(pub, tag, msg, priv.SignWithTag(tag, msg)) + } else { + v.Add(pub, msg, priv.Sign(msg)) + } } - require.NoError(t, v.Verify()) } From 2fd89102b6f8984ffee521461015f23d7e2f307a Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Mon, 22 Dec 2025 15:18:19 +0100 Subject: [PATCH 48/53] tm tests compile --- .../abci/example/kvstore/helpers.go | 5 +- .../abci/example/kvstore/kvstore.go | 8 +- sei-tendermint/abci/tests/server/client.go | 5 +- sei-tendermint/abci/types/pubkey.go | 13 -- sei-tendermint/abci/types/types.go | 5 +- sei-tendermint/crypto/conv.go | 35 +++++ sei-tendermint/crypto/encoding/codec.go | 30 ----- .../internal/consensus/reactor_test.go | 4 +- .../internal/consensus/replay_test.go | 9 +- .../internal/p2p/conn/connection.go | 16 +-- .../internal/p2p/conn/connection_test.go | 10 +- .../p2p/conn/evil_secret_connection_test.go | 3 +- .../internal/p2p/conn/secret_connection.go | 46 +++---- sei-tendermint/internal/p2p/pex/reactor.go | 6 +- .../internal/p2p/pex/reactor_test.go | 14 +- sei-tendermint/internal/state/execution.go | 4 +- .../internal/state/execution_test.go | 13 +- sei-tendermint/internal/state/helpers_test.go | 7 +- sei-tendermint/internal/state/state_test.go | 29 ++--- sei-tendermint/privval/grpc/client.go | 3 +- sei-tendermint/privval/grpc/server.go | 3 +- sei-tendermint/privval/grpc/server_test.go | 3 +- sei-tendermint/privval/msgs_test.go | 3 +- sei-tendermint/privval/signer_client.go | 8 +- .../privval/signer_requestHandler.go | 3 +- .../proto/tendermint/p2p/conn.pb.go | 121 +++++++++--------- .../proto/tendermint/p2p/conn.proto | 7 +- sei-tendermint/proto/tendermint/p2p/pex.pb.go | 61 +++++---- sei-tendermint/proto/tendermint/p2p/pex.proto | 5 +- sei-tendermint/rpc/client/rpc_test.go | 4 +- sei-tendermint/test/e2e/app/app.go | 6 +- .../fuzz/tests/p2p_secretconnection_test.go | 103 ++++++--------- sei-tendermint/types/protobuf.go | 6 +- sei-tendermint/types/protobuf_test.go | 5 +- sei-tendermint/types/validator.go | 7 +- 35 files changed, 288 insertions(+), 322 deletions(-) delete mode 100644 sei-tendermint/abci/types/pubkey.go create mode 100644 sei-tendermint/crypto/conv.go delete mode 100644 sei-tendermint/crypto/encoding/codec.go diff --git a/sei-tendermint/abci/example/kvstore/helpers.go b/sei-tendermint/abci/example/kvstore/helpers.go index a287a2f8ed..b059c64d09 100644 --- a/sei-tendermint/abci/example/kvstore/helpers.go +++ b/sei-tendermint/abci/example/kvstore/helpers.go @@ -24,7 +24,10 @@ func RandVals(cnt int) []types.ValidatorUpdate { if err != nil { panic(err) } - res[i] = types.UpdateValidator(pubKey, int64(power), "") + res[i] = types.ValidatorUpdate{ + PubKey: crypto.PubKeyToProto(pubKey), + Power: int64(power), + } } return res } diff --git a/sei-tendermint/abci/example/kvstore/kvstore.go b/sei-tendermint/abci/example/kvstore/kvstore.go index 4c219f8db1..7bda59267d 100644 --- a/sei-tendermint/abci/example/kvstore/kvstore.go +++ b/sei-tendermint/abci/example/kvstore/kvstore.go @@ -16,7 +16,7 @@ import ( "github.com/tendermint/tendermint/abci/example/code" "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/crypto/encoding" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/libs/log" cryptoproto "github.com/tendermint/tendermint/proto/tendermint/crypto" "github.com/tendermint/tendermint/version" @@ -329,7 +329,7 @@ func (app *Application) Validators() (validators []types.ValidatorUpdate) { } func MakeValSetChangeTx(pubkey cryptoproto.PublicKey, power int64) []byte { - pk, err := encoding.PubKeyFromProto(pubkey) + pk, err := crypto.PubKeyFromProto(pubkey) if err != nil { panic(err) } @@ -379,12 +379,12 @@ func (app *Application) execValidatorTx(tx []byte) *types.ExecTxResult { Log: fmt.Sprintf("can't decode ed25519 key: %v", err), } } - return app.updateValidator(types.UpdateValidator(key, power, "")) + return app.updateValidator(types.ValidatorUpdate{PubKey: crypto.PubKeyToProto(key), Power: power}) } // add, update, or remove a validator func (app *Application) updateValidator(v types.ValidatorUpdate) *types.ExecTxResult { - pubkey, err := encoding.PubKeyFromProto(v.PubKey) + pubkey, err := crypto.PubKeyFromProto(v.PubKey) if err != nil { panic(fmt.Errorf("can't decode public key: %w", err)) } diff --git a/sei-tendermint/abci/tests/server/client.go b/sei-tendermint/abci/tests/server/client.go index 2b7f4bcb73..23fddcd2e1 100644 --- a/sei-tendermint/abci/tests/server/client.go +++ b/sei-tendermint/abci/tests/server/client.go @@ -24,7 +24,10 @@ func InitChain(ctx context.Context, client abciclient.Client) error { } // nolint:gosec // G404: Use of weak random number generator power := mrand.Int() - vals[i] = types.UpdateValidator(pubkey, int64(power), "") + vals[i] = types.ValidatorUpdate { + PubKey: crypto.PubKeyToProto(pubkey), + Power: int64(power), + } } _, err := client.InitChain(ctx, &types.RequestInitChain{ Validators: vals, diff --git a/sei-tendermint/abci/types/pubkey.go b/sei-tendermint/abci/types/pubkey.go deleted file mode 100644 index c556e11f3b..0000000000 --- a/sei-tendermint/abci/types/pubkey.go +++ /dev/null @@ -1,13 +0,0 @@ -package types - -import ( - "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/encoding" -) - -func UpdateValidator(pk crypto.PubKey, power int64, keyType string) ValidatorUpdate { - return ValidatorUpdate{ - PubKey: encoding.PubKeyToProto(pk), - Power: power, - } -} diff --git a/sei-tendermint/abci/types/types.go b/sei-tendermint/abci/types/types.go index c9bc0f8153..665a1a1008 100644 --- a/sei-tendermint/abci/types/types.go +++ b/sei-tendermint/abci/types/types.go @@ -6,7 +6,6 @@ import ( "github.com/gogo/protobuf/jsonpb" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/internal/jsontypes" ) @@ -133,7 +132,7 @@ type validatorUpdateJSON struct { } func (v *ValidatorUpdate) MarshalJSON() ([]byte, error) { - key, err := encoding.PubKeyFromProto(v.PubKey) + key, err := crypto.PubKeyFromProto(v.PubKey) if err != nil { return nil, err } @@ -156,7 +155,7 @@ func (v *ValidatorUpdate) UnmarshalJSON(data []byte) error { if err := jsontypes.Unmarshal(vu.PubKey, &key); err != nil { return err } - v.PubKey = encoding.PubKeyToProto(key) + v.PubKey = crypto.PubKeyToProto(key) v.Power = vu.Power return nil } diff --git a/sei-tendermint/crypto/conv.go b/sei-tendermint/crypto/conv.go new file mode 100644 index 0000000000..665af1c04a --- /dev/null +++ b/sei-tendermint/crypto/conv.go @@ -0,0 +1,35 @@ +package crypto + +import ( + "fmt" + + "github.com/tendermint/tendermint/libs/utils" + "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/internal/jsontypes" + pb "github.com/tendermint/tendermint/proto/tendermint/crypto" +) + +func init() { + jsontypes.MustRegister((*pb.PublicKey)(nil)) + jsontypes.MustRegister((*pb.PublicKey_Ed25519)(nil)) +} + +var PubKeyConv = utils.ProtoConv[PubKey,*pb.PublicKey]{ + Encode: func(k PubKey) *pb.PublicKey { return utils.Alloc(PubKeyToProto(k)) }, + Decode: func(x *pb.PublicKey) (PubKey,error) { return PubKeyFromProto(*x) }, +} + +// PubKeyToProto takes crypto.PubKey and transforms it to a protobuf Pubkey +func PubKeyToProto(k PubKey) pb.PublicKey { + return pb.PublicKey{Sum: &pb.PublicKey_Ed25519{Ed25519: k.Bytes()}} +} + +// PubKeyFromProto takes a protobuf Pubkey and transforms it to a crypto.Pubkey +func PubKeyFromProto(k pb.PublicKey) (PubKey, error) { + switch k := k.Sum.(type) { + case *pb.PublicKey_Ed25519: + return ed25519.PublicKeyFromBytes(k.Ed25519) + default: + return PubKey{}, fmt.Errorf("fromproto: key type %v is not supported", k) + } +} diff --git a/sei-tendermint/crypto/encoding/codec.go b/sei-tendermint/crypto/encoding/codec.go deleted file mode 100644 index 210979e4d6..0000000000 --- a/sei-tendermint/crypto/encoding/codec.go +++ /dev/null @@ -1,30 +0,0 @@ -package encoding - -import ( - "fmt" - - "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/internal/jsontypes" - cryptoproto "github.com/tendermint/tendermint/proto/tendermint/crypto" -) - -func init() { - jsontypes.MustRegister((*cryptoproto.PublicKey)(nil)) - jsontypes.MustRegister((*cryptoproto.PublicKey_Ed25519)(nil)) -} - -// PubKeyToProto takes crypto.PubKey and transforms it to a protobuf Pubkey -func PubKeyToProto(k crypto.PubKey) cryptoproto.PublicKey { - return cryptoproto.PublicKey{Sum: &cryptoproto.PublicKey_Ed25519{Ed25519: k.Bytes()}} -} - -// PubKeyFromProto takes a protobuf Pubkey and transforms it to a crypto.Pubkey -func PubKeyFromProto(k cryptoproto.PublicKey) (crypto.PubKey, error) { - switch k := k.Sum.(type) { - case *cryptoproto.PublicKey_Ed25519: - return ed25519.PublicKeyFromBytes(k.Ed25519) - default: - return crypto.PubKey{}, fmt.Errorf("fromproto: key type %v is not supported", k) - } -} diff --git a/sei-tendermint/internal/consensus/reactor_test.go b/sei-tendermint/internal/consensus/reactor_test.go index 0e75cfc5cd..1eb0e59fbb 100644 --- a/sei-tendermint/internal/consensus/reactor_test.go +++ b/sei-tendermint/internal/consensus/reactor_test.go @@ -19,7 +19,7 @@ import ( "github.com/tendermint/tendermint/abci/example/kvstore" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/crypto/encoding" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/internal/eventbus" "github.com/tendermint/tendermint/internal/mempool" "github.com/tendermint/tendermint/internal/p2p" @@ -501,7 +501,7 @@ func TestReactorValidatorSetChanges(t *testing.T) { pv, _ := states[nodeIdx].privValidator.Get() key, err := pv.GetPubKey(ctx) require.NoError(t, err) - keyProto := encoding.PubKeyToProto(key) + keyProto := crypto.PubKeyToProto(key) newPower := int64(rng.Intn(100000)) tx := kvstore.MakeValSetChangeTx(keyProto, newPower) require.NoError(t, finalizeTx(ctx, valSet, blocksSubs, states, tx)) diff --git a/sei-tendermint/internal/consensus/replay_test.go b/sei-tendermint/internal/consensus/replay_test.go index a63ea8a2f3..75b7d8d949 100644 --- a/sei-tendermint/internal/consensus/replay_test.go +++ b/sei-tendermint/internal/consensus/replay_test.go @@ -21,7 +21,6 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/internal/eventbus" "github.com/tendermint/tendermint/internal/mempool" "github.com/tendermint/tendermint/internal/proxy" @@ -343,7 +342,7 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite { pv, _ := css[nVals].privValidator.Get() newValidatorPubKey1, err := pv.GetPubKey(ctx) require.NoError(t, err) - valPubKey1ABCI := encoding.PubKeyToProto(newValidatorPubKey1) + valPubKey1ABCI := crypto.PubKeyToProto(newValidatorPubKey1) newValidatorTx1 := kvstore.MakeValSetChangeTx(valPubKey1ABCI, testMinPower) err = assertMempool(t, css[0].txNotifier).CheckTx(ctx, newValidatorTx1, nil, mempool.TxInfo{}) assert.NoError(t, err) @@ -379,7 +378,7 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite { pv, _ = css[nVals].privValidator.Get() updateValidatorPubKey1, err := pv.GetPubKey(ctx) require.NoError(t, err) - updatePubKey1ABCI := encoding.PubKeyToProto(updateValidatorPubKey1) + updatePubKey1ABCI := crypto.PubKeyToProto(updateValidatorPubKey1) updateValidatorTx1 := kvstore.MakeValSetChangeTx(updatePubKey1ABCI, 25) err = assertMempool(t, css[0].txNotifier).CheckTx(ctx, updateValidatorTx1, nil, mempool.TxInfo{}) assert.NoError(t, err) @@ -414,14 +413,14 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite { pv, _ = css[nVals+1].privValidator.Get() newValidatorPubKey2, err := pv.GetPubKey(ctx) require.NoError(t, err) - newVal2ABCI := encoding.PubKeyToProto(newValidatorPubKey2) + newVal2ABCI := crypto.PubKeyToProto(newValidatorPubKey2) newValidatorTx2 := kvstore.MakeValSetChangeTx(newVal2ABCI, testMinPower) err = assertMempool(t, css[0].txNotifier).CheckTx(ctx, newValidatorTx2, nil, mempool.TxInfo{}) assert.NoError(t, err) pv, _ = css[nVals+2].privValidator.Get() newValidatorPubKey3, err := pv.GetPubKey(ctx) require.NoError(t, err) - newVal3ABCI := encoding.PubKeyToProto(newValidatorPubKey3) + newVal3ABCI := crypto.PubKeyToProto(newValidatorPubKey3) newValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, testMinPower) err = assertMempool(t, css[0].txNotifier).CheckTx(ctx, newValidatorTx3, nil, mempool.TxInfo{}) assert.NoError(t, err) diff --git a/sei-tendermint/internal/p2p/conn/connection.go b/sei-tendermint/internal/p2p/conn/connection.go index 571a9ced2e..381d6c8827 100644 --- a/sei-tendermint/internal/p2p/conn/connection.go +++ b/sei-tendermint/internal/p2p/conn/connection.go @@ -421,10 +421,10 @@ func (c *MConnection) recvRoutine(ctx context.Context) (err error) { recvPong.Store(true) } case *p2p.Packet_PacketMsg: - channelID, castOk := utils.SafeCast[ChannelID](p.PacketMsg.ChannelID) + channelID, castOk := utils.SafeCast[ChannelID](p.PacketMsg.ChannelId) ch, ok := channels[channelID] if !castOk || !ok { - return errBadChannel{fmt.Errorf("unknown channel %X", p.PacketMsg.ChannelID)} + return errBadChannel{fmt.Errorf("unknown channel %X", p.PacketMsg.ChannelId)} } c.logger.Debug("Read PacketMsg", "conn", c, "packet", packet) msgBytes, err := ch.pushMsg(p.PacketMsg) @@ -451,8 +451,8 @@ func (c *MConnection) maxPacketMsgSize() int { bz, err := proto.Marshal(&p2p.Packet{ Sum: &p2p.Packet_PacketMsg{ PacketMsg: &p2p.PacketMsg{ - ChannelID: 0x01, - EOF: true, + ChannelId: 0x01, + Eof: true, Data: make([]byte, c.config.MaxPacketMsgPayloadSize), }, }, @@ -477,12 +477,12 @@ func (ch *sendChannel) ratio() float32 { // Not goroutine-safe func (ch *sendChannel) popMsg(maxPayload int) *p2p.PacketMsg { payload := ch.queue.Get(0) - packet := &p2p.PacketMsg{ChannelID: int32(ch.desc.ID)} + packet := &p2p.PacketMsg{ChannelId: int32(ch.desc.ID)} if len(*payload) <= maxPayload { - packet.EOF = true + packet.Eof = true packet.Data = *ch.queue.PopFront() } else { - packet.EOF = false + packet.Eof = false packet.Data = (*payload)[:maxPayload] *payload = (*payload)[maxPayload:] } @@ -509,7 +509,7 @@ func (ch *recvChannel) pushMsg(packet *p2p.PacketMsg) ([]byte, error) { return nil, fmt.Errorf("received message exceeds available capacity: %v < %v", wantMax, got) } ch.buf = append(ch.buf, packet.Data...) - if packet.EOF { + if packet.Eof { msgBytes := ch.buf ch.buf = make([]byte, 0, ch.desc.RecvBufferCapacity) return msgBytes, nil diff --git a/sei-tendermint/internal/p2p/conn/connection_test.go b/sei-tendermint/internal/p2p/conn/connection_test.go index 37ccf411ff..85d9f6e1ea 100644 --- a/sei-tendermint/internal/p2p/conn/connection_test.go +++ b/sei-tendermint/internal/p2p/conn/connection_test.go @@ -201,8 +201,8 @@ func TestMConnectionReadErrorLongMessage(t *testing.T) { // send msg thats just right msg := &p2p.PacketMsg{ - ChannelID: 0x01, - EOF: true, + ChannelId: 0x01, + Eof: true, Data: make([]byte, mconn1.config.MaxPacketMsgPayloadSize), } packet := &p2p.Packet{ @@ -245,7 +245,7 @@ func TestConnVectors(t *testing.T) { {"PacketPong", pongMsg(), "1200"}, {"PacketMsg", &p2p.Packet{Sum: &p2p.Packet_PacketMsg{ PacketMsg: &p2p.PacketMsg{ - ChannelID: 1, EOF: false, Data: []byte("data transmitted over the wire"), + ChannelId: 1, Eof: false, Data: []byte("data transmitted over the wire"), }, }}, "1a2208011a1e64617461207472616e736d6974746564206f766572207468652077697265"}, } @@ -271,8 +271,8 @@ func TestMConnectionChannelOverflow(t *testing.T) { protoWriter := protoio.NewDelimitedWriter(c2) msg := &p2p.PacketMsg{ - ChannelID: int32(1025), - EOF: true, + ChannelId: int32(1025), + Eof: true, Data: []byte(`42`), } packet := &p2p.Packet{ diff --git a/sei-tendermint/internal/p2p/conn/evil_secret_connection_test.go b/sei-tendermint/internal/p2p/conn/evil_secret_connection_test.go index 6ff93016c3..6d0610e992 100644 --- a/sei-tendermint/internal/p2p/conn/evil_secret_connection_test.go +++ b/sei-tendermint/internal/p2p/conn/evil_secret_connection_test.go @@ -11,7 +11,6 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/internal/libs/protoio" "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/libs/utils/require" @@ -104,7 +103,7 @@ func (c *evilConn) Read(data []byte) (n int, err error) { case 1: signature := c.signChallenge() if !c.badAuthSignature { - pkpb := encoding.PubKeyToProto(c.privKey.Public()) + pkpb := crypto.PubKeyConv.Encode(c.privKey.Public()) bz, err := protoio.MarshalDelimited(&tmp2p.AuthSigMessage{PubKey: pkpb, Sig: signature.Bytes()}) if err != nil { panic(err) diff --git a/sei-tendermint/internal/p2p/conn/secret_connection.go b/sei-tendermint/internal/p2p/conn/secret_connection.go index ac7af42992..4d4f099dd1 100644 --- a/sei-tendermint/internal/p2p/conn/secret_connection.go +++ b/sei-tendermint/internal/p2p/conn/secret_connection.go @@ -23,11 +23,10 @@ import ( "golang.org/x/crypto/nacl/box" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/internal/libs/protoio" "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/libs/utils/scope" - tmp2p "github.com/tendermint/tendermint/proto/tendermint/p2p" + pb "github.com/tendermint/tendermint/proto/tendermint/p2p" ) // 4 + 1024 == 1028 total frame size @@ -138,15 +137,15 @@ func MakeSecretConnection(ctx context.Context, conn net.Conn, locPrivKey crypto. return scope.Run1(ctx, func(ctx context.Context, s scope.Scope) (*SecretConnection, error) { // Share (in secret) each other's pubkey & challenge signature s.Spawn(func() error { - loc := authSigMessage{locPrivKey.Public(), locPrivKey.Sign(sc.challenge[:])} - _, err := protoio.NewDelimitedWriter(sc).WriteMsg(loc.ToProto()) + loc := &authSigMessage{locPrivKey.Public(), locPrivKey.Sign(sc.challenge[:])} + _, err := protoio.NewDelimitedWriter(sc).WriteMsg(authSigMessageConv.Encode(loc)) return err }) - var pba tmp2p.AuthSigMessage + var pba pb.AuthSigMessage if _, err := protoio.NewDelimitedReader(sc, 1024*1024).ReadMsg(&pba); err != nil { return nil, err } - rem, err := authSigMessageFromProto(&pba) + rem, err := authSigMessageConv.Decode(&pba) if err != nil { return nil, fmt.Errorf("authSigMessageFromProto(): %w", err) } @@ -337,21 +336,22 @@ type authSigMessage struct { Sig crypto.Sig } -func (m *authSigMessage) ToProto() *tmp2p.AuthSigMessage { - return &tmp2p.AuthSigMessage{ - PubKey: encoding.PubKeyToProto(m.Key), - Sig: m.Sig.Bytes(), - } -} - -func authSigMessageFromProto(p *tmp2p.AuthSigMessage) (*authSigMessage, error) { - key, err := encoding.PubKeyFromProto(p.PubKey) - if err != nil { - return nil, fmt.Errorf("PubKey: %w", err) - } - sig, err := crypto.SigFromBytes(p.Sig) - if err != nil { - return nil, fmt.Errorf("Sig: %w", err) - } - return &authSigMessage{key, sig}, nil +var authSigMessageConv = utils.ProtoConv[*authSigMessage, *pb.AuthSigMessage] { + Encode: func(m *authSigMessage) *pb.AuthSigMessage { + return &pb.AuthSigMessage{ + PubKey: crypto.PubKeyConv.Encode(m.Key), + Sig: m.Sig.Bytes(), + } + }, + Decode: func(p *pb.AuthSigMessage) (*authSigMessage, error) { + key, err := crypto.PubKeyConv.DecodeReq(p.PubKey) + if err != nil { + return nil, fmt.Errorf("PubKey: %w", err) + } + sig, err := crypto.SigFromBytes(p.Sig) + if err != nil { + return nil, fmt.Errorf("Sig: %w", err) + } + return &authSigMessage{key, sig}, nil + }, } diff --git a/sei-tendermint/internal/p2p/pex/reactor.go b/sei-tendermint/internal/p2p/pex/reactor.go index 8b24237c85..cf2a82dd9c 100644 --- a/sei-tendermint/internal/p2p/pex/reactor.go +++ b/sei-tendermint/internal/p2p/pex/reactor.go @@ -194,9 +194,9 @@ func (r *Reactor) handlePexMessage(m p2p.RecvMsg[*pb.PexMessage]) error { // Fetch peers from the peer manager, convert NodeAddresses into URL // strings, and send them back to the caller. nodeAddresses := r.router.Advertise(maxAddresses) - pexAddresses := make([]pb.PexAddress, len(nodeAddresses)) + pexAddresses := make([]*pb.PexAddress, len(nodeAddresses)) for idx, addr := range nodeAddresses { - pexAddresses[idx] = pb.PexAddress{URL: addr.String()} + pexAddresses[idx] = &pb.PexAddress{Url: addr.String()} } r.channel.Send(wrap(&pb.PexResponse{Addresses: pexAddresses}), m.From) return nil @@ -211,7 +211,7 @@ func (r *Reactor) handlePexMessage(m p2p.RecvMsg[*pb.PexMessage]) error { var addrs []p2p.NodeAddress for _, pexAddress := range resp.Addresses { - addr, err := p2p.ParseNodeAddress(pexAddress.URL) + addr, err := p2p.ParseNodeAddress(pexAddress.Url) if err != nil { return fmt.Errorf("PEX parse node address error: %w", err) } diff --git a/sei-tendermint/internal/p2p/pex/reactor_test.go b/sei-tendermint/internal/p2p/pex/reactor_test.go index eebd954b2e..fe5ead3dbb 100644 --- a/sei-tendermint/internal/p2p/pex/reactor_test.go +++ b/sei-tendermint/internal/p2p/pex/reactor_test.go @@ -144,11 +144,11 @@ func TestReactorErrorsOnReceivingTooManyPeers(t *testing.T) { } t.Log("send a response with too many addresses") - addresses := make([]pb.PexAddress, 101) + addresses := make([]*pb.PexAddress, 101) for i := range addresses { nodeAddress := p2p.NodeAddress{NodeID: randomNodeID()} - addresses[i] = pb.PexAddress{ - URL: nodeAddress.String(), + addresses[i] = &pb.PexAddress{ + Url: nodeAddress.String(), } } ch.Send(wrap(&pb.PexResponse{Addresses: addresses}), n1) @@ -459,12 +459,12 @@ func (r *reactorTestSuite) listenForPeerDown( r.network.Node(on).WaitForConn(t.Context(), with, false) } -func (r *reactorTestSuite) getAddressesFor(nodes []int) []pb.PexAddress { - addresses := make([]pb.PexAddress, len(nodes)) +func (r *reactorTestSuite) getAddressesFor(nodes []int) []*pb.PexAddress { + addresses := make([]*pb.PexAddress, len(nodes)) for idx, node := range nodes { nodeID := r.nodes[node] - addresses[idx] = pb.PexAddress{ - URL: r.network.Node(nodeID).NodeAddress.String(), + addresses[idx] = &pb.PexAddress{ + Url: r.network.Node(nodeID).NodeAddress.String(), } } return addresses diff --git a/sei-tendermint/internal/state/execution.go b/sei-tendermint/internal/state/execution.go index 2efd7acdd1..a030a94977 100644 --- a/sei-tendermint/internal/state/execution.go +++ b/sei-tendermint/internal/state/execution.go @@ -10,7 +10,7 @@ import ( abciclient "github.com/tendermint/tendermint/abci/client" abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto/encoding" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/merkle" "github.com/tendermint/tendermint/internal/eventbus" "github.com/tendermint/tendermint/internal/mempool" @@ -629,7 +629,7 @@ func validateValidatorUpdates(abciUpdates []abci.ValidatorUpdate, } // Check if validator's pubkey matches an ABCI type in the consensus params - pk, err := encoding.PubKeyFromProto(valUpdate.PubKey) + pk, err := crypto.PubKeyFromProto(valUpdate.PubKey) if err != nil { return err } diff --git a/sei-tendermint/internal/state/execution_test.go b/sei-tendermint/internal/state/execution_test.go index dbd6d9eff6..cfaabdffa2 100644 --- a/sei-tendermint/internal/state/execution_test.go +++ b/sei-tendermint/internal/state/execution_test.go @@ -17,7 +17,6 @@ import ( abcimocks "github.com/tendermint/tendermint/abci/types/mocks" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/internal/eventbus" mpmocks "github.com/tendermint/tendermint/internal/mempool/mocks" "github.com/tendermint/tendermint/internal/proxy" @@ -375,8 +374,8 @@ func TestProcessProposal(t *testing.T) { func TestValidateValidatorUpdates(t *testing.T) { pubkey1 := ed25519.GenerateSecretKey().Public() pubkey2 := ed25519.GenerateSecretKey().Public() - pk1 := encoding.PubKeyToProto(pubkey1) - pk2 := encoding.PubKeyToProto(pubkey2) + pk1 := crypto.PubKeyToProto(pubkey1) + pk2 := crypto.PubKeyToProto(pubkey2) defaultValidatorParams := types.ValidatorParams{PubKeyTypes: []string{types.ABCIPubKeyTypeEd25519}} @@ -432,8 +431,8 @@ func TestUpdateValidators(t *testing.T) { pubkey2 := ed25519.GenerateSecretKey().Public() val2 := types.NewValidator(pubkey2, 20) - pk := encoding.PubKeyToProto(pubkey1) - pk2 := encoding.PubKeyToProto(pubkey2) + pk := crypto.PubKeyToProto(pubkey1) + pk2 := crypto.PubKeyToProto(pubkey2) testCases := []struct { name string @@ -551,7 +550,7 @@ func TestFinalizeBlockValidatorUpdates(t *testing.T) { blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()} pubkey := ed25519.GenerateSecretKey().Public() - pk := encoding.PubKeyToProto(pubkey) + pk := crypto.PubKeyToProto(pubkey) app.ValidatorUpdates = []abci.ValidatorUpdate{ {PubKey: pk, Power: 10}, } @@ -615,7 +614,7 @@ func TestFinalizeBlockValidatorUpdatesResultingInEmptySet(t *testing.T) { require.NoError(t, err) blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()} - vp := encoding.PubKeyToProto(state.Validators.Validators[0].PubKey) + vp := crypto.PubKeyToProto(state.Validators.Validators[0].PubKey) // Remove the only validator app.ValidatorUpdates = []abci.ValidatorUpdate{ {PubKey: vp, Power: 0}, diff --git a/sei-tendermint/internal/state/helpers_test.go b/sei-tendermint/internal/state/helpers_test.go index 91d351ff43..a9cd8dfa64 100644 --- a/sei-tendermint/internal/state/helpers_test.go +++ b/sei-tendermint/internal/state/helpers_test.go @@ -13,7 +13,6 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/crypto/encoding" sm "github.com/tendermint/tendermint/internal/state" sf "github.com/tendermint/tendermint/internal/state/test/factory" "github.com/tendermint/tendermint/internal/test/factory" @@ -156,8 +155,8 @@ func makeHeaderPartsResponsesValPubKeyChange( // If the pubkey is new, remove the old and add the new. _, val := state.NextValidators.GetByIndex(0) if pubkey != val.PubKey { - vPbPk := encoding.PubKeyToProto(val.PubKey) - pbPk := encoding.PubKeyToProto(pubkey) + vPbPk := crypto.PubKeyToProto(val.PubKey) + pbPk := crypto.PubKeyToProto(pubkey) finalizeBlockResponses.ValidatorUpdates = []abci.ValidatorUpdate{ {PubKey: vPbPk, Power: 0}, @@ -181,7 +180,7 @@ func makeHeaderPartsResponsesValPowerChange( // If the pubkey is new, remove the old and add the new. _, val := state.NextValidators.GetByIndex(0) if val.VotingPower != power { - vPbPk := encoding.PubKeyToProto(val.PubKey) + vPbPk := crypto.PubKeyToProto(val.PubKey) finalizeBlockResponses.ValidatorUpdates = []abci.ValidatorUpdate{ {PubKey: vPbPk, Power: power}, diff --git a/sei-tendermint/internal/state/state_test.go b/sei-tendermint/internal/state/state_test.go index 34a1d7c456..88947c6f31 100644 --- a/sei-tendermint/internal/state/state_test.go +++ b/sei-tendermint/internal/state/state_test.go @@ -16,7 +16,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/crypto/encoding" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/merkle" sm "github.com/tendermint/tendermint/internal/state" statefactory "github.com/tendermint/tendermint/internal/state/test/factory" @@ -117,7 +117,7 @@ func TestFinalizeBlockResponsesSaveLoad1(t *testing.T) { finalizeBlockResponses.TxResults[0] = &abci.ExecTxResult{Data: []byte("foo"), Events: nil} finalizeBlockResponses.TxResults[1] = &abci.ExecTxResult{Data: []byte("bar"), Log: "ok", Events: nil} - pbpk := encoding.PubKeyToProto(ed25519.GenerateSecretKey().Public()) + pbpk := crypto.PubKeyToProto(ed25519.GenerateSecretKey().Public()) finalizeBlockResponses.ValidatorUpdates = []abci.ValidatorUpdate{{PubKey: pbpk, Power: 10}} require.NoError(t, stateStore.SaveFinalizeBlockResponses(block.Height, finalizeBlockResponses)) @@ -355,7 +355,7 @@ func TestProposerFrequency(t *testing.T) { for caseNum, testCase := range testCases { // run each case 5 times to sample different // initial priorities - for i := 0; i < 5; i++ { + for range 5 { valSet := genValSetWithPowers(testCase.powers) testProposerFreq(t, caseNum, valSet) } @@ -365,11 +365,11 @@ func TestProposerFrequency(t *testing.T) { maxVals := 100 maxPower := 1000 nTestCases := 5 - for i := 0; i < nTestCases; i++ { + for i := range nTestCases { N := mrand.Int()%maxVals + 1 vals := make([]*types.Validator, N) totalVotePower := int64(0) - for j := 0; j < N; j++ { + for j := range N { // make sure votePower > 0 votePower := int64(mrand.Int()%maxPower) + 1 totalVotePower += votePower @@ -391,7 +391,7 @@ func genValSetWithPowers(powers []int64) *types.ValidatorSet { size := len(powers) vals := make([]*types.Validator, size) totalVotePower := int64(0) - for i := 0; i < size; i++ { + for i := range size { totalVotePower += powers[i] val := types.NewValidator(ed25519.GenerateSecretKey().Public(), powers[i]) val.ProposerPriority = mrand.Int63() @@ -411,7 +411,7 @@ func testProposerFreq(t *testing.T, caseNum int, valSet *types.ValidatorSet) { runMult := 1 runs := int(totalPower) * runMult freqs := make([]int, N) - for i := 0; i < runs; i++ { + for range runs { prop := valSet.GetProposer() idx, _ := valSet.GetByAddress(prop.Address) freqs[idx]++ @@ -474,7 +474,7 @@ func TestProposerPriorityDoesNotGetResetToZero(t *testing.T) { // add a validator val2PubKey := ed25519.GenerateSecretKey().Public() val2VotingPower := int64(100) - fvp := encoding.PubKeyToProto(val2PubKey) + fvp := crypto.PubKeyToProto(val2PubKey) updateAddVal := abci.ValidatorUpdate{PubKey: fvp, Power: val2VotingPower} validatorUpdates, err = types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{updateAddVal}) @@ -601,7 +601,7 @@ func TestProposerPriorityProposerAlternates(t *testing.T) { // add a validator with the same voting power as the first val2PubKey := ed25519.GenerateSecretKey().Public() - fvp := encoding.PubKeyToProto(val2PubKey) + fvp := crypto.PubKeyToProto(val2PubKey) updateAddVal := abci.ValidatorUpdate{PubKey: fvp, Power: val1VotingPower} validatorUpdates, err = types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{updateAddVal}) assert.NoError(t, err) @@ -707,7 +707,7 @@ func TestProposerPriorityProposerAlternates(t *testing.T) { expectedVal1Prio = -9 expectedVal2Prio = 9 - for i := 0; i < 1000; i++ { + for i := range 1000 { // no validator updates: fb := &abci.ResponseFinalizeBlock{ ValidatorUpdates: nil, @@ -767,7 +767,7 @@ func TestLargeGenesisValidator(t *testing.T) { // update state a few times with no validator updates // asserts that the single validator's ProposerPrio stays the same oldState := state - for i := 0; i < 10; i++ { + for range 10 { // no updates: fb := &abci.ResponseFinalizeBlock{ ValidatorUpdates: nil, @@ -800,7 +800,7 @@ func TestLargeGenesisValidator(t *testing.T) { // see: https://github.com/tendermint/tendermint/issues/2960 firstAddedValPubKey := ed25519.GenerateSecretKey().Public() firstAddedValVotingPower := int64(10) - fvp := encoding.PubKeyToProto(firstAddedValPubKey) + fvp := crypto.PubKeyToProto(firstAddedValPubKey) firstAddedVal := abci.ValidatorUpdate{PubKey: fvp, Power: firstAddedValVotingPower} validatorUpdates, err := types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{firstAddedVal}) assert.NoError(t, err) @@ -858,7 +858,7 @@ func TestLargeGenesisValidator(t *testing.T) { // add 10 validators with the same voting power as the one added directly after genesis: for i := 0; i < 10; i++ { addedPubKey := ed25519.GenerateSecretKey().Public() - ap := encoding.PubKeyToProto(addedPubKey) + ap := crypto.PubKeyToProto(addedPubKey) addedVal := abci.ValidatorUpdate{PubKey: ap, Power: firstAddedValVotingPower} validatorUpdates, err := types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{addedVal}) assert.NoError(t, err) @@ -880,7 +880,7 @@ func TestLargeGenesisValidator(t *testing.T) { require.Equal(t, 10+2, len(state.NextValidators.Validators)) // remove genesis validator: - gp := encoding.PubKeyToProto(genesisPubKey) + gp := crypto.PubKeyToProto(genesisPubKey) removeGenesisVal := abci.ValidatorUpdate{PubKey: gp, Power: 0} fb = &abci.ResponseFinalizeBlock{ ValidatorUpdates: []abci.ValidatorUpdate{removeGenesisVal}, @@ -1143,7 +1143,6 @@ func TestStateProto(t *testing.T) { } for _, tt := range tc { - tt := tt pbs, err := tt.state.ToProto() if !tt.expPass1 { assert.Error(t, err) diff --git a/sei-tendermint/privval/grpc/client.go b/sei-tendermint/privval/grpc/client.go index 78e9aa22d2..56d70e1478 100644 --- a/sei-tendermint/privval/grpc/client.go +++ b/sei-tendermint/privval/grpc/client.go @@ -7,7 +7,6 @@ import ( "google.golang.org/grpc/status" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/libs/log" privvalproto "github.com/tendermint/tendermint/proto/tendermint/privval" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -62,7 +61,7 @@ func (sc *SignerClient) GetPubKey(ctx context.Context) (crypto.PubKey, error) { return crypto.PubKey{}, errStatus.Err() } - pk, err := encoding.PubKeyFromProto(resp.PubKey) + pk, err := crypto.PubKeyFromProto(resp.PubKey) if err != nil { return crypto.PubKey{}, err } diff --git a/sei-tendermint/privval/grpc/server.go b/sei-tendermint/privval/grpc/server.go index 8a3de0faa9..4c542d3a1e 100644 --- a/sei-tendermint/privval/grpc/server.go +++ b/sei-tendermint/privval/grpc/server.go @@ -7,7 +7,6 @@ import ( "google.golang.org/grpc/status" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/libs/log" privvalproto "github.com/tendermint/tendermint/proto/tendermint/privval" "github.com/tendermint/tendermint/types" @@ -42,7 +41,7 @@ func (ss *SignerServer) GetPubKey(ctx context.Context, req *privvalproto.PubKeyR return nil, status.Errorf(codes.NotFound, "error getting pubkey: %v", err) } ss.logger.Info("SignerServer: GetPubKey Success") - return &privvalproto.PubKeyResponse{PubKey: encoding.PubKeyToProto(pubKey)}, nil + return &privvalproto.PubKeyResponse{PubKey: crypto.PubKeyToProto(pubKey)}, nil } // SignVote receives a vote sign requests, attempts to sign it diff --git a/sei-tendermint/privval/grpc/server_test.go b/sei-tendermint/privval/grpc/server_test.go index ed79468c6c..3843f84793 100644 --- a/sei-tendermint/privval/grpc/server_test.go +++ b/sei-tendermint/privval/grpc/server_test.go @@ -8,7 +8,6 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/libs/log" tmrand "github.com/tendermint/tendermint/libs/rand" "github.com/tendermint/tendermint/libs/utils" @@ -48,7 +47,7 @@ func TestGetPubKey(t *testing.T) { } else { pk, err := tc.pv.GetPubKey(ctx) require.NoError(t, err) - require.Equal(t, resp.PubKey, encoding.PubKeyToProto(pk)) + require.Equal(t, resp.PubKey, crypto.PubKeyToProto(pk)) } }) } diff --git a/sei-tendermint/privval/msgs_test.go b/sei-tendermint/privval/msgs_test.go index 77a01a8329..7449cfda78 100644 --- a/sei-tendermint/privval/msgs_test.go +++ b/sei-tendermint/privval/msgs_test.go @@ -10,7 +10,6 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/crypto/encoding" cryptoproto "github.com/tendermint/tendermint/proto/tendermint/crypto" privproto "github.com/tendermint/tendermint/proto/tendermint/privval" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -52,7 +51,7 @@ func exampleProposal() *types.Proposal { func TestPrivvalVectors(t *testing.T) { // WARNING: this key has to be stable for hashes to match. pk := ed25519.TestSecretKey([]byte("it's a secret")).Public() - ppk := encoding.PubKeyToProto(pk) + ppk := crypto.PubKeyToProto(pk) // Generate a simple vote vote := exampleVote() diff --git a/sei-tendermint/privval/signer_client.go b/sei-tendermint/privval/signer_client.go index 3a6f194d29..a2b15a34ff 100644 --- a/sei-tendermint/privval/signer_client.go +++ b/sei-tendermint/privval/signer_client.go @@ -6,7 +6,6 @@ import ( "time" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/libs/log" privvalproto "github.com/tendermint/tendermint/proto/tendermint/privval" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -94,12 +93,7 @@ func (sc *SignerClient) GetPubKey(ctx context.Context) (crypto.PubKey, error) { return crypto.PubKey{}, &RemoteSignerError{Code: int(resp.Error.Code), Description: resp.Error.Description} } - pk, err := encoding.PubKeyFromProto(resp.PubKey) - if err != nil { - return crypto.PubKey{}, err - } - - return pk, nil + return crypto.PubKeyFromProto(resp.PubKey) } // SignVote requests a remote signer to sign a vote diff --git a/sei-tendermint/privval/signer_requestHandler.go b/sei-tendermint/privval/signer_requestHandler.go index b0908c50c6..8d57d98106 100644 --- a/sei-tendermint/privval/signer_requestHandler.go +++ b/sei-tendermint/privval/signer_requestHandler.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/encoding" cryptoproto "github.com/tendermint/tendermint/proto/tendermint/crypto" privvalproto "github.com/tendermint/tendermint/proto/tendermint/privval" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -37,7 +36,7 @@ func DefaultValidationRequestHandler( if err != nil { return res, err } - pk := encoding.PubKeyToProto(pubKey) + pk := crypto.PubKeyToProto(pubKey) if err != nil { res = mustWrapMsg(&privvalproto.PubKeyResponse{ PubKey: cryptoproto.PublicKey{}, Error: &privvalproto.RemoteSignerError{Code: 0, Description: err.Error()}}) diff --git a/sei-tendermint/proto/tendermint/p2p/conn.pb.go b/sei-tendermint/proto/tendermint/p2p/conn.pb.go index 16ee463a6a..143610d3ec 100644 --- a/sei-tendermint/proto/tendermint/p2p/conn.pb.go +++ b/sei-tendermint/proto/tendermint/p2p/conn.pb.go @@ -97,8 +97,8 @@ func (m *PacketPong) XXX_DiscardUnknown() { var xxx_messageInfo_PacketPong proto.InternalMessageInfo type PacketMsg struct { - ChannelID int32 `protobuf:"varint,1,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` - EOF bool `protobuf:"varint,2,opt,name=eof,proto3" json:"eof,omitempty"` + ChannelId int32 `protobuf:"varint,1,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` + Eof bool `protobuf:"varint,2,opt,name=eof,proto3" json:"eof,omitempty"` Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` } @@ -135,16 +135,16 @@ func (m *PacketMsg) XXX_DiscardUnknown() { var xxx_messageInfo_PacketMsg proto.InternalMessageInfo -func (m *PacketMsg) GetChannelID() int32 { +func (m *PacketMsg) GetChannelId() int32 { if m != nil { - return m.ChannelID + return m.ChannelId } return 0 } -func (m *PacketMsg) GetEOF() bool { +func (m *PacketMsg) GetEof() bool { if m != nil { - return m.EOF + return m.Eof } return false } @@ -256,8 +256,8 @@ func (*Packet) XXX_OneofWrappers() []interface{} { } type AuthSigMessage struct { - PubKey crypto.PublicKey `protobuf:"bytes,1,opt,name=pub_key,json=pubKey,proto3" json:"pub_key"` - Sig []byte `protobuf:"bytes,2,opt,name=sig,proto3" json:"sig,omitempty"` + PubKey *crypto.PublicKey `protobuf:"bytes,1,opt,name=pub_key,json=pubKey,proto3" json:"pub_key,omitempty"` + Sig []byte `protobuf:"bytes,2,opt,name=sig,proto3" json:"sig,omitempty"` } func (m *AuthSigMessage) Reset() { *m = AuthSigMessage{} } @@ -293,11 +293,11 @@ func (m *AuthSigMessage) XXX_DiscardUnknown() { var xxx_messageInfo_AuthSigMessage proto.InternalMessageInfo -func (m *AuthSigMessage) GetPubKey() crypto.PublicKey { +func (m *AuthSigMessage) GetPubKey() *crypto.PublicKey { if m != nil { return m.PubKey } - return crypto.PublicKey{} + return nil } func (m *AuthSigMessage) GetSig() []byte { @@ -318,32 +318,30 @@ func init() { func init() { proto.RegisterFile("tendermint/p2p/conn.proto", fileDescriptor_22474b5527c8fa9f) } var fileDescriptor_22474b5527c8fa9f = []byte{ - // 395 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x52, 0x3d, 0x8f, 0xd3, 0x40, - 0x10, 0xf5, 0xe2, 0xbb, 0x1c, 0x99, 0x84, 0x13, 0x5a, 0x51, 0x24, 0xd1, 0xc9, 0x89, 0x5c, 0xa5, - 0x40, 0xb6, 0x64, 0x44, 0x03, 0xa2, 0xc0, 0x7c, 0x88, 0xd3, 0x29, 0xba, 0xc8, 0x74, 0x34, 0x96, - 0x3f, 0x96, 0xf5, 0x2a, 0xe7, 0xdd, 0x55, 0x76, 0x5d, 0xf8, 0x5f, 0xf0, 0xb3, 0x8e, 0xee, 0x4a, - 0xaa, 0x08, 0x39, 0x7f, 0x04, 0x79, 0x1d, 0x88, 0x23, 0x71, 0xdd, 0x7b, 0x33, 0xf3, 0xe6, 0x43, - 0xf3, 0x60, 0xaa, 0x09, 0xcf, 0xc9, 0xb6, 0x64, 0x5c, 0xfb, 0x32, 0x90, 0x7e, 0x26, 0x38, 0xf7, - 0xe4, 0x56, 0x68, 0x81, 0x2f, 0x8f, 0x29, 0x4f, 0x06, 0x72, 0xf6, 0x82, 0x0a, 0x2a, 0x4c, 0xca, - 0x6f, 0x51, 0x57, 0x35, 0xbb, 0xea, 0x35, 0xc8, 0xb6, 0xb5, 0xd4, 0xc2, 0xdf, 0x90, 0x5a, 0x75, - 0x59, 0x77, 0x0c, 0xb0, 0x4e, 0xb2, 0x0d, 0xd1, 0x6b, 0xc6, 0x69, 0x8f, 0x09, 0x4e, 0xdd, 0x02, - 0x86, 0x1d, 0x5b, 0x29, 0x8a, 0x5f, 0x02, 0x64, 0x45, 0xc2, 0x39, 0xb9, 0x8b, 0x59, 0x3e, 0x41, - 0x0b, 0xb4, 0x3c, 0x0f, 0x9f, 0x35, 0xbb, 0xf9, 0xf0, 0x43, 0x17, 0xbd, 0xfe, 0x18, 0x0d, 0x0f, - 0x05, 0xd7, 0x39, 0x9e, 0x82, 0x4d, 0xc4, 0xf7, 0xc9, 0x93, 0x05, 0x5a, 0x3e, 0x0d, 0x2f, 0x9a, - 0xdd, 0xdc, 0xfe, 0x74, 0xfb, 0x39, 0x6a, 0x63, 0x18, 0xc3, 0x59, 0x9e, 0xe8, 0x64, 0x62, 0x2f, - 0xd0, 0x72, 0x1c, 0x19, 0xec, 0xfe, 0x44, 0x30, 0xe8, 0x46, 0xe1, 0x77, 0x30, 0x92, 0x06, 0xc5, - 0x92, 0x71, 0x6a, 0x06, 0x8d, 0x82, 0x99, 0x77, 0x7a, 0xaa, 0x77, 0xdc, 0xf9, 0x8b, 0x15, 0x81, - 0xfc, 0xc7, 0xfa, 0x72, 0xc1, 0xa9, 0x59, 0xe0, 0x71, 0xb9, 0x38, 0x91, 0x0b, 0x4e, 0xf1, 0x1b, - 0x38, 0xb0, 0xb8, 0x54, 0xd4, 0xac, 0x38, 0x0a, 0xa6, 0xff, 0x57, 0xaf, 0x54, 0x2b, 0x1e, 0xca, - 0xbf, 0x24, 0x3c, 0x07, 0x5b, 0x55, 0xa5, 0x1b, 0xc3, 0xe5, 0xfb, 0x4a, 0x17, 0x5f, 0x19, 0x5d, - 0x11, 0xa5, 0x12, 0x4a, 0xf0, 0x5b, 0xb8, 0x90, 0x55, 0x1a, 0x6f, 0x48, 0x7d, 0x38, 0xe7, 0xaa, - 0xdf, 0xb1, 0xfb, 0x89, 0xb7, 0xae, 0xd2, 0x3b, 0x96, 0xdd, 0x90, 0x3a, 0x3c, 0xbb, 0xdf, 0xcd, - 0xad, 0x68, 0x20, 0xab, 0xf4, 0x86, 0xd4, 0xf8, 0x39, 0xd8, 0x8a, 0x75, 0x87, 0x8c, 0xa3, 0x16, - 0x86, 0xb7, 0xf7, 0x8d, 0x83, 0x1e, 0x1a, 0x07, 0xfd, 0x6e, 0x1c, 0xf4, 0x63, 0xef, 0x58, 0x0f, - 0x7b, 0xc7, 0xfa, 0xb5, 0x77, 0xac, 0x6f, 0xaf, 0x29, 0xd3, 0x45, 0x95, 0x7a, 0x99, 0x28, 0xfd, - 0xde, 0xd7, 0xfb, 0x0e, 0x32, 0xee, 0x38, 0xb5, 0x54, 0x3a, 0x30, 0xd1, 0x57, 0x7f, 0x02, 0x00, - 0x00, 0xff, 0xff, 0x30, 0xfd, 0xb2, 0x8d, 0x6b, 0x02, 0x00, 0x00, + // 365 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x52, 0x3d, 0x6f, 0xe2, 0x30, + 0x18, 0x8e, 0x8f, 0x83, 0x3b, 0x5e, 0x10, 0x3a, 0x59, 0x37, 0x00, 0xe2, 0x22, 0x94, 0x89, 0x29, + 0x91, 0x72, 0x62, 0x39, 0xe9, 0x86, 0x63, 0xba, 0x0a, 0xa1, 0x46, 0xe9, 0xd4, 0x2e, 0x51, 0x3e, + 0x5c, 0x63, 0x41, 0x6c, 0x0b, 0x3b, 0x43, 0xfe, 0x45, 0x7f, 0x56, 0xbb, 0x31, 0x76, 0xac, 0xe0, + 0x8f, 0x54, 0x71, 0x68, 0x09, 0x52, 0xbb, 0x3d, 0xcf, 0xfb, 0xfa, 0x79, 0xfc, 0x7e, 0xc1, 0x48, + 0x13, 0x9e, 0x91, 0x5d, 0xce, 0xb8, 0xf6, 0xa4, 0x2f, 0xbd, 0x54, 0x70, 0xee, 0xca, 0x9d, 0xd0, + 0x02, 0x0f, 0xce, 0x29, 0x57, 0xfa, 0x72, 0xfc, 0x93, 0x0a, 0x2a, 0x4c, 0xca, 0xab, 0x50, 0xfd, + 0x6a, 0x3c, 0x69, 0x18, 0xa4, 0xbb, 0x52, 0x6a, 0xe1, 0x6d, 0x48, 0xa9, 0xea, 0xac, 0xd3, 0x07, + 0x08, 0xe2, 0x74, 0x43, 0x74, 0xc0, 0x38, 0x6d, 0x30, 0xc1, 0xa9, 0x13, 0x40, 0xb7, 0x66, 0x2b, + 0x45, 0xf1, 0x2f, 0x80, 0x74, 0x1d, 0x73, 0x4e, 0xb6, 0x11, 0xcb, 0x86, 0x68, 0x8a, 0x66, 0xed, + 0xb0, 0x7b, 0x8a, 0x5c, 0x65, 0xf8, 0x07, 0xb4, 0x88, 0xb8, 0x1f, 0x7e, 0x99, 0xa2, 0xd9, 0xf7, + 0xb0, 0x82, 0x18, 0xc3, 0xd7, 0x2c, 0xd6, 0xf1, 0xb0, 0x35, 0x45, 0xb3, 0x7e, 0x68, 0xb0, 0xf3, + 0x84, 0xa0, 0x53, 0x5b, 0xe2, 0xbf, 0xd0, 0x93, 0x06, 0x45, 0x92, 0x71, 0x6a, 0x0c, 0x7b, 0xfe, + 0xd8, 0xbd, 0x6c, 0xc9, 0x3d, 0xd7, 0xf6, 0xdf, 0x0a, 0x41, 0xbe, 0xb3, 0xa6, 0x5c, 0x70, 0x6a, + 0xfe, 0xfd, 0x5c, 0x2e, 0x2e, 0xe4, 0x82, 0x53, 0xfc, 0x07, 0x4e, 0x2c, 0xca, 0x15, 0x35, 0x25, + 0xf6, 0xfc, 0xd1, 0xc7, 0xea, 0x95, 0xaa, 0xc4, 0x5d, 0xf9, 0x46, 0x16, 0x6d, 0x68, 0xa9, 0x22, + 0x77, 0x6e, 0x61, 0xf0, 0xaf, 0xd0, 0xeb, 0x1b, 0x46, 0x57, 0x44, 0xa9, 0x98, 0x12, 0x3c, 0x87, + 0x6f, 0xb2, 0x48, 0xa2, 0x0d, 0x29, 0x4f, 0xed, 0x4c, 0x9a, 0x8e, 0xf5, 0xec, 0xdd, 0xa0, 0x48, + 0xb6, 0x2c, 0x5d, 0x92, 0x32, 0xec, 0xc8, 0x22, 0x59, 0x92, 0xb2, 0x1a, 0x9d, 0x62, 0x75, 0x0b, + 0xfd, 0xb0, 0x82, 0x8b, 0xeb, 0xc7, 0x83, 0x8d, 0xf6, 0x07, 0x1b, 0xbd, 0x1c, 0x6c, 0xf4, 0x70, + 0xb4, 0xad, 0xfd, 0xd1, 0xb6, 0x9e, 0x8f, 0xb6, 0x75, 0x37, 0xa7, 0x4c, 0xaf, 0x8b, 0xc4, 0x4d, + 0x45, 0xee, 0x35, 0xf6, 0xda, 0xbc, 0x11, 0xb3, 0xff, 0xcb, 0xa3, 0x49, 0x3a, 0x26, 0xfa, 0xfb, + 0x35, 0x00, 0x00, 0xff, 0xff, 0x24, 0x4d, 0x23, 0x68, 0x4d, 0x02, 0x00, 0x00, } func (m *PacketPing) Marshal() (dAtA []byte, err error) { @@ -419,9 +417,9 @@ func (m *PacketMsg) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x1a } - if m.EOF { + if m.Eof { i-- - if m.EOF { + if m.Eof { dAtA[i] = 1 } else { dAtA[i] = 0 @@ -429,8 +427,8 @@ func (m *PacketMsg) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x10 } - if m.ChannelID != 0 { - i = encodeVarintConn(dAtA, i, uint64(m.ChannelID)) + if m.ChannelId != 0 { + i = encodeVarintConn(dAtA, i, uint64(m.ChannelId)) i-- dAtA[i] = 0x8 } @@ -559,16 +557,18 @@ func (m *AuthSigMessage) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x12 } - { - size, err := m.PubKey.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if m.PubKey != nil { + { + size, err := m.PubKey.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintConn(dAtA, i, uint64(size)) } - i -= size - i = encodeVarintConn(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa } - i-- - dAtA[i] = 0xa return len(dAtA) - i, nil } @@ -607,10 +607,10 @@ func (m *PacketMsg) Size() (n int) { } var l int _ = l - if m.ChannelID != 0 { - n += 1 + sovConn(uint64(m.ChannelID)) + if m.ChannelId != 0 { + n += 1 + sovConn(uint64(m.ChannelId)) } - if m.EOF { + if m.Eof { n += 2 } l = len(m.Data) @@ -674,8 +674,10 @@ func (m *AuthSigMessage) Size() (n int) { } var l int _ = l - l = m.PubKey.Size() - n += 1 + l + sovConn(uint64(l)) + if m.PubKey != nil { + l = m.PubKey.Size() + n += 1 + l + sovConn(uint64(l)) + } l = len(m.Sig) if l > 0 { n += 1 + l + sovConn(uint64(l)) @@ -820,9 +822,9 @@ func (m *PacketMsg) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ChannelID", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChannelId", wireType) } - m.ChannelID = 0 + m.ChannelId = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowConn @@ -832,14 +834,14 @@ func (m *PacketMsg) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ChannelID |= int32(b&0x7F) << shift + m.ChannelId |= int32(b&0x7F) << shift if b < 0x80 { break } } case 2: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field EOF", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Eof", wireType) } var v int for shift := uint(0); ; shift += 7 { @@ -856,7 +858,7 @@ func (m *PacketMsg) Unmarshal(dAtA []byte) error { break } } - m.EOF = bool(v != 0) + m.Eof = bool(v != 0) case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) @@ -1125,6 +1127,9 @@ func (m *AuthSigMessage) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } + if m.PubKey == nil { + m.PubKey = &crypto.PublicKey{} + } if err := m.PubKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } diff --git a/sei-tendermint/proto/tendermint/p2p/conn.proto b/sei-tendermint/proto/tendermint/p2p/conn.proto index 46c4cebf89..088f97f892 100644 --- a/sei-tendermint/proto/tendermint/p2p/conn.proto +++ b/sei-tendermint/proto/tendermint/p2p/conn.proto @@ -12,8 +12,8 @@ message PacketPing {} message PacketPong {} message PacketMsg { - int32 channel_id = 1 [(gogoproto.customname) = "ChannelID"]; - bool eof = 2 [(gogoproto.customname) = "EOF"]; + int32 channel_id = 1; + bool eof = 2; bytes data = 3; } @@ -26,7 +26,6 @@ message Packet { } message AuthSigMessage { - tendermint.crypto.PublicKey pub_key = 1 [(gogoproto.nullable) = false]; + tendermint.crypto.PublicKey pub_key = 1; bytes sig = 2; - // Supported P2P features. } diff --git a/sei-tendermint/proto/tendermint/p2p/pex.pb.go b/sei-tendermint/proto/tendermint/p2p/pex.pb.go index 15ccce15e5..888227f1ef 100644 --- a/sei-tendermint/proto/tendermint/p2p/pex.pb.go +++ b/sei-tendermint/proto/tendermint/p2p/pex.pb.go @@ -24,7 +24,7 @@ var _ = math.Inf const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type PexAddress struct { - URL string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"` + Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"` } func (m *PexAddress) Reset() { *m = PexAddress{} } @@ -60,9 +60,9 @@ func (m *PexAddress) XXX_DiscardUnknown() { var xxx_messageInfo_PexAddress proto.InternalMessageInfo -func (m *PexAddress) GetURL() string { +func (m *PexAddress) GetUrl() string { if m != nil { - return m.URL + return m.Url } return "" } @@ -104,7 +104,7 @@ func (m *PexRequest) XXX_DiscardUnknown() { var xxx_messageInfo_PexRequest proto.InternalMessageInfo type PexResponse struct { - Addresses []PexAddress `protobuf:"bytes,1,rep,name=addresses,proto3" json:"addresses"` + Addresses []*PexAddress `protobuf:"bytes,1,rep,name=addresses,proto3" json:"addresses,omitempty"` } func (m *PexResponse) Reset() { *m = PexResponse{} } @@ -140,7 +140,7 @@ func (m *PexResponse) XXX_DiscardUnknown() { var xxx_messageInfo_PexResponse proto.InternalMessageInfo -func (m *PexResponse) GetAddresses() []PexAddress { +func (m *PexResponse) GetAddresses() []*PexAddress { if m != nil { return m.Addresses } @@ -242,27 +242,26 @@ func init() { func init() { proto.RegisterFile("tendermint/p2p/pex.proto", fileDescriptor_81c2f011fd13be57) } var fileDescriptor_81c2f011fd13be57 = []byte{ - // 311 bytes of a gzipped FileDescriptorProto + // 295 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x28, 0x49, 0xcd, 0x4b, 0x49, 0x2d, 0xca, 0xcd, 0xcc, 0x2b, 0xd1, 0x2f, 0x30, 0x2a, 0xd0, 0x2f, 0x48, 0xad, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x43, 0xc8, 0xe8, 0x15, 0x18, 0x15, 0x48, 0x89, 0xa4, 0xe7, - 0xa7, 0xe7, 0x83, 0xa5, 0xf4, 0x41, 0x2c, 0x88, 0x2a, 0x25, 0x63, 0x2e, 0xae, 0x80, 0xd4, 0x0a, - 0xc7, 0x94, 0x94, 0xa2, 0xd4, 0xe2, 0x62, 0x21, 0x49, 0x2e, 0xe6, 0xd2, 0xa2, 0x1c, 0x09, 0x46, - 0x05, 0x46, 0x0d, 0x4e, 0x27, 0xf6, 0x47, 0xf7, 0xe4, 0x99, 0x43, 0x83, 0x7c, 0x82, 0x40, 0x62, - 0x5e, 0x2c, 0x1c, 0x4c, 0x02, 0xcc, 0x5e, 0x2c, 0x1c, 0xcc, 0x02, 0x2c, 0x4a, 0x3c, 0x60, 0x4d, - 0x41, 0xa9, 0x85, 0xa5, 0xa9, 0xc5, 0x25, 0x4a, 0xbe, 0x5c, 0xdc, 0x60, 0x5e, 0x71, 0x41, 0x7e, - 0x5e, 0x71, 0xaa, 0x90, 0x1d, 0x17, 0x67, 0x22, 0xc4, 0xb8, 0xd4, 0x62, 0x09, 0x46, 0x05, 0x66, - 0x0d, 0x6e, 0x23, 0x29, 0x3d, 0x54, 0xb7, 0xe8, 0x21, 0xac, 0x74, 0x62, 0x39, 0x71, 0x4f, 0x9e, - 0x21, 0x08, 0xa1, 0x45, 0x69, 0x01, 0x23, 0xd8, 0x74, 0xdf, 0xd4, 0xe2, 0xe2, 0xc4, 0xf4, 0x54, - 0x21, 0x5b, 0x2e, 0xee, 0x82, 0xd4, 0x8a, 0xf8, 0x22, 0x88, 0x65, 0x12, 0xcc, 0x0a, 0x8c, 0x38, - 0x0c, 0x84, 0x3a, 0xc7, 0x83, 0x21, 0x88, 0xab, 0x00, 0xce, 0x13, 0x72, 0xe0, 0xe2, 0x81, 0x68, - 0x87, 0xb8, 0x4e, 0x82, 0x05, 0xac, 0x5f, 0x1a, 0xab, 0x7e, 0x88, 0x12, 0x0f, 0x86, 0x20, 0xee, - 0x02, 0x04, 0xd7, 0x89, 0x95, 0x8b, 0xb9, 0xb8, 0x34, 0xd7, 0x8b, 0x85, 0x83, 0x51, 0x80, 0x09, - 0x12, 0x0a, 0x4e, 0xfe, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, - 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0x65, 0x9a, - 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x8f, 0x14, 0x33, 0xc8, 0x91, 0x04, - 0x8e, 0x01, 0xd4, 0x58, 0x4b, 0x62, 0x03, 0x8b, 0x1a, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0xa7, - 0x1d, 0xdd, 0x6f, 0xce, 0x01, 0x00, 0x00, + 0xa7, 0xe7, 0x83, 0xa5, 0xf4, 0x41, 0x2c, 0x88, 0x2a, 0x25, 0x2d, 0x2e, 0xae, 0x80, 0xd4, 0x0a, + 0xc7, 0x94, 0x94, 0xa2, 0xd4, 0xe2, 0x62, 0x21, 0x01, 0x2e, 0xe6, 0xd2, 0xa2, 0x1c, 0x09, 0x46, + 0x05, 0x46, 0x0d, 0xce, 0x20, 0x10, 0xd3, 0x8b, 0x85, 0x83, 0x49, 0x80, 0xd9, 0x8b, 0x85, 0x83, + 0x59, 0x80, 0x45, 0x89, 0x07, 0xac, 0x36, 0x28, 0xb5, 0xb0, 0x34, 0xb5, 0xb8, 0x44, 0xc9, 0x9d, + 0x8b, 0x1b, 0xcc, 0x2b, 0x2e, 0xc8, 0xcf, 0x2b, 0x4e, 0x15, 0xb2, 0xe0, 0xe2, 0x4c, 0x84, 0x98, + 0x92, 0x5a, 0x2c, 0xc1, 0xa8, 0xc0, 0xac, 0xc1, 0x6d, 0x24, 0xa5, 0x87, 0xea, 0x04, 0x3d, 0x84, + 0x4d, 0x41, 0x08, 0xc5, 0x4a, 0x0b, 0x18, 0xc1, 0xe6, 0xfa, 0xa6, 0x16, 0x17, 0x27, 0xa6, 0xa7, + 0x0a, 0xd9, 0x72, 0x71, 0x17, 0xa4, 0x56, 0xc4, 0x17, 0x41, 0xac, 0x91, 0x60, 0x56, 0x60, 0xc4, + 0x61, 0x14, 0xd4, 0x21, 0x1e, 0x0c, 0x41, 0x5c, 0x05, 0x70, 0x9e, 0x90, 0x03, 0x17, 0x0f, 0x44, + 0x3b, 0xc4, 0x5d, 0x12, 0x2c, 0x60, 0xfd, 0xd2, 0x58, 0xf5, 0x43, 0x94, 0x78, 0x30, 0x04, 0x71, + 0x17, 0x20, 0xb8, 0x4e, 0xac, 0x5c, 0xcc, 0xc5, 0xa5, 0xb9, 0x5e, 0x2c, 0x1c, 0x8c, 0x02, 0x4c, + 0x10, 0xff, 0x3b, 0xf9, 0x9f, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, + 0x8c, 0x13, 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x69, + 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x3e, 0x52, 0x54, 0x20, 0xc7, 0x0a, + 0x38, 0xc8, 0x51, 0xa3, 0x29, 0x89, 0x0d, 0x2c, 0x6a, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x77, + 0x39, 0x25, 0x82, 0xbf, 0x01, 0x00, 0x00, } func (m *PexAddress) Marshal() (dAtA []byte, err error) { @@ -285,10 +284,10 @@ func (m *PexAddress) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.URL) > 0 { - i -= len(m.URL) - copy(dAtA[i:], m.URL) - i = encodeVarintPex(dAtA, i, uint64(len(m.URL))) + if len(m.Url) > 0 { + i -= len(m.Url) + copy(dAtA[i:], m.Url) + i = encodeVarintPex(dAtA, i, uint64(len(m.Url))) i-- dAtA[i] = 0xa } @@ -446,7 +445,7 @@ func (m *PexAddress) Size() (n int) { } var l int _ = l - l = len(m.URL) + l = len(m.Url) if l > 0 { n += 1 + l + sovPex(uint64(l)) } @@ -551,7 +550,7 @@ func (m *PexAddress) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field URL", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Url", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -579,7 +578,7 @@ func (m *PexAddress) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.URL = string(dAtA[iNdEx:postIndex]) + m.Url = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -710,7 +709,7 @@ func (m *PexResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Addresses = append(m.Addresses, PexAddress{}) + m.Addresses = append(m.Addresses, &PexAddress{}) if err := m.Addresses[len(m.Addresses)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } diff --git a/sei-tendermint/proto/tendermint/p2p/pex.proto b/sei-tendermint/proto/tendermint/p2p/pex.proto index ecdca50dc9..94e3336e39 100644 --- a/sei-tendermint/proto/tendermint/p2p/pex.proto +++ b/sei-tendermint/proto/tendermint/p2p/pex.proto @@ -7,15 +7,14 @@ import "gogoproto/gogo.proto"; option go_package = "github.com/tendermint/tendermint/proto/tendermint/p2p"; message PexAddress { - string url = 1 [(gogoproto.customname) = "URL"]; - reserved 2, 3; // See https://github.com/tendermint/spec/pull/352 + string url = 1; } message PexRequest {} message PexResponse { - repeated PexAddress addresses = 1 [(gogoproto.nullable) = false]; + repeated PexAddress addresses = 1; } message PexMessage { diff --git a/sei-tendermint/rpc/client/rpc_test.go b/sei-tendermint/rpc/client/rpc_test.go index b8c3c5cac5..aa4bc370a8 100644 --- a/sei-tendermint/rpc/client/rpc_test.go +++ b/sei-tendermint/rpc/client/rpc_test.go @@ -16,7 +16,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/crypto/encoding" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/internal/mempool" rpccore "github.com/tendermint/tendermint/internal/rpc/core" tmjson "github.com/tendermint/tendermint/libs/json" @@ -557,7 +557,7 @@ func TestClientMethodCalls(t *testing.T) { err = abci.ReadMessage(bytes.NewReader(qres.Value), &v) require.NoError(t, err, "Error reading query result, value %v", qres.Value) - pk, err := encoding.PubKeyFromProto(v.PubKey) + pk, err := crypto.PubKeyFromProto(v.PubKey) require.NoError(t, err) require.Equal(t, pv.Key.PubKey, pk, "Stored PubKey not equal with expected, value %v", string(qres.Value)) diff --git a/sei-tendermint/test/e2e/app/app.go b/sei-tendermint/test/e2e/app/app.go index b65de0a1b9..e8ed2f659e 100644 --- a/sei-tendermint/test/e2e/app/app.go +++ b/sei-tendermint/test/e2e/app/app.go @@ -15,6 +15,7 @@ import ( "github.com/tendermint/tendermint/abci/example/code" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/version" @@ -393,7 +394,10 @@ func (app *Application) validatorUpdates(height uint64) (abci.ValidatorUpdates, if err != nil { return nil, fmt.Errorf("invalid ed25519 pubkey value %q: %w", keyString, err) } - valUpdates = append(valUpdates, abci.UpdateValidator(pubKey, int64(power), app.cfg.KeyType)) + valUpdates = append(valUpdates, abci.ValidatorUpdate { + PubKey: crypto.PubKeyToProto(pubKey), + Power: int64(power), + }) } // the validator updates could be returned in arbitrary order, diff --git a/sei-tendermint/test/fuzz/tests/p2p_secretconnection_test.go b/sei-tendermint/test/fuzz/tests/p2p_secretconnection_test.go index 7c7cb38ed8..6f3b9bbc7d 100644 --- a/sei-tendermint/test/fuzz/tests/p2p_secretconnection_test.go +++ b/sei-tendermint/test/fuzz/tests/p2p_secretconnection_test.go @@ -6,26 +6,26 @@ import ( "bytes" "fmt" "io" - "log" + "context" "testing" + "net" "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/internal/libs/async" - sc "github.com/tendermint/tendermint/internal/p2p/conn" + "github.com/tendermint/tendermint/internal/p2p/conn" + "github.com/tendermint/tendermint/libs/utils/scope" + "github.com/tendermint/tendermint/libs/utils/require" ) func FuzzP2PSecretConnection(f *testing.F) { - f.Fuzz(func(t *testing.T, data []byte) { - fuzz(data) - }) + f.Fuzz(fuzz) } -func fuzz(data []byte) { +func fuzz(t *testing.T, data []byte) { if len(data) == 0 { return } - fooConn, barConn := makeSecretConnPair() + fooConn, barConn := makeSecretConnPair(t) // Run Write in a separate goroutine because if data is greater than 1024 // bytes, each Write must be followed by Read (see io.Pipe documentation). @@ -61,75 +61,56 @@ func fuzz(data []byte) { } type kvstoreConn struct { - *io.PipeReader - *io.PipeWriter + net.Conn + reader *io.PipeReader + writer *io.PipeWriter } +func (drw kvstoreConn) Read(data []byte) (n int, err error) { return drw.reader.Read(data) } +func (drw kvstoreConn) Write(data []byte) (n int, err error) { return drw.writer.Write(data) } + func (drw kvstoreConn) Close() (err error) { - err2 := drw.PipeWriter.CloseWithError(io.EOF) - err1 := drw.PipeReader.Close() + err2 := drw.writer.CloseWithError(io.EOF) + err1 := drw.reader.Close() if err2 != nil { return err } return err1 } + + // Each returned ReadWriteCloser is akin to a net.Connection func makeKVStoreConnPair() (fooConn, barConn kvstoreConn) { barReader, fooWriter := io.Pipe() fooReader, barWriter := io.Pipe() - return kvstoreConn{fooReader, fooWriter}, kvstoreConn{barReader, barWriter} + return kvstoreConn{reader: fooReader, writer: fooWriter}, kvstoreConn{reader: barReader, writer: barWriter} } -func makeSecretConnPair() (fooSecConn, barSecConn *sc.SecretConnection) { - var ( - fooConn, barConn = makeKVStoreConnPair() - fooPrvKey = ed25519.GenerateSecretKey() - fooPubKey = fooPrvKey.Public() - barPrvKey = ed25519.GenerateSecretKey() - barPubKey = barPrvKey.Public() - ) +func makeSecretConnPair(tb testing.TB) (sc1 *conn.SecretConnection, sc2 *conn.SecretConnection) { + ctx := tb.Context() + c1, c2 := makeKVStoreConnPair() + k1 := ed25519.GenerateSecretKey() + k2 := ed25519.GenerateSecretKey() // Make connections from both sides in parallel. - var trs, ok = async.Parallel( - func(_ int) (val any, abort bool, err error) { - fooSecConn, err = sc.MakeSecretConnection(fooConn, fooPrvKey) - if err != nil { - log.Printf("failed to establish SecretConnection for foo: %v", err) - return nil, true, err - } - remotePubBytes := fooSecConn.RemotePubKey() - if remotePubBytes != barPubKey { - err = fmt.Errorf("unexpected fooSecConn.RemotePubKey. Expected %v, got %v", - barPubKey, fooSecConn.RemotePubKey()) - log.Print(err) - return nil, true, err - } - return nil, false, nil - }, - func(_ int) (val any, abort bool, err error) { - barSecConn, err = sc.MakeSecretConnection(barConn, barPrvKey) - if barSecConn == nil { - log.Printf("failed to establish SecretConnection for bar: %v", err) - return nil, true, err - } - remotePubBytes := barSecConn.RemotePubKey() - if remotePubBytes != fooPubKey { - err = fmt.Errorf("unexpected barSecConn.RemotePubKey. Expected %v, got %v", - fooPubKey, barSecConn.RemotePubKey()) - log.Print(err) - return nil, true, err - } - return nil, false, nil - }, - ) - - if trs.FirstError() != nil { - log.Fatalf("unexpected error: %v", trs.FirstError()) - } - if !ok { - log.Fatal("Unexpected task abortion") + err := scope.Run(ctx, func(ctx context.Context, s scope.Scope) error { + s.Spawn(func() error { + var err error + sc1, err = conn.MakeSecretConnection(ctx, c1, k1) + return err + }) + s.Spawn(func() error { + var err error + sc2, err = conn.MakeSecretConnection(ctx, c2, k2) + return err + }) + return nil + }) + if err != nil { + tb.Fatal(err) } - - return fooSecConn, barSecConn + require.Equal(tb, k1.Public(), sc2.RemotePubKey()) + require.Equal(tb, k2.Public(), sc1.RemotePubKey()) + return sc1, sc2 } diff --git a/sei-tendermint/types/protobuf.go b/sei-tendermint/types/protobuf.go index c59ccdee02..d48dc78af5 100644 --- a/sei-tendermint/types/protobuf.go +++ b/sei-tendermint/types/protobuf.go @@ -2,7 +2,7 @@ package types import ( abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto/encoding" + "github.com/tendermint/tendermint/crypto" ) //------------------------------------------------------- @@ -22,7 +22,7 @@ func (tm2pb) Validator(val *Validator) abci.Validator { func (tm2pb) ValidatorUpdate(val *Validator) abci.ValidatorUpdate { return abci.ValidatorUpdate{ - PubKey: encoding.PubKeyToProto(val.PubKey), + PubKey: crypto.PubKeyToProto(val.PubKey), Power: val.VotingPower, } } @@ -46,7 +46,7 @@ type pb2tm struct{} func (pb2tm) ValidatorUpdates(vals []abci.ValidatorUpdate) ([]*Validator, error) { tmVals := make([]*Validator, len(vals)) for i, v := range vals { - pub, err := encoding.PubKeyFromProto(v.PubKey) + pub, err := crypto.PubKeyFromProto(v.PubKey) if err != nil { return nil, err } diff --git a/sei-tendermint/types/protobuf_test.go b/sei-tendermint/types/protobuf_test.go index f931da0f69..0cc2a68e7d 100644 --- a/sei-tendermint/types/protobuf_test.go +++ b/sei-tendermint/types/protobuf_test.go @@ -9,7 +9,6 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/crypto/encoding" ) func TestABCIPubKey(t *testing.T) { @@ -19,8 +18,8 @@ func TestABCIPubKey(t *testing.T) { } func testABCIPubKey(t *testing.T, pk crypto.PubKey) error { - abciPubKey := encoding.PubKeyToProto(pk) - pk2, err := encoding.PubKeyFromProto(abciPubKey) + abciPubKey := crypto.PubKeyToProto(pk) + pk2, err := crypto.PubKeyFromProto(abciPubKey) require.NoError(t, err) require.Equal(t, pk, pk2) return nil diff --git a/sei-tendermint/types/validator.go b/sei-tendermint/types/validator.go index 6d16d74a56..de2bff3079 100644 --- a/sei-tendermint/types/validator.go +++ b/sei-tendermint/types/validator.go @@ -9,7 +9,6 @@ import ( "strings" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/internal/jsontypes" tmrand "github.com/tendermint/tendermint/libs/rand" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -152,7 +151,7 @@ func ValidatorListString(vals []*Validator) string { // as its redundant with the pubkey. This also excludes ProposerPriority // which changes every round. func (v *Validator) Bytes() []byte { - pk := encoding.PubKeyToProto(v.PubKey) + pk := crypto.PubKeyToProto(v.PubKey) pbv := tmproto.SimpleValidator{ PubKey: &pk, VotingPower: v.VotingPower, @@ -172,7 +171,7 @@ func (v *Validator) ToProto() (*tmproto.Validator, error) { } return &tmproto.Validator{ Address: v.Address, - PubKey: encoding.PubKeyToProto(v.PubKey), + PubKey: crypto.PubKeyToProto(v.PubKey), VotingPower: v.VotingPower, ProposerPriority: v.ProposerPriority, }, nil @@ -185,7 +184,7 @@ func ValidatorFromProto(vp *tmproto.Validator) (*Validator, error) { return nil, errors.New("nil validator") } - pk, err := encoding.PubKeyFromProto(vp.PubKey) + pk, err := crypto.PubKeyFromProto(vp.PubKey) if err != nil { return nil, err } From 124731f00a4d4fe0bffdc58b17c021e8c772a10b Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Mon, 22 Dec 2025 15:44:54 +0100 Subject: [PATCH 49/53] fmt --- sei-cosmos/crypto/codec/tm.go | 37 +++++++++---------- sei-cosmos/x/simulation/mock_tendermint.go | 6 +-- .../abci/example/kvstore/helpers.go | 2 +- .../abci/example/kvstore/kvstore.go | 2 +- sei-tendermint/abci/tests/server/client.go | 4 +- sei-tendermint/crypto/conv.go | 8 ++-- .../internal/p2p/conn/secret_connection.go | 2 +- sei-tendermint/internal/state/state_test.go | 2 +- sei-tendermint/test/e2e/app/app.go | 6 +-- .../fuzz/tests/p2p_secretconnection_test.go | 8 ++-- 10 files changed, 37 insertions(+), 40 deletions(-) diff --git a/sei-cosmos/crypto/codec/tm.go b/sei-cosmos/crypto/codec/tm.go index 3adc02dc8b..f71231be39 100644 --- a/sei-cosmos/crypto/codec/tm.go +++ b/sei-cosmos/crypto/codec/tm.go @@ -1,9 +1,8 @@ package codec import ( - tmcrypto "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/encoding" - tmprotocrypto "github.com/tendermint/tendermint/proto/tendermint/crypto" + "github.com/tendermint/tendermint/crypto" + pb "github.com/tendermint/tendermint/proto/tendermint/crypto" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" @@ -11,10 +10,10 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -// FromTmProtoPublicKey converts a TM's tmprotocrypto.PublicKey into our own PubKey. -func FromTmProtoPublicKey(protoPk tmprotocrypto.PublicKey) (cryptotypes.PubKey, error) { +// FromTmProtoPublicKey converts a TM's pb.PublicKey into our own PubKey. +func FromTmProtoPublicKey(protoPk pb.PublicKey) (cryptotypes.PubKey, error) { switch protoPk := protoPk.Sum.(type) { - case *tmprotocrypto.PublicKey_Ed25519: + case *pb.PublicKey_Ed25519: return &ed25519.PubKey{ Key: protoPk.Ed25519, }, nil @@ -23,33 +22,33 @@ func FromTmProtoPublicKey(protoPk tmprotocrypto.PublicKey) (cryptotypes.PubKey, } } -// ToTmProtoPublicKey converts our own PubKey to TM's tmprotocrypto.PublicKey. -func ToTmProtoPublicKey(pk cryptotypes.PubKey) (tmprotocrypto.PublicKey, error) { +// ToTmProtoPublicKey converts our own PubKey to TM's pb.PublicKey. +func ToTmProtoPublicKey(pk cryptotypes.PubKey) (pb.PublicKey, error) { switch pk := pk.(type) { case *ed25519.PubKey: - return tmprotocrypto.PublicKey{ - Sum: &tmprotocrypto.PublicKey_Ed25519{ + return pb.PublicKey{ + Sum: &pb.PublicKey_Ed25519{ Ed25519: pk.Key, }, }, nil case *secp256k1.PubKey: - return tmprotocrypto.PublicKey{}, sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "secp256k1 consensus keys are not supported") + return pb.PublicKey{}, sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "secp256k1 consensus keys are not supported") default: - return tmprotocrypto.PublicKey{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "cannot convert %v to Tendermint public key", pk) + return pb.PublicKey{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "cannot convert %v to Tendermint public key", pk) } } -// FromTmPubKeyInterface converts TM's tmcrypto.PubKey to our own PubKey. -func FromTmPubKeyInterface(tmPk tmcrypto.PubKey) (cryptotypes.PubKey, error) { - return FromTmProtoPublicKey(encoding.PubKeyToProto(tmPk)) +// FromTmPubKeyInterface converts TM's crypto.PubKey to our own PubKey. +func FromTmPubKeyInterface(tmPk crypto.PubKey) (cryptotypes.PubKey, error) { + return FromTmProtoPublicKey(crypto.PubKeyToProto(tmPk)) } -// ToTmPubKeyInterface converts our own PubKey to TM's tmcrypto.PubKey. -func ToTmPubKeyInterface(pk cryptotypes.PubKey) (tmcrypto.PubKey, error) { +// ToTmPubKeyInterface converts our own PubKey to TM's crypto.PubKey. +func ToTmPubKeyInterface(pk cryptotypes.PubKey) (crypto.PubKey, error) { tmProtoPk, err := ToTmProtoPublicKey(pk) if err != nil { - return tmcrypto.PubKey{}, err + return crypto.PubKey{}, err } - return encoding.PubKeyFromProto(tmProtoPk) + return crypto.PubKeyFromProto(tmProtoPk) } diff --git a/sei-cosmos/x/simulation/mock_tendermint.go b/sei-cosmos/x/simulation/mock_tendermint.go index bac06c106c..23e3552951 100644 --- a/sei-cosmos/x/simulation/mock_tendermint.go +++ b/sei-cosmos/x/simulation/mock_tendermint.go @@ -8,7 +8,7 @@ import ( "time" abci "github.com/tendermint/tendermint/abci/types" - cryptoenc "github.com/tendermint/tendermint/crypto/encoding" + "github.com/tendermint/tendermint/crypto" tmbytes "github.com/tendermint/tendermint/libs/bytes" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) @@ -69,7 +69,7 @@ func (vals mockValidators) randomProposer(r *rand.Rand) tmbytes.HexBytes { key := keys[r.Intn(len(keys))] proposer := vals[key].val - pk, err := cryptoenc.PubKeyFromProto(proposer.PubKey) + pk, err := crypto.PubKeyFromProto(proposer.PubKey) if err != nil { //nolint:wsl panic(err) } @@ -149,7 +149,7 @@ func RandomRequestBeginBlock(r *rand.Rand, params Params, event("begin_block", "signing", "missed") } - pubkey, err := cryptoenc.PubKeyFromProto(mVal.val.PubKey) + pubkey, err := crypto.PubKeyFromProto(mVal.val.PubKey) if err != nil { panic(err) } diff --git a/sei-tendermint/abci/example/kvstore/helpers.go b/sei-tendermint/abci/example/kvstore/helpers.go index b059c64d09..8fcab0c282 100644 --- a/sei-tendermint/abci/example/kvstore/helpers.go +++ b/sei-tendermint/abci/example/kvstore/helpers.go @@ -26,7 +26,7 @@ func RandVals(cnt int) []types.ValidatorUpdate { } res[i] = types.ValidatorUpdate{ PubKey: crypto.PubKeyToProto(pubKey), - Power: int64(power), + Power: int64(power), } } return res diff --git a/sei-tendermint/abci/example/kvstore/kvstore.go b/sei-tendermint/abci/example/kvstore/kvstore.go index 7bda59267d..e36d9e1e0c 100644 --- a/sei-tendermint/abci/example/kvstore/kvstore.go +++ b/sei-tendermint/abci/example/kvstore/kvstore.go @@ -15,8 +15,8 @@ import ( "github.com/tendermint/tendermint/abci/example/code" "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/libs/log" cryptoproto "github.com/tendermint/tendermint/proto/tendermint/crypto" "github.com/tendermint/tendermint/version" diff --git a/sei-tendermint/abci/tests/server/client.go b/sei-tendermint/abci/tests/server/client.go index 23fddcd2e1..8c3f431576 100644 --- a/sei-tendermint/abci/tests/server/client.go +++ b/sei-tendermint/abci/tests/server/client.go @@ -24,9 +24,9 @@ func InitChain(ctx context.Context, client abciclient.Client) error { } // nolint:gosec // G404: Use of weak random number generator power := mrand.Int() - vals[i] = types.ValidatorUpdate { + vals[i] = types.ValidatorUpdate{ PubKey: crypto.PubKeyToProto(pubkey), - Power: int64(power), + Power: int64(power), } } _, err := client.InitChain(ctx, &types.RequestInitChain{ diff --git a/sei-tendermint/crypto/conv.go b/sei-tendermint/crypto/conv.go index 665af1c04a..3ac8629d1a 100644 --- a/sei-tendermint/crypto/conv.go +++ b/sei-tendermint/crypto/conv.go @@ -1,11 +1,11 @@ -package crypto +package crypto import ( "fmt" - "github.com/tendermint/tendermint/libs/utils" "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/internal/jsontypes" + "github.com/tendermint/tendermint/libs/utils" pb "github.com/tendermint/tendermint/proto/tendermint/crypto" ) @@ -14,9 +14,9 @@ func init() { jsontypes.MustRegister((*pb.PublicKey_Ed25519)(nil)) } -var PubKeyConv = utils.ProtoConv[PubKey,*pb.PublicKey]{ +var PubKeyConv = utils.ProtoConv[PubKey, *pb.PublicKey]{ Encode: func(k PubKey) *pb.PublicKey { return utils.Alloc(PubKeyToProto(k)) }, - Decode: func(x *pb.PublicKey) (PubKey,error) { return PubKeyFromProto(*x) }, + Decode: func(x *pb.PublicKey) (PubKey, error) { return PubKeyFromProto(*x) }, } // PubKeyToProto takes crypto.PubKey and transforms it to a protobuf Pubkey diff --git a/sei-tendermint/internal/p2p/conn/secret_connection.go b/sei-tendermint/internal/p2p/conn/secret_connection.go index 4d4f099dd1..079880a497 100644 --- a/sei-tendermint/internal/p2p/conn/secret_connection.go +++ b/sei-tendermint/internal/p2p/conn/secret_connection.go @@ -336,7 +336,7 @@ type authSigMessage struct { Sig crypto.Sig } -var authSigMessageConv = utils.ProtoConv[*authSigMessage, *pb.AuthSigMessage] { +var authSigMessageConv = utils.ProtoConv[*authSigMessage, *pb.AuthSigMessage]{ Encode: func(m *authSigMessage) *pb.AuthSigMessage { return &pb.AuthSigMessage{ PubKey: crypto.PubKeyConv.Encode(m.Key), diff --git a/sei-tendermint/internal/state/state_test.go b/sei-tendermint/internal/state/state_test.go index 88947c6f31..86d5046590 100644 --- a/sei-tendermint/internal/state/state_test.go +++ b/sei-tendermint/internal/state/state_test.go @@ -15,8 +15,8 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/merkle" sm "github.com/tendermint/tendermint/internal/state" statefactory "github.com/tendermint/tendermint/internal/state/test/factory" diff --git a/sei-tendermint/test/e2e/app/app.go b/sei-tendermint/test/e2e/app/app.go index e8ed2f659e..bdf4c33706 100644 --- a/sei-tendermint/test/e2e/app/app.go +++ b/sei-tendermint/test/e2e/app/app.go @@ -14,8 +14,8 @@ import ( "github.com/tendermint/tendermint/abci/example/code" abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/version" @@ -394,9 +394,9 @@ func (app *Application) validatorUpdates(height uint64) (abci.ValidatorUpdates, if err != nil { return nil, fmt.Errorf("invalid ed25519 pubkey value %q: %w", keyString, err) } - valUpdates = append(valUpdates, abci.ValidatorUpdate { + valUpdates = append(valUpdates, abci.ValidatorUpdate{ PubKey: crypto.PubKeyToProto(pubKey), - Power: int64(power), + Power: int64(power), }) } diff --git a/sei-tendermint/test/fuzz/tests/p2p_secretconnection_test.go b/sei-tendermint/test/fuzz/tests/p2p_secretconnection_test.go index 6f3b9bbc7d..271828dc06 100644 --- a/sei-tendermint/test/fuzz/tests/p2p_secretconnection_test.go +++ b/sei-tendermint/test/fuzz/tests/p2p_secretconnection_test.go @@ -4,16 +4,16 @@ package tests import ( "bytes" + "context" "fmt" "io" - "context" - "testing" "net" + "testing" "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/internal/p2p/conn" - "github.com/tendermint/tendermint/libs/utils/scope" "github.com/tendermint/tendermint/libs/utils/require" + "github.com/tendermint/tendermint/libs/utils/scope" ) func FuzzP2PSecretConnection(f *testing.F) { @@ -78,8 +78,6 @@ func (drw kvstoreConn) Close() (err error) { return err1 } - - // Each returned ReadWriteCloser is akin to a net.Connection func makeKVStoreConnPair() (fooConn, barConn kvstoreConn) { barReader, fooWriter := io.Pipe() From 2b6d4e2b2530533d506497b770b11ad89cfc859b Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Thu, 1 Jan 2026 16:58:14 +0100 Subject: [PATCH 50/53] regenerated --- .../abci/types/mocks/application.go | 449 ------------------ sei-tendermint/internal/p2p/handshake.proto | 13 + .../internal/p2p/pb/handshake.pb.go | 129 +++++ .../proto/tendermint/p2p/conn.pb.go | 96 ++-- .../proto/tendermint/p2p/conn.proto | 2 +- 5 files changed, 212 insertions(+), 477 deletions(-) delete mode 100644 sei-tendermint/abci/types/mocks/application.go create mode 100644 sei-tendermint/internal/p2p/handshake.proto create mode 100644 sei-tendermint/internal/p2p/pb/handshake.pb.go diff --git a/sei-tendermint/abci/types/mocks/application.go b/sei-tendermint/abci/types/mocks/application.go deleted file mode 100644 index ff120bb329..0000000000 --- a/sei-tendermint/abci/types/mocks/application.go +++ /dev/null @@ -1,449 +0,0 @@ -// Code generated by mockery. DO NOT EDIT. - -package mocks - -import ( - context "context" - - mock "github.com/stretchr/testify/mock" - types "github.com/tendermint/tendermint/abci/types" -) - -// Application is an autogenerated mock type for the Application type -type Application struct { - mock.Mock -} - -// ApplySnapshotChunk provides a mock function with given fields: _a0, _a1 -func (_m *Application) ApplySnapshotChunk(_a0 context.Context, _a1 *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { - ret := _m.Called(_a0, _a1) - - if len(ret) == 0 { - panic("no return value specified for ApplySnapshotChunk") - } - - var r0 *types.ResponseApplySnapshotChunk - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error)); ok { - return rf(_a0, _a1) - } - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestApplySnapshotChunk) *types.ResponseApplySnapshotChunk); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseApplySnapshotChunk) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *types.RequestApplySnapshotChunk) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// CheckTx provides a mock function with given fields: _a0, _a1 -func (_m *Application) CheckTx(_a0 context.Context, _a1 *types.RequestCheckTxV2) (*types.ResponseCheckTxV2, error) { - ret := _m.Called(_a0, _a1) - - if len(ret) == 0 { - panic("no return value specified for CheckTx") - } - - var r0 *types.ResponseCheckTxV2 - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestCheckTxV2) (*types.ResponseCheckTxV2, error)); ok { - return rf(_a0, _a1) - } - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestCheckTxV2) *types.ResponseCheckTxV2); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseCheckTxV2) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *types.RequestCheckTxV2) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Commit provides a mock function with given fields: _a0 -func (_m *Application) Commit(_a0 context.Context) (*types.ResponseCommit, error) { - ret := _m.Called(_a0) - - if len(ret) == 0 { - panic("no return value specified for Commit") - } - - var r0 *types.ResponseCommit - var r1 error - if rf, ok := ret.Get(0).(func(context.Context) (*types.ResponseCommit, error)); ok { - return rf(_a0) - } - if rf, ok := ret.Get(0).(func(context.Context) *types.ResponseCommit); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseCommit) - } - } - - if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(_a0) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// FinalizeBlock provides a mock function with given fields: _a0, _a1 -func (_m *Application) FinalizeBlock(_a0 context.Context, _a1 *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { - ret := _m.Called(_a0, _a1) - - if len(ret) == 0 { - panic("no return value specified for FinalizeBlock") - } - - var r0 *types.ResponseFinalizeBlock - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error)); ok { - return rf(_a0, _a1) - } - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestFinalizeBlock) *types.ResponseFinalizeBlock); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseFinalizeBlock) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *types.RequestFinalizeBlock) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GetTxPriorityHint provides a mock function with given fields: _a0, _a1 -func (_m *Application) GetTxPriorityHint(_a0 context.Context, _a1 *types.RequestGetTxPriorityHintV2) (*types.ResponseGetTxPriorityHint, error) { - ret := _m.Called(_a0, _a1) - - if len(ret) == 0 { - panic("no return value specified for GetTxPriorityHint") - } - - var r0 *types.ResponseGetTxPriorityHint - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestGetTxPriorityHintV2) (*types.ResponseGetTxPriorityHint, error)); ok { - return rf(_a0, _a1) - } - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestGetTxPriorityHintV2) *types.ResponseGetTxPriorityHint); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseGetTxPriorityHint) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *types.RequestGetTxPriorityHintV2) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Info provides a mock function with given fields: _a0, _a1 -func (_m *Application) Info(_a0 context.Context, _a1 *types.RequestInfo) (*types.ResponseInfo, error) { - ret := _m.Called(_a0, _a1) - - if len(ret) == 0 { - panic("no return value specified for Info") - } - - var r0 *types.ResponseInfo - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestInfo) (*types.ResponseInfo, error)); ok { - return rf(_a0, _a1) - } - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestInfo) *types.ResponseInfo); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseInfo) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *types.RequestInfo) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// InitChain provides a mock function with given fields: _a0, _a1 -func (_m *Application) InitChain(_a0 context.Context, _a1 *types.RequestInitChain) (*types.ResponseInitChain, error) { - ret := _m.Called(_a0, _a1) - - if len(ret) == 0 { - panic("no return value specified for InitChain") - } - - var r0 *types.ResponseInitChain - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestInitChain) (*types.ResponseInitChain, error)); ok { - return rf(_a0, _a1) - } - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestInitChain) *types.ResponseInitChain); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseInitChain) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *types.RequestInitChain) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ListSnapshots provides a mock function with given fields: _a0, _a1 -func (_m *Application) ListSnapshots(_a0 context.Context, _a1 *types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { - ret := _m.Called(_a0, _a1) - - if len(ret) == 0 { - panic("no return value specified for ListSnapshots") - } - - var r0 *types.ResponseListSnapshots - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestListSnapshots) (*types.ResponseListSnapshots, error)); ok { - return rf(_a0, _a1) - } - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestListSnapshots) *types.ResponseListSnapshots); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseListSnapshots) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *types.RequestListSnapshots) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// LoadLatest provides a mock function with given fields: _a0, _a1 -func (_m *Application) LoadLatest(_a0 context.Context, _a1 *types.RequestLoadLatest) (*types.ResponseLoadLatest, error) { - ret := _m.Called(_a0, _a1) - - if len(ret) == 0 { - panic("no return value specified for LoadLatest") - } - - var r0 *types.ResponseLoadLatest - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestLoadLatest) (*types.ResponseLoadLatest, error)); ok { - return rf(_a0, _a1) - } - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestLoadLatest) *types.ResponseLoadLatest); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseLoadLatest) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *types.RequestLoadLatest) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// LoadSnapshotChunk provides a mock function with given fields: _a0, _a1 -func (_m *Application) LoadSnapshotChunk(_a0 context.Context, _a1 *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { - ret := _m.Called(_a0, _a1) - - if len(ret) == 0 { - panic("no return value specified for LoadSnapshotChunk") - } - - var r0 *types.ResponseLoadSnapshotChunk - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error)); ok { - return rf(_a0, _a1) - } - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestLoadSnapshotChunk) *types.ResponseLoadSnapshotChunk); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseLoadSnapshotChunk) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *types.RequestLoadSnapshotChunk) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// OfferSnapshot provides a mock function with given fields: _a0, _a1 -func (_m *Application) OfferSnapshot(_a0 context.Context, _a1 *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { - ret := _m.Called(_a0, _a1) - - if len(ret) == 0 { - panic("no return value specified for OfferSnapshot") - } - - var r0 *types.ResponseOfferSnapshot - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error)); ok { - return rf(_a0, _a1) - } - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestOfferSnapshot) *types.ResponseOfferSnapshot); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseOfferSnapshot) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *types.RequestOfferSnapshot) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PrepareProposal provides a mock function with given fields: _a0, _a1 -func (_m *Application) PrepareProposal(_a0 context.Context, _a1 *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { - ret := _m.Called(_a0, _a1) - - if len(ret) == 0 { - panic("no return value specified for PrepareProposal") - } - - var r0 *types.ResponsePrepareProposal - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error)); ok { - return rf(_a0, _a1) - } - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestPrepareProposal) *types.ResponsePrepareProposal); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponsePrepareProposal) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *types.RequestPrepareProposal) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ProcessProposal provides a mock function with given fields: _a0, _a1 -func (_m *Application) ProcessProposal(_a0 context.Context, _a1 *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { - ret := _m.Called(_a0, _a1) - - if len(ret) == 0 { - panic("no return value specified for ProcessProposal") - } - - var r0 *types.ResponseProcessProposal - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestProcessProposal) (*types.ResponseProcessProposal, error)); ok { - return rf(_a0, _a1) - } - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestProcessProposal) *types.ResponseProcessProposal); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseProcessProposal) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *types.RequestProcessProposal) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Query provides a mock function with given fields: _a0, _a1 -func (_m *Application) Query(_a0 context.Context, _a1 *types.RequestQuery) (*types.ResponseQuery, error) { - ret := _m.Called(_a0, _a1) - - if len(ret) == 0 { - panic("no return value specified for Query") - } - - var r0 *types.ResponseQuery - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestQuery) (*types.ResponseQuery, error)); ok { - return rf(_a0, _a1) - } - if rf, ok := ret.Get(0).(func(context.Context, *types.RequestQuery) *types.ResponseQuery); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.ResponseQuery) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *types.RequestQuery) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// NewApplication creates a new instance of Application. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewApplication(t interface { - mock.TestingT - Cleanup(func()) -}) *Application { - mock := &Application{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/sei-tendermint/internal/p2p/handshake.proto b/sei-tendermint/internal/p2p/handshake.proto new file mode 100644 index 0000000000..05296453f6 --- /dev/null +++ b/sei-tendermint/internal/p2p/handshake.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +package p2p.conn; + +import "roles/validator/validator.proto"; + +option go_package = "github.com/tendermint/tendermint/internal/p2p/pb"; + +message Handshake { + // Proof of validator identity. + // Any node is required to allow 1 connection from a validator node. + optional roles.validator.SignedMsg validator_challenge = 1; +} diff --git a/sei-tendermint/internal/p2p/pb/handshake.pb.go b/sei-tendermint/internal/p2p/pb/handshake.pb.go new file mode 100644 index 0000000000..9430b81c21 --- /dev/null +++ b/sei-tendermint/internal/p2p/pb/handshake.pb.go @@ -0,0 +1,129 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.10 +// protoc (unknown) +// source: p2p/handshake.proto + +package pb + +import ( + pb "github.com/tendermint/tendermint/internal/roles/validator/pb" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Handshake struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Proof of validator identity. + // Any node is required to allow 1 connection from a validator node. + ValidatorChallenge *pb.SignedMsg `protobuf:"bytes,1,opt,name=validator_challenge,json=validatorChallenge,proto3,oneof" json:"validator_challenge,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Handshake) Reset() { + *x = Handshake{} + mi := &file_p2p_handshake_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Handshake) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Handshake) ProtoMessage() {} + +func (x *Handshake) ProtoReflect() protoreflect.Message { + mi := &file_p2p_handshake_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Handshake.ProtoReflect.Descriptor instead. +func (*Handshake) Descriptor() ([]byte, []int) { + return file_p2p_handshake_proto_rawDescGZIP(), []int{0} +} + +func (x *Handshake) GetValidatorChallenge() *pb.SignedMsg { + if x != nil { + return x.ValidatorChallenge + } + return nil +} + +var File_p2p_handshake_proto protoreflect.FileDescriptor + +const file_p2p_handshake_proto_rawDesc = "" + + "\n" + + "\x13p2p/handshake.proto\x12\bp2p.conn\x1a\x1froles/validator/validator.proto\"u\n" + + "\tHandshake\x12P\n" + + "\x13validator_challenge\x18\x01 \x01(\v2\x1a.roles.validator.SignedMsgH\x00R\x12validatorChallenge\x88\x01\x01B\x16\n" + + "\x14_validator_challengeB2Z0github.com/tendermint/tendermint/internal/p2p/pbb\x06proto3" + +var ( + file_p2p_handshake_proto_rawDescOnce sync.Once + file_p2p_handshake_proto_rawDescData []byte +) + +func file_p2p_handshake_proto_rawDescGZIP() []byte { + file_p2p_handshake_proto_rawDescOnce.Do(func() { + file_p2p_handshake_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_p2p_handshake_proto_rawDesc), len(file_p2p_handshake_proto_rawDesc))) + }) + return file_p2p_handshake_proto_rawDescData +} + +var file_p2p_handshake_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_p2p_handshake_proto_goTypes = []any{ + (*Handshake)(nil), // 0: p2p.conn.Handshake + (*pb.SignedMsg)(nil), // 1: roles.validator.SignedMsg +} +var file_p2p_handshake_proto_depIdxs = []int32{ + 1, // 0: p2p.conn.Handshake.validator_challenge:type_name -> roles.validator.SignedMsg + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_p2p_handshake_proto_init() } +func file_p2p_handshake_proto_init() { + if File_p2p_handshake_proto != nil { + return + } + file_p2p_handshake_proto_msgTypes[0].OneofWrappers = []any{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_p2p_handshake_proto_rawDesc), len(file_p2p_handshake_proto_rawDesc)), + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_p2p_handshake_proto_goTypes, + DependencyIndexes: file_p2p_handshake_proto_depIdxs, + MessageInfos: file_p2p_handshake_proto_msgTypes, + }.Build() + File_p2p_handshake_proto = out.File + file_p2p_handshake_proto_goTypes = nil + file_p2p_handshake_proto_depIdxs = nil +} diff --git a/sei-tendermint/proto/tendermint/p2p/conn.pb.go b/sei-tendermint/proto/tendermint/p2p/conn.pb.go index 143610d3ec..ee094b9aeb 100644 --- a/sei-tendermint/proto/tendermint/p2p/conn.pb.go +++ b/sei-tendermint/proto/tendermint/p2p/conn.pb.go @@ -5,7 +5,6 @@ package p2p import ( fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" crypto "github.com/tendermint/tendermint/proto/tendermint/crypto" io "io" @@ -256,8 +255,9 @@ func (*Packet) XXX_OneofWrappers() []interface{} { } type AuthSigMessage struct { - PubKey *crypto.PublicKey `protobuf:"bytes,1,opt,name=pub_key,json=pubKey,proto3" json:"pub_key,omitempty"` - Sig []byte `protobuf:"bytes,2,opt,name=sig,proto3" json:"sig,omitempty"` + PubKey *crypto.PublicKey `protobuf:"bytes,1,opt,name=pub_key,json=pubKey,proto3" json:"pub_key,omitempty"` + Sig []byte `protobuf:"bytes,2,opt,name=sig,proto3" json:"sig,omitempty"` + SeiGigaConnection bool `protobuf:"varint,3,opt,name=sei_giga_connection,json=seiGigaConnection,proto3" json:"sei_giga_connection,omitempty"` } func (m *AuthSigMessage) Reset() { *m = AuthSigMessage{} } @@ -307,6 +307,13 @@ func (m *AuthSigMessage) GetSig() []byte { return nil } +func (m *AuthSigMessage) GetSeiGigaConnection() bool { + if m != nil { + return m.SeiGigaConnection + } + return false +} + func init() { proto.RegisterType((*PacketPing)(nil), "tendermint.p2p.PacketPing") proto.RegisterType((*PacketPong)(nil), "tendermint.p2p.PacketPong") @@ -318,30 +325,32 @@ func init() { func init() { proto.RegisterFile("tendermint/p2p/conn.proto", fileDescriptor_22474b5527c8fa9f) } var fileDescriptor_22474b5527c8fa9f = []byte{ - // 365 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x52, 0x3d, 0x6f, 0xe2, 0x30, - 0x18, 0x8e, 0x8f, 0x83, 0x3b, 0x5e, 0x10, 0x3a, 0x59, 0x37, 0x00, 0xe2, 0x22, 0x94, 0x89, 0x29, - 0x91, 0x72, 0x62, 0x39, 0xe9, 0x86, 0x63, 0xba, 0x0a, 0xa1, 0x46, 0xe9, 0xd4, 0x2e, 0x51, 0x3e, - 0x5c, 0x63, 0x41, 0x6c, 0x0b, 0x3b, 0x43, 0xfe, 0x45, 0x7f, 0x56, 0xbb, 0x31, 0x76, 0xac, 0xe0, - 0x8f, 0x54, 0x71, 0x68, 0x09, 0x52, 0xbb, 0x3d, 0xcf, 0xfb, 0xfa, 0x79, 0xfc, 0x7e, 0xc1, 0x48, - 0x13, 0x9e, 0x91, 0x5d, 0xce, 0xb8, 0xf6, 0xa4, 0x2f, 0xbd, 0x54, 0x70, 0xee, 0xca, 0x9d, 0xd0, - 0x02, 0x0f, 0xce, 0x29, 0x57, 0xfa, 0x72, 0xfc, 0x93, 0x0a, 0x2a, 0x4c, 0xca, 0xab, 0x50, 0xfd, - 0x6a, 0x3c, 0x69, 0x18, 0xa4, 0xbb, 0x52, 0x6a, 0xe1, 0x6d, 0x48, 0xa9, 0xea, 0xac, 0xd3, 0x07, - 0x08, 0xe2, 0x74, 0x43, 0x74, 0xc0, 0x38, 0x6d, 0x30, 0xc1, 0xa9, 0x13, 0x40, 0xb7, 0x66, 0x2b, - 0x45, 0xf1, 0x2f, 0x80, 0x74, 0x1d, 0x73, 0x4e, 0xb6, 0x11, 0xcb, 0x86, 0x68, 0x8a, 0x66, 0xed, - 0xb0, 0x7b, 0x8a, 0x5c, 0x65, 0xf8, 0x07, 0xb4, 0x88, 0xb8, 0x1f, 0x7e, 0x99, 0xa2, 0xd9, 0xf7, - 0xb0, 0x82, 0x18, 0xc3, 0xd7, 0x2c, 0xd6, 0xf1, 0xb0, 0x35, 0x45, 0xb3, 0x7e, 0x68, 0xb0, 0xf3, - 0x84, 0xa0, 0x53, 0x5b, 0xe2, 0xbf, 0xd0, 0x93, 0x06, 0x45, 0x92, 0x71, 0x6a, 0x0c, 0x7b, 0xfe, - 0xd8, 0xbd, 0x6c, 0xc9, 0x3d, 0xd7, 0xf6, 0xdf, 0x0a, 0x41, 0xbe, 0xb3, 0xa6, 0x5c, 0x70, 0x6a, - 0xfe, 0xfd, 0x5c, 0x2e, 0x2e, 0xe4, 0x82, 0x53, 0xfc, 0x07, 0x4e, 0x2c, 0xca, 0x15, 0x35, 0x25, - 0xf6, 0xfc, 0xd1, 0xc7, 0xea, 0x95, 0xaa, 0xc4, 0x5d, 0xf9, 0x46, 0x16, 0x6d, 0x68, 0xa9, 0x22, - 0x77, 0x6e, 0x61, 0xf0, 0xaf, 0xd0, 0xeb, 0x1b, 0x46, 0x57, 0x44, 0xa9, 0x98, 0x12, 0x3c, 0x87, - 0x6f, 0xb2, 0x48, 0xa2, 0x0d, 0x29, 0x4f, 0xed, 0x4c, 0x9a, 0x8e, 0xf5, 0xec, 0xdd, 0xa0, 0x48, - 0xb6, 0x2c, 0x5d, 0x92, 0x32, 0xec, 0xc8, 0x22, 0x59, 0x92, 0xb2, 0x1a, 0x9d, 0x62, 0x75, 0x0b, - 0xfd, 0xb0, 0x82, 0x8b, 0xeb, 0xc7, 0x83, 0x8d, 0xf6, 0x07, 0x1b, 0xbd, 0x1c, 0x6c, 0xf4, 0x70, - 0xb4, 0xad, 0xfd, 0xd1, 0xb6, 0x9e, 0x8f, 0xb6, 0x75, 0x37, 0xa7, 0x4c, 0xaf, 0x8b, 0xc4, 0x4d, - 0x45, 0xee, 0x35, 0xf6, 0xda, 0xbc, 0x11, 0xb3, 0xff, 0xcb, 0xa3, 0x49, 0x3a, 0x26, 0xfa, 0xfb, - 0x35, 0x00, 0x00, 0xff, 0xff, 0x24, 0x4d, 0x23, 0x68, 0x4d, 0x02, 0x00, 0x00, + // 387 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x52, 0x3d, 0x6f, 0xe2, 0x40, + 0x10, 0xf5, 0x1e, 0x07, 0x07, 0x03, 0x42, 0x77, 0x7b, 0x0d, 0x20, 0xce, 0x42, 0xae, 0xa8, 0x6c, + 0xc9, 0x27, 0x9a, 0x93, 0xae, 0x38, 0xae, 0xb8, 0x8b, 0x10, 0x8a, 0xe5, 0x74, 0x69, 0x2c, 0x7f, + 0x6c, 0x96, 0x15, 0x78, 0x77, 0xc5, 0xae, 0x0b, 0xff, 0x84, 0x74, 0xf9, 0x59, 0x49, 0x47, 0x99, + 0x32, 0x82, 0x3f, 0x12, 0xd9, 0x26, 0x60, 0xa4, 0xa4, 0x7b, 0x6f, 0x67, 0xde, 0xf8, 0xcd, 0xf8, + 0xc1, 0x50, 0x13, 0x9e, 0x90, 0x6d, 0xca, 0xb8, 0x76, 0xa4, 0x2b, 0x9d, 0x58, 0x70, 0x6e, 0xcb, + 0xad, 0xd0, 0x02, 0xf7, 0xcf, 0x25, 0x5b, 0xba, 0x72, 0x34, 0xae, 0xb5, 0xc6, 0xdb, 0x5c, 0x6a, + 0xe1, 0xac, 0x49, 0xae, 0xaa, 0x6e, 0xab, 0x07, 0xe0, 0x85, 0xf1, 0x9a, 0x68, 0x8f, 0x71, 0x5a, + 0x63, 0x82, 0x53, 0xcb, 0x83, 0x4e, 0xc5, 0x96, 0x8a, 0xe2, 0x1f, 0x00, 0xf1, 0x2a, 0xe4, 0x9c, + 0x6c, 0x02, 0x96, 0x0c, 0xd0, 0x04, 0x4d, 0x9b, 0x7e, 0xe7, 0xf8, 0x72, 0x95, 0xe0, 0xaf, 0xd0, + 0x20, 0xe2, 0x6e, 0xf0, 0x69, 0x82, 0xa6, 0x6d, 0xbf, 0x80, 0x18, 0xc3, 0xe7, 0x24, 0xd4, 0xe1, + 0xa0, 0x31, 0x41, 0xd3, 0x9e, 0x5f, 0x62, 0xeb, 0x09, 0x41, 0xab, 0x1a, 0x89, 0x7f, 0x43, 0x57, + 0x96, 0x28, 0x90, 0x8c, 0xd3, 0x72, 0x60, 0xd7, 0x1d, 0xd9, 0x97, 0xe6, 0xed, 0xb3, 0xb7, 0xff, + 0x86, 0x0f, 0xf2, 0xc4, 0xea, 0x72, 0xc1, 0x69, 0xf9, 0xdd, 0x8f, 0xe5, 0xe2, 0x42, 0x2e, 0x38, + 0xc5, 0xbf, 0xe0, 0xc8, 0x82, 0x54, 0xd1, 0xd2, 0x62, 0xd7, 0x1d, 0xbe, 0xaf, 0x5e, 0xaa, 0x42, + 0xdc, 0x91, 0x6f, 0x64, 0xde, 0x84, 0x86, 0xca, 0x52, 0xeb, 0x1e, 0x41, 0xff, 0x4f, 0xa6, 0x57, + 0x37, 0x8c, 0x2e, 0x89, 0x52, 0x21, 0x25, 0x78, 0x06, 0x5f, 0x64, 0x16, 0x05, 0x6b, 0x92, 0x1f, + 0xf7, 0x19, 0xd7, 0x47, 0x56, 0xc7, 0xb7, 0xbd, 0x2c, 0xda, 0xb0, 0x78, 0x41, 0x72, 0xbf, 0x25, + 0xb3, 0x68, 0x41, 0xf2, 0xe2, 0x76, 0x8a, 0x55, 0x3b, 0xf4, 0xfc, 0x02, 0x62, 0x1b, 0xbe, 0x2b, + 0xc2, 0x02, 0xca, 0x68, 0x18, 0x14, 0xbf, 0x96, 0xc4, 0x9a, 0x09, 0x5e, 0xfa, 0x6c, 0xfb, 0xdf, + 0x14, 0x61, 0xff, 0x18, 0x0d, 0xff, 0x9e, 0x0a, 0xf3, 0xeb, 0xc7, 0xbd, 0x89, 0x76, 0x7b, 0x13, + 0xbd, 0xec, 0x4d, 0xf4, 0x70, 0x30, 0x8d, 0xdd, 0xc1, 0x34, 0x9e, 0x0f, 0xa6, 0x71, 0x3b, 0xa3, + 0x4c, 0xaf, 0xb2, 0xc8, 0x8e, 0x45, 0xea, 0xd4, 0x82, 0x50, 0x8f, 0x4f, 0x91, 0x03, 0xe7, 0x32, + 0x4f, 0x51, 0xab, 0x7c, 0xfd, 0xf9, 0x1a, 0x00, 0x00, 0xff, 0xff, 0x3a, 0x00, 0x4f, 0xc6, 0x68, + 0x02, 0x00, 0x00, } func (m *PacketPing) Marshal() (dAtA []byte, err error) { @@ -550,6 +559,16 @@ func (m *AuthSigMessage) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.SeiGigaConnection { + i-- + if m.SeiGigaConnection { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } if len(m.Sig) > 0 { i -= len(m.Sig) copy(dAtA[i:], m.Sig) @@ -682,6 +701,9 @@ func (m *AuthSigMessage) Size() (n int) { if l > 0 { n += 1 + l + sovConn(uint64(l)) } + if m.SeiGigaConnection { + n += 2 + } return n } @@ -1168,6 +1190,26 @@ func (m *AuthSigMessage) Unmarshal(dAtA []byte) error { m.Sig = []byte{} } iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SeiGigaConnection", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowConn + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.SeiGigaConnection = bool(v != 0) default: iNdEx = preIndex skippy, err := skipConn(dAtA[iNdEx:]) diff --git a/sei-tendermint/proto/tendermint/p2p/conn.proto b/sei-tendermint/proto/tendermint/p2p/conn.proto index 088f97f892..984883371c 100644 --- a/sei-tendermint/proto/tendermint/p2p/conn.proto +++ b/sei-tendermint/proto/tendermint/p2p/conn.proto @@ -2,7 +2,6 @@ syntax = "proto3"; package tendermint.p2p; -import "gogoproto/gogo.proto"; import "tendermint/crypto/keys.proto"; option go_package = "github.com/tendermint/tendermint/proto/tendermint/p2p"; @@ -28,4 +27,5 @@ message Packet { message AuthSigMessage { tendermint.crypto.PublicKey pub_key = 1; bytes sig = 2; + bool sei_giga_connection = 3; } From 531b7120d7dec9d61693314a851169c7bcd97a7c Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Thu, 1 Jan 2026 17:08:11 +0100 Subject: [PATCH 51/53] lint --- sei-tendermint/proto/tendermint/p2p/pex.proto | 2 -- 1 file changed, 2 deletions(-) diff --git a/sei-tendermint/proto/tendermint/p2p/pex.proto b/sei-tendermint/proto/tendermint/p2p/pex.proto index 94e3336e39..95d34e6e0d 100644 --- a/sei-tendermint/proto/tendermint/p2p/pex.proto +++ b/sei-tendermint/proto/tendermint/p2p/pex.proto @@ -2,8 +2,6 @@ syntax = "proto3"; package tendermint.p2p; -import "gogoproto/gogo.proto"; - option go_package = "github.com/tendermint/tendermint/proto/tendermint/p2p"; message PexAddress { From 27e9f94e22805d37b12a3c296440adf76cd1f77f Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Thu, 1 Jan 2026 17:15:06 +0100 Subject: [PATCH 52/53] reverted validator --- .../abci/types/mocks/application.go | 449 ++++++++++++++++++ sei-tendermint/internal/p2p/handshake.proto | 13 - .../internal/p2p/pb/handshake.pb.go | 129 ----- .../internal/roles/validator/msg.go | 25 - .../roles/validator/pb/validator.hashable.go | 4 - .../roles/validator/pb/validator.pb.go | 314 ------------ .../internal/roles/validator/validator.proto | 30 -- 7 files changed, 449 insertions(+), 515 deletions(-) create mode 100644 sei-tendermint/abci/types/mocks/application.go delete mode 100644 sei-tendermint/internal/p2p/handshake.proto delete mode 100644 sei-tendermint/internal/p2p/pb/handshake.pb.go delete mode 100644 sei-tendermint/internal/roles/validator/msg.go delete mode 100644 sei-tendermint/internal/roles/validator/pb/validator.hashable.go delete mode 100644 sei-tendermint/internal/roles/validator/pb/validator.pb.go delete mode 100644 sei-tendermint/internal/roles/validator/validator.proto diff --git a/sei-tendermint/abci/types/mocks/application.go b/sei-tendermint/abci/types/mocks/application.go new file mode 100644 index 0000000000..ff120bb329 --- /dev/null +++ b/sei-tendermint/abci/types/mocks/application.go @@ -0,0 +1,449 @@ +// Code generated by mockery. DO NOT EDIT. + +package mocks + +import ( + context "context" + + mock "github.com/stretchr/testify/mock" + types "github.com/tendermint/tendermint/abci/types" +) + +// Application is an autogenerated mock type for the Application type +type Application struct { + mock.Mock +} + +// ApplySnapshotChunk provides a mock function with given fields: _a0, _a1 +func (_m *Application) ApplySnapshotChunk(_a0 context.Context, _a1 *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for ApplySnapshotChunk") + } + + var r0 *types.ResponseApplySnapshotChunk + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestApplySnapshotChunk) *types.ResponseApplySnapshotChunk); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseApplySnapshotChunk) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestApplySnapshotChunk) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CheckTx provides a mock function with given fields: _a0, _a1 +func (_m *Application) CheckTx(_a0 context.Context, _a1 *types.RequestCheckTxV2) (*types.ResponseCheckTxV2, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for CheckTx") + } + + var r0 *types.ResponseCheckTxV2 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestCheckTxV2) (*types.ResponseCheckTxV2, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestCheckTxV2) *types.ResponseCheckTxV2); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseCheckTxV2) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestCheckTxV2) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Commit provides a mock function with given fields: _a0 +func (_m *Application) Commit(_a0 context.Context) (*types.ResponseCommit, error) { + ret := _m.Called(_a0) + + if len(ret) == 0 { + panic("no return value specified for Commit") + } + + var r0 *types.ResponseCommit + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*types.ResponseCommit, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(context.Context) *types.ResponseCommit); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseCommit) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// FinalizeBlock provides a mock function with given fields: _a0, _a1 +func (_m *Application) FinalizeBlock(_a0 context.Context, _a1 *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for FinalizeBlock") + } + + var r0 *types.ResponseFinalizeBlock + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestFinalizeBlock) *types.ResponseFinalizeBlock); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseFinalizeBlock) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestFinalizeBlock) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetTxPriorityHint provides a mock function with given fields: _a0, _a1 +func (_m *Application) GetTxPriorityHint(_a0 context.Context, _a1 *types.RequestGetTxPriorityHintV2) (*types.ResponseGetTxPriorityHint, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for GetTxPriorityHint") + } + + var r0 *types.ResponseGetTxPriorityHint + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestGetTxPriorityHintV2) (*types.ResponseGetTxPriorityHint, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestGetTxPriorityHintV2) *types.ResponseGetTxPriorityHint); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseGetTxPriorityHint) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestGetTxPriorityHintV2) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Info provides a mock function with given fields: _a0, _a1 +func (_m *Application) Info(_a0 context.Context, _a1 *types.RequestInfo) (*types.ResponseInfo, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for Info") + } + + var r0 *types.ResponseInfo + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestInfo) (*types.ResponseInfo, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestInfo) *types.ResponseInfo); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseInfo) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestInfo) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// InitChain provides a mock function with given fields: _a0, _a1 +func (_m *Application) InitChain(_a0 context.Context, _a1 *types.RequestInitChain) (*types.ResponseInitChain, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for InitChain") + } + + var r0 *types.ResponseInitChain + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestInitChain) (*types.ResponseInitChain, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestInitChain) *types.ResponseInitChain); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseInitChain) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestInitChain) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListSnapshots provides a mock function with given fields: _a0, _a1 +func (_m *Application) ListSnapshots(_a0 context.Context, _a1 *types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for ListSnapshots") + } + + var r0 *types.ResponseListSnapshots + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestListSnapshots) (*types.ResponseListSnapshots, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestListSnapshots) *types.ResponseListSnapshots); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseListSnapshots) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestListSnapshots) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LoadLatest provides a mock function with given fields: _a0, _a1 +func (_m *Application) LoadLatest(_a0 context.Context, _a1 *types.RequestLoadLatest) (*types.ResponseLoadLatest, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for LoadLatest") + } + + var r0 *types.ResponseLoadLatest + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestLoadLatest) (*types.ResponseLoadLatest, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestLoadLatest) *types.ResponseLoadLatest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseLoadLatest) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestLoadLatest) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// LoadSnapshotChunk provides a mock function with given fields: _a0, _a1 +func (_m *Application) LoadSnapshotChunk(_a0 context.Context, _a1 *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for LoadSnapshotChunk") + } + + var r0 *types.ResponseLoadSnapshotChunk + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestLoadSnapshotChunk) *types.ResponseLoadSnapshotChunk); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseLoadSnapshotChunk) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestLoadSnapshotChunk) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OfferSnapshot provides a mock function with given fields: _a0, _a1 +func (_m *Application) OfferSnapshot(_a0 context.Context, _a1 *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for OfferSnapshot") + } + + var r0 *types.ResponseOfferSnapshot + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestOfferSnapshot) *types.ResponseOfferSnapshot); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseOfferSnapshot) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestOfferSnapshot) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PrepareProposal provides a mock function with given fields: _a0, _a1 +func (_m *Application) PrepareProposal(_a0 context.Context, _a1 *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for PrepareProposal") + } + + var r0 *types.ResponsePrepareProposal + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestPrepareProposal) *types.ResponsePrepareProposal); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponsePrepareProposal) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestPrepareProposal) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ProcessProposal provides a mock function with given fields: _a0, _a1 +func (_m *Application) ProcessProposal(_a0 context.Context, _a1 *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for ProcessProposal") + } + + var r0 *types.ResponseProcessProposal + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestProcessProposal) (*types.ResponseProcessProposal, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestProcessProposal) *types.ResponseProcessProposal); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseProcessProposal) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestProcessProposal) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Query provides a mock function with given fields: _a0, _a1 +func (_m *Application) Query(_a0 context.Context, _a1 *types.RequestQuery) (*types.ResponseQuery, error) { + ret := _m.Called(_a0, _a1) + + if len(ret) == 0 { + panic("no return value specified for Query") + } + + var r0 *types.ResponseQuery + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestQuery) (*types.ResponseQuery, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *types.RequestQuery) *types.ResponseQuery); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.ResponseQuery) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *types.RequestQuery) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewApplication creates a new instance of Application. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewApplication(t interface { + mock.TestingT + Cleanup(func()) +}) *Application { + mock := &Application{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/sei-tendermint/internal/p2p/handshake.proto b/sei-tendermint/internal/p2p/handshake.proto deleted file mode 100644 index 05296453f6..0000000000 --- a/sei-tendermint/internal/p2p/handshake.proto +++ /dev/null @@ -1,13 +0,0 @@ -syntax = "proto3"; - -package p2p.conn; - -import "roles/validator/validator.proto"; - -option go_package = "github.com/tendermint/tendermint/internal/p2p/pb"; - -message Handshake { - // Proof of validator identity. - // Any node is required to allow 1 connection from a validator node. - optional roles.validator.SignedMsg validator_challenge = 1; -} diff --git a/sei-tendermint/internal/p2p/pb/handshake.pb.go b/sei-tendermint/internal/p2p/pb/handshake.pb.go deleted file mode 100644 index 9430b81c21..0000000000 --- a/sei-tendermint/internal/p2p/pb/handshake.pb.go +++ /dev/null @@ -1,129 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.36.10 -// protoc (unknown) -// source: p2p/handshake.proto - -package pb - -import ( - pb "github.com/tendermint/tendermint/internal/roles/validator/pb" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" - unsafe "unsafe" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Handshake struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Proof of validator identity. - // Any node is required to allow 1 connection from a validator node. - ValidatorChallenge *pb.SignedMsg `protobuf:"bytes,1,opt,name=validator_challenge,json=validatorChallenge,proto3,oneof" json:"validator_challenge,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Handshake) Reset() { - *x = Handshake{} - mi := &file_p2p_handshake_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Handshake) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Handshake) ProtoMessage() {} - -func (x *Handshake) ProtoReflect() protoreflect.Message { - mi := &file_p2p_handshake_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Handshake.ProtoReflect.Descriptor instead. -func (*Handshake) Descriptor() ([]byte, []int) { - return file_p2p_handshake_proto_rawDescGZIP(), []int{0} -} - -func (x *Handshake) GetValidatorChallenge() *pb.SignedMsg { - if x != nil { - return x.ValidatorChallenge - } - return nil -} - -var File_p2p_handshake_proto protoreflect.FileDescriptor - -const file_p2p_handshake_proto_rawDesc = "" + - "\n" + - "\x13p2p/handshake.proto\x12\bp2p.conn\x1a\x1froles/validator/validator.proto\"u\n" + - "\tHandshake\x12P\n" + - "\x13validator_challenge\x18\x01 \x01(\v2\x1a.roles.validator.SignedMsgH\x00R\x12validatorChallenge\x88\x01\x01B\x16\n" + - "\x14_validator_challengeB2Z0github.com/tendermint/tendermint/internal/p2p/pbb\x06proto3" - -var ( - file_p2p_handshake_proto_rawDescOnce sync.Once - file_p2p_handshake_proto_rawDescData []byte -) - -func file_p2p_handshake_proto_rawDescGZIP() []byte { - file_p2p_handshake_proto_rawDescOnce.Do(func() { - file_p2p_handshake_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_p2p_handshake_proto_rawDesc), len(file_p2p_handshake_proto_rawDesc))) - }) - return file_p2p_handshake_proto_rawDescData -} - -var file_p2p_handshake_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_p2p_handshake_proto_goTypes = []any{ - (*Handshake)(nil), // 0: p2p.conn.Handshake - (*pb.SignedMsg)(nil), // 1: roles.validator.SignedMsg -} -var file_p2p_handshake_proto_depIdxs = []int32{ - 1, // 0: p2p.conn.Handshake.validator_challenge:type_name -> roles.validator.SignedMsg - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_p2p_handshake_proto_init() } -func file_p2p_handshake_proto_init() { - if File_p2p_handshake_proto != nil { - return - } - file_p2p_handshake_proto_msgTypes[0].OneofWrappers = []any{} - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_p2p_handshake_proto_rawDesc), len(file_p2p_handshake_proto_rawDesc)), - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_p2p_handshake_proto_goTypes, - DependencyIndexes: file_p2p_handshake_proto_depIdxs, - MessageInfos: file_p2p_handshake_proto_msgTypes, - }.Build() - File_p2p_handshake_proto = out.File - file_p2p_handshake_proto_goTypes = nil - file_p2p_handshake_proto_depIdxs = nil -} diff --git a/sei-tendermint/internal/roles/validator/msg.go b/sei-tendermint/internal/roles/validator/msg.go deleted file mode 100644 index 26e609401e..0000000000 --- a/sei-tendermint/internal/roles/validator/msg.go +++ /dev/null @@ -1,25 +0,0 @@ -package validator - -import ( - "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/libs/utils" -) - -type Msg interface{ isMsg() } - -type SessionID struct { - utils.ReadOnly - raw [10]byte -} - -func (s *SessionID) Raw() [10]byte { return s.raw } - -func (s *SessionID) isMsg() {} - -type Sig struct{ inner ed25519.Signature } - -type Signed[M Msg] struct { - utils.ReadOnly - msg M - sig Sig -} diff --git a/sei-tendermint/internal/roles/validator/pb/validator.hashable.go b/sei-tendermint/internal/roles/validator/pb/validator.hashable.go deleted file mode 100644 index 81d810592a..0000000000 --- a/sei-tendermint/internal/roles/validator/pb/validator.hashable.go +++ /dev/null @@ -1,4 +0,0 @@ -// Code generated by sei-tendermint/hashable/plugin. DO NOT EDIT. -package pb - -func (*Msg) IsHashable() {} diff --git a/sei-tendermint/internal/roles/validator/pb/validator.pb.go b/sei-tendermint/internal/roles/validator/pb/validator.pb.go deleted file mode 100644 index 703295036a..0000000000 --- a/sei-tendermint/internal/roles/validator/pb/validator.pb.go +++ /dev/null @@ -1,314 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.36.10 -// protoc (unknown) -// source: roles/validator/validator.proto - -package pb - -import ( - _ "github.com/tendermint/tendermint/internal/hashable/pb" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" - unsafe "unsafe" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Msg struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Types that are valid to be assigned to Kind: - // - // *Msg_SessionId - Kind isMsg_Kind `protobuf_oneof:"kind"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Msg) Reset() { - *x = Msg{} - mi := &file_roles_validator_validator_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Msg) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Msg) ProtoMessage() {} - -func (x *Msg) ProtoReflect() protoreflect.Message { - mi := &file_roles_validator_validator_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Msg.ProtoReflect.Descriptor instead. -func (*Msg) Descriptor() ([]byte, []int) { - return file_roles_validator_validator_proto_rawDescGZIP(), []int{0} -} - -func (x *Msg) GetKind() isMsg_Kind { - if x != nil { - return x.Kind - } - return nil -} - -func (x *Msg) GetSessionId() []byte { - if x != nil { - if x, ok := x.Kind.(*Msg_SessionId); ok { - return x.SessionId - } - } - return nil -} - -type isMsg_Kind interface { - isMsg_Kind() -} - -type Msg_SessionId struct { - // Encrypted session key to sign in handshake to prove - // that we are a validator. - SessionId []byte `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3,oneof"` -} - -func (*Msg_SessionId) isMsg_Kind() {} - -type PublicKey struct { - state protoimpl.MessageState `protogen:"open.v1"` - Ed25519 []byte `protobuf:"bytes,1,opt,name=ed25519,proto3" json:"ed25519,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *PublicKey) Reset() { - *x = PublicKey{} - mi := &file_roles_validator_validator_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *PublicKey) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PublicKey) ProtoMessage() {} - -func (x *PublicKey) ProtoReflect() protoreflect.Message { - mi := &file_roles_validator_validator_proto_msgTypes[1] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PublicKey.ProtoReflect.Descriptor instead. -func (*PublicKey) Descriptor() ([]byte, []int) { - return file_roles_validator_validator_proto_rawDescGZIP(), []int{1} -} - -func (x *PublicKey) GetEd25519() []byte { - if x != nil { - return x.Ed25519 - } - return nil -} - -type Signature struct { - state protoimpl.MessageState `protogen:"open.v1"` - Ed25519 []byte `protobuf:"bytes,1,opt,name=ed25519,proto3" json:"ed25519,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Signature) Reset() { - *x = Signature{} - mi := &file_roles_validator_validator_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Signature) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Signature) ProtoMessage() {} - -func (x *Signature) ProtoReflect() protoreflect.Message { - mi := &file_roles_validator_validator_proto_msgTypes[2] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Signature.ProtoReflect.Descriptor instead. -func (*Signature) Descriptor() ([]byte, []int) { - return file_roles_validator_validator_proto_rawDescGZIP(), []int{2} -} - -func (x *Signature) GetEd25519() []byte { - if x != nil { - return x.Ed25519 - } - return nil -} - -type SignedMsg struct { - state protoimpl.MessageState `protogen:"open.v1"` - Msg *Msg `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"` - Key *PublicKey `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` - Sig *Signature `protobuf:"bytes,3,opt,name=sig,proto3" json:"sig,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *SignedMsg) Reset() { - *x = SignedMsg{} - mi := &file_roles_validator_validator_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *SignedMsg) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SignedMsg) ProtoMessage() {} - -func (x *SignedMsg) ProtoReflect() protoreflect.Message { - mi := &file_roles_validator_validator_proto_msgTypes[3] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SignedMsg.ProtoReflect.Descriptor instead. -func (*SignedMsg) Descriptor() ([]byte, []int) { - return file_roles_validator_validator_proto_rawDescGZIP(), []int{3} -} - -func (x *SignedMsg) GetMsg() *Msg { - if x != nil { - return x.Msg - } - return nil -} - -func (x *SignedMsg) GetKey() *PublicKey { - if x != nil { - return x.Key - } - return nil -} - -func (x *SignedMsg) GetSig() *Signature { - if x != nil { - return x.Sig - } - return nil -} - -var File_roles_validator_validator_proto protoreflect.FileDescriptor - -const file_roles_validator_validator_proto_rawDesc = "" + - "\n" + - "\x1froles/validator/validator.proto\x12\x0froles.validator\x1a\x17hashable/hashable.proto\"6\n" + - "\x03Msg\x12\x1f\n" + - "\n" + - "session_id\x18\x01 \x01(\fH\x00R\tsessionId:\x06Ȉ\xe2\xab\f\x01B\x06\n" + - "\x04kind\"%\n" + - "\tPublicKey\x12\x18\n" + - "\aed25519\x18\x01 \x01(\fR\aed25519\"%\n" + - "\tSignature\x12\x18\n" + - "\aed25519\x18\x01 \x01(\fR\aed25519\"\x8f\x01\n" + - "\tSignedMsg\x12&\n" + - "\x03msg\x18\x01 \x01(\v2\x14.roles.validator.MsgR\x03msg\x12,\n" + - "\x03key\x18\x02 \x01(\v2\x1a.roles.validator.PublicKeyR\x03key\x12,\n" + - "\x03sig\x18\x03 \x01(\v2\x1a.roles.validator.SignatureR\x03sigB>Z roles.validator.Msg - 1, // 1: roles.validator.SignedMsg.key:type_name -> roles.validator.PublicKey - 2, // 2: roles.validator.SignedMsg.sig:type_name -> roles.validator.Signature - 3, // [3:3] is the sub-list for method output_type - 3, // [3:3] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name -} - -func init() { file_roles_validator_validator_proto_init() } -func file_roles_validator_validator_proto_init() { - if File_roles_validator_validator_proto != nil { - return - } - file_roles_validator_validator_proto_msgTypes[0].OneofWrappers = []any{ - (*Msg_SessionId)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_roles_validator_validator_proto_rawDesc), len(file_roles_validator_validator_proto_rawDesc)), - NumEnums: 0, - NumMessages: 4, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_roles_validator_validator_proto_goTypes, - DependencyIndexes: file_roles_validator_validator_proto_depIdxs, - MessageInfos: file_roles_validator_validator_proto_msgTypes, - }.Build() - File_roles_validator_validator_proto = out.File - file_roles_validator_validator_proto_goTypes = nil - file_roles_validator_validator_proto_depIdxs = nil -} diff --git a/sei-tendermint/internal/roles/validator/validator.proto b/sei-tendermint/internal/roles/validator/validator.proto deleted file mode 100644 index cd180bb0c0..0000000000 --- a/sei-tendermint/internal/roles/validator/validator.proto +++ /dev/null @@ -1,30 +0,0 @@ -syntax = "proto3"; - -package roles.validator; - -import "hashable/hashable.proto"; - -option go_package = "github.com/tendermint/tendermint/internal/roles/validator/pb"; - -message Msg { - option (hashable.hashable) = true; - oneof kind { - // Encrypted session key to sign in handshake to prove - // that we are a validator. - bytes session_id = 1; - } -} - -message PublicKey { - bytes ed25519 = 1; -} - -message Signature { - bytes ed25519 = 1; -} - -message SignedMsg { - Msg msg = 1; - PublicKey key = 2; - Signature sig = 3; -} From 4de17dccd18a43e9809b9ef8168d444b8de2d3ac Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Thu, 1 Jan 2026 17:29:04 +0100 Subject: [PATCH 53/53] generate --- sei-tendermint/proto/tendermint/p2p/pex.pb.go | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/sei-tendermint/proto/tendermint/p2p/pex.pb.go b/sei-tendermint/proto/tendermint/p2p/pex.pb.go index 888227f1ef..30b5565773 100644 --- a/sei-tendermint/proto/tendermint/p2p/pex.pb.go +++ b/sei-tendermint/proto/tendermint/p2p/pex.pb.go @@ -5,7 +5,6 @@ package p2p import ( fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" io "io" math "math" @@ -242,26 +241,25 @@ func init() { func init() { proto.RegisterFile("tendermint/p2p/pex.proto", fileDescriptor_81c2f011fd13be57) } var fileDescriptor_81c2f011fd13be57 = []byte{ - // 295 bytes of a gzipped FileDescriptorProto + // 283 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x28, 0x49, 0xcd, 0x4b, 0x49, 0x2d, 0xca, 0xcd, 0xcc, 0x2b, 0xd1, 0x2f, 0x30, 0x2a, 0xd0, 0x2f, 0x48, 0xad, 0xd0, 0x2b, - 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x43, 0xc8, 0xe8, 0x15, 0x18, 0x15, 0x48, 0x89, 0xa4, 0xe7, - 0xa7, 0xe7, 0x83, 0xa5, 0xf4, 0x41, 0x2c, 0x88, 0x2a, 0x25, 0x2d, 0x2e, 0xae, 0x80, 0xd4, 0x0a, - 0xc7, 0x94, 0x94, 0xa2, 0xd4, 0xe2, 0x62, 0x21, 0x01, 0x2e, 0xe6, 0xd2, 0xa2, 0x1c, 0x09, 0x46, - 0x05, 0x46, 0x0d, 0xce, 0x20, 0x10, 0xd3, 0x8b, 0x85, 0x83, 0x49, 0x80, 0xd9, 0x8b, 0x85, 0x83, - 0x59, 0x80, 0x45, 0x89, 0x07, 0xac, 0x36, 0x28, 0xb5, 0xb0, 0x34, 0xb5, 0xb8, 0x44, 0xc9, 0x9d, - 0x8b, 0x1b, 0xcc, 0x2b, 0x2e, 0xc8, 0xcf, 0x2b, 0x4e, 0x15, 0xb2, 0xe0, 0xe2, 0x4c, 0x84, 0x98, - 0x92, 0x5a, 0x2c, 0xc1, 0xa8, 0xc0, 0xac, 0xc1, 0x6d, 0x24, 0xa5, 0x87, 0xea, 0x04, 0x3d, 0x84, - 0x4d, 0x41, 0x08, 0xc5, 0x4a, 0x0b, 0x18, 0xc1, 0xe6, 0xfa, 0xa6, 0x16, 0x17, 0x27, 0xa6, 0xa7, - 0x0a, 0xd9, 0x72, 0x71, 0x17, 0xa4, 0x56, 0xc4, 0x17, 0x41, 0xac, 0x91, 0x60, 0x56, 0x60, 0xc4, - 0x61, 0x14, 0xd4, 0x21, 0x1e, 0x0c, 0x41, 0x5c, 0x05, 0x70, 0x9e, 0x90, 0x03, 0x17, 0x0f, 0x44, - 0x3b, 0xc4, 0x5d, 0x12, 0x2c, 0x60, 0xfd, 0xd2, 0x58, 0xf5, 0x43, 0x94, 0x78, 0x30, 0x04, 0x71, - 0x17, 0x20, 0xb8, 0x4e, 0xac, 0x5c, 0xcc, 0xc5, 0xa5, 0xb9, 0x5e, 0x2c, 0x1c, 0x8c, 0x02, 0x4c, - 0x10, 0xff, 0x3b, 0xf9, 0x9f, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, - 0x8c, 0x13, 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x69, - 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x3e, 0x52, 0x54, 0x20, 0xc7, 0x0a, - 0x38, 0xc8, 0x51, 0xa3, 0x29, 0x89, 0x0d, 0x2c, 0x6a, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x77, - 0x39, 0x25, 0x82, 0xbf, 0x01, 0x00, 0x00, + 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x43, 0xc8, 0xe8, 0x15, 0x18, 0x15, 0x28, 0x69, 0x71, 0x71, + 0x05, 0xa4, 0x56, 0x38, 0xa6, 0xa4, 0x14, 0xa5, 0x16, 0x17, 0x0b, 0x09, 0x70, 0x31, 0x97, 0x16, + 0xe5, 0x48, 0x30, 0x2a, 0x30, 0x6a, 0x70, 0x06, 0x81, 0x98, 0x5e, 0x2c, 0x1c, 0x4c, 0x02, 0xcc, + 0x5e, 0x2c, 0x1c, 0xcc, 0x02, 0x2c, 0x4a, 0x3c, 0x60, 0xb5, 0x41, 0xa9, 0x85, 0xa5, 0xa9, 0xc5, + 0x25, 0x4a, 0xee, 0x5c, 0xdc, 0x60, 0x5e, 0x71, 0x41, 0x7e, 0x5e, 0x71, 0xaa, 0x90, 0x05, 0x17, + 0x67, 0x22, 0xc4, 0x94, 0xd4, 0x62, 0x09, 0x46, 0x05, 0x66, 0x0d, 0x6e, 0x23, 0x29, 0x3d, 0x54, + 0xcb, 0xf4, 0x10, 0x36, 0x05, 0x21, 0x14, 0x2b, 0x2d, 0x60, 0x04, 0x9b, 0xeb, 0x9b, 0x5a, 0x5c, + 0x9c, 0x98, 0x9e, 0x2a, 0x64, 0xcb, 0xc5, 0x5d, 0x90, 0x5a, 0x11, 0x5f, 0x04, 0xb1, 0x46, 0x82, + 0x59, 0x81, 0x11, 0x87, 0x51, 0x50, 0x87, 0x78, 0x30, 0x04, 0x71, 0x15, 0xc0, 0x79, 0x42, 0x0e, + 0x5c, 0x3c, 0x10, 0xed, 0x10, 0x77, 0x49, 0xb0, 0x80, 0xf5, 0x4b, 0x63, 0xd5, 0x0f, 0x51, 0xe2, + 0xc1, 0x10, 0xc4, 0x5d, 0x80, 0xe0, 0x3a, 0xb1, 0x72, 0x31, 0x17, 0x97, 0xe6, 0x7a, 0xb1, 0x70, + 0x30, 0x0a, 0x30, 0x41, 0xfc, 0xef, 0xe4, 0x7f, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, + 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, + 0x0c, 0x51, 0xa6, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0x48, 0x81, + 0x8e, 0x1c, 0xfe, 0xa0, 0x70, 0xd7, 0x47, 0x8d, 0x90, 0x24, 0x36, 0xb0, 0xa8, 0x31, 0x20, 0x00, + 0x00, 0xff, 0xff, 0x58, 0x86, 0x8b, 0x44, 0xa9, 0x01, 0x00, 0x00, } func (m *PexAddress) Marshal() (dAtA []byte, err error) {