Skip to content

Commit 340b891

Browse files
nullunCopilot
andauthored
tests: Cover all wellFormed asset errors and small 0 axfer e2e test (#6417)
Co-authored-by: Copilot <[email protected]>
1 parent 7dbdb38 commit 340b891

File tree

2 files changed

+223
-1
lines changed

2 files changed

+223
-1
lines changed

data/transactions/asset_test.go

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
// Copyright (C) 2019-2025 Algorand, Inc.
2+
// This file is part of go-algorand
3+
//
4+
// go-algorand is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as
6+
// published by the Free Software Foundation, either version 3 of the
7+
// License, or (at your option) any later version.
8+
//
9+
// go-algorand is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with go-algorand. If not, see <https://www.gnu.org/licenses/>.
16+
17+
package transactions
18+
19+
import (
20+
"fmt"
21+
"strings"
22+
"testing"
23+
24+
"github.com/algorand/go-algorand/config"
25+
"github.com/algorand/go-algorand/data/basics"
26+
"github.com/algorand/go-algorand/protocol"
27+
"github.com/algorand/go-algorand/test/partitiontest"
28+
"github.com/stretchr/testify/require"
29+
)
30+
31+
func TestAxferWellFormedErrors(t *testing.T) {
32+
partitiontest.PartitionTest(t)
33+
t.Parallel()
34+
35+
cases := []struct {
36+
axfer AssetTransferTxnFields
37+
expectedError string
38+
}{
39+
{
40+
axfer: AssetTransferTxnFields{
41+
XferAsset: basics.AssetIndex(0),
42+
AssetAmount: 0,
43+
AssetReceiver: basics.Address{},
44+
},
45+
},
46+
{
47+
axfer: AssetTransferTxnFields{
48+
XferAsset: basics.AssetIndex(0),
49+
AssetAmount: 1,
50+
AssetReceiver: basics.Address{0x01},
51+
},
52+
expectedError: "asset ID cannot be zero",
53+
},
54+
{
55+
axfer: AssetTransferTxnFields{
56+
XferAsset: basics.AssetIndex(1),
57+
AssetAmount: 0,
58+
AssetSender: basics.Address{0x01},
59+
AssetCloseTo: basics.Address{0x02},
60+
},
61+
expectedError: "cannot close asset by clawback",
62+
},
63+
}
64+
65+
for i, ax := range cases {
66+
name := fmt.Sprintf("axfer_i=%d", i)
67+
if ax.expectedError != "" {
68+
name = ax.expectedError
69+
}
70+
t.Run(name, func(t *testing.T) {
71+
err := ax.axfer.wellFormed()
72+
if ax.expectedError != "" {
73+
require.ErrorContains(t, err, ax.expectedError)
74+
} else {
75+
require.NoError(t, err)
76+
}
77+
})
78+
}
79+
}
80+
81+
func TestAcfgWellFormedErrors(t *testing.T) {
82+
partitiontest.PartitionTest(t)
83+
t.Parallel()
84+
85+
cv18 := protocol.ConsensusV18
86+
cv20 := protocol.ConsensusV20
87+
cv28 := protocol.ConsensusV28
88+
89+
cases := []struct {
90+
acfg AssetConfigTxnFields
91+
cv protocol.ConsensusVersion
92+
expectedError string
93+
}{
94+
{
95+
acfg: AssetConfigTxnFields{
96+
AssetParams: basics.AssetParams{
97+
AssetName: strings.Repeat("A", 33),
98+
},
99+
},
100+
cv: cv18,
101+
expectedError: "transaction asset name too big: 33 > 32",
102+
},
103+
{
104+
acfg: AssetConfigTxnFields{
105+
AssetParams: basics.AssetParams{
106+
UnitName: strings.Repeat("B", 9),
107+
},
108+
},
109+
expectedError: "transaction asset unit name too big: 9 > 8",
110+
},
111+
{
112+
acfg: AssetConfigTxnFields{
113+
AssetParams: basics.AssetParams{
114+
URL: strings.Repeat("C", 33),
115+
},
116+
},
117+
cv: cv18,
118+
expectedError: "transaction asset url too big: 33 > 32",
119+
},
120+
{
121+
acfg: AssetConfigTxnFields{
122+
AssetParams: basics.AssetParams{
123+
Decimals: 20,
124+
},
125+
},
126+
cv: cv20,
127+
expectedError: "transaction asset decimals is too high (max is 19)",
128+
},
129+
{
130+
acfg: AssetConfigTxnFields{
131+
AssetParams: basics.AssetParams{
132+
URL: strings.Repeat("D", 97),
133+
},
134+
},
135+
cv: cv28,
136+
expectedError: "transaction asset url too big: 97 > 96",
137+
},
138+
}
139+
140+
for i, ac := range cases {
141+
name := fmt.Sprintf("acfg_i=%d", i)
142+
if ac.expectedError != "" {
143+
name = ac.expectedError
144+
}
145+
t.Run(name, func(t *testing.T) {
146+
cv := ac.cv
147+
if cv == "" {
148+
cv = protocol.ConsensusFuture
149+
}
150+
err := ac.acfg.wellFormed(config.Consensus[cv])
151+
if ac.expectedError != "" {
152+
require.ErrorContains(t, err, ac.expectedError)
153+
} else {
154+
require.NoError(t, err)
155+
}
156+
})
157+
}
158+
}
159+
160+
func TestAfrzWellFormedErrors(t *testing.T) {
161+
partitiontest.PartitionTest(t)
162+
t.Parallel()
163+
164+
cases := []struct {
165+
afrz AssetFreezeTxnFields
166+
expectedError string
167+
}{
168+
{
169+
afrz: AssetFreezeTxnFields{
170+
FreezeAccount: basics.Address{0x01},
171+
FreezeAsset: 0,
172+
},
173+
expectedError: "asset ID cannot be zero",
174+
},
175+
{
176+
afrz: AssetFreezeTxnFields{
177+
FreezeAccount: basics.Address{},
178+
FreezeAsset: 1,
179+
},
180+
expectedError: "freeze account cannot be empty",
181+
},
182+
}
183+
184+
for i, ac := range cases {
185+
name := fmt.Sprintf("afrz_i=%d", i)
186+
if ac.expectedError != "" {
187+
name = ac.expectedError
188+
}
189+
t.Run(name, func(t *testing.T) {
190+
err := ac.afrz.wellFormed()
191+
if ac.expectedError != "" {
192+
require.ErrorContains(t, err, ac.expectedError)
193+
} else {
194+
require.NoError(t, err)
195+
}
196+
})
197+
}
198+
}

test/scripts/e2e_subs/asset-misc.sh

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ ${gcmd} asset create --creator "${ACCOUNT}" --manager "${ACCOUNTB}" --reserve "$
106106
EXPERROR='account asset info not found'
107107
RES=$(${gcmd} asset info --creator $ACCOUNT --unitname dma 2>&1 || true)
108108
if [[ $RES != *"${EXPERROR}"* ]]; then
109-
date '+asset-misc FAIL asset info should fail unless reserve account was opted in %Y%m%d_%H%M%S'
109+
date "+${scriptname} FAIL asset info should fail unless reserve account was opted in %Y%m%d_%H%M%S"
110110
exit 1
111111
else
112112
echo ok
@@ -187,4 +187,28 @@ else
187187
exit 1
188188
fi
189189

190+
# Test Scenario - check transferring of the 0 asset
191+
# case 1: send 0 units of 0 asset to self should fail
192+
EXPERROR='asset 0 does not exist or has been deleted'
193+
RES=$(${gcmd} asset send --from "${ACCOUNT}" --to "${ACCOUNT}" --assetid 0 --amount 0 2>&1 || true)
194+
if [[ $RES != *"${EXPERROR}"* ]]; then
195+
date "+${scriptname} FAIL asset transfer of 0 units of 0 asset should not be allowed to self in %Y%m%d_%H%M%S"
196+
exit 1
197+
else
198+
echo ok
199+
fi
200+
201+
# case 2: send 0 units of 0 asset to someone else should succeed
202+
${gcmd} asset send --from "${ACCOUNT}" --to "${ACCOUNTB}" --assetid 0 --amount 0
203+
204+
# case 3: send 0 units of 0 asset to someone else including a close-to should fail
205+
EXPERROR='asset 0 not present in account'
206+
RES=$(${gcmd} asset send --from "${ACCOUNT}" --to "${ACCOUNTB}" --assetid 0 --amount 0 --close-to "${ACCOUNTB}" 2>&1 || true)
207+
if [[ $RES != *"${EXPERROR}"* ]]; then
208+
date "+${scriptname} FAIL asset transfer of 0 units of 0 asset including a close-to should not be allowed in %Y%m%d_%H%M%S"
209+
exit 1
210+
else
211+
echo ok
212+
fi
213+
190214
date "+$scriptname OK %Y%m%d_%H%M%S"

0 commit comments

Comments
 (0)