From 56fda787d5ca392d73c130362e6b36ed3f92b462 Mon Sep 17 00:00:00 2001 From: Grzegorz Prusak Date: Wed, 10 Dec 2025 18:27:56 +0100 Subject: [PATCH 01/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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