Skip to content

Commit

Permalink
add substreams tools extract-wasm
Browse files Browse the repository at this point in the history
  • Loading branch information
sduchesneau committed Nov 11, 2024
1 parent f3e78d8 commit 441f7e6
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/release-notes/change-log.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
* Changed `substreams run`: the two positional parameters now align with `gui`: `[package [module_name]]`. Before, it was using fuzzy heuristics to see if a single param was a module name or a package name. You need to be more explicit now, like `gui`.
* Added `substreams publish` to `publish` a package on the substreams registry (check on `https://substreams.dev`).
* Added `substreams registry` to `login` and `publish` on the substreams registry (check on `https://substreams.dev`).
* Added `substreams tools extract-wasm` to extract a wasm file from a substreams package.

## v1.10.11

Expand Down
84 changes: 84 additions & 0 deletions tools/extract-wasm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package tools

import (
"fmt"
"os"

"github.com/spf13/cobra"

"github.com/streamingfast/cli/sflags"
"github.com/streamingfast/substreams/manifest"
pbsubstreams "github.com/streamingfast/substreams/pb/sf/substreams/v1"
)

var extractWASMCmd = &cobra.Command{
Use: "extract-wasm <spkg-url> [dest-wasm-file]",
Short: "extract a wasm binary from a substreams package, useful when publishing a new release of a substreams package without changing the hashes",
Args: cobra.RangeArgs(1, 2),
RunE: extractWASME,
}

func init() {
extractWASMCmd.Flags().String("module", "", "module name to extract")
Cmd.AddCommand(extractWASMCmd)
}

func extractWASME(cmd *cobra.Command, args []string) error {
src := args[0]
dest := "extracted.wasm"
if len(args) == 2 {
dest = args[1]
}

module := sflags.MustGetString(cmd, "module")

manifestReader, err := manifest.NewReader(src)
if err != nil {
return fmt.Errorf("manifest reader: %w", err)
}

pkgBundle, err := manifestReader.Read()
if err != nil {
return fmt.Errorf("read manifest %q: %w", src, err)
}

if pkgBundle == nil {
return fmt.Errorf("no package found")
}

var bin *pbsubstreams.Binary
switch {
case module != "":
for _, mod := range pkgBundle.Package.Modules.Modules {
if mod.Name == module {
bin = pkgBundle.Package.Modules.Binaries[mod.BinaryIndex]
break
}
}
if bin == nil {
return fmt.Errorf("module %q not found", module)
}
case len(pkgBundle.Package.Modules.Binaries) == 1:
bin = pkgBundle.Package.Modules.Binaries[0]
default:
return fmt.Errorf("multiple binaries found, please specify a module name")
}

if err := os.WriteFile(dest, bin.Content, 0644); err != nil {
return fmt.Errorf("write file %q: %w", dest, err)
}
fmt.Printf("WASM extracted to file %s (%s) (%d bytes)\n", dest, bin.Type, len(bin.Content))

fmt.Println("\nTo use in all your modules, replace the file that is set as 'default' under 'binaries' in your substreams.yaml file.")
fmt.Println("To use only on some of your modules, add the following:")
fmt.Printf(`
binaries:
extracted:
type: %s
file: %s
`,
bin.Type, dest)
fmt.Printf("\nand set the `binary` field in each module to the name of the binary, e.g. `extracted`\n\n")

return nil
}

0 comments on commit 441f7e6

Please sign in to comment.