diff --git a/cmd/main.go b/cmd/main.go index 833b45a..91bd2d4 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -16,6 +16,7 @@ import ( dauthsecret "github.com/streamingfast/dauth/secret" dauthtrust "github.com/streamingfast/dauth/trust" "github.com/streamingfast/dmetering" + dmeteringfile "github.com/streamingfast/dmetering/file" dmeteringgrpc "github.com/streamingfast/dmetering/grpc" dmeteringlogger "github.com/streamingfast/dmetering/logger" firecore "github.com/streamingfast/firehose-core" @@ -43,6 +44,7 @@ func Main[B firecore.Block](chain *firecore.Chain[B]) { dmetering.RegisterNull() dmeteringgrpc.Register() dmeteringlogger.Register() + dmeteringfile.Register() paymentGatewayMetering.Register() chain.Validate() diff --git a/devel/standard/standard.yaml b/devel/standard/standard.yaml index e83984d..7736f8a 100644 --- a/devel/standard/standard.yaml +++ b/devel/standard/standard.yaml @@ -4,8 +4,6 @@ start: - merger - relayer - firehose - - substreams-tier1 - - substreams-tier2 flags: advertise-block-id-encoding: "hex" advertise-chain-name: "acme-dummy-blockchain" diff --git a/firehose/info/endpoint_info.go b/firehose/info/endpoint_info.go index e57ab9b..c2c4888 100644 --- a/firehose/info/endpoint_info.go +++ b/firehose/info/endpoint_info.go @@ -108,6 +108,7 @@ func (s *InfoServer) getBlockFromMergedBlocksStore(ctx context.Context, blockNum time.Sleep(time.Millisecond * 500) continue } + return block } } diff --git a/go.mod b/go.mod index dea2a03..abf9bc1 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,7 @@ require ( github.com/streamingfast/derr v0.0.0-20230515163924-8570aaa43fe1 github.com/streamingfast/dgrpc v0.0.0-20240423143010-f36784700c9a github.com/streamingfast/dhammer v0.0.0-20230125192823-c34bbd561bd4 - github.com/streamingfast/dmetering v0.0.0-20240816165719-51768d3da951 + github.com/streamingfast/dmetering v0.0.0-20241007182823-f92200a54cdb github.com/streamingfast/dmetrics v0.0.0-20230919161904-206fa8ebd545 github.com/streamingfast/dstore v0.1.1-0.20240826190906-91345d4a31f2 github.com/streamingfast/jsonpb v0.0.0-20210811021341-3670f0aa02d0 @@ -175,7 +175,7 @@ require ( go.uber.org/automaxprocs v1.5.1 golang.org/x/crypto v0.23.0 // indirect golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.23.0 // indirect + golang.org/x/net v0.23.0 golang.org/x/oauth2 v0.18.0 golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.24.0 // indirect diff --git a/go.sum b/go.sum index 3e635cf..acb9a36 100644 --- a/go.sum +++ b/go.sum @@ -551,8 +551,8 @@ github.com/streamingfast/dgrpc v0.0.0-20240423143010-f36784700c9a h1:JwAGZ7f5vkB github.com/streamingfast/dgrpc v0.0.0-20240423143010-f36784700c9a/go.mod h1:EPtUX/vhRphE37Zo6sDcgD/S3sm5YqXHhxAgzS6Ebwo= 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-20240816165719-51768d3da951 h1:6o6MS3JHrp9A7V6EBHbR7W7mzVCFmXc8U0AjTfvz7PI= -github.com/streamingfast/dmetering v0.0.0-20240816165719-51768d3da951/go.mod h1:UqWuX3REU/IInBUaymFN2eLjuvz+/0SsoUFjeQlLNyI= +github.com/streamingfast/dmetering v0.0.0-20241007182823-f92200a54cdb h1:SooWpzSSU04Z321lLWS6OkTAgoXH0qQEv5mVUi4b+q8= +github.com/streamingfast/dmetering v0.0.0-20241007182823-f92200a54cdb/go.mod h1:UqWuX3REU/IInBUaymFN2eLjuvz+/0SsoUFjeQlLNyI= github.com/streamingfast/dmetrics v0.0.0-20230919161904-206fa8ebd545 h1:SUl04bZKGAv207lp7/6CHOJIRpjUKunwItrno3K463Y= github.com/streamingfast/dmetrics v0.0.0-20230919161904-206fa8ebd545/go.mod h1:JbxEDbzWRG1dHdNIPrYfuPllEkktZMgm40AwVIBENcw= github.com/streamingfast/dstore v0.1.1-0.20240826190906-91345d4a31f2 h1:BB3VSDl8/OHBSvjqfgufwqr4tD5l7XPjXybDm6uudj4= diff --git a/test/integration_test.go b/test/integration_test.go new file mode 100644 index 0000000..62f1fff --- /dev/null +++ b/test/integration_test.go @@ -0,0 +1,226 @@ +package test + +import ( + "fmt" + "io" + "os" + "os/exec" + "path/filepath" + "testing" + "time" + + _ "github.com/streamingfast/dmetering/file" + "github.com/streamingfast/substreams/client" + "github.com/streamingfast/substreams/manifest" + pbsubstreamsrpc "github.com/streamingfast/substreams/pb/sf/substreams/rpc/v2" + "github.com/stretchr/testify/require" + "golang.org/x/net/context" +) + +type Case struct { + name string + spkgRootPath string + moduleName string + startBlock uint64 + // set endBlock to 0 to connect live + endBlock uint64 + expectedReadBytes float64 +} + +func TestIntegration(t *testing.T) { + if os.Getenv("RUN_INTEGRATION_TESTS") != "true" { + t.Skip() + } + + cases := []Case{ + { + name: "sunny path", + spkgRootPath: "./substreams_acme/substreams-acme-v0.1.0.spkg", + moduleName: "map_test_data", + startBlock: 0, + endBlock: 1000, + expectedReadBytes: 696050, + }, + + { + name: "sunny path", + spkgRootPath: "./substreams_acme/substreams-acme-v0.1.0.spkg", + moduleName: "map_test_data", + startBlock: 0, + endBlock: 0, + expectedReadBytes: 696050, + }, + } + + ctx := context.Background() + + rootPath, err := filepath.Abs("../") + if err != nil { + t.Fatalf("getting absolute path: %v", err) + } + + go func() { + err = runTier1(ctx, t, rootPath) + require.NoError(t, err) + }() + + go func() { + err = runTier2(ctx, t, rootPath) + require.NoError(t, err) + }() + + var meteringServer *MeteringTestServer + go func() { + meteringServer = NewMeteringServer(t, ":10016") + meteringServer.Run() + }() + + clientConfig := client.NewSubstreamsClientConfig("localhost:9003", "", 0, false, true) + substreamsClient, _, _, _, err := client.NewSubstreamsClient(clientConfig) + require.NoError(t, err) + + // WAIT SERVERS TO BE READY + time.Sleep(15 * time.Second) + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + if c.endBlock == 0 { + // RUN LIVE + go func() { + err = runDummyNode(ctx, t) + require.NoError(t, err) + }() + } + + err = requestTier1(ctx, t, c, substreamsClient) + require.NoError(t, err) + + resultEvents := meteringServer.bufferedEvents + var totalReadBytes float64 + for _, events := range resultEvents { + for _, event := range events.Events { + for _, metric := range event.Metrics { + // TODO : CHOOSE THE RIGHT METRIC + if metric.Key == "file_uncompressed_read_bytes" { + totalReadBytes += metric.Value + } + } + } + } + + require.Equal(t, c.expectedReadBytes, totalReadBytes) + meteringServer.clearBufferedEvents() + }) + } +} + +func runTier1(ctx context.Context, t *testing.T, rootDir string) error { + cmdPath := filepath.Join(rootDir, "/cmd/firecore") + firehoseDataStoragePath := filepath.Join(rootDir, "devel/standard/firehose-data/storage/") + mergedBlocksStore := fmt.Sprintf("file://%s", filepath.Join(firehoseDataStoragePath, "merged-blocks")) + forkedBlocksStore := fmt.Sprintf("file://%s", filepath.Join(firehoseDataStoragePath, "forked-blocks")) + oneBlocksStore := fmt.Sprintf("file://%s", filepath.Join(firehoseDataStoragePath, "one-blocks")) + + tier1Args := []string{ + "run", + cmdPath, + "start", "substreams-tier1", + "--config-file=", + "--log-to-file=false", + "--common-auth-plugin=null://", + fmt.Sprintf("--common-tmp-dir=%s", t.TempDir()), + fmt.Sprintf("--common-metering-plugin=grpc://localhost:10016?network=dummy_blockchain"), + "--common-system-shutdown-signal-delay=30s", + fmt.Sprintf("--common-merged-blocks-store-url=%s", mergedBlocksStore), + fmt.Sprintf("--common-one-block-store-url=%s", oneBlocksStore), + fmt.Sprintf("--common-forked-blocks-store-url=%s", forkedBlocksStore), + "--common-live-blocks-addr=localhost:10014", + "--common-first-streamable-block=0", + "--substreams-tier1-grpc-listen-addr=:9003", + "--substreams-tier1-subrequests-endpoint=localhost:9004", + "--substreams-tier1-subrequests-insecure=false", + "--substreams-tier1-subrequests-plaintext=true", + fmt.Sprintf("--substreams-state-store-url=%s/substreams_dummy", t.TempDir()), + "--substreams-state-store-default-tag=vtestdummy", + } + + tier1Cmd := exec.CommandContext(ctx, "go", tier1Args...) + + err := handlingTestInstance(t, tier1Cmd, "TIER1", true) + if err != nil { + return fmt.Errorf("handling instance %w", err) + } + + return err +} + +func runTier2(ctx context.Context, t *testing.T, rootDir string) error { + cmdPath := rootDir + "/cmd/firecore" + tier2Args := []string{ + "run", + cmdPath, + "start", "substreams-tier2", + "--config-file=", + "--log-to-file=false", + fmt.Sprintf("--common-tmp-dir=%s", t.TempDir()), + "--substreams-tier2-grpc-listen-addr=:9004", + "--substreams-tier1-subrequests-plaintext=true", + "--substreams-tier1-subrequests-insecure=false", + } + + tier2Cmd := exec.CommandContext(ctx, "go", tier2Args...) + + err := handlingTestInstance(t, tier2Cmd, "TIER2", true) + if err != nil { + return fmt.Errorf("handling instance %w", err) + } + + return err +} + +func runDummyNode(ctx context.Context, t *testing.T) error { + launchDummyCmd := exec.CommandContext(ctx, "../devel/standard/start.sh") + + err := handlingTestInstance(t, launchDummyCmd, "DUMMY_BLOCKCHAIN", true) + if err != nil { + return fmt.Errorf("handling instance %w", err) + } + + return err +} + +func requestTier1(ctx context.Context, t *testing.T, testCase Case, substreamsClient pbsubstreamsrpc.StreamClient) error { + manifestReader, err := manifest.NewReader(testCase.spkgRootPath) + require.NoError(t, err) + + pkgBundle, err := manifestReader.Read() + require.NoError(t, err) + + require.NotEmptyf(t, pkgBundle, "pkgBundle is empty") + + request := pbsubstreamsrpc.Request{ + StartBlockNum: int64(testCase.startBlock), + StartCursor: "", + StopBlockNum: testCase.endBlock, + FinalBlocksOnly: false, + ProductionMode: false, + OutputModule: testCase.moduleName, + Modules: pkgBundle.Package.Modules, + DebugInitialStoreSnapshotForModules: nil, + NoopMode: false, + } + + stream, err := substreamsClient.Blocks(ctx, &request) + require.NoError(t, err) + + for { + block, err := stream.Recv() + if err == io.EOF { + break + } + require.NoError(t, err) + + t.Logf("[REQUESTER]: %v", block) + } + return nil +} diff --git a/test/metering_server.go b/test/metering_server.go new file mode 100644 index 0000000..aa27c41 --- /dev/null +++ b/test/metering_server.go @@ -0,0 +1,57 @@ +package test + +import ( + "context" + "net" + "testing" + + "github.com/test-go/testify/require" + + pbmetering "github.com/streamingfast/dmetering/pb/sf/metering/v1" + "google.golang.org/grpc" + "google.golang.org/protobuf/types/known/emptypb" +) + +type MeteringTestServer struct { + pbmetering.UnimplementedMeteringServer + httpListenAddr string + t *testing.T + bufferedEvents []*pbmetering.Events +} + +func NewMeteringServer(t *testing.T, httpListenAddr string) *MeteringTestServer { + return &MeteringTestServer{ + t: t, + httpListenAddr: httpListenAddr, + bufferedEvents: make([]*pbmetering.Events, 0), + } +} + +func (s *MeteringTestServer) Run() { + lis, err := net.Listen("tcp", s.httpListenAddr) + if err != nil { + require.NoError(s.t, err) + } + + grpcServer := grpc.NewServer() + + pbmetering.RegisterMeteringServer(grpcServer, s) + + s.t.Logf("[Metering]: Server listening port %s", s.httpListenAddr) + if err = grpcServer.Serve(lis); err != nil { + require.NoError(s.t, err) + } +} + +func (s *MeteringTestServer) Emit(ctx context.Context, events *pbmetering.Events) (*emptypb.Empty, error) { + s.bufferedEvents = append(s.bufferedEvents, events) + return &emptypb.Empty{}, nil +} + +func (s *MeteringTestServer) mustEmbedUnimplementedMeteringServer() { + panic("implement me") +} + +func (s *MeteringTestServer) clearBufferedEvents() { + s.bufferedEvents = make([]*pbmetering.Events, 0) +} diff --git a/test/substreams_acme/.gitignore b/test/substreams_acme/.gitignore new file mode 100644 index 0000000..4cc5cd3 --- /dev/null +++ b/test/substreams_acme/.gitignore @@ -0,0 +1,11 @@ +# substreams auth file +.substreams.env + +# Compiled source files +target/ + +# Sink data when running any sinker +sink-data/ + +# The spkg packed by the subtreams cli +*.spkg \ No newline at end of file diff --git a/test/substreams_acme/Cargo.lock b/test/substreams_acme/Cargo.lock new file mode 100644 index 0000000..30fd5a9 --- /dev/null +++ b/test/substreams_acme/Cargo.lock @@ -0,0 +1,1195 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "bigdecimal" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cpufeatures" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "ethabi" +version = "17.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4966fba78396ff92db3b817ee71143eccd98acf0f876b8d600e585a670c5d1b" +dependencies = [ + "ethereum-types", + "hex", + "once_cell", + "regex", + "serde", + "serde_json", + "sha3", + "thiserror", + "uint", +] + +[[package]] +name = "ethbloom" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11da94e443c60508eb62cf256243a64da87304c2802ac2528847f79d750007ef" +dependencies = [ + "crunchy", + "fixed-hash", + "impl-rlp", + "impl-serde", + "tiny-keccak", +] + +[[package]] +name = "ethereum-types" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2827b94c556145446fcce834ca86b7abf0c39a805883fe20e72c5bfdb5a0dc6" +dependencies = [ + "ethbloom", + "fixed-hash", + "impl-rlp", + "impl-serde", + "primitive-types", + "uint", +] + +[[package]] +name = "fastrand" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" + +[[package]] +name = "fixed-hash" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" +dependencies = [ + "byteorder", + "rand", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +dependencies = [ + "rlp", +] + +[[package]] +name = "impl-serde" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "pad" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ad9b889f1b12e0b9ee24db044b5129150d5eada288edc800f789928dc8c0e3" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "parity-scale-codec" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" +dependencies = [ + "arrayvec", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "pest" +version = "2.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d3a6e3394ec80feb3b6393c725571754c6188490265c61aaf260810d6b95aa0" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94429506bde1ca69d1b5601962c73f4172ab4726571a59ea95931218cb0e930e" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "pest_meta" +version = "2.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac8a071862e93690b6e34e9a5fb8e33ff3734473ac0245b27232222c4906a33f" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + +[[package]] +name = "petgraph" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "prettyplease" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +dependencies = [ + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "primitive-types" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28720988bff275df1f51b171e1b2a18c30d194c4d2b61defdacecd625a5d94a" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" +dependencies = [ + "bytes", + "heck", + "itertools", + "lazy_static", + "log", + "multimap", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 1.0.109", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "prost-types" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +dependencies = [ + "prost", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "regex" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rustc-hex", +] + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustix" +version = "0.38.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "serde" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "serde_json" +version = "1.0.128" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "substreams" +version = "0.5.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e47e531af83a3cbb78c627ee8232a0ac86604f11c89e34bd4b721ec41e03e5" +dependencies = [ + "anyhow", + "bigdecimal", + "hex", + "hex-literal", + "num-bigint", + "num-integer", + "num-traits", + "pad", + "pest", + "pest_derive", + "prost", + "prost-build", + "prost-types", + "substreams-macro", + "thiserror", +] + +[[package]] +name = "substreams-database-change" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed32ca6fc7fa4b7a684d3abd5bb0545aadd2df82402e7336443cdbb6f8b350c3" +dependencies = [ + "prost", + "prost-types", + "substreams", +] + +[[package]] +name = "substreams-entity-change" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2c7fca123abff659d15ed30da5b605fa954a29e912c94260c488d0d18f9107d" +dependencies = [ + "base64", + "prost", + "prost-types", + "substreams", +] + +[[package]] +name = "substreams-ethereum" +version = "0.9.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d033738be190ad9c9a63712cf121e4f33ae9c57845c64021e421c45aac688b5" +dependencies = [ + "getrandom", + "num-bigint", + "substreams", + "substreams-ethereum-abigen", + "substreams-ethereum-core", + "substreams-ethereum-derive", +] + +[[package]] +name = "substreams-ethereum-abigen" +version = "0.9.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27ef0adda971fbbd085545e73ccd7efbc12e31139cd301252f478e6b9743ff65" +dependencies = [ + "anyhow", + "ethabi", + "heck", + "hex", + "prettyplease", + "proc-macro2", + "quote", + "substreams-ethereum-core", + "syn 1.0.109", +] + +[[package]] +name = "substreams-ethereum-core" +version = "0.9.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a38e740018de8c2453f08621bab84ac55b0f1bfd42d56cf8b43ad340e670862" +dependencies = [ + "bigdecimal", + "ethabi", + "getrandom", + "num-bigint", + "prost", + "prost-build", + "prost-types", + "substreams", +] + +[[package]] +name = "substreams-ethereum-derive" +version = "0.9.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55c934c70e6ab1fe11a89f401f36e7d9be3fe087687395767a4c13ab3d6bd055" +dependencies = [ + "ethabi", + "heck", + "hex", + "num-bigint", + "proc-macro2", + "quote", + "substreams-ethereum-abigen", + "syn 1.0.109", +] + +[[package]] +name = "substreams-macro" +version = "0.5.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4ac77f08d723dace35739d65df8ed122f6d04e2a3e47929831d4021e3339240" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "thiserror", +] + +[[package]] +name = "substreams_acme" +version = "0.0.1" +dependencies = [ + "anyhow", + "ethabi", + "getrandom", + "hex-literal", + "num-bigint", + "num-traits", + "prost", + "prost-types", + "regex", + "substreams", + "substreams-database-change", + "substreams-entity-change", + "substreams-ethereum", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +dependencies = [ + "cfg-if", + "fastrand", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + +[[package]] +name = "thiserror" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] diff --git a/test/substreams_acme/Cargo.toml b/test/substreams_acme/Cargo.toml new file mode 100644 index 0000000..00f54f6 --- /dev/null +++ b/test/substreams_acme/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "substreams_acme" +version = "0.0.1" +edition = "2021" + +[lib] +name = "substreams" +crate-type = ["cdylib"] + +[dependencies] +ethabi = "17" +hex-literal = "0.3.4" +num-bigint = "0.4" +num-traits = "0.2.15" +prost = "0.11" +prost-types = "0.11" +substreams = "0.5.21" +substreams-ethereum = "0.9" +substreams-database-change = "1" +substreams-entity-change = "1" + +# Required so that ethabi > ethereum-types build correctly under wasm32-unknown-unknown +[target.wasm32-unknown-unknown.dependencies] +getrandom = { version = "0.2", features = ["custom"] } + +[build-dependencies] +anyhow = "1" +substreams-ethereum = "0.9" +regex = "1.8" + +[profile.release] +lto = true +opt-level = 's' +strip = "debuginfo" diff --git a/test/substreams_acme/README.md b/test/substreams_acme/README.md new file mode 100644 index 0000000..d35a0f2 --- /dev/null +++ b/test/substreams_acme/README.md @@ -0,0 +1,18 @@ +# substreams_acme Substreams modules + +This package was initialized via `substreams init`, using the `evm-minimal` template. + +## Usage + +```bash +substreams build +substreams auth +substreams gui +``` + +## Modules + +### `map_my_data` + +This module extracts small bits of block data, and does simple computations over the +number of **transactions** in each block. diff --git a/test/substreams_acme/buf.gen.yaml b/test/substreams_acme/buf.gen.yaml new file mode 100644 index 0000000..7e84c64 --- /dev/null +++ b/test/substreams_acme/buf.gen.yaml @@ -0,0 +1,12 @@ + +version: v1 +plugins: +- plugin: buf.build/community/neoeinstein-prost:v0.2.2 + out: /Users/arnaudberger/StreamingFast/firehose-core/test/substreams_acme/src/pb + opt: + - file_descriptor_set=false + +- plugin: buf.build/community/neoeinstein-prost-crate:v0.3.1 + out: /Users/arnaudberger/StreamingFast/firehose-core/test/substreams_acme/src/pb + opt: + - no_features diff --git a/test/substreams_acme/generator.json b/test/substreams_acme/generator.json new file mode 100644 index 0000000..849376d --- /dev/null +++ b/test/substreams_acme/generator.json @@ -0,0 +1,7 @@ +{ + "generator": "evm-minimal", + "state": { + "name": "substreams_acme", + "chainName": "mainnet" + } +} \ No newline at end of file diff --git a/test/substreams_acme/proto/sf/acme/type/v1/type.proto b/test/substreams_acme/proto/sf/acme/type/v1/type.proto new file mode 100644 index 0000000..b6ae620 --- /dev/null +++ b/test/substreams_acme/proto/sf/acme/type/v1/type.proto @@ -0,0 +1,45 @@ +syntax = "proto3"; + +package sf.acme.type.v1; + +option go_package = "github.com/streamingfast/firehose-acme/pb/sf/acme/type/v1;pbacme"; + +message BlockHeader { + uint64 height = 1; + string hash = 2; + optional uint64 previous_num = 3; + optional string previous_hash = 4; + uint64 final_num = 5; + string final_hash = 6; + uint64 timestamp = 7; +} + +message Block { + BlockHeader header = 1; + repeated Transaction transactions = 2; +} + +message Transaction { + string type = 1; + string hash = 2; + string sender = 3; + string receiver = 4; + BigInt amount = 5; + BigInt fee = 6; + bool success = 7; + repeated Event events = 8; +} + +message Event { + string type = 1; + repeated Attribute attributes = 2; +} + +message Attribute { + string key = 1; + string value = 2; +} + +message BigInt { + bytes bytes = 1; +} diff --git a/test/substreams_acme/proto/testdata.proto b/test/substreams_acme/proto/testdata.proto new file mode 100644 index 0000000..e2b40a4 --- /dev/null +++ b/test/substreams_acme/proto/testdata.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +import "google/protobuf/timestamp.proto"; + +package testdata.v1; + +message TestData { + string block_hash = 1; + uint64 block_number = 2; + google.protobuf.Timestamp block_timestamp = 3; + uint64 transactions_len = 4; +} \ No newline at end of file diff --git a/test/substreams_acme/src/lib.rs b/test/substreams_acme/src/lib.rs new file mode 100644 index 0000000..e5b76d8 --- /dev/null +++ b/test/substreams_acme/src/lib.rs @@ -0,0 +1,19 @@ +mod pb; + +use num_traits::ToPrimitive; +use pb::testdata::v1 as testdata; +use pb::sf::acme::r#type::v1::Block; + +use substreams::Hex; + + +substreams_ethereum::init!(); + +#[substreams::handlers::map] +fn map_test_data(blk: Block) -> testdata::TestData { + let mut test_data = testdata::TestData::default(); + let header = blk.header.clone().unwrap(); + test_data.block_hash = Hex(header.hash).to_string(); + test_data.block_number = header.height.to_u64().unwrap(); + test_data +} diff --git a/test/substreams_acme/src/pb/mod.rs b/test/substreams_acme/src/pb/mod.rs new file mode 100644 index 0000000..e2d9f36 --- /dev/null +++ b/test/substreams_acme/src/pb/mod.rs @@ -0,0 +1,19 @@ +// @generated +pub mod sf { + pub mod acme { + pub mod r#type { + // @@protoc_insertion_point(attribute:sf.acme.type.v1) + pub mod v1 { + include!("sf.acme.type.v1.rs"); + // @@protoc_insertion_point(sf.acme.type.v1) + } + } + } +} +pub mod testdata { + // @@protoc_insertion_point(attribute:testdata.v1) + pub mod v1 { + include!("testdata.v1.rs"); + // @@protoc_insertion_point(testdata.v1) + } +} diff --git a/test/substreams_acme/src/pb/sf.acme.type.v1.rs b/test/substreams_acme/src/pb/sf.acme.type.v1.rs new file mode 100644 index 0000000..84ebcca --- /dev/null +++ b/test/substreams_acme/src/pb/sf.acme.type.v1.rs @@ -0,0 +1,70 @@ +// @generated +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BlockHeader { + #[prost(uint64, tag="1")] + pub height: u64, + #[prost(string, tag="2")] + pub hash: ::prost::alloc::string::String, + #[prost(uint64, optional, tag="3")] + pub previous_num: ::core::option::Option, + #[prost(string, optional, tag="4")] + pub previous_hash: ::core::option::Option<::prost::alloc::string::String>, + #[prost(uint64, tag="5")] + pub final_num: u64, + #[prost(string, tag="6")] + pub final_hash: ::prost::alloc::string::String, + #[prost(uint64, tag="7")] + pub timestamp: u64, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Block { + #[prost(message, optional, tag="1")] + pub header: ::core::option::Option, + #[prost(message, repeated, tag="2")] + pub transactions: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Transaction { + #[prost(string, tag="1")] + pub r#type: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub hash: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub sender: ::prost::alloc::string::String, + #[prost(string, tag="4")] + pub receiver: ::prost::alloc::string::String, + #[prost(message, optional, tag="5")] + pub amount: ::core::option::Option, + #[prost(message, optional, tag="6")] + pub fee: ::core::option::Option, + #[prost(bool, tag="7")] + pub success: bool, + #[prost(message, repeated, tag="8")] + pub events: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Event { + #[prost(string, tag="1")] + pub r#type: ::prost::alloc::string::String, + #[prost(message, repeated, tag="2")] + pub attributes: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Attribute { + #[prost(string, tag="1")] + pub key: ::prost::alloc::string::String, + #[prost(string, tag="2")] + pub value: ::prost::alloc::string::String, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct BigInt { + #[prost(bytes="vec", tag="1")] + pub bytes: ::prost::alloc::vec::Vec, +} +// @@protoc_insertion_point(module) diff --git a/test/substreams_acme/src/pb/testdata.v1.rs b/test/substreams_acme/src/pb/testdata.v1.rs new file mode 100644 index 0000000..6f30bb8 --- /dev/null +++ b/test/substreams_acme/src/pb/testdata.v1.rs @@ -0,0 +1,14 @@ +// @generated +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct TestData { + #[prost(string, tag="1")] + pub block_hash: ::prost::alloc::string::String, + #[prost(uint64, tag="2")] + pub block_number: u64, + #[prost(message, optional, tag="3")] + pub block_timestamp: ::core::option::Option<::prost_types::Timestamp>, + #[prost(uint64, tag="4")] + pub transactions_len: u64, +} +// @@protoc_insertion_point(module) diff --git a/test/substreams_acme/substreams.yaml b/test/substreams_acme/substreams.yaml new file mode 100644 index 0000000..c17173d --- /dev/null +++ b/test/substreams_acme/substreams.yaml @@ -0,0 +1,29 @@ +specVersion: v0.1.0 +package: + name: substreams_acme + version: v0.1.0 + +protobuf: + files: + - testdata.proto + - sf/acme/type/v1/type.proto + importPaths: + - ./proto + excludePaths: + - sf/substreams + - google + +binaries: + default: + type: wasm/rust-v1 + file: ./target/wasm32-unknown-unknown/release/substreams.wasm + +modules: + - name: map_test_data + kind: map + inputs: + - source: sf.acme.type.v1.Block + output : + type: proto:testdata.v1.TestData + +network: mainnet diff --git a/test/utils.go b/test/utils.go new file mode 100644 index 0000000..1a8d33f --- /dev/null +++ b/test/utils.go @@ -0,0 +1,60 @@ +package test + +import ( + "bufio" + "fmt" + "io" + "os/exec" + "testing" +) + +func loggingStdout(t *testing.T, stdoutPipe io.ReadCloser, instance string) { + go func() { + scanner := bufio.NewScanner(stdoutPipe) + for scanner.Scan() { + // Log the stdout output as it comes in + t.Logf("[%s stdout]: %s", instance, scanner.Text()) + } + if err := scanner.Err(); err != nil { + t.Logf("Error reading %s stdout: %v", instance, err) + } + }() +} + +func loggingStderr(t *testing.T, stderrPipe io.ReadCloser, instance string) { + go func() { + scanner := bufio.NewScanner(stderrPipe) + for scanner.Scan() { + t.Logf("[%s stderr]: %s", instance, scanner.Text()) + } + if err := scanner.Err(); err != nil { + t.Logf("Error reading %s stderr: %v", instance, err) + } + }() +} + +func handlingTestInstance(t *testing.T, cmd *exec.Cmd, instance string, withLog bool) error { + stdoutPipe, err := cmd.StdoutPipe() + if err != nil { + return err + } + stderrPipe, err := cmd.StderrPipe() + if err != nil { + return err + } + + if withLog { + loggingStdout(t, stdoutPipe, instance) + loggingStderr(t, stderrPipe, instance) + } + + if err = cmd.Start(); err != nil { + return err + } + + if err = cmd.Wait(); err != nil { + return fmt.Errorf("%s process failed: %w", instance, err) + } + + return err +} diff --git a/well-known/chains.go b/well-known/chains.go index d443cf1..213885d 100644 --- a/well-known/chains.go +++ b/well-known/chains.go @@ -29,6 +29,18 @@ type Chain struct { type WellKnownProtocolList []WellKnownProtocol var WellKnownProtocols = WellKnownProtocolList([]WellKnownProtocol{ + { + Name: "acme", + BlockType: "sf.acme.type.v1.Block", + BytesEncoding: pbfirehose.InfoResponse_BLOCK_ID_ENCODING_HEX, + KnownChains: []*Chain{ + { + Name: "acme-dummy-blockchain", + GenesisBlockID: "5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9", + GenesisBlockNumber: 0, + }, + }, + }, { Name: "ethereum", BlockType: "sf.ethereum.type.v2.Block",