Skip to content

Commit 409ebf0

Browse files
authored
Create cliui_calldata_test.go
1 parent c0b4b2b commit 409ebf0

File tree

1 file changed

+180
-0
lines changed

1 file changed

+180
-0
lines changed

signer/core/cliui_calldata_test.go

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
package core
2+
3+
import (
4+
"bufio"
5+
"bytes"
6+
"os"
7+
"strings"
8+
"testing"
9+
10+
"github.com/ethereum/go-ethereum/common/hexutil"
11+
"github.com/ethereum/go-ethereum/signer/core/apitypes"
12+
)
13+
14+
func captureOutput(t *testing.T, fn func()) string {
15+
t.Helper()
16+
old := os.Stdout
17+
r, w, err := os.Pipe()
18+
if err != nil {
19+
t.Fatalf("pipe error: %v", err)
20+
}
21+
os.Stdout = w
22+
var buf bytes.Buffer
23+
done := make(chan struct{})
24+
go func() {
25+
_, _ = buf.ReadFrom(r)
26+
close(done)
27+
}()
28+
fn()
29+
_ = w.Close()
30+
<-done
31+
os.Stdout = old
32+
return buf.String()
33+
}
34+
35+
func TestApproveTx_DisplaysEffectiveCalldata(t *testing.T) {
36+
mkUI := func(input string) *CommandlineUI {
37+
return &CommandlineUI{in: bufio.NewReader(strings.NewReader(input))}
38+
}
39+
hex := func(b []byte) string { return hexutil.Encode(b) }
40+
// helper to create *hexutil.Bytes
41+
hx := func(b []byte) *hexutil.Bytes { v := hexutil.Bytes(b); return &v }
42+
// zero 1559 fee fields to avoid GasPrice nil deref in CLI
43+
zeroFee := func(a *apitypes.SendTxArgs) {
44+
z := new(hexutil.Big)
45+
a.MaxFeePerGas = z
46+
a.MaxPriorityFeePerGas = z
47+
}
48+
49+
cases := []struct {
50+
name string
51+
args apitypes.SendTxArgs
52+
wantContains []string
53+
wantNotExists []string
54+
}{
55+
{
56+
name: "only input",
57+
args: func() apitypes.SendTxArgs {
58+
a := apitypes.SendTxArgs{Input: hx([]byte{0x01, 0x02})}
59+
zeroFee(&a)
60+
return a
61+
}(),
62+
wantContains: []string{
63+
"input:",
64+
hex([]byte{0x01, 0x02}),
65+
},
66+
wantNotExists: []string{"WARNING: both input and data provided and differ"},
67+
},
68+
{
69+
name: "only data",
70+
args: func() apitypes.SendTxArgs { a := apitypes.SendTxArgs{Data: hx([]byte{0x0a})}; zeroFee(&a); return a }(),
71+
wantContains: []string{
72+
"data:",
73+
hex([]byte{0x0a}),
74+
},
75+
wantNotExists: []string{"WARNING: both input and data provided and differ"},
76+
},
77+
{
78+
name: "both equal",
79+
args: func() apitypes.SendTxArgs {
80+
b := hexutil.Bytes([]byte{0xaa, 0xbb})
81+
a := apitypes.SendTxArgs{Input: &b, Data: &b}
82+
zeroFee(&a)
83+
return a
84+
}(),
85+
wantContains: []string{
86+
"input:",
87+
hex([]byte{0xaa, 0xbb}),
88+
},
89+
wantNotExists: []string{"WARNING: both input and data provided and differ", "data:"},
90+
},
91+
{
92+
name: "both different",
93+
args: func() apitypes.SendTxArgs {
94+
a := apitypes.SendTxArgs{Input: hx([]byte{0x01}), Data: hx([]byte{0x02})}
95+
zeroFee(&a)
96+
return a
97+
}(),
98+
wantContains: []string{
99+
"input:",
100+
"data:",
101+
"WARNING: both input and data provided and differ",
102+
hex([]byte{0x01}),
103+
hex([]byte{0x02}),
104+
},
105+
},
106+
}
107+
108+
for _, tc := range cases {
109+
t.Run(tc.name, func(t *testing.T) {
110+
ui := mkUI("y\n")
111+
req := &SignTxRequest{Transaction: tc.args}
112+
out := captureOutput(t, func() {
113+
_, err := ui.ApproveTx(req)
114+
if err != nil {
115+
t.Fatalf("ApproveTx error: %v", err)
116+
}
117+
})
118+
for _, s := range tc.wantContains {
119+
if !strings.Contains(out, s) {
120+
t.Fatalf("output does not contain %q. Output:\n%s", s, out)
121+
}
122+
}
123+
for _, s := range tc.wantNotExists {
124+
if strings.Contains(out, s) {
125+
t.Fatalf("output should not contain %q. Output:\n%s", s, out)
126+
}
127+
}
128+
})
129+
}
130+
}
131+
132+
func TestLogDiff_EffectiveCalldata(t *testing.T) {
133+
mk := func(inOld, dataOld, inNew, dataNew []byte) (SignTxRequest, SignTxResponse) {
134+
var (
135+
inO, dO, inN, dN *hexutil.Bytes
136+
)
137+
if inOld != nil {
138+
v := hexutil.Bytes(inOld)
139+
inO = &v
140+
}
141+
if dataOld != nil {
142+
v := hexutil.Bytes(dataOld)
143+
dO = &v
144+
}
145+
if inNew != nil {
146+
v := hexutil.Bytes(inNew)
147+
inN = &v
148+
}
149+
if dataNew != nil {
150+
v := hexutil.Bytes(dataNew)
151+
dN = &v
152+
}
153+
return SignTxRequest{Transaction: apitypes.SendTxArgs{Input: inO, Data: dO}}, SignTxResponse{Transaction: apitypes.SendTxArgs{Input: inN, Data: dN}}
154+
}
155+
cases := []struct {
156+
name string
157+
inOld []byte
158+
dataOld []byte
159+
inNew []byte
160+
dataNew []byte
161+
modified bool
162+
}{
163+
{"only input unchanged", []byte{0x01}, nil, []byte{0x01}, nil, false},
164+
{"only data unchanged", nil, []byte{0x02}, nil, []byte{0x02}, false},
165+
{"both equal unchanged", []byte{0x0a}, []byte{0x0a}, []byte{0x0a}, []byte{0x0a}, false},
166+
{"effective changed (input differs)", []byte{0x01}, nil, []byte{0x02}, nil, true},
167+
{"effective changed (data differs, no input)", nil, []byte{0x01}, nil, []byte{0x02}, true},
168+
{"effective equal though underlying fields differ", []byte{0xaa}, []byte{0xbb}, []byte{0xaa}, []byte{0xbb}, false},
169+
{"both set but only new input changes", []byte{0x01}, []byte{0x01}, []byte{0x02}, []byte{0x01}, true},
170+
}
171+
for _, tc := range cases {
172+
t.Run(tc.name, func(t *testing.T) {
173+
orig, nw := mk(tc.inOld, tc.dataOld, tc.inNew, tc.dataNew)
174+
m := logDiff(&orig, &nw)
175+
if m != tc.modified {
176+
t.Fatalf("modified mismatch: have %v want %v", m, tc.modified)
177+
}
178+
})
179+
}
180+
}

0 commit comments

Comments
 (0)