From bef7cda65952be60d44aafab19bda5960ea6925d Mon Sep 17 00:00:00 2001 From: billettc Date: Thu, 18 Jan 2024 13:07:59 -0500 Subject: [PATCH 01/44] bump bstream and update proto stuff --- go.mod | 2 +- go.sum | 18 ++++++++++-------- protoregistry/well_known.go | 3 +-- types/block_range_enum.go | 6 +++--- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index 07a1671..ccf803e 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/spf13/cobra v1.7.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.15.0 - github.com/streamingfast/bstream v0.0.2-0.20240127132523-330edbf00208 + github.com/streamingfast/bstream v0.0.2-0.20240118123300-2bc69dde3598 github.com/streamingfast/cli v0.0.4-0.20230825151644-8cc84512cd80 github.com/streamingfast/dauth v0.0.0-20231120142446-843f4e045cc2 github.com/streamingfast/dbin v0.9.1-0.20231117225723-59790c798e2c diff --git a/go.sum b/go.sum index 6911c85..0e4390c 100644 --- a/go.sum +++ b/go.sum @@ -578,8 +578,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= -github.com/streamingfast/bstream v0.0.2-0.20240127132523-330edbf00208 h1:Lu7c8HMNy48V7RtV5Zc7LcZRJYCPkrGWu8KUV4vRrUs= -github.com/streamingfast/bstream v0.0.2-0.20240127132523-330edbf00208/go.mod h1:08GVb+DXyz6jVNIsbf+2zlaC81UeEGu5o1h49KrSR3Y= +github.com/streamingfast/bstream v0.0.2-0.20240118123300-2bc69dde3598 h1:fCQ+m6x3DZmf0er9vYcjBqqyQ+NOwVogHWSlATZsgfU= +github.com/streamingfast/bstream v0.0.2-0.20240118123300-2bc69dde3598/go.mod h1:08GVb+DXyz6jVNIsbf+2zlaC81UeEGu5o1h49KrSR3Y= github.com/streamingfast/cli v0.0.4-0.20230825151644-8cc84512cd80 h1:UxJUTcEVkdZy8N77E3exz0iNlgQuxl4m220GPvzdZ2s= github.com/streamingfast/cli v0.0.4-0.20230825151644-8cc84512cd80/go.mod h1:QxjVH73Lkqk+mP8bndvhMuQDUINfkgsYhdCH/5TJFKI= github.com/streamingfast/dauth v0.0.0-20231120142446-843f4e045cc2 h1:g4mG6ZCy3/XtcsZXfOHrQOsjVGoX9uTc/QlemaPV4EE= @@ -588,8 +588,10 @@ github.com/streamingfast/dbin v0.9.1-0.20231117225723-59790c798e2c h1:6WjE2yInE+ github.com/streamingfast/dbin v0.9.1-0.20231117225723-59790c798e2c/go.mod h1:dbfiy9ORrL8c6ldSq+L0H9pg8TOqqu/FsghsgUEWK54= github.com/streamingfast/derr v0.0.0-20230515163924-8570aaa43fe1 h1:xJB7rXnOHLesosMjfwWsEL2i/40mFSkzenEb3M0qTyM= github.com/streamingfast/derr v0.0.0-20230515163924-8570aaa43fe1/go.mod h1:QSm/AfaDsE0k1xBYi0lW580YJ/WDV/FKZI628tkZR0Y= -github.com/streamingfast/dgrpc v0.0.0-20240119162453-69517bcc1a7f h1:WDURSuig53yVdqSZDsIpOr/510oGqEtawosa9DtRO6A= -github.com/streamingfast/dgrpc v0.0.0-20240119162453-69517bcc1a7f/go.mod h1:AzMcSri68b21YwdAOw3j4Sq84N/JQ6ONM0B29NSVGyY= +github.com/streamingfast/dgrpc v0.0.0-20230929132851-893fc52687fa h1:L/Ipge5pkZtyHucT7c8F/PiCitiNqQxjoUuxyzWKZew= +github.com/streamingfast/dgrpc v0.0.0-20230929132851-893fc52687fa/go.mod h1:AcY2kk28XswihgU6z37288a3ZF4gGGO7nNwlTI/vET4= +github.com/streamingfast/dlauncher v0.0.0-20230607184145-76399faad89e h1:Nh/gLDv8rOMIidb/gpO4rZOYVe09k+tof/trezkpku4= +github.com/streamingfast/dlauncher v0.0.0-20230607184145-76399faad89e/go.mod h1:xErlHEDd5+4NlR+Mg3ZtW7BTTLB0yZBxZAjHPrkk8X4= github.com/streamingfast/dmetering v0.0.0-20231120142327-a3405f0eed83 h1:IbIUT85146duL9EKwMiiW0HH1djpm8plmJOo+YZbO5U= github.com/streamingfast/dmetering v0.0.0-20231120142327-a3405f0eed83/go.mod h1:3XggUfQMyciaue133qhbIkFqJQqNzozGpa/gI3sdwac= github.com/streamingfast/dmetrics v0.0.0-20230919161904-206fa8ebd545 h1:SUl04bZKGAv207lp7/6CHOJIRpjUKunwItrno3K463Y= @@ -609,8 +611,8 @@ github.com/streamingfast/opaque v0.0.0-20210811180740-0c01d37ea308 h1:xlWSfi1BoP github.com/streamingfast/opaque v0.0.0-20210811180740-0c01d37ea308/go.mod h1:K1p8Bj/wG34KJvYzPUqtzpndffmpkrVY11u2hkyxCWQ= github.com/streamingfast/overseer v0.2.1-0.20210326144022-ee491780e3ef h1:9IVFHRsqvI+vKJwgF1OMV6L55jHbaV/ZLoU4IAG/dME= github.com/streamingfast/overseer v0.2.1-0.20210326144022-ee491780e3ef/go.mod h1:cq8CvbZ3ioFmGrHokSAJalS0lC+pVXLKhITScItUGXY= -github.com/streamingfast/pbgo v0.0.6-0.20240131193313-6b88bc7139db h1:c39xMBgmHgbx1e+cP8KJZ2ziWh9VsjY5C0vDZiytYtw= -github.com/streamingfast/pbgo v0.0.6-0.20240131193313-6b88bc7139db/go.mod h1:eDQjKBYg9BWE2BTaV3UZeLZ5xw05+ywA9RCFTmM1w5Y= +github.com/streamingfast/pbgo v0.0.6-0.20231208140754-ed2bd10b96ee h1:ydH7Ii6P1JIx1bNRO1sFH2VCAr0iZQ8MCHUPBo8i0dY= +github.com/streamingfast/pbgo v0.0.6-0.20231208140754-ed2bd10b96ee/go.mod h1:eDQjKBYg9BWE2BTaV3UZeLZ5xw05+ywA9RCFTmM1w5Y= github.com/streamingfast/protoreflect v0.0.0-20231205191344-4b629d20ce8d h1:33VIARqUqBUKXJcuQoOS1rVSms54tgxhhNCmrLptpLg= github.com/streamingfast/protoreflect v0.0.0-20231205191344-4b629d20ce8d/go.mod h1:aBJivEdekmFWYSQ29EE/fN9IanJWJXbtjy3ky0XD/jE= github.com/streamingfast/sf-tracing v0.0.0-20230616174903-cd2ade641ca9 h1:YRwpVvLYa+FEJlTy0S7mk4UptYjk5zac+A+ZE1phOeA= @@ -619,8 +621,8 @@ github.com/streamingfast/shutter v1.5.0 h1:NpzDYzj0HVpSiDJVO/FFSL6QIK/YKOxY0gJAt github.com/streamingfast/shutter v1.5.0/go.mod h1:B/T6efqdeMGbGwjzPS1ToXzYZI4kDzI5/u4I+7qbjY8= github.com/streamingfast/snapshotter v0.0.0-20230316190750-5bcadfde44d0 h1:Y15G1Z4fpEdm2b+/70owI7TLuXadlqBtGM7rk4Hxrzk= github.com/streamingfast/snapshotter v0.0.0-20230316190750-5bcadfde44d0/go.mod h1:/Rnz2TJvaShjUct0scZ9kKV2Jr9/+KBAoWy4UMYxgv4= -github.com/streamingfast/substreams v1.3.2 h1:czgHC3+ORiKJY75z08R2W67tLxI/WK99NFQgx2fORvg= -github.com/streamingfast/substreams v1.3.2/go.mod h1:fCC3pGTYMi0N4VhJjdJPQydefJpY+tsY9BzWxDi152k= +github.com/streamingfast/substreams v1.2.1-0.20231221200849-a355c5063d0c h1:tpwdanGNJjYCBRbqxGzoXRrz0VWa+Mjeb0OJt/aMOx8= +github.com/streamingfast/substreams v1.2.1-0.20231221200849-a355c5063d0c/go.mod h1:fCC3pGTYMi0N4VhJjdJPQydefJpY+tsY9BzWxDi152k= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= diff --git a/protoregistry/well_known.go b/protoregistry/well_known.go index 237bf0c..d3a7563 100644 --- a/protoregistry/well_known.go +++ b/protoregistry/well_known.go @@ -2,15 +2,14 @@ package protoregistry import ( - "fmt" "encoding/hex" + "fmt" "github.com/jhump/protoreflect/desc" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/descriptorpb" ) - var WellKnownRegistry = NewEmpty() func init() { diff --git a/types/block_range_enum.go b/types/block_range_enum.go index 187a21e..668a645 100644 --- a/types/block_range_enum.go +++ b/types/block_range_enum.go @@ -52,7 +52,7 @@ var _RangeBoundaryValue = map[string]RangeBoundary{ strings.ToLower(_RangeBoundaryName[9:18]): RangeBoundaryExclusive, } -// ParseRangeBoundary attempts to convert a string to a RangeBoundary. +// ParseRangeBoundary attempts to convert a string to a RangeBoundary func ParseRangeBoundary(name string) (RangeBoundary, error) { if x, ok := _RangeBoundaryValue[name]; ok { return x, nil @@ -64,12 +64,12 @@ func ParseRangeBoundary(name string) (RangeBoundary, error) { return RangeBoundary(0), fmt.Errorf("%s is not a valid RangeBoundary, try [%s]", name, strings.Join(_RangeBoundaryNames, ", ")) } -// MarshalText implements the text marshaller method. +// MarshalText implements the text marshaller method func (x RangeBoundary) MarshalText() ([]byte, error) { return []byte(x.String()), nil } -// UnmarshalText implements the text unmarshaller method. +// UnmarshalText implements the text unmarshaller method func (x *RangeBoundary) UnmarshalText(text []byte) error { name := string(text) tmp, err := ParseRangeBoundary(name) From cb81756f14dfe7685e297829707216295df14133 Mon Sep 17 00:00:00 2001 From: arnaudberger Date: Fri, 19 Jan 2024 10:22:57 -0500 Subject: [PATCH 02/44] Adding unmarshalling error print --- cmd/tools/compare/tools_compare_blocks.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/cmd/tools/compare/tools_compare_blocks.go b/cmd/tools/compare/tools_compare_blocks.go index 550ba3e..da7a061 100644 --- a/cmd/tools/compare/tools_compare_blocks.go +++ b/cmd/tools/compare/tools_compare_blocks.go @@ -112,9 +112,9 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm processState := &state{ segments: segments, } - err = storeReference.Walk(ctx, check.WalkBlockPrefix(blockRange, 100), func(filename string) (err error) { fileStartBlock, err := strconv.Atoi(filename) + if err != nil { return fmt.Errorf("parsing filename: %w", err) } @@ -145,6 +145,7 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm &warnAboutExtraBlocks, chain.BlockFactory, ) + if err != nil { bundleErrLock.Lock() bundleReadErr = multierr.Append(bundleReadErr, err) @@ -155,6 +156,7 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm wg.Add(1) go func() { defer wg.Done() + _, currentBlocks, err = readBundle(ctx, filename, storeCurrent, @@ -164,6 +166,7 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm &warnAboutExtraBlocks, chain.BlockFactory, ) + if err != nil { bundleErrLock.Lock() bundleReadErr = multierr.Append(bundleReadErr, err) @@ -233,7 +236,9 @@ func readBundle[B firecore.Block]( var blockHashes []string blocksMap := make(map[string]B) for { + curBlock, err := blockReader.Read() + if err == io.EOF { break } @@ -243,6 +248,7 @@ func readBundle[B firecore.Block]( if curBlock.Number >= stopBlock { break } + if curBlock.Number < fileStartBlock { warnAboutExtraBlocks.Do(func() { fmt.Printf("Warn: Bundle file %s contains block %d, preceding its start_block. This 'feature' is not used anymore and extra blocks like this one will be ignored during compare\n", store.ObjectURL(filename), curBlock.Number) @@ -252,11 +258,12 @@ func readBundle[B firecore.Block]( b := blockFactory() if err = curBlock.Payload.UnmarshalTo(b); err != nil { - fmt.Println("Error unmarshalling block", curBlock.Number, ":", err) + return nil, nil, fmt.Errorf("unmarshalling block: %w", err) break } curBlockPB := sanitizer(b.(B)) + blockHashes = append(blockHashes, curBlock.Id) blocksMap[curBlock.Id] = curBlockPB } @@ -378,6 +385,7 @@ func Compare(reference, current proto.Message, ignoreUnknown bool) (isEqual bool } if !proto.Equal(reference, current) { + ref, err := json.MarshalIndent(reference, "", " ") cli.NoError(err, "marshal JSON reference") From c5487a8328671e3416d6230b7c0c047ee33832b8 Mon Sep 17 00:00:00 2001 From: arnaudberger Date: Fri, 19 Jan 2024 12:27:54 -0500 Subject: [PATCH 03/44] Adding ignore-error-when-JSON-matches flag to compareBlocks cmd --- cmd/tools/compare/tools_compare_blocks.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cmd/tools/compare/tools_compare_blocks.go b/cmd/tools/compare/tools_compare_blocks.go index da7a061..8c63141 100644 --- a/cmd/tools/compare/tools_compare_blocks.go +++ b/cmd/tools/compare/tools_compare_blocks.go @@ -70,6 +70,7 @@ func NewToolsCompareBlocksCmd[B firecore.Block](chain *firecore.Chain[B]) *cobra flags := cmd.PersistentFlags() flags.Bool("diff", false, "When activated, difference is displayed for each block with a difference") flags.Bool("include-unknown-fields", false, "When activated, the 'unknown fields' in the protobuf message will also be compared. These would not generate any difference when unmarshalled with the current protobuf definition.") + flags.Bool("ignore-error-when-JSON-matches", false, "When activated, the reader will ignore error if the JSON representation of the block matches (which results in an empty diff file).") return cmd } @@ -80,6 +81,7 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm return func(cmd *cobra.Command, args []string) error { displayDiff := sflags.MustGetBool(cmd, "diff") ignoreUnknown := !sflags.MustGetBool(cmd, "include-unknown-fields") + ignoreEmptyDiff := sflags.MustGetBool(cmd, "ignore-error-when-JSON-matches") segmentSize := uint64(100000) warnAboutExtraBlocks := sync.Once{} @@ -186,6 +188,12 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm if existsInCurrent { var differences []string isEqual, differences = Compare(referenceBlock, currentBlock, ignoreUnknown) + + if ignoreEmptyDiff && len(differences) == 0 { + fmt.Printf("JSON representation of blocks referenceBlock %s identical, but not protobuf def, blocks are considered equal\n", firehoseBlockToRef(referenceBlock)) + isEqual = true + } + if !isEqual { fmt.Printf("- Block %s is different\n", firehoseBlockToRef(referenceBlock)) if displayDiff { From 1f1153a3479f43bf2ab25239c906cee8ee62e122 Mon Sep 17 00:00:00 2001 From: billettc Date: Mon, 22 Jan 2024 13:52:35 -0500 Subject: [PATCH 04/44] The `firehose`, `substreams-tier1` and `substream-tier2` health endpoint now respects the `common-system-shutdown-signal-delay` configuration value This means that the health endpoint will return `false` now if `SIGINT` has been received but we are still in the shutdown unready period defined by the config value. If you use some sort of load balancer, you should make sure they are configured to use the health endpoint and you should `common-system-shutdown-signal-delay` to something like `15s`. Fixes #9 # Conflicts: # go.sum --- CHANGELOG.md | 2 ++ devel/standard/standard.yaml | 1 + go.mod | 2 +- go.sum | 6 ++---- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c682991..d62b02d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,8 @@ If you were at `firehose-core` version `1.0.0` and are bumping to `1.1.0`, you s * The `firehose`, `substreams-tier1` and `substream-tier2` health endpoint now respects the `common-system-shutdown-signal-delay` configuration value meaning that the health endpoint will return `false` now if `SIGINT` has been received but we are still in the shutdown unready period defined by the config value. If you use some sort of load balancer, you should make sure they are configured to use the health endpoint and you should `common-system-shutdown-signal-delay` to something like `15s`. +* The `firehose`, `substreams-tier1` and `substream-tier2` health endpoint now respects the `common-system-shutdown-signal-delay` configuration value meaning that the health endpoint will return `false` now if `SIGINT` has been received but we are still in the shutdown unready period defined by the config value. If you use some sort of load balancer, you should make sure they are configured to use the health endpoint and you should `common-system-shutdown-signal-delay` to something like `15s`. + * The `firecore.ConsoleReader` gained the ability to print stats as it ingest blocks. * The `firecore.ConsoleReader` has been made stricter by ensuring Firehose chain exchange protocol is respected. diff --git a/devel/standard/standard.yaml b/devel/standard/standard.yaml index d19a64a..dc04818 100644 --- a/devel/standard/standard.yaml +++ b/devel/standard/standard.yaml @@ -18,5 +18,6 @@ start: start --tracer=firehose --store-dir="{node-data-dir}" + --block-rate=1200 --genesis-height=0 --genesis-block-burst=1000 diff --git a/go.mod b/go.mod index ccf803e..1ef6b96 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/streamingfast/dauth v0.0.0-20231120142446-843f4e045cc2 github.com/streamingfast/dbin v0.9.1-0.20231117225723-59790c798e2c github.com/streamingfast/derr v0.0.0-20230515163924-8570aaa43fe1 - github.com/streamingfast/dgrpc v0.0.0-20240119162453-69517bcc1a7f + github.com/streamingfast/dgrpc v0.0.0-20230929132851-893fc52687fa github.com/streamingfast/dmetering v0.0.0-20231120142327-a3405f0eed83 github.com/streamingfast/dmetrics v0.0.0-20230919161904-206fa8ebd545 github.com/streamingfast/dstore v0.1.1-0.20230620124109-3924b3b36c77 diff --git a/go.sum b/go.sum index 0e4390c..89e4959 100644 --- a/go.sum +++ b/go.sum @@ -590,8 +590,6 @@ github.com/streamingfast/derr v0.0.0-20230515163924-8570aaa43fe1 h1:xJB7rXnOHLes github.com/streamingfast/derr v0.0.0-20230515163924-8570aaa43fe1/go.mod h1:QSm/AfaDsE0k1xBYi0lW580YJ/WDV/FKZI628tkZR0Y= github.com/streamingfast/dgrpc v0.0.0-20230929132851-893fc52687fa h1:L/Ipge5pkZtyHucT7c8F/PiCitiNqQxjoUuxyzWKZew= github.com/streamingfast/dgrpc v0.0.0-20230929132851-893fc52687fa/go.mod h1:AcY2kk28XswihgU6z37288a3ZF4gGGO7nNwlTI/vET4= -github.com/streamingfast/dlauncher v0.0.0-20230607184145-76399faad89e h1:Nh/gLDv8rOMIidb/gpO4rZOYVe09k+tof/trezkpku4= -github.com/streamingfast/dlauncher v0.0.0-20230607184145-76399faad89e/go.mod h1:xErlHEDd5+4NlR+Mg3ZtW7BTTLB0yZBxZAjHPrkk8X4= github.com/streamingfast/dmetering v0.0.0-20231120142327-a3405f0eed83 h1:IbIUT85146duL9EKwMiiW0HH1djpm8plmJOo+YZbO5U= github.com/streamingfast/dmetering v0.0.0-20231120142327-a3405f0eed83/go.mod h1:3XggUfQMyciaue133qhbIkFqJQqNzozGpa/gI3sdwac= github.com/streamingfast/dmetrics v0.0.0-20230919161904-206fa8ebd545 h1:SUl04bZKGAv207lp7/6CHOJIRpjUKunwItrno3K463Y= @@ -621,8 +619,8 @@ github.com/streamingfast/shutter v1.5.0 h1:NpzDYzj0HVpSiDJVO/FFSL6QIK/YKOxY0gJAt github.com/streamingfast/shutter v1.5.0/go.mod h1:B/T6efqdeMGbGwjzPS1ToXzYZI4kDzI5/u4I+7qbjY8= github.com/streamingfast/snapshotter v0.0.0-20230316190750-5bcadfde44d0 h1:Y15G1Z4fpEdm2b+/70owI7TLuXadlqBtGM7rk4Hxrzk= github.com/streamingfast/snapshotter v0.0.0-20230316190750-5bcadfde44d0/go.mod h1:/Rnz2TJvaShjUct0scZ9kKV2Jr9/+KBAoWy4UMYxgv4= -github.com/streamingfast/substreams v1.2.1-0.20231221200849-a355c5063d0c h1:tpwdanGNJjYCBRbqxGzoXRrz0VWa+Mjeb0OJt/aMOx8= -github.com/streamingfast/substreams v1.2.1-0.20231221200849-a355c5063d0c/go.mod h1:fCC3pGTYMi0N4VhJjdJPQydefJpY+tsY9BzWxDi152k= +github.com/streamingfast/substreams v1.3.2-0.20240119045851-7de579a236d2 h1:DOARpB5JeJqwPonIbW0FjS/JNxSAnb5Zymm6NnoM+2Q= +github.com/streamingfast/substreams v1.3.2-0.20240119045851-7de579a236d2/go.mod h1:fCC3pGTYMi0N4VhJjdJPQydefJpY+tsY9BzWxDi152k= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= From 69ac5a9bcb545e431d439864fe8b74b34211407a Mon Sep 17 00:00:00 2001 From: Matthieu Vachon Date: Sun, 21 Jan 2024 23:58:14 -0500 Subject: [PATCH 05/44] Fixed precedence ordering of proto registry Refer to changelog diff for details. --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d62b02d..84c3b55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,10 @@ If you were at `firehose-core` version `1.0.0` and are bumping to `1.1.0`, you s * The `tools print one-block` now works correctly on blocks generated by omni-chain `firecore` binary. +* Tools printing Firehose `Block` model to JSON now have `--proto-paths` take higher precedence over well-known types and even the chain itself, the order is `--proto-paths` > `chain` > `well-known` (so `well-known` is lookup last). + +* The `tools print one-block` now works correctly on blocks generated by omni-chain `firecore` binary. + * The various health endpoint now sets `Content-Type: application/json` header prior sending back their response to the client. * The `firehose`, `substreams-tier1` and `substream-tier2` health endpoint now respects the `common-system-shutdown-signal-delay` configuration value meaning that the health endpoint will return `false` now if `SIGINT` has been received but we are still in the shutdown unready period defined by the config value. If you use some sort of load balancer, you should make sure they are configured to use the health endpoint and you should `common-system-shutdown-signal-delay` to something like `15s`. From 2f6e17b14763f6e73be5ada07662e1d19ce2c731 Mon Sep 17 00:00:00 2001 From: billettc Date: Mon, 22 Jan 2024 13:50:24 -0500 Subject: [PATCH 06/44] wip --- cmd/tools/fix/legacy_2_block_any.go | 131 ++++++++++++++++++++++++++++ protoregistry/registry.go | 85 +++++++++--------- protoregistry/registry_test.go | 108 +++++++++++------------ protoregistry/utils.go | 10 ++- protoregistry/well_known.go | 41 ++++----- 5 files changed, 251 insertions(+), 124 deletions(-) create mode 100644 cmd/tools/fix/legacy_2_block_any.go diff --git a/cmd/tools/fix/legacy_2_block_any.go b/cmd/tools/fix/legacy_2_block_any.go new file mode 100644 index 0000000..eeee8e7 --- /dev/null +++ b/cmd/tools/fix/legacy_2_block_any.go @@ -0,0 +1,131 @@ +package fix + +import ( + "fmt" + "io" + + "github.com/spf13/cobra" + "github.com/streamingfast/bstream" + pbbstream "github.com/streamingfast/bstream/pb/sf/bstream/v1" + "github.com/streamingfast/dstore" + firecore "github.com/streamingfast/firehose-core" + "github.com/streamingfast/firehose-core/cmd/tools/check" + "github.com/streamingfast/firehose-core/types" + "go.uber.org/zap" +) + +func NewLegacy2BlockAby[B firecore.Block](chain *firecore.Chain[B], zlog *zap.Logger) *cobra.Command { + return &cobra.Command{ + Use: "legacy_2_block_any []", + Short: "converts merged blocks from legacy format to block any format", + Args: cobra.ExactArgs(3), + RunE: runLegacy2BlockAnyE(zlog), + } +} + +func runLegacy2BlockAnyE(zlog *zap.Logger) firecore.CommandExecutor { + return func(cmd *cobra.Command, args []string) error { + ctx := cmd.Context() + + srcStore, err := dstore.NewDBinStore(args[0]) + if err != nil { + return fmt.Errorf("unable to create source store: %w", err) + } + + destStore, err := dstore.NewDBinStore(args[1]) + if err != nil { + return fmt.Errorf("unable to create destination store: %w", err) + } + + blockRange, err := types.GetBlockRangeFromArg(args[2]) + if err != nil { + return fmt.Errorf("parsing block range: %w", err) + } + + err = srcStore.Walk(ctx, check.WalkBlockPrefix(blockRange, 100), func(filename string) error { + zlog.Debug("checking merged block file", zap.String("filename", filename)) + + startBlock := firecore.MustParseUint64(filename) + + if startBlock > uint64(blockRange.GetStopBlockOr(firecore.MaxUint64)) { + zlog.Debug("skipping merged block file", zap.String("reason", "past stop block"), zap.String("filename", filename)) + return dstore.StopIteration + } + + if startBlock+100 < uint64(blockRange.Start) { + zlog.Debug("skipping merged block file", zap.String("reason", "before start block"), zap.String("filename", filename)) + return nil + } + + rc, err := srcStore.OpenObject(ctx, filename) + if err != nil { + return fmt.Errorf("failed to open %s: %w", filename, err) + } + defer rc.Close() + + br, err := bstream.NewDBinBlockReader(rc) + if err != nil { + return fmt.Errorf("creating block reader: %w", err) + } + + mergeWriter := &firecore.MergedBlocksWriter{ + Store: destStore, + TweakBlock: func(b *pbbstream.Block) (*pbbstream.Block, error) { + + return b, nil + }, + Logger: zlog, + } + + seen := make(map[string]bool) + + var lastBlockID string + var lastBlockNum uint64 + + // iterate through the blocks in the file + for { + block, err := br.Read() + if err == io.EOF { + break + } + + if block.Number < startBlock { + continue + } + + if block.Number > blockRange.GetStopBlockOr(firecore.MaxUint64) { + break + } + + if seen[block.Id] { + zlog.Info("skipping seen block (source merged-blocks had duplicates, skipping)", zap.String("id", block.Id), zap.Uint64("num", block.Number)) + continue + } + + if lastBlockID != "" && block.ParentId != lastBlockID { + return fmt.Errorf("got an invalid sequence of blocks: block %q has previousId %s, previous block %d had ID %q, this endpoint is serving blocks out of order", block.String(), block.ParentId, lastBlockNum, lastBlockID) + } + lastBlockID = block.Id + lastBlockNum = block.Number + + seen[block.Id] = true + + if err := mergeWriter.ProcessBlock(block, nil); err != nil { + return fmt.Errorf("write to blockwriter: %w", err) + } + } + + return nil + }) + + if err == io.EOF { + return nil + } + + if err != nil { + return err + } + + return nil + } +} diff --git a/protoregistry/registry.go b/protoregistry/registry.go index d01c4e1..4f50cbe 100644 --- a/protoregistry/registry.go +++ b/protoregistry/registry.go @@ -5,10 +5,9 @@ import ( "strings" "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + "google.golang.org/protobuf/types/dynamicpb" "google.golang.org/protobuf/types/known/anypb" - - "github.com/jhump/protoreflect/desc" - "github.com/jhump/protoreflect/dynamic" ) // Generate the flags based on Go code in this project directly, this however @@ -16,48 +15,34 @@ import ( // but to fix them we must re-generate it. //go:generate go run ./generator well_known.go protoregistry -type Registry struct { - filesDescriptors []*desc.FileDescriptor -} - -// New creates a new Registry first populated with the well-known types -// and then with the proto files passed as arguments. This means the -// precendence of the proto files is higher than the well-known types. -func New(chainFileDescriptor protoreflect.FileDescriptor, protoPaths ...string) (*Registry, error) { - f := NewEmpty() +func Register(chainFileDescriptor protoreflect.FileDescriptor, protoPaths ...string) error { // Proto paths have the highest precedence, so we register them first if len(protoPaths) > 0 { - if err := f.RegisterFiles(protoPaths); err != nil { - return nil, fmt.Errorf("register proto files: %w", err) + if err := RegisterFiles(protoPaths); err != nil { + return fmt.Errorf("register proto files: %w", err) } } // Chain file descriptor has the second highest precedence, it always // override built-in types if defined. if chainFileDescriptor != nil { - chainFileDesc, err := desc.WrapFile(chainFileDescriptor) + err := RegisterFileDescriptor(chainFileDescriptor) if err != nil { - return nil, fmt.Errorf("wrap file descriptor: %w", err) + return fmt.Errorf("register chain file descriptor: %w", err) } - - f.filesDescriptors = append(f.filesDescriptors, chainFileDesc) } // Last are well known types, they have the lowest precedence - f.Extends(WellKnownRegistry) - - return f, nil -} - -func NewEmpty() *Registry { - f := &Registry{ - filesDescriptors: []*desc.FileDescriptor{}, + fds, err := GetWellKnownFileDescriptors() + if err != nil { + return fmt.Errorf("getting well known file descriptors: %w", err) } - return f + return RegisterFileDescriptors(fds) + } -func (r *Registry) RegisterFiles(files []string) error { +func RegisterFiles(files []string) error { if len(files) == 0 { return nil } @@ -66,30 +51,38 @@ func (r *Registry) RegisterFiles(files []string) error { if err != nil { return fmt.Errorf("parsing proto files: %w", err) } - r.filesDescriptors = append(r.filesDescriptors, fileDescriptors...) - return nil -} -func (r *Registry) RegisterFileDescriptor(f *desc.FileDescriptor) { - r.filesDescriptors = append(r.filesDescriptors, f) + return RegisterFileDescriptors(fileDescriptors) } - -func (r *Registry) Unmarshal(t *anypb.Any) (*dynamic.Message, error) { - for _, fd := range r.filesDescriptors { - md := fd.FindSymbol(cleanTypeURL(t.TypeUrl)) - if md != nil { - dynMsg := dynamic.NewMessageFactoryWithDefaults().NewDynamicMessage(md.(*desc.MessageDescriptor)) - if err := dynMsg.Unmarshal(t.Value); err != nil { - return nil, fmt.Errorf("unmarshalling proto: %w", err) - } - return dynMsg, nil +func RegisterFileDescriptors(fds []protoreflect.FileDescriptor) error { + for _, fd := range fds { + err := RegisterFileDescriptor(fd) + if err != nil { + return fmt.Errorf("registering proto file: %w", err) } } - return nil, fmt.Errorf("no message descriptor in registry for type url: %s", t.TypeUrl) + return nil +} +func RegisterFileDescriptor(fd protoreflect.FileDescriptor) error { + if err := protoregistry.GlobalFiles.RegisterFile(fd); err != nil { + return fmt.Errorf("registering proto file: %w", err) + } + return nil } -func (r *Registry) Extends(registry *Registry) { - r.filesDescriptors = append(r.filesDescriptors, registry.filesDescriptors...) +func Unmarshal(a *anypb.Any) (*dynamicpb.Message, error) { + messageType, err := protoregistry.GlobalTypes.FindMessageByURL(a.TypeUrl) + if err != nil { + return nil, fmt.Errorf("failed to find message type: %v", err) + } + + message := dynamicpb.NewMessage(messageType.Descriptor()) + err = a.UnmarshalTo(message) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal message: %v", err) + } + + return nil, fmt.Errorf("no message descriptor in registry for type url: %s", a.TypeUrl) } func cleanTypeURL(in string) string { diff --git a/protoregistry/registry_test.go b/protoregistry/registry_test.go index 355a8dd..c459fdb 100644 --- a/protoregistry/registry_test.go +++ b/protoregistry/registry_test.go @@ -3,11 +3,13 @@ package protoregistry import ( "testing" - "github.com/jhump/protoreflect/desc" - "github.com/jhump/protoreflect/dynamic" + "github.com/davecgh/go-spew/spew" + "google.golang.org/protobuf/reflect/protoregistry" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/types/dynamicpb" "google.golang.org/protobuf/types/known/anypb" ) @@ -15,63 +17,58 @@ func TestUnmarshal(t *testing.T) { acme := readTestProto(t, "testdata/acme") type args struct { - registry *Registry - typeURL string - value []byte + typeURL string + value []byte } tests := []struct { - name string - args args - want func(tt *testing.T, out *dynamic.Message) - assertion require.ErrorAssertionFunc + name string + protoPaths []string + want func(tt *testing.T, out *dynamicpb.Message) + assertion require.ErrorAssertionFunc + value []byte + typeURL string }{ { - "chain alone", - args{ - registry: mustRegistry(t, acme.UnwrapFile()), - typeURL: "sf.acme.type.v1.Block", - }, - func(tt *testing.T, out *dynamic.Message) { - assert.Equal(tt, "", out.GetFieldByName("hash")) - assert.Equal(tt, uint64(0), out.GetFieldByName("num")) - }, - require.NoError, - }, - { - "overriding built-in chain with proto path", - args{ - registry: mustRegistry(t, acme.UnwrapFile(), "testdata/override_acme"), - typeURL: "sf.acme.type.v1.Block", - }, - func(tt *testing.T, out *dynamic.Message) { - // If you reach this point following a panic in the Go test, the reason there - // is a panic here is because the override_ethereum.proto file is taking - // precedence over the ethereum.proto file, which is not what we want. - assert.Equal(tt, "", out.GetFieldByName("hash_custom")) - assert.Equal(tt, uint64(0), out.GetFieldByName("num_custom")) - }, - require.NoError, - }, - { - "overridding well-know chain (ethereum) with proto path", - args{ - registry: mustRegistry(t, acme.UnwrapFile(), "testdata/override_ethereum"), - typeURL: "sf.ethereum.type.v2.Block", - value: []byte{0x18, 0x0a}, + name: "chain alone", + typeURL: "sf.acme.type.v1.Block", + want: func(tt *testing.T, out *dynamicpb.Message) { + assert.Equal(tt, "", out.Get(out.Descriptor().Fields().ByName("hash"))) + assert.Equal(tt, uint64(0), out.Get(out.Descriptor().Fields().ByName("num"))) }, - func(tt *testing.T, out *dynamic.Message) { - // If you reach this point following a panic in the Go test, the reason there - // is a panic here is because the override_ethereum.proto file is taking - // precedence over the ethereum.proto file, which is not what we want. - assert.Equal(tt, uint64(10), out.GetFieldByName("number_custom")) - }, - require.NoError, + assertion: require.NoError, }, + //{ + // name: "overriding built-in chain with proto path", + // protoPaths: []string{"testdata/override_acme"}, + // typeURL: "sf.acme.type.v1.Block", + // want: func(tt *testing.T, out *dynamicpb.Message) { + // // If you reach this point following a panic in the Go test, the reason there + // // is a panic here is because the override_ethereum.proto file is taking + // // precedence over the ethereum.proto file, which is not what we want. + // assert.Equal(tt, "", out.GetFieldByName("hash_custom")) + // assert.Equal(tt, uint64(0), out.GetFieldByName("num_custom")) + // }, + // assertion: require.NoError, + //}, + //{ + // name: "overridding well-know chain (ethereum) with proto path", + // protoPaths: []string{"testdata/override_ethereum"}, + // typeURL: "sf.ethereum.type.v2.Block", + // value: []byte{0x18, 0x0a}, + // want: func(tt *testing.T, out *dynamicpb.Message) { + // // If you reach this point following a panic in the Go test, the reason there + // // is a panic here is because the override_ethereum.proto file is taking + // // precedence over the ethereum.proto file, which is not what we want. + // assert.Equal(tt, uint64(10), out.GetFieldByName("number_custom")) + // }, + // assertion: require.NoError, + //}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - any := &anypb.Any{TypeUrl: "type.googleapis.com/" + tt.args.typeURL, Value: tt.args.value} - out, err := tt.args.registry.Unmarshal(any) + mustRegistry(t, acme, tt.protoPaths...) + a := &anypb.Any{TypeUrl: "type.googleapis.com/" + tt.typeURL, Value: tt.value} + out, err := Unmarshal(a) tt.assertion(t, err) tt.want(t, out) @@ -79,16 +76,17 @@ func TestUnmarshal(t *testing.T) { } } -func mustRegistry(t *testing.T, chainFileDescriptor protoreflect.FileDescriptor, protoPaths ...string) *Registry { +func mustRegistry(t *testing.T, chainFileDescriptor protoreflect.FileDescriptor, protoPaths ...string) { t.Helper() - reg, err := New(chainFileDescriptor, protoPaths...) + err := RegisterFiles(protoPaths) require.NoError(t, err) - - return reg + err = RegisterFileDescriptor(chainFileDescriptor) + require.NoError(t, err) + spew.Dump(protoregistry.GlobalTypes) } -func readTestProto(t *testing.T, file string) *desc.FileDescriptor { +func readTestProto(t *testing.T, file string) protoreflect.FileDescriptor { t.Helper() descs, err := parseProtoFiles([]string{file}) diff --git a/protoregistry/utils.go b/protoregistry/utils.go index 034424e..f35c71b 100644 --- a/protoregistry/utils.go +++ b/protoregistry/utils.go @@ -6,11 +6,11 @@ import ( "path/filepath" "strings" - "github.com/jhump/protoreflect/desc" "github.com/jhump/protoreflect/desc/protoparse" + "google.golang.org/protobuf/reflect/protoreflect" ) -func parseProtoFiles(importPaths []string) (fds []*desc.FileDescriptor, err error) { +func parseProtoFiles(importPaths []string) (fds []protoreflect.FileDescriptor, err error) { userDir, err := os.UserHomeDir() if err != nil { return nil, fmt.Errorf("get user home dir: %w", err) @@ -56,10 +56,14 @@ func parseProtoFiles(importPaths []string) (fds []*desc.FileDescriptor, err erro } } - fds, err = parser.ParseFiles(protoFiles...) + parsed, err := parser.ParseFiles(protoFiles...) if err != nil { return nil, fmt.Errorf("parsing proto files: %w", err) } + + for _, fd := range parsed { + fds = append(fds, fd.UnwrapFile()) + } return } diff --git a/protoregistry/well_known.go b/protoregistry/well_known.go index d3a7563..0c4582f 100644 --- a/protoregistry/well_known.go +++ b/protoregistry/well_known.go @@ -4,15 +4,15 @@ package protoregistry import ( "encoding/hex" "fmt" + "log" - "github.com/jhump/protoreflect/desc" "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protodesc" + "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/descriptorpb" ) -var WellKnownRegistry = NewEmpty() - -func init() { +func GetWellKnownFileDescriptors() ([]protoreflect.FileDescriptor, error) { protoFiles := []string{ // sf/ethereum/substreams/v1/rpc.proto (https://buf.build/streamingfast/firehose-ethereum/docs/d869cb39aae947ecb0c7df6a1db2b61f:sf.ethereum.substreams.v1) @@ -58,30 +58,31 @@ func init() { "0a1d73662f617277656176652f747970652f76312f747970652e70726f746f121273662e617277656176652e747970652e7631221e0a06426967496e7412140a05627974657318012001280c5205627974657322a6060a05426c6f636b12100a0376657218012001280d5203766572121d0a0a696e6465705f6861736818022001280c5209696e6465704861736812140a056e6f6e636518032001280c52056e6f6e636512250a0e70726576696f75735f626c6f636b18042001280c520d70726576696f7573426c6f636b121c0a0974696d657374616d70180520012804520974696d657374616d7012230a0d6c6173745f7265746172676574180620012804520c6c6173745265746172676574122e0a046469666618072001280b321a2e73662e617277656176652e747970652e76312e426967496e7452046469666612160a06686569676874180820012804520668656967687412120a046861736818092001280c52046861736812170a0774785f726f6f74180a2001280c52067478526f6f7412310a03747873180b2003280b321f2e73662e617277656176652e747970652e76312e5472616e73616374696f6e5203747873121f0a0b77616c6c65745f6c697374180c2001280c520a77616c6c65744c697374121f0a0b7265776172645f61646472180d2001280c520a72657761726441646472122b0a0474616773180e2003280b32172e73662e617277656176652e747970652e76312e546167520474616773123b0a0b7265776172645f706f6f6c180f2001280b321a2e73662e617277656176652e747970652e76312e426967496e74520a726577617264506f6f6c12390a0a77656176655f73697a6518102001280b321a2e73662e617277656176652e747970652e76312e426967496e745209776561766553697a6512390a0a626c6f636b5f73697a6518112001280b321a2e73662e617277656176652e747970652e76312e426967496e745209626c6f636b53697a6512430a0f63756d756c61746976655f6469666618122001280b321a2e73662e617277656176652e747970652e76312e426967496e74520e63756d756c61746976654469666612280a10686173685f6c6973745f6d65726b6c6518142001280c520e686173684c6973744d65726b6c6512330a03706f6118152001280b32212e73662e617277656176652e747970652e76312e50726f6f664f664163636573735203706f6122730a0d50726f6f664f6641636365737312160a066f7074696f6e18012001280952066f7074696f6e12170a0774785f7061746818022001280c5206747850617468121b0a09646174615f7061746818032001280c5208646174615061746812140a056368756e6b18042001280c52056368756e6b229d030a0b5472616e73616374696f6e12160a06666f726d617418012001280d5206666f726d6174120e0a02696418022001280c5202696412170a076c6173745f747818032001280c52066c617374547812140a056f776e657218042001280c52056f776e6572122b0a047461677318052003280b32172e73662e617277656176652e747970652e76312e54616752047461677312160a0674617267657418062001280c520674617267657412360a087175616e7469747918072001280b321a2e73662e617277656176652e747970652e76312e426967496e7452087175616e7469747912120a046461746118082001280c52046461746112370a09646174615f73697a6518092001280b321a2e73662e617277656176652e747970652e76312e426967496e7452086461746153697a65121b0a09646174615f726f6f74180a2001280c520864617461526f6f74121c0a097369676e6174757265180b2001280c52097369676e617475726512320a06726577617264180c2001280b321a2e73662e617277656176652e747970652e76312e426967496e745206726577617264222f0a0354616712120a046e616d6518012001280c52046e616d6512140a0576616c756518022001280c520576616c756542515a4f6769746875622e636f6d2f70696e61782d6e6574776f726b2f66697265686f73652d617277656176652f74797065732f70622f73662f617277656176652f747970652f76313b706261727765617665620670726f746f33", } - var files []*descriptorpb.FileDescriptorProto + var out []protoreflect.FileDescriptor for _, protoFile := range protoFiles { - files = append(files, mustProtoToFileDescriptor(protoFile)) + fd, err := protoToFileDescriptor(protoFile) + if err != nil { + return nil, fmt.Errorf("generating proto file: %w", err) + } + out = append(out, fd) } + return out, nil +} - fdmap, err := desc.CreateFileDescriptors(files) +func protoToFileDescriptor(in string) (protoreflect.FileDescriptor, error) { + protoBytes, err := hex.DecodeString(in) if err != nil { - panic(fmt.Errorf("failed to create file descriptor map: %w", err)) - return + panic(fmt.Errorf("failed to hex decode payload: %w", err)) } - for _, fd := range fdmap { - WellKnownRegistry.RegisterFileDescriptor(fd) + fileDescriptorProto := &descriptorpb.FileDescriptorProto{} + if err := proto.Unmarshal(protoBytes, fileDescriptorProto); err != nil { + return nil, fmt.Errorf("failed to unmarshal file descriptor: %w", err) } -} -func mustProtoToFileDescriptor(in string) *descriptorpb.FileDescriptorProto { - protoBytes, err := hex.DecodeString(in) + fd, err := protodesc.NewFile(fileDescriptorProto, nil) if err != nil { - panic(fmt.Errorf("failed to hex decode payload: %w", err)) - } - out := &descriptorpb.FileDescriptorProto{} - if err := proto.Unmarshal(protoBytes, out); err != nil { - panic(fmt.Errorf("failed to unmarshal file descriptor: %w", err)) + log.Fatalf("Failed to create file descriptor: %v", err) } - return out + return fd, nil } From ac4d30b37f4b5951bc61eacdcead58a149168a34 Mon Sep 17 00:00:00 2001 From: billettc Date: Mon, 22 Jan 2024 16:51:03 -0500 Subject: [PATCH 07/44] bye bye jhump and custom proto registry. We are now using protoregistry.GlobalFiles.RegisterFile and protoregistry.GlobalFiles.RegisterType ... --- cmd/tools/print/tools_print.go | 4 +- jsonencoder/encoder.go | 8 +- jsonencoder/marshallers.go | 9 +- protoregistry/registry.go | 42 +- protoregistry/registry_test.go | 97 +-- .../override/sf/ethereum/type/v2/type.proto | 666 ++++++++++++++++++ .../testdata/override_ethereum/ethereum.proto | 8 - protoregistry/well_known.go | 29 +- 8 files changed, 778 insertions(+), 85 deletions(-) create mode 100644 protoregistry/testdata/override/sf/ethereum/type/v2/type.proto delete mode 100644 protoregistry/testdata/override_ethereum/ethereum.proto diff --git a/cmd/tools/print/tools_print.go b/cmd/tools/print/tools_print.go index b5b1a57..baa1571 100644 --- a/cmd/tools/print/tools_print.go +++ b/cmd/tools/print/tools_print.go @@ -264,10 +264,10 @@ func PrintBStreamBlock(b *pbbstream.Block, printTransactions bool, out io.Writer } func SetupJsonEncoder(cmd *cobra.Command, chainFileDescriptor protoreflect.FileDescriptor) (*jsonencoder.Encoder, error) { - pbregistry, err := protoregistry.New(chainFileDescriptor, sflags.MustGetStringSlice(cmd, "proto-paths")...) + err := protoregistry.Register(chainFileDescriptor, sflags.MustGetStringSlice(cmd, "proto-paths")...) if err != nil { return nil, fmt.Errorf("new registry: %w", err) } - return jsonencoder.New(pbregistry), nil + return jsonencoder.New(), nil } diff --git a/jsonencoder/encoder.go b/jsonencoder/encoder.go index d357cf3..e4ace25 100644 --- a/jsonencoder/encoder.go +++ b/jsonencoder/encoder.go @@ -6,17 +6,13 @@ import ( "github.com/go-json-experiment/json" "github.com/go-json-experiment/json/jsontext" - "github.com/streamingfast/firehose-core/protoregistry" ) type Encoder struct { - protoRegistry *protoregistry.Registry } -func New(registry *protoregistry.Registry) *Encoder { - return &Encoder{ - protoRegistry: registry, - } +func New() *Encoder { + return &Encoder{} } func (e *Encoder) Marshal(in any) error { diff --git a/jsonencoder/marshallers.go b/jsonencoder/marshallers.go index b0e8071..be015ec 100644 --- a/jsonencoder/marshallers.go +++ b/jsonencoder/marshallers.go @@ -5,17 +5,16 @@ import ( "fmt" "strings" - "github.com/jhump/protoreflect/dynamic" - - "github.com/mr-tron/base58" - "github.com/go-json-experiment/json" "github.com/go-json-experiment/json/jsontext" + "github.com/jhump/protoreflect/dynamic" + "github.com/mr-tron/base58" + "github.com/streamingfast/firehose-core/protoregistry" "google.golang.org/protobuf/types/known/anypb" ) func (e *Encoder) anypb(encoder *jsontext.Encoder, t *anypb.Any, options json.Options) error { - msg, err := e.protoRegistry.Unmarshal(t) + msg, err := protoregistry.Unmarshal(t) if err != nil { return fmt.Errorf("unmarshalling proto any: %w", err) } diff --git a/protoregistry/registry.go b/protoregistry/registry.go index 4f50cbe..4978e29 100644 --- a/protoregistry/registry.go +++ b/protoregistry/registry.go @@ -1,6 +1,7 @@ package protoregistry import ( + "errors" "fmt" "strings" @@ -33,13 +34,13 @@ func Register(chainFileDescriptor protoreflect.FileDescriptor, protoPaths ...str } } - // Last are well known types, they have the lowest precedence - fds, err := GetWellKnownFileDescriptors() + //Last are well known types, they have the lowest precedence + err := RegisterWellKnownFileDescriptors() if err != nil { - return fmt.Errorf("getting well known file descriptors: %w", err) + return fmt.Errorf("registering well known file descriptors: %w", err) } - return RegisterFileDescriptors(fds) + return nil } func RegisterFiles(files []string) error { @@ -64,9 +65,36 @@ func RegisterFileDescriptors(fds []protoreflect.FileDescriptor) error { return nil } func RegisterFileDescriptor(fd protoreflect.FileDescriptor) error { - if err := protoregistry.GlobalFiles.RegisterFile(fd); err != nil { - return fmt.Errorf("registering proto file: %w", err) + path := fd.Path() + _, err := protoregistry.GlobalFiles.FindFileByPath(path) + + if err != nil { + if errors.Is(err, protoregistry.NotFound) { + // Register the new file descriptor. + if err := protoregistry.GlobalFiles.RegisterFile(fd); err != nil { + return fmt.Errorf("registering proto file: %w", err) + } + + // Create a new MessageType using the registered FileDescriptor + msgCount := fd.Messages().Len() + for i := 0; i < msgCount; i++ { + messageType := fd.Messages().Get(i) + if messageType == nil { + return fmt.Errorf("message type not found in the registered file") + } + + dmt := dynamicpb.NewMessageType(messageType) // Register the MessageType + err := protoregistry.GlobalTypes.RegisterMessage(dmt) + if err != nil { + return fmt.Errorf("registering message type: %w", err) + } + } + return nil + } + return fmt.Errorf("finding file by path: %w", err) } + + //that mean we already have this file registered, we need to check if we have the message type registered return nil } @@ -82,7 +110,7 @@ func Unmarshal(a *anypb.Any) (*dynamicpb.Message, error) { return nil, fmt.Errorf("failed to unmarshal message: %v", err) } - return nil, fmt.Errorf("no message descriptor in registry for type url: %s", a.TypeUrl) + return message, nil } func cleanTypeURL(in string) string { diff --git a/protoregistry/registry_test.go b/protoregistry/registry_test.go index c459fdb..c809692 100644 --- a/protoregistry/registry_test.go +++ b/protoregistry/registry_test.go @@ -3,12 +3,10 @@ package protoregistry import ( "testing" - "github.com/davecgh/go-spew/spew" - "google.golang.org/protobuf/reflect/protoregistry" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/types/dynamicpb" "google.golang.org/protobuf/types/known/anypb" ) @@ -32,41 +30,65 @@ func TestUnmarshal(t *testing.T) { name: "chain alone", typeURL: "sf.acme.type.v1.Block", want: func(tt *testing.T, out *dynamicpb.Message) { - assert.Equal(tt, "", out.Get(out.Descriptor().Fields().ByName("hash"))) - assert.Equal(tt, uint64(0), out.Get(out.Descriptor().Fields().ByName("num"))) + h := out.Get(out.Descriptor().Fields().ByName("hash")).String() + blockNum := out.Get(out.Descriptor().Fields().ByName("num")).Uint() + assert.Equal(tt, "", h) + assert.Equal(tt, uint64(0), blockNum) + }, + assertion: require.NoError, + }, + { + name: "overriding built-in chain with proto path", + protoPaths: []string{"testdata/override_acme"}, + typeURL: "sf.acme.type.v1.Block", + want: func(tt *testing.T, out *dynamicpb.Message) { + // If you reach this point following a panic in the Go test, the reason there + // is a panic here is because the override_ethereum.proto file is taking + // precedence over the ethereum.proto file, which is not what we want. + h := out.Get(out.Descriptor().Fields().ByName("hash_custom")).String() + blockNum := out.Get(out.Descriptor().Fields().ByName("num_custom")).Uint() + assert.Equal(tt, "", h) + assert.Equal(tt, uint64(0), blockNum) + }, + assertion: require.NoError, + }, + { + name: "well-know chain (ethereum)", + typeURL: "sf.ethereum.type.v2.Block", + value: []byte{0x18, 0x0a}, + want: func(tt *testing.T, out *dynamicpb.Message) { + // If you reach this point following a panic in the Go test, the reason there + // is a panic here is because the override_ethereum.proto file is taking + // precedence over the ethereum.proto file, which is not what we want. + cn := out.Get(out.Descriptor().Fields().ByName("number")).Uint() + assert.Equal(tt, uint64(10), cn) + }, + assertion: require.NoError, + }, + { + name: "overridding well-know chain (ethereum) with proto path", + protoPaths: []string{"testdata/override"}, + typeURL: "sf.ethereum.type.v2.Block", + value: []byte{0x18, 0x0a}, + want: func(tt *testing.T, out *dynamicpb.Message) { + // If you reach this point following a panic in the Go test, the reason there + // is a panic here is because the override_ethereum.proto file is taking + // precedence over the ethereum.proto file, which is not what we want. + cn := out.Get(out.Descriptor().Fields().ByName("number_custom")).Uint() + assert.Equal(tt, uint64(10), cn) }, assertion: require.NoError, }, - //{ - // name: "overriding built-in chain with proto path", - // protoPaths: []string{"testdata/override_acme"}, - // typeURL: "sf.acme.type.v1.Block", - // want: func(tt *testing.T, out *dynamicpb.Message) { - // // If you reach this point following a panic in the Go test, the reason there - // // is a panic here is because the override_ethereum.proto file is taking - // // precedence over the ethereum.proto file, which is not what we want. - // assert.Equal(tt, "", out.GetFieldByName("hash_custom")) - // assert.Equal(tt, uint64(0), out.GetFieldByName("num_custom")) - // }, - // assertion: require.NoError, - //}, - //{ - // name: "overridding well-know chain (ethereum) with proto path", - // protoPaths: []string{"testdata/override_ethereum"}, - // typeURL: "sf.ethereum.type.v2.Block", - // value: []byte{0x18, 0x0a}, - // want: func(tt *testing.T, out *dynamicpb.Message) { - // // If you reach this point following a panic in the Go test, the reason there - // // is a panic here is because the override_ethereum.proto file is taking - // // precedence over the ethereum.proto file, which is not what we want. - // assert.Equal(tt, uint64(10), out.GetFieldByName("number_custom")) - // }, - // assertion: require.NoError, - //}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - mustRegistry(t, acme, tt.protoPaths...) + + protoregistry.GlobalFiles = &protoregistry.Files{} + protoregistry.GlobalTypes = &protoregistry.Types{} + + err := Register(acme, tt.protoPaths...) + require.NoError(t, err) + a := &anypb.Any{TypeUrl: "type.googleapis.com/" + tt.typeURL, Value: tt.value} out, err := Unmarshal(a) tt.assertion(t, err) @@ -75,17 +97,6 @@ func TestUnmarshal(t *testing.T) { }) } } - -func mustRegistry(t *testing.T, chainFileDescriptor protoreflect.FileDescriptor, protoPaths ...string) { - t.Helper() - - err := RegisterFiles(protoPaths) - require.NoError(t, err) - err = RegisterFileDescriptor(chainFileDescriptor) - require.NoError(t, err) - spew.Dump(protoregistry.GlobalTypes) -} - func readTestProto(t *testing.T, file string) protoreflect.FileDescriptor { t.Helper() diff --git a/protoregistry/testdata/override/sf/ethereum/type/v2/type.proto b/protoregistry/testdata/override/sf/ethereum/type/v2/type.proto new file mode 100644 index 0000000..b83655e --- /dev/null +++ b/protoregistry/testdata/override/sf/ethereum/type/v2/type.proto @@ -0,0 +1,666 @@ +syntax = "proto3"; + +package sf.ethereum.type.v2; + +option go_package = "github.com/streamingfast/firehose-ethereum/types/pb/sf/ethereum/type/v2;pbeth"; + +import "google/protobuf/timestamp.proto"; + +message Block { + + // Hash is the block's hash. + bytes hash_custom = 2; + // Number is the block's height at which this block was mined. + uint64 number_custom = 3; + // Size is the size in bytes of the RLP encoding of the block according to Ethereum + // rules. + uint64 size = 4; + // Header contain's the block's header information like its parent hash, the merkel root hash + // and all other information the form a block. + BlockHeader header = 5; + + // Uncles represents block produced with a valid solution but were not actually choosen + // as the canonical block for the given height so they are mostly "forked" blocks. + // + // If the Block has been produced using the Proof of Stake consensus algorithm, this + // field will actually be always empty. + repeated BlockHeader uncles = 6; + + // TransactionTraces hold the execute trace of all the transactions that were executed + // in this block. In in there that you will find most of the Ethereum data model. + repeated TransactionTrace transaction_traces = 10; + + // BalanceChanges here is the array of ETH transfer that happened at the block level + // outside of the normal transaction flow of a block. The best example of this is mining + // reward for the block mined, the transfer of ETH to the miner happens outside the normal + // transaction flow of the chain and is recorded as a `BalanceChange` here since we cannot + // attached it to any transaction. + // + // Only available in DetailLevel: EXTENDED + repeated BalanceChange balance_changes = 11; + + enum DetailLevel{ + DETAILLEVEL_EXTENDED = 0; + // DETAILLEVEL_TRACE = 1; // TBD + DETAILLEVEL_BASE = 2; + } + + // DetailLevel affects the data available in this block. + // + // EXTENDED describes the most complete block, with traces, balance changes, storage changes. It is extracted during the execution of the block. + // BASE describes a block that contains only the block header, transaction receipts and event logs: everything that can be extracted using the base JSON-RPC interface (https://ethereum.org/en/developers/docs/apis/json-rpc/#json-rpc-methods) + // Furthermore, the eth_getTransactionReceipt call has been avoided because it brings only minimal improvements at the cost of requiring an archive node or a full node with complete transaction index. + DetailLevel detail_level = 12; + + // CodeChanges here is the array of smart code change that happened that happened at the block level + // outside of the normal transaction flow of a block. Some Ethereum's fork like BSC and Polygon + // has some capabilities to upgrade internal smart contracts used usually to track the validator + // list. + // + // On hard fork, some procedure runs to upgrade the smart contract code to a new version. In those + // network, a `CodeChange` for each modified smart contract on upgrade would be present here. Note + // that this happen rarely, so the vast majority of block will have an empty list here. + // Only available in DetailLevel: EXTENDED + repeated CodeChange code_changes = 20; + + reserved 40; // bool filtering_applied = 40 [deprecated = true]; + reserved 41; // string filtering_include_filter_expr = 41 [deprecated = true]; + reserved 42; // string filtering_exclude_filter_expr = 42 [deprecated = true]; + + // Ver represents that data model version of the block, it is used internally by Firehose on Ethereum + // as a validation that we are reading the correct version. + int32 ver = 1; +} + +message BlockHeader { + bytes parent_hash = 1; + + // Uncle hash of the block, some reference it as `sha3Uncles`, but `sha3`` is badly worded, so we prefer `uncle_hash`, also + // referred as `ommers` in EIP specification. + // + // If the Block containing this `BlockHeader` has been produced using the Proof of Stake + // consensus algorithm, this field will actually be constant and set to `0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347`. + bytes uncle_hash = 2; + + bytes coinbase = 3; + bytes state_root = 4; + bytes transactions_root = 5; + bytes receipt_root = 6; + bytes logs_bloom = 7; + + // Difficulty is the difficulty of the Proof of Work algorithm that was required to compute a solution. + // + // If the Block containing this `BlockHeader` has been produced using the Proof of Stake + // consensus algorithm, this field will actually be constant and set to `0x00`. + BigInt difficulty = 8; + + // TotalDifficulty is the sum of all previous blocks difficulty including this block difficulty. + // + // If the Block containing this `BlockHeader` has been produced using the Proof of Stake + // consensus algorithm, this field will actually be constant and set to the terminal total difficulty + // that was required to transition to Proof of Stake algorithm, which varies per network. It is set to + // 58 750 000 000 000 000 000 000 on Ethereum Mainnet and to 10 790 000 on Ethereum Testnet Goerli. + BigInt total_difficulty = 17; + + uint64 number = 9; + uint64 gas_limit = 10; + uint64 gas_used = 11; + google.protobuf.Timestamp timestamp = 12; + + // ExtraData is free-form bytes included in the block by the "miner". While on Yellow paper of + // Ethereum this value is maxed to 32 bytes, other consensus algorithm like Clique and some other + // forks are using bigger values to carry special consensus data. + // + // If the Block containing this `BlockHeader` has been produced using the Proof of Stake + // consensus algorithm, this field is strictly enforced to be <= 32 bytes. + bytes extra_data = 13; + + // MixHash is used to prove, when combined with the `nonce` that sufficient amount of computation has been + // achieved and that the solution found is valid. + bytes mix_hash = 14; + + // Nonce is used to prove, when combined with the `mix_hash` that sufficient amount of computation has been + // achieved and that the solution found is valid. + // + // If the Block containing this `BlockHeader` has been produced using the Proof of Stake + // consensus algorithm, this field will actually be constant and set to `0`. + uint64 nonce = 15; + + // Hash is the hash of the block which is actually the computation: + // + // Keccak256(rlp([ + // parent_hash, + // uncle_hash, + // coinbase, + // state_root, + // transactions_root, + // receipt_root, + // logs_bloom, + // difficulty, + // number, + // gas_limit, + // gas_used, + // timestamp, + // extra_data, + // mix_hash, + // nonce, + // base_fee_per_gas (to be included, only if London Fork is active) + // withdrawals_root (to be included, only if Shangai Fork is active) + // ])) + // + bytes hash = 16; + + // Base fee per gas according to EIP-1559 (e.g. London Fork) rules, only set if London is present/active on the chain. + BigInt base_fee_per_gas = 18; + + // Withdrawals root hash according to EIP-4895 (e.g. Shangai Fork) rules, only set if Shangai is present/active on the chain. + // + // Only available in DetailLevel: EXTENDED + bytes withdrawals_root = 19; + + // Only available in DetailLevel: EXTENDED + Uint64NestedArray tx_dependency = 20; +} + +message Uint64NestedArray { + repeated Uint64Array val = 1; +} + +message Uint64Array { + repeated uint64 val = 1; +} + +message BigInt { + bytes bytes = 1; +} + +message TransactionTrace { + // consensus + bytes to = 1; + uint64 nonce = 2; + // GasPrice represents the effective price that has been paid for each gas unit of this transaction. Over time, the + // Ethereum rules changes regarding GasPrice field here. Before London fork, the GasPrice was always set to the + // fixed gas price. After London fork, this value has different meaning depending on the transaction type (see `Type` field). + // + // In cases where `TransactionTrace.Type == TRX_TYPE_LEGACY || TRX_TYPE_ACCESS_LIST`, then GasPrice has the same meaning + // as before the London fork. + // + // In cases where `TransactionTrace.Type == TRX_TYPE_DYNAMIC_FEE`, then GasPrice is the effective gas price paid + // for the transaction which is equals to `BlockHeader.BaseFeePerGas + TransactionTrace.` + BigInt gas_price = 3; + + // GasLimit is the maximum of gas unit the sender of the transaction is willing to consume when perform the EVM + // execution of the whole transaction + uint64 gas_limit = 4; + + // Value is the amount of Ether transferred as part of this transaction. + BigInt value = 5; + + // Input data the transaction will receive for execution of EVM. + bytes input = 6; + + // V is the recovery ID value for the signature Y point. + bytes v = 7; + + // R is the signature's X point on the elliptic curve (32 bytes). + bytes r = 8; + + // S is the signature's Y point on the elliptic curve (32 bytes). + bytes s = 9; + + // GasUsed is the total amount of gas unit used for the whole execution of the transaction. + uint64 gas_used = 10; + + // Type represents the Ethereum transaction type, available only since EIP-2718 & EIP-2930 activation which happened on Berlin fork. + // The value is always set even for transaction before Berlin fork because those before the fork are still legacy transactions. + Type type = 12; + + enum Type { + // All transactions that ever existed prior Berlin fork before EIP-2718 was implemented. + TRX_TYPE_LEGACY = 0; + + // Transaction that specicy an access list of contract/storage_keys that is going to be used + // in this transaction. + // + // Added in Berlin fork (EIP-2930). + TRX_TYPE_ACCESS_LIST = 1; + + // Transaction that specifis an access list just like TRX_TYPE_ACCESS_LIST but in addition defines the + // max base gas gee and max priority gas fee to pay for this transaction. Transaction's of those type are + // executed against EIP-1559 rules which dictates a dynamic gas cost based on the congestion of the network. + TRX_TYPE_DYNAMIC_FEE = 2; + + // Arbitrum-specific transactions + TRX_TYPE_ARBITRUM_DEPOSIT = 100; + TRX_TYPE_ARBITRUM_UNSIGNED = 101; + TRX_TYPE_ARBITRUM_CONTRACT = 102; + TRX_TYPE_ARBITRUM_RETRY = 104; + TRX_TYPE_ARBITRUM_SUBMIT_RETRYABLE = 105; + TRX_TYPE_ARBITRUM_INTERNAL = 106; + TRX_TYPE_ARBITRUM_LEGACY = 120; + + } + + // AcccessList represents the storage access this transaction has agreed to do in which case those storage + // access cost less gas unit per access. + // + // This will is populated only if `TransactionTrace.Type == TRX_TYPE_ACCESS_LIST || TRX_TYPE_DYNAMIC_FEE` which + // is possible only if Berlin (TRX_TYPE_ACCESS_LIST) nor London (TRX_TYPE_DYNAMIC_FEE) fork are active on the chain. + repeated AccessTuple access_list = 14; + + // MaxFeePerGas is the maximum fee per gas the user is willing to pay for the transaction gas used. + // + // This will is populated only if `TransactionTrace.Type == TRX_TYPE_DYNAMIC_FEE` which is possible only + // if Londong fork is active on the chain. + // + // Only available in DetailLevel: EXTENDED + BigInt max_fee_per_gas = 11; + + // MaxPriorityFeePerGas is priority fee per gas the user to pay in extra to the miner on top of the block's + // base fee. + // + // This will is populated only if `TransactionTrace.Type == TRX_TYPE_DYNAMIC_FEE` which is possible only + // if London fork is active on the chain. + // + // Only available in DetailLevel: EXTENDED + BigInt max_priority_fee_per_gas = 13; + + // meta + uint32 index = 20; + bytes hash = 21; + bytes from = 22; + // Only available in DetailLevel: EXTENDED + bytes return_data = 23; + // Only available in DetailLevel: EXTENDED + bytes public_key = 24; + uint64 begin_ordinal = 25; + uint64 end_ordinal = 26; + + // TransactionTraceStatus is the status of the transaction execution and will let you know if the transaction + // was successful or not. + // + // A successful transaction has been recorded to the blockchain's state for calls in it that were successful. + // This means it's possible only a subset of the calls were properly recorded, refer to [calls[].state_reverted] field + // to determine which calls were reverted. + // + // A quirks of the Ethereum protocol is that a transaction `FAILED` or `REVERTED` still affects the blockchain's + // state for **some** of the state changes. Indeed, in those cases, the transactions fees are still paid to the miner + // which means there is a balance change for the transaction's emitter (e.g. `from`) to pay the gas fees, an optional + // balance change for gas refunded to the transaction's emitter (e.g. `from`) and a balance change for the miner who + // received the transaction fees. There is also a nonce change for the transaction's emitter (e.g. `from`). + // + // This means that to properly record the state changes for a transaction, you need to conditionally procees the + // transaction's status. + // + // For a `SUCCEEDED` transaction, you iterate over the `calls` array and record the state changes for each call for + // which `state_reverted == false` (if a transaction succeeded, the call at #0 will always `state_reverted == false` + // because it aligns with the transaction). + // + // For a `FAILED` or `REVERTED` transaction, you iterate over the root call (e.g. at #0, will always exist) for + // balance changes you process those where `reason` is either `REASON_GAS_BUY`, `REASON_GAS_REFUND` or + // `REASON_REWARD_TRANSACTION_FEE` and for nonce change, still on the root call, you pick the nonce change which the + // smallest ordinal (if more than one). + TransactionTraceStatus status = 30; + + TransactionReceipt receipt = 31; + + // Only available in DetailLevel: EXTENDED + repeated Call calls = 32; +} + +// AccessTuple represents a list of storage keys for a given contract's address and is used +// for AccessList construction. +message AccessTuple { + bytes address = 1; + repeated bytes storage_keys = 2; +} + +enum TransactionTraceStatus { + UNKNOWN = 0; + SUCCEEDED = 1; + FAILED = 2; + REVERTED = 3; +} + +message TransactionReceipt { + // State root is an intermediate state_root hash, computed in-between transactions to make + // **sure** you could build a proof and point to state in the middle of a block. Geth client + // uses `PostState + root + PostStateOrStatus`` while Parity used `status_code, root...`` this piles + // hardforks, see (read the EIPs first): + // - https://github.com/ethereum/EIPs/blob/master/EIPS/eip-658.md + // + // Moreover, the notion of `Outcome`` in parity, which segregates the two concepts, which are + // stored in the same field `status_code`` can be computed based on such a hack of the `state_root` + // field, following `EIP-658`. + // + // Before Byzantinium hard fork, this field is always empty. + bytes state_root = 1; + uint64 cumulative_gas_used = 2; + bytes logs_bloom = 3; + repeated Log logs = 4; +} + +message Log { + bytes address = 1; + repeated bytes topics = 2; + bytes data = 3; + + // Index is the index of the log relative to the transaction. This index + // is always populated regardless of the state revertion of the the call + // that emitted this log. + // + // Only available in DetailLevel: EXTENDED + uint32 index = 4; + + // BlockIndex represents the index of the log relative to the Block. + // + // An **important** notice is that this field will be 0 when the call + // that emitted the log has been reverted by the chain. + // + // Currently, there is two locations where a Log can be obtained: + // - block.transaction_traces[].receipt.logs[] + // - block.transaction_traces[].calls[].logs[] + // + // In the `receipt` case, the logs will be populated only when the call + // that emitted them has not been reverted by the chain and when in this + // position, the `blockIndex` is always populated correctly. + // + // In the case of `calls` case, for `call` where `stateReverted == true`, + // the `blockIndex` value will always be 0. + uint32 blockIndex = 6; + + uint64 ordinal = 7; +} + +message Call { + uint32 index = 1; + uint32 parent_index = 2; + uint32 depth = 3; + CallType call_type = 4; + bytes caller = 5; + bytes address = 6; + BigInt value = 7; + uint64 gas_limit = 8; + uint64 gas_consumed = 9; + bytes return_data = 13; + bytes input = 14; + bool executed_code = 15; + bool suicide = 16; + + /* hex representation of the hash -> preimage */ + map keccak_preimages = 20; + repeated StorageChange storage_changes = 21; + repeated BalanceChange balance_changes = 22; + repeated NonceChange nonce_changes = 24; + repeated Log logs = 25; + repeated CodeChange code_changes = 26; + + // Deprecated: repeated bytes created_accounts + reserved 27; + + repeated GasChange gas_changes = 28; + + // Deprecated: repeated GasEvent gas_events + reserved 29; + + // In Ethereum, a call can be either: + // - Successfull, execution passes without any problem encountered + // - Failed, execution failed, and remaining gas should be consumed + // - Reverted, execution failed, but only gas consumed so far is billed, remaining gas is refunded + // + // When a call is either `failed` or `reverted`, the `status_failed` field + // below is set to `true`. If the status is `reverted`, then both `status_failed` + // and `status_reverted` are going to be set to `true`. + bool status_failed = 10; + bool status_reverted = 12; + + // Populated when a call either failed or reverted, so when `status_failed == true`, + // see above for details about those flags. + string failure_reason = 11; + + // This field represents wheter or not the state changes performed + // by this call were correctly recorded by the blockchain. + // + // On Ethereum, a transaction can record state changes even if some + // of its inner nested calls failed. This is problematic however since + // a call will invalidate all its state changes as well as all state + // changes performed by its child call. This means that even if a call + // has a status of `SUCCESS`, the chain might have reverted all the state + // changes it performed. + // + // ```text + // Trx 1 + // Call #1 + // Call #2 + // Call #3 + // |--- Failure here + // Call #4 + // ``` + // + // In the transaction above, while Call #2 and Call #3 would have the + // status `EXECUTED`. + // + // If you check all calls and check only `state_reverted` flag, you might be missing + // some balance changes and nonce changes. This is because when a full transaction fails + // in ethereum (e.g. `calls.all(x.state_reverted == true)`), there is still the transaction + // fee that are recorded to the chain. + // + // Refer to [TransactionTrace#status] field for more details about the handling you must + // perform. + bool state_reverted = 30; + + uint64 begin_ordinal = 31; + uint64 end_ordinal = 32; + + repeated AccountCreation account_creations = 33; + + reserved 50; // repeated ERC20BalanceChange erc20_balance_changes = 50 [deprecated = true]; + reserved 51; // repeated ERC20TransferEvent erc20_transfer_events = 51 [deprecated = true]; + reserved 60; // bool filtering_matched = 60 [deprecated = true]; +} + +enum CallType { + UNSPECIFIED = 0; + CALL = 1; // direct? what's the name for `Call` alone? + CALLCODE = 2; + DELEGATE = 3; + STATIC = 4; + CREATE = 5; // create2 ? any other form of calls? +} + +message StorageChange { + bytes address = 1; + bytes key = 2; + bytes old_value = 3; + bytes new_value = 4; + + uint64 ordinal = 5; +} + +message BalanceChange { + bytes address = 1; + BigInt old_value = 2; + BigInt new_value = 3; + Reason reason = 4; + + // Obtain all balanche change reasons under deep mind repository: + // + // ```shell + // ack -ho 'BalanceChangeReason\(".*"\)' | grep -Eo '".*"' | sort | uniq + // ``` + enum Reason { + REASON_UNKNOWN = 0; + REASON_REWARD_MINE_UNCLE = 1; + REASON_REWARD_MINE_BLOCK = 2; + REASON_DAO_REFUND_CONTRACT = 3; + REASON_DAO_ADJUST_BALANCE = 4; + REASON_TRANSFER = 5; + REASON_GENESIS_BALANCE = 6; + REASON_GAS_BUY = 7; + REASON_REWARD_TRANSACTION_FEE = 8; + REASON_REWARD_FEE_RESET = 14; + REASON_GAS_REFUND = 9; + REASON_TOUCH_ACCOUNT = 10; + REASON_SUICIDE_REFUND = 11; + REASON_SUICIDE_WITHDRAW = 13; + REASON_CALL_BALANCE_OVERRIDE = 12; + // Used on chain(s) where some Ether burning happens + REASON_BURN = 15; + REASON_WITHDRAWAL = 16; + } + + uint64 ordinal = 5; +} + +message NonceChange { + bytes address = 1; + uint64 old_value = 2; + uint64 new_value = 3; + uint64 ordinal = 4; +} + +message AccountCreation { + bytes account = 1; + uint64 ordinal = 2; +} + +message CodeChange { + bytes address = 1; + bytes old_hash = 2; + bytes old_code = 3; + bytes new_hash = 4; + bytes new_code = 5; + + uint64 ordinal = 6; +} + +// The gas change model represents the reason why some gas cost has occurred. +// The gas is computed per actual op codes. Doing them completely might prove +// overwhelming in most cases. +// +// Hence, we only index some of them, those that are costy like all the calls +// one, log events, return data, etc. +message GasChange { + uint64 old_value = 1; + uint64 new_value = 2; + Reason reason = 3; + + // Obtain all gas change reasons under deep mind repository: + // + // ```shell + // ack -ho 'GasChangeReason\(".*"\)' | grep -Eo '".*"' | sort | uniq + // ``` + enum Reason { + REASON_UNKNOWN = 0; + // REASON_CALL is the amount of gas that will be charged for a 'CALL' opcode executed by the EVM + REASON_CALL = 1; + // REASON_CALL_CODE is the amount of gas that will be charged for a 'CALLCODE' opcode executed by the EVM + REASON_CALL_CODE = 2; + // REASON_CALL_DATA_COPY is the amount of gas that will be charged for a 'CALLDATACOPY' opcode executed by the EVM + REASON_CALL_DATA_COPY = 3; + // REASON_CODE_COPY is the amount of gas that will be charged for a 'CALLDATACOPY' opcode executed by the EVM + REASON_CODE_COPY = 4; + // REASON_CODE_STORAGE is the amount of gas that will be charged for code storage + REASON_CODE_STORAGE = 5; + // REASON_CONTRACT_CREATION is the amount of gas that will be charged for a 'CREATE' opcode executed by the EVM and for the gas + // burned for a CREATE, today controlled by EIP150 rules + REASON_CONTRACT_CREATION = 6; + // REASON_CONTRACT_CREATION2 is the amount of gas that will be charged for a 'CREATE2' opcode executed by the EVM and for the gas + // burned for a CREATE2, today controlled by EIP150 rules + REASON_CONTRACT_CREATION2 = 7; + // REASON_DELEGATE_CALL is the amount of gas that will be charged for a 'DELEGATECALL' opcode executed by the EVM + REASON_DELEGATE_CALL = 8; + // REASON_EVENT_LOG is the amount of gas that will be charged for a 'LOG' opcode executed by the EVM + REASON_EVENT_LOG = 9; + // REASON_EXT_CODE_COPY is the amount of gas that will be charged for a 'LOG' opcode executed by the EVM + REASON_EXT_CODE_COPY = 10; + // REASON_FAILED_EXECUTION is the burning of the remaining gas when the execution failed without a revert + REASON_FAILED_EXECUTION = 11; + // REASON_INTRINSIC_GAS is the amount of gas that will be charged for the intrinsic cost of the transaction, there is + // always exactly one of those per transaction + REASON_INTRINSIC_GAS = 12; + // GasChangePrecompiledContract is the amount of gas that will be charged for a precompiled contract execution + REASON_PRECOMPILED_CONTRACT = 13; + // REASON_REFUND_AFTER_EXECUTION is the amount of gas that will be refunded to the caller after the execution of the call, + // if there is left over at the end of execution + REASON_REFUND_AFTER_EXECUTION = 14; + // REASON_RETURN is the amount of gas that will be charged for a 'RETURN' opcode executed by the EVM + REASON_RETURN = 15; + // REASON_RETURN_DATA_COPY is the amount of gas that will be charged for a 'RETURNDATACOPY' opcode executed by the EVM + REASON_RETURN_DATA_COPY = 16; + // REASON_REVERT is the amount of gas that will be charged for a 'REVERT' opcode executed by the EVM + REASON_REVERT = 17; + // REASON_SELF_DESTRUCT is the amount of gas that will be charged for a 'SELFDESTRUCT' opcode executed by the EVM + REASON_SELF_DESTRUCT = 18; + // REASON_STATIC_CALL is the amount of gas that will be charged for a 'STATICALL' opcode executed by the EVM + REASON_STATIC_CALL = 19; + + // REASON_STATE_COLD_ACCESS is the amount of gas that will be charged for a cold storage access as controlled by EIP2929 rules + // + // Added in Berlin fork (Geth 1.10+) + REASON_STATE_COLD_ACCESS = 20; + + // REASON_TX_INITIAL_BALANCE is the initial balance for the call which will be equal to the gasLimit of the call + // + // Added as new tracing reason in Geth, available only on some chains + REASON_TX_INITIAL_BALANCE = 21; + // REASON_TX_REFUNDS is the sum of all refunds which happened during the tx execution (e.g. storage slot being cleared) + // this generates an increase in gas. There is only one such gas change per transaction. + // + // Added as new tracing reason in Geth, available only on some chains + REASON_TX_REFUNDS = 22; + // REASON_TX_LEFT_OVER_RETURNED is the amount of gas left over at the end of transaction's execution that will be returned + // to the chain. This change will always be a negative change as we "drain" left over gas towards 0. If there was no gas + // left at the end of execution, no such even will be emitted. The returned gas's value in Wei is returned to caller. + // There is at most one of such gas change per transaction. + // + // Added as new tracing reason in Geth, available only on some chains + REASON_TX_LEFT_OVER_RETURNED = 23; + + // REASON_CALL_INITIAL_BALANCE is the initial balance for the call which will be equal to the gasLimit of the call. There is only + // one such gas change per call. + // + // Added as new tracing reason in Geth, available only on some chains + REASON_CALL_INITIAL_BALANCE = 24; + // REASON_CALL_LEFT_OVER_RETURNED is the amount of gas left over that will be returned to the caller, this change will always + // be a negative change as we "drain" left over gas towards 0. If there was no gas left at the end of execution, no such even + // will be emitted. + REASON_CALL_LEFT_OVER_RETURNED = 25; + } + + uint64 ordinal = 4; +} + +// HeaderOnlyBlock is used to optimally unpack the [Block] structure (note the +// corresponding message number for the `header` field) while consuming less +// memory, when only the `header` is desired. +// +// WARN: this is a client-side optimization pattern and should be moved in the +// consuming code. +message HeaderOnlyBlock { + BlockHeader header = 5; +} + +// BlockWithRefs is a lightweight block, with traces and transactions +// purged from the `block` within, and only. It is used in transports +// to pass block data around. +message BlockWithRefs { + string id = 1; + Block block = 2; + TransactionRefs transaction_trace_refs = 3; + bool irreversible = 4; +} + +message TransactionTraceWithBlockRef { + TransactionTrace trace = 1; + BlockRef block_ref = 2; +} + +message TransactionRefs { + repeated bytes hashes = 1; +} + +message BlockRef { + bytes hash = 1; + uint64 number = 2; +} diff --git a/protoregistry/testdata/override_ethereum/ethereum.proto b/protoregistry/testdata/override_ethereum/ethereum.proto deleted file mode 100644 index 519e894..0000000 --- a/protoregistry/testdata/override_ethereum/ethereum.proto +++ /dev/null @@ -1,8 +0,0 @@ -syntax = "proto3"; - -package sf.ethereum.type.v2; - -message Block { - bytes hash_custom = 2; - uint64 number_custom = 3; -} \ No newline at end of file diff --git a/protoregistry/well_known.go b/protoregistry/well_known.go index 0c4582f..752bddd 100644 --- a/protoregistry/well_known.go +++ b/protoregistry/well_known.go @@ -4,7 +4,8 @@ package protoregistry import ( "encoding/hex" "fmt" - "log" + + "google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protodesc" @@ -12,8 +13,10 @@ import ( "google.golang.org/protobuf/types/descriptorpb" ) -func GetWellKnownFileDescriptors() ([]protoreflect.FileDescriptor, error) { +func RegisterWellKnownFileDescriptors() error { protoFiles := []string{ + // google/protobuf/timestamp.proto (https://buf.build/streamingfast/firehose-ethereum/docs/d869cb39aae947ecb0c7df6a1db2b61f:google.protobuf) + "0a1f676f6f676c652f70726f746f6275662f74696d657374616d702e70726f746f120f676f6f676c652e70726f746f627566223b0a0954696d657374616d7012180a077365636f6e647318012001280352077365636f6e647312140a056e616e6f7318022001280552056e616e6f734285010a13636f6d2e676f6f676c652e70726f746f627566420e54696d657374616d7050726f746f50015a32676f6f676c652e676f6c616e672e6f72672f70726f746f6275662f74797065732f6b6e6f776e2f74696d657374616d707062f80101a20203475042aa021e476f6f676c652e50726f746f6275662e57656c6c4b6e6f776e5479706573620670726f746f33", // sf/ethereum/substreams/v1/rpc.proto (https://buf.build/streamingfast/firehose-ethereum/docs/d869cb39aae947ecb0c7df6a1db2b61f:sf.ethereum.substreams.v1) "0a2373662f657468657265756d2f73756273747265616d732f76312f7270632e70726f746f121973662e657468657265756d2e73756273747265616d732e763122440a0852706343616c6c7312380a0563616c6c7318012003280b32222e73662e657468657265756d2e73756273747265616d732e76312e52706343616c6c520563616c6c7322360a0752706343616c6c12170a07746f5f6164647218012001280c5206746f4164647212120a046461746118022001280c52046461746122540a0c527063526573706f6e73657312440a09726573706f6e73657318012003280b32262e73662e657468657265756d2e73756273747265616d732e76312e527063526573706f6e73655209726573706f6e73657322370a0b527063526573706f6e736512100a0372617718012001280c520372617712160a066661696c656418022001280852066661696c656442575a556769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d657468657265756d2f74797065732f70622f73662f657468657265756d2f73756273747265616d732f76313b70626574687373620670726f746f33", @@ -21,9 +24,6 @@ func GetWellKnownFileDescriptors() ([]protoreflect.FileDescriptor, error) { // sf/ethereum/transform/v1/transforms.proto (https://buf.build/streamingfast/firehose-ethereum/docs/d869cb39aae947ecb0c7df6a1db2b61f:sf.ethereum.transform.v1) "0a2973662f657468657265756d2f7472616e73666f726d2f76312f7472616e73666f726d732e70726f746f121873662e657468657265756d2e7472616e73666f726d2e763122d6010a0e436f6d62696e656446696c74657212440a0b6c6f675f66696c7465727318012003280b32232e73662e657468657265756d2e7472616e73666f726d2e76312e4c6f6746696c746572520a6c6f6746696c7465727312490a0c63616c6c5f66696c7465727318022003280b32262e73662e657468657265756d2e7472616e73666f726d2e76312e43616c6c546f46696c746572520b63616c6c46696c7465727312330a1673656e645f616c6c5f626c6f636b5f68656164657273180320012808521373656e64416c6c426c6f636b4865616465727322560a0e4d756c74694c6f6746696c74657212440a0b6c6f675f66696c7465727318012003280b32232e73662e657468657265756d2e7472616e73666f726d2e76312e4c6f6746696c746572520a6c6f6746696c7465727322540a094c6f6746696c746572121c0a0961646472657373657318012003280c520961646472657373657312290a106576656e745f7369676e61747572657318022003280c520f6576656e745369676e617475726573225e0a114d756c746943616c6c546f46696c74657212490a0c63616c6c5f66696c7465727318012003280b32262e73662e657468657265756d2e7472616e73666f726d2e76312e43616c6c546f46696c746572520b63616c6c46696c74657273224c0a0c43616c6c546f46696c746572121c0a0961646472657373657318012003280c5209616464726573736573121e0a0a7369676e61747572657318022003280c520a7369676e617475726573220c0a0a4865616465724f6e6c79425a5a586769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d657468657265756d2f74797065732f70622f73662f657468657265756d2f7472616e73666f726d2f76313b70627472616e73666f726d620670726f746f33", - // google/protobuf/timestamp.proto (https://buf.build/streamingfast/firehose-ethereum/docs/d869cb39aae947ecb0c7df6a1db2b61f:google.protobuf) - "0a1f676f6f676c652f70726f746f6275662f74696d657374616d702e70726f746f120f676f6f676c652e70726f746f627566223b0a0954696d657374616d7012180a077365636f6e647318012001280352077365636f6e647312140a056e616e6f7318022001280552056e616e6f734285010a13636f6d2e676f6f676c652e70726f746f627566420e54696d657374616d7050726f746f50015a32676f6f676c652e676f6c616e672e6f72672f70726f746f6275662f74797065732f6b6e6f776e2f74696d657374616d707062f80101a20203475042aa021e476f6f676c652e50726f746f6275662e57656c6c4b6e6f776e5479706573620670726f746f33", - // sf/ethereum/type/v2/type.proto (https://buf.build/streamingfast/firehose-ethereum/docs/d869cb39aae947ecb0c7df6a1db2b61f:sf.ethereum.type.v2) "0a1e73662f657468657265756d2f747970652f76322f747970652e70726f746f121373662e657468657265756d2e747970652e76321a1f676f6f676c652f70726f746f6275662f74696d657374616d702e70726f746f228e050a05426c6f636b12120a046861736818022001280c52046861736812160a066e756d62657218032001280452066e756d62657212120a0473697a65180420012804520473697a6512380a0668656164657218052001280b32202e73662e657468657265756d2e747970652e76322e426c6f636b486561646572520668656164657212380a06756e636c657318062003280b32202e73662e657468657265756d2e747970652e76322e426c6f636b4865616465725206756e636c657312540a127472616e73616374696f6e5f747261636573180a2003280b32252e73662e657468657265756d2e747970652e76322e5472616e73616374696f6e547261636552117472616e73616374696f6e547261636573124b0a0f62616c616e63655f6368616e676573180b2003280b32222e73662e657468657265756d2e747970652e76322e42616c616e63654368616e6765520e62616c616e63654368616e67657312490a0c64657461696c5f6c6576656c180c2001280e32262e73662e657468657265756d2e747970652e76322e426c6f636b2e44657461696c4c6576656c520b64657461696c4c6576656c12420a0c636f64655f6368616e67657318142003280b321f2e73662e657468657265756d2e747970652e76322e436f64654368616e6765520b636f64654368616e676573123c0a0c73797374656d5f63616c6c7318152003280b32192e73662e657468657265756d2e747970652e76322e43616c6c520b73797374656d43616c6c7312100a037665721801200128055203766572223d0a0b44657461696c4c6576656c12180a1444455441494c4c4556454c5f455854454e444544100012140a1044455441494c4c4556454c5f4241534510024a04082810294a040829102a4a04082a102b22d2070a0b426c6f636b486561646572121f0a0b706172656e745f6861736818012001280c520a706172656e7448617368121d0a0a756e636c655f6861736818022001280c5209756e636c6548617368121a0a08636f696e6261736518032001280c5208636f696e62617365121d0a0a73746174655f726f6f7418042001280c52097374617465526f6f74122b0a117472616e73616374696f6e735f726f6f7418052001280c52107472616e73616374696f6e73526f6f7412210a0c726563656970745f726f6f7418062001280c520b72656365697074526f6f74121d0a0a6c6f67735f626c6f6f6d18072001280c52096c6f6773426c6f6f6d123b0a0a646966666963756c747918082001280b321b2e73662e657468657265756d2e747970652e76322e426967496e74520a646966666963756c747912460a10746f74616c5f646966666963756c747918112001280b321b2e73662e657468657265756d2e747970652e76322e426967496e74520f746f74616c446966666963756c747912160a066e756d62657218092001280452066e756d626572121b0a096761735f6c696d6974180a2001280452086761734c696d697412190a086761735f75736564180b2001280452076761735573656412380a0974696d657374616d70180c2001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d70520974696d657374616d70121d0a0a65787472615f64617461180d2001280c520965787472614461746112190a086d69785f68617368180e2001280c52076d69784861736812140a056e6f6e6365180f2001280452056e6f6e636512120a046861736818102001280c52046861736812440a10626173655f6665655f7065725f67617318122001280b321b2e73662e657468657265756d2e747970652e76322e426967496e74520d6261736546656550657247617312290a107769746864726177616c735f726f6f7418132001280c520f7769746864726177616c73526f6f74124b0a0d74785f646570656e64656e637918142001280b32262e73662e657468657265756d2e747970652e76322e55696e7436344e65737465644172726179520c7478446570656e64656e637912270a0d626c6f625f6761735f757365641816200128044800520b626c6f6247617355736564880101122b0a0f6578636573735f626c6f625f6761731817200128044801520d657863657373426c6f62476173880101122c0a12706172656e745f626561636f6e5f726f6f7418182001280c5210706172656e74426561636f6e526f6f7442100a0e5f626c6f625f6761735f7573656442120a105f6578636573735f626c6f625f67617322470a1155696e7436344e6573746564417272617912320a0376616c18012003280b32202e73662e657468657265756d2e747970652e76322e55696e7436344172726179520376616c221f0a0b55696e743634417272617912100a0376616c180120032804520376616c221e0a06426967496e7412140a05627974657318012001280c5205627974657322ab0b0a105472616e73616374696f6e5472616365120e0a02746f18012001280c5202746f12140a056e6f6e636518022001280452056e6f6e636512380a096761735f707269636518032001280b321b2e73662e657468657265756d2e747970652e76322e426967496e7452086761735072696365121b0a096761735f6c696d697418042001280452086761734c696d697412310a0576616c756518052001280b321b2e73662e657468657265756d2e747970652e76322e426967496e74520576616c756512140a05696e70757418062001280c5205696e707574120c0a017618072001280c520176120c0a017218082001280c520172120c0a017318092001280c52017312190a086761735f75736564180a20012804520767617355736564123e0a0474797065180c2001280e322a2e73662e657468657265756d2e747970652e76322e5472616e73616374696f6e54726163652e5479706552047479706512410a0b6163636573735f6c697374180e2003280b32202e73662e657468657265756d2e747970652e76322e4163636573735475706c65520a6163636573734c69737412420a0f6d61785f6665655f7065725f676173180b2001280b321b2e73662e657468657265756d2e747970652e76322e426967496e74520c6d617846656550657247617312530a186d61785f7072696f726974795f6665655f7065725f676173180d2001280b321b2e73662e657468657265756d2e747970652e76322e426967496e7452146d61785072696f7269747946656550657247617312140a05696e64657818142001280d5205696e64657812120a046861736818152001280c52046861736812120a0466726f6d18162001280c520466726f6d121f0a0b72657475726e5f6461746118172001280c520a72657475726e44617461121d0a0a7075626c69635f6b657918182001280c52097075626c69634b657912230a0d626567696e5f6f7264696e616c181920012804520c626567696e4f7264696e616c121f0a0b656e645f6f7264696e616c181a20012804520a656e644f7264696e616c12430a06737461747573181e2001280e322b2e73662e657468657265756d2e747970652e76322e5472616e73616374696f6e5472616365537461747573520673746174757312410a0772656365697074181f2001280b32272e73662e657468657265756d2e747970652e76322e5472616e73616374696f6e52656365697074520772656365697074122f0a0563616c6c7318202003280b32192e73662e657468657265756d2e747970652e76322e43616c6c520563616c6c73121e0a08626c6f625f67617318212001280448005207626c6f6247617388010112490a10626c6f625f6761735f6665655f63617018222001280b321b2e73662e657468657265756d2e747970652e76322e426967496e744801520d626c6f62476173466565436170880101121f0a0b626c6f625f68617368657318232003280c520a626c6f6248617368657322c4020a045479706512130a0f5452585f545950455f4c4547414359100012180a145452585f545950455f4143434553535f4c495354100112180a145452585f545950455f44594e414d49435f464545100212110a0d5452585f545950455f424c4f421003121d0a195452585f545950455f415242495452554d5f4445504f5349541064121e0a1a5452585f545950455f415242495452554d5f554e5349474e45441065121e0a1a5452585f545950455f415242495452554d5f434f4e54524143541066121b0a175452585f545950455f415242495452554d5f5245545259106812260a225452585f545950455f415242495452554d5f5355424d49545f524554525941424c451069121e0a1a5452585f545950455f415242495452554d5f494e5445524e414c106a121c0a185452585f545950455f415242495452554d5f4c45474143591078420b0a095f626c6f625f67617342130a115f626c6f625f6761735f6665655f636170224a0a0b4163636573735475706c6512180a076164647265737318012001280c52076164647265737312210a0c73746f726167655f6b65797318022003280c520b73746f726167654b65797322c6020a125472616e73616374696f6e52656365697074121d0a0a73746174655f726f6f7418012001280c52097374617465526f6f74122e0a1363756d756c61746976655f6761735f75736564180220012804521163756d756c617469766547617355736564121d0a0a6c6f67735f626c6f6f6d18032001280c52096c6f6773426c6f6f6d122c0a046c6f677318042003280b32182e73662e657468657265756d2e747970652e76322e4c6f6752046c6f677312270a0d626c6f625f6761735f757365641805200128044800520b626c6f624761735573656488010112460a0e626c6f625f6761735f707269636518062001280b321b2e73662e657468657265756d2e747970652e76322e426967496e744801520c626c6f62476173507269636588010142100a0e5f626c6f625f6761735f7573656442110a0f5f626c6f625f6761735f7072696365229b010a034c6f6712180a076164647265737318012001280c52076164647265737312160a06746f7069637318022003280c5206746f7069637312120a046461746118032001280c52046461746112140a05696e64657818042001280d5205696e646578121e0a0a626c6f636b496e64657818062001280d520a626c6f636b496e64657812180a076f7264696e616c18072001280452076f7264696e616c22b20a0a0443616c6c12140a05696e64657818012001280d5205696e64657812210a0c706172656e745f696e64657818022001280d520b706172656e74496e64657812140a05646570746818032001280d52056465707468123a0a0963616c6c5f7479706518042001280e321d2e73662e657468657265756d2e747970652e76322e43616c6c54797065520863616c6c5479706512160a0663616c6c657218052001280c520663616c6c657212180a076164647265737318062001280c52076164647265737312310a0576616c756518072001280b321b2e73662e657468657265756d2e747970652e76322e426967496e74520576616c7565121b0a096761735f6c696d697418082001280452086761734c696d697412210a0c6761735f636f6e73756d6564180920012804520b676173436f6e73756d6564121f0a0b72657475726e5f64617461180d2001280c520a72657475726e4461746112140a05696e707574180e2001280c5205696e70757412230a0d65786563757465645f636f6465180f20012808520c6578656375746564436f646512180a077375696369646518102001280852077375696369646512590a106b656363616b5f707265696d6167657318142003280b322e2e73662e657468657265756d2e747970652e76322e43616c6c2e4b656363616b507265696d61676573456e747279520f6b656363616b507265696d61676573124b0a0f73746f726167655f6368616e67657318152003280b32222e73662e657468657265756d2e747970652e76322e53746f726167654368616e6765520e73746f726167654368616e676573124b0a0f62616c616e63655f6368616e67657318162003280b32222e73662e657468657265756d2e747970652e76322e42616c616e63654368616e6765520e62616c616e63654368616e67657312450a0d6e6f6e63655f6368616e67657318182003280b32202e73662e657468657265756d2e747970652e76322e4e6f6e63654368616e6765520c6e6f6e63654368616e676573122c0a046c6f677318192003280b32182e73662e657468657265756d2e747970652e76322e4c6f6752046c6f677312420a0c636f64655f6368616e676573181a2003280b321f2e73662e657468657265756d2e747970652e76322e436f64654368616e6765520b636f64654368616e676573123f0a0b6761735f6368616e676573181c2003280b321e2e73662e657468657265756d2e747970652e76322e4761734368616e6765520a6761734368616e67657312230a0d7374617475735f6661696c6564180a20012808520c7374617475734661696c656412270a0f7374617475735f7265766572746564180c20012808520e737461747573526576657274656412250a0e6661696c7572655f726561736f6e180b20012809520d6661696c757265526561736f6e12250a0e73746174655f7265766572746564181e20012808520d7374617465526576657274656412230a0d626567696e5f6f7264696e616c181f20012804520c626567696e4f7264696e616c121f0a0b656e645f6f7264696e616c182020012804520a656e644f7264696e616c12510a116163636f756e745f6372656174696f6e7318212003280b32242e73662e657468657265756d2e747970652e76322e4163636f756e744372656174696f6e52106163636f756e744372656174696f6e731a420a144b656363616b507265696d61676573456e74727912100a036b657918012001280952036b657912140a0576616c7565180220012809520576616c75653a0238014a04081b101c4a04081d101e4a04083210334a04083310344a04083c103d228f010a0d53746f726167654368616e676512180a076164647265737318012001280c52076164647265737312100a036b657918022001280c52036b6579121b0a096f6c645f76616c756518032001280c52086f6c6456616c7565121b0a096e65775f76616c756518042001280c52086e657756616c756512180a076f7264696e616c18052001280452076f7264696e616c22cc050a0d42616c616e63654368616e676512180a076164647265737318012001280c52076164647265737312380a096f6c645f76616c756518022001280b321b2e73662e657468657265756d2e747970652e76322e426967496e7452086f6c6456616c756512380a096e65775f76616c756518032001280b321b2e73662e657468657265756d2e747970652e76322e426967496e7452086e657756616c756512410a06726561736f6e18042001280e32292e73662e657468657265756d2e747970652e76322e42616c616e63654368616e67652e526561736f6e5206726561736f6e12180a076f7264696e616c18052001280452076f7264696e616c22cf030a06526561736f6e12120a0e524541534f4e5f554e4b4e4f574e1000121c0a18524541534f4e5f5245574152445f4d494e455f554e434c451001121c0a18524541534f4e5f5245574152445f4d494e455f424c4f434b1002121e0a1a524541534f4e5f44414f5f524546554e445f434f4e54524143541003121d0a19524541534f4e5f44414f5f41444a5553545f42414c414e4345100412130a0f524541534f4e5f5452414e534645521005121a0a16524541534f4e5f47454e455349535f42414c414e4345100612120a0e524541534f4e5f4741535f425559100712210a1d524541534f4e5f5245574152445f5452414e53414354494f4e5f4645451008121b0a17524541534f4e5f5245574152445f4645455f5245534554100e12150a11524541534f4e5f4741535f524546554e44100912180a14524541534f4e5f544f5543485f4143434f554e54100a12190a15524541534f4e5f535549434944455f524546554e44100b121b0a17524541534f4e5f535549434944455f5749544844524157100d12200a1c524541534f4e5f43414c4c5f42414c414e43455f4f56455252494445100c120f0a0b524541534f4e5f4255524e100f12150a11524541534f4e5f5749544844524157414c1010227b0a0b4e6f6e63654368616e676512180a076164647265737318012001280c520761646472657373121b0a096f6c645f76616c756518022001280452086f6c6456616c7565121b0a096e65775f76616c756518032001280452086e657756616c756512180a076f7264696e616c18042001280452076f7264696e616c22450a0f4163636f756e744372656174696f6e12180a076163636f756e7418012001280c52076163636f756e7412180a076f7264696e616c18022001280452076f7264696e616c22ac010a0a436f64654368616e676512180a076164647265737318012001280c52076164647265737312190a086f6c645f6861736818022001280c52076f6c644861736812190a086f6c645f636f646518032001280c52076f6c64436f646512190a086e65775f6861736818042001280c52076e65774861736812190a086e65775f636f646518052001280c52076e6577436f646512180a076f7264696e616c18062001280452076f7264696e616c22e0060a094761734368616e6765121b0a096f6c645f76616c756518012001280452086f6c6456616c7565121b0a096e65775f76616c756518022001280452086e657756616c7565123d0a06726561736f6e18032001280e32252e73662e657468657265756d2e747970652e76322e4761734368616e67652e526561736f6e5206726561736f6e12180a076f7264696e616c18042001280452076f7264696e616c22bf050a06526561736f6e12120a0e524541534f4e5f554e4b4e4f574e1000120f0a0b524541534f4e5f43414c4c100112140a10524541534f4e5f43414c4c5f434f4445100212190a15524541534f4e5f43414c4c5f444154415f434f5059100312140a10524541534f4e5f434f44455f434f5059100412170a13524541534f4e5f434f44455f53544f524147451005121c0a18524541534f4e5f434f4e54524143545f4352454154494f4e1006121d0a19524541534f4e5f434f4e54524143545f4352454154494f4e32100712180a14524541534f4e5f44454c45474154455f43414c4c100812140a10524541534f4e5f4556454e545f4c4f47100912180a14524541534f4e5f4558545f434f44455f434f5059100a121b0a17524541534f4e5f4641494c45445f455845435554494f4e100b12180a14524541534f4e5f494e5452494e5349435f474153100c121f0a1b524541534f4e5f505245434f4d50494c45445f434f4e5452414354100d12210a1d524541534f4e5f524546554e445f41465445525f455845435554494f4e100e12110a0d524541534f4e5f52455455524e100f121b0a17524541534f4e5f52455455524e5f444154415f434f5059101012110a0d524541534f4e5f524556455254101112180a14524541534f4e5f53454c465f4445535452554354101212160a12524541534f4e5f5354415449435f43414c4c1013121c0a18524541534f4e5f53544154455f434f4c445f4143434553531014121d0a19524541534f4e5f54585f494e495449414c5f42414c414e4345101512150a11524541534f4e5f54585f524546554e4453101612200a1c524541534f4e5f54585f4c4546545f4f5645525f52455455524e45441017121f0a1b524541534f4e5f43414c4c5f494e495449414c5f42414c414e4345101812220a1e524541534f4e5f43414c4c5f4c4546545f4f5645525f52455455524e45441019224b0a0f4865616465724f6e6c79426c6f636b12380a0668656164657218052001280b32202e73662e657468657265756d2e747970652e76322e426c6f636b486561646572520668656164657222d1010a0d426c6f636b5769746852656673120e0a0269641801200128095202696412300a05626c6f636b18022001280b321a2e73662e657468657265756d2e747970652e76322e426c6f636b5205626c6f636b125a0a167472616e73616374696f6e5f74726163655f7265667318032001280b32242e73662e657468657265756d2e747970652e76322e5472616e73616374696f6e5265667352147472616e73616374696f6e54726163655265667312220a0c697272657665727369626c65180420012808520c697272657665727369626c652297010a1c5472616e73616374696f6e547261636557697468426c6f636b526566123b0a05747261636518012001280b32252e73662e657468657265756d2e747970652e76322e5472616e73616374696f6e547261636552057472616365123a0a09626c6f636b5f72656618022001280b321d2e73662e657468657265756d2e747970652e76322e426c6f636b5265665208626c6f636b52656622290a0f5472616e73616374696f6e5265667312160a0668617368657318012003280c520668617368657322360a08426c6f636b52656612120a046861736818012001280c52046861736812160a066e756d62657218022001280452066e756d6265722a4e0a165472616e73616374696f6e5472616365537461747573120b0a07554e4b4e4f574e1000120d0a095355434345454445441001120a0a064641494c45441002120c0a08524556455254454410032a590a0843616c6c54797065120f0a0b554e535045434946494544100012080a0443414c4c1001120c0a0843414c4c434f44451002120c0a0844454c45474154451003120a0a065354415449431004120a0a064352454154451005424f5a4d6769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d657468657265756d2f74797065732f70622f73662f657468657265756d2f747970652f76323b7062657468620670726f746f33", @@ -42,9 +42,6 @@ func GetWellKnownFileDescriptors() ([]protoreflect.FileDescriptor, error) { // sf/solana/type/v1/type.proto (https://buf.build/streamingfast/firehose-solana/docs/7e16dd37d68049d1a3f548203be431d7:sf.solana.type.v1) "0a1c73662f736f6c616e612f747970652f76312f747970652e70726f746f121173662e736f6c616e612e747970652e7631228f030a05426c6f636b122d0a1270726576696f75735f626c6f636b68617368180120012809521170726576696f7573426c6f636b68617368121c0a09626c6f636b686173681802200128095209626c6f636b68617368121f0a0b706172656e745f736c6f74180320012804520a706172656e74536c6f74124b0a0c7472616e73616374696f6e7318042003280b32272e73662e736f6c616e612e747970652e76312e436f6e6669726d65645472616e73616374696f6e520c7472616e73616374696f6e7312330a077265776172647318052003280b32192e73662e736f6c616e612e747970652e76312e526577617264520772657761726473123f0a0a626c6f636b5f74696d6518062001280b32202e73662e736f6c616e612e747970652e76312e556e697854696d657374616d705209626c6f636b54696d6512410a0c626c6f636b5f68656967687418072001280b321e2e73662e736f6c616e612e747970652e76312e426c6f636b486569676874520b626c6f636b48656967687412120a04736c6f741814200128045204736c6f742296010a14436f6e6669726d65645472616e73616374696f6e12400a0b7472616e73616374696f6e18012001280b321e2e73662e736f6c616e612e747970652e76312e5472616e73616374696f6e520b7472616e73616374696f6e123c0a046d65746118022001280b32282e73662e736f6c616e612e747970652e76312e5472616e73616374696f6e5374617475734d65746152046d65746122630a0b5472616e73616374696f6e121e0a0a7369676e61747572657318012003280c520a7369676e61747572657312340a076d65737361676518022001280b321a2e73662e736f6c616e612e747970652e76312e4d65737361676552076d65737361676522dd020a074d65737361676512380a0668656164657218012001280b32202e73662e736f6c616e612e747970652e76312e4d657373616765486561646572520668656164657212210a0c6163636f756e745f6b65797318022003280c520b6163636f756e744b65797312290a10726563656e745f626c6f636b6861736818032001280c520f726563656e74426c6f636b68617368124a0a0c696e737472756374696f6e7318042003280b32262e73662e736f6c616e612e747970652e76312e436f6d70696c6564496e737472756374696f6e520c696e737472756374696f6e73121c0a0976657273696f6e6564180520012808520976657273696f6e656412600a15616464726573735f7461626c655f6c6f6f6b75707318062003280b322c2e73662e736f6c616e612e747970652e76312e4d657373616765416464726573735461626c654c6f6f6b75705213616464726573735461626c654c6f6f6b75707322cd010a0d4d65737361676548656164657212360a176e756d5f72657175697265645f7369676e61747572657318012001280d52156e756d52657175697265645369676e617475726573123f0a1c6e756d5f726561646f6e6c795f7369676e65645f6163636f756e747318022001280d52196e756d526561646f6e6c795369676e65644163636f756e747312430a1e6e756d5f726561646f6e6c795f756e7369676e65645f6163636f756e747318032001280d521b6e756d526561646f6e6c79556e7369676e65644163636f756e74732292010a194d657373616765416464726573735461626c654c6f6f6b7570121f0a0b6163636f756e745f6b657918012001280c520a6163636f756e744b657912290a107772697461626c655f696e646578657318022001280c520f7772697461626c65496e646578657312290a10726561646f6e6c795f696e646578657318032001280c520f726561646f6e6c79496e64657865732283060a155472616e73616374696f6e5374617475734d65746112350a0365727218012001280b32232e73662e736f6c616e612e747970652e76312e5472616e73616374696f6e4572726f72520365727212100a03666565180220012804520366656512210a0c7072655f62616c616e636573180320032804520b70726542616c616e63657312230a0d706f73745f62616c616e636573180420032804520c706f737442616c616e63657312530a12696e6e65725f696e737472756374696f6e7318052003280b32242e73662e736f6c616e612e747970652e76312e496e6e6572496e737472756374696f6e735211696e6e6572496e737472756374696f6e7312210a0c6c6f675f6d65737361676573180620032809520b6c6f674d65737361676573124d0a127072655f746f6b656e5f62616c616e63657318072003280b321f2e73662e736f6c616e612e747970652e76312e546f6b656e42616c616e63655210707265546f6b656e42616c616e636573124f0a13706f73745f746f6b656e5f62616c616e63657318082003280b321f2e73662e736f6c616e612e747970652e76312e546f6b656e42616c616e63655211706f7374546f6b656e42616c616e63657312330a077265776172647318092003280b32192e73662e736f6c616e612e747970652e76312e526577617264520772657761726473123a0a196c6f616465645f7772697461626c655f616464726573736573180c2003280c52176c6f616465645772697461626c65416464726573736573123a0a196c6f616465645f726561646f6e6c795f616464726573736573180d2003280c52176c6f61646564526561646f6e6c79416464726573736573123e0a0b72657475726e5f64617461180e2001280b321d2e73662e736f6c616e612e747970652e76312e52657475726e44617461520a72657475726e4461746112390a16636f6d707574655f756e6974735f636f6e73756d656418102001280448005214636f6d70757465556e697473436f6e73756d656488010142190a175f636f6d707574655f756e6974735f636f6e73756d656422240a105472616e73616374696f6e4572726f7212100a0365727218012001280c520365727222720a11496e6e6572496e737472756374696f6e7312140a05696e64657818012001280d5205696e64657812470a0c696e737472756374696f6e7318022003280b32232e73662e736f6c616e612e747970652e76312e496e6e6572496e737472756374696f6e520c696e737472756374696f6e7322a5010a10496e6e6572496e737472756374696f6e12280a1070726f6772616d5f69645f696e64657818012001280d520e70726f6772616d4964496e646578121a0a086163636f756e747318022001280c52086163636f756e747312120a046461746118032001280c52046461746112260a0c737461636b5f68656967687418042001280d4800520b737461636b486569676874880101420f0a0d5f737461636b5f686569676874226f0a13436f6d70696c6564496e737472756374696f6e12280a1070726f6772616d5f69645f696e64657818012001280d520e70726f6772616d4964496e646578121a0a086163636f756e747318022001280c52086163636f756e747312120a046461746118032001280c52046461746122c6010a0c546f6b656e42616c616e636512230a0d6163636f756e745f696e64657818012001280d520c6163636f756e74496e64657812120a046d696e7418022001280952046d696e7412480a0f75695f746f6b656e5f616d6f756e7418032001280b32202e73662e736f6c616e612e747970652e76312e5569546f6b656e416d6f756e74520d7569546f6b656e416d6f756e7412140a056f776e657218042001280952056f776e6572121d0a0a70726f6772616d5f6964180520012809520970726f6772616d4964228a010a0d5569546f6b656e416d6f756e74121b0a0975695f616d6f756e7418012001280152087569416d6f756e74121a0a08646563696d616c7318022001280d5208646563696d616c7312160a06616d6f756e741803200128095206616d6f756e7412280a1075695f616d6f756e745f737472696e67180420012809520e7569416d6f756e74537472696e67223f0a0a52657475726e44617461121d0a0a70726f6772616d5f696418012001280c520970726f6772616d496412120a046461746118022001280c52046461746122bf010a0652657761726412160a067075626b657918012001280952067075626b6579121a0a086c616d706f72747318022001280352086c616d706f72747312210a0c706f73745f62616c616e6365180320012804520b706f737442616c616e6365123e0a0b7265776172645f7479706518042001280e321d2e73662e736f6c616e612e747970652e76312e52657761726454797065520a72657761726454797065121e0a0a636f6d6d697373696f6e180520012809520a636f6d6d697373696f6e223e0a075265776172647312330a077265776172647318012003280b32192e73662e736f6c616e612e747970652e76312e526577617264520772657761726473222d0a0d556e697854696d657374616d70121c0a0974696d657374616d70180120012803520974696d657374616d7022300a0b426c6f636b48656967687412210a0c626c6f636b5f686569676874180120012804520b626c6f636b4865696768742a490a0a52657761726454797065120f0a0b556e737065636966696564100012070a03466565100112080a0452656e741002120b0a075374616b696e671003120a0a06566f74696e67100442455a436769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d736f6c616e612f70622f73662f736f6c616e612f747970652f76313b7062736f6c620670726f746f33", - // google/protobuf/timestamp.proto (https://buf.build/streamingfast/firehose-bitcoin/docs/0d8ce32fe71441df82c89dcccda35366:google.protobuf) - "0a1f676f6f676c652f70726f746f6275662f74696d657374616d702e70726f746f120f676f6f676c652e70726f746f627566223b0a0954696d657374616d7012180a077365636f6e647318012001280352077365636f6e647312140a056e616e6f7318022001280552056e616e6f734285010a13636f6d2e676f6f676c652e70726f746f627566420e54696d657374616d7050726f746f50015a32676f6f676c652e676f6c616e672e6f72672f70726f746f6275662f74797065732f6b6e6f776e2f74696d657374616d707062f80101a20203475042aa021e476f6f676c652e50726f746f6275662e57656c6c4b6e6f776e5479706573620670726f746f33", - // sf/bitcoin/type/v1/type.proto (https://buf.build/streamingfast/firehose-bitcoin/docs/0d8ce32fe71441df82c89dcccda35366:sf.bitcoin.type.v1) "0a1d73662f626974636f696e2f747970652f76312f747970652e70726f746f121273662e626974636f696e2e747970652e76311a1f676f6f676c652f70726f746f6275662f74696d657374616d702e70726f746f22e5030a05426c6f636b12120a046861736818012001280952046861736812120a0473697a65180320012805520473697a6512230a0d73747269707065645f73697a65180420012805520c737472697070656453697a6512160a06776569676874180520012805520677656967687412160a06686569676874180620012803520668656967687412180a0776657273696f6e180720012805520776657273696f6e121f0a0b76657273696f6e5f686578180820012809520a76657273696f6e486578121f0a0b6d65726b6c655f726f6f74180920012809520a6d65726b6c65526f6f74122f0a027478180a2003280b321f2e73662e626974636f696e2e747970652e76312e5472616e73616374696f6e5202747812120a0474696d65180b20012803520474696d65121e0a0a6d656469616e74696d65180c20012803520a6d656469616e74696d6512140a056e6f6e6365180d2001280d52056e6f6e636512120a0462697473180e20012809520462697473121e0a0a646966666963756c7479180f20012801520a646966666963756c7479121c0a09636861696e776f726b1810200128095209636861696e776f726b12110a046e5f747818112001280d52036e547812230a0d70726576696f75735f68617368181220012809520c70726576696f75734861736822d4020a0b5472616e73616374696f6e12100a03686578180120012809520368657812120a047478696418022001280952047478696412120a046861736818032001280952046861736812120a0473697a65180420012805520473697a6512140a057673697a6518052001280552057673697a6512160a06776569676874180620012805520677656967687412180a0776657273696f6e18072001280d520776657273696f6e121a0a086c6f636b74696d6518082001280d52086c6f636b74696d6512290a0376696e18092003280b32172e73662e626974636f696e2e747970652e76312e56696e520376696e122c0a04766f7574180a2003280b32182e73662e626974636f696e2e747970652e76312e566f75745204766f7574121c0a09626c6f636b68617368180b200128095209626c6f636b68617368121c0a09626c6f636b74696d65180c200128035209626c6f636b74696d6522c5010a0356696e12120a047478696418012001280952047478696412120a04766f757418022001280d5204766f7574123c0a0a7363726970745f73696718032001280b321d2e73662e626974636f696e2e747970652e76312e5363726970745369675209736372697074536967121a0a0873657175656e636518042001280d520873657175656e636512200a0b7478696e7769746e657373180520032809520b7478696e7769746e657373121a0a08636f696e626173651806200128095208636f696e6261736522710a04566f757412140a0576616c7565180120012801520576616c7565120c0a016e18022001280d52016e12450a0d7363726970745f7075624b657918032001280b32202e73662e626974636f696e2e747970652e76312e5363726970745075624b6579520c7363726970745075624b6579222f0a0953637269707453696712100a0361736d180120012809520361736d12100a0368657818022001280952036865782299010a0c5363726970745075624b657912100a0361736d180120012809520361736d12100a03686578180220012809520368657812190a087265715f7369677318032001280552077265715369677312120a047479706518042001280952047479706512180a0761646472657373180520012809520761646472657373121c0a096164647265737365731806200328095209616464726573736573424d5a4b6769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d626974636f696e2f74797065732f70622f73662f626974636f696e2f747970652f76313b7062627463620670726f746f33", @@ -58,15 +55,18 @@ func GetWellKnownFileDescriptors() ([]protoreflect.FileDescriptor, error) { "0a1d73662f617277656176652f747970652f76312f747970652e70726f746f121273662e617277656176652e747970652e7631221e0a06426967496e7412140a05627974657318012001280c5205627974657322a6060a05426c6f636b12100a0376657218012001280d5203766572121d0a0a696e6465705f6861736818022001280c5209696e6465704861736812140a056e6f6e636518032001280c52056e6f6e636512250a0e70726576696f75735f626c6f636b18042001280c520d70726576696f7573426c6f636b121c0a0974696d657374616d70180520012804520974696d657374616d7012230a0d6c6173745f7265746172676574180620012804520c6c6173745265746172676574122e0a046469666618072001280b321a2e73662e617277656176652e747970652e76312e426967496e7452046469666612160a06686569676874180820012804520668656967687412120a046861736818092001280c52046861736812170a0774785f726f6f74180a2001280c52067478526f6f7412310a03747873180b2003280b321f2e73662e617277656176652e747970652e76312e5472616e73616374696f6e5203747873121f0a0b77616c6c65745f6c697374180c2001280c520a77616c6c65744c697374121f0a0b7265776172645f61646472180d2001280c520a72657761726441646472122b0a0474616773180e2003280b32172e73662e617277656176652e747970652e76312e546167520474616773123b0a0b7265776172645f706f6f6c180f2001280b321a2e73662e617277656176652e747970652e76312e426967496e74520a726577617264506f6f6c12390a0a77656176655f73697a6518102001280b321a2e73662e617277656176652e747970652e76312e426967496e745209776561766553697a6512390a0a626c6f636b5f73697a6518112001280b321a2e73662e617277656176652e747970652e76312e426967496e745209626c6f636b53697a6512430a0f63756d756c61746976655f6469666618122001280b321a2e73662e617277656176652e747970652e76312e426967496e74520e63756d756c61746976654469666612280a10686173685f6c6973745f6d65726b6c6518142001280c520e686173684c6973744d65726b6c6512330a03706f6118152001280b32212e73662e617277656176652e747970652e76312e50726f6f664f664163636573735203706f6122730a0d50726f6f664f6641636365737312160a066f7074696f6e18012001280952066f7074696f6e12170a0774785f7061746818022001280c5206747850617468121b0a09646174615f7061746818032001280c5208646174615061746812140a056368756e6b18042001280c52056368756e6b229d030a0b5472616e73616374696f6e12160a06666f726d617418012001280d5206666f726d6174120e0a02696418022001280c5202696412170a076c6173745f747818032001280c52066c617374547812140a056f776e657218042001280c52056f776e6572122b0a047461677318052003280b32172e73662e617277656176652e747970652e76312e54616752047461677312160a0674617267657418062001280c520674617267657412360a087175616e7469747918072001280b321a2e73662e617277656176652e747970652e76312e426967496e7452087175616e7469747912120a046461746118082001280c52046461746112370a09646174615f73697a6518092001280b321a2e73662e617277656176652e747970652e76312e426967496e7452086461746153697a65121b0a09646174615f726f6f74180a2001280c520864617461526f6f74121c0a097369676e6174757265180b2001280c52097369676e617475726512320a06726577617264180c2001280b321a2e73662e617277656176652e747970652e76312e426967496e745206726577617264222f0a0354616712120a046e616d6518012001280c52046e616d6512140a0576616c756518022001280c520576616c756542515a4f6769746875622e636f6d2f70696e61782d6e6574776f726b2f66697265686f73652d617277656176652f74797065732f70622f73662f617277656176652f747970652f76313b706261727765617665620670726f746f33", } - var out []protoreflect.FileDescriptor for _, protoFile := range protoFiles { fd, err := protoToFileDescriptor(protoFile) if err != nil { - return nil, fmt.Errorf("generating proto file: %w", err) + return fmt.Errorf("generating proto file: %w", err) + } + err = RegisterFileDescriptor(fd) + if err != nil { + return fmt.Errorf("registering file descriptor: %w", err) } - out = append(out, fd) + } - return out, nil + return nil } func protoToFileDescriptor(in string) (protoreflect.FileDescriptor, error) { @@ -80,9 +80,10 @@ func protoToFileDescriptor(in string) (protoreflect.FileDescriptor, error) { return nil, fmt.Errorf("failed to unmarshal file descriptor: %w", err) } - fd, err := protodesc.NewFile(fileDescriptorProto, nil) + fd, err := protodesc.NewFile(fileDescriptorProto, protoregistry.GlobalFiles) if err != nil { - log.Fatalf("Failed to create file descriptor: %v", err) + return nil, fmt.Errorf("creating new file descriptor: %w", err) + } return fd, nil } From 00d5504a58986918e1dc4158a2320b306bff4800 Mon Sep 17 00:00:00 2001 From: billettc Date: Tue, 23 Jan 2024 12:03:26 -0500 Subject: [PATCH 08/44] print dynamicpb using go-json-experiment --- cmd/tools/compare/tools_compare_blocks.go | 21 ++------- cmd/tools/print/tools_print.go | 7 ++- jsonencoder/encoder.go | 7 ++- jsonencoder/marshallers.go | 53 ++++++++++++++++++++++- 4 files changed, 68 insertions(+), 20 deletions(-) diff --git a/cmd/tools/compare/tools_compare_blocks.go b/cmd/tools/compare/tools_compare_blocks.go index 8c63141..d41c7f6 100644 --- a/cmd/tools/compare/tools_compare_blocks.go +++ b/cmd/tools/compare/tools_compare_blocks.go @@ -24,6 +24,8 @@ import ( "strconv" "sync" + "github.com/davecgh/go-spew/spew" + jd "github.com/josephburnett/jd/lib" "github.com/spf13/cobra" "github.com/streamingfast/bstream" @@ -70,7 +72,6 @@ func NewToolsCompareBlocksCmd[B firecore.Block](chain *firecore.Chain[B]) *cobra flags := cmd.PersistentFlags() flags.Bool("diff", false, "When activated, difference is displayed for each block with a difference") flags.Bool("include-unknown-fields", false, "When activated, the 'unknown fields' in the protobuf message will also be compared. These would not generate any difference when unmarshalled with the current protobuf definition.") - flags.Bool("ignore-error-when-JSON-matches", false, "When activated, the reader will ignore error if the JSON representation of the block matches (which results in an empty diff file).") return cmd } @@ -81,7 +82,6 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm return func(cmd *cobra.Command, args []string) error { displayDiff := sflags.MustGetBool(cmd, "diff") ignoreUnknown := !sflags.MustGetBool(cmd, "include-unknown-fields") - ignoreEmptyDiff := sflags.MustGetBool(cmd, "ignore-error-when-JSON-matches") segmentSize := uint64(100000) warnAboutExtraBlocks := sync.Once{} @@ -114,9 +114,9 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm processState := &state{ segments: segments, } + err = storeReference.Walk(ctx, check.WalkBlockPrefix(blockRange, 100), func(filename string) (err error) { fileStartBlock, err := strconv.Atoi(filename) - if err != nil { return fmt.Errorf("parsing filename: %w", err) } @@ -147,7 +147,6 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm &warnAboutExtraBlocks, chain.BlockFactory, ) - if err != nil { bundleErrLock.Lock() bundleReadErr = multierr.Append(bundleReadErr, err) @@ -158,7 +157,6 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm wg.Add(1) go func() { defer wg.Done() - _, currentBlocks, err = readBundle(ctx, filename, storeCurrent, @@ -168,7 +166,6 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm &warnAboutExtraBlocks, chain.BlockFactory, ) - if err != nil { bundleErrLock.Lock() bundleReadErr = multierr.Append(bundleReadErr, err) @@ -188,12 +185,6 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm if existsInCurrent { var differences []string isEqual, differences = Compare(referenceBlock, currentBlock, ignoreUnknown) - - if ignoreEmptyDiff && len(differences) == 0 { - fmt.Printf("JSON representation of blocks referenceBlock %s identical, but not protobuf def, blocks are considered equal\n", firehoseBlockToRef(referenceBlock)) - isEqual = true - } - if !isEqual { fmt.Printf("- Block %s is different\n", firehoseBlockToRef(referenceBlock)) if displayDiff { @@ -244,9 +235,7 @@ func readBundle[B firecore.Block]( var blockHashes []string blocksMap := make(map[string]B) for { - curBlock, err := blockReader.Read() - if err == io.EOF { break } @@ -256,7 +245,6 @@ func readBundle[B firecore.Block]( if curBlock.Number >= stopBlock { break } - if curBlock.Number < fileStartBlock { warnAboutExtraBlocks.Do(func() { fmt.Printf("Warn: Bundle file %s contains block %d, preceding its start_block. This 'feature' is not used anymore and extra blocks like this one will be ignored during compare\n", store.ObjectURL(filename), curBlock.Number) @@ -266,12 +254,10 @@ func readBundle[B firecore.Block]( b := blockFactory() if err = curBlock.Payload.UnmarshalTo(b); err != nil { - return nil, nil, fmt.Errorf("unmarshalling block: %w", err) break } curBlockPB := sanitizer(b.(B)) - blockHashes = append(blockHashes, curBlock.Id) blocksMap[curBlock.Id] = curBlockPB } @@ -391,6 +377,7 @@ func Compare(reference, current proto.Message, ignoreUnknown bool) (isEqual bool } } } + spew.Dump(reference) if !proto.Equal(reference, current) { diff --git a/cmd/tools/print/tools_print.go b/cmd/tools/print/tools_print.go index baa1571..c90d980 100644 --- a/cmd/tools/print/tools_print.go +++ b/cmd/tools/print/tools_print.go @@ -237,7 +237,12 @@ func displayBlock[B firecore.Block](pbBlock *pbbstream.Block, chain *firecore.Ch } // since we are running directly the firecore binary we will *NOT* use the BlockFactory - return encoder.Marshal(pbBlock.Payload) + err := encoder.Marshal(pbBlock.Payload) + if err != nil { + return fmt.Errorf("marshalling block to json: %w", err) + } + + return nil } func PrintBStreamBlock(b *pbbstream.Block, printTransactions bool, out io.Writer) error { diff --git a/jsonencoder/encoder.go b/jsonencoder/encoder.go index e4ace25..cf5eaaf 100644 --- a/jsonencoder/encoder.go +++ b/jsonencoder/encoder.go @@ -2,6 +2,7 @@ package jsonencoder import ( "bytes" + "fmt" "os" "github.com/go-json-experiment/json" @@ -16,7 +17,11 @@ func New() *Encoder { } func (e *Encoder) Marshal(in any) error { - return json.MarshalEncode(jsontext.NewEncoder(os.Stdout), in, json.WithMarshalers(e.getMarshallers(""))) + err := json.MarshalEncode(jsontext.NewEncoder(os.Stdout), in, json.WithMarshalers(e.getMarshallers(""))) + if err != nil { + return fmt.Errorf("marshalling and encoding block to json: %w", err) + } + return nil } func (e *Encoder) MarshalToString(in any) (string, error) { diff --git a/jsonencoder/marshallers.go b/jsonencoder/marshallers.go index be015ec..cec6a3d 100644 --- a/jsonencoder/marshallers.go +++ b/jsonencoder/marshallers.go @@ -5,6 +5,10 @@ import ( "fmt" "strings" + "google.golang.org/protobuf/types/dynamicpb" + + "google.golang.org/protobuf/reflect/protoreflect" + "github.com/go-json-experiment/json" "github.com/go-json-experiment/json/jsontext" "github.com/jhump/protoreflect/dynamic" @@ -18,7 +22,6 @@ func (e *Encoder) anypb(encoder *jsontext.Encoder, t *anypb.Any, options json.Op if err != nil { return fmt.Errorf("unmarshalling proto any: %w", err) } - cnt, err := json.Marshal(msg, json.WithMarshalers(e.getMarshallers(t.TypeUrl))) if err != nil { return fmt.Errorf("json marshalling proto any: %w", err) @@ -26,6 +29,53 @@ func (e *Encoder) anypb(encoder *jsontext.Encoder, t *anypb.Any, options json.Op return encoder.WriteValue(cnt) } +func toValue(msg *dynamicpb.Message) map[string]any { + mapMsg := map[string]any{} + msg.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { + var value any + if fd.IsList() { + out := make([]any, v.List().Len()) + for i := 0; i < v.List().Len(); i++ { + out[i] = v.List().Get(i) + } + value = out + } else if fd.Kind() == protoreflect.MessageKind { + + } else { + value = v.Interface() + } + + mapMsg[string(fd.Name())] = value + return true + }) + return mapMsg +} + +func (e *Encoder) dynamicpbMessage(encoder *jsontext.Encoder, msg *dynamicpb.Message, options json.Options) error { + mapMsg := map[string]any{} + + mapMsg["__unknown_fields__"] = hex.EncodeToString(msg.GetUnknown()) + + msg.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { + if fd.IsList() { + out := make([]any, v.List().Len()) + for i := 0; i < v.List().Len(); i++ { + out[i] = v.List().Get(i).Interface() + } + mapMsg[string(fd.Name())] = out + return true + } + mapMsg[string(fd.Name())] = v.Interface() + return true + }) + + cnt, err := json.Marshal(mapMsg, json.WithMarshalers(e.getMarshallers("solana"))) + if err != nil { + return fmt.Errorf("json marshalling proto any: %w", err) + } + return encoder.WriteValue(cnt) +} + func (e *Encoder) base58Bytes(encoder *jsontext.Encoder, t []byte, options json.Options) error { return encoder.WriteToken(jsontext.String(base58.Encode(t))) } @@ -37,6 +87,7 @@ func (e *Encoder) hexBytes(encoder *jsontext.Encoder, t []byte, options json.Opt func (e *Encoder) getMarshallers(typeURL string) *json.Marshalers { out := []*json.Marshalers{ json.MarshalFuncV2(e.anypb), + json.MarshalFuncV2(e.dynamicpbMessage), } if strings.Contains(typeURL, "solana") { From ff7c6ec288d9cffff030f6cd0ff327ca21247deb Mon Sep 17 00:00:00 2001 From: arnaudberger Date: Tue, 23 Jan 2024 12:11:42 -0500 Subject: [PATCH 09/44] Using dynamic message to fix compare blocks tool # Conflicts: # cmd/tools/compare/tools_compare_blocks.go --- chain.go | 16 ----- cmd/tools/compare/tools_compare_blocks.go | 87 ++++++++++++++--------- 2 files changed, 54 insertions(+), 49 deletions(-) diff --git a/chain.go b/chain.go index caee946..05ae9ab 100644 --- a/chain.go +++ b/chain.go @@ -154,13 +154,6 @@ type Chain[B Block] struct { } type ToolsConfig[B Block] struct { - - // SanitizeBlockForCompare is a function that takes a chain agnostic [block] and transforms it in-place, removing fields - // that should not be compared. - // - // The [SanitizeBlockForCompare] is optional, if nil, no-op sanitizer be used. - SanitizeBlockForCompare SanitizeBlockForCompareFunc[B] - // RegisterExtraCmd enables you to register extra commands to the `fire tools` group. // The callback function is called with the `toolsCmd` command that is the root command of the `fire tools` // as well as the chain, the root logger and root tracer for tools. @@ -190,15 +183,6 @@ type ToolsConfig[B Block] struct { MergedBlockUpgrader func(block *pbbstream.Block) (*pbbstream.Block, error) } -// GetSanitizeBlockForCompare returns the [SanitizeBlockForCompare] value if defined, otherwise a no-op sanitizer. -func (t *ToolsConfig[B]) GetSanitizeBlockForCompare() SanitizeBlockForCompareFunc[B] { - if t == nil || t.SanitizeBlockForCompare == nil { - return func(block B) B { return block } - } - - return t.SanitizeBlockForCompare -} - type TransformFlags struct { // Register is a function that will be called when we need to register the flags for the transforms. // You received the command's flag set and you are responsible of registering the flags. diff --git a/cmd/tools/compare/tools_compare_blocks.go b/cmd/tools/compare/tools_compare_blocks.go index d41c7f6..e6bffb0 100644 --- a/cmd/tools/compare/tools_compare_blocks.go +++ b/cmd/tools/compare/tools_compare_blocks.go @@ -17,15 +17,14 @@ package compare import ( "bytes" "context" - "encoding/json" "fmt" "io" + "os" "reflect" "strconv" "sync" "github.com/davecgh/go-spew/spew" - jd "github.com/josephburnett/jd/lib" "github.com/spf13/cobra" "github.com/streamingfast/bstream" @@ -34,11 +33,14 @@ import ( "github.com/streamingfast/dstore" firecore "github.com/streamingfast/firehose-core" "github.com/streamingfast/firehose-core/cmd/tools/check" + "github.com/streamingfast/firehose-core/protoregistry" "github.com/streamingfast/firehose-core/types" "go.uber.org/multierr" + "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/types/dynamicpb" ) func NewToolsCompareBlocksCmd[B firecore.Block](chain *firecore.Chain[B]) *cobra.Command { @@ -72,19 +74,18 @@ func NewToolsCompareBlocksCmd[B firecore.Block](chain *firecore.Chain[B]) *cobra flags := cmd.PersistentFlags() flags.Bool("diff", false, "When activated, difference is displayed for each block with a difference") flags.Bool("include-unknown-fields", false, "When activated, the 'unknown fields' in the protobuf message will also be compared. These would not generate any difference when unmarshalled with the current protobuf definition.") + flags.StringSlice("proto-paths", []string{""}, "Paths to proto files to use for dynamic decoding of blocks") return cmd } func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.CommandExecutor { - sanitizer := chain.Tools.GetSanitizeBlockForCompare() - return func(cmd *cobra.Command, args []string) error { displayDiff := sflags.MustGetBool(cmd, "diff") - ignoreUnknown := !sflags.MustGetBool(cmd, "include-unknown-fields") + includeUnknownFields := !sflags.MustGetBool(cmd, "include-unknown-fields") + protoPaths := sflags.MustGetStringSlice(cmd, "proto-paths") segmentSize := uint64(100000) warnAboutExtraBlocks := sync.Once{} - ctx := cmd.Context() blockRange, err := types.GetBlockRangeFromArg(args[2]) if err != nil { @@ -131,21 +132,20 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm var bundleErrLock sync.Mutex var bundleReadErr error var referenceBlockHashes []string - var referenceBlocks map[string]B - var currentBlocks map[string]B + var referenceBlocks map[string]*dynamicpb.Message + var currentBlocks map[string]*dynamicpb.Message wg.Add(1) go func() { defer wg.Done() - referenceBlockHashes, referenceBlocks, err = readBundle[B]( + referenceBlockHashes, referenceBlocks, err = readBundle( ctx, filename, storeReference, uint64(fileStartBlock), stopBlock, - sanitizer, &warnAboutExtraBlocks, - chain.BlockFactory, + protoPaths, ) if err != nil { bundleErrLock.Lock() @@ -162,9 +162,8 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm storeCurrent, uint64(fileStartBlock), stopBlock, - sanitizer, &warnAboutExtraBlocks, - chain.BlockFactory, + protoPaths, ) if err != nil { bundleErrLock.Lock() @@ -180,13 +179,15 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm for _, referenceBlockHash := range referenceBlockHashes { referenceBlock := referenceBlocks[referenceBlockHash] currentBlock, existsInCurrent := currentBlocks[referenceBlockHash] + referenceBlockNum := referenceBlock.Get(referenceBlock.Descriptor().Fields().ByName("slot")).Uint() var isEqual bool if existsInCurrent { var differences []string - isEqual, differences = Compare(referenceBlock, currentBlock, ignoreUnknown) + isEqual, differences = Compare(referenceBlock, currentBlock, includeUnknownFields) + if !isEqual { - fmt.Printf("- Block %s is different\n", firehoseBlockToRef(referenceBlock)) + fmt.Printf("- Block %d is different\n", referenceBlockNum) if displayDiff { for _, diff := range differences { fmt.Println(" · ", diff) @@ -194,7 +195,8 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm } } } - processState.process(referenceBlock.GetFirehoseBlockNumber(), !isEqual, !existsInCurrent) + processState.process(referenceBlockNum, !isEqual, !existsInCurrent) + } } return nil @@ -208,20 +210,15 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm } } -func firehoseBlockToRef[B firecore.Block](b B) bstream.BlockRef { - return bstream.NewBlockRef(b.GetFirehoseBlockID(), b.GetFirehoseBlockNumber()) -} - -func readBundle[B firecore.Block]( +func readBundle( ctx context.Context, filename string, store dstore.Store, fileStartBlock, stopBlock uint64, - sanitizer firecore.SanitizeBlockForCompareFunc[B], warnAboutExtraBlocks *sync.Once, - blockFactory func() firecore.Block, -) ([]string, map[string]B, error) { + protoPaths []string, +) ([]string, map[string]*dynamicpb.Message, error) { fileReader, err := store.OpenObject(ctx, filename) if err != nil { return nil, nil, fmt.Errorf("creating reader: %w", err) @@ -233,7 +230,7 @@ func readBundle[B firecore.Block]( } var blockHashes []string - blocksMap := make(map[string]B) + blocksMap := make(map[string]*dynamicpb.Message) for { curBlock, err := blockReader.Read() if err == io.EOF { @@ -252,12 +249,16 @@ func readBundle[B firecore.Block]( continue } - b := blockFactory() - if err = curBlock.Payload.UnmarshalTo(b); err != nil { - break + err = protoregistry.Register(nil, protoPaths...) + + if err != nil { + return nil, nil, fmt.Errorf("protoregistry registry failed: %w", err) } + curBlockPB, err := protoregistry.Unmarshal(curBlock.Payload) - curBlockPB := sanitizer(b.(B)) + if err != nil { + return nil, nil, fmt.Errorf("unmarshalling block: %w", err) + } blockHashes = append(blockHashes, curBlock.Id) blocksMap[curBlock.Id] = curBlockPB } @@ -318,7 +319,7 @@ func (s *state) print() { fmt.Printf("✖ Segment %d - %s has %d different blocks and %d missing blocks (%d blocks counted)\n", s.segments[s.currentSegmentIdx].Start, endBlock, s.differencesFound, s.missingBlocks, s.totalBlocksCounted) } -func Compare(reference, current proto.Message, ignoreUnknown bool) (isEqual bool, differences []string) { +func Compare(reference proto.Message, current proto.Message, includeUnknownFields bool) (isEqual bool, differences []string) { if reference == nil && current == nil { return true, nil } @@ -335,7 +336,7 @@ func Compare(reference, current proto.Message, ignoreUnknown bool) (isEqual bool return false, []string{fmt.Sprintf("reference block is invalid protobuf message, but current block is valid")} } - if ignoreUnknown { + if !includeUnknownFields { referenceMsg.SetUnknown(nil) currentMsg.SetUnknown(nil) reference = referenceMsg.Interface().(proto.Message) @@ -379,12 +380,32 @@ func Compare(reference, current proto.Message, ignoreUnknown bool) (isEqual bool } spew.Dump(reference) + fileRef, err := os.Create("/Users/arnaudberger/t/reference.txt") + if err != nil { + panic(err) + } + defer fileRef.Close() + + spew.Fdump(fileRef, reference) + + fileCur, err := os.Create("/Users/arnaudberger/t/current.txt") + if err != nil { + panic(err) + } + defer fileCur.Close() + + spew.Fdump(fileCur, current) + if !proto.Equal(reference, current) { + opts := protojson.MarshalOptions{ + Multiline: true, + Indent: " ", + } - ref, err := json.MarshalIndent(reference, "", " ") + ref, err := opts.Marshal(reference) cli.NoError(err, "marshal JSON reference") - cur, err := json.MarshalIndent(current, "", " ") + cur, err := opts.Marshal(reference) cli.NoError(err, "marshal JSON current") r, err := jd.ReadJsonString(string(ref)) From eb36d164032462fd31707365ddff8a1d4238bca5 Mon Sep 17 00:00:00 2001 From: arnaudberger Date: Tue, 23 Jan 2024 12:34:29 -0500 Subject: [PATCH 10/44] Comapre block changes for Charles to review --- cmd/tools/compare/tools_compare_blocks.go | 33 +++++++++++++++-------- jsonencoder/marshallers.go | 24 +---------------- 2 files changed, 23 insertions(+), 34 deletions(-) diff --git a/cmd/tools/compare/tools_compare_blocks.go b/cmd/tools/compare/tools_compare_blocks.go index e6bffb0..cde1b05 100644 --- a/cmd/tools/compare/tools_compare_blocks.go +++ b/cmd/tools/compare/tools_compare_blocks.go @@ -24,8 +24,11 @@ import ( "strconv" "sync" - "github.com/davecgh/go-spew/spew" jd "github.com/josephburnett/jd/lib" + + "github.com/streamingfast/firehose-core/jsonencoder" + + "github.com/davecgh/go-spew/spew" "github.com/spf13/cobra" "github.com/streamingfast/bstream" "github.com/streamingfast/cli" @@ -36,7 +39,6 @@ import ( "github.com/streamingfast/firehose-core/protoregistry" "github.com/streamingfast/firehose-core/types" "go.uber.org/multierr" - "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" @@ -378,7 +380,6 @@ func Compare(reference proto.Message, current proto.Message, includeUnknownField } } } - spew.Dump(reference) fileRef, err := os.Create("/Users/arnaudberger/t/reference.txt") if err != nil { @@ -397,21 +398,31 @@ func Compare(reference proto.Message, current proto.Message, includeUnknownField spew.Fdump(fileCur, current) if !proto.Equal(reference, current) { - opts := protojson.MarshalOptions{ - Multiline: true, - Indent: " ", - } - ref, err := opts.Marshal(reference) + encoder := jsonencoder.New() + + referenceAsJSON, err := encoder.MarshalToString(reference) cli.NoError(err, "marshal JSON reference") - cur, err := opts.Marshal(reference) + currentAsJSON, err := encoder.MarshalToString(current) cli.NoError(err, "marshal JSON current") - r, err := jd.ReadJsonString(string(ref)) + // + //opts := protojson.MarshalOptions{ + // Multiline: true, + // Indent: " ", + //} + // + //ref, err := opts.Marshal(reference) + //cli.NoError(err, "marshal JSON reference") + // + //cur, err := opts.Marshal(reference) + //cli.NoError(err, "marshal JSON current") + // + r, err := jd.ReadJsonString(referenceAsJSON) cli.NoError(err, "read JSON reference") - c, err := jd.ReadJsonString(string(cur)) + c, err := jd.ReadJsonString(currentAsJSON) cli.NoError(err, "read JSON current") if diff := r.Diff(c).Render(); diff != "" { diff --git a/jsonencoder/marshallers.go b/jsonencoder/marshallers.go index cec6a3d..d62ab10 100644 --- a/jsonencoder/marshallers.go +++ b/jsonencoder/marshallers.go @@ -29,32 +29,10 @@ func (e *Encoder) anypb(encoder *jsontext.Encoder, t *anypb.Any, options json.Op return encoder.WriteValue(cnt) } -func toValue(msg *dynamicpb.Message) map[string]any { - mapMsg := map[string]any{} - msg.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { - var value any - if fd.IsList() { - out := make([]any, v.List().Len()) - for i := 0; i < v.List().Len(); i++ { - out[i] = v.List().Get(i) - } - value = out - } else if fd.Kind() == protoreflect.MessageKind { - - } else { - value = v.Interface() - } - - mapMsg[string(fd.Name())] = value - return true - }) - return mapMsg -} - func (e *Encoder) dynamicpbMessage(encoder *jsontext.Encoder, msg *dynamicpb.Message, options json.Options) error { mapMsg := map[string]any{} - mapMsg["__unknown_fields__"] = hex.EncodeToString(msg.GetUnknown()) + //mapMsg["__unknown_fields__"] = hex.EncodeToString(msg.GetUnknown()) msg.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { if fd.IsList() { From 2ca4d0834922a665f870fbc27d9bbb8abcca24ca Mon Sep 17 00:00:00 2001 From: billettc Date: Tue, 23 Jan 2024 13:11:13 -0500 Subject: [PATCH 11/44] json encoder now output unknown field --- cmd/tools/compare/tools_compare_blocks.go | 34 +---------------------- jsonencoder/marshallers.go | 14 +++++++--- 2 files changed, 11 insertions(+), 37 deletions(-) diff --git a/cmd/tools/compare/tools_compare_blocks.go b/cmd/tools/compare/tools_compare_blocks.go index cde1b05..28d7354 100644 --- a/cmd/tools/compare/tools_compare_blocks.go +++ b/cmd/tools/compare/tools_compare_blocks.go @@ -19,16 +19,11 @@ import ( "context" "fmt" "io" - "os" "reflect" "strconv" "sync" jd "github.com/josephburnett/jd/lib" - - "github.com/streamingfast/firehose-core/jsonencoder" - - "github.com/davecgh/go-spew/spew" "github.com/spf13/cobra" "github.com/streamingfast/bstream" "github.com/streamingfast/cli" @@ -36,6 +31,7 @@ import ( "github.com/streamingfast/dstore" firecore "github.com/streamingfast/firehose-core" "github.com/streamingfast/firehose-core/cmd/tools/check" + "github.com/streamingfast/firehose-core/jsonencoder" "github.com/streamingfast/firehose-core/protoregistry" "github.com/streamingfast/firehose-core/types" "go.uber.org/multierr" @@ -381,22 +377,6 @@ func Compare(reference proto.Message, current proto.Message, includeUnknownField } } - fileRef, err := os.Create("/Users/arnaudberger/t/reference.txt") - if err != nil { - panic(err) - } - defer fileRef.Close() - - spew.Fdump(fileRef, reference) - - fileCur, err := os.Create("/Users/arnaudberger/t/current.txt") - if err != nil { - panic(err) - } - defer fileCur.Close() - - spew.Fdump(fileCur, current) - if !proto.Equal(reference, current) { encoder := jsonencoder.New() @@ -407,18 +387,6 @@ func Compare(reference proto.Message, current proto.Message, includeUnknownField currentAsJSON, err := encoder.MarshalToString(current) cli.NoError(err, "marshal JSON current") - // - //opts := protojson.MarshalOptions{ - // Multiline: true, - // Indent: " ", - //} - // - //ref, err := opts.Marshal(reference) - //cli.NoError(err, "marshal JSON reference") - // - //cur, err := opts.Marshal(reference) - //cli.NoError(err, "marshal JSON current") - // r, err := jd.ReadJsonString(referenceAsJSON) cli.NoError(err, "read JSON reference") diff --git a/jsonencoder/marshallers.go b/jsonencoder/marshallers.go index d62ab10..f8ef39d 100644 --- a/jsonencoder/marshallers.go +++ b/jsonencoder/marshallers.go @@ -5,15 +5,14 @@ import ( "fmt" "strings" - "google.golang.org/protobuf/types/dynamicpb" - - "google.golang.org/protobuf/reflect/protoreflect" - "github.com/go-json-experiment/json" "github.com/go-json-experiment/json/jsontext" "github.com/jhump/protoreflect/dynamic" "github.com/mr-tron/base58" "github.com/streamingfast/firehose-core/protoregistry" + "google.golang.org/protobuf/encoding/protowire" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/types/dynamicpb" "google.golang.org/protobuf/types/known/anypb" ) @@ -33,6 +32,13 @@ func (e *Encoder) dynamicpbMessage(encoder *jsontext.Encoder, msg *dynamicpb.Mes mapMsg := map[string]any{} //mapMsg["__unknown_fields__"] = hex.EncodeToString(msg.GetUnknown()) + x := msg.GetUnknown() + fieldNumber, ofType, l := protowire.ConsumeField(x) + if l > 0 { + var unknownValue []byte + unknownValue = x[:l] + mapMsg[fmt.Sprintf("__unknown_fields_%d_with_type_%d__", fieldNumber, ofType)] = hex.EncodeToString(unknownValue) + } msg.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { if fd.IsList() { From cdeacd38b2978d13ef95de462452421c9a237e5a Mon Sep 17 00:00:00 2001 From: billettc Date: Tue, 23 Jan 2024 13:29:07 -0500 Subject: [PATCH 12/44] wip --- jsonencoder/encoder.go | 9 ++++++--- jsonencoder/marshallers.go | 13 ++++++++----- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/jsonencoder/encoder.go b/jsonencoder/encoder.go index cf5eaaf..fb00c15 100644 --- a/jsonencoder/encoder.go +++ b/jsonencoder/encoder.go @@ -10,14 +10,17 @@ import ( ) type Encoder struct { + marshallers *json.Marshalers } func New() *Encoder { - return &Encoder{} + e := &Encoder{} + e.setMarshallers("") + return e } func (e *Encoder) Marshal(in any) error { - err := json.MarshalEncode(jsontext.NewEncoder(os.Stdout), in, json.WithMarshalers(e.getMarshallers(""))) + err := json.MarshalEncode(jsontext.NewEncoder(os.Stdout), in, json.WithMarshalers(e.marshallers)) if err != nil { return fmt.Errorf("marshalling and encoding block to json: %w", err) } @@ -26,7 +29,7 @@ func (e *Encoder) Marshal(in any) error { func (e *Encoder) MarshalToString(in any) (string, error) { buf := bytes.NewBuffer(nil) - if err := json.MarshalEncode(jsontext.NewEncoder(buf), in, json.WithMarshalers(e.getMarshallers(""))); err != nil { + if err := json.MarshalEncode(jsontext.NewEncoder(buf), in, json.WithMarshalers(e.marshallers)); err != nil { return "", err } return buf.String(), nil diff --git a/jsonencoder/marshallers.go b/jsonencoder/marshallers.go index f8ef39d..64b9be6 100644 --- a/jsonencoder/marshallers.go +++ b/jsonencoder/marshallers.go @@ -21,7 +21,8 @@ func (e *Encoder) anypb(encoder *jsontext.Encoder, t *anypb.Any, options json.Op if err != nil { return fmt.Errorf("unmarshalling proto any: %w", err) } - cnt, err := json.Marshal(msg, json.WithMarshalers(e.getMarshallers(t.TypeUrl))) + e.setMarshallers(t.TypeUrl) + cnt, err := json.Marshal(msg, json.WithMarshalers(e.marshallers)) if err != nil { return fmt.Errorf("json marshalling proto any: %w", err) } @@ -53,7 +54,7 @@ func (e *Encoder) dynamicpbMessage(encoder *jsontext.Encoder, msg *dynamicpb.Mes return true }) - cnt, err := json.Marshal(mapMsg, json.WithMarshalers(e.getMarshallers("solana"))) + cnt, err := json.Marshal(mapMsg, json.WithMarshalers(e.marshallers)) if err != nil { return fmt.Errorf("json marshalling proto any: %w", err) } @@ -68,7 +69,7 @@ func (e *Encoder) hexBytes(encoder *jsontext.Encoder, t []byte, options json.Opt return encoder.WriteToken(jsontext.String(hex.EncodeToString(t))) } -func (e *Encoder) getMarshallers(typeURL string) *json.Marshalers { +func (e *Encoder) setMarshallers(typeURL string) { out := []*json.Marshalers{ json.MarshalFuncV2(e.anypb), json.MarshalFuncV2(e.dynamicpbMessage), @@ -77,10 +78,12 @@ func (e *Encoder) getMarshallers(typeURL string) *json.Marshalers { if strings.Contains(typeURL, "solana") { dynamic.SetDefaultBytesRepresentation(dynamic.BytesAsBase58) out = append(out, json.MarshalFuncV2(e.base58Bytes)) - return json.NewMarshalers(out...) + e.marshallers = json.NewMarshalers(out...) + return } dynamic.SetDefaultBytesRepresentation(dynamic.BytesAsHex) out = append(out, json.MarshalFuncV2(e.hexBytes)) - return json.NewMarshalers(out...) + e.marshallers = json.NewMarshalers(out...) + return } From adc9d86cfdced8aa01b61846ddac825d68354cad Mon Sep 17 00:00:00 2001 From: billettc Date: Tue, 23 Jan 2024 13:35:54 -0500 Subject: [PATCH 13/44] add todos --- cmd/tools/compare/tools_compare_blocks.go | 92 +++++++++++------------ jsonencoder/marshallers.go | 2 +- 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/cmd/tools/compare/tools_compare_blocks.go b/cmd/tools/compare/tools_compare_blocks.go index 28d7354..948bd85 100644 --- a/cmd/tools/compare/tools_compare_blocks.go +++ b/cmd/tools/compare/tools_compare_blocks.go @@ -15,7 +15,6 @@ package compare import ( - "bytes" "context" "fmt" "io" @@ -35,9 +34,7 @@ import ( "github.com/streamingfast/firehose-core/protoregistry" "github.com/streamingfast/firehose-core/types" "go.uber.org/multierr" - "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/dynamicpb" ) @@ -334,51 +331,54 @@ func Compare(reference proto.Message, current proto.Message, includeUnknownField return false, []string{fmt.Sprintf("reference block is invalid protobuf message, but current block is valid")} } - if !includeUnknownFields { - referenceMsg.SetUnknown(nil) - currentMsg.SetUnknown(nil) - reference = referenceMsg.Interface().(proto.Message) - current = currentMsg.Interface().(proto.Message) - } else { - x := referenceMsg.GetUnknown() - y := currentMsg.GetUnknown() - - if !bytes.Equal(x, y) { - // from https://github.com/protocolbuffers/protobuf-go/tree/v1.28.1/proto - mx := make(map[protoreflect.FieldNumber]protoreflect.RawFields) - my := make(map[protoreflect.FieldNumber]protoreflect.RawFields) - for len(x) > 0 { - fnum, _, n := protowire.ConsumeField(x) - mx[fnum] = append(mx[fnum], x[:n]...) - x = x[n:] - } - for len(y) > 0 { - fnum, _, n := protowire.ConsumeField(y) - my[fnum] = append(my[fnum], y[:n]...) - y = y[n:] - } - for k, v := range mx { - vv, ok := my[k] - if !ok { - differences = append(differences, fmt.Sprintf("reference block contains unknown protobuf field number %d (%x), but current block does not", k, v)) - continue - } - if !bytes.Equal(v, vv) { - differences = append(differences, fmt.Sprintf("unknown protobuf field number %d has different values. Reference: %x, current: %x", k, v, vv)) - } - } - for k := range my { - v, ok := my[k] - if !ok { - differences = append(differences, fmt.Sprintf("current block contains unknown protobuf field number %d (%x), but reference block does not", k, v)) - continue - } - } - } - } - + //if !includeUnknownFields { + // referenceMsg.SetUnknown(nil) + // currentMsg.SetUnknown(nil) + // reference = referenceMsg.Interface().(proto.Message) + // current = currentMsg.Interface().(proto.Message) + //} else { + // x := referenceMsg.GetUnknown() + // y := currentMsg.GetUnknown() + // + // if !bytes.Equal(x, y) { + // // from https://github.com/protocolbuffers/protobuf-go/tree/v1.28.1/proto + // mx := make(map[protoreflect.FieldNumber]protoreflect.RawFields) + // my := make(map[protoreflect.FieldNumber]protoreflect.RawFields) + // for len(x) > 0 { + // fnum, _, n := protowire.ConsumeField(x) + // mx[fnum] = append(mx[fnum], x[:n]...) + // x = x[n:] + // } + // for len(y) > 0 { + // fnum, _, n := protowire.ConsumeField(y) + // my[fnum] = append(my[fnum], y[:n]...) + // y = y[n:] + // } + // for k, v := range mx { + // vv, ok := my[k] + // if !ok { + // differences = append(differences, fmt.Sprintf("reference block contains unknown protobuf field number %d (%x), but current block does not", k, v)) + // continue + // } + // if !bytes.Equal(v, vv) { + // differences = append(differences, fmt.Sprintf("unknown protobuf field number %d has different values. Reference: %x, current: %x", k, v, vv)) + // } + // } + // for k := range my { + // v, ok := my[k] + // if !ok { + // differences = append(differences, fmt.Sprintf("current block contains unknown protobuf field number %d (%x), but reference block does not", k, v)) + // continue + // } + // } + // } + //} + + //todo: handle includeUnknownFields parameter + //todo: I think we should only compare json since the unknown fields are not part of the json output if !proto.Equal(reference, current) { + //todo: turn on or off the unknown fields json output encoder := jsonencoder.New() referenceAsJSON, err := encoder.MarshalToString(reference) diff --git a/jsonencoder/marshallers.go b/jsonencoder/marshallers.go index 64b9be6..bba797c 100644 --- a/jsonencoder/marshallers.go +++ b/jsonencoder/marshallers.go @@ -32,7 +32,7 @@ func (e *Encoder) anypb(encoder *jsontext.Encoder, t *anypb.Any, options json.Op func (e *Encoder) dynamicpbMessage(encoder *jsontext.Encoder, msg *dynamicpb.Message, options json.Options) error { mapMsg := map[string]any{} - //mapMsg["__unknown_fields__"] = hex.EncodeToString(msg.GetUnknown()) + //todo: make Unknown field optional x := msg.GetUnknown() fieldNumber, ofType, l := protowire.ConsumeField(x) if l > 0 { From 6065e780218d28e2d6dd4903c1b31aa75e80eee0 Mon Sep 17 00:00:00 2001 From: billettc Date: Tue, 23 Jan 2024 13:54:52 -0500 Subject: [PATCH 14/44] add more todo todos --- cmd/tools/compare/tools_compare_blocks.go | 78 +++++++---------------- 1 file changed, 24 insertions(+), 54 deletions(-) diff --git a/cmd/tools/compare/tools_compare_blocks.go b/cmd/tools/compare/tools_compare_blocks.go index 948bd85..2049c03 100644 --- a/cmd/tools/compare/tools_compare_blocks.go +++ b/cmd/tools/compare/tools_compare_blocks.go @@ -21,6 +21,7 @@ import ( "reflect" "strconv" "sync" + "time" jd "github.com/josephburnett/jd/lib" "github.com/spf13/cobra" @@ -179,9 +180,9 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm var isEqual bool if existsInCurrent { var differences []string - isEqual, differences = Compare(referenceBlock, currentBlock, includeUnknownFields) + differences = Compare(referenceBlock, currentBlock, includeUnknownFields) - if !isEqual { + if len(differences) > 0 { fmt.Printf("- Block %d is different\n", referenceBlockNum) if displayDiff { for _, diff := range differences { @@ -314,89 +315,58 @@ func (s *state) print() { fmt.Printf("✖ Segment %d - %s has %d different blocks and %d missing blocks (%d blocks counted)\n", s.segments[s.currentSegmentIdx].Start, endBlock, s.differencesFound, s.missingBlocks, s.totalBlocksCounted) } -func Compare(reference proto.Message, current proto.Message, includeUnknownFields bool) (isEqual bool, differences []string) { +func Compare(reference proto.Message, current proto.Message, includeUnknownFields bool) (differences []string) { if reference == nil && current == nil { - return true, nil + return nil } if reflect.TypeOf(reference).Kind() == reflect.Ptr && reference == current { - return true, nil + return nil } referenceMsg := reference.ProtoReflect() currentMsg := current.ProtoReflect() if referenceMsg.IsValid() && !currentMsg.IsValid() { - return false, []string{fmt.Sprintf("reference block is valid protobuf message, but current block is invalid")} + return []string{fmt.Sprintf("reference block is valid protobuf message, but current block is invalid")} } if !referenceMsg.IsValid() && currentMsg.IsValid() { - return false, []string{fmt.Sprintf("reference block is invalid protobuf message, but current block is valid")} + return []string{fmt.Sprintf("reference block is invalid protobuf message, but current block is valid")} } - //if !includeUnknownFields { - // referenceMsg.SetUnknown(nil) - // currentMsg.SetUnknown(nil) - // reference = referenceMsg.Interface().(proto.Message) - // current = currentMsg.Interface().(proto.Message) - //} else { - // x := referenceMsg.GetUnknown() - // y := currentMsg.GetUnknown() - // - // if !bytes.Equal(x, y) { - // // from https://github.com/protocolbuffers/protobuf-go/tree/v1.28.1/proto - // mx := make(map[protoreflect.FieldNumber]protoreflect.RawFields) - // my := make(map[protoreflect.FieldNumber]protoreflect.RawFields) - // for len(x) > 0 { - // fnum, _, n := protowire.ConsumeField(x) - // mx[fnum] = append(mx[fnum], x[:n]...) - // x = x[n:] - // } - // for len(y) > 0 { - // fnum, _, n := protowire.ConsumeField(y) - // my[fnum] = append(my[fnum], y[:n]...) - // y = y[n:] - // } - // for k, v := range mx { - // vv, ok := my[k] - // if !ok { - // differences = append(differences, fmt.Sprintf("reference block contains unknown protobuf field number %d (%x), but current block does not", k, v)) - // continue - // } - // if !bytes.Equal(v, vv) { - // differences = append(differences, fmt.Sprintf("unknown protobuf field number %d has different values. Reference: %x, current: %x", k, v, vv)) - // } - // } - // for k := range my { - // v, ok := my[k] - // if !ok { - // differences = append(differences, fmt.Sprintf("current block contains unknown protobuf field number %d (%x), but reference block does not", k, v)) - // continue - // } - // } - // } - //} - //todo: handle includeUnknownFields parameter - //todo: I think we should only compare json since the unknown fields are not part of the json output if !proto.Equal(reference, current) { + start := time.Now() //todo: turn on or off the unknown fields json output + //todo: receive encoder as parameter encoder := jsonencoder.New() + rS := time.Now() referenceAsJSON, err := encoder.MarshalToString(reference) cli.NoError(err, "marshal JSON reference") + fmt.Println("reference marshal took", time.Since(rS)) + cS := time.Now() currentAsJSON, err := encoder.MarshalToString(current) cli.NoError(err, "marshal JSON current") + fmt.Println("current marshal took", time.Since(cS)) + drS := time.Now() r, err := jd.ReadJsonString(referenceAsJSON) cli.NoError(err, "read JSON reference") c, err := jd.ReadJsonString(currentAsJSON) cli.NoError(err, "read JSON current") + fmt.Println("diff read took", time.Since(drS)) + + diffS := time.Now() + //todo: manage better output off differences if diff := r.Diff(c).Render(); diff != "" { - differences = append(differences, diff) + //differences = append(differences, diff) } - return false, differences + fmt.Println("diff took", time.Since(diffS)) + fmt.Println("total time", time.Since(start)) } - return true, nil + + return differences } From 7773d3a56e856b1f761b98c1742d2d107adf0ed5 Mon Sep 17 00:00:00 2001 From: billettc Date: Tue, 23 Jan 2024 13:58:13 -0500 Subject: [PATCH 15/44] add even more todo todos --- cmd/tools/compare/tools_compare_blocks.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/tools/compare/tools_compare_blocks.go b/cmd/tools/compare/tools_compare_blocks.go index 2049c03..ab8d615 100644 --- a/cmd/tools/compare/tools_compare_blocks.go +++ b/cmd/tools/compare/tools_compare_blocks.go @@ -332,6 +332,7 @@ func Compare(reference proto.Message, current proto.Message, includeUnknownField return []string{fmt.Sprintf("reference block is invalid protobuf message, but current block is valid")} } + //todo: check if there is a equals that do not compare unknown fields //todo: handle includeUnknownFields parameter if !proto.Equal(reference, current) { From b1fb0b36fdfae16ce2fb0a3db1371858b201a6fd Mon Sep 17 00:00:00 2001 From: billettc Date: Tue, 23 Jan 2024 13:59:37 -0500 Subject: [PATCH 16/44] remove time logs --- cmd/tools/compare/tools_compare_blocks.go | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/cmd/tools/compare/tools_compare_blocks.go b/cmd/tools/compare/tools_compare_blocks.go index ab8d615..3aa4aeb 100644 --- a/cmd/tools/compare/tools_compare_blocks.go +++ b/cmd/tools/compare/tools_compare_blocks.go @@ -21,7 +21,6 @@ import ( "reflect" "strconv" "sync" - "time" jd "github.com/josephburnett/jd/lib" "github.com/spf13/cobra" @@ -336,37 +335,27 @@ func Compare(reference proto.Message, current proto.Message, includeUnknownField //todo: handle includeUnknownFields parameter if !proto.Equal(reference, current) { - start := time.Now() //todo: turn on or off the unknown fields json output //todo: receive encoder as parameter encoder := jsonencoder.New() - rS := time.Now() referenceAsJSON, err := encoder.MarshalToString(reference) cli.NoError(err, "marshal JSON reference") - fmt.Println("reference marshal took", time.Since(rS)) - cS := time.Now() currentAsJSON, err := encoder.MarshalToString(current) cli.NoError(err, "marshal JSON current") - fmt.Println("current marshal took", time.Since(cS)) - drS := time.Now() r, err := jd.ReadJsonString(referenceAsJSON) cli.NoError(err, "read JSON reference") c, err := jd.ReadJsonString(currentAsJSON) cli.NoError(err, "read JSON current") - fmt.Println("diff read took", time.Since(drS)) - - diffS := time.Now() //todo: manage better output off differences if diff := r.Diff(c).Render(); diff != "" { - //differences = append(differences, diff) + differences = append(differences, diff) } - fmt.Println("diff took", time.Since(diffS)) - fmt.Println("total time", time.Since(start)) + } return differences From 6fc77749403ceb783925ab7dae91226f374b3098 Mon Sep 17 00:00:00 2001 From: arnaudberger Date: Tue, 23 Jan 2024 16:13:04 -0500 Subject: [PATCH 17/44] add multithreading to compare and handle of includeUnknownFields --- cmd/tools/compare/tools_compare_blocks.go | 67 +++++++++++++++-------- jsonencoder/encoder.go | 18 +++++- jsonencoder/marshallers.go | 15 ++--- 3 files changed, 67 insertions(+), 33 deletions(-) diff --git a/cmd/tools/compare/tools_compare_blocks.go b/cmd/tools/compare/tools_compare_blocks.go index 3aa4aeb..62debb8 100644 --- a/cmd/tools/compare/tools_compare_blocks.go +++ b/cmd/tools/compare/tools_compare_blocks.go @@ -38,6 +38,11 @@ import ( "google.golang.org/protobuf/types/dynamicpb" ) +type BlockDifferences struct { + BlockNumber uint64 + Differences []string +} + func NewToolsCompareBlocksCmd[B firecore.Block](chain *firecore.Chain[B]) *cobra.Command { cmd := &cobra.Command{ Use: "compare-blocks []", @@ -77,7 +82,7 @@ func NewToolsCompareBlocksCmd[B firecore.Block](chain *firecore.Chain[B]) *cobra func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.CommandExecutor { return func(cmd *cobra.Command, args []string) error { displayDiff := sflags.MustGetBool(cmd, "diff") - includeUnknownFields := !sflags.MustGetBool(cmd, "include-unknown-fields") + includeUnknownFields := sflags.MustGetBool(cmd, "include-unknown-fields") protoPaths := sflags.MustGetStringSlice(cmd, "proto-paths") segmentSize := uint64(100000) warnAboutExtraBlocks := sync.Once{} @@ -171,27 +176,42 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm return fmt.Errorf("reading bundles: %w", bundleReadErr) } + blockDifferencesChan := make(chan BlockDifferences, len(referenceBlockHashes)) + for _, referenceBlockHash := range referenceBlockHashes { - referenceBlock := referenceBlocks[referenceBlockHash] - currentBlock, existsInCurrent := currentBlocks[referenceBlockHash] - referenceBlockNum := referenceBlock.Get(referenceBlock.Descriptor().Fields().ByName("slot")).Uint() - - var isEqual bool - if existsInCurrent { - var differences []string - differences = Compare(referenceBlock, currentBlock, includeUnknownFields) - - if len(differences) > 0 { - fmt.Printf("- Block %d is different\n", referenceBlockNum) - if displayDiff { - for _, diff := range differences { - fmt.Println(" · ", diff) - } + wg.Add(1) + go func(hash string) { + defer wg.Done() + referenceBlock := referenceBlocks[hash] + currentBlock, existsInCurrent := currentBlocks[hash] + referenceBlockNum := referenceBlock.Get(referenceBlock.Descriptor().Fields().ByName("slot")).Uint() + + var isDifferent bool + + if existsInCurrent { + var differences []string + differences = Compare(referenceBlock, currentBlock, includeUnknownFields) + + isDifferent = len(differences) > 0 + + if isDifferent { + blockDifferencesChan <- BlockDifferences{BlockNumber: referenceBlockNum, Differences: differences} } } - } - processState.process(referenceBlockNum, !isEqual, !existsInCurrent) + processState.process(referenceBlockNum, isDifferent, !existsInCurrent) + }(referenceBlockHash) + } + + wg.Wait() + close(blockDifferencesChan) + for blockDifferences := range blockDifferencesChan { + fmt.Printf("- Block %d is different\n", blockDifferences.BlockNumber) + if displayDiff { + for _, diff := range blockDifferences.Differences { + fmt.Println(" · ", diff) + } + } } } return nil @@ -244,6 +264,7 @@ func readBundle( continue } + //todo: handle correctly the chainFileDescriptor err = protoregistry.Register(nil, protoPaths...) if err != nil { @@ -332,12 +353,12 @@ func Compare(reference proto.Message, current proto.Message, includeUnknownField } //todo: check if there is a equals that do not compare unknown fields - //todo: handle includeUnknownFields parameter if !proto.Equal(reference, current) { - - //todo: turn on or off the unknown fields json output - //todo: receive encoder as parameter - encoder := jsonencoder.New() + var opts []jsonencoder.EncoderOption + if !includeUnknownFields { + opts = append(opts, jsonencoder.WithoutUnknownFields()) + } + encoder := jsonencoder.New(opts...) referenceAsJSON, err := encoder.MarshalToString(reference) cli.NoError(err, "marshal JSON reference") diff --git a/jsonencoder/encoder.go b/jsonencoder/encoder.go index fb00c15..b0801e1 100644 --- a/jsonencoder/encoder.go +++ b/jsonencoder/encoder.go @@ -10,11 +10,23 @@ import ( ) type Encoder struct { - marshallers *json.Marshalers + marshallers *json.Marshalers + IncludeUnknownFields bool } -func New() *Encoder { - e := &Encoder{} +type EncoderOption func(*Encoder) + +func WithoutUnknownFields() EncoderOption { + return func(e *Encoder) { + e.IncludeUnknownFields = false + } +} +func New(includeUnknownFields ...EncoderOption) *Encoder { + e := &Encoder{IncludeUnknownFields: true} + + for _, opt := range includeUnknownFields { + opt(e) + } e.setMarshallers("") return e } diff --git a/jsonencoder/marshallers.go b/jsonencoder/marshallers.go index bba797c..f995229 100644 --- a/jsonencoder/marshallers.go +++ b/jsonencoder/marshallers.go @@ -32,13 +32,14 @@ func (e *Encoder) anypb(encoder *jsontext.Encoder, t *anypb.Any, options json.Op func (e *Encoder) dynamicpbMessage(encoder *jsontext.Encoder, msg *dynamicpb.Message, options json.Options) error { mapMsg := map[string]any{} - //todo: make Unknown field optional - x := msg.GetUnknown() - fieldNumber, ofType, l := protowire.ConsumeField(x) - if l > 0 { - var unknownValue []byte - unknownValue = x[:l] - mapMsg[fmt.Sprintf("__unknown_fields_%d_with_type_%d__", fieldNumber, ofType)] = hex.EncodeToString(unknownValue) + if e.IncludeUnknownFields { + x := msg.GetUnknown() + fieldNumber, ofType, l := protowire.ConsumeField(x) + if l > 0 { + var unknownValue []byte + unknownValue = x[:l] + mapMsg[fmt.Sprintf("__unknown_fields_%d_with_type_%d__", fieldNumber, ofType)] = hex.EncodeToString(unknownValue) + } } msg.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { From 32aeab87dfaa56a071c49ca825f0cf1ccbcf940c Mon Sep 17 00:00:00 2001 From: Matthieu Vachon Date: Tue, 23 Jan 2024 16:46:04 -0500 Subject: [PATCH 18/44] Now showing which message type was not found when proto unmarshal any fails --- protoregistry/registry.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protoregistry/registry.go b/protoregistry/registry.go index 4978e29..6a002f6 100644 --- a/protoregistry/registry.go +++ b/protoregistry/registry.go @@ -101,7 +101,7 @@ func RegisterFileDescriptor(fd protoreflect.FileDescriptor) error { func Unmarshal(a *anypb.Any) (*dynamicpb.Message, error) { messageType, err := protoregistry.GlobalTypes.FindMessageByURL(a.TypeUrl) if err != nil { - return nil, fmt.Errorf("failed to find message type: %v", err) + return nil, fmt.Errorf("failed to find message type %q: %v", a.TypeUrl, err) } message := dynamicpb.NewMessage(messageType.Descriptor()) From 47d564c0c02e615ef4e1e35cf9bb704affe6b47e Mon Sep 17 00:00:00 2001 From: Matthieu Vachon Date: Tue, 23 Jan 2024 16:52:04 -0500 Subject: [PATCH 19/44] Improved even more error message by cleaning it according to `FindMessageByURL` function --- protoregistry/registry.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/protoregistry/registry.go b/protoregistry/registry.go index 6a002f6..fd2697a 100644 --- a/protoregistry/registry.go +++ b/protoregistry/registry.go @@ -101,7 +101,7 @@ func RegisterFileDescriptor(fd protoreflect.FileDescriptor) error { func Unmarshal(a *anypb.Any) (*dynamicpb.Message, error) { messageType, err := protoregistry.GlobalTypes.FindMessageByURL(a.TypeUrl) if err != nil { - return nil, fmt.Errorf("failed to find message type %q: %v", a.TypeUrl, err) + return nil, fmt.Errorf("failed to find message '%s': %v", urlToMessageFullName(a.TypeUrl), err) } message := dynamicpb.NewMessage(messageType.Descriptor()) @@ -113,6 +113,11 @@ func Unmarshal(a *anypb.Any) (*dynamicpb.Message, error) { return message, nil } -func cleanTypeURL(in string) string { - return strings.Replace(in, "type.googleapis.com/", "", 1) +func urlToMessageFullName(url string) protoreflect.FullName { + message := protoreflect.FullName(url) + if i := strings.LastIndexByte(url, '/'); i >= 0 { + message = message[i+len("/"):] + } + + return message } From ed7dd6a03fcfa4089bd19480df27238d15e86b58 Mon Sep 17 00:00:00 2001 From: billettc Date: Wed, 24 Jan 2024 08:34:44 -0500 Subject: [PATCH 20/44] remove chan and lock at display time --- cmd/tools/compare/tools_compare_blocks.go | 24 +++++++++-------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/cmd/tools/compare/tools_compare_blocks.go b/cmd/tools/compare/tools_compare_blocks.go index 62debb8..adb853f 100644 --- a/cmd/tools/compare/tools_compare_blocks.go +++ b/cmd/tools/compare/tools_compare_blocks.go @@ -176,8 +176,7 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm return fmt.Errorf("reading bundles: %w", bundleReadErr) } - blockDifferencesChan := make(chan BlockDifferences, len(referenceBlockHashes)) - + outLock := sync.Mutex{} for _, referenceBlockHash := range referenceBlockHashes { wg.Add(1) go func(hash string) { @@ -195,24 +194,19 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm isDifferent = len(differences) > 0 if isDifferent { - blockDifferencesChan <- BlockDifferences{BlockNumber: referenceBlockNum, Differences: differences} + outLock.Lock() + fmt.Printf("- Block %d is different\n", referenceBlockNum) + if displayDiff { + for _, diff := range differences { + fmt.Println(" · ", diff) + } + } + outLock.Unlock() } } processState.process(referenceBlockNum, isDifferent, !existsInCurrent) }(referenceBlockHash) } - - wg.Wait() - close(blockDifferencesChan) - - for blockDifferences := range blockDifferencesChan { - fmt.Printf("- Block %d is different\n", blockDifferences.BlockNumber) - if displayDiff { - for _, diff := range blockDifferences.Differences { - fmt.Println(" · ", diff) - } - } - } } return nil }) From a4800c92d3ece9de41abb86bf69cc04530c3f28b Mon Sep 17 00:00:00 2001 From: arnaudberger Date: Wed, 24 Jan 2024 09:01:55 -0500 Subject: [PATCH 21/44] fixing multithreading comparing --- cmd/tools/compare/tools_compare_blocks.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmd/tools/compare/tools_compare_blocks.go b/cmd/tools/compare/tools_compare_blocks.go index adb853f..02fdd2c 100644 --- a/cmd/tools/compare/tools_compare_blocks.go +++ b/cmd/tools/compare/tools_compare_blocks.go @@ -183,6 +183,8 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm defer wg.Done() referenceBlock := referenceBlocks[hash] currentBlock, existsInCurrent := currentBlocks[hash] + fmt.Println("referenceBlockSlot", referenceBlock.Get(referenceBlock.Descriptor().Fields().ByName("slot")).Uint()) + fmt.Println("currentBlockSlot", currentBlock.Get(currentBlock.Descriptor().Fields().ByName("slot")).Uint()) referenceBlockNum := referenceBlock.Get(referenceBlock.Descriptor().Fields().ByName("slot")).Uint() var isDifferent bool @@ -206,6 +208,7 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm } processState.process(referenceBlockNum, isDifferent, !existsInCurrent) }(referenceBlockHash) + wg.Wait() } } return nil From c99b59a07bc58bf841e5074b9243546954140fc4 Mon Sep 17 00:00:00 2001 From: billettc Date: Wed, 24 Jan 2024 10:11:11 -0500 Subject: [PATCH 22/44] fix field order of dynamicpb message --- jsonencoder/marshallers.go | 48 ++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/jsonencoder/marshallers.go b/jsonencoder/marshallers.go index f995229..74f3355 100644 --- a/jsonencoder/marshallers.go +++ b/jsonencoder/marshallers.go @@ -29,8 +29,35 @@ func (e *Encoder) anypb(encoder *jsontext.Encoder, t *anypb.Any, options json.Op return encoder.WriteValue(cnt) } +type kvlist []*kv +type kv struct { + key string + value any +} + +func (e *Encoder) encodeKVList(encoder *jsontext.Encoder, t kvlist, options json.Options) error { + if err := encoder.WriteToken(jsontext.ObjectStart); err != nil { + return err + } + for _, kv := range t { + if err := encoder.WriteToken(jsontext.String(kv.key)); err != nil { + return err + } + + cnt, err := json.Marshal(kv.value, json.WithMarshalers(e.marshallers)) + if err != nil { + return fmt.Errorf("json marshalling of value : %w", err) + } + + if err := encoder.WriteValue(cnt); err != nil { + return err + } + } + return encoder.WriteToken(jsontext.ObjectEnd) +} + func (e *Encoder) dynamicpbMessage(encoder *jsontext.Encoder, msg *dynamicpb.Message, options json.Options) error { - mapMsg := map[string]any{} + var kvl kvlist if e.IncludeUnknownFields { x := msg.GetUnknown() @@ -38,7 +65,10 @@ func (e *Encoder) dynamicpbMessage(encoder *jsontext.Encoder, msg *dynamicpb.Mes if l > 0 { var unknownValue []byte unknownValue = x[:l] - mapMsg[fmt.Sprintf("__unknown_fields_%d_with_type_%d__", fieldNumber, ofType)] = hex.EncodeToString(unknownValue) + kvl = append(kvl, &kv{ + key: fmt.Sprintf("__unknown_fields_%d_with_type_%d__", fieldNumber, ofType), + value: hex.EncodeToString(unknownValue), + }) } } @@ -48,14 +78,21 @@ func (e *Encoder) dynamicpbMessage(encoder *jsontext.Encoder, msg *dynamicpb.Mes for i := 0; i < v.List().Len(); i++ { out[i] = v.List().Get(i).Interface() } - mapMsg[string(fd.Name())] = out + kvl = append(kvl, &kv{ + key: string(fd.Name()), + value: out, + }) return true } - mapMsg[string(fd.Name())] = v.Interface() + kvl = append(kvl, &kv{ + key: string(fd.Name()), + value: v.Interface(), + }) + return true }) - cnt, err := json.Marshal(mapMsg, json.WithMarshalers(e.marshallers)) + cnt, err := json.Marshal(kvl, json.WithMarshalers(e.marshallers)) if err != nil { return fmt.Errorf("json marshalling proto any: %w", err) } @@ -74,6 +111,7 @@ func (e *Encoder) setMarshallers(typeURL string) { out := []*json.Marshalers{ json.MarshalFuncV2(e.anypb), json.MarshalFuncV2(e.dynamicpbMessage), + json.MarshalFuncV2(e.encodeKVList), } if strings.Contains(typeURL, "solana") { From 224df03b4ad6a1e4bb5dfa1c2a421f0b6abceadc Mon Sep 17 00:00:00 2001 From: billettc Date: Wed, 24 Jan 2024 10:21:25 -0500 Subject: [PATCH 23/44] really fix field order of dynamicpb message --- jsonencoder/marshallers.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jsonencoder/marshallers.go b/jsonencoder/marshallers.go index 74f3355..4b5acfd 100644 --- a/jsonencoder/marshallers.go +++ b/jsonencoder/marshallers.go @@ -5,6 +5,8 @@ import ( "fmt" "strings" + "golang.org/x/exp/slices" + "github.com/go-json-experiment/json" "github.com/go-json-experiment/json/jsontext" "github.com/jhump/protoreflect/dynamic" @@ -92,6 +94,10 @@ func (e *Encoder) dynamicpbMessage(encoder *jsontext.Encoder, msg *dynamicpb.Mes return true }) + slices.SortFunc(kvl, func(a, b *kv) bool { + return a.key < b.key + }) + cnt, err := json.Marshal(kvl, json.WithMarshalers(e.marshallers)) if err != nil { return fmt.Errorf("json marshalling proto any: %w", err) From 87738d6a006543186886d564f5fa1c9bfcf6a904 Mon Sep 17 00:00:00 2001 From: arnaudberger Date: Wed, 24 Jan 2024 13:52:13 -0500 Subject: [PATCH 24/44] removing GlobalFiles/Types uses in registry --- cmd/tools/compare/tools_compare_blocks.go | 52 ++++++++++++++++------- cmd/tools/print/tools_print.go | 4 +- jsonencoder/encoder.go | 14 ++++-- jsonencoder/marshallers.go | 5 +-- protoregistry/registry.go | 48 ++++++++++++--------- protoregistry/registry_test.go | 4 +- protoregistry/well_known.go | 12 +++--- 7 files changed, 85 insertions(+), 54 deletions(-) diff --git a/cmd/tools/compare/tools_compare_blocks.go b/cmd/tools/compare/tools_compare_blocks.go index 02fdd2c..27e6be7 100644 --- a/cmd/tools/compare/tools_compare_blocks.go +++ b/cmd/tools/compare/tools_compare_blocks.go @@ -18,6 +18,7 @@ import ( "context" "fmt" "io" + "os" "reflect" "strconv" "sync" @@ -116,6 +117,11 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm segments: segments, } + registry, err := protoregistry.NewRegistry(nil, protoPaths...) + if err != nil { + return fmt.Errorf("creating registry: %w", err) + } + err = storeReference.Walk(ctx, check.WalkBlockPrefix(blockRange, 100), func(filename string) (err error) { fileStartBlock, err := strconv.Atoi(filename) if err != nil { @@ -145,7 +151,7 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm uint64(fileStartBlock), stopBlock, &warnAboutExtraBlocks, - protoPaths, + registry, ) if err != nil { bundleErrLock.Lock() @@ -163,7 +169,7 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm uint64(fileStartBlock), stopBlock, &warnAboutExtraBlocks, - protoPaths, + registry, ) if err != nil { bundleErrLock.Lock() @@ -183,15 +189,13 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm defer wg.Done() referenceBlock := referenceBlocks[hash] currentBlock, existsInCurrent := currentBlocks[hash] - fmt.Println("referenceBlockSlot", referenceBlock.Get(referenceBlock.Descriptor().Fields().ByName("slot")).Uint()) - fmt.Println("currentBlockSlot", currentBlock.Get(currentBlock.Descriptor().Fields().ByName("slot")).Uint()) referenceBlockNum := referenceBlock.Get(referenceBlock.Descriptor().Fields().ByName("slot")).Uint() var isDifferent bool - + fmt.Println("Registry", registry) if existsInCurrent { var differences []string - differences = Compare(referenceBlock, currentBlock, includeUnknownFields) + differences = Compare(referenceBlock, currentBlock, includeUnknownFields, registry) isDifferent = len(differences) > 0 @@ -229,7 +233,7 @@ func readBundle( fileStartBlock, stopBlock uint64, warnAboutExtraBlocks *sync.Once, - protoPaths []string, + registry *protoregistry.Registry, ) ([]string, map[string]*dynamicpb.Message, error) { fileReader, err := store.OpenObject(ctx, filename) if err != nil { @@ -261,13 +265,7 @@ func readBundle( continue } - //todo: handle correctly the chainFileDescriptor - err = protoregistry.Register(nil, protoPaths...) - - if err != nil { - return nil, nil, fmt.Errorf("protoregistry registry failed: %w", err) - } - curBlockPB, err := protoregistry.Unmarshal(curBlock.Payload) + curBlockPB, err := registry.Unmarshal(curBlock.Payload) if err != nil { return nil, nil, fmt.Errorf("unmarshalling block: %w", err) @@ -332,7 +330,7 @@ func (s *state) print() { fmt.Printf("✖ Segment %d - %s has %d different blocks and %d missing blocks (%d blocks counted)\n", s.segments[s.currentSegmentIdx].Start, endBlock, s.differencesFound, s.missingBlocks, s.totalBlocksCounted) } -func Compare(reference proto.Message, current proto.Message, includeUnknownFields bool) (differences []string) { +func Compare(reference proto.Message, current proto.Message, includeUnknownFields bool, registry *protoregistry.Registry) (differences []string) { if reference == nil && current == nil { return nil } @@ -355,7 +353,7 @@ func Compare(reference proto.Message, current proto.Message, includeUnknownField if !includeUnknownFields { opts = append(opts, jsonencoder.WithoutUnknownFields()) } - encoder := jsonencoder.New(opts...) + encoder := jsonencoder.New(registry, opts...) referenceAsJSON, err := encoder.MarshalToString(reference) cli.NoError(err, "marshal JSON reference") @@ -371,6 +369,28 @@ func Compare(reference proto.Message, current proto.Message, includeUnknownField //todo: manage better output off differences if diff := r.Diff(c).Render(); diff != "" { + referenceWriter, err := os.Create("/Users/arnaudberger/t/reference.json") + if err != nil { + fmt.Println(err) + } + currentWriter, err := os.Create("/Users/arnaudberger/t/current.json") + if err != nil { + fmt.Println(err) + } + + _, err = referenceWriter.WriteString(referenceAsJSON) + if err != nil { + fmt.Println(err) + } + _, err = currentWriter.WriteString(currentAsJSON) + if err != nil { + fmt.Println(err) + } + + referenceWriter.Close() + currentWriter.Close() + + panic("diff") differences = append(differences, diff) } diff --git a/cmd/tools/print/tools_print.go b/cmd/tools/print/tools_print.go index c90d980..af41996 100644 --- a/cmd/tools/print/tools_print.go +++ b/cmd/tools/print/tools_print.go @@ -269,10 +269,10 @@ func PrintBStreamBlock(b *pbbstream.Block, printTransactions bool, out io.Writer } func SetupJsonEncoder(cmd *cobra.Command, chainFileDescriptor protoreflect.FileDescriptor) (*jsonencoder.Encoder, error) { - err := protoregistry.Register(chainFileDescriptor, sflags.MustGetStringSlice(cmd, "proto-paths")...) + registry, err := protoregistry.NewRegistry(chainFileDescriptor, sflags.MustGetStringSlice(cmd, "proto-paths")...) if err != nil { return nil, fmt.Errorf("new registry: %w", err) } - return jsonencoder.New(), nil + return jsonencoder.New(registry), nil } diff --git a/jsonencoder/encoder.go b/jsonencoder/encoder.go index b0801e1..fb6241e 100644 --- a/jsonencoder/encoder.go +++ b/jsonencoder/encoder.go @@ -5,24 +5,30 @@ import ( "fmt" "os" + "github.com/streamingfast/firehose-core/protoregistry" + "github.com/go-json-experiment/json" "github.com/go-json-experiment/json/jsontext" ) type Encoder struct { marshallers *json.Marshalers - IncludeUnknownFields bool + includeUnknownFields bool + registry *protoregistry.Registry } type EncoderOption func(*Encoder) func WithoutUnknownFields() EncoderOption { return func(e *Encoder) { - e.IncludeUnknownFields = false + e.includeUnknownFields = false } } -func New(includeUnknownFields ...EncoderOption) *Encoder { - e := &Encoder{IncludeUnknownFields: true} +func New(registry *protoregistry.Registry, includeUnknownFields ...EncoderOption) *Encoder { + e := &Encoder{ + includeUnknownFields: true, + registry: registry, + } for _, opt := range includeUnknownFields { opt(e) diff --git a/jsonencoder/marshallers.go b/jsonencoder/marshallers.go index 4b5acfd..cddf589 100644 --- a/jsonencoder/marshallers.go +++ b/jsonencoder/marshallers.go @@ -11,7 +11,6 @@ import ( "github.com/go-json-experiment/json/jsontext" "github.com/jhump/protoreflect/dynamic" "github.com/mr-tron/base58" - "github.com/streamingfast/firehose-core/protoregistry" "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/dynamicpb" @@ -19,7 +18,7 @@ import ( ) func (e *Encoder) anypb(encoder *jsontext.Encoder, t *anypb.Any, options json.Options) error { - msg, err := protoregistry.Unmarshal(t) + msg, err := e.registry.Unmarshal(t) if err != nil { return fmt.Errorf("unmarshalling proto any: %w", err) } @@ -61,7 +60,7 @@ func (e *Encoder) encodeKVList(encoder *jsontext.Encoder, t kvlist, options json func (e *Encoder) dynamicpbMessage(encoder *jsontext.Encoder, msg *dynamicpb.Message, options json.Options) error { var kvl kvlist - if e.IncludeUnknownFields { + if e.includeUnknownFields { x := msg.GetUnknown() fieldNumber, ofType, l := protowire.ConsumeField(x) if l > 0 { diff --git a/protoregistry/registry.go b/protoregistry/registry.go index fd2697a..75c7a7f 100644 --- a/protoregistry/registry.go +++ b/protoregistry/registry.go @@ -16,34 +16,42 @@ import ( // but to fix them we must re-generate it. //go:generate go run ./generator well_known.go protoregistry -func Register(chainFileDescriptor protoreflect.FileDescriptor, protoPaths ...string) error { +type Registry struct { + Types *protoregistry.Types + Files *protoregistry.Files +} +func NewRegistry(chainFileDescriptor protoreflect.FileDescriptor, protoPaths ...string) (*Registry, error) { + r := &Registry{ + Types: new(protoregistry.Types), + Files: new(protoregistry.Files), + } // Proto paths have the highest precedence, so we register them first if len(protoPaths) > 0 { - if err := RegisterFiles(protoPaths); err != nil { - return fmt.Errorf("register proto files: %w", err) + if err := r.RegisterFiles(protoPaths); err != nil { + return nil, fmt.Errorf("register proto files: %w", err) } } // Chain file descriptor has the second highest precedence, it always // override built-in types if defined. if chainFileDescriptor != nil { - err := RegisterFileDescriptor(chainFileDescriptor) + err := r.RegisterFileDescriptor(chainFileDescriptor) if err != nil { - return fmt.Errorf("register chain file descriptor: %w", err) + return nil, fmt.Errorf("register chain file descriptor: %w", err) } } //Last are well known types, they have the lowest precedence - err := RegisterWellKnownFileDescriptors() + err := RegisterWellKnownFileDescriptors(r) if err != nil { - return fmt.Errorf("registering well known file descriptors: %w", err) + return nil, fmt.Errorf("registering well known file descriptors: %w", err) } - return nil + return r, nil } -func RegisterFiles(files []string) error { +func (r *Registry) RegisterFiles(files []string) error { if len(files) == 0 { return nil } @@ -53,25 +61,25 @@ func RegisterFiles(files []string) error { return fmt.Errorf("parsing proto files: %w", err) } - return RegisterFileDescriptors(fileDescriptors) + return r.RegisterFileDescriptors(fileDescriptors) } -func RegisterFileDescriptors(fds []protoreflect.FileDescriptor) error { +func (r *Registry) RegisterFileDescriptors(fds []protoreflect.FileDescriptor) error { for _, fd := range fds { - err := RegisterFileDescriptor(fd) + err := r.RegisterFileDescriptor(fd) if err != nil { return fmt.Errorf("registering proto file: %w", err) } } return nil } -func RegisterFileDescriptor(fd protoreflect.FileDescriptor) error { +func (r *Registry) RegisterFileDescriptor(fd protoreflect.FileDescriptor) error { path := fd.Path() - _, err := protoregistry.GlobalFiles.FindFileByPath(path) + _, err := r.Files.FindFileByPath(path) if err != nil { if errors.Is(err, protoregistry.NotFound) { - // Register the new file descriptor. - if err := protoregistry.GlobalFiles.RegisterFile(fd); err != nil { + // NewRegistry the new file descriptor. + if err := r.Files.RegisterFile(fd); err != nil { return fmt.Errorf("registering proto file: %w", err) } @@ -83,8 +91,8 @@ func RegisterFileDescriptor(fd protoreflect.FileDescriptor) error { return fmt.Errorf("message type not found in the registered file") } - dmt := dynamicpb.NewMessageType(messageType) // Register the MessageType - err := protoregistry.GlobalTypes.RegisterMessage(dmt) + dmt := dynamicpb.NewMessageType(messageType) // NewRegistry the MessageType + err := r.Types.RegisterMessage(dmt) if err != nil { return fmt.Errorf("registering message type: %w", err) } @@ -98,8 +106,8 @@ func RegisterFileDescriptor(fd protoreflect.FileDescriptor) error { return nil } -func Unmarshal(a *anypb.Any) (*dynamicpb.Message, error) { - messageType, err := protoregistry.GlobalTypes.FindMessageByURL(a.TypeUrl) +func (r *Registry) Unmarshal(a *anypb.Any) (*dynamicpb.Message, error) { + messageType, err := r.Types.FindMessageByURL(a.TypeUrl) if err != nil { return nil, fmt.Errorf("failed to find message '%s': %v", urlToMessageFullName(a.TypeUrl), err) } diff --git a/protoregistry/registry_test.go b/protoregistry/registry_test.go index c809692..d4866e7 100644 --- a/protoregistry/registry_test.go +++ b/protoregistry/registry_test.go @@ -86,11 +86,11 @@ func TestUnmarshal(t *testing.T) { protoregistry.GlobalFiles = &protoregistry.Files{} protoregistry.GlobalTypes = &protoregistry.Types{} - err := Register(acme, tt.protoPaths...) + registry, err := NewRegistry(acme, tt.protoPaths...) require.NoError(t, err) a := &anypb.Any{TypeUrl: "type.googleapis.com/" + tt.typeURL, Value: tt.value} - out, err := Unmarshal(a) + out, err := registry.Unmarshal(a) tt.assertion(t, err) tt.want(t, out) diff --git a/protoregistry/well_known.go b/protoregistry/well_known.go index 752bddd..9c5bf37 100644 --- a/protoregistry/well_known.go +++ b/protoregistry/well_known.go @@ -5,15 +5,13 @@ import ( "encoding/hex" "fmt" - "google.golang.org/protobuf/reflect/protoregistry" - "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protodesc" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/descriptorpb" ) -func RegisterWellKnownFileDescriptors() error { +func RegisterWellKnownFileDescriptors(registry *Registry) error { protoFiles := []string{ // google/protobuf/timestamp.proto (https://buf.build/streamingfast/firehose-ethereum/docs/d869cb39aae947ecb0c7df6a1db2b61f:google.protobuf) "0a1f676f6f676c652f70726f746f6275662f74696d657374616d702e70726f746f120f676f6f676c652e70726f746f627566223b0a0954696d657374616d7012180a077365636f6e647318012001280352077365636f6e647312140a056e616e6f7318022001280552056e616e6f734285010a13636f6d2e676f6f676c652e70726f746f627566420e54696d657374616d7050726f746f50015a32676f6f676c652e676f6c616e672e6f72672f70726f746f6275662f74797065732f6b6e6f776e2f74696d657374616d707062f80101a20203475042aa021e476f6f676c652e50726f746f6275662e57656c6c4b6e6f776e5479706573620670726f746f33", @@ -56,11 +54,11 @@ func RegisterWellKnownFileDescriptors() error { } for _, protoFile := range protoFiles { - fd, err := protoToFileDescriptor(protoFile) + fd, err := protoToFileDescriptor(registry, protoFile) if err != nil { return fmt.Errorf("generating proto file: %w", err) } - err = RegisterFileDescriptor(fd) + err = registry.RegisterFileDescriptor(fd) if err != nil { return fmt.Errorf("registering file descriptor: %w", err) } @@ -69,7 +67,7 @@ func RegisterWellKnownFileDescriptors() error { return nil } -func protoToFileDescriptor(in string) (protoreflect.FileDescriptor, error) { +func protoToFileDescriptor(registry *Registry, in string) (protoreflect.FileDescriptor, error) { protoBytes, err := hex.DecodeString(in) if err != nil { panic(fmt.Errorf("failed to hex decode payload: %w", err)) @@ -80,7 +78,7 @@ func protoToFileDescriptor(in string) (protoreflect.FileDescriptor, error) { return nil, fmt.Errorf("failed to unmarshal file descriptor: %w", err) } - fd, err := protodesc.NewFile(fileDescriptorProto, protoregistry.GlobalFiles) + fd, err := protodesc.NewFile(fileDescriptorProto, registry.Files) if err != nil { return nil, fmt.Errorf("creating new file descriptor: %w", err) From a0849b438f692e81da067cb2c73bca17ddca3e8e Mon Sep 17 00:00:00 2001 From: billettc Date: Wed, 24 Jan 2024 14:07:21 -0500 Subject: [PATCH 25/44] a bit of refactoring --- cmd/tools/compare/tools_compare_blocks.go | 16 ++--- cmd/tools/print/tools_print.go | 12 ++-- {jsonencoder => json}/marshallers.go | 63 ++++++++++++++++--- jsonencoder/encoder.go | 55 ---------------- {protoregistry => proto}/README.md | 0 .../generator/generator.go | 0 .../generator/template.gotmpl | 0 {protoregistry => proto}/registry.go | 2 +- {protoregistry => proto}/registry_test.go | 7 +-- .../testdata/acme/acme.proto | 0 .../override/sf/ethereum/type/v2/type.proto | 0 .../testdata/override_acme/acme.proto | 0 {protoregistry => proto}/utils.go | 2 +- {protoregistry => proto}/well_known.go | 2 +- 14 files changed, 72 insertions(+), 87 deletions(-) rename {jsonencoder => json}/marshallers.go (64%) delete mode 100644 jsonencoder/encoder.go rename {protoregistry => proto}/README.md (100%) rename {protoregistry => proto}/generator/generator.go (100%) rename {protoregistry => proto}/generator/template.gotmpl (100%) rename {protoregistry => proto}/registry.go (99%) rename {protoregistry => proto}/registry_test.go (94%) rename {protoregistry => proto}/testdata/acme/acme.proto (100%) rename {protoregistry => proto}/testdata/override/sf/ethereum/type/v2/type.proto (100%) rename {protoregistry => proto}/testdata/override_acme/acme.proto (100%) rename {protoregistry => proto}/utils.go (98%) rename {protoregistry => proto}/well_known.go (99%) diff --git a/cmd/tools/compare/tools_compare_blocks.go b/cmd/tools/compare/tools_compare_blocks.go index 27e6be7..0dc5c88 100644 --- a/cmd/tools/compare/tools_compare_blocks.go +++ b/cmd/tools/compare/tools_compare_blocks.go @@ -31,8 +31,8 @@ import ( "github.com/streamingfast/dstore" firecore "github.com/streamingfast/firehose-core" "github.com/streamingfast/firehose-core/cmd/tools/check" - "github.com/streamingfast/firehose-core/jsonencoder" - "github.com/streamingfast/firehose-core/protoregistry" + "github.com/streamingfast/firehose-core/json" + fcproto "github.com/streamingfast/firehose-core/proto" "github.com/streamingfast/firehose-core/types" "go.uber.org/multierr" "google.golang.org/protobuf/proto" @@ -117,7 +117,7 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm segments: segments, } - registry, err := protoregistry.NewRegistry(nil, protoPaths...) + registry, err := fcproto.NewRegistry(nil, protoPaths...) if err != nil { return fmt.Errorf("creating registry: %w", err) } @@ -233,7 +233,7 @@ func readBundle( fileStartBlock, stopBlock uint64, warnAboutExtraBlocks *sync.Once, - registry *protoregistry.Registry, + registry *fcproto.Registry, ) ([]string, map[string]*dynamicpb.Message, error) { fileReader, err := store.OpenObject(ctx, filename) if err != nil { @@ -330,7 +330,7 @@ func (s *state) print() { fmt.Printf("✖ Segment %d - %s has %d different blocks and %d missing blocks (%d blocks counted)\n", s.segments[s.currentSegmentIdx].Start, endBlock, s.differencesFound, s.missingBlocks, s.totalBlocksCounted) } -func Compare(reference proto.Message, current proto.Message, includeUnknownFields bool, registry *protoregistry.Registry) (differences []string) { +func Compare(reference proto.Message, current proto.Message, includeUnknownFields bool, registry *fcproto.Registry) (differences []string) { if reference == nil && current == nil { return nil } @@ -349,11 +349,11 @@ func Compare(reference proto.Message, current proto.Message, includeUnknownField //todo: check if there is a equals that do not compare unknown fields if !proto.Equal(reference, current) { - var opts []jsonencoder.EncoderOption + var opts []json.EncoderOption if !includeUnknownFields { - opts = append(opts, jsonencoder.WithoutUnknownFields()) + opts = append(opts, json.WithoutUnknownFields()) } - encoder := jsonencoder.New(registry, opts...) + encoder := json.New(registry, opts...) referenceAsJSON, err := encoder.MarshalToString(reference) cli.NoError(err, "marshal JSON reference") diff --git a/cmd/tools/print/tools_print.go b/cmd/tools/print/tools_print.go index af41996..c863b5c 100644 --- a/cmd/tools/print/tools_print.go +++ b/cmd/tools/print/tools_print.go @@ -26,8 +26,8 @@ import ( "github.com/streamingfast/cli/sflags" "github.com/streamingfast/dstore" firecore "github.com/streamingfast/firehose-core" - "github.com/streamingfast/firehose-core/jsonencoder" - "github.com/streamingfast/firehose-core/protoregistry" + fcjson "github.com/streamingfast/firehose-core/json" + "github.com/streamingfast/firehose-core/proto" "github.com/streamingfast/firehose-core/types" "google.golang.org/protobuf/reflect/protoreflect" ) @@ -209,7 +209,7 @@ func toolsPrintCmdGetOutputMode(cmd *cobra.Command) (PrintOutputMode, error) { return out, nil } -func displayBlock[B firecore.Block](pbBlock *pbbstream.Block, chain *firecore.Chain[B], outputMode PrintOutputMode, printTransactions bool, encoder *jsonencoder.Encoder) error { +func displayBlock[B firecore.Block](pbBlock *pbbstream.Block, chain *firecore.Chain[B], outputMode PrintOutputMode, printTransactions bool, encoder *fcjson.Marshaller) error { if pbBlock == nil { return fmt.Errorf("block is nil") } @@ -268,11 +268,11 @@ func PrintBStreamBlock(b *pbbstream.Block, printTransactions bool, out io.Writer return nil } -func SetupJsonEncoder(cmd *cobra.Command, chainFileDescriptor protoreflect.FileDescriptor) (*jsonencoder.Encoder, error) { - registry, err := protoregistry.NewRegistry(chainFileDescriptor, sflags.MustGetStringSlice(cmd, "proto-paths")...) +func SetupJsonEncoder(cmd *cobra.Command, chainFileDescriptor protoreflect.FileDescriptor) (*fcjson.Marshaller, error) { + registry, err := proto.NewRegistry(chainFileDescriptor, sflags.MustGetStringSlice(cmd, "proto-paths")...) if err != nil { return nil, fmt.Errorf("new registry: %w", err) } - return jsonencoder.New(registry), nil + return fcjson.New(registry), nil } diff --git a/jsonencoder/marshallers.go b/json/marshallers.go similarity index 64% rename from jsonencoder/marshallers.go rename to json/marshallers.go index cddf589..d2f1135 100644 --- a/jsonencoder/marshallers.go +++ b/json/marshallers.go @@ -1,23 +1,68 @@ -package jsonencoder +package json import ( + "bytes" "encoding/hex" "fmt" + "os" "strings" - "golang.org/x/exp/slices" - "github.com/go-json-experiment/json" "github.com/go-json-experiment/json/jsontext" "github.com/jhump/protoreflect/dynamic" "github.com/mr-tron/base58" + "github.com/streamingfast/firehose-core/proto" + "golang.org/x/exp/slices" "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/dynamicpb" "google.golang.org/protobuf/types/known/anypb" ) -func (e *Encoder) anypb(encoder *jsontext.Encoder, t *anypb.Any, options json.Options) error { +type Marshaller struct { + marshallers *json.Marshalers + includeUnknownFields bool + registry *proto.Registry +} + +type EncoderOption func(*Marshaller) + +func WithoutUnknownFields() EncoderOption { + return func(e *Marshaller) { + e.includeUnknownFields = false + } +} +func New(registry *proto.Registry, includeUnknownFields ...EncoderOption) *Marshaller { + e := &Marshaller{ + includeUnknownFields: true, + registry: registry, + } + + for _, opt := range includeUnknownFields { + opt(e) + } + e.setMarshallers("") + return e +} + +func (e *Marshaller) Marshal(in any) error { + err := json.MarshalEncode(jsontext.NewEncoder(os.Stdout), in, json.WithMarshalers(e.marshallers)) + if err != nil { + return fmt.Errorf("marshalling and encoding block to json: %w", err) + } + return nil +} + +func (e *Marshaller) MarshalToString(in any) (string, error) { + buf := bytes.NewBuffer(nil) + if err := json.MarshalEncode(jsontext.NewEncoder(buf), in, json.WithMarshalers(e.marshallers)); err != nil { + return "", err + } + return buf.String(), nil + +} + +func (e *Marshaller) anypb(encoder *jsontext.Encoder, t *anypb.Any, options json.Options) error { msg, err := e.registry.Unmarshal(t) if err != nil { return fmt.Errorf("unmarshalling proto any: %w", err) @@ -36,7 +81,7 @@ type kv struct { value any } -func (e *Encoder) encodeKVList(encoder *jsontext.Encoder, t kvlist, options json.Options) error { +func (e *Marshaller) encodeKVList(encoder *jsontext.Encoder, t kvlist, options json.Options) error { if err := encoder.WriteToken(jsontext.ObjectStart); err != nil { return err } @@ -57,7 +102,7 @@ func (e *Encoder) encodeKVList(encoder *jsontext.Encoder, t kvlist, options json return encoder.WriteToken(jsontext.ObjectEnd) } -func (e *Encoder) dynamicpbMessage(encoder *jsontext.Encoder, msg *dynamicpb.Message, options json.Options) error { +func (e *Marshaller) dynamicpbMessage(encoder *jsontext.Encoder, msg *dynamicpb.Message, options json.Options) error { var kvl kvlist if e.includeUnknownFields { @@ -104,15 +149,15 @@ func (e *Encoder) dynamicpbMessage(encoder *jsontext.Encoder, msg *dynamicpb.Mes return encoder.WriteValue(cnt) } -func (e *Encoder) base58Bytes(encoder *jsontext.Encoder, t []byte, options json.Options) error { +func (e *Marshaller) base58Bytes(encoder *jsontext.Encoder, t []byte, options json.Options) error { return encoder.WriteToken(jsontext.String(base58.Encode(t))) } -func (e *Encoder) hexBytes(encoder *jsontext.Encoder, t []byte, options json.Options) error { +func (e *Marshaller) hexBytes(encoder *jsontext.Encoder, t []byte, options json.Options) error { return encoder.WriteToken(jsontext.String(hex.EncodeToString(t))) } -func (e *Encoder) setMarshallers(typeURL string) { +func (e *Marshaller) setMarshallers(typeURL string) { out := []*json.Marshalers{ json.MarshalFuncV2(e.anypb), json.MarshalFuncV2(e.dynamicpbMessage), diff --git a/jsonencoder/encoder.go b/jsonencoder/encoder.go deleted file mode 100644 index fb6241e..0000000 --- a/jsonencoder/encoder.go +++ /dev/null @@ -1,55 +0,0 @@ -package jsonencoder - -import ( - "bytes" - "fmt" - "os" - - "github.com/streamingfast/firehose-core/protoregistry" - - "github.com/go-json-experiment/json" - "github.com/go-json-experiment/json/jsontext" -) - -type Encoder struct { - marshallers *json.Marshalers - includeUnknownFields bool - registry *protoregistry.Registry -} - -type EncoderOption func(*Encoder) - -func WithoutUnknownFields() EncoderOption { - return func(e *Encoder) { - e.includeUnknownFields = false - } -} -func New(registry *protoregistry.Registry, includeUnknownFields ...EncoderOption) *Encoder { - e := &Encoder{ - includeUnknownFields: true, - registry: registry, - } - - for _, opt := range includeUnknownFields { - opt(e) - } - e.setMarshallers("") - return e -} - -func (e *Encoder) Marshal(in any) error { - err := json.MarshalEncode(jsontext.NewEncoder(os.Stdout), in, json.WithMarshalers(e.marshallers)) - if err != nil { - return fmt.Errorf("marshalling and encoding block to json: %w", err) - } - return nil -} - -func (e *Encoder) MarshalToString(in any) (string, error) { - buf := bytes.NewBuffer(nil) - if err := json.MarshalEncode(jsontext.NewEncoder(buf), in, json.WithMarshalers(e.marshallers)); err != nil { - return "", err - } - return buf.String(), nil - -} diff --git a/protoregistry/README.md b/proto/README.md similarity index 100% rename from protoregistry/README.md rename to proto/README.md diff --git a/protoregistry/generator/generator.go b/proto/generator/generator.go similarity index 100% rename from protoregistry/generator/generator.go rename to proto/generator/generator.go diff --git a/protoregistry/generator/template.gotmpl b/proto/generator/template.gotmpl similarity index 100% rename from protoregistry/generator/template.gotmpl rename to proto/generator/template.gotmpl diff --git a/protoregistry/registry.go b/proto/registry.go similarity index 99% rename from protoregistry/registry.go rename to proto/registry.go index 75c7a7f..ccf6491 100644 --- a/protoregistry/registry.go +++ b/proto/registry.go @@ -1,4 +1,4 @@ -package protoregistry +package proto import ( "errors" diff --git a/protoregistry/registry_test.go b/proto/registry_test.go similarity index 94% rename from protoregistry/registry_test.go rename to proto/registry_test.go index d4866e7..57b1144 100644 --- a/protoregistry/registry_test.go +++ b/proto/registry_test.go @@ -1,4 +1,4 @@ -package protoregistry +package proto import ( "testing" @@ -6,7 +6,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/types/dynamicpb" "google.golang.org/protobuf/types/known/anypb" ) @@ -82,10 +81,6 @@ func TestUnmarshal(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - - protoregistry.GlobalFiles = &protoregistry.Files{} - protoregistry.GlobalTypes = &protoregistry.Types{} - registry, err := NewRegistry(acme, tt.protoPaths...) require.NoError(t, err) diff --git a/protoregistry/testdata/acme/acme.proto b/proto/testdata/acme/acme.proto similarity index 100% rename from protoregistry/testdata/acme/acme.proto rename to proto/testdata/acme/acme.proto diff --git a/protoregistry/testdata/override/sf/ethereum/type/v2/type.proto b/proto/testdata/override/sf/ethereum/type/v2/type.proto similarity index 100% rename from protoregistry/testdata/override/sf/ethereum/type/v2/type.proto rename to proto/testdata/override/sf/ethereum/type/v2/type.proto diff --git a/protoregistry/testdata/override_acme/acme.proto b/proto/testdata/override_acme/acme.proto similarity index 100% rename from protoregistry/testdata/override_acme/acme.proto rename to proto/testdata/override_acme/acme.proto diff --git a/protoregistry/utils.go b/proto/utils.go similarity index 98% rename from protoregistry/utils.go rename to proto/utils.go index f35c71b..b5a24cf 100644 --- a/protoregistry/utils.go +++ b/proto/utils.go @@ -1,4 +1,4 @@ -package protoregistry +package proto import ( "fmt" diff --git a/protoregistry/well_known.go b/proto/well_known.go similarity index 99% rename from protoregistry/well_known.go rename to proto/well_known.go index 9c5bf37..5ad85df 100644 --- a/protoregistry/well_known.go +++ b/proto/well_known.go @@ -1,5 +1,5 @@ // Code generated by 'go run github.com/streamingfast/firehose-core/protoregistry/generator well_known.go protoregistry', DO NOT EDIT! -package protoregistry +package proto import ( "encoding/hex" From 16363f499316d7a3645e2811c31d26ffed41f3ce Mon Sep 17 00:00:00 2001 From: billettc Date: Wed, 24 Jan 2024 15:46:29 -0500 Subject: [PATCH 26/44] bytes encoding is now an option of our json marshaller. added new option `bytes-encoding` to print cmd --- cmd/tools/compare/tools_compare_blocks.go | 4 +- cmd/tools/firehose/client.go | 2 +- cmd/tools/print/tools_print.go | 15 +++- json/marshallers.go | 97 +++++++++++------------ proto/generator/generator.go | 11 ++- proto/generator/template.gotmpl | 56 +++---------- proto/registry.go | 2 +- proto/well_known.go | 50 ++---------- proto/well_known_types.go | 61 ++++++++++++++ 9 files changed, 147 insertions(+), 151 deletions(-) create mode 100644 proto/well_known_types.go diff --git a/cmd/tools/compare/tools_compare_blocks.go b/cmd/tools/compare/tools_compare_blocks.go index 0dc5c88..5b66daa 100644 --- a/cmd/tools/compare/tools_compare_blocks.go +++ b/cmd/tools/compare/tools_compare_blocks.go @@ -349,11 +349,11 @@ func Compare(reference proto.Message, current proto.Message, includeUnknownField //todo: check if there is a equals that do not compare unknown fields if !proto.Equal(reference, current) { - var opts []json.EncoderOption + var opts []json.MarshallerOption if !includeUnknownFields { opts = append(opts, json.WithoutUnknownFields()) } - encoder := json.New(registry, opts...) + encoder := json.NewMarshaller(registry, opts...) referenceAsJSON, err := encoder.MarshalToString(reference) cli.NoError(err, "marshal JSON reference") diff --git a/cmd/tools/firehose/client.go b/cmd/tools/firehose/client.go index 5a4e87f..094e2eb 100644 --- a/cmd/tools/firehose/client.go +++ b/cmd/tools/firehose/client.go @@ -89,7 +89,7 @@ func getFirehoseClientE[B firecore.Block](chain *firecore.Chain[B], rootLog *zap }() } - jencoder, err := print.SetupJsonEncoder(cmd, chain.BlockFactory().ProtoReflect().Descriptor().ParentFile()) + jencoder, err := print.SetupJsonMarshaller(cmd, chain.BlockFactory().ProtoReflect().Descriptor().ParentFile()) if err != nil { return fmt.Errorf("unable to create json encoder: %w", err) } diff --git a/cmd/tools/print/tools_print.go b/cmd/tools/print/tools_print.go index c863b5c..69bf43f 100644 --- a/cmd/tools/print/tools_print.go +++ b/cmd/tools/print/tools_print.go @@ -54,6 +54,7 @@ func NewToolsPrintCmd[B firecore.Block](chain *firecore.Chain[B]) *cobra.Command toolsPrintCmd.AddCommand(toolsPrintMergedBlocksCmd) toolsPrintCmd.PersistentFlags().StringP("output", "o", "text", "Output mode for block printing, either 'text', 'json' or 'jsonl'") + toolsPrintCmd.PersistentFlags().String("bytes-encoding", "hex", "Encoding for bytes fields, either 'hex' or 'base58'") toolsPrintCmd.PersistentFlags().StringSlice("proto-paths", []string{""}, "Paths to proto files to use for dynamic decoding of blocks") toolsPrintCmd.PersistentFlags().Bool("transactions", false, "When in 'text' output mode, also print transactions summary") @@ -100,7 +101,7 @@ func createToolsPrintMergedBlocksE[B firecore.Block](chain *firecore.Chain[B]) f return err } - jencoder, err := SetupJsonEncoder(cmd, chain.BlockFactory().ProtoReflect().Descriptor().ParentFile()) + jencoder, err := SetupJsonMarshaller(cmd, chain.BlockFactory().ProtoReflect().Descriptor().ParentFile()) if err != nil { return fmt.Errorf("unable to create json encoder: %w", err) } @@ -137,7 +138,7 @@ func createToolsPrintOneBlockE[B firecore.Block](chain *firecore.Chain[B]) firec printTransactions := sflags.MustGetBool(cmd, "transactions") - jencoder, err := SetupJsonEncoder(cmd, chain.BlockFactory().ProtoReflect().Descriptor().ParentFile()) + jencoder, err := SetupJsonMarshaller(cmd, chain.BlockFactory().ProtoReflect().Descriptor().ParentFile()) if err != nil { return fmt.Errorf("unable to create json encoder: %w", err) } @@ -268,11 +269,17 @@ func PrintBStreamBlock(b *pbbstream.Block, printTransactions bool, out io.Writer return nil } -func SetupJsonEncoder(cmd *cobra.Command, chainFileDescriptor protoreflect.FileDescriptor) (*fcjson.Marshaller, error) { +func SetupJsonMarshaller(cmd *cobra.Command, chainFileDescriptor protoreflect.FileDescriptor) (*fcjson.Marshaller, error) { registry, err := proto.NewRegistry(chainFileDescriptor, sflags.MustGetStringSlice(cmd, "proto-paths")...) if err != nil { return nil, fmt.Errorf("new registry: %w", err) } - return fcjson.New(registry), nil + var options []fcjson.MarshallerOption + bytesEncoding := sflags.MustGetString(cmd, "bytes-encoding") + if bytesEncoding == "base58" { + options = append(options, fcjson.WithBytesEncoderFunc(fcjson.ToBase58)) + } + + return fcjson.NewMarshaller(registry, options...), nil } diff --git a/json/marshallers.go b/json/marshallers.go index d2f1135..14b67c0 100644 --- a/json/marshallers.go +++ b/json/marshallers.go @@ -5,11 +5,9 @@ import ( "encoding/hex" "fmt" "os" - "strings" "github.com/go-json-experiment/json" "github.com/go-json-experiment/json/jsontext" - "github.com/jhump/protoreflect/dynamic" "github.com/mr-tron/base58" "github.com/streamingfast/firehose-core/proto" "golang.org/x/exp/slices" @@ -19,69 +17,84 @@ import ( "google.golang.org/protobuf/types/known/anypb" ) +type kvList []*kv +type kv struct { + key string + value any +} + type Marshaller struct { marshallers *json.Marshalers includeUnknownFields bool registry *proto.Registry + bytesEncoderFunc func(encoder *jsontext.Encoder, t []byte, options json.Options) error } -type EncoderOption func(*Marshaller) +type MarshallerOption func(*Marshaller) -func WithoutUnknownFields() EncoderOption { +func WithoutUnknownFields() MarshallerOption { return func(e *Marshaller) { e.includeUnknownFields = false } } -func New(registry *proto.Registry, includeUnknownFields ...EncoderOption) *Marshaller { - e := &Marshaller{ +func WithBytesEncoderFunc(f func(encoder *jsontext.Encoder, t []byte, options json.Options) error) MarshallerOption { + return func(e *Marshaller) { + e.bytesEncoderFunc = f + } +} + +func NewMarshaller(registry *proto.Registry, options ...MarshallerOption) *Marshaller { + m := &Marshaller{ includeUnknownFields: true, registry: registry, + bytesEncoderFunc: ToHex, } - for _, opt := range includeUnknownFields { - opt(e) + for _, opt := range options { + opt(m) } - e.setMarshallers("") - return e + + m.marshallers = json.NewMarshalers( + json.MarshalFuncV2(m.anypb), + json.MarshalFuncV2(m.dynamicpbMessage), + json.MarshalFuncV2(m.encodeKVList), + json.MarshalFuncV2(m.bytesEncoderFunc), + ) + + return m } -func (e *Marshaller) Marshal(in any) error { - err := json.MarshalEncode(jsontext.NewEncoder(os.Stdout), in, json.WithMarshalers(e.marshallers)) +func (m *Marshaller) Marshal(in any) error { + err := json.MarshalEncode(jsontext.NewEncoder(os.Stdout), in, json.WithMarshalers(m.marshallers)) if err != nil { return fmt.Errorf("marshalling and encoding block to json: %w", err) } return nil } -func (e *Marshaller) MarshalToString(in any) (string, error) { +func (m *Marshaller) MarshalToString(in any) (string, error) { buf := bytes.NewBuffer(nil) - if err := json.MarshalEncode(jsontext.NewEncoder(buf), in, json.WithMarshalers(e.marshallers)); err != nil { + if err := json.MarshalEncode(jsontext.NewEncoder(buf), in, json.WithMarshalers(m.marshallers)); err != nil { return "", err } return buf.String(), nil } -func (e *Marshaller) anypb(encoder *jsontext.Encoder, t *anypb.Any, options json.Options) error { - msg, err := e.registry.Unmarshal(t) +func (m *Marshaller) anypb(encoder *jsontext.Encoder, t *anypb.Any, options json.Options) error { + msg, err := m.registry.Unmarshal(t) if err != nil { return fmt.Errorf("unmarshalling proto any: %w", err) } - e.setMarshallers(t.TypeUrl) - cnt, err := json.Marshal(msg, json.WithMarshalers(e.marshallers)) + + cnt, err := json.Marshal(msg, json.WithMarshalers(m.marshallers)) if err != nil { return fmt.Errorf("json marshalling proto any: %w", err) } return encoder.WriteValue(cnt) } -type kvlist []*kv -type kv struct { - key string - value any -} - -func (e *Marshaller) encodeKVList(encoder *jsontext.Encoder, t kvlist, options json.Options) error { +func (m *Marshaller) encodeKVList(encoder *jsontext.Encoder, t kvList, options json.Options) error { if err := encoder.WriteToken(jsontext.ObjectStart); err != nil { return err } @@ -90,7 +103,7 @@ func (e *Marshaller) encodeKVList(encoder *jsontext.Encoder, t kvlist, options j return err } - cnt, err := json.Marshal(kv.value, json.WithMarshalers(e.marshallers)) + cnt, err := json.Marshal(kv.value, json.WithMarshalers(m.marshallers)) if err != nil { return fmt.Errorf("json marshalling of value : %w", err) } @@ -102,10 +115,10 @@ func (e *Marshaller) encodeKVList(encoder *jsontext.Encoder, t kvlist, options j return encoder.WriteToken(jsontext.ObjectEnd) } -func (e *Marshaller) dynamicpbMessage(encoder *jsontext.Encoder, msg *dynamicpb.Message, options json.Options) error { - var kvl kvlist +func (m *Marshaller) dynamicpbMessage(encoder *jsontext.Encoder, msg *dynamicpb.Message, options json.Options) error { + var kvl kvList - if e.includeUnknownFields { + if m.includeUnknownFields { x := msg.GetUnknown() fieldNumber, ofType, l := protowire.ConsumeField(x) if l > 0 { @@ -142,37 +155,17 @@ func (e *Marshaller) dynamicpbMessage(encoder *jsontext.Encoder, msg *dynamicpb. return a.key < b.key }) - cnt, err := json.Marshal(kvl, json.WithMarshalers(e.marshallers)) + cnt, err := json.Marshal(kvl, json.WithMarshalers(m.marshallers)) if err != nil { return fmt.Errorf("json marshalling proto any: %w", err) } return encoder.WriteValue(cnt) } -func (e *Marshaller) base58Bytes(encoder *jsontext.Encoder, t []byte, options json.Options) error { +func ToBase58(encoder *jsontext.Encoder, t []byte, options json.Options) error { return encoder.WriteToken(jsontext.String(base58.Encode(t))) } -func (e *Marshaller) hexBytes(encoder *jsontext.Encoder, t []byte, options json.Options) error { +func ToHex(encoder *jsontext.Encoder, t []byte, options json.Options) error { return encoder.WriteToken(jsontext.String(hex.EncodeToString(t))) } - -func (e *Marshaller) setMarshallers(typeURL string) { - out := []*json.Marshalers{ - json.MarshalFuncV2(e.anypb), - json.MarshalFuncV2(e.dynamicpbMessage), - json.MarshalFuncV2(e.encodeKVList), - } - - if strings.Contains(typeURL, "solana") { - dynamic.SetDefaultBytesRepresentation(dynamic.BytesAsBase58) - out = append(out, json.MarshalFuncV2(e.base58Bytes)) - e.marshallers = json.NewMarshalers(out...) - return - } - - dynamic.SetDefaultBytesRepresentation(dynamic.BytesAsHex) - out = append(out, json.MarshalFuncV2(e.hexBytes)) - e.marshallers = json.NewMarshalers(out...) - return -} diff --git a/proto/generator/generator.go b/proto/generator/generator.go index fd3e081..fb3eeb7 100644 --- a/proto/generator/generator.go +++ b/proto/generator/generator.go @@ -15,13 +15,12 @@ import ( "text/template" "time" - "google.golang.org/protobuf/proto" - "buf.build/gen/go/bufbuild/reflect/connectrpc/go/buf/reflect/v1beta1/reflectv1beta1connect" reflectv1beta1 "buf.build/gen/go/bufbuild/reflect/protocolbuffers/go/buf/reflect/v1beta1" connect "connectrpc.com/connect" "github.com/iancoleman/strcase" "github.com/streamingfast/cli" + "google.golang.org/protobuf/proto" ) //go:embed *.gotmpl @@ -77,10 +76,17 @@ func main() { name = *file.Name } + bytesEncoding := "hex" + + if strings.Contains(name, "solana") { + bytesEncoding = "base58" + } + protofiles = append(protofiles, ProtoFile{ Name: name, Data: cnt, BufRegistryPackageURL: buildBufRegistryPackageURL(wellKnownProtoRepo, deferPtr(file.Package, ""), fileDescriptorSet.Msg.Version), + BytesEncoding: bytesEncoding, }) } // avoid hitting the buf.build rate limit @@ -124,6 +130,7 @@ type ProtoFile struct { Name string Data []byte BufRegistryPackageURL string + BytesEncoding string } func templateFunctions() template.FuncMap { diff --git a/proto/generator/template.gotmpl b/proto/generator/template.gotmpl index 33bf5d7..1da9e24 100644 --- a/proto/generator/template.gotmpl +++ b/proto/generator/template.gotmpl @@ -1,51 +1,15 @@ // Code generated by 'go run github.com/streamingfast/firehose-core/protoregistry/generator well_known.go protoregistry', DO NOT EDIT! package {{.Package}} -import ( - "fmt" - "encoding/hex" - - "github.com/jhump/protoreflect/desc" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/descriptorpb" -) - - -var WellKnownRegistry = New() +var wellKnownTypes []*WellKnownType func init() { - protoFiles := []string{ - {{- range .ProtoFiles}} - - // {{.Name}} ({{.BufRegistryPackageURL}}) - "{{.Data | toHex}}", - {{- end}} - } - - var files []*descriptorpb.FileDescriptorProto - for _, protoFile := range protoFiles { - files = append(files, mustProtoToFileDescriptor(protoFile)) - } - - fdmap, err := desc.CreateFileDescriptors(files) - if err != nil { - panic(fmt.Errorf("failed to create file descriptor map: %w", err)) - return - } - - for _, fd := range fdmap { - WellKnownRegistry.RegisterFileDescriptor(fd) - } -} - -func mustProtoToFileDescriptor(in string) *descriptorpb.FileDescriptorProto { - protoBytes, err := hex.DecodeString(in) - if err != nil { - panic(fmt.Errorf("failed to hex decode payload: %w", err)) - } - out := &descriptorpb.FileDescriptorProto{} - if err := proto.Unmarshal(protoBytes, out); err != nil { - panic(fmt.Errorf("failed to unmarshal file descriptor: %w", err)) - } - return out -} + wellKnownTypes = []*WellKnownType{ +{{- range .ProtoFiles}} + { + // {{.Name}} ({{.BufRegistryPackageURL}}) + proto: "{{.Data | toHex}}", + }, +{{- end}} + } +} \ No newline at end of file diff --git a/proto/registry.go b/proto/registry.go index ccf6491..7df761d 100644 --- a/proto/registry.go +++ b/proto/registry.go @@ -14,7 +14,7 @@ import ( // Generate the flags based on Go code in this project directly, this however // creates a chicken & egg problem if there is compilation error within the project // but to fix them we must re-generate it. -//go:generate go run ./generator well_known.go protoregistry +//go:generate go run ./generator well_known_types.go proto type Registry struct { Types *protoregistry.Types diff --git a/proto/well_known.go b/proto/well_known.go index 5ad85df..53f5952 100644 --- a/proto/well_known.go +++ b/proto/well_known.go @@ -1,4 +1,3 @@ -// Code generated by 'go run github.com/streamingfast/firehose-core/protoregistry/generator well_known.go protoregistry', DO NOT EDIT! package proto import ( @@ -11,50 +10,15 @@ import ( "google.golang.org/protobuf/types/descriptorpb" ) -func RegisterWellKnownFileDescriptors(registry *Registry) error { - protoFiles := []string{ - // google/protobuf/timestamp.proto (https://buf.build/streamingfast/firehose-ethereum/docs/d869cb39aae947ecb0c7df6a1db2b61f:google.protobuf) - "0a1f676f6f676c652f70726f746f6275662f74696d657374616d702e70726f746f120f676f6f676c652e70726f746f627566223b0a0954696d657374616d7012180a077365636f6e647318012001280352077365636f6e647312140a056e616e6f7318022001280552056e616e6f734285010a13636f6d2e676f6f676c652e70726f746f627566420e54696d657374616d7050726f746f50015a32676f6f676c652e676f6c616e672e6f72672f70726f746f6275662f74797065732f6b6e6f776e2f74696d657374616d707062f80101a20203475042aa021e476f6f676c652e50726f746f6275662e57656c6c4b6e6f776e5479706573620670726f746f33", - - // sf/ethereum/substreams/v1/rpc.proto (https://buf.build/streamingfast/firehose-ethereum/docs/d869cb39aae947ecb0c7df6a1db2b61f:sf.ethereum.substreams.v1) - "0a2373662f657468657265756d2f73756273747265616d732f76312f7270632e70726f746f121973662e657468657265756d2e73756273747265616d732e763122440a0852706343616c6c7312380a0563616c6c7318012003280b32222e73662e657468657265756d2e73756273747265616d732e76312e52706343616c6c520563616c6c7322360a0752706343616c6c12170a07746f5f6164647218012001280c5206746f4164647212120a046461746118022001280c52046461746122540a0c527063526573706f6e73657312440a09726573706f6e73657318012003280b32262e73662e657468657265756d2e73756273747265616d732e76312e527063526573706f6e73655209726573706f6e73657322370a0b527063526573706f6e736512100a0372617718012001280c520372617712160a066661696c656418022001280852066661696c656442575a556769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d657468657265756d2f74797065732f70622f73662f657468657265756d2f73756273747265616d732f76313b70626574687373620670726f746f33", - - // sf/ethereum/transform/v1/transforms.proto (https://buf.build/streamingfast/firehose-ethereum/docs/d869cb39aae947ecb0c7df6a1db2b61f:sf.ethereum.transform.v1) - "0a2973662f657468657265756d2f7472616e73666f726d2f76312f7472616e73666f726d732e70726f746f121873662e657468657265756d2e7472616e73666f726d2e763122d6010a0e436f6d62696e656446696c74657212440a0b6c6f675f66696c7465727318012003280b32232e73662e657468657265756d2e7472616e73666f726d2e76312e4c6f6746696c746572520a6c6f6746696c7465727312490a0c63616c6c5f66696c7465727318022003280b32262e73662e657468657265756d2e7472616e73666f726d2e76312e43616c6c546f46696c746572520b63616c6c46696c7465727312330a1673656e645f616c6c5f626c6f636b5f68656164657273180320012808521373656e64416c6c426c6f636b4865616465727322560a0e4d756c74694c6f6746696c74657212440a0b6c6f675f66696c7465727318012003280b32232e73662e657468657265756d2e7472616e73666f726d2e76312e4c6f6746696c746572520a6c6f6746696c7465727322540a094c6f6746696c746572121c0a0961646472657373657318012003280c520961646472657373657312290a106576656e745f7369676e61747572657318022003280c520f6576656e745369676e617475726573225e0a114d756c746943616c6c546f46696c74657212490a0c63616c6c5f66696c7465727318012003280b32262e73662e657468657265756d2e7472616e73666f726d2e76312e43616c6c546f46696c746572520b63616c6c46696c74657273224c0a0c43616c6c546f46696c746572121c0a0961646472657373657318012003280c5209616464726573736573121e0a0a7369676e61747572657318022003280c520a7369676e617475726573220c0a0a4865616465724f6e6c79425a5a586769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d657468657265756d2f74797065732f70622f73662f657468657265756d2f7472616e73666f726d2f76313b70627472616e73666f726d620670726f746f33", - - // sf/ethereum/type/v2/type.proto (https://buf.build/streamingfast/firehose-ethereum/docs/d869cb39aae947ecb0c7df6a1db2b61f:sf.ethereum.type.v2) - "0a1e73662f657468657265756d2f747970652f76322f747970652e70726f746f121373662e657468657265756d2e747970652e76321a1f676f6f676c652f70726f746f6275662f74696d657374616d702e70726f746f228e050a05426c6f636b12120a046861736818022001280c52046861736812160a066e756d62657218032001280452066e756d62657212120a0473697a65180420012804520473697a6512380a0668656164657218052001280b32202e73662e657468657265756d2e747970652e76322e426c6f636b486561646572520668656164657212380a06756e636c657318062003280b32202e73662e657468657265756d2e747970652e76322e426c6f636b4865616465725206756e636c657312540a127472616e73616374696f6e5f747261636573180a2003280b32252e73662e657468657265756d2e747970652e76322e5472616e73616374696f6e547261636552117472616e73616374696f6e547261636573124b0a0f62616c616e63655f6368616e676573180b2003280b32222e73662e657468657265756d2e747970652e76322e42616c616e63654368616e6765520e62616c616e63654368616e67657312490a0c64657461696c5f6c6576656c180c2001280e32262e73662e657468657265756d2e747970652e76322e426c6f636b2e44657461696c4c6576656c520b64657461696c4c6576656c12420a0c636f64655f6368616e67657318142003280b321f2e73662e657468657265756d2e747970652e76322e436f64654368616e6765520b636f64654368616e676573123c0a0c73797374656d5f63616c6c7318152003280b32192e73662e657468657265756d2e747970652e76322e43616c6c520b73797374656d43616c6c7312100a037665721801200128055203766572223d0a0b44657461696c4c6576656c12180a1444455441494c4c4556454c5f455854454e444544100012140a1044455441494c4c4556454c5f4241534510024a04082810294a040829102a4a04082a102b22d2070a0b426c6f636b486561646572121f0a0b706172656e745f6861736818012001280c520a706172656e7448617368121d0a0a756e636c655f6861736818022001280c5209756e636c6548617368121a0a08636f696e6261736518032001280c5208636f696e62617365121d0a0a73746174655f726f6f7418042001280c52097374617465526f6f74122b0a117472616e73616374696f6e735f726f6f7418052001280c52107472616e73616374696f6e73526f6f7412210a0c726563656970745f726f6f7418062001280c520b72656365697074526f6f74121d0a0a6c6f67735f626c6f6f6d18072001280c52096c6f6773426c6f6f6d123b0a0a646966666963756c747918082001280b321b2e73662e657468657265756d2e747970652e76322e426967496e74520a646966666963756c747912460a10746f74616c5f646966666963756c747918112001280b321b2e73662e657468657265756d2e747970652e76322e426967496e74520f746f74616c446966666963756c747912160a066e756d62657218092001280452066e756d626572121b0a096761735f6c696d6974180a2001280452086761734c696d697412190a086761735f75736564180b2001280452076761735573656412380a0974696d657374616d70180c2001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d70520974696d657374616d70121d0a0a65787472615f64617461180d2001280c520965787472614461746112190a086d69785f68617368180e2001280c52076d69784861736812140a056e6f6e6365180f2001280452056e6f6e636512120a046861736818102001280c52046861736812440a10626173655f6665655f7065725f67617318122001280b321b2e73662e657468657265756d2e747970652e76322e426967496e74520d6261736546656550657247617312290a107769746864726177616c735f726f6f7418132001280c520f7769746864726177616c73526f6f74124b0a0d74785f646570656e64656e637918142001280b32262e73662e657468657265756d2e747970652e76322e55696e7436344e65737465644172726179520c7478446570656e64656e637912270a0d626c6f625f6761735f757365641816200128044800520b626c6f6247617355736564880101122b0a0f6578636573735f626c6f625f6761731817200128044801520d657863657373426c6f62476173880101122c0a12706172656e745f626561636f6e5f726f6f7418182001280c5210706172656e74426561636f6e526f6f7442100a0e5f626c6f625f6761735f7573656442120a105f6578636573735f626c6f625f67617322470a1155696e7436344e6573746564417272617912320a0376616c18012003280b32202e73662e657468657265756d2e747970652e76322e55696e7436344172726179520376616c221f0a0b55696e743634417272617912100a0376616c180120032804520376616c221e0a06426967496e7412140a05627974657318012001280c5205627974657322ab0b0a105472616e73616374696f6e5472616365120e0a02746f18012001280c5202746f12140a056e6f6e636518022001280452056e6f6e636512380a096761735f707269636518032001280b321b2e73662e657468657265756d2e747970652e76322e426967496e7452086761735072696365121b0a096761735f6c696d697418042001280452086761734c696d697412310a0576616c756518052001280b321b2e73662e657468657265756d2e747970652e76322e426967496e74520576616c756512140a05696e70757418062001280c5205696e707574120c0a017618072001280c520176120c0a017218082001280c520172120c0a017318092001280c52017312190a086761735f75736564180a20012804520767617355736564123e0a0474797065180c2001280e322a2e73662e657468657265756d2e747970652e76322e5472616e73616374696f6e54726163652e5479706552047479706512410a0b6163636573735f6c697374180e2003280b32202e73662e657468657265756d2e747970652e76322e4163636573735475706c65520a6163636573734c69737412420a0f6d61785f6665655f7065725f676173180b2001280b321b2e73662e657468657265756d2e747970652e76322e426967496e74520c6d617846656550657247617312530a186d61785f7072696f726974795f6665655f7065725f676173180d2001280b321b2e73662e657468657265756d2e747970652e76322e426967496e7452146d61785072696f7269747946656550657247617312140a05696e64657818142001280d5205696e64657812120a046861736818152001280c52046861736812120a0466726f6d18162001280c520466726f6d121f0a0b72657475726e5f6461746118172001280c520a72657475726e44617461121d0a0a7075626c69635f6b657918182001280c52097075626c69634b657912230a0d626567696e5f6f7264696e616c181920012804520c626567696e4f7264696e616c121f0a0b656e645f6f7264696e616c181a20012804520a656e644f7264696e616c12430a06737461747573181e2001280e322b2e73662e657468657265756d2e747970652e76322e5472616e73616374696f6e5472616365537461747573520673746174757312410a0772656365697074181f2001280b32272e73662e657468657265756d2e747970652e76322e5472616e73616374696f6e52656365697074520772656365697074122f0a0563616c6c7318202003280b32192e73662e657468657265756d2e747970652e76322e43616c6c520563616c6c73121e0a08626c6f625f67617318212001280448005207626c6f6247617388010112490a10626c6f625f6761735f6665655f63617018222001280b321b2e73662e657468657265756d2e747970652e76322e426967496e744801520d626c6f62476173466565436170880101121f0a0b626c6f625f68617368657318232003280c520a626c6f6248617368657322c4020a045479706512130a0f5452585f545950455f4c4547414359100012180a145452585f545950455f4143434553535f4c495354100112180a145452585f545950455f44594e414d49435f464545100212110a0d5452585f545950455f424c4f421003121d0a195452585f545950455f415242495452554d5f4445504f5349541064121e0a1a5452585f545950455f415242495452554d5f554e5349474e45441065121e0a1a5452585f545950455f415242495452554d5f434f4e54524143541066121b0a175452585f545950455f415242495452554d5f5245545259106812260a225452585f545950455f415242495452554d5f5355424d49545f524554525941424c451069121e0a1a5452585f545950455f415242495452554d5f494e5445524e414c106a121c0a185452585f545950455f415242495452554d5f4c45474143591078420b0a095f626c6f625f67617342130a115f626c6f625f6761735f6665655f636170224a0a0b4163636573735475706c6512180a076164647265737318012001280c52076164647265737312210a0c73746f726167655f6b65797318022003280c520b73746f726167654b65797322c6020a125472616e73616374696f6e52656365697074121d0a0a73746174655f726f6f7418012001280c52097374617465526f6f74122e0a1363756d756c61746976655f6761735f75736564180220012804521163756d756c617469766547617355736564121d0a0a6c6f67735f626c6f6f6d18032001280c52096c6f6773426c6f6f6d122c0a046c6f677318042003280b32182e73662e657468657265756d2e747970652e76322e4c6f6752046c6f677312270a0d626c6f625f6761735f757365641805200128044800520b626c6f624761735573656488010112460a0e626c6f625f6761735f707269636518062001280b321b2e73662e657468657265756d2e747970652e76322e426967496e744801520c626c6f62476173507269636588010142100a0e5f626c6f625f6761735f7573656442110a0f5f626c6f625f6761735f7072696365229b010a034c6f6712180a076164647265737318012001280c52076164647265737312160a06746f7069637318022003280c5206746f7069637312120a046461746118032001280c52046461746112140a05696e64657818042001280d5205696e646578121e0a0a626c6f636b496e64657818062001280d520a626c6f636b496e64657812180a076f7264696e616c18072001280452076f7264696e616c22b20a0a0443616c6c12140a05696e64657818012001280d5205696e64657812210a0c706172656e745f696e64657818022001280d520b706172656e74496e64657812140a05646570746818032001280d52056465707468123a0a0963616c6c5f7479706518042001280e321d2e73662e657468657265756d2e747970652e76322e43616c6c54797065520863616c6c5479706512160a0663616c6c657218052001280c520663616c6c657212180a076164647265737318062001280c52076164647265737312310a0576616c756518072001280b321b2e73662e657468657265756d2e747970652e76322e426967496e74520576616c7565121b0a096761735f6c696d697418082001280452086761734c696d697412210a0c6761735f636f6e73756d6564180920012804520b676173436f6e73756d6564121f0a0b72657475726e5f64617461180d2001280c520a72657475726e4461746112140a05696e707574180e2001280c5205696e70757412230a0d65786563757465645f636f6465180f20012808520c6578656375746564436f646512180a077375696369646518102001280852077375696369646512590a106b656363616b5f707265696d6167657318142003280b322e2e73662e657468657265756d2e747970652e76322e43616c6c2e4b656363616b507265696d61676573456e747279520f6b656363616b507265696d61676573124b0a0f73746f726167655f6368616e67657318152003280b32222e73662e657468657265756d2e747970652e76322e53746f726167654368616e6765520e73746f726167654368616e676573124b0a0f62616c616e63655f6368616e67657318162003280b32222e73662e657468657265756d2e747970652e76322e42616c616e63654368616e6765520e62616c616e63654368616e67657312450a0d6e6f6e63655f6368616e67657318182003280b32202e73662e657468657265756d2e747970652e76322e4e6f6e63654368616e6765520c6e6f6e63654368616e676573122c0a046c6f677318192003280b32182e73662e657468657265756d2e747970652e76322e4c6f6752046c6f677312420a0c636f64655f6368616e676573181a2003280b321f2e73662e657468657265756d2e747970652e76322e436f64654368616e6765520b636f64654368616e676573123f0a0b6761735f6368616e676573181c2003280b321e2e73662e657468657265756d2e747970652e76322e4761734368616e6765520a6761734368616e67657312230a0d7374617475735f6661696c6564180a20012808520c7374617475734661696c656412270a0f7374617475735f7265766572746564180c20012808520e737461747573526576657274656412250a0e6661696c7572655f726561736f6e180b20012809520d6661696c757265526561736f6e12250a0e73746174655f7265766572746564181e20012808520d7374617465526576657274656412230a0d626567696e5f6f7264696e616c181f20012804520c626567696e4f7264696e616c121f0a0b656e645f6f7264696e616c182020012804520a656e644f7264696e616c12510a116163636f756e745f6372656174696f6e7318212003280b32242e73662e657468657265756d2e747970652e76322e4163636f756e744372656174696f6e52106163636f756e744372656174696f6e731a420a144b656363616b507265696d61676573456e74727912100a036b657918012001280952036b657912140a0576616c7565180220012809520576616c75653a0238014a04081b101c4a04081d101e4a04083210334a04083310344a04083c103d228f010a0d53746f726167654368616e676512180a076164647265737318012001280c52076164647265737312100a036b657918022001280c52036b6579121b0a096f6c645f76616c756518032001280c52086f6c6456616c7565121b0a096e65775f76616c756518042001280c52086e657756616c756512180a076f7264696e616c18052001280452076f7264696e616c22cc050a0d42616c616e63654368616e676512180a076164647265737318012001280c52076164647265737312380a096f6c645f76616c756518022001280b321b2e73662e657468657265756d2e747970652e76322e426967496e7452086f6c6456616c756512380a096e65775f76616c756518032001280b321b2e73662e657468657265756d2e747970652e76322e426967496e7452086e657756616c756512410a06726561736f6e18042001280e32292e73662e657468657265756d2e747970652e76322e42616c616e63654368616e67652e526561736f6e5206726561736f6e12180a076f7264696e616c18052001280452076f7264696e616c22cf030a06526561736f6e12120a0e524541534f4e5f554e4b4e4f574e1000121c0a18524541534f4e5f5245574152445f4d494e455f554e434c451001121c0a18524541534f4e5f5245574152445f4d494e455f424c4f434b1002121e0a1a524541534f4e5f44414f5f524546554e445f434f4e54524143541003121d0a19524541534f4e5f44414f5f41444a5553545f42414c414e4345100412130a0f524541534f4e5f5452414e534645521005121a0a16524541534f4e5f47454e455349535f42414c414e4345100612120a0e524541534f4e5f4741535f425559100712210a1d524541534f4e5f5245574152445f5452414e53414354494f4e5f4645451008121b0a17524541534f4e5f5245574152445f4645455f5245534554100e12150a11524541534f4e5f4741535f524546554e44100912180a14524541534f4e5f544f5543485f4143434f554e54100a12190a15524541534f4e5f535549434944455f524546554e44100b121b0a17524541534f4e5f535549434944455f5749544844524157100d12200a1c524541534f4e5f43414c4c5f42414c414e43455f4f56455252494445100c120f0a0b524541534f4e5f4255524e100f12150a11524541534f4e5f5749544844524157414c1010227b0a0b4e6f6e63654368616e676512180a076164647265737318012001280c520761646472657373121b0a096f6c645f76616c756518022001280452086f6c6456616c7565121b0a096e65775f76616c756518032001280452086e657756616c756512180a076f7264696e616c18042001280452076f7264696e616c22450a0f4163636f756e744372656174696f6e12180a076163636f756e7418012001280c52076163636f756e7412180a076f7264696e616c18022001280452076f7264696e616c22ac010a0a436f64654368616e676512180a076164647265737318012001280c52076164647265737312190a086f6c645f6861736818022001280c52076f6c644861736812190a086f6c645f636f646518032001280c52076f6c64436f646512190a086e65775f6861736818042001280c52076e65774861736812190a086e65775f636f646518052001280c52076e6577436f646512180a076f7264696e616c18062001280452076f7264696e616c22e0060a094761734368616e6765121b0a096f6c645f76616c756518012001280452086f6c6456616c7565121b0a096e65775f76616c756518022001280452086e657756616c7565123d0a06726561736f6e18032001280e32252e73662e657468657265756d2e747970652e76322e4761734368616e67652e526561736f6e5206726561736f6e12180a076f7264696e616c18042001280452076f7264696e616c22bf050a06526561736f6e12120a0e524541534f4e5f554e4b4e4f574e1000120f0a0b524541534f4e5f43414c4c100112140a10524541534f4e5f43414c4c5f434f4445100212190a15524541534f4e5f43414c4c5f444154415f434f5059100312140a10524541534f4e5f434f44455f434f5059100412170a13524541534f4e5f434f44455f53544f524147451005121c0a18524541534f4e5f434f4e54524143545f4352454154494f4e1006121d0a19524541534f4e5f434f4e54524143545f4352454154494f4e32100712180a14524541534f4e5f44454c45474154455f43414c4c100812140a10524541534f4e5f4556454e545f4c4f47100912180a14524541534f4e5f4558545f434f44455f434f5059100a121b0a17524541534f4e5f4641494c45445f455845435554494f4e100b12180a14524541534f4e5f494e5452494e5349435f474153100c121f0a1b524541534f4e5f505245434f4d50494c45445f434f4e5452414354100d12210a1d524541534f4e5f524546554e445f41465445525f455845435554494f4e100e12110a0d524541534f4e5f52455455524e100f121b0a17524541534f4e5f52455455524e5f444154415f434f5059101012110a0d524541534f4e5f524556455254101112180a14524541534f4e5f53454c465f4445535452554354101212160a12524541534f4e5f5354415449435f43414c4c1013121c0a18524541534f4e5f53544154455f434f4c445f4143434553531014121d0a19524541534f4e5f54585f494e495449414c5f42414c414e4345101512150a11524541534f4e5f54585f524546554e4453101612200a1c524541534f4e5f54585f4c4546545f4f5645525f52455455524e45441017121f0a1b524541534f4e5f43414c4c5f494e495449414c5f42414c414e4345101812220a1e524541534f4e5f43414c4c5f4c4546545f4f5645525f52455455524e45441019224b0a0f4865616465724f6e6c79426c6f636b12380a0668656164657218052001280b32202e73662e657468657265756d2e747970652e76322e426c6f636b486561646572520668656164657222d1010a0d426c6f636b5769746852656673120e0a0269641801200128095202696412300a05626c6f636b18022001280b321a2e73662e657468657265756d2e747970652e76322e426c6f636b5205626c6f636b125a0a167472616e73616374696f6e5f74726163655f7265667318032001280b32242e73662e657468657265756d2e747970652e76322e5472616e73616374696f6e5265667352147472616e73616374696f6e54726163655265667312220a0c697272657665727369626c65180420012808520c697272657665727369626c652297010a1c5472616e73616374696f6e547261636557697468426c6f636b526566123b0a05747261636518012001280b32252e73662e657468657265756d2e747970652e76322e5472616e73616374696f6e547261636552057472616365123a0a09626c6f636b5f72656618022001280b321d2e73662e657468657265756d2e747970652e76322e426c6f636b5265665208626c6f636b52656622290a0f5472616e73616374696f6e5265667312160a0668617368657318012003280c520668617368657322360a08426c6f636b52656612120a046861736818012001280c52046861736812160a066e756d62657218022001280452066e756d6265722a4e0a165472616e73616374696f6e5472616365537461747573120b0a07554e4b4e4f574e1000120d0a095355434345454445441001120a0a064641494c45441002120c0a08524556455254454410032a590a0843616c6c54797065120f0a0b554e535045434946494544100012080a0443414c4c1001120c0a0843414c4c434f44451002120c0a0844454c45474154451003120a0a065354415449431004120a0a064352454154451005424f5a4d6769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d657468657265756d2f74797065732f70622f73662f657468657265756d2f747970652f76323b7062657468620670726f746f33", - - // sf/ethereum/trxstream/v1/trxstream.proto (https://buf.build/streamingfast/firehose-ethereum/docs/d869cb39aae947ecb0c7df6a1db2b61f:sf.ethereum.trxstream.v1) - "0a2873662f657468657265756d2f74727873747265616d2f76312f74727873747265616d2e70726f746f121873662e657468657265756d2e74727873747265616d2e76311a1f676f6f676c652f70726f746f6275662f74696d657374616d702e70726f746f1a1e73662f657468657265756d2f747970652f76322f747970652e70726f746f22140a125472616e73616374696f6e5265717565737422a5080a105472616e73616374696f6e537461746512570a0e70726576696f75735f737461746518012001280e32302e73662e657468657265756d2e74727873747265616d2e76312e5472616e73616374696f6e53746174652e5374617465520d70726576696f7573537461746512550a0d63757272656e745f737461746518022001280e32302e73662e657468657265756d2e74727873747265616d2e76312e5472616e73616374696f6e53746174652e5374617465520c63757272656e74537461746512550a0a7472616e736974696f6e180a2001280e32352e73662e657468657265756d2e74727873747265616d2e76312e5472616e73616374696f6e53746174652e5472616e736974696f6e520a7472616e736974696f6e12120a0468617368180b2001280c52046861736812370a0374727818032001280b32252e73662e657468657265756d2e74727873747265616d2e76312e5472616e73616374696f6e520374727812430a0c626c6f636b5f68656164657218042001280b32202e73662e657468657265756d2e747970652e76322e426c6f636b486561646572520b626c6f636b48656164657212540a127472616e73616374696f6e5f74726163657318052001280b32252e73662e657468657265756d2e747970652e76322e5472616e73616374696f6e547261636552117472616e73616374696f6e54726163657312220a0c636f6e6669726d6174696f6e180620012804520c636f6e6669726d6174696f6e124c0a11686561645f626c6f636b5f68656164657218072001280b32202e73662e657468657265756d2e747970652e76322e426c6f636b486561646572520f68656164426c6f636b48656164657212280a107265706c616365645f62795f6861736818082001280c520e7265706c6163656442794861736812480a1270656e64696e675f66697273745f7365656e180c2001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d70521070656e64696e6746697273745365656e12460a1170656e64696e675f6c6173745f7365656e180d2001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d70520f70656e64696e674c6173745365656e229c010a0a5472616e736974696f6e120e0a0a5452414e535f494e4954100012100a0c5452414e535f504f4f4c45441001120f0a0b5452414e535f4d494e4544100212100a0c5452414e535f464f524b4544100312130a0f5452414e535f434f4e4649524d4544100412120a0e5452414e535f5245504c41434544100512200a1c5452414e535f53504543554c41544956454c595f4558454355544544100622550a05537461746512110a0d53544154455f554e4b4e4f574e100012110a0d53544154455f50454e44494e47100112120a0e53544154455f494e5f424c4f434b100212120a0e53544154455f5245504c41434544100322a5020a0b5472616e73616374696f6e120e0a02746f18012001280c5202746f12140a056e6f6e636518022001280452056e6f6e636512380a096761735f707269636518032001280b321b2e73662e657468657265756d2e747970652e76322e426967496e7452086761735072696365121b0a096761735f6c696d697418042001280452086761734c696d697412310a0576616c756518052001280b321b2e73662e657468657265756d2e747970652e76322e426967496e74520576616c756512140a05696e70757418062001280c5205696e707574120c0a017618072001280c520176120c0a017218082001280c520172120c0a017318092001280c52017312120a046861736818152001280c52046861736812120a0466726f6d18162001280c520466726f6d327a0a115472616e73616374696f6e53747265616d12650a0c5472616e73616374696f6e73122c2e73662e657468657265756d2e74727873747265616d2e76312e5472616e73616374696f6e526571756573741a252e73662e657468657265756d2e74727873747265616d2e76312e5472616e73616374696f6e3001425f5a5d6769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d657468657265756d2d707269762f74797065732f70622f73662f657468657265756d2f74727873747265616d2f76313b706274727873747265616d620670726f746f33", - - // sf/near/transform/v1/transform.proto (https://buf.build/streamingfast/firehose-near/docs/0b7e4efe1b9f447495fdfb54b7a6880f:sf.near.transform.v1) - "0a2473662f6e6561722f7472616e73666f726d2f76312f7472616e73666f726d2e70726f746f121473662e6e6561722e7472616e73666f726d2e7631228f010a1242617369635265636569707446696c746572121a0a086163636f756e747318012003280952086163636f756e7473125d0a177072656669785f616e645f7375666669785f706169727318022003280b32262e73662e6e6561722e7472616e73666f726d2e76312e507265666978537566666978506169725214707265666978416e64537566666978506169727322420a105072656669785375666669785061697212160a06707265666978180120012809520670726566697812160a067375666669781802200128095206737566666978220c0a0a4865616465724f6e6c79424c5a4a6769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d6e6561722f70622f73662f6e6561722f7472616e73666f726d2f76313b70627472616e73666f726d620670726f746f33", - - // sf/near/type/v1/type.proto (https://buf.build/streamingfast/firehose-near/docs/0b7e4efe1b9f447495fdfb54b7a6880f:sf.near.type.v1) - "0a1a73662f6e6561722f747970652f76312f747970652e70726f746f120f73662e6e6561722e747970652e7631229b020a05426c6f636b12160a06617574686f721801200128095206617574686f7212340a0668656164657218022001280b321c2e73662e6e6561722e747970652e76312e426c6f636b486561646572520668656164657212410a0d6368756e6b5f6865616465727318032003280b321c2e73662e6e6561722e747970652e76312e4368756e6b486561646572520c6368756e6b4865616465727312350a0673686172647318042003280b321d2e73662e6e6561722e747970652e76312e496e646578657253686172645206736861726473124a0a0d73746174655f6368616e67657318052003280b32252e73662e6e6561722e747970652e76312e53746174654368616e6765576974684361757365520c73746174654368616e67657322470a0f4865616465724f6e6c79426c6f636b12340a0668656164657218022001280b321c2e73662e6e6561722e747970652e76312e426c6f636b48656164657252066865616465722288010a1453746174654368616e676557697468436175736512370a0576616c756518012001280b32212e73662e6e6561722e747970652e76312e53746174654368616e676556616c7565520576616c756512370a05636175736518022001280b32212e73662e6e6561722e747970652e76312e53746174654368616e676543617573655205636175736522d50c0a1053746174654368616e6765436175736512660a146e6f745f7772697461626c655f746f5f6469736b18012001280b32332e73662e6e6561722e747970652e76312e53746174654368616e676543617573652e4e6f745772697461626c65546f4469736b480052116e6f745772697461626c65546f4469736b12550a0d696e697469616c5f737461746518022001280b322e2e73662e6e6561722e747970652e76312e53746174654368616e676543617573652e496e697469616c53746174654800520c696e697469616c537461746512700a167472616e73616374696f6e5f70726f63657373696e6718032001280b32372e73662e6e6561722e747970652e76312e53746174654368616e676543617573652e5472616e73616374696f6e50726f63657373696e67480052157472616e73616374696f6e50726f63657373696e67128d010a21616374696f6e5f726563656970745f70726f63657373696e675f7374617274656418042001280b32402e73662e6e6561722e747970652e76312e53746174654368616e676543617573652e416374696f6e5265636569707450726f63657373696e67537461727465644800521e616374696f6e5265636569707450726f63657373696e675374617274656412750a19616374696f6e5f726563656970745f6761735f72657761726418052001280b32382e73662e6e6561722e747970652e76312e53746174654368616e676543617573652e416374696f6e5265636569707447617352657761726448005216616374696f6e5265636569707447617352657761726412640a12726563656970745f70726f63657373696e6718062001280b32332e73662e6e6561722e747970652e76312e53746174654368616e676543617573652e5265636569707450726f63657373696e67480052117265636569707450726f63657373696e6712610a11706f7374706f6e65645f7265636569707418072001280b32322e73662e6e6561722e747970652e76312e53746174654368616e676543617573652e506f7374706f6e65645265636569707448005210706f7374706f6e65645265636569707412740a18757064617465645f64656c617965645f726563656970747318082001280b32382e73662e6e6561722e747970652e76312e53746174654368616e676543617573652e5570646174656444656c617965645265636569707473480052167570646174656444656c61796564526563656970747312770a1976616c696461746f725f6163636f756e74735f75706461746518092001280b32392e73662e6e6561722e747970652e76312e53746174654368616e676543617573652e56616c696461746f724163636f756e74735570646174654800521776616c696461746f724163636f756e7473557064617465124b0a096d6967726174696f6e180a2001280b322b2e73662e6e6561722e747970652e76312e53746174654368616e676543617573652e4d6967726174696f6e480052096d6967726174696f6e1a130a114e6f745772697461626c65546f4469736b1a0e0a0c496e697469616c53746174651a4d0a155472616e73616374696f6e50726f63657373696e6712340a0774785f6861736818012001280b321b2e73662e6e6561722e747970652e76312e43727970746f4861736852067478486173681a600a1e416374696f6e5265636569707450726f63657373696e6753746172746564123e0a0c726563656970745f6861736818012001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520b72656365697074486173681a4e0a16416374696f6e5265636569707447617352657761726412340a0774785f6861736818012001280b321b2e73662e6e6561722e747970652e76312e43727970746f4861736852067478486173681a490a115265636569707450726f63657373696e6712340a0774785f6861736818012001280b321b2e73662e6e6561722e747970652e76312e43727970746f4861736852067478486173681a480a10506f7374706f6e65645265636569707412340a0774785f6861736818012001280b321b2e73662e6e6561722e747970652e76312e43727970746f4861736852067478486173681a180a165570646174656444656c6179656452656365697074731a190a1756616c696461746f724163636f756e74735570646174651a0b0a094d6967726174696f6e42070a05636175736522da0b0a1053746174654368616e676556616c756512580a0e6163636f756e745f75706461746518012001280b322f2e73662e6e6561722e747970652e76312e53746174654368616e676556616c75652e4163636f756e745570646174654800520d6163636f756e74557064617465125e0a106163636f756e745f64656c6574696f6e18022001280b32312e73662e6e6561722e747970652e76312e53746174654368616e676556616c75652e4163636f756e7444656c6574696f6e4800520f6163636f756e7444656c6574696f6e125f0a116163636573735f6b65795f75706461746518032001280b32312e73662e6e6561722e747970652e76312e53746174654368616e676556616c75652e4163636573734b65795570646174654800520f6163636573734b657955706461746512650a136163636573735f6b65795f64656c6574696f6e18042001280b32332e73662e6e6561722e747970652e76312e53746174654368616e676556616c75652e4163636573734b657944656c6574696f6e480052116163636573734b657944656c6574696f6e124f0a0b646174615f75706461746518052001280b322c2e73662e6e6561722e747970652e76312e53746174654368616e676556616c75652e446174615570646174654800520a6461746155706461746512550a0d646174615f64656c6574696f6e18062001280b322e2e73662e6e6561722e747970652e76312e53746174654368616e676556616c75652e4461746144656c6574696f6e4800520c6461746144656c6574696f6e12680a14636f6e74726163745f636f64655f75706461746518072001280b32342e73662e6e6561722e747970652e76312e53746174654368616e676556616c75652e436f6e7472616374436f646555706461746548005212636f6e7472616374436f646555706461746512650a11636f6e74726163745f64656c6574696f6e18082001280b32362e73662e6e6561722e747970652e76312e53746174654368616e676556616c75652e436f6e7472616374436f646544656c6574696f6e48005210636f6e747261637444656c6574696f6e1a620a0d4163636f756e74557064617465121d0a0a6163636f756e745f696418012001280952096163636f756e74496412320a076163636f756e7418022001280b32182e73662e6e6561722e747970652e76312e4163636f756e7452076163636f756e741a300a0f4163636f756e7444656c6574696f6e121d0a0a6163636f756e745f696418012001280952096163636f756e7449641aa6010a0f4163636573734b6579557064617465121d0a0a6163636f756e745f696418012001280952096163636f756e74496412390a0a7075626c69635f6b657918022001280b321a2e73662e6e6561722e747970652e76312e5075626c69634b657952097075626c69634b657912390a0a6163636573735f6b657918032001280b321a2e73662e6e6561722e747970652e76312e4163636573734b657952096163636573734b65791a6d0a114163636573734b657944656c6574696f6e121d0a0a6163636f756e745f696418012001280952096163636f756e74496412390a0a7075626c69635f6b657918022001280b321a2e73662e6e6561722e747970652e76312e5075626c69634b657952097075626c69634b65791a530a0a44617461557064617465121d0a0a6163636f756e745f696418012001280952096163636f756e74496412100a036b657918022001280c52036b657912140a0576616c756518032001280c520576616c75651a3f0a0c4461746144656c6574696f6e121d0a0a6163636f756e745f696418012001280952096163636f756e74496412100a036b657918022001280c52036b65791a470a12436f6e7472616374436f6465557064617465121d0a0a6163636f756e745f696418012001280952096163636f756e74496412120a04636f646518022001280c5204636f64651a350a14436f6e7472616374436f646544656c6574696f6e121d0a0a6163636f756e745f696418012001280952096163636f756e74496442070a0576616c756522ca010a074163636f756e74122f0a06616d6f756e7418012001280b32172e73662e6e6561722e747970652e76312e426967496e745206616d6f756e74122f0a066c6f636b656418022001280b32172e73662e6e6561722e747970652e76312e426967496e7452066c6f636b656412380a09636f64655f6861736818032001280b321b2e73662e6e6561722e747970652e76312e43727970746f486173685208636f64654861736812230a0d73746f726167655f7573616765180420012804520c73746f72616765557361676522c50e0a0b426c6f636b48656164657212160a066865696768741801200128045206686569676874121f0a0b707265765f686569676874180220012804520a7072657648656967687412360a0865706f63685f696418032001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520765706f63684964123f0a0d6e6578745f65706f63685f696418042001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520b6e65787445706f63684964122f0a046861736818052001280b321b2e73662e6e6561722e747970652e76312e43727970746f4861736852046861736812380a09707265765f6861736818062001280b321b2e73662e6e6561722e747970652e76312e43727970746f486173685208707265764861736812430a0f707265765f73746174655f726f6f7418072001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520d707265765374617465526f6f74124b0a136368756e6b5f72656365697074735f726f6f7418082001280b321b2e73662e6e6561722e747970652e76312e43727970746f4861736852116368756e6b5265636569707473526f6f7412490a126368756e6b5f686561646572735f726f6f7418092001280b321b2e73662e6e6561722e747970652e76312e43727970746f4861736852106368756e6b48656164657273526f6f74123f0a0d6368756e6b5f74785f726f6f74180a2001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520b6368756e6b5478526f6f74123e0a0c6f7574636f6d655f726f6f74180b2001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520b6f7574636f6d65526f6f7412270a0f6368756e6b735f696e636c75646564180c20012804520e6368756e6b73496e636c7564656412440a0f6368616c6c656e6765735f726f6f74180d2001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520e6368616c6c656e676573526f6f74121c0a0974696d657374616d70180e20012804520974696d657374616d70122b0a1174696d657374616d705f6e616e6f736563180f20012804521074696d657374616d704e616e6f736563123e0a0c72616e646f6d5f76616c756518102001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520b72616e646f6d56616c756512500a1376616c696461746f725f70726f706f73616c7318112003280b321f2e73662e6e6561722e747970652e76312e56616c696461746f725374616b65521276616c696461746f7250726f706f73616c73121d0a0a6368756e6b5f6d61736b18122003280852096368756e6b4d61736b12340a096761735f707269636518132001280b32172e73662e6e6561722e747970652e76312e426967496e745208676173507269636512230a0d626c6f636b5f6f7264696e616c181420012804520c626c6f636b4f7264696e616c123a0a0c746f74616c5f737570706c7918152001280b32172e73662e6e6561722e747970652e76312e426967496e74520b746f74616c537570706c79124e0a116368616c6c656e6765735f726573756c7418162003280b32212e73662e6e6561722e747970652e76312e536c617368656456616c696461746f7252106368616c6c656e676573526573756c7412350a176c6173745f66696e616c5f626c6f636b5f68656967687418172001280452146c61737446696e616c426c6f636b48656967687412450a106c6173745f66696e616c5f626c6f636b18182001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520e6c61737446696e616c426c6f636b123a0a1a6c6173745f64735f66696e616c5f626c6f636b5f68656967687418192001280452166c617374447346696e616c426c6f636b486569676874124a0a136c6173745f64735f66696e616c5f626c6f636b181a2001280b321b2e73662e6e6561722e747970652e76312e43727970746f4861736852106c617374447346696e616c426c6f636b123d0a0c6e6578745f62705f68617368181b2001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520a6e65787442704861736812470a11626c6f636b5f6d65726b6c655f726f6f74181c2001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520f626c6f636b4d65726b6c65526f6f74122f0a1465706f63685f73796e635f646174615f68617368181d2001280c521165706f636853796e63446174614861736812380a09617070726f76616c73181e2003280b321a2e73662e6e6561722e747970652e76312e5369676e61747572655209617070726f76616c7312380a097369676e6174757265181f2001280b321a2e73662e6e6561722e747970652e76312e5369676e617475726552097369676e617475726512360a176c61746573745f70726f746f636f6c5f76657273696f6e18202001280d52156c617465737450726f746f636f6c56657273696f6e221e0a06426967496e7412140a05627974657318012001280c5205627974657322220a0a43727970746f4861736812140a05627974657318012001280c5205627974657322510a095369676e6174757265122e0a047479706518012001280e321a2e73662e6e6561722e747970652e76312e43757276654b696e6452047479706512140a05627974657318022001280c5205627974657322510a095075626c69634b6579122e0a047479706518012001280e321a2e73662e6e6561722e747970652e76312e43757276654b696e6452047479706512140a05627974657318022001280c520562797465732299010a0e56616c696461746f725374616b65121d0a0a6163636f756e745f696418012001280952096163636f756e74496412390a0a7075626c69635f6b657918022001280b321a2e73662e6e6561722e747970652e76312e5075626c69634b657952097075626c69634b6579122d0a057374616b6518032001280b32172e73662e6e6561722e747970652e76312e426967496e7452057374616b6522570a10536c617368656456616c696461746f72121d0a0a6163636f756e745f696418012001280952096163636f756e74496412240a0e69735f646f75626c655f7369676e180220012808520c6973446f75626c655369676e22f6050a0b4368756e6b486561646572121d0a0a6368756e6b5f6861736818012001280c52096368756e6b4861736812260a0f707265765f626c6f636b5f6861736818022001280c520d70726576426c6f636b4861736812210a0c6f7574636f6d655f726f6f7418032001280c520b6f7574636f6d65526f6f7412260a0f707265765f73746174655f726f6f7418042001280c520d707265765374617465526f6f74122e0a13656e636f6465645f6d65726b6c655f726f6f7418052001280c5211656e636f6465644d65726b6c65526f6f7412250a0e656e636f6465645f6c656e677468180620012804520d656e636f6465644c656e67746812250a0e6865696768745f63726561746564180720012804520d6865696768744372656174656412270a0f6865696768745f696e636c75646564180820012804520e686569676874496e636c7564656412190a0873686172645f696418092001280452077368617264496412190a086761735f75736564180a20012804520767617355736564121b0a096761735f6c696d6974180b2001280452086761734c696d697412420a1076616c696461746f725f726577617264180c2001280b32172e73662e6e6561722e747970652e76312e426967496e74520f76616c696461746f72526577617264123c0a0d62616c616e63655f6275726e74180d2001280b32172e73662e6e6561722e747970652e76312e426967496e74520c62616c616e63654275726e7412340a166f7574676f696e675f72656365697074735f726f6f74180e2001280c52146f7574676f696e675265636569707473526f6f7412170a0774785f726f6f74180f2001280c52067478526f6f7412500a1376616c696461746f725f70726f706f73616c7318102003280b321f2e73662e6e6561722e747970652e76312e56616c696461746f725374616b65521276616c696461746f7250726f706f73616c7312380a097369676e617475726518112001280b321a2e73662e6e6561722e747970652e76312e5369676e617475726552097369676e617475726522d1010a0c496e6465786572536861726412190a0873686172645f696418012001280452077368617264496412330a056368756e6b18022001280b321d2e73662e6e6561722e747970652e76312e496e64657865724368756e6b52056368756e6b12710a1a726563656970745f657865637574696f6e5f6f7574636f6d657318032003280b32332e73662e6e6561722e747970652e76312e496e6465786572457865637574696f6e4f7574636f6d655769746852656365697074521872656365697074457865637574696f6e4f7574636f6d657322ae010a22496e6465786572457865637574696f6e4f7574636f6d65576974685265636569707412540a11657865637574696f6e5f6f7574636f6d6518012001280b32272e73662e6e6561722e747970652e76312e457865637574696f6e4f7574636f6d655769746849645210657865637574696f6e4f7574636f6d6512320a077265636569707418022001280b32182e73662e6e6561722e747970652e76312e5265636569707452077265636569707422e6010a0c496e64657865724368756e6b12160a06617574686f721801200128095206617574686f7212340a0668656164657218022001280b321c2e73662e6e6561722e747970652e76312e4368756e6b486561646572520668656164657212520a0c7472616e73616374696f6e7318032003280b322e2e73662e6e6561722e747970652e76312e496e64657865725472616e73616374696f6e576974684f7574636f6d65520c7472616e73616374696f6e7312340a08726563656970747318042003280b32182e73662e6e6561722e747970652e76312e526563656970745208726563656970747322bc010a1d496e64657865725472616e73616374696f6e576974684f7574636f6d6512440a0b7472616e73616374696f6e18012001280b32222e73662e6e6561722e747970652e76312e5369676e65645472616e73616374696f6e520b7472616e73616374696f6e12550a076f7574636f6d6518022001280b323b2e73662e6e6561722e747970652e76312e496e6465786572457865637574696f6e4f7574636f6d65576974684f7074696f6e616c5265636569707452076f7574636f6d6522c0020a115369676e65645472616e73616374696f6e121b0a097369676e65725f696418012001280952087369676e6572496412390a0a7075626c69635f6b657918022001280b321a2e73662e6e6561722e747970652e76312e5075626c69634b657952097075626c69634b657912140a056e6f6e636518032001280452056e6f6e6365121f0a0b72656365697665725f6964180420012809520a7265636569766572496412310a07616374696f6e7318052003280b32172e73662e6e6561722e747970652e76312e416374696f6e5207616374696f6e7312380a097369676e617475726518062001280b321a2e73662e6e6561722e747970652e76312e5369676e617475726552097369676e6174757265122f0a046861736818072001280b321b2e73662e6e6561722e747970652e76312e43727970746f4861736852046861736822b6010a2a496e6465786572457865637574696f6e4f7574636f6d65576974684f7074696f6e616c5265636569707412540a11657865637574696f6e5f6f7574636f6d6518012001280b32272e73662e6e6561722e747970652e76312e457865637574696f6e4f7574636f6d655769746849645210657865637574696f6e4f7574636f6d6512320a077265636569707418022001280b32182e73662e6e6561722e747970652e76312e526563656970745207726563656970742286020a075265636569707412250a0e7072656465636573736f725f6964180120012809520d7072656465636573736f724964121f0a0b72656365697665725f6964180220012809520a72656365697665724964123a0a0a726563656970745f696418032001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520972656365697074496412380a06616374696f6e180a2001280b321e2e73662e6e6561722e747970652e76312e52656365697074416374696f6e48005206616374696f6e12320a0464617461180b2001280b321c2e73662e6e6561722e747970652e76312e5265636569707444617461480052046461746142090a077265636569707422570a0b526563656970744461746112340a07646174615f696418012001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520664617461496412120a046461746118022001280c52046461746122f3020a0d52656365697074416374696f6e121b0a097369676e65725f696418012001280952087369676e6572496412460a117369676e65725f7075626c69635f6b657918022001280b321a2e73662e6e6561722e747970652e76312e5075626c69634b6579520f7369676e65725075626c69634b657912340a096761735f707269636518032001280b32172e73662e6e6561722e747970652e76312e426967496e745208676173507269636512510a156f75747075745f646174615f72656365697665727318042003280b321d2e73662e6e6561722e747970652e76312e44617461526563656976657252136f75747075744461746152656365697665727312410a0e696e7075745f646174615f69647318052003280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520c696e7075744461746149647312310a07616374696f6e7318062003280b32172e73662e6e6561722e747970652e76312e416374696f6e5207616374696f6e7322650a0c44617461526563656976657212340a07646174615f696418012001280b321b2e73662e6e6561722e747970652e76312e43727970746f486173685206646174614964121f0a0b72656365697665725f6964180220012809520a7265636569766572496422f1010a16457865637574696f6e4f7574636f6d6557697468496412310a0570726f6f6618012001280b321b2e73662e6e6561722e747970652e76312e4d65726b6c6550617468520570726f6f66123a0a0a626c6f636b5f6861736818022001280b321b2e73662e6e6561722e747970652e76312e43727970746f486173685209626c6f636b48617368122b0a02696418032001280b321b2e73662e6e6561722e747970652e76312e43727970746f4861736852026964123b0a076f7574636f6d6518042001280b32212e73662e6e6561722e747970652e76312e457865637574696f6e4f7574636f6d6552076f7574636f6d6522e9040a10457865637574696f6e4f7574636f6d6512120a046c6f677318012003280952046c6f6773123c0a0b726563656970745f69647318022003280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520a72656365697074496473121b0a096761735f6275726e7418032001280452086761734275726e74123a0a0c746f6b656e735f6275726e7418042001280b32172e73662e6e6561722e747970652e76312e426967496e74520b746f6b656e734275726e74121f0a0b6578656375746f725f6964180520012809520a6578656375746f72496412430a07756e6b6e6f776e18142001280b32272e73662e6e6561722e747970652e76312e556e6b6e6f776e457865637574696f6e53746174757348005207756e6b6e6f776e12430a076661696c75726518152001280b32272e73662e6e6561722e747970652e76312e4661696c757265457865637574696f6e537461747573480052076661696c75726512530a0d737563636573735f76616c756518162001280b322c2e73662e6e6561722e747970652e76312e5375636365737356616c7565457865637574696f6e5374617475734800520c7375636365737356616c756512600a12737563636573735f726563656970745f696418172001280b32302e73662e6e6561722e747970652e76312e53756363657373526563656970744964457865637574696f6e5374617475734800521073756363657373526563656970744964123e0a086d6574616461746118062001280e32222e73662e6e6561722e747970652e76312e457865637574696f6e4d6574616461746152086d6574616461746142080a0673746174757322330a1b5375636365737356616c7565457865637574696f6e53746174757312140a0576616c756518012001280c520576616c7565224e0a1f53756363657373526563656970744964457865637574696f6e537461747573122b0a02696418012001280b321b2e73662e6e6561722e747970652e76312e43727970746f486173685202696422180a16556e6b6e6f776e457865637574696f6e53746174757322b3010a164661696c757265457865637574696f6e53746174757312410a0c616374696f6e5f6572726f7218012001280b321c2e73662e6e6561722e747970652e76312e416374696f6e4572726f724800520b616374696f6e4572726f72124b0a10696e76616c69645f74785f6572726f7218022001280e321f2e73662e6e6561722e747970652e76312e496e76616c696454784572726f724800520e696e76616c696454784572726f7242090a076661696c75726522bc130a0b416374696f6e4572726f7212140a05696e6465781801200128045205696e64657812640a156163636f756e745f616c72656164795f657869737418152001280b322e2e73662e6e6561722e747970652e76312e4163636f756e74416c72656164794578697374734572726f724b696e64480052136163636f756e74416c7265616479457869737412640a166163636f756e745f646f65735f6e6f745f657869737418162001280b322d2e73662e6e6561722e747970652e76312e4163636f756e74446f65734e6f7445786973744572726f724b696e64480052136163636f756e74446f65734e6f7445786973741280010a206372656174655f6163636f756e745f6f6e6c795f62795f72656769737472617218172001280b32362e73662e6e6561722e747970652e76312e4372656174654163636f756e744f6e6c7942795265676973747261724572726f724b696e644800521c6372656174654163636f756e744f6e6c79427952656769737472617212700a1a6372656174655f6163636f756e745f6e6f745f616c6c6f77656418182001280b32312e73662e6e6561722e747970652e76312e4372656174654163636f756e744e6f74416c6c6f7765644572726f724b696e64480052176372656174654163636f756e744e6f74416c6c6f776564125d0a136163746f725f6e6f5f7065726d697373696f6e18192001280b322b2e73662e6e6561722e747970652e76312e4163746f724e6f5065726d697373696f6e4572726f724b696e64480052116163746f724e6f5065726d697373696f6e126b0a1964656c6574655f6b65795f646f65735f6e6f745f6578697374181a2001280b322f2e73662e6e6561722e747970652e76312e44656c6574654b6579446f65734e6f7445786973744572726f724b696e644800521564656c6574654b6579446f65734e6f74457869737412640a166164645f6b65795f616c72656164795f657869737473181b2001280b322d2e73662e6e6561722e747970652e76312e4164644b6579416c72656164794578697374734572726f724b696e64480052136164644b6579416c726561647945786973747312660a1664656c6574655f6163636f756e745f7374616b696e67181c2001280b322e2e73662e6e6561722e747970652e76312e44656c6574654163636f756e745374616b696e674572726f724b696e644800521464656c6574654163636f756e745374616b696e6712640a166c61636b5f62616c616e63655f666f725f7374617465181d2001280b322d2e73662e6e6561722e747970652e76312e4c61636b42616c616e6365466f7253746174654572726f724b696e64480052136c61636b42616c616e6365466f72537461746512540a1074726965735f746f5f756e7374616b65181e2001280b32282e73662e6e6561722e747970652e76312e5472696573546f556e7374616b654572726f724b696e644800520e7472696573546f556e7374616b65124e0a0e74726965735f746f5f7374616b65181f2001280b32262e73662e6e6561722e747970652e76312e5472696573546f5374616b654572726f724b696e644800520c7472696573546f5374616b65125c0a12696e73756666696369656e745f7374616b6518202001280b322b2e73662e6e6561722e747970652e76312e496e73756666696369656e745374616b654572726f724b696e6448005211696e73756666696369656e745374616b65124d0a0d66756e6374696f6e5f63616c6c18212001280b32262e73662e6e6561722e747970652e76312e46756e6374696f6e43616c6c4572726f724b696e644800520c66756e6374696f6e43616c6c12660a166e65775f726563656970745f76616c69646174696f6e18222001280b322e2e73662e6e6561722e747970652e76312e4e65775265636569707456616c69646174696f6e4572726f724b696e64480052146e65775265636569707456616c69646174696f6e1292010a266f6e6c795f696d706c696369745f6163636f756e745f6372656174696f6e5f616c6c6f77656418232001280b323c2e73662e6e6561722e747970652e76312e4f6e6c79496d706c696369744163636f756e744372656174696f6e416c6c6f7765644572726f724b696e64480052226f6e6c79496d706c696369744163636f756e744372656174696f6e416c6c6f776564127d0a1f64656c6574655f6163636f756e745f776974685f6c617267655f737461746518242001280b32352e73662e6e6561722e747970652e76312e44656c6574654163636f756e74576974684c6172676553746174654572726f724b696e644800521b64656c6574654163636f756e74576974684c6172676553746174651280010a2164656c65676174655f616374696f6e5f696e76616c69645f7369676e617475726518252001280b32332e73662e6e6561722e747970652e76312e44656c6567617465416374696f6e496e76616c69645369676e61747572654b696e644800521e64656c6567617465416374696f6e496e76616c69645369676e617475726512a8010a3164656c65676174655f616374696f6e5f73656e6465725f646f65735f6e6f745f6d617463685f74785f726563656976657218262001280b323f2e73662e6e6561722e747970652e76312e44656c6567617465416374696f6e53656e646572446f65734e6f744d61746368547852656365697665724b696e644800522a64656c6567617465416374696f6e53656e646572446f65734e6f744d617463685478526563656976657212640a1764656c65676174655f616374696f6e5f6578706972656418272001280b322a2e73662e6e6561722e747970652e76312e44656c6567617465416374696f6e457870697265644b696e644800521564656c6567617465416374696f6e45787069726564127b0a2064656c65676174655f616374696f6e5f6163636573735f6b65795f6572726f7218282001280b32312e73662e6e6561722e747970652e76312e44656c6567617465416374696f6e4163636573734b65794572726f724b696e644800521c64656c6567617465416374696f6e4163636573734b65794572726f7212740a1d64656c65676174655f616374696f6e5f696e76616c69645f6e6f6e636518292001280b322f2e73662e6e6561722e747970652e76312e44656c6567617465416374696f6e496e76616c69644e6f6e63654b696e644800521a64656c6567617465416374696f6e496e76616c69644e6f6e636512780a1f64656c65676174655f616374696f6e5f6e6f6e63655f746f6f5f6c61726765182a2001280b32302e73662e6e6561722e747970652e76312e44656c6567617465416374696f6e4e6f6e6365546f6f4c617267654b696e644800521b64656c6567617465416374696f6e4e6f6e6365546f6f4c6172676542060a046b696e64223e0a1d4163636f756e74416c72656164794578697374734572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e744964223d0a1c4163636f756e74446f65734e6f7445786973744572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e744964229f010a254372656174654163636f756e744f6e6c7942795265676973747261724572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e74496412300a147265676973747261725f6163636f756e745f696418022001280952127265676973747261724163636f756e74496412250a0e7072656465636573736f725f6964180320012809520d7072656465636573736f72496422680a204372656174654163636f756e744e6f74416c6c6f7765644572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e74496412250a0e7072656465636573736f725f6964180220012809520d7072656465636573736f72496422560a1a4163746f724e6f5065726d697373696f6e4572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e74496412190a086163746f725f696418022001280952076163746f724964227a0a1e44656c6574654b6579446f65734e6f7445786973744572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e74496412390a0a7075626c69635f6b657918022001280b321a2e73662e6e6561722e747970652e76312e5075626c69634b657952097075626c69634b657922780a1c4164644b6579416c72656164794578697374734572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e74496412390a0a7075626c69635f6b657918022001280b321a2e73662e6e6561722e747970652e76312e5075626c69634b657952097075626c69634b6579223e0a1d44656c6574654163636f756e745374616b696e674572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e74496422700a1c4c61636b42616c616e6365466f7253746174654572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e74496412310a0762616c616e636518022001280b32172e73662e6e6561722e747970652e76312e426967496e74520762616c616e636522380a175472696573546f556e7374616b654572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e74496422c9010a155472696573546f5374616b654572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e744964122d0a057374616b6518022001280b32172e73662e6e6561722e747970652e76312e426967496e7452057374616b65122f0a066c6f636b656418032001280b32172e73662e6e6561722e747970652e76312e426967496e7452066c6f636b656412310a0762616c616e636518042001280b32172e73662e6e6561722e747970652e76312e426967496e74520762616c616e636522a8010a1a496e73756666696369656e745374616b654572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e744964122d0a057374616b6518022001280b32172e73662e6e6561722e747970652e76312e426967496e7452057374616b65123c0a0d6d696e696d756d5f7374616b6518032001280b32172e73662e6e6561722e747970652e76312e426967496e74520c6d696e696d756d5374616b6522540a1546756e6374696f6e43616c6c4572726f724b696e64123b0a056572726f7218012001280e32252e73662e6e6561722e747970652e76312e46756e6374696f6e43616c6c4572726f7253657252056572726f72225e0a1d4e65775265636569707456616c69646174696f6e4572726f724b696e64123d0a056572726f7218012001280e32272e73662e6e6561722e747970652e76312e5265636569707456616c69646174696f6e4572726f7252056572726f72224c0a2b4f6e6c79496d706c696369744163636f756e744372656174696f6e416c6c6f7765644572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e74496422450a2444656c6574654163636f756e74576974684c6172676553746174654572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e74496422240a2244656c6567617465416374696f6e496e76616c69645369676e61747572654b696e64226e0a2e44656c6567617465416374696f6e53656e646572446f65734e6f744d61746368547852656365697665724b696e64121b0a0973656e6465725f6964180120012809520873656e6465724964121f0a0b72656365697665725f6964180220012809520a72656365697665724964221b0a1944656c6567617465416374696f6e457870697265644b696e6422590a2044656c6567617465416374696f6e4163636573734b65794572726f724b696e6412350a056572726f7218012001280e321f2e73662e6e6561722e747970652e76312e496e76616c696454784572726f7252056572726f7222620a1e44656c6567617465416374696f6e496e76616c69644e6f6e63654b696e6412250a0e64656c65676174655f6e6f6e6365180120012804520d64656c65676174654e6f6e636512190a08616b5f6e6f6e63651802200128045207616b4e6f6e636522690a1f44656c6567617465416374696f6e4e6f6e6365546f6f4c617267654b696e6412250a0e64656c65676174655f6e6f6e6365180120012804520d64656c65676174654e6f6e6365121f0a0b75707065725f626f756e64180220012804520a7570706572426f756e6422410a0a4d65726b6c655061746812330a047061746818012003280b321f2e73662e6e6561722e747970652e76312e4d65726b6c65506174684974656d520470617468227b0a0e4d65726b6c65506174684974656d122f0a046861736818012001280b321b2e73662e6e6561722e747970652e76312e43727970746f4861736852046861736812380a09646972656374696f6e18022001280e321a2e73662e6e6561722e747970652e76312e446972656374696f6e5209646972656374696f6e2285050a06416374696f6e124d0a0e6372656174655f6163636f756e7418012001280b32242e73662e6e6561722e747970652e76312e4372656174654163636f756e74416374696f6e4800520d6372656174654163636f756e7412500a0f6465706c6f795f636f6e747261637418022001280b32252e73662e6e6561722e747970652e76312e4465706c6f79436f6e7472616374416374696f6e4800520e6465706c6f79436f6e7472616374124a0a0d66756e6374696f6e5f63616c6c18032001280b32232e73662e6e6561722e747970652e76312e46756e6374696f6e43616c6c416374696f6e4800520c66756e6374696f6e43616c6c123d0a087472616e7366657218042001280b321f2e73662e6e6561722e747970652e76312e5472616e73666572416374696f6e480052087472616e7366657212340a057374616b6518052001280b321c2e73662e6e6561722e747970652e76312e5374616b65416374696f6e480052057374616b6512380a076164645f6b657918062001280b321d2e73662e6e6561722e747970652e76312e4164644b6579416374696f6e480052066164644b657912410a0a64656c6574655f6b657918072001280b32202e73662e6e6561722e747970652e76312e44656c6574654b6579416374696f6e4800520964656c6574654b6579124d0a0e64656c6574655f6163636f756e7418082001280b32242e73662e6e6561722e747970652e76312e44656c6574654163636f756e74416374696f6e4800520d64656c6574654163636f756e7412430a0864656c656761746518092001280b32252e73662e6e6561722e747970652e76312e5369676e656444656c6567617465416374696f6e4800520864656c656761746542080a06616374696f6e22150a134372656174654163636f756e74416374696f6e222a0a144465706c6f79436f6e7472616374416374696f6e12120a04636f646518012001280c5204636f6465228e010a1246756e6374696f6e43616c6c416374696f6e121f0a0b6d6574686f645f6e616d65180120012809520a6d6574686f644e616d6512120a046172677318022001280c52046172677312100a03676173180320012804520367617312310a076465706f73697418042001280b32172e73662e6e6561722e747970652e76312e426967496e7452076465706f73697422430a0e5472616e73666572416374696f6e12310a076465706f73697418012001280b32172e73662e6e6561722e747970652e76312e426967496e7452076465706f73697422770a0b5374616b65416374696f6e122d0a057374616b6518012001280b32172e73662e6e6561722e747970652e76312e426967496e7452057374616b6512390a0a7075626c69635f6b657918022001280b321a2e73662e6e6561722e747970652e76312e5075626c69634b657952097075626c69634b65792284010a0c4164644b6579416374696f6e12390a0a7075626c69635f6b657918012001280b321a2e73662e6e6561722e747970652e76312e5075626c69634b657952097075626c69634b657912390a0a6163636573735f6b657918022001280b321a2e73662e6e6561722e747970652e76312e4163636573734b657952096163636573734b6579224c0a0f44656c6574654b6579416374696f6e12390a0a7075626c69635f6b657918012001280b321a2e73662e6e6561722e747970652e76312e5075626c69634b657952097075626c69634b6579223c0a1344656c6574654163636f756e74416374696f6e12250a0e62656e65666963696172795f6964180120012809520d62656e65666963696172794964229a010a145369676e656444656c6567617465416374696f6e12380a097369676e617475726518012001280b321a2e73662e6e6561722e747970652e76312e5369676e617475726552097369676e617475726512480a0f64656c65676174655f616374696f6e18022001280b321f2e73662e6e6561722e747970652e76312e44656c6567617465416374696f6e520e64656c6567617465416374696f6e22fc010a0e44656c6567617465416374696f6e121b0a0973656e6465725f6964180120012809520873656e6465724964121f0a0b72656365697665725f6964180220012809520a7265636569766572496412310a07616374696f6e7318032003280b32172e73662e6e6561722e747970652e76312e416374696f6e5207616374696f6e7312140a056e6f6e636518042001280452056e6f6e636512280a106d61785f626c6f636b5f686569676874180520012804520e6d6178426c6f636b48656967687412390a0a7075626c69635f6b657918062001280b321a2e73662e6e6561722e747970652e76312e5075626c69634b657952097075626c69634b657922670a094163636573734b657912140a056e6f6e636518012001280452056e6f6e636512440a0a7065726d697373696f6e18022001280b32242e73662e6e6561722e747970652e76312e4163636573734b65795065726d697373696f6e520a7065726d697373696f6e22bd010a134163636573734b65795065726d697373696f6e124e0a0d66756e6374696f6e5f63616c6c18012001280b32272e73662e6e6561722e747970652e76312e46756e6374696f6e43616c6c5065726d697373696f6e4800520c66756e6374696f6e43616c6c12480a0b66756c6c5f61636365737318022001280b32252e73662e6e6561722e747970652e76312e46756c6c4163636573735065726d697373696f6e4800520a66756c6c416363657373420c0a0a7065726d697373696f6e2293010a1646756e6374696f6e43616c6c5065726d697373696f6e12350a09616c6c6f77616e636518012001280b32172e73662e6e6561722e747970652e76312e426967496e745209616c6c6f77616e6365121f0a0b72656365697665725f6964180220012809520a7265636569766572496412210a0c6d6574686f645f6e616d6573180320032809520b6d6574686f644e616d657322160a1446756c6c4163636573735065726d697373696f6e2a270a0943757276654b696e64120b0a07454432353531391000120d0a09534543503235364b3110012a2c0a11457865637574696f6e4d6574616461746112170a13457865637574696f6e4d65746164617461563110002aa9010a1446756e6374696f6e43616c6c4572726f7253657212140a10436f6d70696c6174696f6e4572726f721000120d0a094c696e6b4572726f72100112160a124d6574686f645265736f6c76654572726f721002120c0a085761736d54726170100312140a105761736d556e6b6e6f776e4572726f721004120d0a09486f73744572726f721005120d0a095f45564d4572726f72100612120a0e457865637574696f6e4572726f7210072aed010a165265636569707456616c69646174696f6e4572726f7212180a14496e76616c69645072656465636573736f7249641000121c0a18496e76616c696452656365697665724163636f756e7449641001121a0a16496e76616c69645369676e65724163636f756e744964100212190a15496e76616c696444617461526563656976657249641003121f0a1b52657475726e656456616c75654c656e6774684578636565646564100412270a234e756d626572496e70757444617461446570656e64656e6369657345786365656465641005121a0a16416374696f6e7356616c69646174696f6e4572726f7210062abe020a0e496e76616c696454784572726f7212190a15496e76616c69644163636573734b65794572726f72100012130a0f496e76616c69645369676e65724964100112160a125369676e6572446f65734e6f744578697374100212100a0c496e76616c69644e6f6e6365100312110a0d4e6f6e6365546f6f4c61726765100412150a11496e76616c696452656365697665724964100512140a10496e76616c69645369676e6174757265100612140a104e6f74456e6f75676842616c616e6365100712170a134c61636b42616c616e6365466f725374617465100812100a0c436f73744f766572666c6f77100912100a0c496e76616c6964436861696e100a120b0a0745787069726564100b12150a11416374696f6e7356616c69646174696f6e100c121b0a175472616e73616374696f6e53697a654578636565646564100d2a200a09446972656374696f6e12080a046c656674100012090a057269676874100142425a406769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d6e6561722f70622f73662f6e6561722f747970652f76313b70626e656172620670726f746f33", - - // sf/solana/transforms/v1/transforms.proto (https://buf.build/streamingfast/firehose-solana/docs/7e16dd37d68049d1a3f548203be431d7:sf.solana.transforms.v1) - "0a2873662f736f6c616e612f7472616e73666f726d732f76312f7472616e73666f726d732e70726f746f121773662e736f6c616e612e7472616e73666f726d732e763122300a0d50726f6772616d46696c746572121f0a0b70726f6772616d5f696473180120032809520a70726f6772616d49647342525a506769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d736f6c616e612f70622f73662f736f6c616e612f7472616e73666f726d732f76313b70627472616e73666f726d73620670726f746f33", - - // sf/solana/type/v1/type.proto (https://buf.build/streamingfast/firehose-solana/docs/7e16dd37d68049d1a3f548203be431d7:sf.solana.type.v1) - "0a1c73662f736f6c616e612f747970652f76312f747970652e70726f746f121173662e736f6c616e612e747970652e7631228f030a05426c6f636b122d0a1270726576696f75735f626c6f636b68617368180120012809521170726576696f7573426c6f636b68617368121c0a09626c6f636b686173681802200128095209626c6f636b68617368121f0a0b706172656e745f736c6f74180320012804520a706172656e74536c6f74124b0a0c7472616e73616374696f6e7318042003280b32272e73662e736f6c616e612e747970652e76312e436f6e6669726d65645472616e73616374696f6e520c7472616e73616374696f6e7312330a077265776172647318052003280b32192e73662e736f6c616e612e747970652e76312e526577617264520772657761726473123f0a0a626c6f636b5f74696d6518062001280b32202e73662e736f6c616e612e747970652e76312e556e697854696d657374616d705209626c6f636b54696d6512410a0c626c6f636b5f68656967687418072001280b321e2e73662e736f6c616e612e747970652e76312e426c6f636b486569676874520b626c6f636b48656967687412120a04736c6f741814200128045204736c6f742296010a14436f6e6669726d65645472616e73616374696f6e12400a0b7472616e73616374696f6e18012001280b321e2e73662e736f6c616e612e747970652e76312e5472616e73616374696f6e520b7472616e73616374696f6e123c0a046d65746118022001280b32282e73662e736f6c616e612e747970652e76312e5472616e73616374696f6e5374617475734d65746152046d65746122630a0b5472616e73616374696f6e121e0a0a7369676e61747572657318012003280c520a7369676e61747572657312340a076d65737361676518022001280b321a2e73662e736f6c616e612e747970652e76312e4d65737361676552076d65737361676522dd020a074d65737361676512380a0668656164657218012001280b32202e73662e736f6c616e612e747970652e76312e4d657373616765486561646572520668656164657212210a0c6163636f756e745f6b65797318022003280c520b6163636f756e744b65797312290a10726563656e745f626c6f636b6861736818032001280c520f726563656e74426c6f636b68617368124a0a0c696e737472756374696f6e7318042003280b32262e73662e736f6c616e612e747970652e76312e436f6d70696c6564496e737472756374696f6e520c696e737472756374696f6e73121c0a0976657273696f6e6564180520012808520976657273696f6e656412600a15616464726573735f7461626c655f6c6f6f6b75707318062003280b322c2e73662e736f6c616e612e747970652e76312e4d657373616765416464726573735461626c654c6f6f6b75705213616464726573735461626c654c6f6f6b75707322cd010a0d4d65737361676548656164657212360a176e756d5f72657175697265645f7369676e61747572657318012001280d52156e756d52657175697265645369676e617475726573123f0a1c6e756d5f726561646f6e6c795f7369676e65645f6163636f756e747318022001280d52196e756d526561646f6e6c795369676e65644163636f756e747312430a1e6e756d5f726561646f6e6c795f756e7369676e65645f6163636f756e747318032001280d521b6e756d526561646f6e6c79556e7369676e65644163636f756e74732292010a194d657373616765416464726573735461626c654c6f6f6b7570121f0a0b6163636f756e745f6b657918012001280c520a6163636f756e744b657912290a107772697461626c655f696e646578657318022001280c520f7772697461626c65496e646578657312290a10726561646f6e6c795f696e646578657318032001280c520f726561646f6e6c79496e64657865732283060a155472616e73616374696f6e5374617475734d65746112350a0365727218012001280b32232e73662e736f6c616e612e747970652e76312e5472616e73616374696f6e4572726f72520365727212100a03666565180220012804520366656512210a0c7072655f62616c616e636573180320032804520b70726542616c616e63657312230a0d706f73745f62616c616e636573180420032804520c706f737442616c616e63657312530a12696e6e65725f696e737472756374696f6e7318052003280b32242e73662e736f6c616e612e747970652e76312e496e6e6572496e737472756374696f6e735211696e6e6572496e737472756374696f6e7312210a0c6c6f675f6d65737361676573180620032809520b6c6f674d65737361676573124d0a127072655f746f6b656e5f62616c616e63657318072003280b321f2e73662e736f6c616e612e747970652e76312e546f6b656e42616c616e63655210707265546f6b656e42616c616e636573124f0a13706f73745f746f6b656e5f62616c616e63657318082003280b321f2e73662e736f6c616e612e747970652e76312e546f6b656e42616c616e63655211706f7374546f6b656e42616c616e63657312330a077265776172647318092003280b32192e73662e736f6c616e612e747970652e76312e526577617264520772657761726473123a0a196c6f616465645f7772697461626c655f616464726573736573180c2003280c52176c6f616465645772697461626c65416464726573736573123a0a196c6f616465645f726561646f6e6c795f616464726573736573180d2003280c52176c6f61646564526561646f6e6c79416464726573736573123e0a0b72657475726e5f64617461180e2001280b321d2e73662e736f6c616e612e747970652e76312e52657475726e44617461520a72657475726e4461746112390a16636f6d707574655f756e6974735f636f6e73756d656418102001280448005214636f6d70757465556e697473436f6e73756d656488010142190a175f636f6d707574655f756e6974735f636f6e73756d656422240a105472616e73616374696f6e4572726f7212100a0365727218012001280c520365727222720a11496e6e6572496e737472756374696f6e7312140a05696e64657818012001280d5205696e64657812470a0c696e737472756374696f6e7318022003280b32232e73662e736f6c616e612e747970652e76312e496e6e6572496e737472756374696f6e520c696e737472756374696f6e7322a5010a10496e6e6572496e737472756374696f6e12280a1070726f6772616d5f69645f696e64657818012001280d520e70726f6772616d4964496e646578121a0a086163636f756e747318022001280c52086163636f756e747312120a046461746118032001280c52046461746112260a0c737461636b5f68656967687418042001280d4800520b737461636b486569676874880101420f0a0d5f737461636b5f686569676874226f0a13436f6d70696c6564496e737472756374696f6e12280a1070726f6772616d5f69645f696e64657818012001280d520e70726f6772616d4964496e646578121a0a086163636f756e747318022001280c52086163636f756e747312120a046461746118032001280c52046461746122c6010a0c546f6b656e42616c616e636512230a0d6163636f756e745f696e64657818012001280d520c6163636f756e74496e64657812120a046d696e7418022001280952046d696e7412480a0f75695f746f6b656e5f616d6f756e7418032001280b32202e73662e736f6c616e612e747970652e76312e5569546f6b656e416d6f756e74520d7569546f6b656e416d6f756e7412140a056f776e657218042001280952056f776e6572121d0a0a70726f6772616d5f6964180520012809520970726f6772616d4964228a010a0d5569546f6b656e416d6f756e74121b0a0975695f616d6f756e7418012001280152087569416d6f756e74121a0a08646563696d616c7318022001280d5208646563696d616c7312160a06616d6f756e741803200128095206616d6f756e7412280a1075695f616d6f756e745f737472696e67180420012809520e7569416d6f756e74537472696e67223f0a0a52657475726e44617461121d0a0a70726f6772616d5f696418012001280c520970726f6772616d496412120a046461746118022001280c52046461746122bf010a0652657761726412160a067075626b657918012001280952067075626b6579121a0a086c616d706f72747318022001280352086c616d706f72747312210a0c706f73745f62616c616e6365180320012804520b706f737442616c616e6365123e0a0b7265776172645f7479706518042001280e321d2e73662e736f6c616e612e747970652e76312e52657761726454797065520a72657761726454797065121e0a0a636f6d6d697373696f6e180520012809520a636f6d6d697373696f6e223e0a075265776172647312330a077265776172647318012003280b32192e73662e736f6c616e612e747970652e76312e526577617264520772657761726473222d0a0d556e697854696d657374616d70121c0a0974696d657374616d70180120012803520974696d657374616d7022300a0b426c6f636b48656967687412210a0c626c6f636b5f686569676874180120012804520b626c6f636b4865696768742a490a0a52657761726454797065120f0a0b556e737065636966696564100012070a03466565100112080a0452656e741002120b0a075374616b696e671003120a0a06566f74696e67100442455a436769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d736f6c616e612f70622f73662f736f6c616e612f747970652f76313b7062736f6c620670726f746f33", - - // sf/bitcoin/type/v1/type.proto (https://buf.build/streamingfast/firehose-bitcoin/docs/0d8ce32fe71441df82c89dcccda35366:sf.bitcoin.type.v1) - "0a1d73662f626974636f696e2f747970652f76312f747970652e70726f746f121273662e626974636f696e2e747970652e76311a1f676f6f676c652f70726f746f6275662f74696d657374616d702e70726f746f22e5030a05426c6f636b12120a046861736818012001280952046861736812120a0473697a65180320012805520473697a6512230a0d73747269707065645f73697a65180420012805520c737472697070656453697a6512160a06776569676874180520012805520677656967687412160a06686569676874180620012803520668656967687412180a0776657273696f6e180720012805520776657273696f6e121f0a0b76657273696f6e5f686578180820012809520a76657273696f6e486578121f0a0b6d65726b6c655f726f6f74180920012809520a6d65726b6c65526f6f74122f0a027478180a2003280b321f2e73662e626974636f696e2e747970652e76312e5472616e73616374696f6e5202747812120a0474696d65180b20012803520474696d65121e0a0a6d656469616e74696d65180c20012803520a6d656469616e74696d6512140a056e6f6e6365180d2001280d52056e6f6e636512120a0462697473180e20012809520462697473121e0a0a646966666963756c7479180f20012801520a646966666963756c7479121c0a09636861696e776f726b1810200128095209636861696e776f726b12110a046e5f747818112001280d52036e547812230a0d70726576696f75735f68617368181220012809520c70726576696f75734861736822d4020a0b5472616e73616374696f6e12100a03686578180120012809520368657812120a047478696418022001280952047478696412120a046861736818032001280952046861736812120a0473697a65180420012805520473697a6512140a057673697a6518052001280552057673697a6512160a06776569676874180620012805520677656967687412180a0776657273696f6e18072001280d520776657273696f6e121a0a086c6f636b74696d6518082001280d52086c6f636b74696d6512290a0376696e18092003280b32172e73662e626974636f696e2e747970652e76312e56696e520376696e122c0a04766f7574180a2003280b32182e73662e626974636f696e2e747970652e76312e566f75745204766f7574121c0a09626c6f636b68617368180b200128095209626c6f636b68617368121c0a09626c6f636b74696d65180c200128035209626c6f636b74696d6522c5010a0356696e12120a047478696418012001280952047478696412120a04766f757418022001280d5204766f7574123c0a0a7363726970745f73696718032001280b321d2e73662e626974636f696e2e747970652e76312e5363726970745369675209736372697074536967121a0a0873657175656e636518042001280d520873657175656e636512200a0b7478696e7769746e657373180520032809520b7478696e7769746e657373121a0a08636f696e626173651806200128095208636f696e6261736522710a04566f757412140a0576616c7565180120012801520576616c7565120c0a016e18022001280d52016e12450a0d7363726970745f7075624b657918032001280b32202e73662e626974636f696e2e747970652e76312e5363726970745075624b6579520c7363726970745075624b6579222f0a0953637269707453696712100a0361736d180120012809520361736d12100a0368657818022001280952036865782299010a0c5363726970745075624b657912100a0361736d180120012809520361736d12100a03686578180220012809520368657812190a087265715f7369677318032001280552077265715369677312120a047479706518042001280952047479706512180a0761646472657373180520012809520761646472657373121c0a096164647265737365731806200328095209616464726573736573424d5a4b6769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d626974636f696e2f74797065732f70622f73662f626974636f696e2f747970652f76313b7062627463620670726f746f33", - - // google/protobuf/timestamp.proto (https://buf.build/pinax/firehose-antelope/docs/3af26456175d4f1883a091182f77d0db:google.protobuf) - "0a1f676f6f676c652f70726f746f6275662f74696d657374616d702e70726f746f120f676f6f676c652e70726f746f627566223b0a0954696d657374616d7012180a077365636f6e647318012001280352077365636f6e647312140a056e616e6f7318022001280552056e616e6f734285010a13636f6d2e676f6f676c652e70726f746f627566420e54696d657374616d7050726f746f50015a32676f6f676c652e676f6c616e672e6f72672f70726f746f6275662f74797065732f6b6e6f776e2f74696d657374616d707062f80101a20203475042aa021e476f6f676c652e50726f746f6275662e57656c6c4b6e6f776e5479706573620670726f746f33", - - // sf/antelope/type/v1/type.proto (https://buf.build/pinax/firehose-antelope/docs/3af26456175d4f1883a091182f77d0db:sf.antelope.type.v1) - "0a1e73662f616e74656c6f70652f747970652f76312f747970652e70726f746f121373662e616e74656c6f70652e747970652e76311a1f676f6f676c652f70726f746f6275662f74696d657374616d702e70726f746f22550a0c416374696f6e54726163657312450a0d616374696f6e5f74726163657318012003280b32202e73662e616e74656c6f70652e747970652e76312e416374696f6e5472616365520c616374696f6e54726163657322690a115472616e73616374696f6e54726163657312540a127472616e73616374696f6e5f74726163657318012003280b32252e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e547261636552117472616e73616374696f6e54726163657322390a0544424f707312300a0664625f6f707318012003280b32192e73662e616e74656c6f70652e747970652e76312e44424f70520564624f7073228b160a05426c6f636b120e0a0269641801200128095202696412160a066e756d62657218022001280d52066e756d62657212180a0776657273696f6e18032001280d520776657273696f6e12380a0668656164657218042001280b32202e73662e616e74656c6f70652e747970652e76312e426c6f636b4865616465725206686561646572122d0a1270726f64756365725f7369676e6174757265180520012809521170726f64756365725369676e617475726512490a10626c6f636b5f657874656e73696f6e7318072003280b321e2e73662e616e74656c6f70652e747970652e76312e457874656e73696f6e520f626c6f636b457874656e73696f6e73124d0a2364706f735f70726f706f7365645f697272657665727369626c655f626c6f636b6e756d18082001280d522064706f7350726f706f736564497272657665727369626c65426c6f636b6e756d123c0a1a64706f735f697272657665727369626c655f626c6f636b6e756d18092001280d521864706f73497272657665727369626c65426c6f636b6e756d124f0a10626c6f636b726f6f745f6d65726b6c65180b2001280b32242e73662e616e74656c6f70652e747970652e76312e426c6f636b526f6f744d65726b6c65520f626c6f636b726f6f744d65726b6c6512660a1970726f64756365725f746f5f6c6173745f70726f6475636564180c2003280b322b2e73662e616e74656c6f70652e747970652e76312e50726f6475636572546f4c61737450726f6475636564521670726f6475636572546f4c61737450726f6475636564126d0a1c70726f64756365725f746f5f6c6173745f696d706c6965645f697262180d2003280b322d2e73662e616e74656c6f70652e747970652e76312e50726f6475636572546f4c617374496d706c696564495242521870726f6475636572546f4c617374496d706c69656449726212230a0d636f6e6669726d5f636f756e74180f2003280d520c636f6e6669726d436f756e7412570a1070656e64696e675f7363686564756c6518102001280b322c2e73662e616e74656c6f70652e747970652e76312e50656e64696e6750726f64756365725363686564756c65520f70656e64696e675363686564756c65126e0a1b6163746976617465645f70726f746f636f6c5f666561747572657318112001280b322e2e73662e616e74656c6f70652e747970652e76312e41637469766174656450726f746f636f6c4665617475726573521961637469766174656450726f746f636f6c4665617475726573123c0a0a726c696d69745f6f707318132003280b321d2e73662e616e74656c6f70652e747970652e76312e526c696d69744f705209726c696d69744f707312600a17756e66696c74657265645f7472616e73616374696f6e7318062003280b32272e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e526563656970745216756e66696c74657265645472616e73616374696f6e73125c0a1566696c74657265645f7472616e73616374696f6e73182f2003280b32272e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e52656365697074521466696c74657265645472616e73616374696f6e7312400a1c756e66696c74657265645f7472616e73616374696f6e5f636f756e7418162001280d521a756e66696c74657265645472616e73616374696f6e436f756e74123c0a1a66696c74657265645f7472616e73616374696f6e5f636f756e7418302001280d521866696c74657265645472616e73616374696f6e436f756e7412690a23756e66696c74657265645f696d706c696369745f7472616e73616374696f6e5f6f707318142003280b321a2e73662e616e74656c6f70652e747970652e76312e5472784f705220756e66696c7465726564496d706c696369745472616e73616374696f6e4f707312650a2166696c74657265645f696d706c696369745f7472616e73616374696f6e5f6f707318312003280b321a2e73662e616e74656c6f70652e747970652e76312e5472784f70521e66696c7465726564496d706c696369745472616e73616374696f6e4f707312690a1d756e66696c74657265645f7472616e73616374696f6e5f74726163657318152003280b32252e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5472616365521b756e66696c74657265645472616e73616374696f6e54726163657312650a1b66696c74657265645f7472616e73616374696f6e5f747261636573182e2003280b32252e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5472616365521966696c74657265645472616e73616374696f6e547261636573124b0a22756e66696c74657265645f7472616e73616374696f6e5f74726163655f636f756e7418172001280d521f756e66696c74657265645472616e73616374696f6e5472616365436f756e7412470a2066696c74657265645f7472616e73616374696f6e5f74726163655f636f756e74182b2001280d521d66696c74657265645472616e73616374696f6e5472616365436f756e7412520a26756e66696c74657265645f65786563757465645f696e7075745f616374696f6e5f636f756e7418182001280d5222756e66696c74657265644578656375746564496e707574416374696f6e436f756e74124e0a2466696c74657265645f65786563757465645f696e7075745f616374696f6e5f636f756e74182c2001280d522066696c74657265644578656375746564496e707574416374696f6e436f756e7412520a26756e66696c74657265645f65786563757465645f746f74616c5f616374696f6e5f636f756e7418192001280d5222756e66696c74657265644578656375746564546f74616c416374696f6e436f756e74124e0a2466696c74657265645f65786563757465645f746f74616c5f616374696f6e5f636f756e74182d2001280d522066696c74657265644578656375746564546f74616c416374696f6e436f756e74122a0a11626c6f636b5f7369676e696e675f6b6579180e20012809520f626c6f636b5369676e696e674b657912530a126163746976655f7363686564756c655f7631180a2001280b32252e73662e616e74656c6f70652e747970652e76312e50726f64756365725363686564756c6552106163746976655363686564756c65563112720a2076616c69645f626c6f636b5f7369676e696e675f617574686f726974795f7632181e2001280b322a2e73662e616e74656c6f70652e747970652e76312e426c6f636b5369676e696e67417574686f72697479521c76616c6964426c6f636b5369676e696e67417574686f726974795632125c0a126163746976655f7363686564756c655f7632181f2001280b322e2e73662e616e74656c6f70652e747970652e76312e50726f6475636572417574686f726974795363686564756c6552106163746976655363686564756c655632122b0a1166696c746572696e675f6170706c696564182820012808521066696c746572696e674170706c69656412410a1d66696c746572696e675f696e636c7564655f66696c7465725f65787072182920012809521a66696c746572696e67496e636c75646546696c7465724578707212410a1d66696c746572696e675f6578636c7564655f66696c7465725f65787072182a20012809521a66696c746572696e674578636c75646546696c74657245787072125d0a2c66696c746572696e675f73797374656d5f616374696f6e735f696e636c7564655f66696c7465725f65787072183220012809522766696c746572696e6753797374656d416374696f6e73496e636c75646546696c746572457870724a04081210132284030a0d426c6f636b5769746852656673120e0a0269641801200128095202696412300a05626c6f636b18022001280b321a2e73662e616e74656c6f70652e747970652e76312e426c6f636b5205626c6f636b12600a19696d706c696369745f7472616e73616374696f6e5f7265667318032001280b32242e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e526566735217696d706c696369745472616e73616374696f6e52656673124f0a107472616e73616374696f6e5f7265667318042001280b32242e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e52656673520f7472616e73616374696f6e52656673125a0a167472616e73616374696f6e5f74726163655f7265667318052001280b32242e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5265667352147472616e73616374696f6e54726163655265667312220a0c697272657665727369626c65180620012808520c697272657665727369626c6522290a0f5472616e73616374696f6e5265667312160a0668617368657318012003280c520668617368657322480a1941637469766174656450726f746f636f6c4665617475726573122b0a1170726f746f636f6c5f666561747572657318012003280c521070726f746f636f6c46656174757265732281020a1750656e64696e6750726f64756365725363686564756c6512280a107363686564756c655f6c69625f6e756d18012001280d520e7363686564756c654c69624e756d12230a0d7363686564756c655f6861736818022001280c520c7363686564756c654861736812460a0b7363686564756c655f763118032001280b32252e73662e616e74656c6f70652e747970652e76312e50726f64756365725363686564756c65520a7363686564756c655631124f0a0b7363686564756c655f763218042001280b322e2e73662e616e74656c6f70652e747970652e76312e50726f6475636572417574686f726974795363686564756c65520a7363686564756c655632226c0a1050726f64756365725363686564756c6512180a0776657273696f6e18012001280d520776657273696f6e123e0a0970726f64756365727318022003280b32202e73662e616e74656c6f70652e747970652e76312e50726f64756365724b6579520970726f647563657273225c0a0b50726f64756365724b657912210a0c6163636f756e745f6e616d65180120012809520b6163636f756e744e616d65122a0a11626c6f636b5f7369676e696e675f6b6579180220012809520f626c6f636b5369676e696e674b6579227b0a1950726f6475636572417574686f726974795363686564756c6512180a0776657273696f6e18012001280d520776657273696f6e12440a0970726f64756365727318022003280b32262e73662e616e74656c6f70652e747970652e76312e50726f6475636572417574686f72697479520970726f647563657273229a010a1150726f6475636572417574686f7269747912210a0c6163636f756e745f6e616d65180120012809520b6163636f756e744e616d6512620a17626c6f636b5f7369676e696e675f617574686f7269747918022001280b322a2e73662e616e74656c6f70652e747970652e76312e426c6f636b5369676e696e67417574686f726974795215626c6f636b5369676e696e67417574686f7269747922620a15426c6f636b5369676e696e67417574686f72697479123e0a02763018012001280b322c2e73662e616e74656c6f70652e747970652e76312e426c6f636b5369676e696e67417574686f72697479563048005202763042090a0776617269616e74226b0a17426c6f636b5369676e696e67417574686f726974795630121c0a097468726573686f6c6418012001280d52097468726573686f6c6412320a046b65797318022003280b321e2e73662e616e74656c6f70652e747970652e76312e4b657957656967687452046b65797322530a0f426c6f636b526f6f744d65726b6c65121d0a0a6e6f64655f636f756e7418012001280d52096e6f6465436f756e7412210a0c6163746976655f6e6f64657318022003280c520b6163746976654e6f64657322630a1650726f6475636572546f4c61737450726f647563656412120a046e616d6518012001280952046e616d6512350a176c6173745f626c6f636b5f6e756d5f70726f647563656418022001280d52146c617374426c6f636b4e756d50726f647563656422650a1850726f6475636572546f4c617374496d706c69656449524212120a046e616d6518012001280952046e616d6512350a176c6173745f626c6f636b5f6e756d5f70726f647563656418022001280d52146c617374426c6f636b4e756d50726f647563656422b0020a125472616e73616374696f6e52656365697074120e0a0269641804200128095202696412140a05696e6465781806200128045205696e646578123e0a0673746174757318012001280e32262e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e537461747573520673746174757312350a176370755f75736167655f6d6963726f5f7365636f6e647318022001280d521463707555736167654d6963726f5365636f6e647312260a0f6e65745f75736167655f776f72647318032001280d520d6e65745573616765576f72647312550a127061636b65645f7472616e73616374696f6e18052001280b32262e73662e616e74656c6f70652e747970652e76312e5061636b65645472616e73616374696f6e52117061636b65645472616e73616374696f6e22bd010a115061636b65645472616e73616374696f6e121e0a0a7369676e617475726573180120032809520a7369676e61747572657312200a0b636f6d7072657373696f6e18022001280d520b636f6d7072657373696f6e12370a187061636b65645f636f6e746578745f667265655f6461746118032001280c52157061636b6564436f6e746578744672656544617461122d0a127061636b65645f7472616e73616374696f6e18042001280c52117061636b65645472616e73616374696f6e22b6030a0b426c6f636b48656164657212380a0974696d657374616d7018032001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d70520974696d657374616d70121a0a0870726f6475636572180420012809520870726f6475636572121c0a09636f6e6669726d656418052001280d5209636f6e6669726d6564121a0a0870726576696f7573180620012809520870726576696f7573122b0a117472616e73616374696f6e5f6d726f6f7418072001280c52107472616e73616374696f6e4d726f6f7412210a0c616374696f6e5f6d726f6f7418082001280c520b616374696f6e4d726f6f7412290a107363686564756c655f76657273696f6e18092001280d520f7363686564756c6556657273696f6e124b0a116865616465725f657874656e73696f6e73180b2003280b321e2e73662e616e74656c6f70652e747970652e76312e457874656e73696f6e5210686561646572457874656e73696f6e73124f0a106e65775f70726f6475636572735f7631180a2001280b32252e73662e616e74656c6f70652e747970652e76312e50726f64756365725363686564756c65520e6e657750726f647563657273563122fb090a105472616e73616374696f6e4576656e74120e0a0269641801200128095202696412190a08626c6f636b5f69641802200128095207626c6f636b4964121b0a09626c6f636b5f6e756d18032001280d5208626c6f636b4e756d12220a0c697272657665727369626c65180420012808520c697272657665727369626c6512640a11696e7465726e616c5f6164646974696f6e18052001280b32352e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e4576656e742e4164646564496e7465726e616c6c7948005210696e7465726e616c4164646974696f6e12490a086164646974696f6e18062001280b322b2e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e4576656e742e4164646564480052086164646974696f6e124e0a09657865637574696f6e18072001280b322e2e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e4576656e742e457865637574656448005209657865637574696f6e125e0a0f647472785f7363686564756c696e6718082001280b32332e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e4576656e742e447472785363686564756c65644800520e647472785363686564756c696e6712610a11647472785f63616e63656c6c6174696f6e18092001280b32322e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e4576656e742e4474727843616e63656c6564480052106474727843616e63656c6c6174696f6e1a5b0a0f4164646564496e7465726e616c6c7912480a0b7472616e73616374696f6e18012001280b32262e73662e616e74656c6f70652e747970652e76312e5369676e65645472616e73616374696f6e520b7472616e73616374696f6e1ad6010a05416464656412410a077265636569707418012001280b32272e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5265636569707452077265636569707412480a0b7472616e73616374696f6e18022001280b32262e73662e616e74656c6f70652e747970652e76312e5369676e65645472616e73616374696f6e520b7472616e73616374696f6e12400a0b7075626c69635f6b65797318032001280b321f2e73662e616e74656c6f70652e747970652e76312e5075626c69634b657973520a7075626c69634b6579731a8b010a084578656375746564123b0a05747261636518012001280b32252e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e54726163655205747261636512420a0b626c6f636b48656164657218022001280b32202e73662e616e74656c6f70652e747970652e76312e426c6f636b486561646572520b626c6f636b4865616465721a98010a0d447472785363686564756c6564123d0a0a637265617465645f627918012001280b321e2e73662e616e74656c6f70652e747970652e76312e457874445472784f70520963726561746564427912480a0b7472616e73616374696f6e18022001280b32262e73662e616e74656c6f70652e747970652e76312e5369676e65645472616e73616374696f6e520b7472616e73616374696f6e1a4f0a0c4474727843616e63656c6564123f0a0b63616e63656c65645f627918012001280b321e2e73662e616e74656c6f70652e747970652e76312e457874445472784f70520a63616e63656c6564427942070a056576656e74222d0a0a5075626c69634b657973121f0a0b7075626c69635f6b657973180120032809520a7075626c69634b657973229d060a145472616e73616374696f6e4c6966656379636c65120e0a0269641801200128095202696412550a127472616e73616374696f6e5f73746174757318022001280e32262e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e53746174757352117472616e73616374696f6e53746174757312580a137472616e73616374696f6e5f7265636569707418242001280b32272e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5265636569707452127472616e73616374696f6e5265636569707412480a0b7472616e73616374696f6e180a2001280b32262e73662e616e74656c6f70652e747970652e76312e5369676e65645472616e73616374696f6e520b7472616e73616374696f6e121f0a0b7075626c69635f6b657973181320032809520a7075626c69634b657973124e0a0f657865637574696f6e5f7472616365180b2001280b32252e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5472616365520e657865637574696f6e547261636512560a16657865637574696f6e5f626c6f636b5f686561646572180c2001280b32202e73662e616e74656c6f70652e747970652e76312e426c6f636b4865616465725214657865637574696f6e426c6f636b486561646572123d0a0a637265617465645f627918142001280b321e2e73662e616e74656c6f70652e747970652e76312e457874445472784f705209637265617465644279123f0a0b63616e63656c65645f627918152001280b321e2e73662e616e74656c6f70652e747970652e76312e457874445472784f70520a63616e63656c6564427912330a156372656174696f6e5f697272657665727369626c6518212001280852146372656174696f6e497272657665727369626c6512350a16657865637574696f6e5f697272657665727369626c651822200128085215657865637574696f6e497272657665727369626c6512390a1863616e63656c6174696f6e5f697272657665727369626c65182320012808521763616e63656c6174696f6e497272657665727369626c654a04080d10134a040816102122a3010a115369676e65645472616e73616374696f6e12420a0b7472616e73616374696f6e18012001280b32202e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e520b7472616e73616374696f6e121e0a0a7369676e617475726573180220032809520a7369676e617475726573122a0a11636f6e746578745f667265655f6461746118032003280c520f636f6e7465787446726565446174612293020a0b5472616e73616374696f6e123e0a0668656164657218012001280b32262e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e4865616465725206686561646572124d0a14636f6e746578745f667265655f616374696f6e7318022003280b321b2e73662e616e74656c6f70652e747970652e76312e416374696f6e5212636f6e7465787446726565416374696f6e7312350a07616374696f6e7318032003280b321b2e73662e616e74656c6f70652e747970652e76312e416374696f6e5207616374696f6e73123e0a0a657874656e73696f6e7318042003280b321e2e73662e616e74656c6f70652e747970652e76312e457874656e73696f6e520a657874656e73696f6e732292020a115472616e73616374696f6e486561646572123a0a0a65787069726174696f6e18012001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d70520a65787069726174696f6e12220a0d7265665f626c6f636b5f6e756d18022001280d520b726566426c6f636b4e756d12280a107265665f626c6f636b5f70726566697818032001280d520e726566426c6f636b507265666978122d0a136d61785f6e65745f75736167655f776f72647318042001280d52106d61784e65745573616765576f72647312270a106d61785f6370755f75736167655f6d7318052001280d520d6d617843707555736167654d73121b0a0964656c61795f73656318062001280d520864656c61795365632288090a105472616e73616374696f6e5472616365120e0a02696418012001280952026964121b0a09626c6f636b5f6e756d1802200128045208626c6f636b4e756d12140a05696e646578181a200128045205696e64657812390a0a626c6f636b5f74696d6518032001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d705209626c6f636b54696d65122a0a1170726f64756365725f626c6f636b5f6964180420012809520f70726f6475636572426c6f636b496412470a077265636569707418052001280b322d2e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5265636569707448656164657252077265636569707412180a07656c61707365641806200128035207656c6170736564121b0a096e65745f757361676518072001280452086e65745573616765121c0a097363686564756c656418082001280852097363686564756c656412450a0d616374696f6e5f74726163657318092003280b32202e73662e616e74656c6f70652e747970652e76312e416374696f6e5472616365520c616374696f6e54726163657312510a116661696c65645f647472785f7472616365180a2001280b32252e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5472616365520f6661696c6564447472785472616365123c0a09657863657074696f6e180f2001280b321e2e73662e616e74656c6f70652e747970652e76312e457863657074696f6e5209657863657074696f6e121d0a0a6572726f725f636f646518102001280452096572726f72436f646512300a0664625f6f707318112003280b32192e73662e616e74656c6f70652e747970652e76312e44424f70520564624f707312360a08647472785f6f707318122003280b321b2e73662e616e74656c6f70652e747970652e76312e445472784f705207647472784f7073123f0a0b666561747572655f6f707318132003280b321e2e73662e616e74656c6f70652e747970652e76312e466561747572654f70520a666561747572654f707312360a087065726d5f6f707318142003280b321b2e73662e616e74656c6f70652e747970652e76312e5065726d4f7052077065726d4f707312330a0772616d5f6f707318152003280b321a2e73662e616e74656c6f70652e747970652e76312e52414d4f70520672616d4f707312520a1272616d5f636f7272656374696f6e5f6f707318162003280b32242e73662e616e74656c6f70652e747970652e76312e52414d436f7272656374696f6e4f70521072616d436f7272656374696f6e4f7073123c0a0a726c696d69745f6f707318172003280b321d2e73662e616e74656c6f70652e747970652e76312e526c696d69744f705209726c696d69744f707312390a097461626c655f6f707318182003280b321c2e73662e616e74656c6f70652e747970652e76312e5461626c654f7052087461626c654f7073124a0a0d6372656174696f6e5f7472656518192003280b32252e73662e616e74656c6f70652e747970652e76312e4372656174696f6e466c61744e6f6465520c6372656174696f6e547265654a04081e101f22b9010a185472616e73616374696f6e52656365697074486561646572123e0a0673746174757318012001280e32262e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e537461747573520673746174757312350a176370755f75736167655f6d6963726f5f7365636f6e647318022001280d521463707555736167654d6963726f5365636f6e647312260a0f6e65745f75736167655f776f72647318032001280d520d6e65745573616765576f72647322ba010a06416374696f6e12180a076163636f756e7418012001280952076163636f756e7412120a046e616d6518022001280952046e616d65124a0a0d617574686f72697a6174696f6e18032003280b32242e73662e616e74656c6f70652e747970652e76312e5065726d697373696f6e4c6576656c520d617574686f72697a6174696f6e121b0a096a736f6e5f6461746118042001280952086a736f6e4461746112190a087261775f6461746118052001280c520772617744617461228e080a0b416374696f6e5472616365121a0a087265636569766572180b2001280952087265636569766572123c0a077265636569707418012001280b32222e73662e616e74656c6f70652e747970652e76312e416374696f6e5265636569707452077265636569707412330a06616374696f6e18022001280b321b2e73662e616e74656c6f70652e747970652e76312e416374696f6e5206616374696f6e12210a0c636f6e746578745f66726565180320012808520b636f6e746578744672656512180a07656c61707365641804200128035207656c617073656412180a07636f6e736f6c651805200128095207636f6e736f6c6512250a0e7472616e73616374696f6e5f6964180620012809520d7472616e73616374696f6e4964121b0a09626c6f636b5f6e756d1807200128045208626c6f636b4e756d122a0a1170726f64756365725f626c6f636b5f6964180820012809520f70726f6475636572426c6f636b496412390a0a626c6f636b5f74696d6518092001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d705209626c6f636b54696d6512520a126163636f756e745f72616d5f64656c746173180a2003280b32242e73662e616e74656c6f70652e747970652e76312e4163636f756e7452414d44656c746152106163636f756e7452616d44656c74617312280a107261775f72657475726e5f76616c756518292001280c520e72617752657475726e56616c7565122a0a116a736f6e5f72657475726e5f76616c7565182a20012809520f6a736f6e52657475726e56616c7565123c0a09657863657074696f6e180f2001280b321e2e73662e616e74656c6f70652e747970652e76312e457863657074696f6e5209657863657074696f6e121d0a0a6572726f725f636f646518142001280452096572726f72436f646512250a0e616374696f6e5f6f7264696e616c18102001280d520d616374696f6e4f7264696e616c12340a1663726561746f725f616374696f6e5f6f7264696e616c18112001280d521463726561746f72416374696f6e4f7264696e616c125a0a2a636c6f736573745f756e6e6f7469666965645f616e636573746f725f616374696f6e5f6f7264696e616c18122001280d5226636c6f73657374556e6e6f746966696564416e636573746f72416374696f6e4f7264696e616c12270a0f657865637574696f6e5f696e64657818132001280d520e657865637574696f6e496e646578122b0a1166696c746572696e675f6d617463686564181e20012808521066696c746572696e674d61746368656412520a2666696c746572696e675f6d6174636865645f73797374656d5f616374696f6e5f66696c746572181f20012808522266696c746572696e674d61746368656453797374656d416374696f6e46696c7465724a040828102922a1020a0d416374696f6e52656365697074121a0a0872656365697665721801200128095208726563656976657212160a06646967657374180220012809520664696765737412270a0f676c6f62616c5f73657175656e6365180320012804520e676c6f62616c53657175656e636512460a0d617574685f73657175656e636518042003280b32212e73662e616e74656c6f70652e747970652e76312e4175746853657175656e6365520c6175746853657175656e636512230a0d726563765f73657175656e6365180520012804520c7265637653657175656e636512230a0d636f64655f73657175656e6365180620012804520c636f646553657175656e636512210a0c6162695f73657175656e6365180720012804520b61626953657175656e6365224d0a0c4175746853657175656e636512210a0c6163636f756e745f6e616d65180120012809520b6163636f756e744e616d65121a0a0873657175656e6365180220012804520873657175656e636522410a0f4163636f756e7452414d44656c746112180a076163636f756e7418012001280952076163636f756e7412140a0564656c7461180220012803520564656c7461223e0a0c4163636f756e7444656c746112180a076163636f756e7418012001280952076163636f756e7412140a0564656c7461180220012803520564656c746122330a09457874656e73696f6e12120a047479706518012001280d52047479706512120a046461746118022001280c520464617461228a020a055472784f7012420a096f7065726174696f6e18012001280e32242e73662e616e74656c6f70652e747970652e76312e5472784f702e4f7065726174696f6e52096f7065726174696f6e12120a046e616d6518022001280952046e616d6512250a0e7472616e73616374696f6e5f6964180320012809520d7472616e73616374696f6e496412480a0b7472616e73616374696f6e18042001280b32262e73662e616e74656c6f70652e747970652e76312e5369676e65645472616e73616374696f6e520b7472616e73616374696f6e22380a094f7065726174696f6e12150a114f5045524154494f4e5f554e4b4e4f574e100012140a104f5045524154494f4e5f435245415445100122f4030a0444424f7012410a096f7065726174696f6e18012001280e32232e73662e616e74656c6f70652e747970652e76312e44424f702e4f7065726174696f6e52096f7065726174696f6e12210a0c616374696f6e5f696e64657818022001280d520b616374696f6e496e64657812120a04636f64651803200128095204636f646512140a0573636f7065180420012809520573636f7065121d0a0a7461626c655f6e616d6518052001280952097461626c654e616d65121f0a0b7072696d6172795f6b6579180620012809520a7072696d6172794b6579121b0a096f6c645f706179657218072001280952086f6c645061796572121b0a096e65775f706179657218082001280952086e6577506179657212190a086f6c645f6461746118092001280c52076f6c644461746112190a086e65775f64617461180a2001280c52076e65774461746112220a0d6f6c645f646174615f6a736f6e180b20012809520b6f6c64446174614a736f6e12220a0d6e65775f646174615f6a736f6e180c20012809520b6e6577446174614a736f6e22640a094f7065726174696f6e12150a114f5045524154494f4e5f554e4b4e4f574e100012140a104f5045524154494f4e5f494e53455254100112140a104f5045524154494f4e5f555044415445100212140a104f5045524154494f4e5f52454d4f5645100322e20c0a0552414d4f7012420a096f7065726174696f6e18012001280e32242e73662e616e74656c6f70652e747970652e76312e52414d4f702e4f7065726174696f6e52096f7065726174696f6e12210a0c616374696f6e5f696e64657818022001280d520b616374696f6e496e64657812140a0570617965721803200128095205706179657212140a0564656c7461180420012803520564656c746112140a0575736167651805200128045205757361676512420a096e616d65737061636518062001280e32242e73662e616e74656c6f70652e747970652e76312e52414d4f702e4e616d65737061636552096e616d65737061636512390a06616374696f6e18072001280e32212e73662e616e74656c6f70652e747970652e76312e52414d4f702e416374696f6e5206616374696f6e121d0a0a756e697175655f6b65791808200128095209756e697175654b65792282070a094f7065726174696f6e12150a114f5045524154494f4e5f554e4b4e4f574e1000121a0a164f5045524154494f4e5f4352454154455f5441424c451001121e0a1a4f5045524154494f4e5f44454645525245445f5452585f414444100212210a1d4f5045524154494f4e5f44454645525245445f5452585f43414e43454c100312210a1d4f5045524154494f4e5f44454645525245445f5452585f505553484544100412290a254f5045524154494f4e5f44454645525245445f5452585f52414d5f434f5252454354494f4e100512220a1e4f5045524154494f4e5f44454645525245445f5452585f52454d4f564544100612180a144f5045524154494f4e5f44454c45544541555448100712160a124f5045524154494f4e5f4c494e4b41555448100812180a144f5045524154494f4e5f4e45574143434f554e541009121f0a1b4f5045524154494f4e5f5052494d4152595f494e4445585f414444100a12220a1e4f5045524154494f4e5f5052494d4152595f494e4445585f52454d4f5645100b12220a1e4f5045524154494f4e5f5052494d4152595f494e4445585f555044415445100c12300a2c4f5045524154494f4e5f5052494d4152595f494e4445585f5550444154455f4144445f4e45575f5041594552100d12330a2f4f5045524154494f4e5f5052494d4152595f494e4445585f5550444154455f52454d4f56455f4f4c445f5041594552100e121a0a164f5045524154494f4e5f52454d4f56455f5441424c45100f12210a1d4f5045524154494f4e5f5345434f4e444152595f494e4445585f414444101012240a204f5045524154494f4e5f5345434f4e444152595f494e4445585f52454d4f5645101112320a2e4f5045524154494f4e5f5345434f4e444152595f494e4445585f5550444154455f4144445f4e45575f5041594552101212350a314f5045524154494f4e5f5345434f4e444152595f494e4445585f5550444154455f52454d4f56455f4f4c445f5041594552101312140a104f5045524154494f4e5f534554414249101412150a114f5045524154494f4e5f534554434f4445101512180a144f5045524154494f4e5f554e4c494e4b415554481016121f0a1b4f5045524154494f4e5f555044415445415554485f4352454154451017121f0a1b4f5045524154494f4e5f555044415445415554485f555044415445101812180a144f5045524154494f4e5f44455052454341544544101922fc010a094e616d65737061636512150a114e414d4553504143455f554e4b4e4f574e100012110a0d4e414d4553504143455f414249100112150a114e414d4553504143455f4143434f554e54100212120a0e4e414d4553504143455f41555448100312170a134e414d4553504143455f415554485f4c494e4b100412120a0e4e414d4553504143455f434f44451005121a0a164e414d4553504143455f44454645525245445f5452581006121d0a194e414d4553504143455f5345434f4e444152595f494e444558100712130a0f4e414d4553504143455f5441424c45100812170a134e414d4553504143455f5441424c455f524f5710092204080a100a228d010a06416374696f6e12120a0e414354494f4e5f554e4b4e4f574e1000120e0a0a414354494f4e5f414444100112110a0d414354494f4e5f43414e43454c100212150a11414354494f4e5f434f5252454354494f4e1003120f0a0b414354494f4e5f50555348100412110a0d414354494f4e5f52454d4f5645100512110a0d414354494f4e5f55504441544510062281010a0f52414d436f7272656374696f6e4f7012230a0d636f7272656374696f6e5f6964180120012809520c636f7272656374696f6e4964121d0a0a756e697175655f6b65791802200128095209756e697175654b657912140a0570617965721803200128095205706179657212140a0564656c7461180420012803520564656c746122a1020a075461626c654f7012440a096f7065726174696f6e18012001280e32262e73662e616e74656c6f70652e747970652e76312e5461626c654f702e4f7065726174696f6e52096f7065726174696f6e12210a0c616374696f6e5f696e64657818022001280d520b616374696f6e496e64657812140a0570617965721803200128095205706179657212120a04636f64651804200128095204636f646512140a0573636f7065180520012809520573636f7065121d0a0a7461626c655f6e616d6518062001280952097461626c654e616d65224e0a094f7065726174696f6e12150a114f5045524154494f4e5f554e4b4e4f574e100012140a104f5045524154494f4e5f494e53455254100112140a104f5045524154494f4e5f52454d4f5645100222d1040a06445472784f7012430a096f7065726174696f6e18012001280e32252e73662e616e74656c6f70652e747970652e76312e445472784f702e4f7065726174696f6e52096f7065726174696f6e12210a0c616374696f6e5f696e64657818022001280d520b616374696f6e496e64657812160a0673656e646572180320012809520673656e646572121b0a0973656e6465725f6964180420012809520873656e646572496412140a0570617965721805200128095205706179657212210a0c7075626c69736865645f6174180620012809520b7075626c69736865644174121f0a0b64656c61795f756e74696c180720012809520a64656c6179556e74696c12230a0d65787069726174696f6e5f6174180820012809520c65787069726174696f6e417412250a0e7472616e73616374696f6e5f6964180920012809520d7472616e73616374696f6e496412480a0b7472616e73616374696f6e180a2001280b32262e73662e616e74656c6f70652e747970652e76312e5369676e65645472616e73616374696f6e520b7472616e73616374696f6e22b9010a094f7065726174696f6e12150a114f5045524154494f4e5f554e4b4e4f574e100012140a104f5045524154494f4e5f435245415445100112190a154f5045524154494f4e5f505553485f435245415445100212140a104f5045524154494f4e5f4641494c4544100312140a104f5045524154494f4e5f43414e43454c1004121b0a174f5045524154494f4e5f4d4f444946595f43414e43454c1005121b0a174f5045524154494f4e5f4d4f444946595f435245415445100622e8010a09457874445472784f7012320a15736f757263655f7472616e73616374696f6e5f69641801200128095213736f757263655472616e73616374696f6e4964121b0a09626c6f636b5f6e756d1802200128045208626c6f636b4e756d12190a08626c6f636b5f69641803200128095207626c6f636b496412390a0a626c6f636b5f74696d6518042001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d705209626c6f636b54696d6512340a07647472785f6f7018052001280b321b2e73662e616e74656c6f70652e747970652e76312e445472784f705206647472784f7022e5010a09466561747572654f7012120a046b696e6418012001280952046b696e6412210a0c616374696f6e5f696e64657818022001280d520b616374696f6e496e64657812250a0e666561747572655f646967657374180320012809520d6665617475726544696765737412360a076665617475726518042001280b321c2e73662e616e74656c6f70652e747970652e76312e4665617475726552076665617475726522420a044b696e6412100a0c4b494e445f554e4b4e4f574e100012150a114b494e445f5052455f4143544956415445100112110a0d4b494e445f41435449564154451002227a0a104372656174696f6e466c61744e6f646512300a1463726561746f725f616374696f6e5f696e646578180120012805521263726561746f72416374696f6e496e64657812340a16657865637574696f6e5f616374696f6e5f696e64657818022001280d5214657865637574696f6e416374696f6e496e64657822da020a065065726d4f7012430a096f7065726174696f6e18012001280e32252e73662e616e74656c6f70652e747970652e76312e5065726d4f702e4f7065726174696f6e52096f7065726174696f6e12210a0c616374696f6e5f696e64657818022001280d520b616374696f6e496e64657812400a086f6c645f7065726d18082001280b32252e73662e616e74656c6f70652e747970652e76312e5065726d697373696f6e4f626a65637452076f6c645065726d12400a086e65775f7065726d18092001280b32252e73662e616e74656c6f70652e747970652e76312e5065726d697373696f6e4f626a65637452076e65775065726d22640a094f7065726174696f6e12150a114f5045524154494f4e5f554e4b4e4f574e100012140a104f5045524154494f4e5f494e53455254100112140a104f5045524154494f4e5f555044415445100212140a104f5045524154494f4e5f52454d4f5645100322e6010a105065726d697373696f6e4f626a656374120e0a026964180a2001280452026964121b0a09706172656e745f6964180b200128045208706172656e74496412140a056f776e657218012001280952056f776e657212120a046e616d6518022001280952046e616d65123d0a0c6c6173745f7570646174656418032001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d70520b6c61737455706461746564123c0a09617574686f7269747918042001280b321e2e73662e616e74656c6f70652e747970652e76312e417574686f726974795209617574686f72697479227d0a0a5065726d697373696f6e12120a046e616d6518012001280952046e616d6512160a06706172656e741802200128095206706172656e7412430a0d72657175697265645f6175746818032001280b321e2e73662e616e74656c6f70652e747970652e76312e417574686f72697479520c72657175697265644175746822dc010a09417574686f72697479121c0a097468726573686f6c6418012001280d52097468726573686f6c6412320a046b65797318022003280b321e2e73662e616e74656c6f70652e747970652e76312e4b657957656967687452046b65797312460a086163636f756e747318032003280b322a2e73662e616e74656c6f70652e747970652e76312e5065726d697373696f6e4c6576656c57656967687452086163636f756e747312350a05776169747318042003280b321f2e73662e616e74656c6f70652e747970652e76312e576169745765696768745205776169747322420a094b6579576569676874121d0a0a7075626c69635f6b657918012001280952097075626c69634b657912160a0677656967687418022001280d520677656967687422470a0f5065726d697373696f6e4c6576656c12140a056163746f7218012001280952056163746f72121e0a0a7065726d697373696f6e180220012809520a7065726d697373696f6e22750a155065726d697373696f6e4c6576656c57656967687412440a0a7065726d697373696f6e18012001280b32242e73662e616e74656c6f70652e747970652e76312e5065726d697373696f6e4c6576656c520a7065726d697373696f6e12160a0677656967687418022001280d5206776569676874223f0a0a5761697457656967687412190a08776169745f73656318012001280d52077761697453656312160a0677656967687418022001280d520677656967687422c3030a08526c696d69744f7012450a096f7065726174696f6e18012001280e32272e73662e616e74656c6f70652e747970652e76312e526c696d69744f702e4f7065726174696f6e52096f7065726174696f6e12380a05737461746518022001280b32202e73662e616e74656c6f70652e747970652e76312e526c696d69745374617465480052057374617465123b0a06636f6e66696718032001280b32212e73662e616e74656c6f70652e747970652e76312e526c696d6974436f6e66696748005206636f6e66696712510a0e6163636f756e745f6c696d69747318042001280b32282e73662e616e74656c6f70652e747970652e76312e526c696d69744163636f756e744c696d6974734800520d6163636f756e744c696d697473124e0a0d6163636f756e745f757361676518052001280b32272e73662e616e74656c6f70652e747970652e76312e526c696d69744163636f756e7455736167654800520c6163636f756e745573616765224e0a094f7065726174696f6e12150a114f5045524154494f4e5f554e4b4e4f574e100012140a104f5045524154494f4e5f494e53455254100112140a104f5045524154494f4e5f555044415445100242060a046b696e6422f5030a0b526c696d69745374617465125c0a17617665726167655f626c6f636b5f6e65745f757361676518012001280b32252e73662e616e74656c6f70652e747970652e76312e5573616765416363756d756c61746f72521461766572616765426c6f636b4e65745573616765125c0a17617665726167655f626c6f636b5f6370755f757361676518022001280b32252e73662e616e74656c6f70652e747970652e76312e5573616765416363756d756c61746f72521461766572616765426c6f636b4370755573616765122a0a1170656e64696e675f6e65745f7573616765180320012804520f70656e64696e674e65745573616765122a0a1170656e64696e675f6370755f7573616765180420012804520f70656e64696e67437075557361676512280a10746f74616c5f6e65745f776569676874180520012804520e746f74616c4e657457656967687412280a10746f74616c5f6370755f776569676874180620012804520e746f74616c43707557656967687412260a0f746f74616c5f72616d5f6279746573180720012804520d746f74616c52616d4279746573122a0a117669727475616c5f6e65745f6c696d6974180820012804520f7669727475616c4e65744c696d6974122a0a117669727475616c5f6370755f6c696d6974180920012804520f7669727475616c4370754c696d697422dc020a0c526c696d6974436f6e666967125d0a146370755f6c696d69745f706172616d657465727318012001280b322b2e73662e616e74656c6f70652e747970652e76312e456c61737469634c696d6974506172616d657465727352126370754c696d6974506172616d6574657273125d0a146e65745f6c696d69745f706172616d657465727318022001280b322b2e73662e616e74656c6f70652e747970652e76312e456c61737469634c696d6974506172616d657465727352126e65744c696d6974506172616d657465727312460a206163636f756e745f6370755f75736167655f617665726167655f77696e646f7718032001280d521c6163636f756e7443707555736167654176657261676557696e646f7712460a206163636f756e745f6e65745f75736167655f617665726167655f77696e646f7718042001280d521c6163636f756e744e657455736167654176657261676557696e646f7722a0010a13526c696d69744163636f756e744c696d69747312140a056f776e657218012001280952056f776e657212180a0770656e64696e67180220012808520770656e64696e67121d0a0a6e65745f77656967687418032001280352096e6574576569676874121d0a0a6370755f7765696768741804200128035209637075576569676874121b0a0972616d5f6279746573180520012803520872616d427974657322cf010a12526c696d69744163636f756e74557361676512140a056f776e657218012001280952056f776e657212420a096e65745f757361676518022001280b32252e73662e616e74656c6f70652e747970652e76312e5573616765416363756d756c61746f7252086e6574557361676512420a096370755f757361676518032001280b32252e73662e616e74656c6f70652e747970652e76312e5573616765416363756d756c61746f7252086370755573616765121b0a0972616d5f7573616765180420012804520872616d5573616765226c0a105573616765416363756d756c61746f7212210a0c6c6173745f6f7264696e616c18012001280d520b6c6173744f7264696e616c12190a0876616c75655f6578180220012804520776616c75654578121a0a08636f6e73756d65641803200128045208636f6e73756d65642281020a16456c61737469634c696d6974506172616d657465727312160a06746172676574180120012804520674617267657412100a036d617818022001280452036d617812180a07706572696f647318032001280d5207706572696f647312250a0e6d61785f6d756c7469706c69657218042001280d520d6d61784d756c7469706c696572123f0a0d636f6e74726163745f7261746518052001280b321a2e73662e616e74656c6f70652e747970652e76312e526174696f520c636f6e747261637452617465123b0a0b657870616e645f7261746518062001280b321a2e73662e616e74656c6f70652e747970652e76312e526174696f520a657870616e645261746522470a05526174696f121c0a096e756d657261746f7218012001280452096e756d657261746f7212200a0b64656e6f6d696e61746f72180220012804520b64656e6f6d696e61746f7222ae040a09457863657074696f6e12120a04636f64651801200128055204636f646512120a046e616d6518022001280952046e616d6512180a076d65737361676518032001280952076d657373616765123f0a05737461636b18042003280b32292e73662e616e74656c6f70652e747970652e76312e457863657074696f6e2e4c6f674d6573736167655205737461636b1a7d0a0a4c6f674d65737361676512430a07636f6e7465787418012001280b32292e73662e616e74656c6f70652e747970652e76312e457863657074696f6e2e4c6f67436f6e746578745207636f6e7465787412160a06666f726d61741802200128095206666f726d617412120a046461746118042001280c5204646174611a9e020a0a4c6f67436f6e7465787412140a056c6576656c18012001280952056c6576656c12120a0466696c65180220012809520466696c6512120a046c696e6518032001280552046c696e6512160a066d6574686f6418042001280952066d6574686f64121a0a08686f73746e616d651805200128095208686f73746e616d65121f0a0b7468726561645f6e616d65180620012809520a7468726561644e616d6512380a0974696d657374616d7018072001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d70520974696d657374616d7012430a07636f6e7465787418082001280b32292e73662e616e74656c6f70652e747970652e76312e457863657074696f6e2e4c6f67436f6e746578745207636f6e7465787422e7020a074665617475726512250a0e666561747572655f646967657374180120012809520d6665617475726544696765737412640a177375626a6563746976655f7265737472696374696f6e7318022001280b322b2e73662e616e74656c6f70652e747970652e76312e5375626a6563746976655265737472696374696f6e7352167375626a6563746976655265737472696374696f6e73122d0a126465736372697074696f6e5f64696765737418032001280952116465736372697074696f6e44696765737412220a0c646570656e64656e63696573180420032809520c646570656e64656e6369657312320a1570726f746f636f6c5f666561747572655f74797065180520012809521370726f746f636f6c466561747572655479706512480a0d73706563696669636174696f6e18062003280b32222e73662e616e74656c6f70652e747970652e76312e53706563696669636174696f6e520d73706563696669636174696f6e22b2010a165375626a6563746976655265737472696374696f6e7312180a07656e61626c65641801200128085207656e61626c656412350a1670726561637469766174696f6e5f7265717569726564180220012808521570726561637469766174696f6e526571756972656412470a206561726c696573745f616c6c6f7765645f61637469766174696f6e5f74696d65180320012809521d6561726c69657374416c6c6f77656441637469766174696f6e54696d6522390a0d53706563696669636174696f6e12120a046e616d6518012001280952046e616d6512140a0576616c7565180220012809520576616c756522e2010a124163636f756e744372656174696f6e52656612180a076163636f756e7418012001280952076163636f756e7412180a0763726561746f72180220012809520763726561746f72121b0a09626c6f636b5f6e756d1803200128045208626c6f636b4e756d12190a08626c6f636b5f69641804200128095207626c6f636b496412390a0a626c6f636b5f74696d6518052001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d705209626c6f636b54696d6512250a0e7472616e73616374696f6e5f6964180620012809520d7472616e73616374696f6e496422c4010a0f4865616465724f6e6c79426c6f636b120e0a0269641801200128095202696412160a066e756d62657218022001280d52066e756d62657212380a0668656164657218042001280b32202e73662e616e74656c6f70652e747970652e76312e426c6f636b4865616465725206686561646572124f0a10626c6f636b726f6f745f6d65726b6c65180b2001280b32242e73662e616e74656c6f70652e747970652e76312e426c6f636b526f6f744d65726b6c65520f626c6f636b726f6f744d65726b6c652297010a1c5472616e73616374696f6e547261636557697468426c6f636b526566123b0a05747261636518012001280b32252e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e547261636552057472616365123a0a09626c6f636b5f72656618022001280b321d2e73662e616e74656c6f70652e747970652e76312e426c6f636b5265665208626c6f636b52656622360a08426c6f636b52656612120a046861736818012001280c52046861736812160a066e756d62657218022001280452066e756d6265722aba010a12426c6f636b5265766572736962696c697479121b0a17424c4f434b5245564552534942494c4954595f4e4f4e45100012210a1d424c4f434b5245564552534942494c4954595f52455645525349424c45100112230a1f424c4f434b5245564552534942494c4954595f495252455645525349424c451002121c0a18424c4f434b5245564552534942494c4954595f5354414c45100312210a1d424c4f434b5245564552534942494c4954595f4d415942455354414c4510042a8c020a115472616e73616374696f6e537461747573121a0a165452414e53414354494f4e5354415455535f4e4f4e451000121e0a1a5452414e53414354494f4e5354415455535f45584543555445441001121e0a1a5452414e53414354494f4e5354415455535f534f46544641494c1002121e0a1a5452414e53414354494f4e5354415455535f484152444641494c1003121d0a195452414e53414354494f4e5354415455535f44454c415945441004121d0a195452414e53414354494f4e5354415455535f455850495245441005121d0a195452414e53414354494f4e5354415455535f554e4b4e4f574e1006121e0a1a5452414e53414354494f4e5354415455535f43414e43454c4544100742545a526769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d616e74656c6f70652f74797065732f70622f73662f616e74656c6f70652f747970652f76313b7062616e74656c6f7065620670726f746f33", +type WellKnownType struct { + proto string + BytesEncoding string +} - // sf/arweave/type/v1/type.proto (https://buf.build/pinax/firehose-arweave/docs/eeea46c6211b43189e1af8bb682b3bc6:sf.arweave.type.v1) - "0a1d73662f617277656176652f747970652f76312f747970652e70726f746f121273662e617277656176652e747970652e7631221e0a06426967496e7412140a05627974657318012001280c5205627974657322a6060a05426c6f636b12100a0376657218012001280d5203766572121d0a0a696e6465705f6861736818022001280c5209696e6465704861736812140a056e6f6e636518032001280c52056e6f6e636512250a0e70726576696f75735f626c6f636b18042001280c520d70726576696f7573426c6f636b121c0a0974696d657374616d70180520012804520974696d657374616d7012230a0d6c6173745f7265746172676574180620012804520c6c6173745265746172676574122e0a046469666618072001280b321a2e73662e617277656176652e747970652e76312e426967496e7452046469666612160a06686569676874180820012804520668656967687412120a046861736818092001280c52046861736812170a0774785f726f6f74180a2001280c52067478526f6f7412310a03747873180b2003280b321f2e73662e617277656176652e747970652e76312e5472616e73616374696f6e5203747873121f0a0b77616c6c65745f6c697374180c2001280c520a77616c6c65744c697374121f0a0b7265776172645f61646472180d2001280c520a72657761726441646472122b0a0474616773180e2003280b32172e73662e617277656176652e747970652e76312e546167520474616773123b0a0b7265776172645f706f6f6c180f2001280b321a2e73662e617277656176652e747970652e76312e426967496e74520a726577617264506f6f6c12390a0a77656176655f73697a6518102001280b321a2e73662e617277656176652e747970652e76312e426967496e745209776561766553697a6512390a0a626c6f636b5f73697a6518112001280b321a2e73662e617277656176652e747970652e76312e426967496e745209626c6f636b53697a6512430a0f63756d756c61746976655f6469666618122001280b321a2e73662e617277656176652e747970652e76312e426967496e74520e63756d756c61746976654469666612280a10686173685f6c6973745f6d65726b6c6518142001280c520e686173684c6973744d65726b6c6512330a03706f6118152001280b32212e73662e617277656176652e747970652e76312e50726f6f664f664163636573735203706f6122730a0d50726f6f664f6641636365737312160a066f7074696f6e18012001280952066f7074696f6e12170a0774785f7061746818022001280c5206747850617468121b0a09646174615f7061746818032001280c5208646174615061746812140a056368756e6b18042001280c52056368756e6b229d030a0b5472616e73616374696f6e12160a06666f726d617418012001280d5206666f726d6174120e0a02696418022001280c5202696412170a076c6173745f747818032001280c52066c617374547812140a056f776e657218042001280c52056f776e6572122b0a047461677318052003280b32172e73662e617277656176652e747970652e76312e54616752047461677312160a0674617267657418062001280c520674617267657412360a087175616e7469747918072001280b321a2e73662e617277656176652e747970652e76312e426967496e7452087175616e7469747912120a046461746118082001280c52046461746112370a09646174615f73697a6518092001280b321a2e73662e617277656176652e747970652e76312e426967496e7452086461746153697a65121b0a09646174615f726f6f74180a2001280c520864617461526f6f74121c0a097369676e6174757265180b2001280c52097369676e617475726512320a06726577617264180c2001280b321a2e73662e617277656176652e747970652e76312e426967496e745206726577617264222f0a0354616712120a046e616d6518012001280c52046e616d6512140a0576616c756518022001280c520576616c756542515a4f6769746875622e636f6d2f70696e61782d6e6574776f726b2f66697265686f73652d617277656176652f74797065732f70622f73662f617277656176652f747970652f76313b706261727765617665620670726f746f33", - } +func RegisterWellKnownFileDescriptors(registry *Registry) error { - for _, protoFile := range protoFiles { - fd, err := protoToFileDescriptor(registry, protoFile) + for _, wt := range wellKnownTypes { + fd, err := protoToFileDescriptor(registry, wt.proto) if err != nil { return fmt.Errorf("generating proto file: %w", err) } diff --git a/proto/well_known_types.go b/proto/well_known_types.go new file mode 100644 index 0000000..e6fba82 --- /dev/null +++ b/proto/well_known_types.go @@ -0,0 +1,61 @@ +// Code generated by 'go run github.com/streamingfast/firehose-core/protoregistry/generator well_known.go protoregistry', DO NOT EDIT! +package proto + +var wellKnownTypes []*WellKnownType + +func init() { + wellKnownTypes = []*WellKnownType{ + { + // sf/ethereum/substreams/v1/rpc.proto (https://buf.build/streamingfast/firehose-ethereum/docs/d869cb39aae947ecb0c7df6a1db2b61f:sf.ethereum.substreams.v1) + proto: "0a2373662f657468657265756d2f73756273747265616d732f76312f7270632e70726f746f121973662e657468657265756d2e73756273747265616d732e763122440a0852706343616c6c7312380a0563616c6c7318012003280b32222e73662e657468657265756d2e73756273747265616d732e76312e52706343616c6c520563616c6c7322360a0752706343616c6c12170a07746f5f6164647218012001280c5206746f4164647212120a046461746118022001280c52046461746122540a0c527063526573706f6e73657312440a09726573706f6e73657318012003280b32262e73662e657468657265756d2e73756273747265616d732e76312e527063526573706f6e73655209726573706f6e73657322370a0b527063526573706f6e736512100a0372617718012001280c520372617712160a066661696c656418022001280852066661696c656442575a556769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d657468657265756d2f74797065732f70622f73662f657468657265756d2f73756273747265616d732f76313b70626574687373620670726f746f33", + }, + { + // sf/ethereum/transform/v1/transforms.proto (https://buf.build/streamingfast/firehose-ethereum/docs/d869cb39aae947ecb0c7df6a1db2b61f:sf.ethereum.transform.v1) + proto: "0a2973662f657468657265756d2f7472616e73666f726d2f76312f7472616e73666f726d732e70726f746f121873662e657468657265756d2e7472616e73666f726d2e763122d6010a0e436f6d62696e656446696c74657212440a0b6c6f675f66696c7465727318012003280b32232e73662e657468657265756d2e7472616e73666f726d2e76312e4c6f6746696c746572520a6c6f6746696c7465727312490a0c63616c6c5f66696c7465727318022003280b32262e73662e657468657265756d2e7472616e73666f726d2e76312e43616c6c546f46696c746572520b63616c6c46696c7465727312330a1673656e645f616c6c5f626c6f636b5f68656164657273180320012808521373656e64416c6c426c6f636b4865616465727322560a0e4d756c74694c6f6746696c74657212440a0b6c6f675f66696c7465727318012003280b32232e73662e657468657265756d2e7472616e73666f726d2e76312e4c6f6746696c746572520a6c6f6746696c7465727322540a094c6f6746696c746572121c0a0961646472657373657318012003280c520961646472657373657312290a106576656e745f7369676e61747572657318022003280c520f6576656e745369676e617475726573225e0a114d756c746943616c6c546f46696c74657212490a0c63616c6c5f66696c7465727318012003280b32262e73662e657468657265756d2e7472616e73666f726d2e76312e43616c6c546f46696c746572520b63616c6c46696c74657273224c0a0c43616c6c546f46696c746572121c0a0961646472657373657318012003280c5209616464726573736573121e0a0a7369676e61747572657318022003280c520a7369676e617475726573220c0a0a4865616465724f6e6c79425a5a586769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d657468657265756d2f74797065732f70622f73662f657468657265756d2f7472616e73666f726d2f76313b70627472616e73666f726d620670726f746f33", + }, + { + // google/protobuf/timestamp.proto (https://buf.build/streamingfast/firehose-ethereum/docs/d869cb39aae947ecb0c7df6a1db2b61f:google.protobuf) + proto: "0a1f676f6f676c652f70726f746f6275662f74696d657374616d702e70726f746f120f676f6f676c652e70726f746f627566223b0a0954696d657374616d7012180a077365636f6e647318012001280352077365636f6e647312140a056e616e6f7318022001280552056e616e6f734285010a13636f6d2e676f6f676c652e70726f746f627566420e54696d657374616d7050726f746f50015a32676f6f676c652e676f6c616e672e6f72672f70726f746f6275662f74797065732f6b6e6f776e2f74696d657374616d707062f80101a20203475042aa021e476f6f676c652e50726f746f6275662e57656c6c4b6e6f776e5479706573620670726f746f33", + }, + { + // sf/ethereum/type/v2/type.proto (https://buf.build/streamingfast/firehose-ethereum/docs/d869cb39aae947ecb0c7df6a1db2b61f:sf.ethereum.type.v2) + proto: "0a1e73662f657468657265756d2f747970652f76322f747970652e70726f746f121373662e657468657265756d2e747970652e76321a1f676f6f676c652f70726f746f6275662f74696d657374616d702e70726f746f228e050a05426c6f636b12120a046861736818022001280c52046861736812160a066e756d62657218032001280452066e756d62657212120a0473697a65180420012804520473697a6512380a0668656164657218052001280b32202e73662e657468657265756d2e747970652e76322e426c6f636b486561646572520668656164657212380a06756e636c657318062003280b32202e73662e657468657265756d2e747970652e76322e426c6f636b4865616465725206756e636c657312540a127472616e73616374696f6e5f747261636573180a2003280b32252e73662e657468657265756d2e747970652e76322e5472616e73616374696f6e547261636552117472616e73616374696f6e547261636573124b0a0f62616c616e63655f6368616e676573180b2003280b32222e73662e657468657265756d2e747970652e76322e42616c616e63654368616e6765520e62616c616e63654368616e67657312490a0c64657461696c5f6c6576656c180c2001280e32262e73662e657468657265756d2e747970652e76322e426c6f636b2e44657461696c4c6576656c520b64657461696c4c6576656c12420a0c636f64655f6368616e67657318142003280b321f2e73662e657468657265756d2e747970652e76322e436f64654368616e6765520b636f64654368616e676573123c0a0c73797374656d5f63616c6c7318152003280b32192e73662e657468657265756d2e747970652e76322e43616c6c520b73797374656d43616c6c7312100a037665721801200128055203766572223d0a0b44657461696c4c6576656c12180a1444455441494c4c4556454c5f455854454e444544100012140a1044455441494c4c4556454c5f4241534510024a04082810294a040829102a4a04082a102b22d2070a0b426c6f636b486561646572121f0a0b706172656e745f6861736818012001280c520a706172656e7448617368121d0a0a756e636c655f6861736818022001280c5209756e636c6548617368121a0a08636f696e6261736518032001280c5208636f696e62617365121d0a0a73746174655f726f6f7418042001280c52097374617465526f6f74122b0a117472616e73616374696f6e735f726f6f7418052001280c52107472616e73616374696f6e73526f6f7412210a0c726563656970745f726f6f7418062001280c520b72656365697074526f6f74121d0a0a6c6f67735f626c6f6f6d18072001280c52096c6f6773426c6f6f6d123b0a0a646966666963756c747918082001280b321b2e73662e657468657265756d2e747970652e76322e426967496e74520a646966666963756c747912460a10746f74616c5f646966666963756c747918112001280b321b2e73662e657468657265756d2e747970652e76322e426967496e74520f746f74616c446966666963756c747912160a066e756d62657218092001280452066e756d626572121b0a096761735f6c696d6974180a2001280452086761734c696d697412190a086761735f75736564180b2001280452076761735573656412380a0974696d657374616d70180c2001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d70520974696d657374616d70121d0a0a65787472615f64617461180d2001280c520965787472614461746112190a086d69785f68617368180e2001280c52076d69784861736812140a056e6f6e6365180f2001280452056e6f6e636512120a046861736818102001280c52046861736812440a10626173655f6665655f7065725f67617318122001280b321b2e73662e657468657265756d2e747970652e76322e426967496e74520d6261736546656550657247617312290a107769746864726177616c735f726f6f7418132001280c520f7769746864726177616c73526f6f74124b0a0d74785f646570656e64656e637918142001280b32262e73662e657468657265756d2e747970652e76322e55696e7436344e65737465644172726179520c7478446570656e64656e637912270a0d626c6f625f6761735f757365641816200128044800520b626c6f6247617355736564880101122b0a0f6578636573735f626c6f625f6761731817200128044801520d657863657373426c6f62476173880101122c0a12706172656e745f626561636f6e5f726f6f7418182001280c5210706172656e74426561636f6e526f6f7442100a0e5f626c6f625f6761735f7573656442120a105f6578636573735f626c6f625f67617322470a1155696e7436344e6573746564417272617912320a0376616c18012003280b32202e73662e657468657265756d2e747970652e76322e55696e7436344172726179520376616c221f0a0b55696e743634417272617912100a0376616c180120032804520376616c221e0a06426967496e7412140a05627974657318012001280c5205627974657322ab0b0a105472616e73616374696f6e5472616365120e0a02746f18012001280c5202746f12140a056e6f6e636518022001280452056e6f6e636512380a096761735f707269636518032001280b321b2e73662e657468657265756d2e747970652e76322e426967496e7452086761735072696365121b0a096761735f6c696d697418042001280452086761734c696d697412310a0576616c756518052001280b321b2e73662e657468657265756d2e747970652e76322e426967496e74520576616c756512140a05696e70757418062001280c5205696e707574120c0a017618072001280c520176120c0a017218082001280c520172120c0a017318092001280c52017312190a086761735f75736564180a20012804520767617355736564123e0a0474797065180c2001280e322a2e73662e657468657265756d2e747970652e76322e5472616e73616374696f6e54726163652e5479706552047479706512410a0b6163636573735f6c697374180e2003280b32202e73662e657468657265756d2e747970652e76322e4163636573735475706c65520a6163636573734c69737412420a0f6d61785f6665655f7065725f676173180b2001280b321b2e73662e657468657265756d2e747970652e76322e426967496e74520c6d617846656550657247617312530a186d61785f7072696f726974795f6665655f7065725f676173180d2001280b321b2e73662e657468657265756d2e747970652e76322e426967496e7452146d61785072696f7269747946656550657247617312140a05696e64657818142001280d5205696e64657812120a046861736818152001280c52046861736812120a0466726f6d18162001280c520466726f6d121f0a0b72657475726e5f6461746118172001280c520a72657475726e44617461121d0a0a7075626c69635f6b657918182001280c52097075626c69634b657912230a0d626567696e5f6f7264696e616c181920012804520c626567696e4f7264696e616c121f0a0b656e645f6f7264696e616c181a20012804520a656e644f7264696e616c12430a06737461747573181e2001280e322b2e73662e657468657265756d2e747970652e76322e5472616e73616374696f6e5472616365537461747573520673746174757312410a0772656365697074181f2001280b32272e73662e657468657265756d2e747970652e76322e5472616e73616374696f6e52656365697074520772656365697074122f0a0563616c6c7318202003280b32192e73662e657468657265756d2e747970652e76322e43616c6c520563616c6c73121e0a08626c6f625f67617318212001280448005207626c6f6247617388010112490a10626c6f625f6761735f6665655f63617018222001280b321b2e73662e657468657265756d2e747970652e76322e426967496e744801520d626c6f62476173466565436170880101121f0a0b626c6f625f68617368657318232003280c520a626c6f6248617368657322c4020a045479706512130a0f5452585f545950455f4c4547414359100012180a145452585f545950455f4143434553535f4c495354100112180a145452585f545950455f44594e414d49435f464545100212110a0d5452585f545950455f424c4f421003121d0a195452585f545950455f415242495452554d5f4445504f5349541064121e0a1a5452585f545950455f415242495452554d5f554e5349474e45441065121e0a1a5452585f545950455f415242495452554d5f434f4e54524143541066121b0a175452585f545950455f415242495452554d5f5245545259106812260a225452585f545950455f415242495452554d5f5355424d49545f524554525941424c451069121e0a1a5452585f545950455f415242495452554d5f494e5445524e414c106a121c0a185452585f545950455f415242495452554d5f4c45474143591078420b0a095f626c6f625f67617342130a115f626c6f625f6761735f6665655f636170224a0a0b4163636573735475706c6512180a076164647265737318012001280c52076164647265737312210a0c73746f726167655f6b65797318022003280c520b73746f726167654b65797322c6020a125472616e73616374696f6e52656365697074121d0a0a73746174655f726f6f7418012001280c52097374617465526f6f74122e0a1363756d756c61746976655f6761735f75736564180220012804521163756d756c617469766547617355736564121d0a0a6c6f67735f626c6f6f6d18032001280c52096c6f6773426c6f6f6d122c0a046c6f677318042003280b32182e73662e657468657265756d2e747970652e76322e4c6f6752046c6f677312270a0d626c6f625f6761735f757365641805200128044800520b626c6f624761735573656488010112460a0e626c6f625f6761735f707269636518062001280b321b2e73662e657468657265756d2e747970652e76322e426967496e744801520c626c6f62476173507269636588010142100a0e5f626c6f625f6761735f7573656442110a0f5f626c6f625f6761735f7072696365229b010a034c6f6712180a076164647265737318012001280c52076164647265737312160a06746f7069637318022003280c5206746f7069637312120a046461746118032001280c52046461746112140a05696e64657818042001280d5205696e646578121e0a0a626c6f636b496e64657818062001280d520a626c6f636b496e64657812180a076f7264696e616c18072001280452076f7264696e616c22b20a0a0443616c6c12140a05696e64657818012001280d5205696e64657812210a0c706172656e745f696e64657818022001280d520b706172656e74496e64657812140a05646570746818032001280d52056465707468123a0a0963616c6c5f7479706518042001280e321d2e73662e657468657265756d2e747970652e76322e43616c6c54797065520863616c6c5479706512160a0663616c6c657218052001280c520663616c6c657212180a076164647265737318062001280c52076164647265737312310a0576616c756518072001280b321b2e73662e657468657265756d2e747970652e76322e426967496e74520576616c7565121b0a096761735f6c696d697418082001280452086761734c696d697412210a0c6761735f636f6e73756d6564180920012804520b676173436f6e73756d6564121f0a0b72657475726e5f64617461180d2001280c520a72657475726e4461746112140a05696e707574180e2001280c5205696e70757412230a0d65786563757465645f636f6465180f20012808520c6578656375746564436f646512180a077375696369646518102001280852077375696369646512590a106b656363616b5f707265696d6167657318142003280b322e2e73662e657468657265756d2e747970652e76322e43616c6c2e4b656363616b507265696d61676573456e747279520f6b656363616b507265696d61676573124b0a0f73746f726167655f6368616e67657318152003280b32222e73662e657468657265756d2e747970652e76322e53746f726167654368616e6765520e73746f726167654368616e676573124b0a0f62616c616e63655f6368616e67657318162003280b32222e73662e657468657265756d2e747970652e76322e42616c616e63654368616e6765520e62616c616e63654368616e67657312450a0d6e6f6e63655f6368616e67657318182003280b32202e73662e657468657265756d2e747970652e76322e4e6f6e63654368616e6765520c6e6f6e63654368616e676573122c0a046c6f677318192003280b32182e73662e657468657265756d2e747970652e76322e4c6f6752046c6f677312420a0c636f64655f6368616e676573181a2003280b321f2e73662e657468657265756d2e747970652e76322e436f64654368616e6765520b636f64654368616e676573123f0a0b6761735f6368616e676573181c2003280b321e2e73662e657468657265756d2e747970652e76322e4761734368616e6765520a6761734368616e67657312230a0d7374617475735f6661696c6564180a20012808520c7374617475734661696c656412270a0f7374617475735f7265766572746564180c20012808520e737461747573526576657274656412250a0e6661696c7572655f726561736f6e180b20012809520d6661696c757265526561736f6e12250a0e73746174655f7265766572746564181e20012808520d7374617465526576657274656412230a0d626567696e5f6f7264696e616c181f20012804520c626567696e4f7264696e616c121f0a0b656e645f6f7264696e616c182020012804520a656e644f7264696e616c12510a116163636f756e745f6372656174696f6e7318212003280b32242e73662e657468657265756d2e747970652e76322e4163636f756e744372656174696f6e52106163636f756e744372656174696f6e731a420a144b656363616b507265696d61676573456e74727912100a036b657918012001280952036b657912140a0576616c7565180220012809520576616c75653a0238014a04081b101c4a04081d101e4a04083210334a04083310344a04083c103d228f010a0d53746f726167654368616e676512180a076164647265737318012001280c52076164647265737312100a036b657918022001280c52036b6579121b0a096f6c645f76616c756518032001280c52086f6c6456616c7565121b0a096e65775f76616c756518042001280c52086e657756616c756512180a076f7264696e616c18052001280452076f7264696e616c22cc050a0d42616c616e63654368616e676512180a076164647265737318012001280c52076164647265737312380a096f6c645f76616c756518022001280b321b2e73662e657468657265756d2e747970652e76322e426967496e7452086f6c6456616c756512380a096e65775f76616c756518032001280b321b2e73662e657468657265756d2e747970652e76322e426967496e7452086e657756616c756512410a06726561736f6e18042001280e32292e73662e657468657265756d2e747970652e76322e42616c616e63654368616e67652e526561736f6e5206726561736f6e12180a076f7264696e616c18052001280452076f7264696e616c22cf030a06526561736f6e12120a0e524541534f4e5f554e4b4e4f574e1000121c0a18524541534f4e5f5245574152445f4d494e455f554e434c451001121c0a18524541534f4e5f5245574152445f4d494e455f424c4f434b1002121e0a1a524541534f4e5f44414f5f524546554e445f434f4e54524143541003121d0a19524541534f4e5f44414f5f41444a5553545f42414c414e4345100412130a0f524541534f4e5f5452414e534645521005121a0a16524541534f4e5f47454e455349535f42414c414e4345100612120a0e524541534f4e5f4741535f425559100712210a1d524541534f4e5f5245574152445f5452414e53414354494f4e5f4645451008121b0a17524541534f4e5f5245574152445f4645455f5245534554100e12150a11524541534f4e5f4741535f524546554e44100912180a14524541534f4e5f544f5543485f4143434f554e54100a12190a15524541534f4e5f535549434944455f524546554e44100b121b0a17524541534f4e5f535549434944455f5749544844524157100d12200a1c524541534f4e5f43414c4c5f42414c414e43455f4f56455252494445100c120f0a0b524541534f4e5f4255524e100f12150a11524541534f4e5f5749544844524157414c1010227b0a0b4e6f6e63654368616e676512180a076164647265737318012001280c520761646472657373121b0a096f6c645f76616c756518022001280452086f6c6456616c7565121b0a096e65775f76616c756518032001280452086e657756616c756512180a076f7264696e616c18042001280452076f7264696e616c22450a0f4163636f756e744372656174696f6e12180a076163636f756e7418012001280c52076163636f756e7412180a076f7264696e616c18022001280452076f7264696e616c22ac010a0a436f64654368616e676512180a076164647265737318012001280c52076164647265737312190a086f6c645f6861736818022001280c52076f6c644861736812190a086f6c645f636f646518032001280c52076f6c64436f646512190a086e65775f6861736818042001280c52076e65774861736812190a086e65775f636f646518052001280c52076e6577436f646512180a076f7264696e616c18062001280452076f7264696e616c22e0060a094761734368616e6765121b0a096f6c645f76616c756518012001280452086f6c6456616c7565121b0a096e65775f76616c756518022001280452086e657756616c7565123d0a06726561736f6e18032001280e32252e73662e657468657265756d2e747970652e76322e4761734368616e67652e526561736f6e5206726561736f6e12180a076f7264696e616c18042001280452076f7264696e616c22bf050a06526561736f6e12120a0e524541534f4e5f554e4b4e4f574e1000120f0a0b524541534f4e5f43414c4c100112140a10524541534f4e5f43414c4c5f434f4445100212190a15524541534f4e5f43414c4c5f444154415f434f5059100312140a10524541534f4e5f434f44455f434f5059100412170a13524541534f4e5f434f44455f53544f524147451005121c0a18524541534f4e5f434f4e54524143545f4352454154494f4e1006121d0a19524541534f4e5f434f4e54524143545f4352454154494f4e32100712180a14524541534f4e5f44454c45474154455f43414c4c100812140a10524541534f4e5f4556454e545f4c4f47100912180a14524541534f4e5f4558545f434f44455f434f5059100a121b0a17524541534f4e5f4641494c45445f455845435554494f4e100b12180a14524541534f4e5f494e5452494e5349435f474153100c121f0a1b524541534f4e5f505245434f4d50494c45445f434f4e5452414354100d12210a1d524541534f4e5f524546554e445f41465445525f455845435554494f4e100e12110a0d524541534f4e5f52455455524e100f121b0a17524541534f4e5f52455455524e5f444154415f434f5059101012110a0d524541534f4e5f524556455254101112180a14524541534f4e5f53454c465f4445535452554354101212160a12524541534f4e5f5354415449435f43414c4c1013121c0a18524541534f4e5f53544154455f434f4c445f4143434553531014121d0a19524541534f4e5f54585f494e495449414c5f42414c414e4345101512150a11524541534f4e5f54585f524546554e4453101612200a1c524541534f4e5f54585f4c4546545f4f5645525f52455455524e45441017121f0a1b524541534f4e5f43414c4c5f494e495449414c5f42414c414e4345101812220a1e524541534f4e5f43414c4c5f4c4546545f4f5645525f52455455524e45441019224b0a0f4865616465724f6e6c79426c6f636b12380a0668656164657218052001280b32202e73662e657468657265756d2e747970652e76322e426c6f636b486561646572520668656164657222d1010a0d426c6f636b5769746852656673120e0a0269641801200128095202696412300a05626c6f636b18022001280b321a2e73662e657468657265756d2e747970652e76322e426c6f636b5205626c6f636b125a0a167472616e73616374696f6e5f74726163655f7265667318032001280b32242e73662e657468657265756d2e747970652e76322e5472616e73616374696f6e5265667352147472616e73616374696f6e54726163655265667312220a0c697272657665727369626c65180420012808520c697272657665727369626c652297010a1c5472616e73616374696f6e547261636557697468426c6f636b526566123b0a05747261636518012001280b32252e73662e657468657265756d2e747970652e76322e5472616e73616374696f6e547261636552057472616365123a0a09626c6f636b5f72656618022001280b321d2e73662e657468657265756d2e747970652e76322e426c6f636b5265665208626c6f636b52656622290a0f5472616e73616374696f6e5265667312160a0668617368657318012003280c520668617368657322360a08426c6f636b52656612120a046861736818012001280c52046861736812160a066e756d62657218022001280452066e756d6265722a4e0a165472616e73616374696f6e5472616365537461747573120b0a07554e4b4e4f574e1000120d0a095355434345454445441001120a0a064641494c45441002120c0a08524556455254454410032a590a0843616c6c54797065120f0a0b554e535045434946494544100012080a0443414c4c1001120c0a0843414c4c434f44451002120c0a0844454c45474154451003120a0a065354415449431004120a0a064352454154451005424f5a4d6769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d657468657265756d2f74797065732f70622f73662f657468657265756d2f747970652f76323b7062657468620670726f746f33", + }, + { + // sf/ethereum/trxstream/v1/trxstream.proto (https://buf.build/streamingfast/firehose-ethereum/docs/d869cb39aae947ecb0c7df6a1db2b61f:sf.ethereum.trxstream.v1) + proto: "0a2873662f657468657265756d2f74727873747265616d2f76312f74727873747265616d2e70726f746f121873662e657468657265756d2e74727873747265616d2e76311a1f676f6f676c652f70726f746f6275662f74696d657374616d702e70726f746f1a1e73662f657468657265756d2f747970652f76322f747970652e70726f746f22140a125472616e73616374696f6e5265717565737422a5080a105472616e73616374696f6e537461746512570a0e70726576696f75735f737461746518012001280e32302e73662e657468657265756d2e74727873747265616d2e76312e5472616e73616374696f6e53746174652e5374617465520d70726576696f7573537461746512550a0d63757272656e745f737461746518022001280e32302e73662e657468657265756d2e74727873747265616d2e76312e5472616e73616374696f6e53746174652e5374617465520c63757272656e74537461746512550a0a7472616e736974696f6e180a2001280e32352e73662e657468657265756d2e74727873747265616d2e76312e5472616e73616374696f6e53746174652e5472616e736974696f6e520a7472616e736974696f6e12120a0468617368180b2001280c52046861736812370a0374727818032001280b32252e73662e657468657265756d2e74727873747265616d2e76312e5472616e73616374696f6e520374727812430a0c626c6f636b5f68656164657218042001280b32202e73662e657468657265756d2e747970652e76322e426c6f636b486561646572520b626c6f636b48656164657212540a127472616e73616374696f6e5f74726163657318052001280b32252e73662e657468657265756d2e747970652e76322e5472616e73616374696f6e547261636552117472616e73616374696f6e54726163657312220a0c636f6e6669726d6174696f6e180620012804520c636f6e6669726d6174696f6e124c0a11686561645f626c6f636b5f68656164657218072001280b32202e73662e657468657265756d2e747970652e76322e426c6f636b486561646572520f68656164426c6f636b48656164657212280a107265706c616365645f62795f6861736818082001280c520e7265706c6163656442794861736812480a1270656e64696e675f66697273745f7365656e180c2001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d70521070656e64696e6746697273745365656e12460a1170656e64696e675f6c6173745f7365656e180d2001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d70520f70656e64696e674c6173745365656e229c010a0a5472616e736974696f6e120e0a0a5452414e535f494e4954100012100a0c5452414e535f504f4f4c45441001120f0a0b5452414e535f4d494e4544100212100a0c5452414e535f464f524b4544100312130a0f5452414e535f434f4e4649524d4544100412120a0e5452414e535f5245504c41434544100512200a1c5452414e535f53504543554c41544956454c595f4558454355544544100622550a05537461746512110a0d53544154455f554e4b4e4f574e100012110a0d53544154455f50454e44494e47100112120a0e53544154455f494e5f424c4f434b100212120a0e53544154455f5245504c41434544100322a5020a0b5472616e73616374696f6e120e0a02746f18012001280c5202746f12140a056e6f6e636518022001280452056e6f6e636512380a096761735f707269636518032001280b321b2e73662e657468657265756d2e747970652e76322e426967496e7452086761735072696365121b0a096761735f6c696d697418042001280452086761734c696d697412310a0576616c756518052001280b321b2e73662e657468657265756d2e747970652e76322e426967496e74520576616c756512140a05696e70757418062001280c5205696e707574120c0a017618072001280c520176120c0a017218082001280c520172120c0a017318092001280c52017312120a046861736818152001280c52046861736812120a0466726f6d18162001280c520466726f6d327a0a115472616e73616374696f6e53747265616d12650a0c5472616e73616374696f6e73122c2e73662e657468657265756d2e74727873747265616d2e76312e5472616e73616374696f6e526571756573741a252e73662e657468657265756d2e74727873747265616d2e76312e5472616e73616374696f6e3001425f5a5d6769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d657468657265756d2d707269762f74797065732f70622f73662f657468657265756d2f74727873747265616d2f76313b706274727873747265616d620670726f746f33", + }, + { + // sf/near/transform/v1/transform.proto (https://buf.build/streamingfast/firehose-near/docs/0b7e4efe1b9f447495fdfb54b7a6880f:sf.near.transform.v1) + proto: "0a2473662f6e6561722f7472616e73666f726d2f76312f7472616e73666f726d2e70726f746f121473662e6e6561722e7472616e73666f726d2e7631228f010a1242617369635265636569707446696c746572121a0a086163636f756e747318012003280952086163636f756e7473125d0a177072656669785f616e645f7375666669785f706169727318022003280b32262e73662e6e6561722e7472616e73666f726d2e76312e507265666978537566666978506169725214707265666978416e64537566666978506169727322420a105072656669785375666669785061697212160a06707265666978180120012809520670726566697812160a067375666669781802200128095206737566666978220c0a0a4865616465724f6e6c79424c5a4a6769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d6e6561722f70622f73662f6e6561722f7472616e73666f726d2f76313b70627472616e73666f726d620670726f746f33", + }, + { + // sf/near/type/v1/type.proto (https://buf.build/streamingfast/firehose-near/docs/0b7e4efe1b9f447495fdfb54b7a6880f:sf.near.type.v1) + proto: "0a1a73662f6e6561722f747970652f76312f747970652e70726f746f120f73662e6e6561722e747970652e7631229b020a05426c6f636b12160a06617574686f721801200128095206617574686f7212340a0668656164657218022001280b321c2e73662e6e6561722e747970652e76312e426c6f636b486561646572520668656164657212410a0d6368756e6b5f6865616465727318032003280b321c2e73662e6e6561722e747970652e76312e4368756e6b486561646572520c6368756e6b4865616465727312350a0673686172647318042003280b321d2e73662e6e6561722e747970652e76312e496e646578657253686172645206736861726473124a0a0d73746174655f6368616e67657318052003280b32252e73662e6e6561722e747970652e76312e53746174654368616e6765576974684361757365520c73746174654368616e67657322470a0f4865616465724f6e6c79426c6f636b12340a0668656164657218022001280b321c2e73662e6e6561722e747970652e76312e426c6f636b48656164657252066865616465722288010a1453746174654368616e676557697468436175736512370a0576616c756518012001280b32212e73662e6e6561722e747970652e76312e53746174654368616e676556616c7565520576616c756512370a05636175736518022001280b32212e73662e6e6561722e747970652e76312e53746174654368616e676543617573655205636175736522d50c0a1053746174654368616e6765436175736512660a146e6f745f7772697461626c655f746f5f6469736b18012001280b32332e73662e6e6561722e747970652e76312e53746174654368616e676543617573652e4e6f745772697461626c65546f4469736b480052116e6f745772697461626c65546f4469736b12550a0d696e697469616c5f737461746518022001280b322e2e73662e6e6561722e747970652e76312e53746174654368616e676543617573652e496e697469616c53746174654800520c696e697469616c537461746512700a167472616e73616374696f6e5f70726f63657373696e6718032001280b32372e73662e6e6561722e747970652e76312e53746174654368616e676543617573652e5472616e73616374696f6e50726f63657373696e67480052157472616e73616374696f6e50726f63657373696e67128d010a21616374696f6e5f726563656970745f70726f63657373696e675f7374617274656418042001280b32402e73662e6e6561722e747970652e76312e53746174654368616e676543617573652e416374696f6e5265636569707450726f63657373696e67537461727465644800521e616374696f6e5265636569707450726f63657373696e675374617274656412750a19616374696f6e5f726563656970745f6761735f72657761726418052001280b32382e73662e6e6561722e747970652e76312e53746174654368616e676543617573652e416374696f6e5265636569707447617352657761726448005216616374696f6e5265636569707447617352657761726412640a12726563656970745f70726f63657373696e6718062001280b32332e73662e6e6561722e747970652e76312e53746174654368616e676543617573652e5265636569707450726f63657373696e67480052117265636569707450726f63657373696e6712610a11706f7374706f6e65645f7265636569707418072001280b32322e73662e6e6561722e747970652e76312e53746174654368616e676543617573652e506f7374706f6e65645265636569707448005210706f7374706f6e65645265636569707412740a18757064617465645f64656c617965645f726563656970747318082001280b32382e73662e6e6561722e747970652e76312e53746174654368616e676543617573652e5570646174656444656c617965645265636569707473480052167570646174656444656c61796564526563656970747312770a1976616c696461746f725f6163636f756e74735f75706461746518092001280b32392e73662e6e6561722e747970652e76312e53746174654368616e676543617573652e56616c696461746f724163636f756e74735570646174654800521776616c696461746f724163636f756e7473557064617465124b0a096d6967726174696f6e180a2001280b322b2e73662e6e6561722e747970652e76312e53746174654368616e676543617573652e4d6967726174696f6e480052096d6967726174696f6e1a130a114e6f745772697461626c65546f4469736b1a0e0a0c496e697469616c53746174651a4d0a155472616e73616374696f6e50726f63657373696e6712340a0774785f6861736818012001280b321b2e73662e6e6561722e747970652e76312e43727970746f4861736852067478486173681a600a1e416374696f6e5265636569707450726f63657373696e6753746172746564123e0a0c726563656970745f6861736818012001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520b72656365697074486173681a4e0a16416374696f6e5265636569707447617352657761726412340a0774785f6861736818012001280b321b2e73662e6e6561722e747970652e76312e43727970746f4861736852067478486173681a490a115265636569707450726f63657373696e6712340a0774785f6861736818012001280b321b2e73662e6e6561722e747970652e76312e43727970746f4861736852067478486173681a480a10506f7374706f6e65645265636569707412340a0774785f6861736818012001280b321b2e73662e6e6561722e747970652e76312e43727970746f4861736852067478486173681a180a165570646174656444656c6179656452656365697074731a190a1756616c696461746f724163636f756e74735570646174651a0b0a094d6967726174696f6e42070a05636175736522da0b0a1053746174654368616e676556616c756512580a0e6163636f756e745f75706461746518012001280b322f2e73662e6e6561722e747970652e76312e53746174654368616e676556616c75652e4163636f756e745570646174654800520d6163636f756e74557064617465125e0a106163636f756e745f64656c6574696f6e18022001280b32312e73662e6e6561722e747970652e76312e53746174654368616e676556616c75652e4163636f756e7444656c6574696f6e4800520f6163636f756e7444656c6574696f6e125f0a116163636573735f6b65795f75706461746518032001280b32312e73662e6e6561722e747970652e76312e53746174654368616e676556616c75652e4163636573734b65795570646174654800520f6163636573734b657955706461746512650a136163636573735f6b65795f64656c6574696f6e18042001280b32332e73662e6e6561722e747970652e76312e53746174654368616e676556616c75652e4163636573734b657944656c6574696f6e480052116163636573734b657944656c6574696f6e124f0a0b646174615f75706461746518052001280b322c2e73662e6e6561722e747970652e76312e53746174654368616e676556616c75652e446174615570646174654800520a6461746155706461746512550a0d646174615f64656c6574696f6e18062001280b322e2e73662e6e6561722e747970652e76312e53746174654368616e676556616c75652e4461746144656c6574696f6e4800520c6461746144656c6574696f6e12680a14636f6e74726163745f636f64655f75706461746518072001280b32342e73662e6e6561722e747970652e76312e53746174654368616e676556616c75652e436f6e7472616374436f646555706461746548005212636f6e7472616374436f646555706461746512650a11636f6e74726163745f64656c6574696f6e18082001280b32362e73662e6e6561722e747970652e76312e53746174654368616e676556616c75652e436f6e7472616374436f646544656c6574696f6e48005210636f6e747261637444656c6574696f6e1a620a0d4163636f756e74557064617465121d0a0a6163636f756e745f696418012001280952096163636f756e74496412320a076163636f756e7418022001280b32182e73662e6e6561722e747970652e76312e4163636f756e7452076163636f756e741a300a0f4163636f756e7444656c6574696f6e121d0a0a6163636f756e745f696418012001280952096163636f756e7449641aa6010a0f4163636573734b6579557064617465121d0a0a6163636f756e745f696418012001280952096163636f756e74496412390a0a7075626c69635f6b657918022001280b321a2e73662e6e6561722e747970652e76312e5075626c69634b657952097075626c69634b657912390a0a6163636573735f6b657918032001280b321a2e73662e6e6561722e747970652e76312e4163636573734b657952096163636573734b65791a6d0a114163636573734b657944656c6574696f6e121d0a0a6163636f756e745f696418012001280952096163636f756e74496412390a0a7075626c69635f6b657918022001280b321a2e73662e6e6561722e747970652e76312e5075626c69634b657952097075626c69634b65791a530a0a44617461557064617465121d0a0a6163636f756e745f696418012001280952096163636f756e74496412100a036b657918022001280c52036b657912140a0576616c756518032001280c520576616c75651a3f0a0c4461746144656c6574696f6e121d0a0a6163636f756e745f696418012001280952096163636f756e74496412100a036b657918022001280c52036b65791a470a12436f6e7472616374436f6465557064617465121d0a0a6163636f756e745f696418012001280952096163636f756e74496412120a04636f646518022001280c5204636f64651a350a14436f6e7472616374436f646544656c6574696f6e121d0a0a6163636f756e745f696418012001280952096163636f756e74496442070a0576616c756522ca010a074163636f756e74122f0a06616d6f756e7418012001280b32172e73662e6e6561722e747970652e76312e426967496e745206616d6f756e74122f0a066c6f636b656418022001280b32172e73662e6e6561722e747970652e76312e426967496e7452066c6f636b656412380a09636f64655f6861736818032001280b321b2e73662e6e6561722e747970652e76312e43727970746f486173685208636f64654861736812230a0d73746f726167655f7573616765180420012804520c73746f72616765557361676522c50e0a0b426c6f636b48656164657212160a066865696768741801200128045206686569676874121f0a0b707265765f686569676874180220012804520a7072657648656967687412360a0865706f63685f696418032001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520765706f63684964123f0a0d6e6578745f65706f63685f696418042001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520b6e65787445706f63684964122f0a046861736818052001280b321b2e73662e6e6561722e747970652e76312e43727970746f4861736852046861736812380a09707265765f6861736818062001280b321b2e73662e6e6561722e747970652e76312e43727970746f486173685208707265764861736812430a0f707265765f73746174655f726f6f7418072001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520d707265765374617465526f6f74124b0a136368756e6b5f72656365697074735f726f6f7418082001280b321b2e73662e6e6561722e747970652e76312e43727970746f4861736852116368756e6b5265636569707473526f6f7412490a126368756e6b5f686561646572735f726f6f7418092001280b321b2e73662e6e6561722e747970652e76312e43727970746f4861736852106368756e6b48656164657273526f6f74123f0a0d6368756e6b5f74785f726f6f74180a2001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520b6368756e6b5478526f6f74123e0a0c6f7574636f6d655f726f6f74180b2001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520b6f7574636f6d65526f6f7412270a0f6368756e6b735f696e636c75646564180c20012804520e6368756e6b73496e636c7564656412440a0f6368616c6c656e6765735f726f6f74180d2001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520e6368616c6c656e676573526f6f74121c0a0974696d657374616d70180e20012804520974696d657374616d70122b0a1174696d657374616d705f6e616e6f736563180f20012804521074696d657374616d704e616e6f736563123e0a0c72616e646f6d5f76616c756518102001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520b72616e646f6d56616c756512500a1376616c696461746f725f70726f706f73616c7318112003280b321f2e73662e6e6561722e747970652e76312e56616c696461746f725374616b65521276616c696461746f7250726f706f73616c73121d0a0a6368756e6b5f6d61736b18122003280852096368756e6b4d61736b12340a096761735f707269636518132001280b32172e73662e6e6561722e747970652e76312e426967496e745208676173507269636512230a0d626c6f636b5f6f7264696e616c181420012804520c626c6f636b4f7264696e616c123a0a0c746f74616c5f737570706c7918152001280b32172e73662e6e6561722e747970652e76312e426967496e74520b746f74616c537570706c79124e0a116368616c6c656e6765735f726573756c7418162003280b32212e73662e6e6561722e747970652e76312e536c617368656456616c696461746f7252106368616c6c656e676573526573756c7412350a176c6173745f66696e616c5f626c6f636b5f68656967687418172001280452146c61737446696e616c426c6f636b48656967687412450a106c6173745f66696e616c5f626c6f636b18182001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520e6c61737446696e616c426c6f636b123a0a1a6c6173745f64735f66696e616c5f626c6f636b5f68656967687418192001280452166c617374447346696e616c426c6f636b486569676874124a0a136c6173745f64735f66696e616c5f626c6f636b181a2001280b321b2e73662e6e6561722e747970652e76312e43727970746f4861736852106c617374447346696e616c426c6f636b123d0a0c6e6578745f62705f68617368181b2001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520a6e65787442704861736812470a11626c6f636b5f6d65726b6c655f726f6f74181c2001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520f626c6f636b4d65726b6c65526f6f74122f0a1465706f63685f73796e635f646174615f68617368181d2001280c521165706f636853796e63446174614861736812380a09617070726f76616c73181e2003280b321a2e73662e6e6561722e747970652e76312e5369676e61747572655209617070726f76616c7312380a097369676e6174757265181f2001280b321a2e73662e6e6561722e747970652e76312e5369676e617475726552097369676e617475726512360a176c61746573745f70726f746f636f6c5f76657273696f6e18202001280d52156c617465737450726f746f636f6c56657273696f6e221e0a06426967496e7412140a05627974657318012001280c5205627974657322220a0a43727970746f4861736812140a05627974657318012001280c5205627974657322510a095369676e6174757265122e0a047479706518012001280e321a2e73662e6e6561722e747970652e76312e43757276654b696e6452047479706512140a05627974657318022001280c5205627974657322510a095075626c69634b6579122e0a047479706518012001280e321a2e73662e6e6561722e747970652e76312e43757276654b696e6452047479706512140a05627974657318022001280c520562797465732299010a0e56616c696461746f725374616b65121d0a0a6163636f756e745f696418012001280952096163636f756e74496412390a0a7075626c69635f6b657918022001280b321a2e73662e6e6561722e747970652e76312e5075626c69634b657952097075626c69634b6579122d0a057374616b6518032001280b32172e73662e6e6561722e747970652e76312e426967496e7452057374616b6522570a10536c617368656456616c696461746f72121d0a0a6163636f756e745f696418012001280952096163636f756e74496412240a0e69735f646f75626c655f7369676e180220012808520c6973446f75626c655369676e22f6050a0b4368756e6b486561646572121d0a0a6368756e6b5f6861736818012001280c52096368756e6b4861736812260a0f707265765f626c6f636b5f6861736818022001280c520d70726576426c6f636b4861736812210a0c6f7574636f6d655f726f6f7418032001280c520b6f7574636f6d65526f6f7412260a0f707265765f73746174655f726f6f7418042001280c520d707265765374617465526f6f74122e0a13656e636f6465645f6d65726b6c655f726f6f7418052001280c5211656e636f6465644d65726b6c65526f6f7412250a0e656e636f6465645f6c656e677468180620012804520d656e636f6465644c656e67746812250a0e6865696768745f63726561746564180720012804520d6865696768744372656174656412270a0f6865696768745f696e636c75646564180820012804520e686569676874496e636c7564656412190a0873686172645f696418092001280452077368617264496412190a086761735f75736564180a20012804520767617355736564121b0a096761735f6c696d6974180b2001280452086761734c696d697412420a1076616c696461746f725f726577617264180c2001280b32172e73662e6e6561722e747970652e76312e426967496e74520f76616c696461746f72526577617264123c0a0d62616c616e63655f6275726e74180d2001280b32172e73662e6e6561722e747970652e76312e426967496e74520c62616c616e63654275726e7412340a166f7574676f696e675f72656365697074735f726f6f74180e2001280c52146f7574676f696e675265636569707473526f6f7412170a0774785f726f6f74180f2001280c52067478526f6f7412500a1376616c696461746f725f70726f706f73616c7318102003280b321f2e73662e6e6561722e747970652e76312e56616c696461746f725374616b65521276616c696461746f7250726f706f73616c7312380a097369676e617475726518112001280b321a2e73662e6e6561722e747970652e76312e5369676e617475726552097369676e617475726522d1010a0c496e6465786572536861726412190a0873686172645f696418012001280452077368617264496412330a056368756e6b18022001280b321d2e73662e6e6561722e747970652e76312e496e64657865724368756e6b52056368756e6b12710a1a726563656970745f657865637574696f6e5f6f7574636f6d657318032003280b32332e73662e6e6561722e747970652e76312e496e6465786572457865637574696f6e4f7574636f6d655769746852656365697074521872656365697074457865637574696f6e4f7574636f6d657322ae010a22496e6465786572457865637574696f6e4f7574636f6d65576974685265636569707412540a11657865637574696f6e5f6f7574636f6d6518012001280b32272e73662e6e6561722e747970652e76312e457865637574696f6e4f7574636f6d655769746849645210657865637574696f6e4f7574636f6d6512320a077265636569707418022001280b32182e73662e6e6561722e747970652e76312e5265636569707452077265636569707422e6010a0c496e64657865724368756e6b12160a06617574686f721801200128095206617574686f7212340a0668656164657218022001280b321c2e73662e6e6561722e747970652e76312e4368756e6b486561646572520668656164657212520a0c7472616e73616374696f6e7318032003280b322e2e73662e6e6561722e747970652e76312e496e64657865725472616e73616374696f6e576974684f7574636f6d65520c7472616e73616374696f6e7312340a08726563656970747318042003280b32182e73662e6e6561722e747970652e76312e526563656970745208726563656970747322bc010a1d496e64657865725472616e73616374696f6e576974684f7574636f6d6512440a0b7472616e73616374696f6e18012001280b32222e73662e6e6561722e747970652e76312e5369676e65645472616e73616374696f6e520b7472616e73616374696f6e12550a076f7574636f6d6518022001280b323b2e73662e6e6561722e747970652e76312e496e6465786572457865637574696f6e4f7574636f6d65576974684f7074696f6e616c5265636569707452076f7574636f6d6522c0020a115369676e65645472616e73616374696f6e121b0a097369676e65725f696418012001280952087369676e6572496412390a0a7075626c69635f6b657918022001280b321a2e73662e6e6561722e747970652e76312e5075626c69634b657952097075626c69634b657912140a056e6f6e636518032001280452056e6f6e6365121f0a0b72656365697665725f6964180420012809520a7265636569766572496412310a07616374696f6e7318052003280b32172e73662e6e6561722e747970652e76312e416374696f6e5207616374696f6e7312380a097369676e617475726518062001280b321a2e73662e6e6561722e747970652e76312e5369676e617475726552097369676e6174757265122f0a046861736818072001280b321b2e73662e6e6561722e747970652e76312e43727970746f4861736852046861736822b6010a2a496e6465786572457865637574696f6e4f7574636f6d65576974684f7074696f6e616c5265636569707412540a11657865637574696f6e5f6f7574636f6d6518012001280b32272e73662e6e6561722e747970652e76312e457865637574696f6e4f7574636f6d655769746849645210657865637574696f6e4f7574636f6d6512320a077265636569707418022001280b32182e73662e6e6561722e747970652e76312e526563656970745207726563656970742286020a075265636569707412250a0e7072656465636573736f725f6964180120012809520d7072656465636573736f724964121f0a0b72656365697665725f6964180220012809520a72656365697665724964123a0a0a726563656970745f696418032001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520972656365697074496412380a06616374696f6e180a2001280b321e2e73662e6e6561722e747970652e76312e52656365697074416374696f6e48005206616374696f6e12320a0464617461180b2001280b321c2e73662e6e6561722e747970652e76312e5265636569707444617461480052046461746142090a077265636569707422570a0b526563656970744461746112340a07646174615f696418012001280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520664617461496412120a046461746118022001280c52046461746122f3020a0d52656365697074416374696f6e121b0a097369676e65725f696418012001280952087369676e6572496412460a117369676e65725f7075626c69635f6b657918022001280b321a2e73662e6e6561722e747970652e76312e5075626c69634b6579520f7369676e65725075626c69634b657912340a096761735f707269636518032001280b32172e73662e6e6561722e747970652e76312e426967496e745208676173507269636512510a156f75747075745f646174615f72656365697665727318042003280b321d2e73662e6e6561722e747970652e76312e44617461526563656976657252136f75747075744461746152656365697665727312410a0e696e7075745f646174615f69647318052003280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520c696e7075744461746149647312310a07616374696f6e7318062003280b32172e73662e6e6561722e747970652e76312e416374696f6e5207616374696f6e7322650a0c44617461526563656976657212340a07646174615f696418012001280b321b2e73662e6e6561722e747970652e76312e43727970746f486173685206646174614964121f0a0b72656365697665725f6964180220012809520a7265636569766572496422f1010a16457865637574696f6e4f7574636f6d6557697468496412310a0570726f6f6618012001280b321b2e73662e6e6561722e747970652e76312e4d65726b6c6550617468520570726f6f66123a0a0a626c6f636b5f6861736818022001280b321b2e73662e6e6561722e747970652e76312e43727970746f486173685209626c6f636b48617368122b0a02696418032001280b321b2e73662e6e6561722e747970652e76312e43727970746f4861736852026964123b0a076f7574636f6d6518042001280b32212e73662e6e6561722e747970652e76312e457865637574696f6e4f7574636f6d6552076f7574636f6d6522e9040a10457865637574696f6e4f7574636f6d6512120a046c6f677318012003280952046c6f6773123c0a0b726563656970745f69647318022003280b321b2e73662e6e6561722e747970652e76312e43727970746f48617368520a72656365697074496473121b0a096761735f6275726e7418032001280452086761734275726e74123a0a0c746f6b656e735f6275726e7418042001280b32172e73662e6e6561722e747970652e76312e426967496e74520b746f6b656e734275726e74121f0a0b6578656375746f725f6964180520012809520a6578656375746f72496412430a07756e6b6e6f776e18142001280b32272e73662e6e6561722e747970652e76312e556e6b6e6f776e457865637574696f6e53746174757348005207756e6b6e6f776e12430a076661696c75726518152001280b32272e73662e6e6561722e747970652e76312e4661696c757265457865637574696f6e537461747573480052076661696c75726512530a0d737563636573735f76616c756518162001280b322c2e73662e6e6561722e747970652e76312e5375636365737356616c7565457865637574696f6e5374617475734800520c7375636365737356616c756512600a12737563636573735f726563656970745f696418172001280b32302e73662e6e6561722e747970652e76312e53756363657373526563656970744964457865637574696f6e5374617475734800521073756363657373526563656970744964123e0a086d6574616461746118062001280e32222e73662e6e6561722e747970652e76312e457865637574696f6e4d6574616461746152086d6574616461746142080a0673746174757322330a1b5375636365737356616c7565457865637574696f6e53746174757312140a0576616c756518012001280c520576616c7565224e0a1f53756363657373526563656970744964457865637574696f6e537461747573122b0a02696418012001280b321b2e73662e6e6561722e747970652e76312e43727970746f486173685202696422180a16556e6b6e6f776e457865637574696f6e53746174757322b3010a164661696c757265457865637574696f6e53746174757312410a0c616374696f6e5f6572726f7218012001280b321c2e73662e6e6561722e747970652e76312e416374696f6e4572726f724800520b616374696f6e4572726f72124b0a10696e76616c69645f74785f6572726f7218022001280e321f2e73662e6e6561722e747970652e76312e496e76616c696454784572726f724800520e696e76616c696454784572726f7242090a076661696c75726522bc130a0b416374696f6e4572726f7212140a05696e6465781801200128045205696e64657812640a156163636f756e745f616c72656164795f657869737418152001280b322e2e73662e6e6561722e747970652e76312e4163636f756e74416c72656164794578697374734572726f724b696e64480052136163636f756e74416c7265616479457869737412640a166163636f756e745f646f65735f6e6f745f657869737418162001280b322d2e73662e6e6561722e747970652e76312e4163636f756e74446f65734e6f7445786973744572726f724b696e64480052136163636f756e74446f65734e6f7445786973741280010a206372656174655f6163636f756e745f6f6e6c795f62795f72656769737472617218172001280b32362e73662e6e6561722e747970652e76312e4372656174654163636f756e744f6e6c7942795265676973747261724572726f724b696e644800521c6372656174654163636f756e744f6e6c79427952656769737472617212700a1a6372656174655f6163636f756e745f6e6f745f616c6c6f77656418182001280b32312e73662e6e6561722e747970652e76312e4372656174654163636f756e744e6f74416c6c6f7765644572726f724b696e64480052176372656174654163636f756e744e6f74416c6c6f776564125d0a136163746f725f6e6f5f7065726d697373696f6e18192001280b322b2e73662e6e6561722e747970652e76312e4163746f724e6f5065726d697373696f6e4572726f724b696e64480052116163746f724e6f5065726d697373696f6e126b0a1964656c6574655f6b65795f646f65735f6e6f745f6578697374181a2001280b322f2e73662e6e6561722e747970652e76312e44656c6574654b6579446f65734e6f7445786973744572726f724b696e644800521564656c6574654b6579446f65734e6f74457869737412640a166164645f6b65795f616c72656164795f657869737473181b2001280b322d2e73662e6e6561722e747970652e76312e4164644b6579416c72656164794578697374734572726f724b696e64480052136164644b6579416c726561647945786973747312660a1664656c6574655f6163636f756e745f7374616b696e67181c2001280b322e2e73662e6e6561722e747970652e76312e44656c6574654163636f756e745374616b696e674572726f724b696e644800521464656c6574654163636f756e745374616b696e6712640a166c61636b5f62616c616e63655f666f725f7374617465181d2001280b322d2e73662e6e6561722e747970652e76312e4c61636b42616c616e6365466f7253746174654572726f724b696e64480052136c61636b42616c616e6365466f72537461746512540a1074726965735f746f5f756e7374616b65181e2001280b32282e73662e6e6561722e747970652e76312e5472696573546f556e7374616b654572726f724b696e644800520e7472696573546f556e7374616b65124e0a0e74726965735f746f5f7374616b65181f2001280b32262e73662e6e6561722e747970652e76312e5472696573546f5374616b654572726f724b696e644800520c7472696573546f5374616b65125c0a12696e73756666696369656e745f7374616b6518202001280b322b2e73662e6e6561722e747970652e76312e496e73756666696369656e745374616b654572726f724b696e6448005211696e73756666696369656e745374616b65124d0a0d66756e6374696f6e5f63616c6c18212001280b32262e73662e6e6561722e747970652e76312e46756e6374696f6e43616c6c4572726f724b696e644800520c66756e6374696f6e43616c6c12660a166e65775f726563656970745f76616c69646174696f6e18222001280b322e2e73662e6e6561722e747970652e76312e4e65775265636569707456616c69646174696f6e4572726f724b696e64480052146e65775265636569707456616c69646174696f6e1292010a266f6e6c795f696d706c696369745f6163636f756e745f6372656174696f6e5f616c6c6f77656418232001280b323c2e73662e6e6561722e747970652e76312e4f6e6c79496d706c696369744163636f756e744372656174696f6e416c6c6f7765644572726f724b696e64480052226f6e6c79496d706c696369744163636f756e744372656174696f6e416c6c6f776564127d0a1f64656c6574655f6163636f756e745f776974685f6c617267655f737461746518242001280b32352e73662e6e6561722e747970652e76312e44656c6574654163636f756e74576974684c6172676553746174654572726f724b696e644800521b64656c6574654163636f756e74576974684c6172676553746174651280010a2164656c65676174655f616374696f6e5f696e76616c69645f7369676e617475726518252001280b32332e73662e6e6561722e747970652e76312e44656c6567617465416374696f6e496e76616c69645369676e61747572654b696e644800521e64656c6567617465416374696f6e496e76616c69645369676e617475726512a8010a3164656c65676174655f616374696f6e5f73656e6465725f646f65735f6e6f745f6d617463685f74785f726563656976657218262001280b323f2e73662e6e6561722e747970652e76312e44656c6567617465416374696f6e53656e646572446f65734e6f744d61746368547852656365697665724b696e644800522a64656c6567617465416374696f6e53656e646572446f65734e6f744d617463685478526563656976657212640a1764656c65676174655f616374696f6e5f6578706972656418272001280b322a2e73662e6e6561722e747970652e76312e44656c6567617465416374696f6e457870697265644b696e644800521564656c6567617465416374696f6e45787069726564127b0a2064656c65676174655f616374696f6e5f6163636573735f6b65795f6572726f7218282001280b32312e73662e6e6561722e747970652e76312e44656c6567617465416374696f6e4163636573734b65794572726f724b696e644800521c64656c6567617465416374696f6e4163636573734b65794572726f7212740a1d64656c65676174655f616374696f6e5f696e76616c69645f6e6f6e636518292001280b322f2e73662e6e6561722e747970652e76312e44656c6567617465416374696f6e496e76616c69644e6f6e63654b696e644800521a64656c6567617465416374696f6e496e76616c69644e6f6e636512780a1f64656c65676174655f616374696f6e5f6e6f6e63655f746f6f5f6c61726765182a2001280b32302e73662e6e6561722e747970652e76312e44656c6567617465416374696f6e4e6f6e6365546f6f4c617267654b696e644800521b64656c6567617465416374696f6e4e6f6e6365546f6f4c6172676542060a046b696e64223e0a1d4163636f756e74416c72656164794578697374734572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e744964223d0a1c4163636f756e74446f65734e6f7445786973744572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e744964229f010a254372656174654163636f756e744f6e6c7942795265676973747261724572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e74496412300a147265676973747261725f6163636f756e745f696418022001280952127265676973747261724163636f756e74496412250a0e7072656465636573736f725f6964180320012809520d7072656465636573736f72496422680a204372656174654163636f756e744e6f74416c6c6f7765644572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e74496412250a0e7072656465636573736f725f6964180220012809520d7072656465636573736f72496422560a1a4163746f724e6f5065726d697373696f6e4572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e74496412190a086163746f725f696418022001280952076163746f724964227a0a1e44656c6574654b6579446f65734e6f7445786973744572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e74496412390a0a7075626c69635f6b657918022001280b321a2e73662e6e6561722e747970652e76312e5075626c69634b657952097075626c69634b657922780a1c4164644b6579416c72656164794578697374734572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e74496412390a0a7075626c69635f6b657918022001280b321a2e73662e6e6561722e747970652e76312e5075626c69634b657952097075626c69634b6579223e0a1d44656c6574654163636f756e745374616b696e674572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e74496422700a1c4c61636b42616c616e6365466f7253746174654572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e74496412310a0762616c616e636518022001280b32172e73662e6e6561722e747970652e76312e426967496e74520762616c616e636522380a175472696573546f556e7374616b654572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e74496422c9010a155472696573546f5374616b654572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e744964122d0a057374616b6518022001280b32172e73662e6e6561722e747970652e76312e426967496e7452057374616b65122f0a066c6f636b656418032001280b32172e73662e6e6561722e747970652e76312e426967496e7452066c6f636b656412310a0762616c616e636518042001280b32172e73662e6e6561722e747970652e76312e426967496e74520762616c616e636522a8010a1a496e73756666696369656e745374616b654572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e744964122d0a057374616b6518022001280b32172e73662e6e6561722e747970652e76312e426967496e7452057374616b65123c0a0d6d696e696d756d5f7374616b6518032001280b32172e73662e6e6561722e747970652e76312e426967496e74520c6d696e696d756d5374616b6522540a1546756e6374696f6e43616c6c4572726f724b696e64123b0a056572726f7218012001280e32252e73662e6e6561722e747970652e76312e46756e6374696f6e43616c6c4572726f7253657252056572726f72225e0a1d4e65775265636569707456616c69646174696f6e4572726f724b696e64123d0a056572726f7218012001280e32272e73662e6e6561722e747970652e76312e5265636569707456616c69646174696f6e4572726f7252056572726f72224c0a2b4f6e6c79496d706c696369744163636f756e744372656174696f6e416c6c6f7765644572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e74496422450a2444656c6574654163636f756e74576974684c6172676553746174654572726f724b696e64121d0a0a6163636f756e745f696418012001280952096163636f756e74496422240a2244656c6567617465416374696f6e496e76616c69645369676e61747572654b696e64226e0a2e44656c6567617465416374696f6e53656e646572446f65734e6f744d61746368547852656365697665724b696e64121b0a0973656e6465725f6964180120012809520873656e6465724964121f0a0b72656365697665725f6964180220012809520a72656365697665724964221b0a1944656c6567617465416374696f6e457870697265644b696e6422590a2044656c6567617465416374696f6e4163636573734b65794572726f724b696e6412350a056572726f7218012001280e321f2e73662e6e6561722e747970652e76312e496e76616c696454784572726f7252056572726f7222620a1e44656c6567617465416374696f6e496e76616c69644e6f6e63654b696e6412250a0e64656c65676174655f6e6f6e6365180120012804520d64656c65676174654e6f6e636512190a08616b5f6e6f6e63651802200128045207616b4e6f6e636522690a1f44656c6567617465416374696f6e4e6f6e6365546f6f4c617267654b696e6412250a0e64656c65676174655f6e6f6e6365180120012804520d64656c65676174654e6f6e6365121f0a0b75707065725f626f756e64180220012804520a7570706572426f756e6422410a0a4d65726b6c655061746812330a047061746818012003280b321f2e73662e6e6561722e747970652e76312e4d65726b6c65506174684974656d520470617468227b0a0e4d65726b6c65506174684974656d122f0a046861736818012001280b321b2e73662e6e6561722e747970652e76312e43727970746f4861736852046861736812380a09646972656374696f6e18022001280e321a2e73662e6e6561722e747970652e76312e446972656374696f6e5209646972656374696f6e2285050a06416374696f6e124d0a0e6372656174655f6163636f756e7418012001280b32242e73662e6e6561722e747970652e76312e4372656174654163636f756e74416374696f6e4800520d6372656174654163636f756e7412500a0f6465706c6f795f636f6e747261637418022001280b32252e73662e6e6561722e747970652e76312e4465706c6f79436f6e7472616374416374696f6e4800520e6465706c6f79436f6e7472616374124a0a0d66756e6374696f6e5f63616c6c18032001280b32232e73662e6e6561722e747970652e76312e46756e6374696f6e43616c6c416374696f6e4800520c66756e6374696f6e43616c6c123d0a087472616e7366657218042001280b321f2e73662e6e6561722e747970652e76312e5472616e73666572416374696f6e480052087472616e7366657212340a057374616b6518052001280b321c2e73662e6e6561722e747970652e76312e5374616b65416374696f6e480052057374616b6512380a076164645f6b657918062001280b321d2e73662e6e6561722e747970652e76312e4164644b6579416374696f6e480052066164644b657912410a0a64656c6574655f6b657918072001280b32202e73662e6e6561722e747970652e76312e44656c6574654b6579416374696f6e4800520964656c6574654b6579124d0a0e64656c6574655f6163636f756e7418082001280b32242e73662e6e6561722e747970652e76312e44656c6574654163636f756e74416374696f6e4800520d64656c6574654163636f756e7412430a0864656c656761746518092001280b32252e73662e6e6561722e747970652e76312e5369676e656444656c6567617465416374696f6e4800520864656c656761746542080a06616374696f6e22150a134372656174654163636f756e74416374696f6e222a0a144465706c6f79436f6e7472616374416374696f6e12120a04636f646518012001280c5204636f6465228e010a1246756e6374696f6e43616c6c416374696f6e121f0a0b6d6574686f645f6e616d65180120012809520a6d6574686f644e616d6512120a046172677318022001280c52046172677312100a03676173180320012804520367617312310a076465706f73697418042001280b32172e73662e6e6561722e747970652e76312e426967496e7452076465706f73697422430a0e5472616e73666572416374696f6e12310a076465706f73697418012001280b32172e73662e6e6561722e747970652e76312e426967496e7452076465706f73697422770a0b5374616b65416374696f6e122d0a057374616b6518012001280b32172e73662e6e6561722e747970652e76312e426967496e7452057374616b6512390a0a7075626c69635f6b657918022001280b321a2e73662e6e6561722e747970652e76312e5075626c69634b657952097075626c69634b65792284010a0c4164644b6579416374696f6e12390a0a7075626c69635f6b657918012001280b321a2e73662e6e6561722e747970652e76312e5075626c69634b657952097075626c69634b657912390a0a6163636573735f6b657918022001280b321a2e73662e6e6561722e747970652e76312e4163636573734b657952096163636573734b6579224c0a0f44656c6574654b6579416374696f6e12390a0a7075626c69635f6b657918012001280b321a2e73662e6e6561722e747970652e76312e5075626c69634b657952097075626c69634b6579223c0a1344656c6574654163636f756e74416374696f6e12250a0e62656e65666963696172795f6964180120012809520d62656e65666963696172794964229a010a145369676e656444656c6567617465416374696f6e12380a097369676e617475726518012001280b321a2e73662e6e6561722e747970652e76312e5369676e617475726552097369676e617475726512480a0f64656c65676174655f616374696f6e18022001280b321f2e73662e6e6561722e747970652e76312e44656c6567617465416374696f6e520e64656c6567617465416374696f6e22fc010a0e44656c6567617465416374696f6e121b0a0973656e6465725f6964180120012809520873656e6465724964121f0a0b72656365697665725f6964180220012809520a7265636569766572496412310a07616374696f6e7318032003280b32172e73662e6e6561722e747970652e76312e416374696f6e5207616374696f6e7312140a056e6f6e636518042001280452056e6f6e636512280a106d61785f626c6f636b5f686569676874180520012804520e6d6178426c6f636b48656967687412390a0a7075626c69635f6b657918062001280b321a2e73662e6e6561722e747970652e76312e5075626c69634b657952097075626c69634b657922670a094163636573734b657912140a056e6f6e636518012001280452056e6f6e636512440a0a7065726d697373696f6e18022001280b32242e73662e6e6561722e747970652e76312e4163636573734b65795065726d697373696f6e520a7065726d697373696f6e22bd010a134163636573734b65795065726d697373696f6e124e0a0d66756e6374696f6e5f63616c6c18012001280b32272e73662e6e6561722e747970652e76312e46756e6374696f6e43616c6c5065726d697373696f6e4800520c66756e6374696f6e43616c6c12480a0b66756c6c5f61636365737318022001280b32252e73662e6e6561722e747970652e76312e46756c6c4163636573735065726d697373696f6e4800520a66756c6c416363657373420c0a0a7065726d697373696f6e2293010a1646756e6374696f6e43616c6c5065726d697373696f6e12350a09616c6c6f77616e636518012001280b32172e73662e6e6561722e747970652e76312e426967496e745209616c6c6f77616e6365121f0a0b72656365697665725f6964180220012809520a7265636569766572496412210a0c6d6574686f645f6e616d6573180320032809520b6d6574686f644e616d657322160a1446756c6c4163636573735065726d697373696f6e2a270a0943757276654b696e64120b0a07454432353531391000120d0a09534543503235364b3110012a2c0a11457865637574696f6e4d6574616461746112170a13457865637574696f6e4d65746164617461563110002aa9010a1446756e6374696f6e43616c6c4572726f7253657212140a10436f6d70696c6174696f6e4572726f721000120d0a094c696e6b4572726f72100112160a124d6574686f645265736f6c76654572726f721002120c0a085761736d54726170100312140a105761736d556e6b6e6f776e4572726f721004120d0a09486f73744572726f721005120d0a095f45564d4572726f72100612120a0e457865637574696f6e4572726f7210072aed010a165265636569707456616c69646174696f6e4572726f7212180a14496e76616c69645072656465636573736f7249641000121c0a18496e76616c696452656365697665724163636f756e7449641001121a0a16496e76616c69645369676e65724163636f756e744964100212190a15496e76616c696444617461526563656976657249641003121f0a1b52657475726e656456616c75654c656e6774684578636565646564100412270a234e756d626572496e70757444617461446570656e64656e6369657345786365656465641005121a0a16416374696f6e7356616c69646174696f6e4572726f7210062abe020a0e496e76616c696454784572726f7212190a15496e76616c69644163636573734b65794572726f72100012130a0f496e76616c69645369676e65724964100112160a125369676e6572446f65734e6f744578697374100212100a0c496e76616c69644e6f6e6365100312110a0d4e6f6e6365546f6f4c61726765100412150a11496e76616c696452656365697665724964100512140a10496e76616c69645369676e6174757265100612140a104e6f74456e6f75676842616c616e6365100712170a134c61636b42616c616e6365466f725374617465100812100a0c436f73744f766572666c6f77100912100a0c496e76616c6964436861696e100a120b0a0745787069726564100b12150a11416374696f6e7356616c69646174696f6e100c121b0a175472616e73616374696f6e53697a654578636565646564100d2a200a09446972656374696f6e12080a046c656674100012090a057269676874100142425a406769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d6e6561722f70622f73662f6e6561722f747970652f76313b70626e656172620670726f746f33", + }, + { + // sf/solana/transforms/v1/transforms.proto (https://buf.build/streamingfast/firehose-solana/docs/7e16dd37d68049d1a3f548203be431d7:sf.solana.transforms.v1) + proto: "0a2873662f736f6c616e612f7472616e73666f726d732f76312f7472616e73666f726d732e70726f746f121773662e736f6c616e612e7472616e73666f726d732e763122300a0d50726f6772616d46696c746572121f0a0b70726f6772616d5f696473180120032809520a70726f6772616d49647342525a506769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d736f6c616e612f70622f73662f736f6c616e612f7472616e73666f726d732f76313b70627472616e73666f726d73620670726f746f33", + }, + { + // sf/solana/type/v1/type.proto (https://buf.build/streamingfast/firehose-solana/docs/7e16dd37d68049d1a3f548203be431d7:sf.solana.type.v1) + proto: "0a1c73662f736f6c616e612f747970652f76312f747970652e70726f746f121173662e736f6c616e612e747970652e7631228f030a05426c6f636b122d0a1270726576696f75735f626c6f636b68617368180120012809521170726576696f7573426c6f636b68617368121c0a09626c6f636b686173681802200128095209626c6f636b68617368121f0a0b706172656e745f736c6f74180320012804520a706172656e74536c6f74124b0a0c7472616e73616374696f6e7318042003280b32272e73662e736f6c616e612e747970652e76312e436f6e6669726d65645472616e73616374696f6e520c7472616e73616374696f6e7312330a077265776172647318052003280b32192e73662e736f6c616e612e747970652e76312e526577617264520772657761726473123f0a0a626c6f636b5f74696d6518062001280b32202e73662e736f6c616e612e747970652e76312e556e697854696d657374616d705209626c6f636b54696d6512410a0c626c6f636b5f68656967687418072001280b321e2e73662e736f6c616e612e747970652e76312e426c6f636b486569676874520b626c6f636b48656967687412120a04736c6f741814200128045204736c6f742296010a14436f6e6669726d65645472616e73616374696f6e12400a0b7472616e73616374696f6e18012001280b321e2e73662e736f6c616e612e747970652e76312e5472616e73616374696f6e520b7472616e73616374696f6e123c0a046d65746118022001280b32282e73662e736f6c616e612e747970652e76312e5472616e73616374696f6e5374617475734d65746152046d65746122630a0b5472616e73616374696f6e121e0a0a7369676e61747572657318012003280c520a7369676e61747572657312340a076d65737361676518022001280b321a2e73662e736f6c616e612e747970652e76312e4d65737361676552076d65737361676522dd020a074d65737361676512380a0668656164657218012001280b32202e73662e736f6c616e612e747970652e76312e4d657373616765486561646572520668656164657212210a0c6163636f756e745f6b65797318022003280c520b6163636f756e744b65797312290a10726563656e745f626c6f636b6861736818032001280c520f726563656e74426c6f636b68617368124a0a0c696e737472756374696f6e7318042003280b32262e73662e736f6c616e612e747970652e76312e436f6d70696c6564496e737472756374696f6e520c696e737472756374696f6e73121c0a0976657273696f6e6564180520012808520976657273696f6e656412600a15616464726573735f7461626c655f6c6f6f6b75707318062003280b322c2e73662e736f6c616e612e747970652e76312e4d657373616765416464726573735461626c654c6f6f6b75705213616464726573735461626c654c6f6f6b75707322cd010a0d4d65737361676548656164657212360a176e756d5f72657175697265645f7369676e61747572657318012001280d52156e756d52657175697265645369676e617475726573123f0a1c6e756d5f726561646f6e6c795f7369676e65645f6163636f756e747318022001280d52196e756d526561646f6e6c795369676e65644163636f756e747312430a1e6e756d5f726561646f6e6c795f756e7369676e65645f6163636f756e747318032001280d521b6e756d526561646f6e6c79556e7369676e65644163636f756e74732292010a194d657373616765416464726573735461626c654c6f6f6b7570121f0a0b6163636f756e745f6b657918012001280c520a6163636f756e744b657912290a107772697461626c655f696e646578657318022001280c520f7772697461626c65496e646578657312290a10726561646f6e6c795f696e646578657318032001280c520f726561646f6e6c79496e64657865732283060a155472616e73616374696f6e5374617475734d65746112350a0365727218012001280b32232e73662e736f6c616e612e747970652e76312e5472616e73616374696f6e4572726f72520365727212100a03666565180220012804520366656512210a0c7072655f62616c616e636573180320032804520b70726542616c616e63657312230a0d706f73745f62616c616e636573180420032804520c706f737442616c616e63657312530a12696e6e65725f696e737472756374696f6e7318052003280b32242e73662e736f6c616e612e747970652e76312e496e6e6572496e737472756374696f6e735211696e6e6572496e737472756374696f6e7312210a0c6c6f675f6d65737361676573180620032809520b6c6f674d65737361676573124d0a127072655f746f6b656e5f62616c616e63657318072003280b321f2e73662e736f6c616e612e747970652e76312e546f6b656e42616c616e63655210707265546f6b656e42616c616e636573124f0a13706f73745f746f6b656e5f62616c616e63657318082003280b321f2e73662e736f6c616e612e747970652e76312e546f6b656e42616c616e63655211706f7374546f6b656e42616c616e63657312330a077265776172647318092003280b32192e73662e736f6c616e612e747970652e76312e526577617264520772657761726473123a0a196c6f616465645f7772697461626c655f616464726573736573180c2003280c52176c6f616465645772697461626c65416464726573736573123a0a196c6f616465645f726561646f6e6c795f616464726573736573180d2003280c52176c6f61646564526561646f6e6c79416464726573736573123e0a0b72657475726e5f64617461180e2001280b321d2e73662e736f6c616e612e747970652e76312e52657475726e44617461520a72657475726e4461746112390a16636f6d707574655f756e6974735f636f6e73756d656418102001280448005214636f6d70757465556e697473436f6e73756d656488010142190a175f636f6d707574655f756e6974735f636f6e73756d656422240a105472616e73616374696f6e4572726f7212100a0365727218012001280c520365727222720a11496e6e6572496e737472756374696f6e7312140a05696e64657818012001280d5205696e64657812470a0c696e737472756374696f6e7318022003280b32232e73662e736f6c616e612e747970652e76312e496e6e6572496e737472756374696f6e520c696e737472756374696f6e7322a5010a10496e6e6572496e737472756374696f6e12280a1070726f6772616d5f69645f696e64657818012001280d520e70726f6772616d4964496e646578121a0a086163636f756e747318022001280c52086163636f756e747312120a046461746118032001280c52046461746112260a0c737461636b5f68656967687418042001280d4800520b737461636b486569676874880101420f0a0d5f737461636b5f686569676874226f0a13436f6d70696c6564496e737472756374696f6e12280a1070726f6772616d5f69645f696e64657818012001280d520e70726f6772616d4964496e646578121a0a086163636f756e747318022001280c52086163636f756e747312120a046461746118032001280c52046461746122c6010a0c546f6b656e42616c616e636512230a0d6163636f756e745f696e64657818012001280d520c6163636f756e74496e64657812120a046d696e7418022001280952046d696e7412480a0f75695f746f6b656e5f616d6f756e7418032001280b32202e73662e736f6c616e612e747970652e76312e5569546f6b656e416d6f756e74520d7569546f6b656e416d6f756e7412140a056f776e657218042001280952056f776e6572121d0a0a70726f6772616d5f6964180520012809520970726f6772616d4964228a010a0d5569546f6b656e416d6f756e74121b0a0975695f616d6f756e7418012001280152087569416d6f756e74121a0a08646563696d616c7318022001280d5208646563696d616c7312160a06616d6f756e741803200128095206616d6f756e7412280a1075695f616d6f756e745f737472696e67180420012809520e7569416d6f756e74537472696e67223f0a0a52657475726e44617461121d0a0a70726f6772616d5f696418012001280c520970726f6772616d496412120a046461746118022001280c52046461746122bf010a0652657761726412160a067075626b657918012001280952067075626b6579121a0a086c616d706f72747318022001280352086c616d706f72747312210a0c706f73745f62616c616e6365180320012804520b706f737442616c616e6365123e0a0b7265776172645f7479706518042001280e321d2e73662e736f6c616e612e747970652e76312e52657761726454797065520a72657761726454797065121e0a0a636f6d6d697373696f6e180520012809520a636f6d6d697373696f6e223e0a075265776172647312330a077265776172647318012003280b32192e73662e736f6c616e612e747970652e76312e526577617264520772657761726473222d0a0d556e697854696d657374616d70121c0a0974696d657374616d70180120012803520974696d657374616d7022300a0b426c6f636b48656967687412210a0c626c6f636b5f686569676874180120012804520b626c6f636b4865696768742a490a0a52657761726454797065120f0a0b556e737065636966696564100012070a03466565100112080a0452656e741002120b0a075374616b696e671003120a0a06566f74696e67100442455a436769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d736f6c616e612f70622f73662f736f6c616e612f747970652f76313b7062736f6c620670726f746f33", + }, + { + // google/protobuf/timestamp.proto (https://buf.build/streamingfast/firehose-bitcoin/docs/0d8ce32fe71441df82c89dcccda35366:google.protobuf) + proto: "0a1f676f6f676c652f70726f746f6275662f74696d657374616d702e70726f746f120f676f6f676c652e70726f746f627566223b0a0954696d657374616d7012180a077365636f6e647318012001280352077365636f6e647312140a056e616e6f7318022001280552056e616e6f734285010a13636f6d2e676f6f676c652e70726f746f627566420e54696d657374616d7050726f746f50015a32676f6f676c652e676f6c616e672e6f72672f70726f746f6275662f74797065732f6b6e6f776e2f74696d657374616d707062f80101a20203475042aa021e476f6f676c652e50726f746f6275662e57656c6c4b6e6f776e5479706573620670726f746f33", + }, + { + // sf/bitcoin/type/v1/type.proto (https://buf.build/streamingfast/firehose-bitcoin/docs/0d8ce32fe71441df82c89dcccda35366:sf.bitcoin.type.v1) + proto: "0a1d73662f626974636f696e2f747970652f76312f747970652e70726f746f121273662e626974636f696e2e747970652e76311a1f676f6f676c652f70726f746f6275662f74696d657374616d702e70726f746f22e5030a05426c6f636b12120a046861736818012001280952046861736812120a0473697a65180320012805520473697a6512230a0d73747269707065645f73697a65180420012805520c737472697070656453697a6512160a06776569676874180520012805520677656967687412160a06686569676874180620012803520668656967687412180a0776657273696f6e180720012805520776657273696f6e121f0a0b76657273696f6e5f686578180820012809520a76657273696f6e486578121f0a0b6d65726b6c655f726f6f74180920012809520a6d65726b6c65526f6f74122f0a027478180a2003280b321f2e73662e626974636f696e2e747970652e76312e5472616e73616374696f6e5202747812120a0474696d65180b20012803520474696d65121e0a0a6d656469616e74696d65180c20012803520a6d656469616e74696d6512140a056e6f6e6365180d2001280d52056e6f6e636512120a0462697473180e20012809520462697473121e0a0a646966666963756c7479180f20012801520a646966666963756c7479121c0a09636861696e776f726b1810200128095209636861696e776f726b12110a046e5f747818112001280d52036e547812230a0d70726576696f75735f68617368181220012809520c70726576696f75734861736822d4020a0b5472616e73616374696f6e12100a03686578180120012809520368657812120a047478696418022001280952047478696412120a046861736818032001280952046861736812120a0473697a65180420012805520473697a6512140a057673697a6518052001280552057673697a6512160a06776569676874180620012805520677656967687412180a0776657273696f6e18072001280d520776657273696f6e121a0a086c6f636b74696d6518082001280d52086c6f636b74696d6512290a0376696e18092003280b32172e73662e626974636f696e2e747970652e76312e56696e520376696e122c0a04766f7574180a2003280b32182e73662e626974636f696e2e747970652e76312e566f75745204766f7574121c0a09626c6f636b68617368180b200128095209626c6f636b68617368121c0a09626c6f636b74696d65180c200128035209626c6f636b74696d6522c5010a0356696e12120a047478696418012001280952047478696412120a04766f757418022001280d5204766f7574123c0a0a7363726970745f73696718032001280b321d2e73662e626974636f696e2e747970652e76312e5363726970745369675209736372697074536967121a0a0873657175656e636518042001280d520873657175656e636512200a0b7478696e7769746e657373180520032809520b7478696e7769746e657373121a0a08636f696e626173651806200128095208636f696e6261736522710a04566f757412140a0576616c7565180120012801520576616c7565120c0a016e18022001280d52016e12450a0d7363726970745f7075624b657918032001280b32202e73662e626974636f696e2e747970652e76312e5363726970745075624b6579520c7363726970745075624b6579222f0a0953637269707453696712100a0361736d180120012809520361736d12100a0368657818022001280952036865782299010a0c5363726970745075624b657912100a0361736d180120012809520361736d12100a03686578180220012809520368657812190a087265715f7369677318032001280552077265715369677312120a047479706518042001280952047479706512180a0761646472657373180520012809520761646472657373121c0a096164647265737365731806200328095209616464726573736573424d5a4b6769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d626974636f696e2f74797065732f70622f73662f626974636f696e2f747970652f76313b7062627463620670726f746f33", + }, + { + // google/protobuf/timestamp.proto (https://buf.build/pinax/firehose-antelope/docs/716581be38ac455eade2e70f33a09bf3:google.protobuf) + proto: "0a1f676f6f676c652f70726f746f6275662f74696d657374616d702e70726f746f120f676f6f676c652e70726f746f627566223b0a0954696d657374616d7012180a077365636f6e647318012001280352077365636f6e647312140a056e616e6f7318022001280552056e616e6f734285010a13636f6d2e676f6f676c652e70726f746f627566420e54696d657374616d7050726f746f50015a32676f6f676c652e676f6c616e672e6f72672f70726f746f6275662f74797065732f6b6e6f776e2f74696d657374616d707062f80101a20203475042aa021e476f6f676c652e50726f746f6275662e57656c6c4b6e6f776e5479706573620670726f746f33", + }, + { + // sf/antelope/type/v1/type.proto (https://buf.build/pinax/firehose-antelope/docs/716581be38ac455eade2e70f33a09bf3:sf.antelope.type.v1) + proto: "0a1e73662f616e74656c6f70652f747970652f76312f747970652e70726f746f121373662e616e74656c6f70652e747970652e76311a1f676f6f676c652f70726f746f6275662f74696d657374616d702e70726f746f22550a0c416374696f6e54726163657312450a0d616374696f6e5f74726163657318012003280b32202e73662e616e74656c6f70652e747970652e76312e416374696f6e5472616365520c616374696f6e54726163657322690a115472616e73616374696f6e54726163657312540a127472616e73616374696f6e5f74726163657318012003280b32252e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e547261636552117472616e73616374696f6e54726163657322390a0544424f707312300a0664625f6f707318012003280b32192e73662e616e74656c6f70652e747970652e76312e44424f70520564624f7073228b160a05426c6f636b120e0a0269641801200128095202696412160a066e756d62657218022001280d52066e756d62657212180a0776657273696f6e18032001280d520776657273696f6e12380a0668656164657218042001280b32202e73662e616e74656c6f70652e747970652e76312e426c6f636b4865616465725206686561646572122d0a1270726f64756365725f7369676e6174757265180520012809521170726f64756365725369676e617475726512490a10626c6f636b5f657874656e73696f6e7318072003280b321e2e73662e616e74656c6f70652e747970652e76312e457874656e73696f6e520f626c6f636b457874656e73696f6e73124d0a2364706f735f70726f706f7365645f697272657665727369626c655f626c6f636b6e756d18082001280d522064706f7350726f706f736564497272657665727369626c65426c6f636b6e756d123c0a1a64706f735f697272657665727369626c655f626c6f636b6e756d18092001280d521864706f73497272657665727369626c65426c6f636b6e756d124f0a10626c6f636b726f6f745f6d65726b6c65180b2001280b32242e73662e616e74656c6f70652e747970652e76312e426c6f636b526f6f744d65726b6c65520f626c6f636b726f6f744d65726b6c6512660a1970726f64756365725f746f5f6c6173745f70726f6475636564180c2003280b322b2e73662e616e74656c6f70652e747970652e76312e50726f6475636572546f4c61737450726f6475636564521670726f6475636572546f4c61737450726f6475636564126d0a1c70726f64756365725f746f5f6c6173745f696d706c6965645f697262180d2003280b322d2e73662e616e74656c6f70652e747970652e76312e50726f6475636572546f4c617374496d706c696564495242521870726f6475636572546f4c617374496d706c69656449726212230a0d636f6e6669726d5f636f756e74180f2003280d520c636f6e6669726d436f756e7412570a1070656e64696e675f7363686564756c6518102001280b322c2e73662e616e74656c6f70652e747970652e76312e50656e64696e6750726f64756365725363686564756c65520f70656e64696e675363686564756c65126e0a1b6163746976617465645f70726f746f636f6c5f666561747572657318112001280b322e2e73662e616e74656c6f70652e747970652e76312e41637469766174656450726f746f636f6c4665617475726573521961637469766174656450726f746f636f6c4665617475726573123c0a0a726c696d69745f6f707318132003280b321d2e73662e616e74656c6f70652e747970652e76312e526c696d69744f705209726c696d69744f707312600a17756e66696c74657265645f7472616e73616374696f6e7318062003280b32272e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e526563656970745216756e66696c74657265645472616e73616374696f6e73125c0a1566696c74657265645f7472616e73616374696f6e73182f2003280b32272e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e52656365697074521466696c74657265645472616e73616374696f6e7312400a1c756e66696c74657265645f7472616e73616374696f6e5f636f756e7418162001280d521a756e66696c74657265645472616e73616374696f6e436f756e74123c0a1a66696c74657265645f7472616e73616374696f6e5f636f756e7418302001280d521866696c74657265645472616e73616374696f6e436f756e7412690a23756e66696c74657265645f696d706c696369745f7472616e73616374696f6e5f6f707318142003280b321a2e73662e616e74656c6f70652e747970652e76312e5472784f705220756e66696c7465726564496d706c696369745472616e73616374696f6e4f707312650a2166696c74657265645f696d706c696369745f7472616e73616374696f6e5f6f707318312003280b321a2e73662e616e74656c6f70652e747970652e76312e5472784f70521e66696c7465726564496d706c696369745472616e73616374696f6e4f707312690a1d756e66696c74657265645f7472616e73616374696f6e5f74726163657318152003280b32252e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5472616365521b756e66696c74657265645472616e73616374696f6e54726163657312650a1b66696c74657265645f7472616e73616374696f6e5f747261636573182e2003280b32252e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5472616365521966696c74657265645472616e73616374696f6e547261636573124b0a22756e66696c74657265645f7472616e73616374696f6e5f74726163655f636f756e7418172001280d521f756e66696c74657265645472616e73616374696f6e5472616365436f756e7412470a2066696c74657265645f7472616e73616374696f6e5f74726163655f636f756e74182b2001280d521d66696c74657265645472616e73616374696f6e5472616365436f756e7412520a26756e66696c74657265645f65786563757465645f696e7075745f616374696f6e5f636f756e7418182001280d5222756e66696c74657265644578656375746564496e707574416374696f6e436f756e74124e0a2466696c74657265645f65786563757465645f696e7075745f616374696f6e5f636f756e74182c2001280d522066696c74657265644578656375746564496e707574416374696f6e436f756e7412520a26756e66696c74657265645f65786563757465645f746f74616c5f616374696f6e5f636f756e7418192001280d5222756e66696c74657265644578656375746564546f74616c416374696f6e436f756e74124e0a2466696c74657265645f65786563757465645f746f74616c5f616374696f6e5f636f756e74182d2001280d522066696c74657265644578656375746564546f74616c416374696f6e436f756e74122a0a11626c6f636b5f7369676e696e675f6b6579180e20012809520f626c6f636b5369676e696e674b657912530a126163746976655f7363686564756c655f7631180a2001280b32252e73662e616e74656c6f70652e747970652e76312e50726f64756365725363686564756c6552106163746976655363686564756c65563112720a2076616c69645f626c6f636b5f7369676e696e675f617574686f726974795f7632181e2001280b322a2e73662e616e74656c6f70652e747970652e76312e426c6f636b5369676e696e67417574686f72697479521c76616c6964426c6f636b5369676e696e67417574686f726974795632125c0a126163746976655f7363686564756c655f7632181f2001280b322e2e73662e616e74656c6f70652e747970652e76312e50726f6475636572417574686f726974795363686564756c6552106163746976655363686564756c655632122b0a1166696c746572696e675f6170706c696564182820012808521066696c746572696e674170706c69656412410a1d66696c746572696e675f696e636c7564655f66696c7465725f65787072182920012809521a66696c746572696e67496e636c75646546696c7465724578707212410a1d66696c746572696e675f6578636c7564655f66696c7465725f65787072182a20012809521a66696c746572696e674578636c75646546696c74657245787072125d0a2c66696c746572696e675f73797374656d5f616374696f6e735f696e636c7564655f66696c7465725f65787072183220012809522766696c746572696e6753797374656d416374696f6e73496e636c75646546696c746572457870724a04081210132284030a0d426c6f636b5769746852656673120e0a0269641801200128095202696412300a05626c6f636b18022001280b321a2e73662e616e74656c6f70652e747970652e76312e426c6f636b5205626c6f636b12600a19696d706c696369745f7472616e73616374696f6e5f7265667318032001280b32242e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e526566735217696d706c696369745472616e73616374696f6e52656673124f0a107472616e73616374696f6e5f7265667318042001280b32242e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e52656673520f7472616e73616374696f6e52656673125a0a167472616e73616374696f6e5f74726163655f7265667318052001280b32242e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5265667352147472616e73616374696f6e54726163655265667312220a0c697272657665727369626c65180620012808520c697272657665727369626c6522290a0f5472616e73616374696f6e5265667312160a0668617368657318012003280c520668617368657322480a1941637469766174656450726f746f636f6c4665617475726573122b0a1170726f746f636f6c5f666561747572657318012003280c521070726f746f636f6c46656174757265732281020a1750656e64696e6750726f64756365725363686564756c6512280a107363686564756c655f6c69625f6e756d18012001280d520e7363686564756c654c69624e756d12230a0d7363686564756c655f6861736818022001280c520c7363686564756c654861736812460a0b7363686564756c655f763118032001280b32252e73662e616e74656c6f70652e747970652e76312e50726f64756365725363686564756c65520a7363686564756c655631124f0a0b7363686564756c655f763218042001280b322e2e73662e616e74656c6f70652e747970652e76312e50726f6475636572417574686f726974795363686564756c65520a7363686564756c655632226c0a1050726f64756365725363686564756c6512180a0776657273696f6e18012001280d520776657273696f6e123e0a0970726f64756365727318022003280b32202e73662e616e74656c6f70652e747970652e76312e50726f64756365724b6579520970726f647563657273225c0a0b50726f64756365724b657912210a0c6163636f756e745f6e616d65180120012809520b6163636f756e744e616d65122a0a11626c6f636b5f7369676e696e675f6b6579180220012809520f626c6f636b5369676e696e674b6579227b0a1950726f6475636572417574686f726974795363686564756c6512180a0776657273696f6e18012001280d520776657273696f6e12440a0970726f64756365727318022003280b32262e73662e616e74656c6f70652e747970652e76312e50726f6475636572417574686f72697479520970726f647563657273229a010a1150726f6475636572417574686f7269747912210a0c6163636f756e745f6e616d65180120012809520b6163636f756e744e616d6512620a17626c6f636b5f7369676e696e675f617574686f7269747918022001280b322a2e73662e616e74656c6f70652e747970652e76312e426c6f636b5369676e696e67417574686f726974795215626c6f636b5369676e696e67417574686f7269747922620a15426c6f636b5369676e696e67417574686f72697479123e0a02763018012001280b322c2e73662e616e74656c6f70652e747970652e76312e426c6f636b5369676e696e67417574686f72697479563048005202763042090a0776617269616e74226b0a17426c6f636b5369676e696e67417574686f726974795630121c0a097468726573686f6c6418012001280d52097468726573686f6c6412320a046b65797318022003280b321e2e73662e616e74656c6f70652e747970652e76312e4b657957656967687452046b65797322530a0f426c6f636b526f6f744d65726b6c65121d0a0a6e6f64655f636f756e7418012001280d52096e6f6465436f756e7412210a0c6163746976655f6e6f64657318022003280c520b6163746976654e6f64657322630a1650726f6475636572546f4c61737450726f647563656412120a046e616d6518012001280952046e616d6512350a176c6173745f626c6f636b5f6e756d5f70726f647563656418022001280d52146c617374426c6f636b4e756d50726f647563656422650a1850726f6475636572546f4c617374496d706c69656449524212120a046e616d6518012001280952046e616d6512350a176c6173745f626c6f636b5f6e756d5f70726f647563656418022001280d52146c617374426c6f636b4e756d50726f647563656422b0020a125472616e73616374696f6e52656365697074120e0a0269641804200128095202696412140a05696e6465781806200128045205696e646578123e0a0673746174757318012001280e32262e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e537461747573520673746174757312350a176370755f75736167655f6d6963726f5f7365636f6e647318022001280d521463707555736167654d6963726f5365636f6e647312260a0f6e65745f75736167655f776f72647318032001280d520d6e65745573616765576f72647312550a127061636b65645f7472616e73616374696f6e18052001280b32262e73662e616e74656c6f70652e747970652e76312e5061636b65645472616e73616374696f6e52117061636b65645472616e73616374696f6e22bd010a115061636b65645472616e73616374696f6e121e0a0a7369676e617475726573180120032809520a7369676e61747572657312200a0b636f6d7072657373696f6e18022001280d520b636f6d7072657373696f6e12370a187061636b65645f636f6e746578745f667265655f6461746118032001280c52157061636b6564436f6e746578744672656544617461122d0a127061636b65645f7472616e73616374696f6e18042001280c52117061636b65645472616e73616374696f6e22b6030a0b426c6f636b48656164657212380a0974696d657374616d7018032001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d70520974696d657374616d70121a0a0870726f6475636572180420012809520870726f6475636572121c0a09636f6e6669726d656418052001280d5209636f6e6669726d6564121a0a0870726576696f7573180620012809520870726576696f7573122b0a117472616e73616374696f6e5f6d726f6f7418072001280c52107472616e73616374696f6e4d726f6f7412210a0c616374696f6e5f6d726f6f7418082001280c520b616374696f6e4d726f6f7412290a107363686564756c655f76657273696f6e18092001280d520f7363686564756c6556657273696f6e124b0a116865616465725f657874656e73696f6e73180b2003280b321e2e73662e616e74656c6f70652e747970652e76312e457874656e73696f6e5210686561646572457874656e73696f6e73124f0a106e65775f70726f6475636572735f7631180a2001280b32252e73662e616e74656c6f70652e747970652e76312e50726f64756365725363686564756c65520e6e657750726f647563657273563122fb090a105472616e73616374696f6e4576656e74120e0a0269641801200128095202696412190a08626c6f636b5f69641802200128095207626c6f636b4964121b0a09626c6f636b5f6e756d18032001280d5208626c6f636b4e756d12220a0c697272657665727369626c65180420012808520c697272657665727369626c6512640a11696e7465726e616c5f6164646974696f6e18052001280b32352e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e4576656e742e4164646564496e7465726e616c6c7948005210696e7465726e616c4164646974696f6e12490a086164646974696f6e18062001280b322b2e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e4576656e742e4164646564480052086164646974696f6e124e0a09657865637574696f6e18072001280b322e2e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e4576656e742e457865637574656448005209657865637574696f6e125e0a0f647472785f7363686564756c696e6718082001280b32332e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e4576656e742e447472785363686564756c65644800520e647472785363686564756c696e6712610a11647472785f63616e63656c6c6174696f6e18092001280b32322e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e4576656e742e4474727843616e63656c6564480052106474727843616e63656c6c6174696f6e1a5b0a0f4164646564496e7465726e616c6c7912480a0b7472616e73616374696f6e18012001280b32262e73662e616e74656c6f70652e747970652e76312e5369676e65645472616e73616374696f6e520b7472616e73616374696f6e1ad6010a05416464656412410a077265636569707418012001280b32272e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5265636569707452077265636569707412480a0b7472616e73616374696f6e18022001280b32262e73662e616e74656c6f70652e747970652e76312e5369676e65645472616e73616374696f6e520b7472616e73616374696f6e12400a0b7075626c69635f6b65797318032001280b321f2e73662e616e74656c6f70652e747970652e76312e5075626c69634b657973520a7075626c69634b6579731a8b010a084578656375746564123b0a05747261636518012001280b32252e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e54726163655205747261636512420a0b626c6f636b48656164657218022001280b32202e73662e616e74656c6f70652e747970652e76312e426c6f636b486561646572520b626c6f636b4865616465721a98010a0d447472785363686564756c6564123d0a0a637265617465645f627918012001280b321e2e73662e616e74656c6f70652e747970652e76312e457874445472784f70520963726561746564427912480a0b7472616e73616374696f6e18022001280b32262e73662e616e74656c6f70652e747970652e76312e5369676e65645472616e73616374696f6e520b7472616e73616374696f6e1a4f0a0c4474727843616e63656c6564123f0a0b63616e63656c65645f627918012001280b321e2e73662e616e74656c6f70652e747970652e76312e457874445472784f70520a63616e63656c6564427942070a056576656e74222d0a0a5075626c69634b657973121f0a0b7075626c69635f6b657973180120032809520a7075626c69634b657973229d060a145472616e73616374696f6e4c6966656379636c65120e0a0269641801200128095202696412550a127472616e73616374696f6e5f73746174757318022001280e32262e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e53746174757352117472616e73616374696f6e53746174757312580a137472616e73616374696f6e5f7265636569707418242001280b32272e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5265636569707452127472616e73616374696f6e5265636569707412480a0b7472616e73616374696f6e180a2001280b32262e73662e616e74656c6f70652e747970652e76312e5369676e65645472616e73616374696f6e520b7472616e73616374696f6e121f0a0b7075626c69635f6b657973181320032809520a7075626c69634b657973124e0a0f657865637574696f6e5f7472616365180b2001280b32252e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5472616365520e657865637574696f6e547261636512560a16657865637574696f6e5f626c6f636b5f686561646572180c2001280b32202e73662e616e74656c6f70652e747970652e76312e426c6f636b4865616465725214657865637574696f6e426c6f636b486561646572123d0a0a637265617465645f627918142001280b321e2e73662e616e74656c6f70652e747970652e76312e457874445472784f705209637265617465644279123f0a0b63616e63656c65645f627918152001280b321e2e73662e616e74656c6f70652e747970652e76312e457874445472784f70520a63616e63656c6564427912330a156372656174696f6e5f697272657665727369626c6518212001280852146372656174696f6e497272657665727369626c6512350a16657865637574696f6e5f697272657665727369626c651822200128085215657865637574696f6e497272657665727369626c6512390a1863616e63656c6174696f6e5f697272657665727369626c65182320012808521763616e63656c6174696f6e497272657665727369626c654a04080d10134a040816102122a3010a115369676e65645472616e73616374696f6e12420a0b7472616e73616374696f6e18012001280b32202e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e520b7472616e73616374696f6e121e0a0a7369676e617475726573180220032809520a7369676e617475726573122a0a11636f6e746578745f667265655f6461746118032003280c520f636f6e7465787446726565446174612293020a0b5472616e73616374696f6e123e0a0668656164657218012001280b32262e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e4865616465725206686561646572124d0a14636f6e746578745f667265655f616374696f6e7318022003280b321b2e73662e616e74656c6f70652e747970652e76312e416374696f6e5212636f6e7465787446726565416374696f6e7312350a07616374696f6e7318032003280b321b2e73662e616e74656c6f70652e747970652e76312e416374696f6e5207616374696f6e73123e0a0a657874656e73696f6e7318042003280b321e2e73662e616e74656c6f70652e747970652e76312e457874656e73696f6e520a657874656e73696f6e732292020a115472616e73616374696f6e486561646572123a0a0a65787069726174696f6e18012001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d70520a65787069726174696f6e12220a0d7265665f626c6f636b5f6e756d18022001280d520b726566426c6f636b4e756d12280a107265665f626c6f636b5f70726566697818032001280d520e726566426c6f636b507265666978122d0a136d61785f6e65745f75736167655f776f72647318042001280d52106d61784e65745573616765576f72647312270a106d61785f6370755f75736167655f6d7318052001280d520d6d617843707555736167654d73121b0a0964656c61795f73656318062001280d520864656c61795365632288090a105472616e73616374696f6e5472616365120e0a02696418012001280952026964121b0a09626c6f636b5f6e756d1802200128045208626c6f636b4e756d12140a05696e646578181a200128045205696e64657812390a0a626c6f636b5f74696d6518032001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d705209626c6f636b54696d65122a0a1170726f64756365725f626c6f636b5f6964180420012809520f70726f6475636572426c6f636b496412470a077265636569707418052001280b322d2e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5265636569707448656164657252077265636569707412180a07656c61707365641806200128035207656c6170736564121b0a096e65745f757361676518072001280452086e65745573616765121c0a097363686564756c656418082001280852097363686564756c656412450a0d616374696f6e5f74726163657318092003280b32202e73662e616e74656c6f70652e747970652e76312e416374696f6e5472616365520c616374696f6e54726163657312510a116661696c65645f647472785f7472616365180a2001280b32252e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5472616365520f6661696c6564447472785472616365123c0a09657863657074696f6e180f2001280b321e2e73662e616e74656c6f70652e747970652e76312e457863657074696f6e5209657863657074696f6e121d0a0a6572726f725f636f646518102001280452096572726f72436f646512300a0664625f6f707318112003280b32192e73662e616e74656c6f70652e747970652e76312e44424f70520564624f707312360a08647472785f6f707318122003280b321b2e73662e616e74656c6f70652e747970652e76312e445472784f705207647472784f7073123f0a0b666561747572655f6f707318132003280b321e2e73662e616e74656c6f70652e747970652e76312e466561747572654f70520a666561747572654f707312360a087065726d5f6f707318142003280b321b2e73662e616e74656c6f70652e747970652e76312e5065726d4f7052077065726d4f707312330a0772616d5f6f707318152003280b321a2e73662e616e74656c6f70652e747970652e76312e52414d4f70520672616d4f707312520a1272616d5f636f7272656374696f6e5f6f707318162003280b32242e73662e616e74656c6f70652e747970652e76312e52414d436f7272656374696f6e4f70521072616d436f7272656374696f6e4f7073123c0a0a726c696d69745f6f707318172003280b321d2e73662e616e74656c6f70652e747970652e76312e526c696d69744f705209726c696d69744f707312390a097461626c655f6f707318182003280b321c2e73662e616e74656c6f70652e747970652e76312e5461626c654f7052087461626c654f7073124a0a0d6372656174696f6e5f7472656518192003280b32252e73662e616e74656c6f70652e747970652e76312e4372656174696f6e466c61744e6f6465520c6372656174696f6e547265654a04081e101f22b9010a185472616e73616374696f6e52656365697074486561646572123e0a0673746174757318012001280e32262e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e537461747573520673746174757312350a176370755f75736167655f6d6963726f5f7365636f6e647318022001280d521463707555736167654d6963726f5365636f6e647312260a0f6e65745f75736167655f776f72647318032001280d520d6e65745573616765576f72647322ba010a06416374696f6e12180a076163636f756e7418012001280952076163636f756e7412120a046e616d6518022001280952046e616d65124a0a0d617574686f72697a6174696f6e18032003280b32242e73662e616e74656c6f70652e747970652e76312e5065726d697373696f6e4c6576656c520d617574686f72697a6174696f6e121b0a096a736f6e5f6461746118042001280952086a736f6e4461746112190a087261775f6461746118052001280c520772617744617461228e080a0b416374696f6e5472616365121a0a087265636569766572180b2001280952087265636569766572123c0a077265636569707418012001280b32222e73662e616e74656c6f70652e747970652e76312e416374696f6e5265636569707452077265636569707412330a06616374696f6e18022001280b321b2e73662e616e74656c6f70652e747970652e76312e416374696f6e5206616374696f6e12210a0c636f6e746578745f66726565180320012808520b636f6e746578744672656512180a07656c61707365641804200128035207656c617073656412180a07636f6e736f6c651805200128095207636f6e736f6c6512250a0e7472616e73616374696f6e5f6964180620012809520d7472616e73616374696f6e4964121b0a09626c6f636b5f6e756d1807200128045208626c6f636b4e756d122a0a1170726f64756365725f626c6f636b5f6964180820012809520f70726f6475636572426c6f636b496412390a0a626c6f636b5f74696d6518092001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d705209626c6f636b54696d6512520a126163636f756e745f72616d5f64656c746173180a2003280b32242e73662e616e74656c6f70652e747970652e76312e4163636f756e7452414d44656c746152106163636f756e7452616d44656c74617312280a107261775f72657475726e5f76616c756518292001280c520e72617752657475726e56616c7565122a0a116a736f6e5f72657475726e5f76616c7565182a20012809520f6a736f6e52657475726e56616c7565123c0a09657863657074696f6e180f2001280b321e2e73662e616e74656c6f70652e747970652e76312e457863657074696f6e5209657863657074696f6e121d0a0a6572726f725f636f646518142001280452096572726f72436f646512250a0e616374696f6e5f6f7264696e616c18102001280d520d616374696f6e4f7264696e616c12340a1663726561746f725f616374696f6e5f6f7264696e616c18112001280d521463726561746f72416374696f6e4f7264696e616c125a0a2a636c6f736573745f756e6e6f7469666965645f616e636573746f725f616374696f6e5f6f7264696e616c18122001280d5226636c6f73657374556e6e6f746966696564416e636573746f72416374696f6e4f7264696e616c12270a0f657865637574696f6e5f696e64657818132001280d520e657865637574696f6e496e646578122b0a1166696c746572696e675f6d617463686564181e20012808521066696c746572696e674d61746368656412520a2666696c746572696e675f6d6174636865645f73797374656d5f616374696f6e5f66696c746572181f20012808522266696c746572696e674d61746368656453797374656d416374696f6e46696c7465724a040828102922a1020a0d416374696f6e52656365697074121a0a0872656365697665721801200128095208726563656976657212160a06646967657374180220012809520664696765737412270a0f676c6f62616c5f73657175656e6365180320012804520e676c6f62616c53657175656e636512460a0d617574685f73657175656e636518042003280b32212e73662e616e74656c6f70652e747970652e76312e4175746853657175656e6365520c6175746853657175656e636512230a0d726563765f73657175656e6365180520012804520c7265637653657175656e636512230a0d636f64655f73657175656e6365180620012804520c636f646553657175656e636512210a0c6162695f73657175656e6365180720012804520b61626953657175656e6365224d0a0c4175746853657175656e636512210a0c6163636f756e745f6e616d65180120012809520b6163636f756e744e616d65121a0a0873657175656e6365180220012804520873657175656e636522410a0f4163636f756e7452414d44656c746112180a076163636f756e7418012001280952076163636f756e7412140a0564656c7461180220012803520564656c7461223e0a0c4163636f756e7444656c746112180a076163636f756e7418012001280952076163636f756e7412140a0564656c7461180220012803520564656c746122330a09457874656e73696f6e12120a047479706518012001280d52047479706512120a046461746118022001280c520464617461228a020a055472784f7012420a096f7065726174696f6e18012001280e32242e73662e616e74656c6f70652e747970652e76312e5472784f702e4f7065726174696f6e52096f7065726174696f6e12120a046e616d6518022001280952046e616d6512250a0e7472616e73616374696f6e5f6964180320012809520d7472616e73616374696f6e496412480a0b7472616e73616374696f6e18042001280b32262e73662e616e74656c6f70652e747970652e76312e5369676e65645472616e73616374696f6e520b7472616e73616374696f6e22380a094f7065726174696f6e12150a114f5045524154494f4e5f554e4b4e4f574e100012140a104f5045524154494f4e5f435245415445100122f4030a0444424f7012410a096f7065726174696f6e18012001280e32232e73662e616e74656c6f70652e747970652e76312e44424f702e4f7065726174696f6e52096f7065726174696f6e12210a0c616374696f6e5f696e64657818022001280d520b616374696f6e496e64657812120a04636f64651803200128095204636f646512140a0573636f7065180420012809520573636f7065121d0a0a7461626c655f6e616d6518052001280952097461626c654e616d65121f0a0b7072696d6172795f6b6579180620012809520a7072696d6172794b6579121b0a096f6c645f706179657218072001280952086f6c645061796572121b0a096e65775f706179657218082001280952086e6577506179657212190a086f6c645f6461746118092001280c52076f6c644461746112190a086e65775f64617461180a2001280c52076e65774461746112220a0d6f6c645f646174615f6a736f6e180b20012809520b6f6c64446174614a736f6e12220a0d6e65775f646174615f6a736f6e180c20012809520b6e6577446174614a736f6e22640a094f7065726174696f6e12150a114f5045524154494f4e5f554e4b4e4f574e100012140a104f5045524154494f4e5f494e53455254100112140a104f5045524154494f4e5f555044415445100212140a104f5045524154494f4e5f52454d4f5645100322e20c0a0552414d4f7012420a096f7065726174696f6e18012001280e32242e73662e616e74656c6f70652e747970652e76312e52414d4f702e4f7065726174696f6e52096f7065726174696f6e12210a0c616374696f6e5f696e64657818022001280d520b616374696f6e496e64657812140a0570617965721803200128095205706179657212140a0564656c7461180420012803520564656c746112140a0575736167651805200128045205757361676512420a096e616d65737061636518062001280e32242e73662e616e74656c6f70652e747970652e76312e52414d4f702e4e616d65737061636552096e616d65737061636512390a06616374696f6e18072001280e32212e73662e616e74656c6f70652e747970652e76312e52414d4f702e416374696f6e5206616374696f6e121d0a0a756e697175655f6b65791808200128095209756e697175654b65792282070a094f7065726174696f6e12150a114f5045524154494f4e5f554e4b4e4f574e1000121a0a164f5045524154494f4e5f4352454154455f5441424c451001121e0a1a4f5045524154494f4e5f44454645525245445f5452585f414444100212210a1d4f5045524154494f4e5f44454645525245445f5452585f43414e43454c100312210a1d4f5045524154494f4e5f44454645525245445f5452585f505553484544100412290a254f5045524154494f4e5f44454645525245445f5452585f52414d5f434f5252454354494f4e100512220a1e4f5045524154494f4e5f44454645525245445f5452585f52454d4f564544100612180a144f5045524154494f4e5f44454c45544541555448100712160a124f5045524154494f4e5f4c494e4b41555448100812180a144f5045524154494f4e5f4e45574143434f554e541009121f0a1b4f5045524154494f4e5f5052494d4152595f494e4445585f414444100a12220a1e4f5045524154494f4e5f5052494d4152595f494e4445585f52454d4f5645100b12220a1e4f5045524154494f4e5f5052494d4152595f494e4445585f555044415445100c12300a2c4f5045524154494f4e5f5052494d4152595f494e4445585f5550444154455f4144445f4e45575f5041594552100d12330a2f4f5045524154494f4e5f5052494d4152595f494e4445585f5550444154455f52454d4f56455f4f4c445f5041594552100e121a0a164f5045524154494f4e5f52454d4f56455f5441424c45100f12210a1d4f5045524154494f4e5f5345434f4e444152595f494e4445585f414444101012240a204f5045524154494f4e5f5345434f4e444152595f494e4445585f52454d4f5645101112320a2e4f5045524154494f4e5f5345434f4e444152595f494e4445585f5550444154455f4144445f4e45575f5041594552101212350a314f5045524154494f4e5f5345434f4e444152595f494e4445585f5550444154455f52454d4f56455f4f4c445f5041594552101312140a104f5045524154494f4e5f534554414249101412150a114f5045524154494f4e5f534554434f4445101512180a144f5045524154494f4e5f554e4c494e4b415554481016121f0a1b4f5045524154494f4e5f555044415445415554485f4352454154451017121f0a1b4f5045524154494f4e5f555044415445415554485f555044415445101812180a144f5045524154494f4e5f44455052454341544544101922fc010a094e616d65737061636512150a114e414d4553504143455f554e4b4e4f574e100012110a0d4e414d4553504143455f414249100112150a114e414d4553504143455f4143434f554e54100212120a0e4e414d4553504143455f41555448100312170a134e414d4553504143455f415554485f4c494e4b100412120a0e4e414d4553504143455f434f44451005121a0a164e414d4553504143455f44454645525245445f5452581006121d0a194e414d4553504143455f5345434f4e444152595f494e444558100712130a0f4e414d4553504143455f5441424c45100812170a134e414d4553504143455f5441424c455f524f5710092204080a100a228d010a06416374696f6e12120a0e414354494f4e5f554e4b4e4f574e1000120e0a0a414354494f4e5f414444100112110a0d414354494f4e5f43414e43454c100212150a11414354494f4e5f434f5252454354494f4e1003120f0a0b414354494f4e5f50555348100412110a0d414354494f4e5f52454d4f5645100512110a0d414354494f4e5f55504441544510062281010a0f52414d436f7272656374696f6e4f7012230a0d636f7272656374696f6e5f6964180120012809520c636f7272656374696f6e4964121d0a0a756e697175655f6b65791802200128095209756e697175654b657912140a0570617965721803200128095205706179657212140a0564656c7461180420012803520564656c746122a1020a075461626c654f7012440a096f7065726174696f6e18012001280e32262e73662e616e74656c6f70652e747970652e76312e5461626c654f702e4f7065726174696f6e52096f7065726174696f6e12210a0c616374696f6e5f696e64657818022001280d520b616374696f6e496e64657812140a0570617965721803200128095205706179657212120a04636f64651804200128095204636f646512140a0573636f7065180520012809520573636f7065121d0a0a7461626c655f6e616d6518062001280952097461626c654e616d65224e0a094f7065726174696f6e12150a114f5045524154494f4e5f554e4b4e4f574e100012140a104f5045524154494f4e5f494e53455254100112140a104f5045524154494f4e5f52454d4f5645100222d1040a06445472784f7012430a096f7065726174696f6e18012001280e32252e73662e616e74656c6f70652e747970652e76312e445472784f702e4f7065726174696f6e52096f7065726174696f6e12210a0c616374696f6e5f696e64657818022001280d520b616374696f6e496e64657812160a0673656e646572180320012809520673656e646572121b0a0973656e6465725f6964180420012809520873656e646572496412140a0570617965721805200128095205706179657212210a0c7075626c69736865645f6174180620012809520b7075626c69736865644174121f0a0b64656c61795f756e74696c180720012809520a64656c6179556e74696c12230a0d65787069726174696f6e5f6174180820012809520c65787069726174696f6e417412250a0e7472616e73616374696f6e5f6964180920012809520d7472616e73616374696f6e496412480a0b7472616e73616374696f6e180a2001280b32262e73662e616e74656c6f70652e747970652e76312e5369676e65645472616e73616374696f6e520b7472616e73616374696f6e22b9010a094f7065726174696f6e12150a114f5045524154494f4e5f554e4b4e4f574e100012140a104f5045524154494f4e5f435245415445100112190a154f5045524154494f4e5f505553485f435245415445100212140a104f5045524154494f4e5f4641494c4544100312140a104f5045524154494f4e5f43414e43454c1004121b0a174f5045524154494f4e5f4d4f444946595f43414e43454c1005121b0a174f5045524154494f4e5f4d4f444946595f435245415445100622e8010a09457874445472784f7012320a15736f757263655f7472616e73616374696f6e5f69641801200128095213736f757263655472616e73616374696f6e4964121b0a09626c6f636b5f6e756d1802200128045208626c6f636b4e756d12190a08626c6f636b5f69641803200128095207626c6f636b496412390a0a626c6f636b5f74696d6518042001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d705209626c6f636b54696d6512340a07647472785f6f7018052001280b321b2e73662e616e74656c6f70652e747970652e76312e445472784f705206647472784f7022e5010a09466561747572654f7012120a046b696e6418012001280952046b696e6412210a0c616374696f6e5f696e64657818022001280d520b616374696f6e496e64657812250a0e666561747572655f646967657374180320012809520d6665617475726544696765737412360a076665617475726518042001280b321c2e73662e616e74656c6f70652e747970652e76312e4665617475726552076665617475726522420a044b696e6412100a0c4b494e445f554e4b4e4f574e100012150a114b494e445f5052455f4143544956415445100112110a0d4b494e445f41435449564154451002227a0a104372656174696f6e466c61744e6f646512300a1463726561746f725f616374696f6e5f696e646578180120012805521263726561746f72416374696f6e496e64657812340a16657865637574696f6e5f616374696f6e5f696e64657818022001280d5214657865637574696f6e416374696f6e496e64657822da020a065065726d4f7012430a096f7065726174696f6e18012001280e32252e73662e616e74656c6f70652e747970652e76312e5065726d4f702e4f7065726174696f6e52096f7065726174696f6e12210a0c616374696f6e5f696e64657818022001280d520b616374696f6e496e64657812400a086f6c645f7065726d18082001280b32252e73662e616e74656c6f70652e747970652e76312e5065726d697373696f6e4f626a65637452076f6c645065726d12400a086e65775f7065726d18092001280b32252e73662e616e74656c6f70652e747970652e76312e5065726d697373696f6e4f626a65637452076e65775065726d22640a094f7065726174696f6e12150a114f5045524154494f4e5f554e4b4e4f574e100012140a104f5045524154494f4e5f494e53455254100112140a104f5045524154494f4e5f555044415445100212140a104f5045524154494f4e5f52454d4f5645100322e6010a105065726d697373696f6e4f626a656374120e0a026964180a2001280452026964121b0a09706172656e745f6964180b200128045208706172656e74496412140a056f776e657218012001280952056f776e657212120a046e616d6518022001280952046e616d65123d0a0c6c6173745f7570646174656418032001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d70520b6c61737455706461746564123c0a09617574686f7269747918042001280b321e2e73662e616e74656c6f70652e747970652e76312e417574686f726974795209617574686f72697479227d0a0a5065726d697373696f6e12120a046e616d6518012001280952046e616d6512160a06706172656e741802200128095206706172656e7412430a0d72657175697265645f6175746818032001280b321e2e73662e616e74656c6f70652e747970652e76312e417574686f72697479520c72657175697265644175746822dc010a09417574686f72697479121c0a097468726573686f6c6418012001280d52097468726573686f6c6412320a046b65797318022003280b321e2e73662e616e74656c6f70652e747970652e76312e4b657957656967687452046b65797312460a086163636f756e747318032003280b322a2e73662e616e74656c6f70652e747970652e76312e5065726d697373696f6e4c6576656c57656967687452086163636f756e747312350a05776169747318042003280b321f2e73662e616e74656c6f70652e747970652e76312e576169745765696768745205776169747322420a094b6579576569676874121d0a0a7075626c69635f6b657918012001280952097075626c69634b657912160a0677656967687418022001280d520677656967687422470a0f5065726d697373696f6e4c6576656c12140a056163746f7218012001280952056163746f72121e0a0a7065726d697373696f6e180220012809520a7065726d697373696f6e22750a155065726d697373696f6e4c6576656c57656967687412440a0a7065726d697373696f6e18012001280b32242e73662e616e74656c6f70652e747970652e76312e5065726d697373696f6e4c6576656c520a7065726d697373696f6e12160a0677656967687418022001280d5206776569676874223f0a0a5761697457656967687412190a08776169745f73656318012001280d52077761697453656312160a0677656967687418022001280d520677656967687422c3030a08526c696d69744f7012450a096f7065726174696f6e18012001280e32272e73662e616e74656c6f70652e747970652e76312e526c696d69744f702e4f7065726174696f6e52096f7065726174696f6e12380a05737461746518022001280b32202e73662e616e74656c6f70652e747970652e76312e526c696d69745374617465480052057374617465123b0a06636f6e66696718032001280b32212e73662e616e74656c6f70652e747970652e76312e526c696d6974436f6e66696748005206636f6e66696712510a0e6163636f756e745f6c696d69747318042001280b32282e73662e616e74656c6f70652e747970652e76312e526c696d69744163636f756e744c696d6974734800520d6163636f756e744c696d697473124e0a0d6163636f756e745f757361676518052001280b32272e73662e616e74656c6f70652e747970652e76312e526c696d69744163636f756e7455736167654800520c6163636f756e745573616765224e0a094f7065726174696f6e12150a114f5045524154494f4e5f554e4b4e4f574e100012140a104f5045524154494f4e5f494e53455254100112140a104f5045524154494f4e5f555044415445100242060a046b696e6422f5030a0b526c696d69745374617465125c0a17617665726167655f626c6f636b5f6e65745f757361676518012001280b32252e73662e616e74656c6f70652e747970652e76312e5573616765416363756d756c61746f72521461766572616765426c6f636b4e65745573616765125c0a17617665726167655f626c6f636b5f6370755f757361676518022001280b32252e73662e616e74656c6f70652e747970652e76312e5573616765416363756d756c61746f72521461766572616765426c6f636b4370755573616765122a0a1170656e64696e675f6e65745f7573616765180320012804520f70656e64696e674e65745573616765122a0a1170656e64696e675f6370755f7573616765180420012804520f70656e64696e67437075557361676512280a10746f74616c5f6e65745f776569676874180520012804520e746f74616c4e657457656967687412280a10746f74616c5f6370755f776569676874180620012804520e746f74616c43707557656967687412260a0f746f74616c5f72616d5f6279746573180720012804520d746f74616c52616d4279746573122a0a117669727475616c5f6e65745f6c696d6974180820012804520f7669727475616c4e65744c696d6974122a0a117669727475616c5f6370755f6c696d6974180920012804520f7669727475616c4370754c696d697422dc020a0c526c696d6974436f6e666967125d0a146370755f6c696d69745f706172616d657465727318012001280b322b2e73662e616e74656c6f70652e747970652e76312e456c61737469634c696d6974506172616d657465727352126370754c696d6974506172616d6574657273125d0a146e65745f6c696d69745f706172616d657465727318022001280b322b2e73662e616e74656c6f70652e747970652e76312e456c61737469634c696d6974506172616d657465727352126e65744c696d6974506172616d657465727312460a206163636f756e745f6370755f75736167655f617665726167655f77696e646f7718032001280d521c6163636f756e7443707555736167654176657261676557696e646f7712460a206163636f756e745f6e65745f75736167655f617665726167655f77696e646f7718042001280d521c6163636f756e744e657455736167654176657261676557696e646f7722a0010a13526c696d69744163636f756e744c696d69747312140a056f776e657218012001280952056f776e657212180a0770656e64696e67180220012808520770656e64696e67121d0a0a6e65745f77656967687418032001280352096e6574576569676874121d0a0a6370755f7765696768741804200128035209637075576569676874121b0a0972616d5f6279746573180520012803520872616d427974657322cf010a12526c696d69744163636f756e74557361676512140a056f776e657218012001280952056f776e657212420a096e65745f757361676518022001280b32252e73662e616e74656c6f70652e747970652e76312e5573616765416363756d756c61746f7252086e6574557361676512420a096370755f757361676518032001280b32252e73662e616e74656c6f70652e747970652e76312e5573616765416363756d756c61746f7252086370755573616765121b0a0972616d5f7573616765180420012804520872616d5573616765226c0a105573616765416363756d756c61746f7212210a0c6c6173745f6f7264696e616c18012001280d520b6c6173744f7264696e616c12190a0876616c75655f6578180220012804520776616c75654578121a0a08636f6e73756d65641803200128045208636f6e73756d65642281020a16456c61737469634c696d6974506172616d657465727312160a06746172676574180120012804520674617267657412100a036d617818022001280452036d617812180a07706572696f647318032001280d5207706572696f647312250a0e6d61785f6d756c7469706c69657218042001280d520d6d61784d756c7469706c696572123f0a0d636f6e74726163745f7261746518052001280b321a2e73662e616e74656c6f70652e747970652e76312e526174696f520c636f6e747261637452617465123b0a0b657870616e645f7261746518062001280b321a2e73662e616e74656c6f70652e747970652e76312e526174696f520a657870616e645261746522470a05526174696f121c0a096e756d657261746f7218012001280452096e756d657261746f7212200a0b64656e6f6d696e61746f72180220012804520b64656e6f6d696e61746f7222ae040a09457863657074696f6e12120a04636f64651801200128055204636f646512120a046e616d6518022001280952046e616d6512180a076d65737361676518032001280952076d657373616765123f0a05737461636b18042003280b32292e73662e616e74656c6f70652e747970652e76312e457863657074696f6e2e4c6f674d6573736167655205737461636b1a7d0a0a4c6f674d65737361676512430a07636f6e7465787418012001280b32292e73662e616e74656c6f70652e747970652e76312e457863657074696f6e2e4c6f67436f6e746578745207636f6e7465787412160a06666f726d61741802200128095206666f726d617412120a046461746118042001280c5204646174611a9e020a0a4c6f67436f6e7465787412140a056c6576656c18012001280952056c6576656c12120a0466696c65180220012809520466696c6512120a046c696e6518032001280552046c696e6512160a066d6574686f6418042001280952066d6574686f64121a0a08686f73746e616d651805200128095208686f73746e616d65121f0a0b7468726561645f6e616d65180620012809520a7468726561644e616d6512380a0974696d657374616d7018072001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d70520974696d657374616d7012430a07636f6e7465787418082001280b32292e73662e616e74656c6f70652e747970652e76312e457863657074696f6e2e4c6f67436f6e746578745207636f6e7465787422e7020a074665617475726512250a0e666561747572655f646967657374180120012809520d6665617475726544696765737412640a177375626a6563746976655f7265737472696374696f6e7318022001280b322b2e73662e616e74656c6f70652e747970652e76312e5375626a6563746976655265737472696374696f6e7352167375626a6563746976655265737472696374696f6e73122d0a126465736372697074696f6e5f64696765737418032001280952116465736372697074696f6e44696765737412220a0c646570656e64656e63696573180420032809520c646570656e64656e6369657312320a1570726f746f636f6c5f666561747572655f74797065180520012809521370726f746f636f6c466561747572655479706512480a0d73706563696669636174696f6e18062003280b32222e73662e616e74656c6f70652e747970652e76312e53706563696669636174696f6e520d73706563696669636174696f6e22b2010a165375626a6563746976655265737472696374696f6e7312180a07656e61626c65641801200128085207656e61626c656412350a1670726561637469766174696f6e5f7265717569726564180220012808521570726561637469766174696f6e526571756972656412470a206561726c696573745f616c6c6f7765645f61637469766174696f6e5f74696d65180320012809521d6561726c69657374416c6c6f77656441637469766174696f6e54696d6522390a0d53706563696669636174696f6e12120a046e616d6518012001280952046e616d6512140a0576616c7565180220012809520576616c756522e2010a124163636f756e744372656174696f6e52656612180a076163636f756e7418012001280952076163636f756e7412180a0763726561746f72180220012809520763726561746f72121b0a09626c6f636b5f6e756d1803200128045208626c6f636b4e756d12190a08626c6f636b5f69641804200128095207626c6f636b496412390a0a626c6f636b5f74696d6518052001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d705209626c6f636b54696d6512250a0e7472616e73616374696f6e5f6964180620012809520d7472616e73616374696f6e496422c4010a0f4865616465724f6e6c79426c6f636b120e0a0269641801200128095202696412160a066e756d62657218022001280d52066e756d62657212380a0668656164657218042001280b32202e73662e616e74656c6f70652e747970652e76312e426c6f636b4865616465725206686561646572124f0a10626c6f636b726f6f745f6d65726b6c65180b2001280b32242e73662e616e74656c6f70652e747970652e76312e426c6f636b526f6f744d65726b6c65520f626c6f636b726f6f744d65726b6c652297010a1c5472616e73616374696f6e547261636557697468426c6f636b526566123b0a05747261636518012001280b32252e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e547261636552057472616365123a0a09626c6f636b5f72656618022001280b321d2e73662e616e74656c6f70652e747970652e76312e426c6f636b5265665208626c6f636b52656622360a08426c6f636b52656612120a046861736818012001280c52046861736812160a066e756d62657218022001280452066e756d6265722aba010a12426c6f636b5265766572736962696c697479121b0a17424c4f434b5245564552534942494c4954595f4e4f4e45100012210a1d424c4f434b5245564552534942494c4954595f52455645525349424c45100112230a1f424c4f434b5245564552534942494c4954595f495252455645525349424c451002121c0a18424c4f434b5245564552534942494c4954595f5354414c45100312210a1d424c4f434b5245564552534942494c4954595f4d415942455354414c4510042a8c020a115472616e73616374696f6e537461747573121a0a165452414e53414354494f4e5354415455535f4e4f4e451000121e0a1a5452414e53414354494f4e5354415455535f45584543555445441001121e0a1a5452414e53414354494f4e5354415455535f534f46544641494c1002121e0a1a5452414e53414354494f4e5354415455535f484152444641494c1003121d0a195452414e53414354494f4e5354415455535f44454c415945441004121d0a195452414e53414354494f4e5354415455535f455850495245441005121d0a195452414e53414354494f4e5354415455535f554e4b4e4f574e1006121e0a1a5452414e53414354494f4e5354415455535f43414e43454c4544100742545a526769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d616e74656c6f70652f74797065732f70622f73662f616e74656c6f70652f747970652f76313b7062616e74656c6f7065620670726f746f33", + }, + } +} From 510d954f44e75cb5cb42088c6c303e6e04a3e6ad Mon Sep 17 00:00:00 2001 From: arnaudberger Date: Wed, 24 Jan 2024 22:26:40 -0500 Subject: [PATCH 27/44] fixing compare-blocks for dummy blockchain --- cmd/tools/compare/tools_compare_blocks.go | 28 ++++++++++++++--------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/cmd/tools/compare/tools_compare_blocks.go b/cmd/tools/compare/tools_compare_blocks.go index 5b66daa..72eb4d2 100644 --- a/cmd/tools/compare/tools_compare_blocks.go +++ b/cmd/tools/compare/tools_compare_blocks.go @@ -139,12 +139,13 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm var bundleReadErr error var referenceBlockHashes []string var referenceBlocks map[string]*dynamicpb.Message + var referenceBlocksNum map[string]uint64 var currentBlocks map[string]*dynamicpb.Message wg.Add(1) go func() { defer wg.Done() - referenceBlockHashes, referenceBlocks, err = readBundle( + referenceBlockHashes, referenceBlocks, referenceBlocksNum, err = readBundle( ctx, filename, storeReference, @@ -163,7 +164,7 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm wg.Add(1) go func() { defer wg.Done() - _, currentBlocks, err = readBundle(ctx, + _, currentBlocks, _, err = readBundle(ctx, filename, storeCurrent, uint64(fileStartBlock), @@ -189,10 +190,9 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm defer wg.Done() referenceBlock := referenceBlocks[hash] currentBlock, existsInCurrent := currentBlocks[hash] - referenceBlockNum := referenceBlock.Get(referenceBlock.Descriptor().Fields().ByName("slot")).Uint() + referenceBlockNum := referenceBlocksNum[hash] var isDifferent bool - fmt.Println("Registry", registry) if existsInCurrent { var differences []string differences = Compare(referenceBlock, currentBlock, includeUnknownFields, registry) @@ -234,26 +234,31 @@ func readBundle( stopBlock uint64, warnAboutExtraBlocks *sync.Once, registry *fcproto.Registry, -) ([]string, map[string]*dynamicpb.Message, error) { +) ([]string, map[string]*dynamicpb.Message, map[string]uint64, error) { fileReader, err := store.OpenObject(ctx, filename) + + fmt.Println("store", store) + fmt.Println("fileReader", fileReader) + if err != nil { - return nil, nil, fmt.Errorf("creating reader: %w", err) + return nil, nil, nil, fmt.Errorf("creating reader: %w", err) } blockReader, err := bstream.NewDBinBlockReader(fileReader) if err != nil { - return nil, nil, fmt.Errorf("creating block reader: %w", err) + return nil, nil, nil, fmt.Errorf("creating block reader: %w", err) } var blockHashes []string blocksMap := make(map[string]*dynamicpb.Message) + blockNumMap := make(map[string]uint64) for { curBlock, err := blockReader.Read() if err == io.EOF { break } if err != nil { - return nil, nil, fmt.Errorf("reading blocks: %w", err) + return nil, nil, nil, fmt.Errorf("reading blocks: %w", err) } if curBlock.Number >= stopBlock { break @@ -268,13 +273,14 @@ func readBundle( curBlockPB, err := registry.Unmarshal(curBlock.Payload) if err != nil { - return nil, nil, fmt.Errorf("unmarshalling block: %w", err) + return nil, nil, nil, fmt.Errorf("unmarshalling block: %w", err) } blockHashes = append(blockHashes, curBlock.Id) + blockNumMap[curBlock.Id] = curBlock.Number blocksMap[curBlock.Id] = curBlockPB } - return blockHashes, blocksMap, nil + return blockHashes, blocksMap, blockNumMap, nil } type state struct { @@ -390,7 +396,7 @@ func Compare(reference proto.Message, current proto.Message, includeUnknownField referenceWriter.Close() currentWriter.Close() - panic("diff") + panic("boum" /*referenceMsg.Get(referenceMsg.Descriptor().Fields().ByName("slot")).Uint()*/) differences = append(differences, diff) } From d54f03159889c69c7c9770a099664e59ae29ef13 Mon Sep 17 00:00:00 2001 From: arnaudberger Date: Wed, 24 Jan 2024 22:30:22 -0500 Subject: [PATCH 28/44] Removing unecessary print --- cmd/tools/compare/tools_compare_blocks.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/cmd/tools/compare/tools_compare_blocks.go b/cmd/tools/compare/tools_compare_blocks.go index 72eb4d2..1a04f7d 100644 --- a/cmd/tools/compare/tools_compare_blocks.go +++ b/cmd/tools/compare/tools_compare_blocks.go @@ -237,9 +237,6 @@ func readBundle( ) ([]string, map[string]*dynamicpb.Message, map[string]uint64, error) { fileReader, err := store.OpenObject(ctx, filename) - fmt.Println("store", store) - fmt.Println("fileReader", fileReader) - if err != nil { return nil, nil, nil, fmt.Errorf("creating reader: %w", err) } From 71dcf2619e966206e3577d5a5d0091e506517fc4 Mon Sep 17 00:00:00 2001 From: arnaudberger Date: Thu, 25 Jan 2024 09:56:15 -0500 Subject: [PATCH 29/44] Removing file writers from compare blocks script --- cmd/tools/compare/tools_compare_blocks.go | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/cmd/tools/compare/tools_compare_blocks.go b/cmd/tools/compare/tools_compare_blocks.go index 1a04f7d..7d124b9 100644 --- a/cmd/tools/compare/tools_compare_blocks.go +++ b/cmd/tools/compare/tools_compare_blocks.go @@ -18,7 +18,6 @@ import ( "context" "fmt" "io" - "os" "reflect" "strconv" "sync" @@ -372,28 +371,6 @@ func Compare(reference proto.Message, current proto.Message, includeUnknownField //todo: manage better output off differences if diff := r.Diff(c).Render(); diff != "" { - referenceWriter, err := os.Create("/Users/arnaudberger/t/reference.json") - if err != nil { - fmt.Println(err) - } - currentWriter, err := os.Create("/Users/arnaudberger/t/current.json") - if err != nil { - fmt.Println(err) - } - - _, err = referenceWriter.WriteString(referenceAsJSON) - if err != nil { - fmt.Println(err) - } - _, err = currentWriter.WriteString(currentAsJSON) - if err != nil { - fmt.Println(err) - } - - referenceWriter.Close() - currentWriter.Close() - - panic("boum" /*referenceMsg.Get(referenceMsg.Descriptor().Fields().ByName("slot")).Uint()*/) differences = append(differences, diff) } From 316921b928b992e6af0e238fc5110b5516b1f316 Mon Sep 17 00:00:00 2001 From: arnaudberger Date: Fri, 26 Jan 2024 16:48:27 -0500 Subject: [PATCH 30/44] Add a bytesEncoding flag for compare blocks cmd --- cmd/tools/compare/tools_compare_blocks.go | 30 +++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/cmd/tools/compare/tools_compare_blocks.go b/cmd/tools/compare/tools_compare_blocks.go index 7d124b9..e68cf96 100644 --- a/cmd/tools/compare/tools_compare_blocks.go +++ b/cmd/tools/compare/tools_compare_blocks.go @@ -18,6 +18,7 @@ import ( "context" "fmt" "io" + "os" "reflect" "strconv" "sync" @@ -73,6 +74,7 @@ func NewToolsCompareBlocksCmd[B firecore.Block](chain *firecore.Chain[B]) *cobra flags := cmd.PersistentFlags() flags.Bool("diff", false, "When activated, difference is displayed for each block with a difference") + flags.String("bytes-encoding", "hex", "Encoding for bytes fields, either 'hex' or 'base58'") flags.Bool("include-unknown-fields", false, "When activated, the 'unknown fields' in the protobuf message will also be compared. These would not generate any difference when unmarshalled with the current protobuf definition.") flags.StringSlice("proto-paths", []string{""}, "Paths to proto files to use for dynamic decoding of blocks") @@ -84,6 +86,7 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm displayDiff := sflags.MustGetBool(cmd, "diff") includeUnknownFields := sflags.MustGetBool(cmd, "include-unknown-fields") protoPaths := sflags.MustGetStringSlice(cmd, "proto-paths") + bytesEncoding := sflags.MustGetString(cmd, "bytes-encoding") segmentSize := uint64(100000) warnAboutExtraBlocks := sync.Once{} ctx := cmd.Context() @@ -194,7 +197,7 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm var isDifferent bool if existsInCurrent { var differences []string - differences = Compare(referenceBlock, currentBlock, includeUnknownFields, registry) + differences = Compare(referenceBlock, currentBlock, includeUnknownFields, registry, bytesEncoding) isDifferent = len(differences) > 0 @@ -332,7 +335,7 @@ func (s *state) print() { fmt.Printf("✖ Segment %d - %s has %d different blocks and %d missing blocks (%d blocks counted)\n", s.segments[s.currentSegmentIdx].Start, endBlock, s.differencesFound, s.missingBlocks, s.totalBlocksCounted) } -func Compare(reference proto.Message, current proto.Message, includeUnknownFields bool, registry *fcproto.Registry) (differences []string) { +func Compare(reference proto.Message, current proto.Message, includeUnknownFields bool, registry *fcproto.Registry, bytesEncoding string) (differences []string) { if reference == nil && current == nil { return nil } @@ -355,6 +358,11 @@ func Compare(reference proto.Message, current proto.Message, includeUnknownField if !includeUnknownFields { opts = append(opts, json.WithoutUnknownFields()) } + + if bytesEncoding == "base58" { + opts = append(opts, json.WithBytesEncoderFunc(json.ToBase58)) + } + encoder := json.NewMarshaller(registry, opts...) referenceAsJSON, err := encoder.MarshalToString(reference) @@ -369,8 +377,26 @@ func Compare(reference proto.Message, current proto.Message, includeUnknownField c, err := jd.ReadJsonString(currentAsJSON) cli.NoError(err, "read JSON current") + //Get the r and the c and print them within a file for further analysis + + referenceWriter, err := os.Create("/Users/arnaudberger/t/reference.json") + if err != nil { + fmt.Println(err) + } + defer referenceWriter.Close() + currentWriter, err := os.Create("/Users/arnaudberger/t/current.json") + if err != nil { + fmt.Println(err) + } + + defer currentWriter.Close() + + referenceWriter.WriteString(referenceAsJSON) + currentWriter.WriteString(currentAsJSON) + //todo: manage better output off differences if diff := r.Diff(c).Render(); diff != "" { + differences = append(differences, diff) } From 7b9ac161e74fa1c3e4578bf6da3c364bb50bb443 Mon Sep 17 00:00:00 2001 From: billettc Date: Mon, 29 Jan 2024 15:45:39 -0500 Subject: [PATCH 31/44] Added optimistic multi-threaded block fetch --- blockpoller/fetcher.go | 2 +- blockpoller/init_test.go | 10 +- blockpoller/poller.go | 202 ++++++++++++++++++----- blockpoller/poller_test.go | 4 +- blockpoller/state_file_test.go | 2 +- go.mod | 3 +- go.sum | 2 + node-manager/boot/eos_jungle/config.ini | 2 +- node-manager/boot/eos_mainnet/config.ini | 2 +- 9 files changed, 179 insertions(+), 50 deletions(-) diff --git a/blockpoller/fetcher.go b/blockpoller/fetcher.go index 5bbaf77..abb3de4 100644 --- a/blockpoller/fetcher.go +++ b/blockpoller/fetcher.go @@ -7,5 +7,5 @@ import ( ) type BlockFetcher interface { - Fetch(ctx context.Context, blkNum uint64) (*pbbstream.Block, error) + Fetch(ctx context.Context, blkNum uint64) (b *pbbstream.Block, skipped bool, err error) } diff --git a/blockpoller/init_test.go b/blockpoller/init_test.go index 4528af5..e7b1eab 100644 --- a/blockpoller/init_test.go +++ b/blockpoller/init_test.go @@ -47,13 +47,13 @@ func (b *TestBlockFetcher) PollingInterval() time.Duration { return 0 } -func (b *TestBlockFetcher) Fetch(_ context.Context, blkNum uint64) (*pbbstream.Block, error) { +func (b *TestBlockFetcher) Fetch(_ context.Context, blkNum uint64) (*pbbstream.Block, bool, error) { if len(b.blocks) == 0 { assert.Fail(b.t, fmt.Sprintf("should not have fetched block %d", blkNum)) } if b.idx >= uint64(len(b.blocks)) { - return nil, derr.NewFatalError(TestErrCompleteDone) + return nil, false, derr.NewFatalError(TestErrCompleteDone) } if blkNum != b.blocks[b.idx].expect.Number { @@ -62,12 +62,12 @@ func (b *TestBlockFetcher) Fetch(_ context.Context, blkNum uint64) (*pbbstream.B blkToSend := b.blocks[b.idx].send b.idx++ - return blkToSend, nil + return blkToSend, false, nil } func (b *TestBlockFetcher) check(t *testing.T) { t.Helper() - require.Equal(b.t, uint64(len(b.blocks)), b.idx, "we should have fetched all %d blocks, only fired %d blocks", len(b.blocks), b.idx) + require.Equal(b.t, uint64(len(b.blocks)), b.idx, "we should have fetched all %d optimisticlyPolledBlocks, only fired %d optimisticlyPolledBlocks", len(b.blocks), b.idx) } var _ BlockHandler = &TestBlockFinalizer{} @@ -108,7 +108,7 @@ func (t *TestBlockFinalizer) Handle(blk *pbbstream.Block) error { func (b *TestBlockFinalizer) check(t *testing.T) { t.Helper() - require.Equal(b.t, uint64(len(b.fireBlocks)), b.idx, "we should have fired all %d blocks, only fired %d blocks", len(b.fireBlocks), b.idx) + require.Equal(b.t, uint64(len(b.fireBlocks)), b.idx, "we should have fired all %d optimisticlyPolledBlocks, only fired %d optimisticlyPolledBlocks", len(b.fireBlocks), b.idx) } var _ BlockHandler = &TestNoopBlockFinalizer{} diff --git a/blockpoller/poller.go b/blockpoller/poller.go index faf7e95..dffa1a5 100644 --- a/blockpoller/poller.go +++ b/blockpoller/poller.go @@ -8,6 +8,7 @@ import ( "github.com/streamingfast/bstream/forkable" pbbstream "github.com/streamingfast/bstream/pb/sf/bstream/v1" "github.com/streamingfast/derr" + "github.com/streamingfast/dhammer" "github.com/streamingfast/firehose-core/internal/utils" "github.com/streamingfast/shutter" "go.uber.org/zap" @@ -35,6 +36,8 @@ type BlockPoller struct { forkDB *forkable.ForkDB logger *zap.Logger + + optimisticallyPolledBlocks map[uint64]*BlockItem } func New( @@ -59,37 +62,57 @@ func New( return b } -func (p *BlockPoller) Run(ctx context.Context, startBlockNum uint64) error { +func (p *BlockPoller) Run(ctx context.Context, startBlockNum uint64, numberOfBlockToFetch int) error { p.startBlockNumGate = startBlockNum p.logger.Info("starting poller", zap.Uint64("start_block_num", startBlockNum), + zap.Uint64("resolved_start_block_num", resolveStartBlockNum), ) p.blockHandler.Init() - startBlock, err := p.blockFetcher.Fetch(ctx, startBlockNum) - if err != nil { - return fmt.Errorf("unable to fetch start block %d: %w", startBlockNum, err) + + for { + startBlock, skip, err := p.blockFetcher.Fetch(ctx, startBlockNum) + if err != nil { + return fmt.Errorf("unable to fetch start block %d: %w", startBlockNum, err) + } + if skip { + resolveStartBlockNum++ + continue + } + return p.run(startBlock.AsRef(), numberOfBlockToFetch) } - return p.run(startBlock.AsRef()) } -func (p *BlockPoller) run(resolvedStartBlock bstream.BlockRef) (err error) { - +func (p *BlockPoller) run(resolvedStartBlock bstream.BlockRef, numberOfBlockToFetch int) (err error) { p.forkDB, resolvedStartBlock, err = initState(resolvedStartBlock, p.stateStorePath, p.ignoreCursor, p.logger) if err != nil { return fmt.Errorf("unable to initialize cursor: %w", err) } currentCursor := &cursor{state: ContinuousSegState, logger: p.logger} - blkIter := resolvedStartBlock.Num() + blockToFetch := resolvedStartBlock.Num() + var hashToFetch *string for { if p.IsTerminating() { p.logger.Info("block poller is terminating") } - blkIter, err = p.processBlock(currentCursor, blkIter) + p.logger.Info("about to fetch block", zap.Uint64("block_to_fetch", blockToFetch)) + var fetchedBlock *pbbstream.Block + if hashToFetch != nil { + fetchedBlock, err = p.fetchBlockWithHash(blockToFetch, *hashToFetch) + } else { + fetchedBlock, err = p.fetchBlock(blockToFetch, numberOfBlockToFetch) + } + + if err != nil { + return fmt.Errorf("unable to fetch block %d: %w", blockToFetch, err) + } + + blockToFetch, hashToFetch, err = p.processBlock(currentCursor, fetchedBlock) if err != nil { - return fmt.Errorf("unable to fetch block %d: %w", blkIter, err) + return fmt.Errorf("unable to fetch block %d: %w", blockToFetch, err) } if p.IsTerminating() { @@ -98,62 +121,160 @@ func (p *BlockPoller) run(resolvedStartBlock bstream.BlockRef) (err error) { } } -func (p *BlockPoller) processBlock(currentState *cursor, blkNum uint64) (uint64, error) { - if blkNum < p.forkDB.LIBNum() { - panic(fmt.Errorf("unexpected error block %d is below the current LIB num %d. There should be no re-org above the current LIB num", blkNum, p.forkDB.LIBNum())) +func (p *BlockPoller) processBlock(currentState *cursor, block *pbbstream.Block) (uint64, *string, error) { + p.logger.Info("processing block", zap.Stringer("block", block.AsRef()), zap.Uint64("lib_num", block.LibNum)) + if block.Number < p.forkDB.LIBNum() { + panic(fmt.Errorf("unexpected error block %d is below the current LIB num %d. There should be no re-org above the current LIB num", block.Number, p.forkDB.LIBNum())) } // On the first run, we will fetch the blk for the `startBlockRef`, since we have a `Ref` it stands // to reason that we may already have the block. We could potentially optimize this - blk, err := p.fetchBlock(blkNum) - if err != nil { - return 0, fmt.Errorf("unable to fetch block %d: %w", blkNum, err) - } - seenBlk, seenParent := p.forkDB.AddLink(blk.AsRef(), blk.ParentId, newBlock(blk)) + seenBlk, seenParent := p.forkDB.AddLink(block.AsRef(), block.ParentId, newBlock(block)) - currentState.addBlk(blk, seenBlk, seenParent) + currentState.addBlk(block, seenBlk, seenParent) blkCompleteSegNum := currentState.getBlkSegmentNum() - blocks, reachLib := p.forkDB.CompleteSegment(blkCompleteSegNum) + completeSegment, reachLib := p.forkDB.CompleteSegment(blkCompleteSegNum) p.logger.Debug("checked if block is complete segment", zap.Uint64("blk_num", blkCompleteSegNum.Num()), - zap.Int("segment_len", len(blocks)), + zap.Int("segment_len", len(completeSegment)), zap.Bool("reached_lib", reachLib), ) if reachLib { currentState.blkIsConnectedToLib() - err = p.fireCompleteSegment(blocks) + err := p.fireCompleteSegment(completeSegment) if err != nil { - return 0, fmt.Errorf("firing complete segment: %w", err) + return 0, nil, fmt.Errorf("firing complete segment: %w", err) } // since the block is linkable to the current lib // we can safely set the new lib to the current block's Lib // the assumption here is that teh Lib the Block we received from the block fetcher ir ALWAYS CORRECT - p.logger.Debug("setting lib", zap.Stringer("blk", blk.AsRef()), zap.Uint64("lib_num", blk.LibNum)) - p.forkDB.SetLIB(blk.AsRef(), blk.LibNum) + p.logger.Debug("setting lib", zap.Stringer("blk", block.AsRef()), zap.Uint64("lib_num", block.LibNum)) + p.forkDB.SetLIB(block.AsRef(), block.LibNum) p.forkDB.PurgeBeforeLIB(0) - err := p.saveState(blocks) + err = p.saveState(completeSegment) if err != nil { - return 0, fmt.Errorf("saving state: %w", err) + return 0, nil, fmt.Errorf("saving state: %w", err) } - return nextBlkInSeg(blocks), nil + nextBlockNum := nextBlkInSeg(completeSegment) + return nextBlockNum, nil, nil } currentState.blkIsNotConnectedToLib() - return prevBlkInSeg(blocks), nil + + prevBlockNum, prevBlockHash := prevBlockInSegment(completeSegment) + return prevBlockNum, prevBlockHash, nil } -func (p *BlockPoller) fetchBlock(blkNum uint64) (blk *pbbstream.Block, err error) { - var out *pbbstream.Block - err = derr.Retry(p.fetchBlockRetryCount, func(ctx context.Context) error { - out, err = p.blockFetcher.Fetch(ctx, blkNum) +type BlockItem struct { + blockNumber uint64 + block *pbbstream.Block + skipped bool +} + +func (p *BlockPoller) loadNextBlocks(blockNumber uint64, numberOfBlockToFetch int) error { + p.optimisticallyPolledBlocks = map[uint64]*BlockItem{} + + nailer := dhammer.NewNailer(10, func(ctx context.Context, blockToFetch uint64) (*BlockItem, error) { + var blockItem *BlockItem + err := derr.Retry(p.fetchBlockRetryCount, func(ctx context.Context) error { + b, skip, err := p.blockFetcher.Fetch(ctx, blockToFetch) + if err != nil { + return fmt.Errorf("unable to fetch block %d: %w", blockToFetch, err) + } + if skip { + blockItem = &BlockItem{ + blockNumber: blockToFetch, + block: nil, + skipped: true, + } + return nil + } + + blockItem = &BlockItem{ + blockNumber: blockToFetch, + block: b, + skipped: false, + } + return nil + + }) + if err != nil { - return fmt.Errorf("unable to fetch block %d: %w", blkNum, err) + return nil, fmt.Errorf("failed to fetch block with retries %d: %w", blockToFetch, err) + } + + return blockItem, err + }) + + ctx := context.Background() + nailer.Start(ctx) + + done := make(chan interface{}, 1) + go func() { + for blockItem := range nailer.Out { + p.optimisticallyPolledBlocks[blockItem.blockNumber] = blockItem + } + + close(done) + }() + + for i := 0; i < numberOfBlockToFetch; i++ { + b := blockNumber + uint64(i) + nailer.Push(ctx, b) + } + nailer.Close() + + <-done + + if nailer.Err() != nil { + return fmt.Errorf("failed optimistically fetch blocks starting at %d: %w", blockNumber, nailer.Err()) + } + + return nil +} + +func (p *BlockPoller) fetchBlock(blockNumber uint64, numberOfBlockToFetch int) (*pbbstream.Block, error) { + for { + blockItem, found := p.optimisticallyPolledBlocks[blockNumber] + if !found { + err := p.loadNextBlocks(blockNumber, numberOfBlockToFetch) + if err != nil { + return nil, fmt.Errorf("failed to load next blocks: %w", err) + } + continue //that will retry the current block after loading the more blocks + } + if blockItem.skipped { + blockNumber++ + continue + } + + p.logger.Info("block was optimistically polled", zap.Uint64("block_num", blockNumber)) + return blockItem.block, nil + } +} + +func (p *BlockPoller) fetchBlockWithHash(blkNum uint64, hash string) (*pbbstream.Block, error) { + _ = hash //todo: hash will be used to fetch block from cache + + p.optimisticallyPolledBlocks = map[uint64]*BlockItem{} + + var out *pbbstream.Block + var skipped bool + err := derr.Retry(p.fetchBlockRetryCount, func(ctx context.Context) error { + //todo: get block from cache + var fetchErr error + out, skipped, fetchErr = p.blockFetcher.Fetch(ctx, blkNum) + if fetchErr != nil { + return fmt.Errorf("unable to fetch block %d: %w", blkNum, fetchErr) + } + if skipped { + return nil } return nil }) @@ -162,6 +283,10 @@ func (p *BlockPoller) fetchBlock(blkNum uint64) (blk *pbbstream.Block, err error return nil, fmt.Errorf("failed to fetch block with retries %d: %w", blkNum, err) } + if skipped { + return nil, fmt.Errorf("block %d was skipped and sould not have been requested", blkNum) + } + if p.forceFinalityAfterBlocks != nil { utils.TweakBlockFinality(blk, *p.forceFinalityAfterBlocks) } @@ -198,14 +323,15 @@ func (p *BlockPoller) fire(blk *block) (bool, error) { func nextBlkInSeg(blocks []*forkable.Block) uint64 { if len(blocks) == 0 { - panic(fmt.Errorf("the blocks segments should never be empty")) + panic(fmt.Errorf("the optimisticlyPolledBlocks segments should never be empty")) } return blocks[len(blocks)-1].BlockNum + 1 } -func prevBlkInSeg(blocks []*forkable.Block) uint64 { +func prevBlockInSegment(blocks []*forkable.Block) (uint64, *string) { if len(blocks) == 0 { - panic(fmt.Errorf("the blocks segments should never be empty")) + panic(fmt.Errorf("the optimisticlyPolledBlocks segments should never be empty")) } - return blocks[0].Object.(*block).ParentNum + blockObject := blocks[0].Object.(*block) + return blockObject.ParentNum, &blockObject.ParentId } diff --git a/blockpoller/poller_test.go b/blockpoller/poller_test.go index 8fff155..720d010 100644 --- a/blockpoller/poller_test.go +++ b/blockpoller/poller_test.go @@ -121,7 +121,7 @@ func TestForkHandler_run(t *testing.T) { }, }, { - name: "with skipping blocks", + name: "with skipping optimisticlyPolledBlocks", startBlock: blk("100a", "99a", 100).AsRef(), blocks: []*TestBlock{ tb("100a", "99a", 100), @@ -157,7 +157,7 @@ func TestForkHandler_run(t *testing.T) { f := New(blockFetcher, blockFinalizer) f.forkDB = forkable.NewForkDB() - err := f.run(tt.startBlock) + err := f.run(tt.startBlock, 1) if !errors.Is(err, TestErrCompleteDone) { require.NoError(t, err) } diff --git a/blockpoller/state_file_test.go b/blockpoller/state_file_test.go index 3e410c8..804e99d 100644 --- a/blockpoller/state_file_test.go +++ b/blockpoller/state_file_test.go @@ -33,7 +33,7 @@ func TestFireBlockFinalizer_state(t *testing.T) { fk.AddLink(bstream.NewBlockRef("106a", 106), "105a", &block{Block: blk("106a", "105a", 101)}) fk.AddLink(bstream.NewBlockRef("105a", 105), "104a", &block{Block: blk("105a", "104a", 101)}) expectedBlocks, reachedLib := fk.CompleteSegment(blk("105a", "104a", 101).AsRef()) - // simulate firing the blocks + // simulate firing the optimisticlyPolledBlocks for _, blk := range expectedBlocks { blk.Object.(*block).fired = true } diff --git a/go.mod b/go.mod index 1ef6b96..5ecf49b 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,8 @@ require ( github.com/streamingfast/dauth v0.0.0-20231120142446-843f4e045cc2 github.com/streamingfast/dbin v0.9.1-0.20231117225723-59790c798e2c github.com/streamingfast/derr v0.0.0-20230515163924-8570aaa43fe1 - github.com/streamingfast/dgrpc v0.0.0-20230929132851-893fc52687fa + github.com/streamingfast/dgrpc v0.0.0-20240119162453-69517bcc1a7f + github.com/streamingfast/dhammer v0.0.0-20230125192823-c34bbd561bd4 github.com/streamingfast/dmetering v0.0.0-20231120142327-a3405f0eed83 github.com/streamingfast/dmetrics v0.0.0-20230919161904-206fa8ebd545 github.com/streamingfast/dstore v0.1.1-0.20230620124109-3924b3b36c77 diff --git a/go.sum b/go.sum index 89e4959..98faabf 100644 --- a/go.sum +++ b/go.sum @@ -590,6 +590,8 @@ github.com/streamingfast/derr v0.0.0-20230515163924-8570aaa43fe1 h1:xJB7rXnOHLes github.com/streamingfast/derr v0.0.0-20230515163924-8570aaa43fe1/go.mod h1:QSm/AfaDsE0k1xBYi0lW580YJ/WDV/FKZI628tkZR0Y= github.com/streamingfast/dgrpc v0.0.0-20230929132851-893fc52687fa h1:L/Ipge5pkZtyHucT7c8F/PiCitiNqQxjoUuxyzWKZew= github.com/streamingfast/dgrpc v0.0.0-20230929132851-893fc52687fa/go.mod h1:AcY2kk28XswihgU6z37288a3ZF4gGGO7nNwlTI/vET4= +github.com/streamingfast/dhammer v0.0.0-20230125192823-c34bbd561bd4 h1:HKi8AIkLBzxZWmbCRUo1RxoOLK33iXO6gZprfsE9rf4= +github.com/streamingfast/dhammer v0.0.0-20230125192823-c34bbd561bd4/go.mod h1:ehPytv7E4rI65iLcrwTes4rNGGqPPiugnH+20nDQyp4= github.com/streamingfast/dmetering v0.0.0-20231120142327-a3405f0eed83 h1:IbIUT85146duL9EKwMiiW0HH1djpm8plmJOo+YZbO5U= github.com/streamingfast/dmetering v0.0.0-20231120142327-a3405f0eed83/go.mod h1:3XggUfQMyciaue133qhbIkFqJQqNzozGpa/gI3sdwac= github.com/streamingfast/dmetrics v0.0.0-20230919161904-206fa8ebd545 h1:SUl04bZKGAv207lp7/6CHOJIRpjUKunwItrno3K463Y= diff --git a/node-manager/boot/eos_jungle/config.ini b/node-manager/boot/eos_jungle/config.ini index f55ba3d..1c5b690 100644 --- a/node-manager/boot/eos_jungle/config.ini +++ b/node-manager/boot/eos_jungle/config.ini @@ -6,7 +6,7 @@ connection-cleanup-period = 60 verbose-http-errors = true chain-state-db-size-mb = 64000 # shared-memory-size-mb = 2048 -reversible-blocks-db-size-mb = 2048 +reversible-optimisticlyPolledBlocks-db-size-mb = 2048 http-validate-host = false max-transaction-time = 5000 abi-serializer-max-time-ms = 500000 diff --git a/node-manager/boot/eos_mainnet/config.ini b/node-manager/boot/eos_mainnet/config.ini index 26bd919..e73da15 100644 --- a/node-manager/boot/eos_mainnet/config.ini +++ b/node-manager/boot/eos_mainnet/config.ini @@ -5,7 +5,7 @@ p2p-max-nodes-per-host = 2 connection-cleanup-period = 60 verbose-http-errors = true chain-state-db-size-mb = 64000 -reversible-blocks-db-size-mb = 2048 +reversible-optimisticlyPolledBlocks-db-size-mb = 2048 # shared-memory-size-mb = 2048 http-validate-host = false max-transaction-time = 5000 From 1007359e2799871bc2715b9a08bcb3bf2e4acefd Mon Sep 17 00:00:00 2001 From: billettc Date: Tue, 30 Jan 2024 07:58:15 -0500 Subject: [PATCH 32/44] Do not schedule block fetch if block are not available on chain --- blockpoller/fetcher.go | 1 + blockpoller/init_test.go | 4 ++++ blockpoller/poller.go | 24 ++++++++++++++++++++---- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/blockpoller/fetcher.go b/blockpoller/fetcher.go index abb3de4..46d9c90 100644 --- a/blockpoller/fetcher.go +++ b/blockpoller/fetcher.go @@ -7,5 +7,6 @@ import ( ) type BlockFetcher interface { + IsBlockAvailable(requestedSlot uint64) bool Fetch(ctx context.Context, blkNum uint64) (b *pbbstream.Block, skipped bool, err error) } diff --git a/blockpoller/init_test.go b/blockpoller/init_test.go index e7b1eab..2ac934a 100644 --- a/blockpoller/init_test.go +++ b/blockpoller/init_test.go @@ -47,6 +47,10 @@ func (b *TestBlockFetcher) PollingInterval() time.Duration { return 0 } +func (b *TestBlockFetcher) IsBlockAvailable(requestedSlot uint64) bool { + return true +} + func (b *TestBlockFetcher) Fetch(_ context.Context, blkNum uint64) (*pbbstream.Block, bool, error) { if len(b.blocks) == 0 { assert.Fail(b.t, fmt.Sprintf("should not have fetched block %d", blkNum)) diff --git a/blockpoller/poller.go b/blockpoller/poller.go index dffa1a5..6f7705d 100644 --- a/blockpoller/poller.go +++ b/blockpoller/poller.go @@ -177,7 +177,7 @@ type BlockItem struct { skipped bool } -func (p *BlockPoller) loadNextBlocks(blockNumber uint64, numberOfBlockToFetch int) error { +func (p *BlockPoller) loadNextBlocks(requestedBlock uint64, numberOfBlockToFetch int) error { p.optimisticallyPolledBlocks = map[uint64]*BlockItem{} nailer := dhammer.NewNailer(10, func(ctx context.Context, blockToFetch uint64) (*BlockItem, error) { @@ -224,16 +224,32 @@ func (p *BlockPoller) loadNextBlocks(blockNumber uint64, numberOfBlockToFetch in close(done) }() + didTriggerFetch := false for i := 0; i < numberOfBlockToFetch; i++ { - b := blockNumber + uint64(i) - nailer.Push(ctx, b) + b := requestedBlock + uint64(i) + + //only fetch block if it is available on chain + if p.blockFetcher.IsBlockAvailable(b) { + didTriggerFetch = true + nailer.Push(ctx, b) + } else { + //if this block is not available, we can assume that the next blocks are not available as well + break + } } + + if !didTriggerFetch { + //if we did not trigger any fetch, we fetch the requested block + // Fetcher should return the block when available (this will be a blocking call until the block is available) + nailer.Push(ctx, requestedBlock) + } + nailer.Close() <-done if nailer.Err() != nil { - return fmt.Errorf("failed optimistically fetch blocks starting at %d: %w", blockNumber, nailer.Err()) + return fmt.Errorf("failed optimistically fetch blocks starting at %d: %w", requestedBlock, nailer.Err()) } return nil From 49fda4ee724e6fce482fbfc1225e5a8adafe1a4c Mon Sep 17 00:00:00 2001 From: billettc Date: Wed, 31 Jan 2024 08:39:41 -0500 Subject: [PATCH 33/44] add some log --- blockpoller/poller.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/blockpoller/poller.go b/blockpoller/poller.go index 6f7705d..4ef9070 100644 --- a/blockpoller/poller.go +++ b/blockpoller/poller.go @@ -195,7 +195,7 @@ func (p *BlockPoller) loadNextBlocks(requestedBlock uint64, numberOfBlockToFetch } return nil } - + //todo: add block to cache blockItem = &BlockItem{ blockNumber: blockToFetch, block: b, @@ -230,6 +230,7 @@ func (p *BlockPoller) loadNextBlocks(requestedBlock uint64, numberOfBlockToFetch //only fetch block if it is available on chain if p.blockFetcher.IsBlockAvailable(b) { + p.logger.Info("optimistically fetching block", zap.Uint64("block_num", b)) didTriggerFetch = true nailer.Push(ctx, b) } else { From 58774fe9836aeda4d0e2d718805560623202dd32 Mon Sep 17 00:00:00 2001 From: billettc Date: Tue, 6 Feb 2024 15:02:09 -0500 Subject: [PATCH 34/44] remove resolve start block --- blockpoller/poller.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/blockpoller/poller.go b/blockpoller/poller.go index 4ef9070..8a81373 100644 --- a/blockpoller/poller.go +++ b/blockpoller/poller.go @@ -66,7 +66,6 @@ func (p *BlockPoller) Run(ctx context.Context, startBlockNum uint64, numberOfBlo p.startBlockNumGate = startBlockNum p.logger.Info("starting poller", zap.Uint64("start_block_num", startBlockNum), - zap.Uint64("resolved_start_block_num", resolveStartBlockNum), ) p.blockHandler.Init() @@ -76,12 +75,11 @@ func (p *BlockPoller) Run(ctx context.Context, startBlockNum uint64, numberOfBlo return fmt.Errorf("unable to fetch start block %d: %w", startBlockNum, err) } if skip { - resolveStartBlockNum++ + startBlockNum++ continue } return p.run(startBlock.AsRef(), numberOfBlockToFetch) } - } func (p *BlockPoller) run(resolvedStartBlock bstream.BlockRef, numberOfBlockToFetch int) (err error) { From b4db7bfee379784c319070e2352cef22d460f20d Mon Sep 17 00:00:00 2001 From: billettc Date: Tue, 6 Feb 2024 16:07:40 -0500 Subject: [PATCH 35/44] add log to detect fork --- blockpoller/poller.go | 1 + 1 file changed, 1 insertion(+) diff --git a/blockpoller/poller.go b/blockpoller/poller.go index 8a81373..a8281d2 100644 --- a/blockpoller/poller.go +++ b/blockpoller/poller.go @@ -275,6 +275,7 @@ func (p *BlockPoller) fetchBlock(blockNumber uint64, numberOfBlockToFetch int) ( } func (p *BlockPoller) fetchBlockWithHash(blkNum uint64, hash string) (*pbbstream.Block, error) { + p.logger.Info("fetching block with hash", zap.Uint64("block_num", blkNum), zap.String("hash", hash)) _ = hash //todo: hash will be used to fetch block from cache p.optimisticallyPolledBlocks = map[uint64]*BlockItem{} From d227a8f64e591ae77092a3dddc5dfb921028a7b3 Mon Sep 17 00:00:00 2001 From: billettc Date: Wed, 7 Feb 2024 10:48:04 -0500 Subject: [PATCH 36/44] bump bstream --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 5ecf49b..84bd132 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/spf13/cobra v1.7.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.15.0 - github.com/streamingfast/bstream v0.0.2-0.20240118123300-2bc69dde3598 + github.com/streamingfast/bstream v0.0.2-0.20240207154557-a98153ba4b86 github.com/streamingfast/cli v0.0.4-0.20230825151644-8cc84512cd80 github.com/streamingfast/dauth v0.0.0-20231120142446-843f4e045cc2 github.com/streamingfast/dbin v0.9.1-0.20231117225723-59790c798e2c diff --git a/go.sum b/go.sum index 98faabf..a946750 100644 --- a/go.sum +++ b/go.sum @@ -578,8 +578,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= -github.com/streamingfast/bstream v0.0.2-0.20240118123300-2bc69dde3598 h1:fCQ+m6x3DZmf0er9vYcjBqqyQ+NOwVogHWSlATZsgfU= -github.com/streamingfast/bstream v0.0.2-0.20240118123300-2bc69dde3598/go.mod h1:08GVb+DXyz6jVNIsbf+2zlaC81UeEGu5o1h49KrSR3Y= +github.com/streamingfast/bstream v0.0.2-0.20240207154557-a98153ba4b86 h1:PIdAr8WwyinSDAQY+vHDI5mkm8EvGuhMV+NFajyFQzY= +github.com/streamingfast/bstream v0.0.2-0.20240207154557-a98153ba4b86/go.mod h1:08GVb+DXyz6jVNIsbf+2zlaC81UeEGu5o1h49KrSR3Y= github.com/streamingfast/cli v0.0.4-0.20230825151644-8cc84512cd80 h1:UxJUTcEVkdZy8N77E3exz0iNlgQuxl4m220GPvzdZ2s= github.com/streamingfast/cli v0.0.4-0.20230825151644-8cc84512cd80/go.mod h1:QxjVH73Lkqk+mP8bndvhMuQDUINfkgsYhdCH/5TJFKI= github.com/streamingfast/dauth v0.0.0-20231120142446-843f4e045cc2 h1:g4mG6ZCy3/XtcsZXfOHrQOsjVGoX9uTc/QlemaPV4EE= From e2f493b552477de968e4e869bd9749ebede91741 Mon Sep 17 00:00:00 2001 From: billettc Date: Fri, 9 Feb 2024 11:17:13 -0500 Subject: [PATCH 37/44] go generate and go mod tidy --- go.sum | 12 ++++++------ proto/well_known_types.go | 8 ++++++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/go.sum b/go.sum index a946750..b2c76df 100644 --- a/go.sum +++ b/go.sum @@ -588,8 +588,8 @@ github.com/streamingfast/dbin v0.9.1-0.20231117225723-59790c798e2c h1:6WjE2yInE+ github.com/streamingfast/dbin v0.9.1-0.20231117225723-59790c798e2c/go.mod h1:dbfiy9ORrL8c6ldSq+L0H9pg8TOqqu/FsghsgUEWK54= github.com/streamingfast/derr v0.0.0-20230515163924-8570aaa43fe1 h1:xJB7rXnOHLesosMjfwWsEL2i/40mFSkzenEb3M0qTyM= github.com/streamingfast/derr v0.0.0-20230515163924-8570aaa43fe1/go.mod h1:QSm/AfaDsE0k1xBYi0lW580YJ/WDV/FKZI628tkZR0Y= -github.com/streamingfast/dgrpc v0.0.0-20230929132851-893fc52687fa h1:L/Ipge5pkZtyHucT7c8F/PiCitiNqQxjoUuxyzWKZew= -github.com/streamingfast/dgrpc v0.0.0-20230929132851-893fc52687fa/go.mod h1:AcY2kk28XswihgU6z37288a3ZF4gGGO7nNwlTI/vET4= +github.com/streamingfast/dgrpc v0.0.0-20240119162453-69517bcc1a7f h1:WDURSuig53yVdqSZDsIpOr/510oGqEtawosa9DtRO6A= +github.com/streamingfast/dgrpc v0.0.0-20240119162453-69517bcc1a7f/go.mod h1:AzMcSri68b21YwdAOw3j4Sq84N/JQ6ONM0B29NSVGyY= github.com/streamingfast/dhammer v0.0.0-20230125192823-c34bbd561bd4 h1:HKi8AIkLBzxZWmbCRUo1RxoOLK33iXO6gZprfsE9rf4= github.com/streamingfast/dhammer v0.0.0-20230125192823-c34bbd561bd4/go.mod h1:ehPytv7E4rI65iLcrwTes4rNGGqPPiugnH+20nDQyp4= github.com/streamingfast/dmetering v0.0.0-20231120142327-a3405f0eed83 h1:IbIUT85146duL9EKwMiiW0HH1djpm8plmJOo+YZbO5U= @@ -611,8 +611,8 @@ github.com/streamingfast/opaque v0.0.0-20210811180740-0c01d37ea308 h1:xlWSfi1BoP github.com/streamingfast/opaque v0.0.0-20210811180740-0c01d37ea308/go.mod h1:K1p8Bj/wG34KJvYzPUqtzpndffmpkrVY11u2hkyxCWQ= github.com/streamingfast/overseer v0.2.1-0.20210326144022-ee491780e3ef h1:9IVFHRsqvI+vKJwgF1OMV6L55jHbaV/ZLoU4IAG/dME= github.com/streamingfast/overseer v0.2.1-0.20210326144022-ee491780e3ef/go.mod h1:cq8CvbZ3ioFmGrHokSAJalS0lC+pVXLKhITScItUGXY= -github.com/streamingfast/pbgo v0.0.6-0.20231208140754-ed2bd10b96ee h1:ydH7Ii6P1JIx1bNRO1sFH2VCAr0iZQ8MCHUPBo8i0dY= -github.com/streamingfast/pbgo v0.0.6-0.20231208140754-ed2bd10b96ee/go.mod h1:eDQjKBYg9BWE2BTaV3UZeLZ5xw05+ywA9RCFTmM1w5Y= +github.com/streamingfast/pbgo v0.0.6-0.20240131193313-6b88bc7139db h1:c39xMBgmHgbx1e+cP8KJZ2ziWh9VsjY5C0vDZiytYtw= +github.com/streamingfast/pbgo v0.0.6-0.20240131193313-6b88bc7139db/go.mod h1:eDQjKBYg9BWE2BTaV3UZeLZ5xw05+ywA9RCFTmM1w5Y= github.com/streamingfast/protoreflect v0.0.0-20231205191344-4b629d20ce8d h1:33VIARqUqBUKXJcuQoOS1rVSms54tgxhhNCmrLptpLg= github.com/streamingfast/protoreflect v0.0.0-20231205191344-4b629d20ce8d/go.mod h1:aBJivEdekmFWYSQ29EE/fN9IanJWJXbtjy3ky0XD/jE= github.com/streamingfast/sf-tracing v0.0.0-20230616174903-cd2ade641ca9 h1:YRwpVvLYa+FEJlTy0S7mk4UptYjk5zac+A+ZE1phOeA= @@ -621,8 +621,8 @@ github.com/streamingfast/shutter v1.5.0 h1:NpzDYzj0HVpSiDJVO/FFSL6QIK/YKOxY0gJAt github.com/streamingfast/shutter v1.5.0/go.mod h1:B/T6efqdeMGbGwjzPS1ToXzYZI4kDzI5/u4I+7qbjY8= github.com/streamingfast/snapshotter v0.0.0-20230316190750-5bcadfde44d0 h1:Y15G1Z4fpEdm2b+/70owI7TLuXadlqBtGM7rk4Hxrzk= github.com/streamingfast/snapshotter v0.0.0-20230316190750-5bcadfde44d0/go.mod h1:/Rnz2TJvaShjUct0scZ9kKV2Jr9/+KBAoWy4UMYxgv4= -github.com/streamingfast/substreams v1.3.2-0.20240119045851-7de579a236d2 h1:DOARpB5JeJqwPonIbW0FjS/JNxSAnb5Zymm6NnoM+2Q= -github.com/streamingfast/substreams v1.3.2-0.20240119045851-7de579a236d2/go.mod h1:fCC3pGTYMi0N4VhJjdJPQydefJpY+tsY9BzWxDi152k= +github.com/streamingfast/substreams v1.3.2 h1:czgHC3+ORiKJY75z08R2W67tLxI/WK99NFQgx2fORvg= +github.com/streamingfast/substreams v1.3.2/go.mod h1:fCC3pGTYMi0N4VhJjdJPQydefJpY+tsY9BzWxDi152k= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= diff --git a/proto/well_known_types.go b/proto/well_known_types.go index e6fba82..9e72a8f 100644 --- a/proto/well_known_types.go +++ b/proto/well_known_types.go @@ -50,12 +50,16 @@ func init() { proto: "0a1d73662f626974636f696e2f747970652f76312f747970652e70726f746f121273662e626974636f696e2e747970652e76311a1f676f6f676c652f70726f746f6275662f74696d657374616d702e70726f746f22e5030a05426c6f636b12120a046861736818012001280952046861736812120a0473697a65180320012805520473697a6512230a0d73747269707065645f73697a65180420012805520c737472697070656453697a6512160a06776569676874180520012805520677656967687412160a06686569676874180620012803520668656967687412180a0776657273696f6e180720012805520776657273696f6e121f0a0b76657273696f6e5f686578180820012809520a76657273696f6e486578121f0a0b6d65726b6c655f726f6f74180920012809520a6d65726b6c65526f6f74122f0a027478180a2003280b321f2e73662e626974636f696e2e747970652e76312e5472616e73616374696f6e5202747812120a0474696d65180b20012803520474696d65121e0a0a6d656469616e74696d65180c20012803520a6d656469616e74696d6512140a056e6f6e6365180d2001280d52056e6f6e636512120a0462697473180e20012809520462697473121e0a0a646966666963756c7479180f20012801520a646966666963756c7479121c0a09636861696e776f726b1810200128095209636861696e776f726b12110a046e5f747818112001280d52036e547812230a0d70726576696f75735f68617368181220012809520c70726576696f75734861736822d4020a0b5472616e73616374696f6e12100a03686578180120012809520368657812120a047478696418022001280952047478696412120a046861736818032001280952046861736812120a0473697a65180420012805520473697a6512140a057673697a6518052001280552057673697a6512160a06776569676874180620012805520677656967687412180a0776657273696f6e18072001280d520776657273696f6e121a0a086c6f636b74696d6518082001280d52086c6f636b74696d6512290a0376696e18092003280b32172e73662e626974636f696e2e747970652e76312e56696e520376696e122c0a04766f7574180a2003280b32182e73662e626974636f696e2e747970652e76312e566f75745204766f7574121c0a09626c6f636b68617368180b200128095209626c6f636b68617368121c0a09626c6f636b74696d65180c200128035209626c6f636b74696d6522c5010a0356696e12120a047478696418012001280952047478696412120a04766f757418022001280d5204766f7574123c0a0a7363726970745f73696718032001280b321d2e73662e626974636f696e2e747970652e76312e5363726970745369675209736372697074536967121a0a0873657175656e636518042001280d520873657175656e636512200a0b7478696e7769746e657373180520032809520b7478696e7769746e657373121a0a08636f696e626173651806200128095208636f696e6261736522710a04566f757412140a0576616c7565180120012801520576616c7565120c0a016e18022001280d52016e12450a0d7363726970745f7075624b657918032001280b32202e73662e626974636f696e2e747970652e76312e5363726970745075624b6579520c7363726970745075624b6579222f0a0953637269707453696712100a0361736d180120012809520361736d12100a0368657818022001280952036865782299010a0c5363726970745075624b657912100a0361736d180120012809520361736d12100a03686578180220012809520368657812190a087265715f7369677318032001280552077265715369677312120a047479706518042001280952047479706512180a0761646472657373180520012809520761646472657373121c0a096164647265737365731806200328095209616464726573736573424d5a4b6769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d626974636f696e2f74797065732f70622f73662f626974636f696e2f747970652f76313b7062627463620670726f746f33", }, { - // google/protobuf/timestamp.proto (https://buf.build/pinax/firehose-antelope/docs/716581be38ac455eade2e70f33a09bf3:google.protobuf) + // google/protobuf/timestamp.proto (https://buf.build/pinax/firehose-antelope/docs/3af26456175d4f1883a091182f77d0db:google.protobuf) proto: "0a1f676f6f676c652f70726f746f6275662f74696d657374616d702e70726f746f120f676f6f676c652e70726f746f627566223b0a0954696d657374616d7012180a077365636f6e647318012001280352077365636f6e647312140a056e616e6f7318022001280552056e616e6f734285010a13636f6d2e676f6f676c652e70726f746f627566420e54696d657374616d7050726f746f50015a32676f6f676c652e676f6c616e672e6f72672f70726f746f6275662f74797065732f6b6e6f776e2f74696d657374616d707062f80101a20203475042aa021e476f6f676c652e50726f746f6275662e57656c6c4b6e6f776e5479706573620670726f746f33", }, { - // sf/antelope/type/v1/type.proto (https://buf.build/pinax/firehose-antelope/docs/716581be38ac455eade2e70f33a09bf3:sf.antelope.type.v1) + // sf/antelope/type/v1/type.proto (https://buf.build/pinax/firehose-antelope/docs/3af26456175d4f1883a091182f77d0db:sf.antelope.type.v1) proto: "0a1e73662f616e74656c6f70652f747970652f76312f747970652e70726f746f121373662e616e74656c6f70652e747970652e76311a1f676f6f676c652f70726f746f6275662f74696d657374616d702e70726f746f22550a0c416374696f6e54726163657312450a0d616374696f6e5f74726163657318012003280b32202e73662e616e74656c6f70652e747970652e76312e416374696f6e5472616365520c616374696f6e54726163657322690a115472616e73616374696f6e54726163657312540a127472616e73616374696f6e5f74726163657318012003280b32252e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e547261636552117472616e73616374696f6e54726163657322390a0544424f707312300a0664625f6f707318012003280b32192e73662e616e74656c6f70652e747970652e76312e44424f70520564624f7073228b160a05426c6f636b120e0a0269641801200128095202696412160a066e756d62657218022001280d52066e756d62657212180a0776657273696f6e18032001280d520776657273696f6e12380a0668656164657218042001280b32202e73662e616e74656c6f70652e747970652e76312e426c6f636b4865616465725206686561646572122d0a1270726f64756365725f7369676e6174757265180520012809521170726f64756365725369676e617475726512490a10626c6f636b5f657874656e73696f6e7318072003280b321e2e73662e616e74656c6f70652e747970652e76312e457874656e73696f6e520f626c6f636b457874656e73696f6e73124d0a2364706f735f70726f706f7365645f697272657665727369626c655f626c6f636b6e756d18082001280d522064706f7350726f706f736564497272657665727369626c65426c6f636b6e756d123c0a1a64706f735f697272657665727369626c655f626c6f636b6e756d18092001280d521864706f73497272657665727369626c65426c6f636b6e756d124f0a10626c6f636b726f6f745f6d65726b6c65180b2001280b32242e73662e616e74656c6f70652e747970652e76312e426c6f636b526f6f744d65726b6c65520f626c6f636b726f6f744d65726b6c6512660a1970726f64756365725f746f5f6c6173745f70726f6475636564180c2003280b322b2e73662e616e74656c6f70652e747970652e76312e50726f6475636572546f4c61737450726f6475636564521670726f6475636572546f4c61737450726f6475636564126d0a1c70726f64756365725f746f5f6c6173745f696d706c6965645f697262180d2003280b322d2e73662e616e74656c6f70652e747970652e76312e50726f6475636572546f4c617374496d706c696564495242521870726f6475636572546f4c617374496d706c69656449726212230a0d636f6e6669726d5f636f756e74180f2003280d520c636f6e6669726d436f756e7412570a1070656e64696e675f7363686564756c6518102001280b322c2e73662e616e74656c6f70652e747970652e76312e50656e64696e6750726f64756365725363686564756c65520f70656e64696e675363686564756c65126e0a1b6163746976617465645f70726f746f636f6c5f666561747572657318112001280b322e2e73662e616e74656c6f70652e747970652e76312e41637469766174656450726f746f636f6c4665617475726573521961637469766174656450726f746f636f6c4665617475726573123c0a0a726c696d69745f6f707318132003280b321d2e73662e616e74656c6f70652e747970652e76312e526c696d69744f705209726c696d69744f707312600a17756e66696c74657265645f7472616e73616374696f6e7318062003280b32272e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e526563656970745216756e66696c74657265645472616e73616374696f6e73125c0a1566696c74657265645f7472616e73616374696f6e73182f2003280b32272e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e52656365697074521466696c74657265645472616e73616374696f6e7312400a1c756e66696c74657265645f7472616e73616374696f6e5f636f756e7418162001280d521a756e66696c74657265645472616e73616374696f6e436f756e74123c0a1a66696c74657265645f7472616e73616374696f6e5f636f756e7418302001280d521866696c74657265645472616e73616374696f6e436f756e7412690a23756e66696c74657265645f696d706c696369745f7472616e73616374696f6e5f6f707318142003280b321a2e73662e616e74656c6f70652e747970652e76312e5472784f705220756e66696c7465726564496d706c696369745472616e73616374696f6e4f707312650a2166696c74657265645f696d706c696369745f7472616e73616374696f6e5f6f707318312003280b321a2e73662e616e74656c6f70652e747970652e76312e5472784f70521e66696c7465726564496d706c696369745472616e73616374696f6e4f707312690a1d756e66696c74657265645f7472616e73616374696f6e5f74726163657318152003280b32252e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5472616365521b756e66696c74657265645472616e73616374696f6e54726163657312650a1b66696c74657265645f7472616e73616374696f6e5f747261636573182e2003280b32252e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5472616365521966696c74657265645472616e73616374696f6e547261636573124b0a22756e66696c74657265645f7472616e73616374696f6e5f74726163655f636f756e7418172001280d521f756e66696c74657265645472616e73616374696f6e5472616365436f756e7412470a2066696c74657265645f7472616e73616374696f6e5f74726163655f636f756e74182b2001280d521d66696c74657265645472616e73616374696f6e5472616365436f756e7412520a26756e66696c74657265645f65786563757465645f696e7075745f616374696f6e5f636f756e7418182001280d5222756e66696c74657265644578656375746564496e707574416374696f6e436f756e74124e0a2466696c74657265645f65786563757465645f696e7075745f616374696f6e5f636f756e74182c2001280d522066696c74657265644578656375746564496e707574416374696f6e436f756e7412520a26756e66696c74657265645f65786563757465645f746f74616c5f616374696f6e5f636f756e7418192001280d5222756e66696c74657265644578656375746564546f74616c416374696f6e436f756e74124e0a2466696c74657265645f65786563757465645f746f74616c5f616374696f6e5f636f756e74182d2001280d522066696c74657265644578656375746564546f74616c416374696f6e436f756e74122a0a11626c6f636b5f7369676e696e675f6b6579180e20012809520f626c6f636b5369676e696e674b657912530a126163746976655f7363686564756c655f7631180a2001280b32252e73662e616e74656c6f70652e747970652e76312e50726f64756365725363686564756c6552106163746976655363686564756c65563112720a2076616c69645f626c6f636b5f7369676e696e675f617574686f726974795f7632181e2001280b322a2e73662e616e74656c6f70652e747970652e76312e426c6f636b5369676e696e67417574686f72697479521c76616c6964426c6f636b5369676e696e67417574686f726974795632125c0a126163746976655f7363686564756c655f7632181f2001280b322e2e73662e616e74656c6f70652e747970652e76312e50726f6475636572417574686f726974795363686564756c6552106163746976655363686564756c655632122b0a1166696c746572696e675f6170706c696564182820012808521066696c746572696e674170706c69656412410a1d66696c746572696e675f696e636c7564655f66696c7465725f65787072182920012809521a66696c746572696e67496e636c75646546696c7465724578707212410a1d66696c746572696e675f6578636c7564655f66696c7465725f65787072182a20012809521a66696c746572696e674578636c75646546696c74657245787072125d0a2c66696c746572696e675f73797374656d5f616374696f6e735f696e636c7564655f66696c7465725f65787072183220012809522766696c746572696e6753797374656d416374696f6e73496e636c75646546696c746572457870724a04081210132284030a0d426c6f636b5769746852656673120e0a0269641801200128095202696412300a05626c6f636b18022001280b321a2e73662e616e74656c6f70652e747970652e76312e426c6f636b5205626c6f636b12600a19696d706c696369745f7472616e73616374696f6e5f7265667318032001280b32242e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e526566735217696d706c696369745472616e73616374696f6e52656673124f0a107472616e73616374696f6e5f7265667318042001280b32242e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e52656673520f7472616e73616374696f6e52656673125a0a167472616e73616374696f6e5f74726163655f7265667318052001280b32242e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5265667352147472616e73616374696f6e54726163655265667312220a0c697272657665727369626c65180620012808520c697272657665727369626c6522290a0f5472616e73616374696f6e5265667312160a0668617368657318012003280c520668617368657322480a1941637469766174656450726f746f636f6c4665617475726573122b0a1170726f746f636f6c5f666561747572657318012003280c521070726f746f636f6c46656174757265732281020a1750656e64696e6750726f64756365725363686564756c6512280a107363686564756c655f6c69625f6e756d18012001280d520e7363686564756c654c69624e756d12230a0d7363686564756c655f6861736818022001280c520c7363686564756c654861736812460a0b7363686564756c655f763118032001280b32252e73662e616e74656c6f70652e747970652e76312e50726f64756365725363686564756c65520a7363686564756c655631124f0a0b7363686564756c655f763218042001280b322e2e73662e616e74656c6f70652e747970652e76312e50726f6475636572417574686f726974795363686564756c65520a7363686564756c655632226c0a1050726f64756365725363686564756c6512180a0776657273696f6e18012001280d520776657273696f6e123e0a0970726f64756365727318022003280b32202e73662e616e74656c6f70652e747970652e76312e50726f64756365724b6579520970726f647563657273225c0a0b50726f64756365724b657912210a0c6163636f756e745f6e616d65180120012809520b6163636f756e744e616d65122a0a11626c6f636b5f7369676e696e675f6b6579180220012809520f626c6f636b5369676e696e674b6579227b0a1950726f6475636572417574686f726974795363686564756c6512180a0776657273696f6e18012001280d520776657273696f6e12440a0970726f64756365727318022003280b32262e73662e616e74656c6f70652e747970652e76312e50726f6475636572417574686f72697479520970726f647563657273229a010a1150726f6475636572417574686f7269747912210a0c6163636f756e745f6e616d65180120012809520b6163636f756e744e616d6512620a17626c6f636b5f7369676e696e675f617574686f7269747918022001280b322a2e73662e616e74656c6f70652e747970652e76312e426c6f636b5369676e696e67417574686f726974795215626c6f636b5369676e696e67417574686f7269747922620a15426c6f636b5369676e696e67417574686f72697479123e0a02763018012001280b322c2e73662e616e74656c6f70652e747970652e76312e426c6f636b5369676e696e67417574686f72697479563048005202763042090a0776617269616e74226b0a17426c6f636b5369676e696e67417574686f726974795630121c0a097468726573686f6c6418012001280d52097468726573686f6c6412320a046b65797318022003280b321e2e73662e616e74656c6f70652e747970652e76312e4b657957656967687452046b65797322530a0f426c6f636b526f6f744d65726b6c65121d0a0a6e6f64655f636f756e7418012001280d52096e6f6465436f756e7412210a0c6163746976655f6e6f64657318022003280c520b6163746976654e6f64657322630a1650726f6475636572546f4c61737450726f647563656412120a046e616d6518012001280952046e616d6512350a176c6173745f626c6f636b5f6e756d5f70726f647563656418022001280d52146c617374426c6f636b4e756d50726f647563656422650a1850726f6475636572546f4c617374496d706c69656449524212120a046e616d6518012001280952046e616d6512350a176c6173745f626c6f636b5f6e756d5f70726f647563656418022001280d52146c617374426c6f636b4e756d50726f647563656422b0020a125472616e73616374696f6e52656365697074120e0a0269641804200128095202696412140a05696e6465781806200128045205696e646578123e0a0673746174757318012001280e32262e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e537461747573520673746174757312350a176370755f75736167655f6d6963726f5f7365636f6e647318022001280d521463707555736167654d6963726f5365636f6e647312260a0f6e65745f75736167655f776f72647318032001280d520d6e65745573616765576f72647312550a127061636b65645f7472616e73616374696f6e18052001280b32262e73662e616e74656c6f70652e747970652e76312e5061636b65645472616e73616374696f6e52117061636b65645472616e73616374696f6e22bd010a115061636b65645472616e73616374696f6e121e0a0a7369676e617475726573180120032809520a7369676e61747572657312200a0b636f6d7072657373696f6e18022001280d520b636f6d7072657373696f6e12370a187061636b65645f636f6e746578745f667265655f6461746118032001280c52157061636b6564436f6e746578744672656544617461122d0a127061636b65645f7472616e73616374696f6e18042001280c52117061636b65645472616e73616374696f6e22b6030a0b426c6f636b48656164657212380a0974696d657374616d7018032001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d70520974696d657374616d70121a0a0870726f6475636572180420012809520870726f6475636572121c0a09636f6e6669726d656418052001280d5209636f6e6669726d6564121a0a0870726576696f7573180620012809520870726576696f7573122b0a117472616e73616374696f6e5f6d726f6f7418072001280c52107472616e73616374696f6e4d726f6f7412210a0c616374696f6e5f6d726f6f7418082001280c520b616374696f6e4d726f6f7412290a107363686564756c655f76657273696f6e18092001280d520f7363686564756c6556657273696f6e124b0a116865616465725f657874656e73696f6e73180b2003280b321e2e73662e616e74656c6f70652e747970652e76312e457874656e73696f6e5210686561646572457874656e73696f6e73124f0a106e65775f70726f6475636572735f7631180a2001280b32252e73662e616e74656c6f70652e747970652e76312e50726f64756365725363686564756c65520e6e657750726f647563657273563122fb090a105472616e73616374696f6e4576656e74120e0a0269641801200128095202696412190a08626c6f636b5f69641802200128095207626c6f636b4964121b0a09626c6f636b5f6e756d18032001280d5208626c6f636b4e756d12220a0c697272657665727369626c65180420012808520c697272657665727369626c6512640a11696e7465726e616c5f6164646974696f6e18052001280b32352e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e4576656e742e4164646564496e7465726e616c6c7948005210696e7465726e616c4164646974696f6e12490a086164646974696f6e18062001280b322b2e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e4576656e742e4164646564480052086164646974696f6e124e0a09657865637574696f6e18072001280b322e2e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e4576656e742e457865637574656448005209657865637574696f6e125e0a0f647472785f7363686564756c696e6718082001280b32332e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e4576656e742e447472785363686564756c65644800520e647472785363686564756c696e6712610a11647472785f63616e63656c6c6174696f6e18092001280b32322e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e4576656e742e4474727843616e63656c6564480052106474727843616e63656c6c6174696f6e1a5b0a0f4164646564496e7465726e616c6c7912480a0b7472616e73616374696f6e18012001280b32262e73662e616e74656c6f70652e747970652e76312e5369676e65645472616e73616374696f6e520b7472616e73616374696f6e1ad6010a05416464656412410a077265636569707418012001280b32272e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5265636569707452077265636569707412480a0b7472616e73616374696f6e18022001280b32262e73662e616e74656c6f70652e747970652e76312e5369676e65645472616e73616374696f6e520b7472616e73616374696f6e12400a0b7075626c69635f6b65797318032001280b321f2e73662e616e74656c6f70652e747970652e76312e5075626c69634b657973520a7075626c69634b6579731a8b010a084578656375746564123b0a05747261636518012001280b32252e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e54726163655205747261636512420a0b626c6f636b48656164657218022001280b32202e73662e616e74656c6f70652e747970652e76312e426c6f636b486561646572520b626c6f636b4865616465721a98010a0d447472785363686564756c6564123d0a0a637265617465645f627918012001280b321e2e73662e616e74656c6f70652e747970652e76312e457874445472784f70520963726561746564427912480a0b7472616e73616374696f6e18022001280b32262e73662e616e74656c6f70652e747970652e76312e5369676e65645472616e73616374696f6e520b7472616e73616374696f6e1a4f0a0c4474727843616e63656c6564123f0a0b63616e63656c65645f627918012001280b321e2e73662e616e74656c6f70652e747970652e76312e457874445472784f70520a63616e63656c6564427942070a056576656e74222d0a0a5075626c69634b657973121f0a0b7075626c69635f6b657973180120032809520a7075626c69634b657973229d060a145472616e73616374696f6e4c6966656379636c65120e0a0269641801200128095202696412550a127472616e73616374696f6e5f73746174757318022001280e32262e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e53746174757352117472616e73616374696f6e53746174757312580a137472616e73616374696f6e5f7265636569707418242001280b32272e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5265636569707452127472616e73616374696f6e5265636569707412480a0b7472616e73616374696f6e180a2001280b32262e73662e616e74656c6f70652e747970652e76312e5369676e65645472616e73616374696f6e520b7472616e73616374696f6e121f0a0b7075626c69635f6b657973181320032809520a7075626c69634b657973124e0a0f657865637574696f6e5f7472616365180b2001280b32252e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5472616365520e657865637574696f6e547261636512560a16657865637574696f6e5f626c6f636b5f686561646572180c2001280b32202e73662e616e74656c6f70652e747970652e76312e426c6f636b4865616465725214657865637574696f6e426c6f636b486561646572123d0a0a637265617465645f627918142001280b321e2e73662e616e74656c6f70652e747970652e76312e457874445472784f705209637265617465644279123f0a0b63616e63656c65645f627918152001280b321e2e73662e616e74656c6f70652e747970652e76312e457874445472784f70520a63616e63656c6564427912330a156372656174696f6e5f697272657665727369626c6518212001280852146372656174696f6e497272657665727369626c6512350a16657865637574696f6e5f697272657665727369626c651822200128085215657865637574696f6e497272657665727369626c6512390a1863616e63656c6174696f6e5f697272657665727369626c65182320012808521763616e63656c6174696f6e497272657665727369626c654a04080d10134a040816102122a3010a115369676e65645472616e73616374696f6e12420a0b7472616e73616374696f6e18012001280b32202e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e520b7472616e73616374696f6e121e0a0a7369676e617475726573180220032809520a7369676e617475726573122a0a11636f6e746578745f667265655f6461746118032003280c520f636f6e7465787446726565446174612293020a0b5472616e73616374696f6e123e0a0668656164657218012001280b32262e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e4865616465725206686561646572124d0a14636f6e746578745f667265655f616374696f6e7318022003280b321b2e73662e616e74656c6f70652e747970652e76312e416374696f6e5212636f6e7465787446726565416374696f6e7312350a07616374696f6e7318032003280b321b2e73662e616e74656c6f70652e747970652e76312e416374696f6e5207616374696f6e73123e0a0a657874656e73696f6e7318042003280b321e2e73662e616e74656c6f70652e747970652e76312e457874656e73696f6e520a657874656e73696f6e732292020a115472616e73616374696f6e486561646572123a0a0a65787069726174696f6e18012001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d70520a65787069726174696f6e12220a0d7265665f626c6f636b5f6e756d18022001280d520b726566426c6f636b4e756d12280a107265665f626c6f636b5f70726566697818032001280d520e726566426c6f636b507265666978122d0a136d61785f6e65745f75736167655f776f72647318042001280d52106d61784e65745573616765576f72647312270a106d61785f6370755f75736167655f6d7318052001280d520d6d617843707555736167654d73121b0a0964656c61795f73656318062001280d520864656c61795365632288090a105472616e73616374696f6e5472616365120e0a02696418012001280952026964121b0a09626c6f636b5f6e756d1802200128045208626c6f636b4e756d12140a05696e646578181a200128045205696e64657812390a0a626c6f636b5f74696d6518032001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d705209626c6f636b54696d65122a0a1170726f64756365725f626c6f636b5f6964180420012809520f70726f6475636572426c6f636b496412470a077265636569707418052001280b322d2e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5265636569707448656164657252077265636569707412180a07656c61707365641806200128035207656c6170736564121b0a096e65745f757361676518072001280452086e65745573616765121c0a097363686564756c656418082001280852097363686564756c656412450a0d616374696f6e5f74726163657318092003280b32202e73662e616e74656c6f70652e747970652e76312e416374696f6e5472616365520c616374696f6e54726163657312510a116661696c65645f647472785f7472616365180a2001280b32252e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e5472616365520f6661696c6564447472785472616365123c0a09657863657074696f6e180f2001280b321e2e73662e616e74656c6f70652e747970652e76312e457863657074696f6e5209657863657074696f6e121d0a0a6572726f725f636f646518102001280452096572726f72436f646512300a0664625f6f707318112003280b32192e73662e616e74656c6f70652e747970652e76312e44424f70520564624f707312360a08647472785f6f707318122003280b321b2e73662e616e74656c6f70652e747970652e76312e445472784f705207647472784f7073123f0a0b666561747572655f6f707318132003280b321e2e73662e616e74656c6f70652e747970652e76312e466561747572654f70520a666561747572654f707312360a087065726d5f6f707318142003280b321b2e73662e616e74656c6f70652e747970652e76312e5065726d4f7052077065726d4f707312330a0772616d5f6f707318152003280b321a2e73662e616e74656c6f70652e747970652e76312e52414d4f70520672616d4f707312520a1272616d5f636f7272656374696f6e5f6f707318162003280b32242e73662e616e74656c6f70652e747970652e76312e52414d436f7272656374696f6e4f70521072616d436f7272656374696f6e4f7073123c0a0a726c696d69745f6f707318172003280b321d2e73662e616e74656c6f70652e747970652e76312e526c696d69744f705209726c696d69744f707312390a097461626c655f6f707318182003280b321c2e73662e616e74656c6f70652e747970652e76312e5461626c654f7052087461626c654f7073124a0a0d6372656174696f6e5f7472656518192003280b32252e73662e616e74656c6f70652e747970652e76312e4372656174696f6e466c61744e6f6465520c6372656174696f6e547265654a04081e101f22b9010a185472616e73616374696f6e52656365697074486561646572123e0a0673746174757318012001280e32262e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e537461747573520673746174757312350a176370755f75736167655f6d6963726f5f7365636f6e647318022001280d521463707555736167654d6963726f5365636f6e647312260a0f6e65745f75736167655f776f72647318032001280d520d6e65745573616765576f72647322ba010a06416374696f6e12180a076163636f756e7418012001280952076163636f756e7412120a046e616d6518022001280952046e616d65124a0a0d617574686f72697a6174696f6e18032003280b32242e73662e616e74656c6f70652e747970652e76312e5065726d697373696f6e4c6576656c520d617574686f72697a6174696f6e121b0a096a736f6e5f6461746118042001280952086a736f6e4461746112190a087261775f6461746118052001280c520772617744617461228e080a0b416374696f6e5472616365121a0a087265636569766572180b2001280952087265636569766572123c0a077265636569707418012001280b32222e73662e616e74656c6f70652e747970652e76312e416374696f6e5265636569707452077265636569707412330a06616374696f6e18022001280b321b2e73662e616e74656c6f70652e747970652e76312e416374696f6e5206616374696f6e12210a0c636f6e746578745f66726565180320012808520b636f6e746578744672656512180a07656c61707365641804200128035207656c617073656412180a07636f6e736f6c651805200128095207636f6e736f6c6512250a0e7472616e73616374696f6e5f6964180620012809520d7472616e73616374696f6e4964121b0a09626c6f636b5f6e756d1807200128045208626c6f636b4e756d122a0a1170726f64756365725f626c6f636b5f6964180820012809520f70726f6475636572426c6f636b496412390a0a626c6f636b5f74696d6518092001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d705209626c6f636b54696d6512520a126163636f756e745f72616d5f64656c746173180a2003280b32242e73662e616e74656c6f70652e747970652e76312e4163636f756e7452414d44656c746152106163636f756e7452616d44656c74617312280a107261775f72657475726e5f76616c756518292001280c520e72617752657475726e56616c7565122a0a116a736f6e5f72657475726e5f76616c7565182a20012809520f6a736f6e52657475726e56616c7565123c0a09657863657074696f6e180f2001280b321e2e73662e616e74656c6f70652e747970652e76312e457863657074696f6e5209657863657074696f6e121d0a0a6572726f725f636f646518142001280452096572726f72436f646512250a0e616374696f6e5f6f7264696e616c18102001280d520d616374696f6e4f7264696e616c12340a1663726561746f725f616374696f6e5f6f7264696e616c18112001280d521463726561746f72416374696f6e4f7264696e616c125a0a2a636c6f736573745f756e6e6f7469666965645f616e636573746f725f616374696f6e5f6f7264696e616c18122001280d5226636c6f73657374556e6e6f746966696564416e636573746f72416374696f6e4f7264696e616c12270a0f657865637574696f6e5f696e64657818132001280d520e657865637574696f6e496e646578122b0a1166696c746572696e675f6d617463686564181e20012808521066696c746572696e674d61746368656412520a2666696c746572696e675f6d6174636865645f73797374656d5f616374696f6e5f66696c746572181f20012808522266696c746572696e674d61746368656453797374656d416374696f6e46696c7465724a040828102922a1020a0d416374696f6e52656365697074121a0a0872656365697665721801200128095208726563656976657212160a06646967657374180220012809520664696765737412270a0f676c6f62616c5f73657175656e6365180320012804520e676c6f62616c53657175656e636512460a0d617574685f73657175656e636518042003280b32212e73662e616e74656c6f70652e747970652e76312e4175746853657175656e6365520c6175746853657175656e636512230a0d726563765f73657175656e6365180520012804520c7265637653657175656e636512230a0d636f64655f73657175656e6365180620012804520c636f646553657175656e636512210a0c6162695f73657175656e6365180720012804520b61626953657175656e6365224d0a0c4175746853657175656e636512210a0c6163636f756e745f6e616d65180120012809520b6163636f756e744e616d65121a0a0873657175656e6365180220012804520873657175656e636522410a0f4163636f756e7452414d44656c746112180a076163636f756e7418012001280952076163636f756e7412140a0564656c7461180220012803520564656c7461223e0a0c4163636f756e7444656c746112180a076163636f756e7418012001280952076163636f756e7412140a0564656c7461180220012803520564656c746122330a09457874656e73696f6e12120a047479706518012001280d52047479706512120a046461746118022001280c520464617461228a020a055472784f7012420a096f7065726174696f6e18012001280e32242e73662e616e74656c6f70652e747970652e76312e5472784f702e4f7065726174696f6e52096f7065726174696f6e12120a046e616d6518022001280952046e616d6512250a0e7472616e73616374696f6e5f6964180320012809520d7472616e73616374696f6e496412480a0b7472616e73616374696f6e18042001280b32262e73662e616e74656c6f70652e747970652e76312e5369676e65645472616e73616374696f6e520b7472616e73616374696f6e22380a094f7065726174696f6e12150a114f5045524154494f4e5f554e4b4e4f574e100012140a104f5045524154494f4e5f435245415445100122f4030a0444424f7012410a096f7065726174696f6e18012001280e32232e73662e616e74656c6f70652e747970652e76312e44424f702e4f7065726174696f6e52096f7065726174696f6e12210a0c616374696f6e5f696e64657818022001280d520b616374696f6e496e64657812120a04636f64651803200128095204636f646512140a0573636f7065180420012809520573636f7065121d0a0a7461626c655f6e616d6518052001280952097461626c654e616d65121f0a0b7072696d6172795f6b6579180620012809520a7072696d6172794b6579121b0a096f6c645f706179657218072001280952086f6c645061796572121b0a096e65775f706179657218082001280952086e6577506179657212190a086f6c645f6461746118092001280c52076f6c644461746112190a086e65775f64617461180a2001280c52076e65774461746112220a0d6f6c645f646174615f6a736f6e180b20012809520b6f6c64446174614a736f6e12220a0d6e65775f646174615f6a736f6e180c20012809520b6e6577446174614a736f6e22640a094f7065726174696f6e12150a114f5045524154494f4e5f554e4b4e4f574e100012140a104f5045524154494f4e5f494e53455254100112140a104f5045524154494f4e5f555044415445100212140a104f5045524154494f4e5f52454d4f5645100322e20c0a0552414d4f7012420a096f7065726174696f6e18012001280e32242e73662e616e74656c6f70652e747970652e76312e52414d4f702e4f7065726174696f6e52096f7065726174696f6e12210a0c616374696f6e5f696e64657818022001280d520b616374696f6e496e64657812140a0570617965721803200128095205706179657212140a0564656c7461180420012803520564656c746112140a0575736167651805200128045205757361676512420a096e616d65737061636518062001280e32242e73662e616e74656c6f70652e747970652e76312e52414d4f702e4e616d65737061636552096e616d65737061636512390a06616374696f6e18072001280e32212e73662e616e74656c6f70652e747970652e76312e52414d4f702e416374696f6e5206616374696f6e121d0a0a756e697175655f6b65791808200128095209756e697175654b65792282070a094f7065726174696f6e12150a114f5045524154494f4e5f554e4b4e4f574e1000121a0a164f5045524154494f4e5f4352454154455f5441424c451001121e0a1a4f5045524154494f4e5f44454645525245445f5452585f414444100212210a1d4f5045524154494f4e5f44454645525245445f5452585f43414e43454c100312210a1d4f5045524154494f4e5f44454645525245445f5452585f505553484544100412290a254f5045524154494f4e5f44454645525245445f5452585f52414d5f434f5252454354494f4e100512220a1e4f5045524154494f4e5f44454645525245445f5452585f52454d4f564544100612180a144f5045524154494f4e5f44454c45544541555448100712160a124f5045524154494f4e5f4c494e4b41555448100812180a144f5045524154494f4e5f4e45574143434f554e541009121f0a1b4f5045524154494f4e5f5052494d4152595f494e4445585f414444100a12220a1e4f5045524154494f4e5f5052494d4152595f494e4445585f52454d4f5645100b12220a1e4f5045524154494f4e5f5052494d4152595f494e4445585f555044415445100c12300a2c4f5045524154494f4e5f5052494d4152595f494e4445585f5550444154455f4144445f4e45575f5041594552100d12330a2f4f5045524154494f4e5f5052494d4152595f494e4445585f5550444154455f52454d4f56455f4f4c445f5041594552100e121a0a164f5045524154494f4e5f52454d4f56455f5441424c45100f12210a1d4f5045524154494f4e5f5345434f4e444152595f494e4445585f414444101012240a204f5045524154494f4e5f5345434f4e444152595f494e4445585f52454d4f5645101112320a2e4f5045524154494f4e5f5345434f4e444152595f494e4445585f5550444154455f4144445f4e45575f5041594552101212350a314f5045524154494f4e5f5345434f4e444152595f494e4445585f5550444154455f52454d4f56455f4f4c445f5041594552101312140a104f5045524154494f4e5f534554414249101412150a114f5045524154494f4e5f534554434f4445101512180a144f5045524154494f4e5f554e4c494e4b415554481016121f0a1b4f5045524154494f4e5f555044415445415554485f4352454154451017121f0a1b4f5045524154494f4e5f555044415445415554485f555044415445101812180a144f5045524154494f4e5f44455052454341544544101922fc010a094e616d65737061636512150a114e414d4553504143455f554e4b4e4f574e100012110a0d4e414d4553504143455f414249100112150a114e414d4553504143455f4143434f554e54100212120a0e4e414d4553504143455f41555448100312170a134e414d4553504143455f415554485f4c494e4b100412120a0e4e414d4553504143455f434f44451005121a0a164e414d4553504143455f44454645525245445f5452581006121d0a194e414d4553504143455f5345434f4e444152595f494e444558100712130a0f4e414d4553504143455f5441424c45100812170a134e414d4553504143455f5441424c455f524f5710092204080a100a228d010a06416374696f6e12120a0e414354494f4e5f554e4b4e4f574e1000120e0a0a414354494f4e5f414444100112110a0d414354494f4e5f43414e43454c100212150a11414354494f4e5f434f5252454354494f4e1003120f0a0b414354494f4e5f50555348100412110a0d414354494f4e5f52454d4f5645100512110a0d414354494f4e5f55504441544510062281010a0f52414d436f7272656374696f6e4f7012230a0d636f7272656374696f6e5f6964180120012809520c636f7272656374696f6e4964121d0a0a756e697175655f6b65791802200128095209756e697175654b657912140a0570617965721803200128095205706179657212140a0564656c7461180420012803520564656c746122a1020a075461626c654f7012440a096f7065726174696f6e18012001280e32262e73662e616e74656c6f70652e747970652e76312e5461626c654f702e4f7065726174696f6e52096f7065726174696f6e12210a0c616374696f6e5f696e64657818022001280d520b616374696f6e496e64657812140a0570617965721803200128095205706179657212120a04636f64651804200128095204636f646512140a0573636f7065180520012809520573636f7065121d0a0a7461626c655f6e616d6518062001280952097461626c654e616d65224e0a094f7065726174696f6e12150a114f5045524154494f4e5f554e4b4e4f574e100012140a104f5045524154494f4e5f494e53455254100112140a104f5045524154494f4e5f52454d4f5645100222d1040a06445472784f7012430a096f7065726174696f6e18012001280e32252e73662e616e74656c6f70652e747970652e76312e445472784f702e4f7065726174696f6e52096f7065726174696f6e12210a0c616374696f6e5f696e64657818022001280d520b616374696f6e496e64657812160a0673656e646572180320012809520673656e646572121b0a0973656e6465725f6964180420012809520873656e646572496412140a0570617965721805200128095205706179657212210a0c7075626c69736865645f6174180620012809520b7075626c69736865644174121f0a0b64656c61795f756e74696c180720012809520a64656c6179556e74696c12230a0d65787069726174696f6e5f6174180820012809520c65787069726174696f6e417412250a0e7472616e73616374696f6e5f6964180920012809520d7472616e73616374696f6e496412480a0b7472616e73616374696f6e180a2001280b32262e73662e616e74656c6f70652e747970652e76312e5369676e65645472616e73616374696f6e520b7472616e73616374696f6e22b9010a094f7065726174696f6e12150a114f5045524154494f4e5f554e4b4e4f574e100012140a104f5045524154494f4e5f435245415445100112190a154f5045524154494f4e5f505553485f435245415445100212140a104f5045524154494f4e5f4641494c4544100312140a104f5045524154494f4e5f43414e43454c1004121b0a174f5045524154494f4e5f4d4f444946595f43414e43454c1005121b0a174f5045524154494f4e5f4d4f444946595f435245415445100622e8010a09457874445472784f7012320a15736f757263655f7472616e73616374696f6e5f69641801200128095213736f757263655472616e73616374696f6e4964121b0a09626c6f636b5f6e756d1802200128045208626c6f636b4e756d12190a08626c6f636b5f69641803200128095207626c6f636b496412390a0a626c6f636b5f74696d6518042001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d705209626c6f636b54696d6512340a07647472785f6f7018052001280b321b2e73662e616e74656c6f70652e747970652e76312e445472784f705206647472784f7022e5010a09466561747572654f7012120a046b696e6418012001280952046b696e6412210a0c616374696f6e5f696e64657818022001280d520b616374696f6e496e64657812250a0e666561747572655f646967657374180320012809520d6665617475726544696765737412360a076665617475726518042001280b321c2e73662e616e74656c6f70652e747970652e76312e4665617475726552076665617475726522420a044b696e6412100a0c4b494e445f554e4b4e4f574e100012150a114b494e445f5052455f4143544956415445100112110a0d4b494e445f41435449564154451002227a0a104372656174696f6e466c61744e6f646512300a1463726561746f725f616374696f6e5f696e646578180120012805521263726561746f72416374696f6e496e64657812340a16657865637574696f6e5f616374696f6e5f696e64657818022001280d5214657865637574696f6e416374696f6e496e64657822da020a065065726d4f7012430a096f7065726174696f6e18012001280e32252e73662e616e74656c6f70652e747970652e76312e5065726d4f702e4f7065726174696f6e52096f7065726174696f6e12210a0c616374696f6e5f696e64657818022001280d520b616374696f6e496e64657812400a086f6c645f7065726d18082001280b32252e73662e616e74656c6f70652e747970652e76312e5065726d697373696f6e4f626a65637452076f6c645065726d12400a086e65775f7065726d18092001280b32252e73662e616e74656c6f70652e747970652e76312e5065726d697373696f6e4f626a65637452076e65775065726d22640a094f7065726174696f6e12150a114f5045524154494f4e5f554e4b4e4f574e100012140a104f5045524154494f4e5f494e53455254100112140a104f5045524154494f4e5f555044415445100212140a104f5045524154494f4e5f52454d4f5645100322e6010a105065726d697373696f6e4f626a656374120e0a026964180a2001280452026964121b0a09706172656e745f6964180b200128045208706172656e74496412140a056f776e657218012001280952056f776e657212120a046e616d6518022001280952046e616d65123d0a0c6c6173745f7570646174656418032001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d70520b6c61737455706461746564123c0a09617574686f7269747918042001280b321e2e73662e616e74656c6f70652e747970652e76312e417574686f726974795209617574686f72697479227d0a0a5065726d697373696f6e12120a046e616d6518012001280952046e616d6512160a06706172656e741802200128095206706172656e7412430a0d72657175697265645f6175746818032001280b321e2e73662e616e74656c6f70652e747970652e76312e417574686f72697479520c72657175697265644175746822dc010a09417574686f72697479121c0a097468726573686f6c6418012001280d52097468726573686f6c6412320a046b65797318022003280b321e2e73662e616e74656c6f70652e747970652e76312e4b657957656967687452046b65797312460a086163636f756e747318032003280b322a2e73662e616e74656c6f70652e747970652e76312e5065726d697373696f6e4c6576656c57656967687452086163636f756e747312350a05776169747318042003280b321f2e73662e616e74656c6f70652e747970652e76312e576169745765696768745205776169747322420a094b6579576569676874121d0a0a7075626c69635f6b657918012001280952097075626c69634b657912160a0677656967687418022001280d520677656967687422470a0f5065726d697373696f6e4c6576656c12140a056163746f7218012001280952056163746f72121e0a0a7065726d697373696f6e180220012809520a7065726d697373696f6e22750a155065726d697373696f6e4c6576656c57656967687412440a0a7065726d697373696f6e18012001280b32242e73662e616e74656c6f70652e747970652e76312e5065726d697373696f6e4c6576656c520a7065726d697373696f6e12160a0677656967687418022001280d5206776569676874223f0a0a5761697457656967687412190a08776169745f73656318012001280d52077761697453656312160a0677656967687418022001280d520677656967687422c3030a08526c696d69744f7012450a096f7065726174696f6e18012001280e32272e73662e616e74656c6f70652e747970652e76312e526c696d69744f702e4f7065726174696f6e52096f7065726174696f6e12380a05737461746518022001280b32202e73662e616e74656c6f70652e747970652e76312e526c696d69745374617465480052057374617465123b0a06636f6e66696718032001280b32212e73662e616e74656c6f70652e747970652e76312e526c696d6974436f6e66696748005206636f6e66696712510a0e6163636f756e745f6c696d69747318042001280b32282e73662e616e74656c6f70652e747970652e76312e526c696d69744163636f756e744c696d6974734800520d6163636f756e744c696d697473124e0a0d6163636f756e745f757361676518052001280b32272e73662e616e74656c6f70652e747970652e76312e526c696d69744163636f756e7455736167654800520c6163636f756e745573616765224e0a094f7065726174696f6e12150a114f5045524154494f4e5f554e4b4e4f574e100012140a104f5045524154494f4e5f494e53455254100112140a104f5045524154494f4e5f555044415445100242060a046b696e6422f5030a0b526c696d69745374617465125c0a17617665726167655f626c6f636b5f6e65745f757361676518012001280b32252e73662e616e74656c6f70652e747970652e76312e5573616765416363756d756c61746f72521461766572616765426c6f636b4e65745573616765125c0a17617665726167655f626c6f636b5f6370755f757361676518022001280b32252e73662e616e74656c6f70652e747970652e76312e5573616765416363756d756c61746f72521461766572616765426c6f636b4370755573616765122a0a1170656e64696e675f6e65745f7573616765180320012804520f70656e64696e674e65745573616765122a0a1170656e64696e675f6370755f7573616765180420012804520f70656e64696e67437075557361676512280a10746f74616c5f6e65745f776569676874180520012804520e746f74616c4e657457656967687412280a10746f74616c5f6370755f776569676874180620012804520e746f74616c43707557656967687412260a0f746f74616c5f72616d5f6279746573180720012804520d746f74616c52616d4279746573122a0a117669727475616c5f6e65745f6c696d6974180820012804520f7669727475616c4e65744c696d6974122a0a117669727475616c5f6370755f6c696d6974180920012804520f7669727475616c4370754c696d697422dc020a0c526c696d6974436f6e666967125d0a146370755f6c696d69745f706172616d657465727318012001280b322b2e73662e616e74656c6f70652e747970652e76312e456c61737469634c696d6974506172616d657465727352126370754c696d6974506172616d6574657273125d0a146e65745f6c696d69745f706172616d657465727318022001280b322b2e73662e616e74656c6f70652e747970652e76312e456c61737469634c696d6974506172616d657465727352126e65744c696d6974506172616d657465727312460a206163636f756e745f6370755f75736167655f617665726167655f77696e646f7718032001280d521c6163636f756e7443707555736167654176657261676557696e646f7712460a206163636f756e745f6e65745f75736167655f617665726167655f77696e646f7718042001280d521c6163636f756e744e657455736167654176657261676557696e646f7722a0010a13526c696d69744163636f756e744c696d69747312140a056f776e657218012001280952056f776e657212180a0770656e64696e67180220012808520770656e64696e67121d0a0a6e65745f77656967687418032001280352096e6574576569676874121d0a0a6370755f7765696768741804200128035209637075576569676874121b0a0972616d5f6279746573180520012803520872616d427974657322cf010a12526c696d69744163636f756e74557361676512140a056f776e657218012001280952056f776e657212420a096e65745f757361676518022001280b32252e73662e616e74656c6f70652e747970652e76312e5573616765416363756d756c61746f7252086e6574557361676512420a096370755f757361676518032001280b32252e73662e616e74656c6f70652e747970652e76312e5573616765416363756d756c61746f7252086370755573616765121b0a0972616d5f7573616765180420012804520872616d5573616765226c0a105573616765416363756d756c61746f7212210a0c6c6173745f6f7264696e616c18012001280d520b6c6173744f7264696e616c12190a0876616c75655f6578180220012804520776616c75654578121a0a08636f6e73756d65641803200128045208636f6e73756d65642281020a16456c61737469634c696d6974506172616d657465727312160a06746172676574180120012804520674617267657412100a036d617818022001280452036d617812180a07706572696f647318032001280d5207706572696f647312250a0e6d61785f6d756c7469706c69657218042001280d520d6d61784d756c7469706c696572123f0a0d636f6e74726163745f7261746518052001280b321a2e73662e616e74656c6f70652e747970652e76312e526174696f520c636f6e747261637452617465123b0a0b657870616e645f7261746518062001280b321a2e73662e616e74656c6f70652e747970652e76312e526174696f520a657870616e645261746522470a05526174696f121c0a096e756d657261746f7218012001280452096e756d657261746f7212200a0b64656e6f6d696e61746f72180220012804520b64656e6f6d696e61746f7222ae040a09457863657074696f6e12120a04636f64651801200128055204636f646512120a046e616d6518022001280952046e616d6512180a076d65737361676518032001280952076d657373616765123f0a05737461636b18042003280b32292e73662e616e74656c6f70652e747970652e76312e457863657074696f6e2e4c6f674d6573736167655205737461636b1a7d0a0a4c6f674d65737361676512430a07636f6e7465787418012001280b32292e73662e616e74656c6f70652e747970652e76312e457863657074696f6e2e4c6f67436f6e746578745207636f6e7465787412160a06666f726d61741802200128095206666f726d617412120a046461746118042001280c5204646174611a9e020a0a4c6f67436f6e7465787412140a056c6576656c18012001280952056c6576656c12120a0466696c65180220012809520466696c6512120a046c696e6518032001280552046c696e6512160a066d6574686f6418042001280952066d6574686f64121a0a08686f73746e616d651805200128095208686f73746e616d65121f0a0b7468726561645f6e616d65180620012809520a7468726561644e616d6512380a0974696d657374616d7018072001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d70520974696d657374616d7012430a07636f6e7465787418082001280b32292e73662e616e74656c6f70652e747970652e76312e457863657074696f6e2e4c6f67436f6e746578745207636f6e7465787422e7020a074665617475726512250a0e666561747572655f646967657374180120012809520d6665617475726544696765737412640a177375626a6563746976655f7265737472696374696f6e7318022001280b322b2e73662e616e74656c6f70652e747970652e76312e5375626a6563746976655265737472696374696f6e7352167375626a6563746976655265737472696374696f6e73122d0a126465736372697074696f6e5f64696765737418032001280952116465736372697074696f6e44696765737412220a0c646570656e64656e63696573180420032809520c646570656e64656e6369657312320a1570726f746f636f6c5f666561747572655f74797065180520012809521370726f746f636f6c466561747572655479706512480a0d73706563696669636174696f6e18062003280b32222e73662e616e74656c6f70652e747970652e76312e53706563696669636174696f6e520d73706563696669636174696f6e22b2010a165375626a6563746976655265737472696374696f6e7312180a07656e61626c65641801200128085207656e61626c656412350a1670726561637469766174696f6e5f7265717569726564180220012808521570726561637469766174696f6e526571756972656412470a206561726c696573745f616c6c6f7765645f61637469766174696f6e5f74696d65180320012809521d6561726c69657374416c6c6f77656441637469766174696f6e54696d6522390a0d53706563696669636174696f6e12120a046e616d6518012001280952046e616d6512140a0576616c7565180220012809520576616c756522e2010a124163636f756e744372656174696f6e52656612180a076163636f756e7418012001280952076163636f756e7412180a0763726561746f72180220012809520763726561746f72121b0a09626c6f636b5f6e756d1803200128045208626c6f636b4e756d12190a08626c6f636b5f69641804200128095207626c6f636b496412390a0a626c6f636b5f74696d6518052001280b321a2e676f6f676c652e70726f746f6275662e54696d657374616d705209626c6f636b54696d6512250a0e7472616e73616374696f6e5f6964180620012809520d7472616e73616374696f6e496422c4010a0f4865616465724f6e6c79426c6f636b120e0a0269641801200128095202696412160a066e756d62657218022001280d52066e756d62657212380a0668656164657218042001280b32202e73662e616e74656c6f70652e747970652e76312e426c6f636b4865616465725206686561646572124f0a10626c6f636b726f6f745f6d65726b6c65180b2001280b32242e73662e616e74656c6f70652e747970652e76312e426c6f636b526f6f744d65726b6c65520f626c6f636b726f6f744d65726b6c652297010a1c5472616e73616374696f6e547261636557697468426c6f636b526566123b0a05747261636518012001280b32252e73662e616e74656c6f70652e747970652e76312e5472616e73616374696f6e547261636552057472616365123a0a09626c6f636b5f72656618022001280b321d2e73662e616e74656c6f70652e747970652e76312e426c6f636b5265665208626c6f636b52656622360a08426c6f636b52656612120a046861736818012001280c52046861736812160a066e756d62657218022001280452066e756d6265722aba010a12426c6f636b5265766572736962696c697479121b0a17424c4f434b5245564552534942494c4954595f4e4f4e45100012210a1d424c4f434b5245564552534942494c4954595f52455645525349424c45100112230a1f424c4f434b5245564552534942494c4954595f495252455645525349424c451002121c0a18424c4f434b5245564552534942494c4954595f5354414c45100312210a1d424c4f434b5245564552534942494c4954595f4d415942455354414c4510042a8c020a115472616e73616374696f6e537461747573121a0a165452414e53414354494f4e5354415455535f4e4f4e451000121e0a1a5452414e53414354494f4e5354415455535f45584543555445441001121e0a1a5452414e53414354494f4e5354415455535f534f46544641494c1002121e0a1a5452414e53414354494f4e5354415455535f484152444641494c1003121d0a195452414e53414354494f4e5354415455535f44454c415945441004121d0a195452414e53414354494f4e5354415455535f455850495245441005121d0a195452414e53414354494f4e5354415455535f554e4b4e4f574e1006121e0a1a5452414e53414354494f4e5354415455535f43414e43454c4544100742545a526769746875622e636f6d2f73747265616d696e67666173742f66697265686f73652d616e74656c6f70652f74797065732f70622f73662f616e74656c6f70652f747970652f76313b7062616e74656c6f7065620670726f746f33", }, + { + // sf/arweave/type/v1/type.proto (https://buf.build/pinax/firehose-arweave/docs/eeea46c6211b43189e1af8bb682b3bc6:sf.arweave.type.v1) + proto: "0a1d73662f617277656176652f747970652f76312f747970652e70726f746f121273662e617277656176652e747970652e7631221e0a06426967496e7412140a05627974657318012001280c5205627974657322a6060a05426c6f636b12100a0376657218012001280d5203766572121d0a0a696e6465705f6861736818022001280c5209696e6465704861736812140a056e6f6e636518032001280c52056e6f6e636512250a0e70726576696f75735f626c6f636b18042001280c520d70726576696f7573426c6f636b121c0a0974696d657374616d70180520012804520974696d657374616d7012230a0d6c6173745f7265746172676574180620012804520c6c6173745265746172676574122e0a046469666618072001280b321a2e73662e617277656176652e747970652e76312e426967496e7452046469666612160a06686569676874180820012804520668656967687412120a046861736818092001280c52046861736812170a0774785f726f6f74180a2001280c52067478526f6f7412310a03747873180b2003280b321f2e73662e617277656176652e747970652e76312e5472616e73616374696f6e5203747873121f0a0b77616c6c65745f6c697374180c2001280c520a77616c6c65744c697374121f0a0b7265776172645f61646472180d2001280c520a72657761726441646472122b0a0474616773180e2003280b32172e73662e617277656176652e747970652e76312e546167520474616773123b0a0b7265776172645f706f6f6c180f2001280b321a2e73662e617277656176652e747970652e76312e426967496e74520a726577617264506f6f6c12390a0a77656176655f73697a6518102001280b321a2e73662e617277656176652e747970652e76312e426967496e745209776561766553697a6512390a0a626c6f636b5f73697a6518112001280b321a2e73662e617277656176652e747970652e76312e426967496e745209626c6f636b53697a6512430a0f63756d756c61746976655f6469666618122001280b321a2e73662e617277656176652e747970652e76312e426967496e74520e63756d756c61746976654469666612280a10686173685f6c6973745f6d65726b6c6518142001280c520e686173684c6973744d65726b6c6512330a03706f6118152001280b32212e73662e617277656176652e747970652e76312e50726f6f664f664163636573735203706f6122730a0d50726f6f664f6641636365737312160a066f7074696f6e18012001280952066f7074696f6e12170a0774785f7061746818022001280c5206747850617468121b0a09646174615f7061746818032001280c5208646174615061746812140a056368756e6b18042001280c52056368756e6b229d030a0b5472616e73616374696f6e12160a06666f726d617418012001280d5206666f726d6174120e0a02696418022001280c5202696412170a076c6173745f747818032001280c52066c617374547812140a056f776e657218042001280c52056f776e6572122b0a047461677318052003280b32172e73662e617277656176652e747970652e76312e54616752047461677312160a0674617267657418062001280c520674617267657412360a087175616e7469747918072001280b321a2e73662e617277656176652e747970652e76312e426967496e7452087175616e7469747912120a046461746118082001280c52046461746112370a09646174615f73697a6518092001280b321a2e73662e617277656176652e747970652e76312e426967496e7452086461746153697a65121b0a09646174615f726f6f74180a2001280c520864617461526f6f74121c0a097369676e6174757265180b2001280c52097369676e617475726512320a06726577617264180c2001280b321a2e73662e617277656176652e747970652e76312e426967496e745206726577617264222f0a0354616712120a046e616d6518012001280c52046e616d6512140a0576616c756518022001280c520576616c756542515a4f6769746875622e636f6d2f70696e61782d6e6574776f726b2f66697265686f73652d617277656176652f74797065732f70622f73662f617277656176652f747970652f76313b706261727765617665620670726f746f33", + }, } } From cdcdb15879399f149b5cf1d730fa0d6ada7596ca Mon Sep 17 00:00:00 2001 From: billettc Date: Fri, 9 Feb 2024 11:17:57 -0500 Subject: [PATCH 38/44] fix compilation issues --- blockpoller/poller.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blockpoller/poller.go b/blockpoller/poller.go index a8281d2..0daffd9 100644 --- a/blockpoller/poller.go +++ b/blockpoller/poller.go @@ -304,7 +304,7 @@ func (p *BlockPoller) fetchBlockWithHash(blkNum uint64, hash string) (*pbbstream } if p.forceFinalityAfterBlocks != nil { - utils.TweakBlockFinality(blk, *p.forceFinalityAfterBlocks) + utils.TweakBlockFinality(out, *p.forceFinalityAfterBlocks) } return out, nil From 6ef5d200c68fd14781a85bd445ff70ec1c3476d9 Mon Sep 17 00:00:00 2001 From: billettc Date: Fri, 9 Feb 2024 11:20:22 -0500 Subject: [PATCH 39/44] change log --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84c3b55..07aa5a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,18 @@ Operators, you should copy/paste content of this content straight to your projec If you were at `firehose-core` version `1.0.0` and are bumping to `1.1.0`, you should copy the content between those 2 version to your own repository, replacing placeholder value `fire{chain}` with your chain's own binary. +## UNRELEASED + +* Poller is now fetching blocks in an optimized way, it will fetch several blocks at once and then process them. + +* Poller is now handling skipped blocks, it will fetch the next blocks until it find a none skipped block. + +* Compare tool is now using dynamic protobuf unmarshaler, it will be able to compare any block type. + +* Print tool is now using dynamic protobuf unmarshaler, it will be able to print any block type. + +* Print tool is encoding bytes in base64 by default, it can be changed to hex or base58 by using parameter `bytes-encoding`. + ## v1.1.3 * Removed useless chainLatestFinalizeBlock from blockPoller initialization From 69c1ad3ef6cf763d198faa1ab8f0532b0c338e5e Mon Sep 17 00:00:00 2001 From: billettc Date: Fri, 9 Feb 2024 11:30:05 -0500 Subject: [PATCH 40/44] remove hardcode stuff --- cmd/tools/compare/tools_compare_blocks.go | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/cmd/tools/compare/tools_compare_blocks.go b/cmd/tools/compare/tools_compare_blocks.go index e68cf96..2211189 100644 --- a/cmd/tools/compare/tools_compare_blocks.go +++ b/cmd/tools/compare/tools_compare_blocks.go @@ -18,7 +18,6 @@ import ( "context" "fmt" "io" - "os" "reflect" "strconv" "sync" @@ -377,24 +376,6 @@ func Compare(reference proto.Message, current proto.Message, includeUnknownField c, err := jd.ReadJsonString(currentAsJSON) cli.NoError(err, "read JSON current") - //Get the r and the c and print them within a file for further analysis - - referenceWriter, err := os.Create("/Users/arnaudberger/t/reference.json") - if err != nil { - fmt.Println(err) - } - defer referenceWriter.Close() - currentWriter, err := os.Create("/Users/arnaudberger/t/current.json") - if err != nil { - fmt.Println(err) - } - - defer currentWriter.Close() - - referenceWriter.WriteString(referenceAsJSON) - currentWriter.WriteString(currentAsJSON) - - //todo: manage better output off differences if diff := r.Diff(c).Render(); diff != "" { differences = append(differences, diff) From c2962488009af4f1f668d35a230c4f867c05f1b1 Mon Sep 17 00:00:00 2001 From: billettc Date: Fri, 9 Feb 2024 11:38:35 -0500 Subject: [PATCH 41/44] fix blocks being replaced by optimisticlyPolledBlocks in string and doc --- blockpoller/init_test.go | 4 ++-- blockpoller/poller.go | 4 ++-- blockpoller/poller_test.go | 2 +- blockpoller/state_file_test.go | 2 +- node-manager/boot/eos_jungle/config.ini | 2 +- node-manager/boot/eos_mainnet/config.ini | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/blockpoller/init_test.go b/blockpoller/init_test.go index 2ac934a..75b5545 100644 --- a/blockpoller/init_test.go +++ b/blockpoller/init_test.go @@ -71,7 +71,7 @@ func (b *TestBlockFetcher) Fetch(_ context.Context, blkNum uint64) (*pbbstream.B func (b *TestBlockFetcher) check(t *testing.T) { t.Helper() - require.Equal(b.t, uint64(len(b.blocks)), b.idx, "we should have fetched all %d optimisticlyPolledBlocks, only fired %d optimisticlyPolledBlocks", len(b.blocks), b.idx) + require.Equal(b.t, uint64(len(b.blocks)), b.idx, "we should have fetched all %d blocks, only fired %d blocks", len(b.blocks), b.idx) } var _ BlockHandler = &TestBlockFinalizer{} @@ -112,7 +112,7 @@ func (t *TestBlockFinalizer) Handle(blk *pbbstream.Block) error { func (b *TestBlockFinalizer) check(t *testing.T) { t.Helper() - require.Equal(b.t, uint64(len(b.fireBlocks)), b.idx, "we should have fired all %d optimisticlyPolledBlocks, only fired %d optimisticlyPolledBlocks", len(b.fireBlocks), b.idx) + require.Equal(b.t, uint64(len(b.fireBlocks)), b.idx, "we should have fired all %d blocks, only fired %d blocks", len(b.fireBlocks), b.idx) } var _ BlockHandler = &TestNoopBlockFinalizer{} diff --git a/blockpoller/poller.go b/blockpoller/poller.go index 0daffd9..1e5c79e 100644 --- a/blockpoller/poller.go +++ b/blockpoller/poller.go @@ -339,14 +339,14 @@ func (p *BlockPoller) fire(blk *block) (bool, error) { func nextBlkInSeg(blocks []*forkable.Block) uint64 { if len(blocks) == 0 { - panic(fmt.Errorf("the optimisticlyPolledBlocks segments should never be empty")) + panic(fmt.Errorf("the blocks segments should never be empty")) } return blocks[len(blocks)-1].BlockNum + 1 } func prevBlockInSegment(blocks []*forkable.Block) (uint64, *string) { if len(blocks) == 0 { - panic(fmt.Errorf("the optimisticlyPolledBlocks segments should never be empty")) + panic(fmt.Errorf("the blocks segments should never be empty")) } blockObject := blocks[0].Object.(*block) return blockObject.ParentNum, &blockObject.ParentId diff --git a/blockpoller/poller_test.go b/blockpoller/poller_test.go index 720d010..fbb0406 100644 --- a/blockpoller/poller_test.go +++ b/blockpoller/poller_test.go @@ -121,7 +121,7 @@ func TestForkHandler_run(t *testing.T) { }, }, { - name: "with skipping optimisticlyPolledBlocks", + name: "with skipping blocks", startBlock: blk("100a", "99a", 100).AsRef(), blocks: []*TestBlock{ tb("100a", "99a", 100), diff --git a/blockpoller/state_file_test.go b/blockpoller/state_file_test.go index 804e99d..3e410c8 100644 --- a/blockpoller/state_file_test.go +++ b/blockpoller/state_file_test.go @@ -33,7 +33,7 @@ func TestFireBlockFinalizer_state(t *testing.T) { fk.AddLink(bstream.NewBlockRef("106a", 106), "105a", &block{Block: blk("106a", "105a", 101)}) fk.AddLink(bstream.NewBlockRef("105a", 105), "104a", &block{Block: blk("105a", "104a", 101)}) expectedBlocks, reachedLib := fk.CompleteSegment(blk("105a", "104a", 101).AsRef()) - // simulate firing the optimisticlyPolledBlocks + // simulate firing the blocks for _, blk := range expectedBlocks { blk.Object.(*block).fired = true } diff --git a/node-manager/boot/eos_jungle/config.ini b/node-manager/boot/eos_jungle/config.ini index 1c5b690..f55ba3d 100644 --- a/node-manager/boot/eos_jungle/config.ini +++ b/node-manager/boot/eos_jungle/config.ini @@ -6,7 +6,7 @@ connection-cleanup-period = 60 verbose-http-errors = true chain-state-db-size-mb = 64000 # shared-memory-size-mb = 2048 -reversible-optimisticlyPolledBlocks-db-size-mb = 2048 +reversible-blocks-db-size-mb = 2048 http-validate-host = false max-transaction-time = 5000 abi-serializer-max-time-ms = 500000 diff --git a/node-manager/boot/eos_mainnet/config.ini b/node-manager/boot/eos_mainnet/config.ini index e73da15..26bd919 100644 --- a/node-manager/boot/eos_mainnet/config.ini +++ b/node-manager/boot/eos_mainnet/config.ini @@ -5,7 +5,7 @@ p2p-max-nodes-per-host = 2 connection-cleanup-period = 60 verbose-http-errors = true chain-state-db-size-mb = 64000 -reversible-optimisticlyPolledBlocks-db-size-mb = 2048 +reversible-blocks-db-size-mb = 2048 # shared-memory-size-mb = 2048 http-validate-host = false max-transaction-time = 5000 From e931cdca8a39d879d4630b58c1255abb9efbc5c2 Mon Sep 17 00:00:00 2001 From: billettc Date: Fri, 16 Feb 2024 09:55:05 -0500 Subject: [PATCH 42/44] bump to go 1.22 --- .github/workflows/docker.yml | 2 +- Dockerfile | 2 +- go.mod | 2 +- proto/registry.go | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index f764d36..68d9874 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: - go-version: [ 1.20.x ] + go-version: [ 1.22.x ] outputs: tags: ${{ steps.meta.outputs.tags }} diff --git a/Dockerfile b/Dockerfile index 764a9a8..c891343 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.21-alpine as build +FROM golang:1.22-alpine as build WORKDIR /app COPY go.mod go.sum ./ diff --git a/go.mod b/go.mod index 84bd132..d310850 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/streamingfast/firehose-core -go 1.21 +go 1.22 require ( buf.build/gen/go/bufbuild/reflect/connectrpc/go v1.12.0-20230822193137-310c9c4845dd.1 diff --git a/proto/registry.go b/proto/registry.go index 7df761d..c975a87 100644 --- a/proto/registry.go +++ b/proto/registry.go @@ -63,6 +63,7 @@ func (r *Registry) RegisterFiles(files []string) error { return r.RegisterFileDescriptors(fileDescriptors) } + func (r *Registry) RegisterFileDescriptors(fds []protoreflect.FileDescriptor) error { for _, fd := range fds { err := r.RegisterFileDescriptor(fd) From 764b793926e4141c90e5d94ba16261c4a77ab407 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Duchesneau?= Date: Fri, 16 Feb 2024 10:38:32 -0500 Subject: [PATCH 43/44] put back the SanitizeBlockForCompare method, now with pbbstream block --- chain.go | 17 ++++++++++++++++- cmd/tools/compare/tools_compare_blocks.go | 10 ++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/chain.go b/chain.go index 05ae9ab..8268aa2 100644 --- a/chain.go +++ b/chain.go @@ -21,7 +21,7 @@ import ( // SanitizeBlockForCompareFunc takes a chain agnostic [block] and transforms it in-place, removing fields // that should not be compared. -type SanitizeBlockForCompareFunc[B Block] func(block B) B +type SanitizeBlockForCompareFunc func(block *pbbstream.Block) *pbbstream.Block // Chain is the omni config object for configuring your chain specific information. It contains various // fields that are used everywhere to properly configure the `firehose-` binary. @@ -154,6 +154,12 @@ type Chain[B Block] struct { } type ToolsConfig[B Block] struct { + // SanitizeBlockForCompare is a function that takes a chain agnostic [block] and transforms it in-place, removing fields + // that should not be compared. + // + // The [SanitizeBlockForCompare] is optional, if nil, no-op sanitizer be used. + SanitizeBlockForCompare SanitizeBlockForCompareFunc + // RegisterExtraCmd enables you to register extra commands to the `fire tools` group. // The callback function is called with the `toolsCmd` command that is the root command of the `fire tools` // as well as the chain, the root logger and root tracer for tools. @@ -183,6 +189,15 @@ type ToolsConfig[B Block] struct { MergedBlockUpgrader func(block *pbbstream.Block) (*pbbstream.Block, error) } +// GetSanitizeBlockForCompare returns the [SanitizeBlockForCompare] value if defined, otherwise a no-op sanitizer. +func (t *ToolsConfig[B]) GetSanitizeBlockForCompare() SanitizeBlockForCompareFunc { + if t == nil || t.SanitizeBlockForCompare == nil { + return func(block *pbbstream.Block) *pbbstream.Block { return block } + } + + return t.SanitizeBlockForCompare +} + type TransformFlags struct { // Register is a function that will be called when we need to register the flags for the transforms. // You received the command's flag set and you are responsible of registering the flags. diff --git a/cmd/tools/compare/tools_compare_blocks.go b/cmd/tools/compare/tools_compare_blocks.go index 2211189..063a116 100644 --- a/cmd/tools/compare/tools_compare_blocks.go +++ b/cmd/tools/compare/tools_compare_blocks.go @@ -81,6 +81,7 @@ func NewToolsCompareBlocksCmd[B firecore.Block](chain *firecore.Chain[B]) *cobra } func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.CommandExecutor { + return func(cmd *cobra.Command, args []string) error { displayDiff := sflags.MustGetBool(cmd, "diff") includeUnknownFields := sflags.MustGetBool(cmd, "include-unknown-fields") @@ -123,6 +124,8 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm return fmt.Errorf("creating registry: %w", err) } + sanitizer := chain.Tools.GetSanitizeBlockForCompare() + err = storeReference.Walk(ctx, check.WalkBlockPrefix(blockRange, 100), func(filename string) (err error) { fileStartBlock, err := strconv.Atoi(filename) if err != nil { @@ -153,6 +156,7 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm uint64(fileStartBlock), stopBlock, &warnAboutExtraBlocks, + sanitizer, registry, ) if err != nil { @@ -171,6 +175,7 @@ func runCompareBlocksE[B firecore.Block](chain *firecore.Chain[B]) firecore.Comm uint64(fileStartBlock), stopBlock, &warnAboutExtraBlocks, + sanitizer, registry, ) if err != nil { @@ -234,6 +239,7 @@ func readBundle( fileStartBlock, stopBlock uint64, warnAboutExtraBlocks *sync.Once, + sanitizer firecore.SanitizeBlockForCompareFunc, registry *fcproto.Registry, ) ([]string, map[string]*dynamicpb.Message, map[string]uint64, error) { fileReader, err := store.OpenObject(ctx, filename) @@ -268,6 +274,10 @@ func readBundle( continue } + if sanitizer != nil { + curBlock = sanitizer(curBlock) + } + curBlockPB, err := registry.Unmarshal(curBlock.Payload) if err != nil { From 59b50257d636d79476e7838017f55e01468a76e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Duchesneau?= Date: Fri, 16 Feb 2024 11:08:28 -0500 Subject: [PATCH 44/44] default poller retries infinite --- CHANGELOG.md | 2 ++ blockpoller/poller.go | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56813cb..a924cfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ If you were at `firehose-core` version `1.0.0` and are bumping to `1.1.0`, you s * Poller is now handling skipped blocks, it will fetch the next blocks until it find a none skipped block. +* Poller now has default retry value of infinite. + * Compare tool is now using dynamic protobuf unmarshaler, it will be able to compare any block type. * Print tool is now using dynamic protobuf unmarshaler, it will be able to print any block type. diff --git a/blockpoller/poller.go b/blockpoller/poller.go index 1e5c79e..08198f2 100644 --- a/blockpoller/poller.go +++ b/blockpoller/poller.go @@ -3,6 +3,7 @@ package blockpoller import ( "context" "fmt" + "math" "github.com/streamingfast/bstream" "github.com/streamingfast/bstream/forkable" @@ -50,7 +51,7 @@ func New( Shutter: shutter.New(), blockFetcher: blockFetcher, blockHandler: blockHandler, - fetchBlockRetryCount: 4, + fetchBlockRetryCount: math.MaxUint64, logger: zap.NewNop(), forceFinalityAfterBlocks: utils.GetEnvForceFinalityAfterBlocks(), } @@ -62,10 +63,11 @@ func New( return b } -func (p *BlockPoller) Run(ctx context.Context, startBlockNum uint64, numberOfBlockToFetch int) error { +func (p *BlockPoller) Run(ctx context.Context, startBlockNum uint64, blockFetchBatchSize int) error { p.startBlockNumGate = startBlockNum p.logger.Info("starting poller", zap.Uint64("start_block_num", startBlockNum), + zap.Uint64("block_fetch_batch_size", uint64(blockFetchBatchSize)), ) p.blockHandler.Init() @@ -78,7 +80,7 @@ func (p *BlockPoller) Run(ctx context.Context, startBlockNum uint64, numberOfBlo startBlockNum++ continue } - return p.run(startBlock.AsRef(), numberOfBlockToFetch) + return p.run(startBlock.AsRef(), blockFetchBatchSize) } }