From 4da0d0ac64ad496f8d015be764813a7cfdc32e79 Mon Sep 17 00:00:00 2001 From: Jenita Date: Sat, 14 Jun 2025 12:48:32 -0500 Subject: [PATCH 1/5] feat: added changes to implementutxoWholeResult Signed-off-by: Jenita --- cmd/gouroboros/query.go | 12 ++++++++++++ protocol/localstatequery/client.go | 7 +++++++ 2 files changed, 19 insertions(+) diff --git a/cmd/gouroboros/query.go b/cmd/gouroboros/query.go index c562ddb6..019d30ad 100644 --- a/cmd/gouroboros/query.go +++ b/cmd/gouroboros/query.go @@ -278,6 +278,18 @@ func testQuery(f *globalFlags) { fmt.Printf("Assets: %s\n", assetsJson) } } + case "utxo-whole-result": + result, err := o.LocalStateQuery().Client.GetUTxOWhole() + if err != nil { + fmt.Printf("ERROR: failure querying UTxO whole: %s\n", err) + os.Exit(1) + } + jsonData, err := json.MarshalIndent(result, "", " ") + if err != nil { + fmt.Printf("ERROR: failed to marshal UTxO whole to JSON: %s\n", err) + os.Exit(1) + } + fmt.Println(string(jsonData)) default: fmt.Printf("ERROR: unknown query: %s\n", queryFlags.flagset.Args()[0]) os.Exit(1) diff --git a/protocol/localstatequery/client.go b/protocol/localstatequery/client.go index 14cd73fc..f31186a7 100644 --- a/protocol/localstatequery/client.go +++ b/protocol/localstatequery/client.go @@ -15,6 +15,7 @@ package localstatequery import ( + "encoding/json" "errors" "fmt" "sync" @@ -499,6 +500,12 @@ func (c *Client) GetUTxOWhole() (*UTxOWholeResult, error) { if err := c.runQuery(query, &result); err != nil { return nil, err } + jsonData, err := json.MarshalIndent(result, "", " ") + if err != nil { + return nil, fmt.Errorf("error marshaling UTxOWhole result to JSON: %s", err) + } + fmt.Println("UTxOWhole Result:") + fmt.Println(string(jsonData)) return &result, nil } From fdcfa3f217deb4ace09ecef7d3ec57930fd01bf1 Mon Sep 17 00:00:00 2001 From: Jenita Date: Sat, 14 Jun 2025 12:56:51 -0500 Subject: [PATCH 2/5] feat: added changes to implementutxoWholeResult Signed-off-by: Jenita --- protocol/localstatequery/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocol/localstatequery/client.go b/protocol/localstatequery/client.go index f31186a7..6ce9e293 100644 --- a/protocol/localstatequery/client.go +++ b/protocol/localstatequery/client.go @@ -502,7 +502,7 @@ func (c *Client) GetUTxOWhole() (*UTxOWholeResult, error) { } jsonData, err := json.MarshalIndent(result, "", " ") if err != nil { - return nil, fmt.Errorf("error marshaling UTxOWhole result to JSON: %s", err) + return nil, fmt.Errorf("error marshaling UTxOWhole result to JSON: %w", err) } fmt.Println("UTxOWhole Result:") fmt.Println(string(jsonData)) From 5a3a5523737ad621d7f05d54d3c258b34b0b42d6 Mon Sep 17 00:00:00 2001 From: Jenita Date: Mon, 11 Aug 2025 17:23:07 -0500 Subject: [PATCH 3/5] feat: added changes to implementutxoWholeResult Signed-off-by: Jenita --- cmd/gouroboros/query.go | 35 +++++++++-- protocol/localstatequery/client.go | 97 ++++++++++++++++++++++++++--- protocol/localstatequery/queries.go | 5 +- 3 files changed, 123 insertions(+), 14 deletions(-) diff --git a/cmd/gouroboros/query.go b/cmd/gouroboros/query.go index 019d30ad..fb964bd5 100644 --- a/cmd/gouroboros/query.go +++ b/cmd/gouroboros/query.go @@ -279,17 +279,40 @@ func testQuery(f *globalFlags) { } } case "utxo-whole-result": - result, err := o.LocalStateQuery().Client.GetUTxOWhole() + utxos, err := o.LocalStateQuery().Client.GetUTxOWhole() if err != nil { fmt.Printf("ERROR: failure querying UTxO whole: %s\n", err) os.Exit(1) } - jsonData, err := json.MarshalIndent(result, "", " ") - if err != nil { - fmt.Printf("ERROR: failed to marshal UTxO whole to JSON: %s\n", err) - os.Exit(1) + + for utxoId, utxo := range utxos.Results { + fmt.Println("---") + fmt.Printf("UTxO ID: %s#%d\n", utxoId.Hash.String(), utxoId.Idx) + fmt.Printf("Address: %x\n", utxo.Address) + fmt.Printf("Amount: %d\n", utxo.Amount) + + // Handle assets + if utxo.Assets != nil { + assets := utxo.Assets() + fmt.Printf("Assests: %d\n", assets) + if assets != nil { + fmt.Printf("Assets: %s\n", assets) + } + } + + // Handle datum + if utxo.Datum != nil { + datum := utxo.Datum() + fmt.Printf("Datum: %d\n", datum) + if datum != nil { + if cborData := datum.Cbor(); err == nil { + fmt.Printf("Datum CBOR: %x\n", cborData) + } else { + fmt.Printf("Datum present (error decoding: %v)\n", err) + } + } + } } - fmt.Println(string(jsonData)) default: fmt.Printf("ERROR: unknown query: %s\n", queryFlags.flagset.Args()[0]) os.Exit(1) diff --git a/protocol/localstatequery/client.go b/protocol/localstatequery/client.go index 6ce9e293..b289981a 100644 --- a/protocol/localstatequery/client.go +++ b/protocol/localstatequery/client.go @@ -15,7 +15,6 @@ package localstatequery import ( - "encoding/json" "errors" "fmt" "sync" @@ -477,6 +476,90 @@ func (c *Client) GetUTxOByAddress( return &result, nil } +func (c *Client) GetUTxOWholeRaw() ([]byte, error) { + c.busyMutex.Lock() + defer c.busyMutex.Unlock() + + currentEra, err := c.getCurrentEra() + if err != nil { + return nil, err + } + + query := buildShelleyQuery( + currentEra, + QueryTypeShelleyUtxoWhole, + ) + + msg := NewMsgQuery(query) + if !c.acquired { + if err := c.acquire(AcquireVolatileTip{}); err != nil { + return nil, err + } + } + if err := c.SendMessage(msg); err != nil { + return nil, err + } + resultCbor, ok := <-c.queryResultChan + if !ok { + return nil, protocol.ErrProtocolShuttingDown + } + return resultCbor, nil +} + +func decodeSimpleUTxO(rawCBOR []byte) (map[string]map[string]interface{}, error) { + var cborData []interface{} + if _, err := cbor.Decode(rawCBOR, &cborData); err != nil { + return nil, fmt.Errorf("CBOR decode error: %v", err) + } + + result := make(map[string]map[string]interface{}) + + for _, entry := range cborData { + entrySlice, ok := entry.([]interface{}) + if !ok || len(entrySlice) != 2 { + continue + } + + // Decode input (TxId + index) + input, ok := entrySlice[0].([]interface{}) + if !ok || len(input) != 2 { + continue + } + + txId, ok := input[0].([]byte) + if !ok { + continue + } + + outputIdx, ok := input[1].(uint64) + if !ok { + continue + } + + // Decode output (address + value) + output, ok := entrySlice[1].([]interface{}) + if !ok || len(output) != 2 { + continue + } + + address, ok := output[0].([]byte) + if !ok { + continue + } + + value := output[1] // Could be uint64 (lovelace) or map (multi-asset) + + // Create entry + key := fmt.Sprintf("%x#%d", txId, outputIdx) + result[key] = map[string]interface{}{ + "address": address, + "value": value, + } + } + + return result, nil +} + // GetUTxOWhole returns the current UTxO set func (c *Client) GetUTxOWhole() (*UTxOWholeResult, error) { c.Protocol.Logger(). @@ -500,12 +583,12 @@ func (c *Client) GetUTxOWhole() (*UTxOWholeResult, error) { if err := c.runQuery(query, &result); err != nil { return nil, err } - jsonData, err := json.MarshalIndent(result, "", " ") - if err != nil { - return nil, fmt.Errorf("error marshaling UTxOWhole result to JSON: %w", err) - } - fmt.Println("UTxOWhole Result:") - fmt.Println(string(jsonData)) + // jsonData, err := json.MarshalIndent(result, "", " ") + // if err != nil { + // return nil, fmt.Errorf("error marshaling UTxOWhole result to JSON: %w", err) + // } + // fmt.Println("UTxOWhole Result:") + // fmt.Println(string(jsonData)) return &result, nil } diff --git a/protocol/localstatequery/queries.go b/protocol/localstatequery/queries.go index af7a2de4..ce633b6b 100644 --- a/protocol/localstatequery/queries.go +++ b/protocol/localstatequery/queries.go @@ -596,7 +596,10 @@ func (u *UtxoId) MarshalCBOR() ([]byte, error) { /* result [{* utxo => value }] */ -type UTxOWholeResult any +type UTxOWholeResult struct { + cbor.StructAsArray + Results map[UtxoId]ledger.BabbageTransactionOutput +} // TODO (#863) type DebugEpochStateResult any From cdf1c0a1ab1a2944d06b3673965005dde212d965 Mon Sep 17 00:00:00 2001 From: Jenita Date: Mon, 11 Aug 2025 17:24:43 -0500 Subject: [PATCH 4/5] feat: added changes to implementutxoWholeResult Signed-off-by: Jenita --- protocol/localstatequery/client.go | 90 ------------------------------ 1 file changed, 90 deletions(-) diff --git a/protocol/localstatequery/client.go b/protocol/localstatequery/client.go index b289981a..14cd73fc 100644 --- a/protocol/localstatequery/client.go +++ b/protocol/localstatequery/client.go @@ -476,90 +476,6 @@ func (c *Client) GetUTxOByAddress( return &result, nil } -func (c *Client) GetUTxOWholeRaw() ([]byte, error) { - c.busyMutex.Lock() - defer c.busyMutex.Unlock() - - currentEra, err := c.getCurrentEra() - if err != nil { - return nil, err - } - - query := buildShelleyQuery( - currentEra, - QueryTypeShelleyUtxoWhole, - ) - - msg := NewMsgQuery(query) - if !c.acquired { - if err := c.acquire(AcquireVolatileTip{}); err != nil { - return nil, err - } - } - if err := c.SendMessage(msg); err != nil { - return nil, err - } - resultCbor, ok := <-c.queryResultChan - if !ok { - return nil, protocol.ErrProtocolShuttingDown - } - return resultCbor, nil -} - -func decodeSimpleUTxO(rawCBOR []byte) (map[string]map[string]interface{}, error) { - var cborData []interface{} - if _, err := cbor.Decode(rawCBOR, &cborData); err != nil { - return nil, fmt.Errorf("CBOR decode error: %v", err) - } - - result := make(map[string]map[string]interface{}) - - for _, entry := range cborData { - entrySlice, ok := entry.([]interface{}) - if !ok || len(entrySlice) != 2 { - continue - } - - // Decode input (TxId + index) - input, ok := entrySlice[0].([]interface{}) - if !ok || len(input) != 2 { - continue - } - - txId, ok := input[0].([]byte) - if !ok { - continue - } - - outputIdx, ok := input[1].(uint64) - if !ok { - continue - } - - // Decode output (address + value) - output, ok := entrySlice[1].([]interface{}) - if !ok || len(output) != 2 { - continue - } - - address, ok := output[0].([]byte) - if !ok { - continue - } - - value := output[1] // Could be uint64 (lovelace) or map (multi-asset) - - // Create entry - key := fmt.Sprintf("%x#%d", txId, outputIdx) - result[key] = map[string]interface{}{ - "address": address, - "value": value, - } - } - - return result, nil -} - // GetUTxOWhole returns the current UTxO set func (c *Client) GetUTxOWhole() (*UTxOWholeResult, error) { c.Protocol.Logger(). @@ -583,12 +499,6 @@ func (c *Client) GetUTxOWhole() (*UTxOWholeResult, error) { if err := c.runQuery(query, &result); err != nil { return nil, err } - // jsonData, err := json.MarshalIndent(result, "", " ") - // if err != nil { - // return nil, fmt.Errorf("error marshaling UTxOWhole result to JSON: %w", err) - // } - // fmt.Println("UTxOWhole Result:") - // fmt.Println(string(jsonData)) return &result, nil } From a5d08f81c856b7b3c59b8cb96a68619d020c8b15 Mon Sep 17 00:00:00 2001 From: Jenita Date: Mon, 11 Aug 2025 17:35:06 -0500 Subject: [PATCH 5/5] feat: added changes to implementutxoWholeResult Signed-off-by: Jenita --- cmd/gouroboros/query.go | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/cmd/gouroboros/query.go b/cmd/gouroboros/query.go index fb964bd5..71542cdd 100644 --- a/cmd/gouroboros/query.go +++ b/cmd/gouroboros/query.go @@ -288,28 +288,20 @@ func testQuery(f *globalFlags) { for utxoId, utxo := range utxos.Results { fmt.Println("---") fmt.Printf("UTxO ID: %s#%d\n", utxoId.Hash.String(), utxoId.Idx) - fmt.Printf("Address: %x\n", utxo.Address) - fmt.Printf("Amount: %d\n", utxo.Amount) + fmt.Printf("Address: %x\n", utxo.Address()) + fmt.Printf("Amount: %d\n", utxo.Amount()) - // Handle assets - if utxo.Assets != nil { - assets := utxo.Assets() - fmt.Printf("Assests: %d\n", assets) - if assets != nil { - fmt.Printf("Assets: %s\n", assets) - } + assets := utxo.Assets() + if assets != nil { + fmt.Printf("Assets: %+v\n", assets) } - // Handle datum - if utxo.Datum != nil { - datum := utxo.Datum() - fmt.Printf("Datum: %d\n", datum) - if datum != nil { - if cborData := datum.Cbor(); err == nil { - fmt.Printf("Datum CBOR: %x\n", cborData) - } else { - fmt.Printf("Datum present (error decoding: %v)\n", err) - } + datum := utxo.Datum() + if datum != nil { + if cborData := datum.Cbor(); cborData != nil { + fmt.Printf("Datum CBOR: %x\n", cborData) + } else { + fmt.Printf("Datum present (error decoding)") } } }