Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 198 additions & 0 deletions data/transactions/asset_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
// Copyright (C) 2019-2025 Algorand, Inc.
// This file is part of go-algorand
//
// go-algorand is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// go-algorand is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with go-algorand. If not, see <https://www.gnu.org/licenses/>.

package transactions

import (
"fmt"
"strings"
"testing"

"github.com/algorand/go-algorand/config"
"github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/protocol"
"github.com/algorand/go-algorand/test/partitiontest"
"github.com/stretchr/testify/require"
)

func TestAxferWellFormedErrors(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()

cases := []struct {
axfer AssetTransferTxnFields
expectedError string
}{
{
axfer: AssetTransferTxnFields{
XferAsset: basics.AssetIndex(0),
AssetAmount: 0,
AssetReceiver: basics.Address{},
},
},
{
axfer: AssetTransferTxnFields{
XferAsset: basics.AssetIndex(0),
AssetAmount: 1,
AssetReceiver: basics.Address{0x01},
},
expectedError: "asset ID cannot be zero",
},
{
axfer: AssetTransferTxnFields{
XferAsset: basics.AssetIndex(1),
AssetAmount: 0,
AssetSender: basics.Address{0x01},
AssetCloseTo: basics.Address{0x02},
},
expectedError: "cannot close asset by clawback",
},
}

for i, ax := range cases {
name := fmt.Sprintf("axfer_i=%d", i)
if ax.expectedError != "" {
name = ax.expectedError
}
t.Run(name, func(t *testing.T) {
err := ax.axfer.wellFormed()
if ax.expectedError != "" {
require.ErrorContains(t, err, ax.expectedError)
} else {
require.NoError(t, err)
}
})
}
}

func TestAcfgWellFormedErrors(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()

cv18 := protocol.ConsensusV18
cv20 := protocol.ConsensusV20
cv28 := protocol.ConsensusV28

cases := []struct {
acfg AssetConfigTxnFields
cv protocol.ConsensusVersion
expectedError string
}{
{
acfg: AssetConfigTxnFields{
AssetParams: basics.AssetParams{
AssetName: strings.Repeat("A", 33),
},
},
cv: cv18,
expectedError: "transaction asset name too big: 33 > 32",
},
{
acfg: AssetConfigTxnFields{
AssetParams: basics.AssetParams{
UnitName: strings.Repeat("B", 9),
},
},
expectedError: "transaction asset unit name too big: 9 > 8",
},
{
acfg: AssetConfigTxnFields{
AssetParams: basics.AssetParams{
URL: strings.Repeat("C", 33),
},
},
cv: cv18,
expectedError: "transaction asset url too big: 33 > 32",
},
{
acfg: AssetConfigTxnFields{
AssetParams: basics.AssetParams{
Decimals: 20,
},
},
cv: cv20,
expectedError: "transaction asset decimals is too high (max is 19)",
},
{
acfg: AssetConfigTxnFields{
AssetParams: basics.AssetParams{
URL: strings.Repeat("D", 97),
},
},
cv: cv28,
expectedError: "transaction asset url too big: 97 > 96",
},
}

for i, ac := range cases {
name := fmt.Sprintf("acfg_i=%d", i)
if ac.expectedError != "" {
name = ac.expectedError
}
t.Run(name, func(t *testing.T) {
cv := ac.cv
if cv == "" {
cv = protocol.ConsensusFuture
}
err := ac.acfg.wellFormed(config.Consensus[cv])
if ac.expectedError != "" {
require.ErrorContains(t, err, ac.expectedError)
} else {
require.NoError(t, err)
}
})
}
}

func TestAfrzWellFormedErrors(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()

cases := []struct {
afrz AssetFreezeTxnFields
expectedError string
}{
{
afrz: AssetFreezeTxnFields{
FreezeAccount: basics.Address{0x01},
FreezeAsset: 0,
},
expectedError: "asset ID cannot be zero",
},
{
afrz: AssetFreezeTxnFields{
FreezeAccount: basics.Address{},
FreezeAsset: 1,
},
expectedError: "freeze account cannot be empty",
},
}

for i, ac := range cases {
name := fmt.Sprintf("afrz_i=%d", i)
if ac.expectedError != "" {
name = ac.expectedError
}
t.Run(name, func(t *testing.T) {
err := ac.afrz.wellFormed()
if ac.expectedError != "" {
require.ErrorContains(t, err, ac.expectedError)
} else {
require.NoError(t, err)
}
})
}
}
26 changes: 25 additions & 1 deletion test/scripts/e2e_subs/asset-misc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ ${gcmd} asset create --creator "${ACCOUNT}" --manager "${ACCOUNTB}" --reserve "$
EXPERROR='account asset info not found'
RES=$(${gcmd} asset info --creator $ACCOUNT --unitname dma 2>&1 || true)
if [[ $RES != *"${EXPERROR}"* ]]; then
date '+asset-misc FAIL asset info should fail unless reserve account was opted in %Y%m%d_%H%M%S'
date "+${scriptname} FAIL asset info should fail unless reserve account was opted in %Y%m%d_%H%M%S"
exit 1
else
echo ok
Expand Down Expand Up @@ -187,4 +187,28 @@ else
exit 1
fi

# Test Scenario - check transferring of the 0 asset
# case 1: send 0 units of 0 asset to self should fail
EXPERROR='asset 0 does not exist or has been deleted'
RES=$(${gcmd} asset send --from "${ACCOUNT}" --to "${ACCOUNT}" --assetid 0 --amount 0 2>&1 || true)
if [[ $RES != *"${EXPERROR}"* ]]; then
date "+${scriptname} FAIL asset transfer of 0 units of 0 asset should not be allowed to self in %Y%m%d_%H%M%S"
exit 1
else
echo ok
fi

# case 2: send 0 units of 0 asset to someone else should succeed
${gcmd} asset send --from "${ACCOUNT}" --to "${ACCOUNTB}" --assetid 0 --amount 0

# case 3: send 0 units of 0 asset to someone else including a close-to should fail
EXPERROR='asset 0 not present in account'
RES=$(${gcmd} asset send --from "${ACCOUNT}" --to "${ACCOUNTB}" --assetid 0 --amount 0 --close-to "${ACCOUNTB}" 2>&1 || true)
if [[ $RES != *"${EXPERROR}"* ]]; then
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"
exit 1
else
echo ok
fi

date "+$scriptname OK %Y%m%d_%H%M%S"