Skip to content

Commit 33aed59

Browse files
committed
feat(ledger): Added friendly string representation of TX outputs for the eras alonzo, babbage, byron, mary and shelley
Signed-off-by: Akhil Repala <[email protected]>
1 parent c8cb60b commit 33aed59

File tree

13 files changed

+188
-4
lines changed

13 files changed

+188
-4
lines changed

ledger/alonzo/alonzo.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,19 @@ func (o AlonzoTransactionOutput) Utxorpc() (*utxorpc.TxOutput, error) {
447447
nil
448448
}
449449

450+
func (o AlonzoTransactionOutput) String() string {
451+
assets := ""
452+
if o.OutputAmount.Assets != nil && len(o.OutputAmount.Assets.Policies()) > 0 {
453+
assets = " assets=..."
454+
}
455+
return fmt.Sprintf(
456+
"(AlonzoTransactionOutput address=%s amount=%d%s)",
457+
o.OutputAddress.String(),
458+
o.OutputAmount.Amount,
459+
assets,
460+
)
461+
}
462+
450463
type AlonzoRedeemer struct {
451464
cbor.StructAsArray
452465
Tag common.RedeemerTag

ledger/alonzo/alonzo_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package alonzo
1717
import (
1818
"math/big"
1919
"reflect"
20+
"regexp"
2021
"testing"
2122

2223
"github.com/blinklabs-io/gouroboros/cbor"
@@ -277,3 +278,23 @@ func TestAlonzoRedeemersIter(t *testing.T) {
277278
iterIdx++
278279
}
279280
}
281+
282+
func TestAlonzoTransactionOutputString(t *testing.T) {
283+
addr, _ := common.NewAddress(
284+
"addr1qytna5k2fq9ler0fuk45j7zfwv7t2zwhp777nvdjqqfr5tz8ztpwnk8zq5ngetcz5k5mckgkajnygtsra9aej2h3ek5seupmvd",
285+
)
286+
ma := common.NewMultiAsset[common.MultiAssetTypeOutput](
287+
map[common.Blake2b224]map[cbor.ByteString]uint64{
288+
common.NewBlake2b224(make([]byte, 28)): {cbor.NewByteString([]byte("t")): 2},
289+
},
290+
)
291+
out := AlonzoTransactionOutput{
292+
OutputAddress: addr,
293+
OutputAmount: mary.MaryTransactionOutputValue{Amount: 456, Assets: &ma},
294+
}
295+
s := out.String()
296+
re := regexp.MustCompile(`^\(AlonzoTransactionOutput address=addr1[0-9a-z]+ amount=456 assets=\.\.\.\)$`)
297+
if !re.MatchString(s) {
298+
t.Fatalf("unexpected string: %s", s)
299+
}
300+
}

ledger/babbage/babbage.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,19 @@ func (o BabbageTransactionOutput) Utxorpc() (*utxorpc.TxOutput, error) {
649649
nil
650650
}
651651

652+
func (o BabbageTransactionOutput) String() string {
653+
assets := ""
654+
if o.OutputAmount.Assets != nil && len(o.OutputAmount.Assets.Policies()) > 0 {
655+
assets = " assets=..."
656+
}
657+
return fmt.Sprintf(
658+
"(BabbageTransactionOutput address=%s amount=%d%s)",
659+
o.OutputAddress.String(),
660+
o.OutputAmount.Amount,
661+
assets,
662+
)
663+
}
664+
652665
type BabbageTransactionWitnessSet struct {
653666
cbor.DecodeStoreCbor
654667
VkeyWitnesses []common.VkeyWitness `cbor:"0,keyasint,omitempty"`

ledger/babbage/babbage_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package babbage
1717
import (
1818
"math/big"
1919
"reflect"
20+
"regexp"
2021
"testing"
2122

2223
"github.com/blinklabs-io/gouroboros/cbor"
@@ -2970,3 +2971,23 @@ func TestBabbageTransactionOutputToPlutusDataCoinAssets(t *testing.T) {
29702971
)
29712972
}
29722973
}
2974+
2975+
func TestBabbageTransactionOutputString(t *testing.T) {
2976+
addr, _ := common.NewAddress(
2977+
"addr1qytna5k2fq9ler0fuk45j7zfwv7t2zwhp777nvdjqqfr5tz8ztpwnk8zq5ngetcz5k5mckgkajnygtsra9aej2h3ek5seupmvd",
2978+
)
2979+
ma := common.NewMultiAsset[common.MultiAssetTypeOutput](
2980+
map[common.Blake2b224]map[cbor.ByteString]uint64{
2981+
common.NewBlake2b224(make([]byte, 28)): {cbor.NewByteString([]byte("x")): 2},
2982+
},
2983+
)
2984+
out := BabbageTransactionOutput{
2985+
OutputAddress: addr,
2986+
OutputAmount: mary.MaryTransactionOutputValue{Amount: 456, Assets: &ma},
2987+
}
2988+
s := out.String()
2989+
re := regexp.MustCompile(`^\(BabbageTransactionOutput address=addr1[0-9a-z]+ amount=456 assets=\.\.\.\)$`)
2990+
if !re.MatchString(s) {
2991+
t.Fatalf("unexpected string: %s", s)
2992+
}
2993+
}

ledger/byron/byron.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,14 @@ func (o ByronTransactionOutput) Utxorpc() (*utxorpc.TxOutput, error) {
462462
nil
463463
}
464464

465+
func (o ByronTransactionOutput) String() string {
466+
return fmt.Sprintf(
467+
"(ByronTransactionOutput address=%s amount=%d)",
468+
o.OutputAddress.String(),
469+
o.OutputAmount,
470+
)
471+
}
472+
465473
type ByronBlockVersion struct {
466474
cbor.StructAsArray
467475
Major uint16

ledger/byron/byron_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package byron_test
1616

1717
import (
1818
"reflect"
19+
"regexp"
1920
"testing"
2021

2122
"github.com/blinklabs-io/gouroboros/ledger/byron"
@@ -104,3 +105,23 @@ func TestByronTransaction_Utxorpc_Empty(t *testing.T) {
104105
t.Errorf("Expected fee = 0, got %d", result.Fee)
105106
}
106107
}
108+
109+
func TestByronTransactionOutputString(t *testing.T) {
110+
addr, err := common.NewByronAddressFromParts(
111+
0,
112+
make([]byte, common.AddressHashSize),
113+
common.ByronAddressAttributes{},
114+
)
115+
if err != nil {
116+
t.Fatalf("address: %v", err)
117+
}
118+
out := byron.ByronTransactionOutput{
119+
OutputAddress: addr,
120+
OutputAmount: 456,
121+
}
122+
s := out.String()
123+
re := regexp.MustCompile(`^\(ByronTransactionOutput address=[1-9A-HJ-NP-Za-km-z]+ amount=456\)$`)
124+
if !re.MatchString(s) {
125+
t.Fatalf("unexpected string: %s", s)
126+
}
127+
}

ledger/common/tx.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ type TransactionOutput interface {
7777
Utxorpc() (*utxorpc.TxOutput, error)
7878
ScriptRef() Script
7979
ToPlutusData() data.PlutusData
80+
String() string
8081
}
8182

8283
type TransactionWitnessSet interface {

ledger/mary/errors.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
package mary
1616

1717
import (
18-
"fmt"
1918
"strings"
2019

2120
"github.com/blinklabs-io/gouroboros/ledger/common"
@@ -28,7 +27,7 @@ type OutputTooBigUtxoError struct {
2827
func (e OutputTooBigUtxoError) Error() string {
2928
tmpOutputs := make([]string, len(e.Outputs))
3029
for idx, tmpOutput := range e.Outputs {
31-
tmpOutputs[idx] = fmt.Sprintf("%#v", tmpOutput)
30+
tmpOutputs[idx] = tmpOutput.String()
3231
}
3332
return "output value too large: " + strings.Join(tmpOutputs, ", ")
3433
}

ledger/mary/mary.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,19 @@ func (o MaryTransactionOutput) Utxorpc() (*utxorpc.TxOutput, error) {
490490
err
491491
}
492492

493+
func (o MaryTransactionOutput) String() string {
494+
assets := ""
495+
if o.OutputAmount.Assets != nil && len(o.OutputAmount.Assets.Policies()) > 0 {
496+
assets = " assets=..."
497+
}
498+
return fmt.Sprintf(
499+
"(MaryTransactionOutput address=%s amount=%d%s)",
500+
o.OutputAddress.String(),
501+
o.OutputAmount.Amount,
502+
assets,
503+
)
504+
}
505+
493506
type MaryTransactionOutputValue struct {
494507
cbor.StructAsArray
495508
Amount uint64

ledger/mary/mary_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package mary
1717
import (
1818
"encoding/hex"
1919
"reflect"
20+
"regexp"
2021
"testing"
2122

2223
"github.com/blinklabs-io/gouroboros/cbor"
@@ -115,3 +116,34 @@ func TestMaryTransactionOutputValueEncodeDecode(t *testing.T) {
115116
}
116117
}
117118
}
119+
120+
func TestMaryTransactionOutputString(t *testing.T) {
121+
addr, _ := common.NewAddress("addr1qytna5k2fq9ler0fuk45j7zfwv7t2zwhp777nvdjqqfr5tz8ztpwnk8zq5ngetcz5k5mckgkajnygtsra9aej2h3ek5seupmvd")
122+
ma := common.NewMultiAsset[common.MultiAssetTypeOutput](
123+
map[common.Blake2b224]map[cbor.ByteString]uint64{
124+
common.NewBlake2b224(make([]byte, 28)): {cbor.NewByteString([]byte("token")): 2},
125+
},
126+
)
127+
out := MaryTransactionOutput{
128+
OutputAddress: addr,
129+
OutputAmount: MaryTransactionOutputValue{Amount: 456, Assets: &ma},
130+
}
131+
s := out.String()
132+
re := regexp.MustCompile(`^\(MaryTransactionOutput address=addr1[0-9a-z]+ amount=456 assets=\.\.\.\)$`)
133+
if !re.MatchString(s) {
134+
t.Fatalf("unexpected string: %s", s)
135+
}
136+
}
137+
138+
func TestMaryOutputTooBigErrorFormatting(t *testing.T) {
139+
addr, _ := common.NewAddress("addr1qytna5k2fq9ler0fuk45j7zfwv7t2zwhp777nvdjqqfr5tz8ztpwnk8zq5ngetcz5k5mckgkajnygtsra9aej2h3ek5seupmvd")
140+
out := &MaryTransactionOutput{
141+
OutputAddress: addr,
142+
OutputAmount: MaryTransactionOutputValue{Amount: 456},
143+
}
144+
errStr := OutputTooBigUtxoError{Outputs: []common.TransactionOutput{out}}.Error()
145+
re := regexp.MustCompile(`^output value too large: \(MaryTransactionOutput address=addr1[0-9a-z]+ amount=456\)$`)
146+
if !re.MatchString(errStr) {
147+
t.Fatalf("unexpected error: %s", errStr)
148+
}
149+
}

0 commit comments

Comments
 (0)