package main import ( "encoding/json" "flag" "fmt" "os" pump_parser "github.com/thloyi/pump-parser" ) type blockResponse struct { Result blockResult `json:"result"` } type blockResult struct { BlockTime *int64 `json:"blockTime"` Transactions []pump_parser.RawTx `json:"transactions"` } func main() { var ( filePath = flag.String("file", "", "path to getBlock payload json") slot = flag.Uint64("slot", 0, "block slot") swapsOnly = flag.Bool("swaps-only", false, "only include transactions with swaps > 0") ) flag.Parse() if *filePath == "" || *slot == 0 { fmt.Fprintln(os.Stderr, "usage: measure_tx_binary_block -file /path/block.json -slot 413539056") os.Exit(2) } raw, err := os.ReadFile(*filePath) if err != nil { fmt.Fprintf(os.Stderr, "read file: %v\n", err) os.Exit(1) } var response blockResponse if err := json.Unmarshal(raw, &response); err != nil { fmt.Fprintf(os.Stderr, "unmarshal block payload: %v\n", err) os.Exit(1) } var blockTime *uint64 if response.Result.BlockTime != nil { bt := uint64(*response.Result.BlockTime) blockTime = &bt } total := len(response.Result.Transactions) converted := 0 parsed := 0 convertFailures := 0 parseFailures := 0 encodeFailures := 0 filteredOutNoSwaps := 0 var totalRawTxBytes int var totalSingleEncoded int minSingleEncoded := -1 maxSingleEncoded := 0 parsedTxs := make([]pump_parser.Tx, 0, total) for i, rawTx := range response.Result.Transactions { transactionJSON, err := json.Marshal(rawTx.Transaction) if err == nil { totalRawTxBytes += len(transactionJSON) } rawTx.BlockTime = 0 if blockTime != nil { rawTx.BlockTime = int64(*blockTime) } rawTx.Slot = *slot rawTx.IndexWithinBlock = int64(i) converted++ tx, err := pump_parser.ParseRawTx(&rawTx) if err != nil { parseFailures++ continue } if *swapsOnly && len(tx.Swaps) == 0 { filteredOutNoSwaps++ continue } parsed++ encoded, err := pump_parser.EncodeTxBinary(tx) if err != nil { encodeFailures++ continue } size := len(encoded) totalSingleEncoded += size if minSingleEncoded == -1 || size < minSingleEncoded { minSingleEncoded = size } if size > maxSingleEncoded { maxSingleEncoded = size } parsedTxs = append(parsedTxs, *tx) } batchEncoded, err := pump_parser.EncodeTxsBinary(parsedTxs) if err != nil { fmt.Fprintf(os.Stderr, "encode txs binary: %v\n", err) os.Exit(1) } avgSingleEncoded := 0 if parsed > 0 { avgSingleEncoded = totalSingleEncoded / parsed } fmt.Printf("block_slot=%d\n", *slot) fmt.Printf("payload_json_bytes=%d\n", len(raw)) fmt.Printf("transactions_total=%d\n", total) fmt.Printf("transactions_converted=%d\n", converted) fmt.Printf("transactions_parsed=%d\n", parsed) fmt.Printf("transactions_filtered_no_swaps=%d\n", filteredOutNoSwaps) fmt.Printf("convert_failures=%d\n", convertFailures) fmt.Printf("parse_failures=%d\n", parseFailures) fmt.Printf("encode_failures=%d\n", encodeFailures) fmt.Printf("raw_tx_total_bytes=%d\n", totalRawTxBytes) fmt.Printf("single_txbinary_total_bytes=%d\n", totalSingleEncoded) fmt.Printf("single_txbinary_avg_bytes=%d\n", avgSingleEncoded) fmt.Printf("single_txbinary_min_bytes=%d\n", minSingleEncoded) fmt.Printf("single_txbinary_max_bytes=%d\n", maxSingleEncoded) fmt.Printf("batch_shared_table_bytes=%d\n", len(batchEncoded)) if totalSingleEncoded > 0 { fmt.Printf("batch_vs_single_saved_bytes=%d\n", totalSingleEncoded-len(batchEncoded)) } }