Skip to content

Commit 90f4aa9

Browse files
Merge pull request #6453 from oasisprotocol/uniyalabhishek/staking-tx-address-formatting
2 parents db325a0 + b9d1585 commit 90f4aa9

4 files changed

Lines changed: 169 additions & 6 deletions

File tree

.changelog/6453.feature.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
go/staking/api: Format known addresses in staking transaction PrettyPrint

go/staking/api/api.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ type Transfer struct {
426426
// PrettyPrint writes a pretty-printed representation of Transfer to the given
427427
// writer.
428428
func (t Transfer) PrettyPrint(ctx context.Context, prefix string, w io.Writer) {
429-
fmt.Fprintf(w, "%sTo: %s\n", prefix, t.To)
429+
fmt.Fprintf(w, "%sTo: %s\n", prefix, FormatAddress(ctx, t.To))
430430

431431
fmt.Fprintf(w, "%sAmount: ", prefix)
432432
token.PrettyPrintAmount(ctx, t.Amount, w)
@@ -477,7 +477,7 @@ type Escrow struct {
477477
// PrettyPrint writes a pretty-printed representation of Escrow to the given
478478
// writer.
479479
func (e Escrow) PrettyPrint(ctx context.Context, prefix string, w io.Writer) {
480-
fmt.Fprintf(w, "%sTo: %s\n", prefix, e.Account)
480+
fmt.Fprintf(w, "%sTo: %s\n", prefix, FormatAddress(ctx, e.Account))
481481

482482
fmt.Fprintf(w, "%sAmount: ", prefix)
483483
token.PrettyPrintAmount(ctx, e.Amount, w)
@@ -503,8 +503,8 @@ type ReclaimEscrow struct {
503503

504504
// PrettyPrint writes a pretty-printed representation of ReclaimEscrow to the
505505
// given writer.
506-
func (re ReclaimEscrow) PrettyPrint(_ context.Context, prefix string, w io.Writer) {
507-
fmt.Fprintf(w, "%sFrom: %s\n", prefix, re.Account)
506+
func (re ReclaimEscrow) PrettyPrint(ctx context.Context, prefix string, w io.Writer) {
507+
fmt.Fprintf(w, "%sFrom: %s\n", prefix, FormatAddress(ctx, re.Account))
508508

509509
fmt.Fprintf(w, "%sShares: %s\n", prefix, re.Shares)
510510
}
@@ -552,7 +552,7 @@ type Allow struct {
552552

553553
// PrettyPrint writes a pretty-printed representation of Allow to the given writer.
554554
func (aw Allow) PrettyPrint(ctx context.Context, prefix string, w io.Writer) {
555-
fmt.Fprintf(w, "%sBeneficiary: %s\n", prefix, aw.Beneficiary)
555+
fmt.Fprintf(w, "%sBeneficiary: %s\n", prefix, FormatAddress(ctx, aw.Beneficiary))
556556

557557
sign := "+"
558558
if aw.Negative {
@@ -582,7 +582,7 @@ type Withdraw struct {
582582

583583
// PrettyPrint writes a pretty-printed representation of Withdraw to the given writer.
584584
func (wt Withdraw) PrettyPrint(ctx context.Context, prefix string, w io.Writer) {
585-
fmt.Fprintf(w, "%sFrom: %s\n", prefix, wt.From)
585+
fmt.Fprintf(w, "%sFrom: %s\n", prefix, FormatAddress(ctx, wt.From))
586586

587587
fmt.Fprintf(w, "%sAmount: ", prefix)
588588
token.PrettyPrintAmount(ctx, wt.Amount, w)

go/staking/api/prettyprint.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,43 @@ import (
99
"github.com/oasisprotocol/oasis-core/go/common/quantity"
1010
)
1111

12+
type contextKey string
13+
14+
// ContextKeyAccountNames is the key to retrieve native (Bech32) account names from context.
15+
var ContextKeyAccountNames = contextKey("staking/account-names")
16+
17+
// AccountNames maps native (Bech32) addresses to user-defined account names for pretty printing.
18+
type AccountNames map[string]string
19+
20+
// FormatAddress is like FormatAddressWith but reads names from ctx.
21+
func FormatAddress(ctx context.Context, addr Address) string {
22+
var names AccountNames
23+
if v, ok := ctx.Value(ContextKeyAccountNames).(AccountNames); ok {
24+
names = v
25+
}
26+
27+
return FormatAddressWith(names, addr)
28+
}
29+
30+
// FormatAddressWith formats a staking address for display.
31+
//
32+
// Output cases:
33+
// - Named address: "name (oasis1...)"
34+
// - Unknown address: "oasis1..."
35+
func FormatAddressWith(names AccountNames, addr Address) string {
36+
native := addr.String()
37+
if names == nil {
38+
return native
39+
}
40+
41+
name := names[native]
42+
if name == "" {
43+
return native
44+
}
45+
46+
return fmt.Sprintf("%s (%s)", name, native)
47+
}
48+
1249
// PrettyPrintCommissionRatePercentage returns the string representing the
1350
// commission rate (bound) in percentage for the given commission rate (bound)
1451
// numerator.

go/staking/api/prettyprint_test.go

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package api
22

33
import (
4+
"bytes"
45
"context"
56
"testing"
67

@@ -10,6 +11,14 @@ import (
1011
"github.com/oasisprotocol/oasis-core/go/common/quantity"
1112
)
1213

14+
func mustAddress(t *testing.T, raw string) Address {
15+
t.Helper()
16+
17+
var addr Address
18+
require.NoError(t, addr.UnmarshalText([]byte(raw)))
19+
return addr
20+
}
21+
1322
func TestPrettyPrintCommissionRatePercentage(t *testing.T) {
1423
require := require.New(t)
1524

@@ -54,3 +63,119 @@ func TestPrettyPrintCommissionScheduleIndexInfixes(t *testing.T) {
5463
require.Equal(t.expectedEmptyInfix, emptyInfix, "obtained empty infix didn't match expected value")
5564
}
5665
}
66+
67+
func TestFormatAddressWith(t *testing.T) {
68+
require := require.New(t)
69+
70+
addr := mustAddress(t, "oasis1qrydpazemvuwtnp3efm7vmfvg3tde044qg6cxwzx")
71+
native := addr.String()
72+
73+
for _, tc := range []struct {
74+
name string
75+
names AccountNames
76+
expected string
77+
}{
78+
{
79+
name: "nil names",
80+
names: nil,
81+
expected: native,
82+
},
83+
{
84+
name: "empty names",
85+
names: AccountNames{},
86+
expected: native,
87+
},
88+
{
89+
name: "unknown name",
90+
names: AccountNames{"oasis1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpkfh7w": "ignored"},
91+
expected: native,
92+
},
93+
{
94+
name: "named address",
95+
names: AccountNames{native: "test:bob"},
96+
expected: "test:bob (" + native + ")",
97+
},
98+
} {
99+
t.Run(tc.name, func(t *testing.T) {
100+
require.Equal(tc.expected, FormatAddressWith(tc.names, addr))
101+
})
102+
}
103+
}
104+
105+
func TestFormatAddress(t *testing.T) {
106+
require := require.New(t)
107+
108+
addr := mustAddress(t, "oasis1qrydpazemvuwtnp3efm7vmfvg3tde044qg6cxwzx")
109+
native := addr.String()
110+
111+
t.Run("without context names", func(t *testing.T) {
112+
require.Equal(native, FormatAddress(context.Background(), addr))
113+
})
114+
115+
t.Run("with context names", func(t *testing.T) {
116+
ctx := context.WithValue(context.Background(), ContextKeyAccountNames, AccountNames{
117+
native: "test:bob",
118+
})
119+
require.Equal("test:bob ("+native+")", FormatAddress(ctx, addr))
120+
})
121+
}
122+
123+
func TestStakingTxPrettyPrintUsesNamedAddresses(t *testing.T) {
124+
require := require.New(t)
125+
126+
addr := mustAddress(t, "oasis1qrydpazemvuwtnp3efm7vmfvg3tde044qg6cxwzx")
127+
native := addr.String()
128+
amt := *quantity.NewFromUint64(1)
129+
130+
ctx := context.WithValue(context.Background(), ContextKeyAccountNames, AccountNames{
131+
native: "test:bob",
132+
})
133+
134+
for _, tc := range []struct {
135+
name string
136+
pretty func(context.Context, *bytes.Buffer)
137+
expected string
138+
}{
139+
{
140+
name: "transfer to",
141+
pretty: func(ctx context.Context, buf *bytes.Buffer) {
142+
Transfer{To: addr, Amount: amt}.PrettyPrint(ctx, "", buf)
143+
},
144+
expected: "To: test:bob (" + native + ")",
145+
},
146+
{
147+
name: "escrow account",
148+
pretty: func(ctx context.Context, buf *bytes.Buffer) {
149+
Escrow{Account: addr, Amount: amt}.PrettyPrint(ctx, "", buf)
150+
},
151+
expected: "To: test:bob (" + native + ")",
152+
},
153+
{
154+
name: "reclaim escrow from",
155+
pretty: func(ctx context.Context, buf *bytes.Buffer) {
156+
ReclaimEscrow{Account: addr, Shares: amt}.PrettyPrint(ctx, "", buf)
157+
},
158+
expected: "From: test:bob (" + native + ")",
159+
},
160+
{
161+
name: "allow beneficiary",
162+
pretty: func(ctx context.Context, buf *bytes.Buffer) {
163+
Allow{Beneficiary: addr, AmountChange: amt}.PrettyPrint(ctx, "", buf)
164+
},
165+
expected: "Beneficiary: test:bob (" + native + ")",
166+
},
167+
{
168+
name: "withdraw from",
169+
pretty: func(ctx context.Context, buf *bytes.Buffer) {
170+
Withdraw{From: addr, Amount: amt}.PrettyPrint(ctx, "", buf)
171+
},
172+
expected: "From: test:bob (" + native + ")",
173+
},
174+
} {
175+
t.Run(tc.name, func(t *testing.T) {
176+
var buf bytes.Buffer
177+
tc.pretty(ctx, &buf)
178+
require.Contains(buf.String(), tc.expected)
179+
})
180+
}
181+
}

0 commit comments

Comments
 (0)