From 3fea13d19d61d115e5de26207f91d686a3ebd266 Mon Sep 17 00:00:00 2001 From: Matthieu Vachon Date: Mon, 8 Jan 2024 21:34:19 -0500 Subject: [PATCH] Updated to latest Firehose standards --- README.md | 82 +++------- core/engine.go | 64 +++++--- core/hash.go | 11 -- core/node.go | 64 ++++++-- core/store.go | 49 +++--- firehose/firehose.go | 84 ---------- go.mod | 2 +- main.go | 45 ++---- pb/generate.sh | 8 +- pb/last_generate.txt | 4 +- pb/sf/acme/type/v1/type.pb.go | 297 ++++++++++++++++++++++------------ tracer/firehose_tracer.go | 133 +++++++++++++++ tracer/tracer.go | 19 +++ types/types.go | 42 ++++- 14 files changed, 547 insertions(+), 357 deletions(-) delete mode 100644 core/hash.go delete mode 100644 firehose/firehose.go create mode 100644 tracer/firehose_tracer.go create mode 100644 tracer/tracer.go diff --git a/README.md b/README.md index ca175dc..90c4438 100644 --- a/README.md +++ b/README.md @@ -8,50 +8,17 @@ process. ## Requirements - Go -## Building - -Clone the repository: -```bash -git clone https://github.com/streamingfast/dummy-blockchain.git -cd dummy-blockchain -``` +## Getting Started -Then install the binary: +To install the binary: ```bash -go install . +go install github.com/streamingfast/dummy-blockchain@laest ``` -## Usage - -Run `./dummy-blockchain --help` to see list of all available flags: - -``` -CLI for the Dummy Chain - -Usage: - dummy-blockchain [command] - -Available Commands: - completion Generate the autocompletion script for the specified shell - help Help about any command - init Initialize local blockchain state - reset Reset local blockchain state - start Start blockchain service - -Flags: - --block-rate int Block production rate (per minute) (default 60) - --firehose-enabled Enable instrumentation - --genesis-height uint Blockchain genesis height (default 1) - -h, --help help for dummy-blockchain - --log-level string Logging level (default "info") - --server-addr string Server address (default "0.0.0.0:8080") - --stop-height uint Stop block production at this height - --store-dir string Directory for storing blockchain state (default "./data") - -Use "dummy-blockchain [command] --help" for more information about a command. -``` +> [!NOTE] +> Ensure `go env GOPATH` directoy is part of your PATH (export PATH="`` `go env GOPATH` ``:$PATH") To start the chain, run: @@ -77,31 +44,30 @@ INFO[2022-01-13T11:55:13-06:00] processing block ha To enable firehose instrumentation: ``` -./dummy-blockchain start --firehose-enabled -# Or using env var -FIREHOSE_ENABLED=1 ./dummy-blockchain start +./dummy-blockchain start --tracer=firehose ``` -Output will look like: +Firehose logger statement will be printed as blocks are executed/produced. This mode is meant to be run +using by a Firehose `reader-node`, see https://github.com/streamingfast/firehose-acme. -``` -INFO[2022-01-13T11:55:52-06:00] initializing node -INFO[2022-01-13T11:55:52-06:00] initializing store -DEBU[2022-01-13T11:55:52-06:00] creating store root directory dir=./data -INFO[2022-01-13T11:55:52-06:00] loading last block tip=6 -INFO[2022-01-13T11:55:52-06:00] initializing engine -INFO[2022-01-13T11:55:52-06:00] starting block producer rate=1s -INFO[2022-01-13T11:55:53-06:00] processing block hash=7902699be42c8a8e46fbbb4501726517e86b22c56a189f7625a6da49081b2451 height=7 -FIRE BLOCK_BEGIN 7 -FIRE BLOCK CAcSQDc5MDI2OTliZTQyYzhhOGU0NmZiYmI0NTAxNzI2NTE3ZTg2YjIyYzU2YTE4OWY3NjI1YTZkYTQ5MDgxYjI0NTEaQGU3ZjZjMDExNzc2ZThkYjdjZDMzMGI1NDE3NGZkNzZmN2QwMjE2YjYxMjM4N2E1ZmZjZmI4MWU2ZjA5MTk2ODMqjAEKCHRyYW5zZmVyEkBiMTEwZDg4OWUzNGU2MTdlMmIyYmZmNTdhYWMzNTU3Njc2YzJmNjgxZjM2NWJhZDVhODk2MTVkN2E4MDZmMGY0GgoweERFQURCRUFGIgoweEJBQUFBQUFEKgAyBAoCJxA4AUIcCg50b2tlbl90cmFuc2ZlchIKCgNmb28SA2JhciqSAQoIdHJhbnNmZXISQDBlYzE5MmMwZjkwZDEzMzJmMmFiY2E0Mzk4NTk2ZDM5Nzg0MzRlY2JhZTZhYmVhOGZmZDk4OTQxMmI1OTI0NTgaCjB4REVBREJFQUYiCjB4QkFBQUFBQUQqBgoEO5rKADIECgInEDgBQhwKDnRva2VuX3RyYW5zZmVyEgoKA2ZvbxIDYmFyKpIBCgh0cmFuc2ZlchJAMWFlNWEwYzkwMDE3Mzk4NzllZjgxMmE3Y2IzZjMyOTQyMzNmNTBlNWQxZGJkZTc0NzFiNDUxNjMzMDdjNmNkORoKMHhERUFEQkVBRiIKMHhCQUFBQUFBRCoGCgR3NZQAMgQKAicQOAFCHAoOdG9rZW5fdHJhbnNmZXISCgoDZm9vEgNiYXIqkgEKCHRyYW5zZmVyEkBiNjJmODNhYzc5MmJhYWNkMTdmNDI4NTg1NDM3Yzg0NTY2NjlkMGM1MGNmYjVmZGMxMWM5YTY3NTgxZDgxMzExGgoweERFQURCRUFGIgoweEJBQUFBQUFEKgYKBLLQXgAyBAoCJxA4AUIcCg50b2tlbl90cmFuc2ZlchIKCgNmb28SA2JhciqSAQoIdHJhbnNmZXISQGI5YjUwYzU5ZjQyNTFlOWQyZDRkYzQ5Mjc1ZWM0NzYwYTNjOTcwYTllNWQ5MjU0OGQwNDg5MzIzNDkzYmFkODUaCjB4REVBREJFQUYiCjB4QkFBQUFBQUQqBgoE7msoADIECgInEDgBQhwKDnRva2VuX3RyYW5zZmVyEgoKA2ZvbxIDYmFyKpMBCgh0cmFuc2ZlchJANWUzZjViZDMyMDYxNTQ3ZjdkMTAzNWQ0NDg2NGU5Mjg2YTE1OTRiOWJkMDUyOWMzMTU5ODhkOWNkMDdiYzU5MxoKMHhERUFEQkVBRiIKMHhCQUFBQUFBRCoHCgUBKgXyADIECgInEDgBQhwKDnRva2VuX3RyYW5zZmVyEgoKA2ZvbxIDYmFyKpMBCgh0cmFuc2ZlchJAZmYwM2ViZDU2OWJiZTgzMzg3ZTU2M2NkMTdkZDcxODBiZWI3MmNiOGMyYmZmODY3MDAyYzdhZGQyMjUxNGExMxoKMHhERUFEQkVBRiIKMHhCQUFBQUFBRCoHCgUBZaC8ADIECgInEDgBQhwKDnRva2VuX3RyYW5zZmVyEgoKA2ZvbxIDYmFy -FIRE BLOCK_END 7 -``` +## Tracer + +This project showcase a "fake" blockchain's node codebase. For developers looking into integrating a native Firehose integration, we suggest to integrate in blockchain's client code directly by some form of tracing plugin that is able to receive all the important callback's while transactions are execution integrating as deeply as wanted. + +You will see here in [tracer/tracer.go](./tracer/tracer.go) and [tracer/firehose_tracer.go](./tracer/firehose_tracer.go) a sketch of such "plugin" in Golang, `geth` can be inspected to see a full fledged block synchronization tracing plugin in a production codebase. + +The output format must strictly respect https://github.com/streamingfast/firehose-core standard, the [tracer/firehose_tracer.go](./tracer/firehose_tracer.go) implementation shows how we suggest implementing such tracer, you are free to implement the way you like. + +## Building -Customize Firehose log output with environment variable: +Clone the repository: + +```bash +git clone https://github.com/streamingfast/dummy-blockchain.git +cd dummy-blockchain -- `FIREHOSE_LOGS_OUTPUT=stdout` - Log to STDOUT (default) -- `FIREHOSE_LOGS_OUTPUT=stderr` - Log to STDERR -- `FIREHOSE_LOGS_OUTPUT=/path/to/file.log` - Log to regular file +go run . start +``` ## HTTP API diff --git a/core/engine.go b/core/engine.go index 831e766..f2b23e9 100644 --- a/core/engine.go +++ b/core/engine.go @@ -16,6 +16,7 @@ type Engine struct { blockRate time.Duration blockChan chan *types.Block prevBlock *types.Block + finalBlock *types.Block } func NewEngine(genesisHeight, stopHeight uint64, rate int) Engine { @@ -33,8 +34,14 @@ func NewEngine(genesisHeight, stopHeight uint64, rate int) Engine { } } -func (e *Engine) Initialize(block *types.Block) error { - e.prevBlock = block +func (e *Engine) Initialize(prevBlock *types.Block, finalBlock *types.Block) error { + e.prevBlock = prevBlock + e.finalBlock = finalBlock + + if finalBlock == nil { + return fmt.Errorf("final block cannot be nil") + } + return nil } @@ -44,7 +51,7 @@ func (e *Engine) StartBlockProduction(ctx context.Context) { logrus.WithField("rate", e.blockRate).Info("starting block producer") if e.stopHeight > 0 { logrus.WithField("stop_height", e.stopHeight).Info("block production will stop at height") - if e.prevBlock != nil && e.prevBlock.Height >= e.stopHeight { + if e.prevBlock != nil && e.prevBlock.Header.Height >= e.stopHeight { ticker.Stop() } } @@ -53,9 +60,9 @@ func (e *Engine) StartBlockProduction(ctx context.Context) { select { case <-ticker.C: block := e.createBlock() - e.blockChan <- &block + e.blockChan <- block - if e.stopHeight > 0 && block.Height >= e.stopHeight { + if e.stopHeight > 0 && block.Header.Height >= e.stopHeight { logrus.Info("reached stop height") ticker.Stop() } @@ -71,40 +78,51 @@ func (e *Engine) Subscription() <-chan *types.Block { return e.blockChan } -func (e *Engine) createBlock() types.Block { - block := types.Block{ - Timestamp: time.Now().UTC(), - Transactions: []types.Transaction{}, - } - - if e.prevBlock != nil { // Continue the chain - block.Height = e.prevBlock.Height + 1 - block.Hash = makeHash(block.Height) - block.PrevHash = e.prevBlock.Hash - } else { // Start from genesis height +func (e *Engine) createBlock() *types.Block { + if e.prevBlock == nil { logrus.WithField("height", e.genesisHeight).Info("starting from genesis block height") + genesisBlock := types.GenesisBlock(e.genesisHeight) + e.prevBlock = genesisBlock + e.finalBlock = genesisBlock - block.Height = e.genesisHeight - block.Hash = makeHash(e.genesisHeight) - block.PrevHash = makeHash(e.genesisHeight - 1) + return genesisBlock } - for i := uint64(0); i < block.Height%10; i++ { + block := &types.Block{ + Header: &types.BlockHeader{ + Height: e.prevBlock.Header.Height + 1, + Hash: types.MakeHash(e.prevBlock.Header.Height + 1), + PrevNum: &e.prevBlock.Header.Height, + PrevHash: &e.prevBlock.Header.Hash, + FinalNum: e.finalBlock.Header.Height, + FinalHash: e.finalBlock.Header.Hash, + }, + Transactions: []types.Transaction{}, + } + + trxCount := min(block.Header.Height%10, 500) + for i := uint64(0); i < trxCount; i++ { tx := types.Transaction{ Type: "transfer", - Hash: makeHash(fmt.Sprintf("%v-%v", block.Height, i)), + Hash: types.MakeHash(fmt.Sprintf("%v-%v", block.Header.Height, i)), Sender: "0xDEADBEEF", Receiver: "0xBAAAAAAD", Amount: big.NewInt(int64(i * 1000000000)), Fee: big.NewInt(10000), Success: true, - Events: e.generateEvents(block.Height), + Events: e.generateEvents(block.Header.Height), } block.Transactions = append(block.Transactions, tx) } - e.prevBlock = &block + e.prevBlock = block + + if block.Header.Height%10 == 0 { + logrus.WithField("height", block.Header.Height).Info("produced block is now the final block") + e.finalBlock = block + } + return block } diff --git a/core/hash.go b/core/hash.go deleted file mode 100644 index 25a509a..0000000 --- a/core/hash.go +++ /dev/null @@ -1,11 +0,0 @@ -package core - -import ( - "crypto/sha256" - "fmt" -) - -func makeHash(data interface{}) string { - shaSum := sha256.Sum256([]byte(fmt.Sprintf("%v", data))) - return fmt.Sprintf("%x", shaSum) -} diff --git a/core/node.go b/core/node.go index 92fadf9..d908eea 100644 --- a/core/node.go +++ b/core/node.go @@ -2,9 +2,10 @@ package core import ( "context" + "fmt" "github.com/sirupsen/logrus" - "github.com/streamingfast/dummy-blockchain/firehose" + "github.com/streamingfast/dummy-blockchain/tracer" "github.com/streamingfast/dummy-blockchain/types" ) @@ -12,6 +13,7 @@ type Node struct { engine Engine server Server store *Store + tracer tracer.Tracer } func NewNode( @@ -20,13 +22,15 @@ func NewNode( genesisHeight uint64, stopHeight uint64, serverAddr string, + tracer tracer.Tracer, ) *Node { - store := NewStore(storeDir) + store := NewStore(storeDir, genesisHeight) return &Node{ engine: NewEngine(genesisHeight, stopHeight, blockRate), store: store, server: NewServer(store, serverAddr), + tracer: tracer, } } @@ -40,8 +44,7 @@ func (node *Node) Initialize() error { } var tipBlock *types.Block - - if tip := node.store.meta.TipHeight; tip > 0 { + if tip := node.store.meta.HeadHeight; tip > 0 { logrus.WithField("tip", tip).Info("loading last block") block, err := node.store.ReadBlock(tip) if err != nil { @@ -51,12 +54,38 @@ func (node *Node) Initialize() error { tipBlock = block } + var finalBlock *types.Block + final := node.store.meta.FinalHeight + if final == 0 { + // We are uninitialized, so we need to create a genesis block + final = node.store.genesisHeight + } + + logrus.WithField("final", final).Info("loading final block") + finalBlock, err := node.store.ReadBlock(final) + if err != nil { + logrus.WithError(err).Error("cant read final block") + return err + } + + if finalBlock == nil { + return fmt.Errorf("can't find final block %d", final) + } + logrus.Info("initializing engine") - if err := node.engine.Initialize(tipBlock); err != nil { + if err := node.engine.Initialize(tipBlock, finalBlock); err != nil { logrus.WithError(err).Error("engine initialization failed") return err } + if tracer := node.tracer; tracer != nil { + logrus.Info("initializing tracer") + if err := node.tracer.Initialize(); err != nil { + logrus.WithError(err).Error("tracer initialization failed") + return err + } + } + return nil } @@ -75,18 +104,21 @@ func (node *Node) Start(ctx context.Context) error { return err } - if firehose.Enabled { - firehose.BeginBlock(block.Height) + if tracer := node.tracer; tracer != nil { + tracer.OnBlockStart(block.Header) for _, trx := range block.Transactions { - firehose.BeginTrx(&trx) - for idx, event := range trx.Events { - firehose.TrxBeginEvent(trx.Hash, &event) - for _, attr := range event.Attributes { - firehose.TrxEventAttr(trx.Hash, uint64(idx), attr.Key, attr.Value) + tracer.OnTrxStart(&trx) + + func() { + defer tracer.OnTrxEnd(&trx) + + for _, event := range trx.Events { + tracer.OnTrxEvent(trx.Hash, &event) } - } + }() } - firehose.EndBlock(block) + + tracer.OnBlockEnd(block, node.engine.finalBlock.Header) } case <-ctx.Done(): @@ -97,8 +129,8 @@ func (node *Node) Start(ctx context.Context) error { func (node *Node) processBlock(block *types.Block) error { logrus. - WithField("height", block.Height). - WithField("hash", block.Hash). + WithField("height", block.Header.Height). + WithField("hash", block.Header.Hash). Info("processing block") if err := node.store.WriteBlock(block); err != nil { diff --git a/core/store.go b/core/store.go index 7e9c01f..1304fcd 100644 --- a/core/store.go +++ b/core/store.go @@ -3,12 +3,10 @@ package core import ( "encoding/json" "fmt" - "io/ioutil" "os" "path/filepath" "github.com/sirupsen/logrus" - "github.com/streamingfast/dummy-blockchain/types" ) @@ -17,23 +15,25 @@ const ( ) type Store struct { - rootDir string - blocksDir string - metaPath string - currentGroup int + rootDir string + blocksDir string + metaPath string + currentGroup int + genesisHeight uint64 meta struct { - StartHeight uint64 `json:"start_height"` - TipHeight uint64 `json:"tip_height"` + FinalHeight uint64 `json:"final_height"` + HeadHeight uint64 `json:"head_height"` } } -func NewStore(rootDir string) *Store { +func NewStore(rootDir string, genesisHeight uint64) *Store { return &Store{ - rootDir: rootDir, - blocksDir: filepath.Join(rootDir, "blocks"), - metaPath: filepath.Join(rootDir, "meta.json"), - currentGroup: -1, + rootDir: rootDir, + blocksDir: filepath.Join(rootDir, "blocks"), + metaPath: filepath.Join(rootDir, "meta.json"), + currentGroup: -1, + genesisHeight: genesisHeight, } } @@ -55,10 +55,7 @@ func (store *Store) Initialize() error { } func (store *Store) WriteBlock(block *types.Block) error { - store.meta.TipHeight = block.Height - if store.meta.StartHeight == 0 { - store.meta.StartHeight = block.Height - } + store.meta.HeadHeight = block.Header.Height raw, err := store.encodeBlock(block) if err != nil { @@ -70,7 +67,7 @@ func (store *Store) WriteBlock(block *types.Block) error { return err } - group := int(store.blockGroup(block.Height)) + group := int(store.blockGroup(block.Header.Height)) if group != store.currentGroup { groupDir := fmt.Sprintf("%s/%010d", store.blocksDir, group) if err := os.MkdirAll(groupDir, 0700); err != nil { @@ -79,21 +76,25 @@ func (store *Store) WriteBlock(block *types.Block) error { store.currentGroup = group } - if err := ioutil.WriteFile(store.blockFilename(block.Height), raw, 0655); err != nil { + if err := os.WriteFile(store.blockFilename(block.Header.Height), raw, 0655); err != nil { return err } - return ioutil.WriteFile(store.metaPath, meta, 0655) + return os.WriteFile(store.metaPath, meta, 0655) } func (store *Store) CurrentBlock() (*types.Block, error) { - return store.ReadBlock(store.meta.TipHeight) + return store.ReadBlock(store.meta.HeadHeight) } func (store *Store) ReadBlock(height uint64) (*types.Block, error) { + if height == store.genesisHeight { + return types.GenesisBlock(store.genesisHeight), nil + } + block := &types.Block{} - data, err := ioutil.ReadFile(store.blockFilename(height)) + data, err := os.ReadFile(store.blockFilename(height)) if err != nil { return nil, err } @@ -119,12 +120,12 @@ func (store *Store) readMeta() error { return err } - if err := ioutil.WriteFile(store.metaPath, meta, 0655); err != nil { + if err := os.WriteFile(store.metaPath, meta, 0655); err != nil { return err } } - data, err := ioutil.ReadFile(store.metaPath) + data, err := os.ReadFile(store.metaPath) if err != nil { return err } diff --git a/firehose/firehose.go b/firehose/firehose.go deleted file mode 100644 index 86e2d76..0000000 --- a/firehose/firehose.go +++ /dev/null @@ -1,84 +0,0 @@ -package firehose - -import ( - "encoding/hex" - "fmt" - "github.com/streamingfast/dummy-blockchain/types" - "io" - "math/big" -) - -var ( - Enabled bool - writer io.WriteCloser -) - -func Enable(w io.WriteCloser) { - Enabled = true - writer = w -} - -func SetWriter(w io.WriteCloser) { - writer = w -} - -func Shutdown() { - writer.Close() -} - -// BeginBlock marks the beginning of the block data for a single height -func BeginBlock(number uint64) { - // FIRE BLOCK_BEGIN - fmt.Fprintf(writer, "FIRE BLOCK_BEGIN %d\n", number) -} - -// BeginTrx marks the beginning of a transaction -func BeginTrx(trx *types.Transaction) { - // FIRE BEGIN_TRX - trxAmount := "0" - if trx.Amount.Cmp(new(big.Int).SetUint64(0)) > 0 { - trxAmount = hex.EncodeToString(trx.Amount.Bytes()) - } - - fmt.Fprintf(writer, "FIRE BEGIN_TRX %s %s %s %s %s %s %t\n", - trx.Hash, - trx.Type, - trx.Sender, - trx.Receiver, - trxAmount, - hex.EncodeToString(trx.Fee.Bytes()), - trx.Success, - ) -} - -// TrxBeginEvent records the beginning of an event -func TrxBeginEvent(trxHash string, event *types.Event) { - // FIRE TRX_BEGIN_EVENT - fmt.Fprintf(writer, "FIRE TRX_BEGIN_EVENT %s %s\n", - trxHash, - event.Type, - ) -} - -// TrxEventAttr record an attribute for a given event -func TrxEventAttr(trxHash string, eventIndex uint64, key string, value string) { - // FIRE TRX_BEGIN_EVENT - fmt.Fprintf(writer, "FIRE TRX_EVENT_ATTR %s %d %s %s\n", - trxHash, - eventIndex, - key, - value, - ) -} - -// EndBlock marks the end of the block data for a single height -func EndBlock(blk *types.Block) { - // FIRE BLOCK_END - fmt.Fprintf(writer, "FIRE BLOCK_END %d %s %s %d %d\n", - blk.Height, - blk.Hash, - blk.PrevHash, - blk.Timestamp.UnixNano(), - len(blk.Transactions), - ) -} diff --git a/go.mod b/go.mod index ce1eb91..19470ab 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/streamingfast/dummy-blockchain -go 1.17 +go 1.21 require ( github.com/gin-gonic/gin v1.7.7 diff --git a/main.go b/main.go index 291b5f3..bfb6a1c 100644 --- a/main.go +++ b/main.go @@ -10,17 +10,17 @@ import ( "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/streamingfast/dummy-blockchain/core" - "github.com/streamingfast/dummy-blockchain/firehose" + "github.com/streamingfast/dummy-blockchain/tracer" ) var cliOpts = struct { - GenesisHeight uint64 - LogLevel string - StoreDir string - BlockRate int - ServerAddr string - Instrumentation bool - StopHeight uint64 + GenesisHeight uint64 + LogLevel string + StoreDir string + BlockRate int + ServerAddr string + Tracer string + StopHeight uint64 }{} func main() { @@ -58,7 +58,7 @@ func initFlags(root *cobra.Command) error { flags.IntVar(&cliOpts.BlockRate, "block-rate", 60, "Block production rate (per minute)") flags.Uint64Var(&cliOpts.StopHeight, "stop-height", 0, "Stop block production at this height") flags.StringVar(&cliOpts.ServerAddr, "server-addr", "0.0.0.0:8080", "Server address") - flags.BoolVar(&cliOpts.Instrumentation, "firehose-enabled", false, "Enable instrumentation") + flags.StringVar(&cliOpts.Tracer, "tracer", "", "The tracer to use, either , none or firehose") return nil } @@ -83,7 +83,7 @@ func makeInitCommand() *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { logrus.WithField("dir", cliOpts.StoreDir).Info("initializing chain store") - store := core.NewStore(cliOpts.StoreDir) + store := core.NewStore(cliOpts.StoreDir, cliOpts.GenesisHeight) return store.Initialize() }, } @@ -117,9 +117,9 @@ func makeStartComand() *cobra.Command { return errors.New("block rate option must be greater than 1") } - if cliOpts.Instrumentation || os.Getenv("FIREHOSE_ENABLED") == "1" { - initFirehose() - defer firehose.Shutdown() + var blockTracer tracer.Tracer + if cliOpts.Tracer == "firehose" { + blockTracer = &tracer.FirehoseTracer{} } node := core.NewNode( @@ -128,6 +128,7 @@ func makeStartComand() *cobra.Command { cliOpts.GenesisHeight, cliOpts.StopHeight, cliOpts.ServerAddr, + blockTracer, ) if err := node.Initialize(); err != nil { @@ -155,24 +156,6 @@ func makeStartComand() *cobra.Command { } } -func initFirehose() { - // A global flag to enable instrumentation - firehoseLogsOutput := os.Getenv("FIREHOSE_LOGS_OUTPUT") - - switch firehoseLogsOutput { - case "", "stdout", "STDOUT": - firehose.Enable(os.Stdout) - case "stderr", "STDERR": - firehose.Enable(os.Stderr) - default: - outputFile, err := os.OpenFile(firehoseLogsOutput, os.O_CREATE|os.O_APPEND|os.O_WRONLY|os.O_SYNC, 0666) - if err != nil { - logrus.WithError(err).Fatal("cant open Firehose logs output file") - } - firehose.Enable(outputFile) - } -} - func waitForSignal() os.Signal { sig := make(chan os.Signal, 1) signal.Notify(sig, syscall.SIGTERM) diff --git a/pb/generate.sh b/pb/generate.sh index 0a6b1b1..26dbfbb 100755 --- a/pb/generate.sh +++ b/pb/generate.sh @@ -60,20 +60,20 @@ function checks() { # version waits forever. So we pipe some wrong input to make it exit fast. This in the new version # which supports `--version` correctly print the version anyway and discard the standard input # so it's good with both version. - result=`printf "" | protoc-gen-go --version 2>&1 | grep -Eo "v1.[2-9][6-9]"` + result=`printf "" | protoc-gen-go --version 2>&1 | grep -Eo "v1.(2[6-9]|[3-9][0-9]+)"` if [[ "$result" == "" ]]; then echo "Your version of 'protoc-gen-go' (at `which protoc-gen-go`) is not recent enough." echo "" echo "To fix your problem, perform those commands:" echo "" - echo " go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.27.0" - echo " go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1.0" + echo " go install google.golang.org/protobuf/cmd/protoc-gen-go@latest" + echo " go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@vlatest" echo "" echo "If everything is working as expetcted, the command:" echo "" echo " protoc-gen-go --version" echo "" - echo "Should print 'protoc-gen-go v1.27.0' (if it just hangs, you don't have the correct version)" + echo "Should print 'protoc-gen-go v1.32.0' (if it just hangs, you don't have the correct version)" exit 1 fi } diff --git a/pb/last_generate.txt b/pb/last_generate.txt index a6053d2..b08bb36 100644 --- a/pb/last_generate.txt +++ b/pb/last_generate.txt @@ -1,2 +1,2 @@ -generate.sh - Thu Sep 29 09:29:50 EDT 2022 - maoueh -firehose-acme/proto revision: 37870a5 +generate.sh - Mon Jan 8 15:38:28 EST 2024 - maoueh +firehose-acme/proto revision: 1e24bd4 diff --git a/pb/sf/acme/type/v1/type.pb.go b/pb/sf/acme/type/v1/type.pb.go index 60f6591..9c7b67b 100644 --- a/pb/sf/acme/type/v1/type.pb.go +++ b/pb/sf/acme/type/v1/type.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.27.0 -// protoc v3.21.4 +// protoc-gen-go v1.32.0 +// protoc v4.25.0 // source: sf/acme/type/v1/type.proto package pbacme @@ -20,20 +20,22 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type Block struct { +type BlockHeader struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Height uint64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"` - Hash string `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"` - PrevHash string `protobuf:"bytes,3,opt,name=prevHash,proto3" json:"prevHash,omitempty"` - Timestamp uint64 `protobuf:"varint,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"` - Transactions []*Transaction `protobuf:"bytes,5,rep,name=transactions,proto3" json:"transactions,omitempty"` + Height uint64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"` + Hash string `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"` + PreviousNum *uint64 `protobuf:"varint,3,opt,name=previous_num,json=previousNum,proto3,oneof" json:"previous_num,omitempty"` + PreviousHash *string `protobuf:"bytes,4,opt,name=previous_hash,json=previousHash,proto3,oneof" json:"previous_hash,omitempty"` + FinalNum uint64 `protobuf:"varint,5,opt,name=final_num,json=finalNum,proto3" json:"final_num,omitempty"` + FinalHash string `protobuf:"bytes,6,opt,name=final_hash,json=finalHash,proto3" json:"final_hash,omitempty"` + Timestamp uint64 `protobuf:"varint,7,opt,name=timestamp,proto3" json:"timestamp,omitempty"` } -func (x *Block) Reset() { - *x = Block{} +func (x *BlockHeader) Reset() { + *x = BlockHeader{} if protoimpl.UnsafeEnabled { mi := &file_sf_acme_type_v1_type_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -41,13 +43,13 @@ func (x *Block) Reset() { } } -func (x *Block) String() string { +func (x *BlockHeader) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Block) ProtoMessage() {} +func (*BlockHeader) ProtoMessage() {} -func (x *Block) ProtoReflect() protoreflect.Message { +func (x *BlockHeader) ProtoReflect() protoreflect.Message { mi := &file_sf_acme_type_v1_type_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -59,39 +61,108 @@ func (x *Block) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Block.ProtoReflect.Descriptor instead. -func (*Block) Descriptor() ([]byte, []int) { +// Deprecated: Use BlockHeader.ProtoReflect.Descriptor instead. +func (*BlockHeader) Descriptor() ([]byte, []int) { return file_sf_acme_type_v1_type_proto_rawDescGZIP(), []int{0} } -func (x *Block) GetHeight() uint64 { +func (x *BlockHeader) GetHeight() uint64 { if x != nil { return x.Height } return 0 } -func (x *Block) GetHash() string { +func (x *BlockHeader) GetHash() string { if x != nil { return x.Hash } return "" } -func (x *Block) GetPrevHash() string { +func (x *BlockHeader) GetPreviousNum() uint64 { + if x != nil && x.PreviousNum != nil { + return *x.PreviousNum + } + return 0 +} + +func (x *BlockHeader) GetPreviousHash() string { + if x != nil && x.PreviousHash != nil { + return *x.PreviousHash + } + return "" +} + +func (x *BlockHeader) GetFinalNum() uint64 { if x != nil { - return x.PrevHash + return x.FinalNum + } + return 0 +} + +func (x *BlockHeader) GetFinalHash() string { + if x != nil { + return x.FinalHash } return "" } -func (x *Block) GetTimestamp() uint64 { +func (x *BlockHeader) GetTimestamp() uint64 { if x != nil { return x.Timestamp } return 0 } +type Block struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Header *BlockHeader `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` + Transactions []*Transaction `protobuf:"bytes,2,rep,name=transactions,proto3" json:"transactions,omitempty"` +} + +func (x *Block) Reset() { + *x = Block{} + if protoimpl.UnsafeEnabled { + mi := &file_sf_acme_type_v1_type_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Block) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Block) ProtoMessage() {} + +func (x *Block) ProtoReflect() protoreflect.Message { + mi := &file_sf_acme_type_v1_type_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Block.ProtoReflect.Descriptor instead. +func (*Block) Descriptor() ([]byte, []int) { + return file_sf_acme_type_v1_type_proto_rawDescGZIP(), []int{1} +} + +func (x *Block) GetHeader() *BlockHeader { + if x != nil { + return x.Header + } + return nil +} + func (x *Block) GetTransactions() []*Transaction { if x != nil { return x.Transactions @@ -117,7 +188,7 @@ type Transaction struct { func (x *Transaction) Reset() { *x = Transaction{} if protoimpl.UnsafeEnabled { - mi := &file_sf_acme_type_v1_type_proto_msgTypes[1] + mi := &file_sf_acme_type_v1_type_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -130,7 +201,7 @@ func (x *Transaction) String() string { func (*Transaction) ProtoMessage() {} func (x *Transaction) ProtoReflect() protoreflect.Message { - mi := &file_sf_acme_type_v1_type_proto_msgTypes[1] + mi := &file_sf_acme_type_v1_type_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -143,7 +214,7 @@ func (x *Transaction) ProtoReflect() protoreflect.Message { // Deprecated: Use Transaction.ProtoReflect.Descriptor instead. func (*Transaction) Descriptor() ([]byte, []int) { - return file_sf_acme_type_v1_type_proto_rawDescGZIP(), []int{1} + return file_sf_acme_type_v1_type_proto_rawDescGZIP(), []int{2} } func (x *Transaction) GetType() string { @@ -214,7 +285,7 @@ type Event struct { func (x *Event) Reset() { *x = Event{} if protoimpl.UnsafeEnabled { - mi := &file_sf_acme_type_v1_type_proto_msgTypes[2] + mi := &file_sf_acme_type_v1_type_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -227,7 +298,7 @@ func (x *Event) String() string { func (*Event) ProtoMessage() {} func (x *Event) ProtoReflect() protoreflect.Message { - mi := &file_sf_acme_type_v1_type_proto_msgTypes[2] + mi := &file_sf_acme_type_v1_type_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -240,7 +311,7 @@ func (x *Event) ProtoReflect() protoreflect.Message { // Deprecated: Use Event.ProtoReflect.Descriptor instead. func (*Event) Descriptor() ([]byte, []int) { - return file_sf_acme_type_v1_type_proto_rawDescGZIP(), []int{2} + return file_sf_acme_type_v1_type_proto_rawDescGZIP(), []int{3} } func (x *Event) GetType() string { @@ -269,7 +340,7 @@ type Attribute struct { func (x *Attribute) Reset() { *x = Attribute{} if protoimpl.UnsafeEnabled { - mi := &file_sf_acme_type_v1_type_proto_msgTypes[3] + mi := &file_sf_acme_type_v1_type_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -282,7 +353,7 @@ func (x *Attribute) String() string { func (*Attribute) ProtoMessage() {} func (x *Attribute) ProtoReflect() protoreflect.Message { - mi := &file_sf_acme_type_v1_type_proto_msgTypes[3] + mi := &file_sf_acme_type_v1_type_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -295,7 +366,7 @@ func (x *Attribute) ProtoReflect() protoreflect.Message { // Deprecated: Use Attribute.ProtoReflect.Descriptor instead. func (*Attribute) Descriptor() ([]byte, []int) { - return file_sf_acme_type_v1_type_proto_rawDescGZIP(), []int{3} + return file_sf_acme_type_v1_type_proto_rawDescGZIP(), []int{4} } func (x *Attribute) GetKey() string { @@ -323,7 +394,7 @@ type BigInt struct { func (x *BigInt) Reset() { *x = BigInt{} if protoimpl.UnsafeEnabled { - mi := &file_sf_acme_type_v1_type_proto_msgTypes[4] + mi := &file_sf_acme_type_v1_type_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -336,7 +407,7 @@ func (x *BigInt) String() string { func (*BigInt) ProtoMessage() {} func (x *BigInt) ProtoReflect() protoreflect.Message { - mi := &file_sf_acme_type_v1_type_proto_msgTypes[4] + mi := &file_sf_acme_type_v1_type_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -349,7 +420,7 @@ func (x *BigInt) ProtoReflect() protoreflect.Message { // Deprecated: Use BigInt.ProtoReflect.Descriptor instead. func (*BigInt) Descriptor() ([]byte, []int) { - return file_sf_acme_type_v1_type_proto_rawDescGZIP(), []int{4} + return file_sf_acme_type_v1_type_proto_rawDescGZIP(), []int{5} } func (x *BigInt) GetBytes() []byte { @@ -364,52 +435,65 @@ var File_sf_acme_type_v1_type_proto protoreflect.FileDescriptor var file_sf_acme_type_v1_type_proto_rawDesc = []byte{ 0x0a, 0x1a, 0x73, 0x66, 0x2f, 0x61, 0x63, 0x6d, 0x65, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x73, 0x66, - 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x76, 0x31, 0x22, 0xaf, 0x01, - 0x0a, 0x05, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, - 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, - 0x61, 0x73, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x65, 0x76, 0x48, 0x61, 0x73, 0x68, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x65, 0x76, 0x48, 0x61, 0x73, 0x68, 0x12, - 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x40, 0x0a, - 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x66, 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, - 0x8f, 0x02, 0x0a, 0x0b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, - 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, - 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x12, 0x2f, 0x0a, 0x06, 0x61, - 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x66, - 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x69, - 0x67, 0x49, 0x6e, 0x74, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x03, - 0x66, 0x65, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x66, 0x2e, 0x61, - 0x63, 0x6d, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x69, 0x67, 0x49, - 0x6e, 0x74, 0x52, 0x03, 0x66, 0x65, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x12, 0x2e, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x66, 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, - 0x73, 0x22, 0x57, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x3a, - 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x66, 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x0a, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x22, 0x33, 0x0a, 0x09, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, - 0x1e, 0x0a, 0x06, 0x42, 0x69, 0x67, 0x49, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x42, - 0x48, 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x66, 0x61, 0x73, 0x74, 0x2f, 0x66, 0x69, 0x72, 0x65, - 0x68, 0x6f, 0x73, 0x65, 0x2d, 0x61, 0x63, 0x6d, 0x65, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, - 0x70, 0x62, 0x2f, 0x73, 0x66, 0x2f, 0x61, 0x63, 0x6d, 0x65, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x2f, - 0x76, 0x31, 0x3b, 0x70, 0x62, 0x61, 0x63, 0x6d, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x76, 0x31, 0x22, 0x88, 0x02, + 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x16, 0x0a, + 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x26, 0x0a, 0x0c, 0x70, 0x72, 0x65, + 0x76, 0x69, 0x6f, 0x75, 0x73, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x48, + 0x00, 0x52, 0x0b, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x4e, 0x75, 0x6d, 0x88, 0x01, + 0x01, 0x12, 0x28, 0x0a, 0x0d, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x5f, 0x68, 0x61, + 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x0c, 0x70, 0x72, 0x65, 0x76, + 0x69, 0x6f, 0x75, 0x73, 0x48, 0x61, 0x73, 0x68, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x09, 0x66, + 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, + 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x4e, 0x75, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x69, 0x6e, 0x61, + 0x6c, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x69, + 0x6e, 0x61, 0x6c, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, + 0x75, 0x73, 0x5f, 0x6e, 0x75, 0x6d, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, + 0x6f, 0x75, 0x73, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x22, 0x7f, 0x0a, 0x05, 0x42, 0x6c, 0x6f, 0x63, + 0x6b, 0x12, 0x34, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x66, 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, + 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x40, 0x0a, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x73, 0x66, 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x8f, 0x02, 0x0a, 0x0b, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, + 0x68, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x63, + 0x65, 0x69, 0x76, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x63, + 0x65, 0x69, 0x76, 0x65, 0x72, 0x12, 0x2f, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x66, 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, + 0x74, 0x79, 0x70, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x69, 0x67, 0x49, 0x6e, 0x74, 0x52, 0x06, + 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x03, 0x66, 0x65, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x66, 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x69, 0x67, 0x49, 0x6e, 0x74, 0x52, 0x03, 0x66, 0x65, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x2e, 0x0a, 0x06, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x66, + 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x57, 0x0a, 0x05, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x3a, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, + 0x66, 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x73, 0x22, 0x33, 0x0a, 0x09, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x1e, 0x0a, 0x06, 0x42, 0x69, 0x67, + 0x49, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x42, 0x42, 0x5a, 0x40, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, + 0x67, 0x66, 0x61, 0x73, 0x74, 0x2f, 0x66, 0x69, 0x72, 0x65, 0x68, 0x6f, 0x73, 0x65, 0x2d, 0x61, + 0x63, 0x6d, 0x65, 0x2f, 0x70, 0x62, 0x2f, 0x73, 0x66, 0x2f, 0x61, 0x63, 0x6d, 0x65, 0x2f, 0x74, + 0x79, 0x70, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x62, 0x61, 0x63, 0x6d, 0x65, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -424,25 +508,27 @@ func file_sf_acme_type_v1_type_proto_rawDescGZIP() []byte { return file_sf_acme_type_v1_type_proto_rawDescData } -var file_sf_acme_type_v1_type_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_sf_acme_type_v1_type_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_sf_acme_type_v1_type_proto_goTypes = []interface{}{ - (*Block)(nil), // 0: sf.acme.type.v1.Block - (*Transaction)(nil), // 1: sf.acme.type.v1.Transaction - (*Event)(nil), // 2: sf.acme.type.v1.Event - (*Attribute)(nil), // 3: sf.acme.type.v1.Attribute - (*BigInt)(nil), // 4: sf.acme.type.v1.BigInt + (*BlockHeader)(nil), // 0: sf.acme.type.v1.BlockHeader + (*Block)(nil), // 1: sf.acme.type.v1.Block + (*Transaction)(nil), // 2: sf.acme.type.v1.Transaction + (*Event)(nil), // 3: sf.acme.type.v1.Event + (*Attribute)(nil), // 4: sf.acme.type.v1.Attribute + (*BigInt)(nil), // 5: sf.acme.type.v1.BigInt } var file_sf_acme_type_v1_type_proto_depIdxs = []int32{ - 1, // 0: sf.acme.type.v1.Block.transactions:type_name -> sf.acme.type.v1.Transaction - 4, // 1: sf.acme.type.v1.Transaction.amount:type_name -> sf.acme.type.v1.BigInt - 4, // 2: sf.acme.type.v1.Transaction.fee:type_name -> sf.acme.type.v1.BigInt - 2, // 3: sf.acme.type.v1.Transaction.events:type_name -> sf.acme.type.v1.Event - 3, // 4: sf.acme.type.v1.Event.attributes:type_name -> sf.acme.type.v1.Attribute - 5, // [5:5] is the sub-list for method output_type - 5, // [5:5] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name + 0, // 0: sf.acme.type.v1.Block.header:type_name -> sf.acme.type.v1.BlockHeader + 2, // 1: sf.acme.type.v1.Block.transactions:type_name -> sf.acme.type.v1.Transaction + 5, // 2: sf.acme.type.v1.Transaction.amount:type_name -> sf.acme.type.v1.BigInt + 5, // 3: sf.acme.type.v1.Transaction.fee:type_name -> sf.acme.type.v1.BigInt + 3, // 4: sf.acme.type.v1.Transaction.events:type_name -> sf.acme.type.v1.Event + 4, // 5: sf.acme.type.v1.Event.attributes:type_name -> sf.acme.type.v1.Attribute + 6, // [6:6] is the sub-list for method output_type + 6, // [6:6] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name } func init() { file_sf_acme_type_v1_type_proto_init() } @@ -452,7 +538,7 @@ func file_sf_acme_type_v1_type_proto_init() { } if !protoimpl.UnsafeEnabled { file_sf_acme_type_v1_type_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Block); i { + switch v := v.(*BlockHeader); i { case 0: return &v.state case 1: @@ -464,7 +550,7 @@ func file_sf_acme_type_v1_type_proto_init() { } } file_sf_acme_type_v1_type_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Transaction); i { + switch v := v.(*Block); i { case 0: return &v.state case 1: @@ -476,7 +562,7 @@ func file_sf_acme_type_v1_type_proto_init() { } } file_sf_acme_type_v1_type_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Event); i { + switch v := v.(*Transaction); i { case 0: return &v.state case 1: @@ -488,7 +574,7 @@ func file_sf_acme_type_v1_type_proto_init() { } } file_sf_acme_type_v1_type_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Attribute); i { + switch v := v.(*Event); i { case 0: return &v.state case 1: @@ -500,6 +586,18 @@ func file_sf_acme_type_v1_type_proto_init() { } } file_sf_acme_type_v1_type_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Attribute); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_sf_acme_type_v1_type_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BigInt); i { case 0: return &v.state @@ -512,13 +610,14 @@ func file_sf_acme_type_v1_type_proto_init() { } } } + file_sf_acme_type_v1_type_proto_msgTypes[0].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_sf_acme_type_v1_type_proto_rawDesc, NumEnums: 0, - NumMessages: 5, + NumMessages: 6, NumExtensions: 0, NumServices: 0, }, diff --git a/tracer/firehose_tracer.go b/tracer/firehose_tracer.go new file mode 100644 index 0000000..741bb9b --- /dev/null +++ b/tracer/firehose_tracer.go @@ -0,0 +1,133 @@ +package tracer + +import ( + "encoding/base64" + "fmt" + + pbacme "github.com/streamingfast/dummy-blockchain/pb/sf/acme/type/v1" + "github.com/streamingfast/dummy-blockchain/types" + "google.golang.org/protobuf/proto" +) + +var _ Tracer = &FirehoseTracer{} + +type FirehoseTracer struct { + activeBlock *pbacme.Block + activeTrx *pbacme.Transaction +} + +// Initialize implements Tracer. +func (*FirehoseTracer) Initialize() error { + fmt.Printf("FIRE INIT 1.0 %s\n", new(pbacme.Block).ProtoReflect().Descriptor().FullName()) + return nil +} + +// OnBlockEnd implements Tracer. +func (t *FirehoseTracer) OnBlockEnd(blk *types.Block, finalBlockHeader *types.BlockHeader) { + if t.activeBlock == nil { + panic(fmt.Errorf("no active block, something is wrong in the tracer call order")) + } + + header := t.activeBlock.Header + + previousNum := uint64(0) + if header.PreviousNum != nil { + previousNum = *header.PreviousNum + } + + previousHash := "" + if header.PreviousHash != nil { + previousHash = *header.PreviousHash + } + + blockPayload, err := proto.Marshal(t.activeBlock) + if err != nil { + panic(fmt.Errorf("unable to marshal block: %w", err)) + } + + fmt.Printf("FIRE BLOCK %d %s %d %s %d %d %s\n", + header.Height, + header.Hash, + previousNum, + previousHash, + header.FinalNum, + header.Timestamp, + base64.StdEncoding.EncodeToString(blockPayload), + ) + + t.activeBlock = nil + t.activeTrx = nil +} + +// OnBlockStart implements Tracer. +func (t *FirehoseTracer) OnBlockStart(header *types.BlockHeader) { + if t.activeBlock != nil { + panic(fmt.Errorf("block already started, something is wrong in the tracer call order")) + } + + t.activeBlock = &pbacme.Block{ + Header: &pbacme.BlockHeader{ + Height: header.Height, + Hash: header.Hash, + FinalNum: header.FinalNum, + FinalHash: header.FinalHash, + Timestamp: uint64(header.Timestamp.UnixNano()), + }, + } + + if header.PrevHash != nil { + t.activeBlock.Header.PreviousNum = header.PrevNum + t.activeBlock.Header.PreviousHash = header.PrevHash + } +} + +// OnTrxStart implements Tracer. +func (t *FirehoseTracer) OnTrxStart(trx *types.Transaction) { + if t.activeTrx != nil { + panic(fmt.Errorf("transaction already started, something is wrong in the tracer call order")) + } + + t.activeTrx = &pbacme.Transaction{ + Type: trx.Type, + Hash: trx.Hash, + Sender: trx.Sender, + Receiver: trx.Receiver, + Amount: &pbacme.BigInt{Bytes: trx.Amount.Bytes()}, + Fee: &pbacme.BigInt{Bytes: trx.Fee.Bytes()}, + } +} + +// OnTrxEvent implements Tracer. +func (t *FirehoseTracer) OnTrxEvent(trxHash string, event *types.Event) { + if t.activeTrx == nil { + panic(fmt.Errorf("no active transaction, something is wrong in the tracer call order")) + } + + pbEvent := &pbacme.Event{ + Type: event.Type, + } + + if len(event.Attributes) > 0 { + pbEvent.Attributes = make([]*pbacme.Attribute, len(event.Attributes)) + for i, attr := range event.Attributes { + pbEvent.Attributes[i] = &pbacme.Attribute{ + Key: attr.Key, + Value: attr.Value, + } + } + } + + t.activeTrx.Events = append(t.activeTrx.Events, pbEvent) +} + +// OnTrxEnd implements Tracer. +func (t *FirehoseTracer) OnTrxEnd(trx *types.Transaction) { + if t.activeTrx == nil { + panic(fmt.Errorf("no active transaction, something is wrong in the tracer call order")) + } + + t.activeTrx.Success = trx.Success + + t.activeBlock.Transactions = append(t.activeBlock.Transactions, t.activeTrx) + t.activeTrx = nil +} diff --git a/tracer/tracer.go b/tracer/tracer.go new file mode 100644 index 0000000..e7a8543 --- /dev/null +++ b/tracer/tracer.go @@ -0,0 +1,19 @@ +package tracer + +import ( + "github.com/streamingfast/dummy-blockchain/types" +) + +type Tracer interface { + Initialize() error + + OnBlockStart(header *types.BlockHeader) + + OnTrxStart(trx *types.Transaction) + + OnTrxEvent(trxHash string, event *types.Event) + + OnTrxEnd(trx *types.Transaction) + + OnBlockEnd(blk *types.Block, finalBlockHeader *types.BlockHeader) +} diff --git a/types/types.go b/types/types.go index 7b3408f..cda708e 100644 --- a/types/types.go +++ b/types/types.go @@ -1,15 +1,49 @@ package types import ( + "crypto/sha256" + "fmt" "math/big" "time" ) +func MakeHash(data interface{}) string { + shaSum := sha256.Sum256([]byte(fmt.Sprintf("%v", data))) + return fmt.Sprintf("%x", shaSum) +} + +func GenesisBlock(height uint64) *Block { + genesisTime, err := time.Parse(time.RFC3339, "2024-01-01T00:00:00Z") + if err != nil { + panic(err) + } + + header := &BlockHeader{ + Height: height, + Hash: MakeHash(height), + FinalNum: height, + FinalHash: MakeHash(height), + Timestamp: genesisTime, + } + + return &Block{ + Header: header, + Transactions: nil, + } +} + +type BlockHeader struct { + Height uint64 `json:"height"` + Hash string `json:"hash"` + PrevNum *uint64 `json:"prev_num"` + PrevHash *string `json:"prev_hash"` + FinalNum uint64 `json:"final_num"` + FinalHash string `json:"final_hash"` + Timestamp time.Time `json:"timestamp"` +} + type Block struct { - Height uint64 `json:"height"` - Hash string `json:"hash"` - PrevHash string `json:"prev_hash"` - Timestamp time.Time `json:"timestamp"` + Header *BlockHeader `json:"header"` Transactions []Transaction `json:"transactions"` }