github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/sdk/bank/keeper_test.go (about)

     1  package bank
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/require"
     7  
     8  	"github.com/gnolang/gno/tm2/pkg/crypto"
     9  	"github.com/gnolang/gno/tm2/pkg/sdk"
    10  	"github.com/gnolang/gno/tm2/pkg/std"
    11  )
    12  
    13  func TestKeeper(t *testing.T) {
    14  	t.Parallel()
    15  
    16  	env := setupTestEnv()
    17  	ctx := env.ctx
    18  
    19  	addr := crypto.AddressFromPreimage([]byte("addr1"))
    20  	addr2 := crypto.AddressFromPreimage([]byte("addr2"))
    21  	addr3 := crypto.AddressFromPreimage([]byte("addr3"))
    22  	acc := env.acck.NewAccountWithAddress(ctx, addr)
    23  
    24  	// Test GetCoins/SetCoins
    25  	env.acck.SetAccount(ctx, acc)
    26  	require.True(t, env.bank.GetCoins(ctx, addr).IsEqual(std.NewCoins()))
    27  
    28  	env.bank.SetCoins(ctx, addr, std.NewCoins(std.NewCoin("foocoin", 10)))
    29  	require.True(t, env.bank.GetCoins(ctx, addr).IsEqual(std.NewCoins(std.NewCoin("foocoin", 10))))
    30  
    31  	// Test HasCoins
    32  	require.True(t, env.bank.HasCoins(ctx, addr, std.NewCoins(std.NewCoin("foocoin", 10))))
    33  	require.True(t, env.bank.HasCoins(ctx, addr, std.NewCoins(std.NewCoin("foocoin", 5))))
    34  	require.False(t, env.bank.HasCoins(ctx, addr, std.NewCoins(std.NewCoin("foocoin", 15))))
    35  	require.False(t, env.bank.HasCoins(ctx, addr, std.NewCoins(std.NewCoin("barcoin", 5))))
    36  
    37  	// Test AddCoins
    38  	env.bank.AddCoins(ctx, addr, std.NewCoins(std.NewCoin("foocoin", 15)))
    39  	require.True(t, env.bank.GetCoins(ctx, addr).IsEqual(std.NewCoins(std.NewCoin("foocoin", 25))))
    40  
    41  	env.bank.AddCoins(ctx, addr, std.NewCoins(std.NewCoin("barcoin", 15)))
    42  	require.True(t, env.bank.GetCoins(ctx, addr).IsEqual(std.NewCoins(std.NewCoin("barcoin", 15), std.NewCoin("foocoin", 25))))
    43  
    44  	// Test SubtractCoins
    45  	env.bank.SubtractCoins(ctx, addr, std.NewCoins(std.NewCoin("foocoin", 10)))
    46  	env.bank.SubtractCoins(ctx, addr, std.NewCoins(std.NewCoin("barcoin", 5)))
    47  	require.True(t, env.bank.GetCoins(ctx, addr).IsEqual(std.NewCoins(std.NewCoin("barcoin", 10), std.NewCoin("foocoin", 15))))
    48  
    49  	env.bank.SubtractCoins(ctx, addr, std.NewCoins(std.NewCoin("barcoin", 11)))
    50  	require.True(t, env.bank.GetCoins(ctx, addr).IsEqual(std.NewCoins(std.NewCoin("barcoin", 10), std.NewCoin("foocoin", 15))))
    51  
    52  	env.bank.SubtractCoins(ctx, addr, std.NewCoins(std.NewCoin("barcoin", 10)))
    53  	require.True(t, env.bank.GetCoins(ctx, addr).IsEqual(std.NewCoins(std.NewCoin("foocoin", 15))))
    54  	require.False(t, env.bank.HasCoins(ctx, addr, std.NewCoins(std.NewCoin("barcoin", 1))))
    55  
    56  	// Test SendCoins
    57  	env.bank.SendCoins(ctx, addr, addr2, std.NewCoins(std.NewCoin("foocoin", 5)))
    58  	require.True(t, env.bank.GetCoins(ctx, addr).IsEqual(std.NewCoins(std.NewCoin("foocoin", 10))))
    59  	require.True(t, env.bank.GetCoins(ctx, addr2).IsEqual(std.NewCoins(std.NewCoin("foocoin", 5))))
    60  
    61  	_ = env.bank.SendCoins(ctx, addr, addr2, std.NewCoins(std.NewCoin("foocoin", 50)))
    62  	require.True(t, env.bank.GetCoins(ctx, addr).IsEqual(std.NewCoins(std.NewCoin("foocoin", 10))))
    63  	require.True(t, env.bank.GetCoins(ctx, addr2).IsEqual(std.NewCoins(std.NewCoin("foocoin", 5))))
    64  
    65  	env.bank.AddCoins(ctx, addr, std.NewCoins(std.NewCoin("barcoin", 30)))
    66  	env.bank.SendCoins(ctx, addr, addr2, std.NewCoins(std.NewCoin("barcoin", 10), std.NewCoin("foocoin", 5)))
    67  	require.True(t, env.bank.GetCoins(ctx, addr).IsEqual(std.NewCoins(std.NewCoin("barcoin", 20), std.NewCoin("foocoin", 5))))
    68  	require.True(t, env.bank.GetCoins(ctx, addr2).IsEqual(std.NewCoins(std.NewCoin("barcoin", 10), std.NewCoin("foocoin", 10))))
    69  
    70  	// Test InputOutputCoins
    71  	input1 := NewInput(addr2, std.NewCoins(std.NewCoin("foocoin", 2)))
    72  	output1 := NewOutput(addr, std.NewCoins(std.NewCoin("foocoin", 2)))
    73  	env.bank.InputOutputCoins(ctx, []Input{input1}, []Output{output1})
    74  	require.True(t, env.bank.GetCoins(ctx, addr).IsEqual(std.NewCoins(std.NewCoin("barcoin", 20), std.NewCoin("foocoin", 7))))
    75  	require.True(t, env.bank.GetCoins(ctx, addr2).IsEqual(std.NewCoins(std.NewCoin("barcoin", 10), std.NewCoin("foocoin", 8))))
    76  
    77  	inputs := []Input{
    78  		NewInput(addr, std.NewCoins(std.NewCoin("foocoin", 3))),
    79  		NewInput(addr2, std.NewCoins(std.NewCoin("barcoin", 3), std.NewCoin("foocoin", 2))),
    80  	}
    81  
    82  	outputs := []Output{
    83  		NewOutput(addr, std.NewCoins(std.NewCoin("barcoin", 1))),
    84  		NewOutput(addr3, std.NewCoins(std.NewCoin("barcoin", 2), std.NewCoin("foocoin", 5))),
    85  	}
    86  	env.bank.InputOutputCoins(ctx, inputs, outputs)
    87  	require.True(t, env.bank.GetCoins(ctx, addr).IsEqual(std.NewCoins(std.NewCoin("barcoin", 21), std.NewCoin("foocoin", 4))))
    88  	require.True(t, env.bank.GetCoins(ctx, addr2).IsEqual(std.NewCoins(std.NewCoin("barcoin", 7), std.NewCoin("foocoin", 6))))
    89  	require.True(t, env.bank.GetCoins(ctx, addr3).IsEqual(std.NewCoins(std.NewCoin("barcoin", 2), std.NewCoin("foocoin", 5))))
    90  }
    91  
    92  func TestBankKeeper(t *testing.T) {
    93  	t.Parallel()
    94  
    95  	env := setupTestEnv()
    96  	ctx := env.ctx
    97  
    98  	bank := NewBankKeeper(env.acck)
    99  
   100  	addr := crypto.AddressFromPreimage([]byte("addr1"))
   101  	addr2 := crypto.AddressFromPreimage([]byte("addr2"))
   102  	acc := env.acck.NewAccountWithAddress(ctx, addr)
   103  
   104  	// Test GetCoins/SetCoins
   105  	env.acck.SetAccount(ctx, acc)
   106  	require.True(t, bank.GetCoins(ctx, addr).IsEqual(std.NewCoins()))
   107  
   108  	env.bank.SetCoins(ctx, addr, std.NewCoins(std.NewCoin("foocoin", 10)))
   109  	require.True(t, bank.GetCoins(ctx, addr).IsEqual(std.NewCoins(std.NewCoin("foocoin", 10))))
   110  
   111  	// Test HasCoins
   112  	require.True(t, bank.HasCoins(ctx, addr, std.NewCoins(std.NewCoin("foocoin", 10))))
   113  	require.True(t, bank.HasCoins(ctx, addr, std.NewCoins(std.NewCoin("foocoin", 5))))
   114  	require.False(t, bank.HasCoins(ctx, addr, std.NewCoins(std.NewCoin("foocoin", 15))))
   115  	require.False(t, bank.HasCoins(ctx, addr, std.NewCoins(std.NewCoin("barcoin", 5))))
   116  
   117  	env.bank.SetCoins(ctx, addr, std.NewCoins(std.NewCoin("foocoin", 15)))
   118  
   119  	// Test SendCoins
   120  	bank.SendCoins(ctx, addr, addr2, std.NewCoins(std.NewCoin("foocoin", 5)))
   121  	require.True(t, bank.GetCoins(ctx, addr).IsEqual(std.NewCoins(std.NewCoin("foocoin", 10))))
   122  	require.True(t, bank.GetCoins(ctx, addr2).IsEqual(std.NewCoins(std.NewCoin("foocoin", 5))))
   123  
   124  	err := bank.SendCoins(ctx, addr, addr2, std.NewCoins(std.NewCoin("foocoin", 50)))
   125  	require.True(t, bank.GetCoins(ctx, addr).IsEqual(std.NewCoins(std.NewCoin("foocoin", 10))))
   126  	require.True(t, bank.GetCoins(ctx, addr2).IsEqual(std.NewCoins(std.NewCoin("foocoin", 5))))
   127  
   128  	env.bank.AddCoins(ctx, addr, std.NewCoins(std.NewCoin("barcoin", 30)))
   129  	bank.SendCoins(ctx, addr, addr2, std.NewCoins(std.NewCoin("barcoin", 10), std.NewCoin("foocoin", 5)))
   130  	require.True(t, bank.GetCoins(ctx, addr).IsEqual(std.NewCoins(std.NewCoin("barcoin", 20), std.NewCoin("foocoin", 5))))
   131  	require.True(t, bank.GetCoins(ctx, addr2).IsEqual(std.NewCoins(std.NewCoin("barcoin", 10), std.NewCoin("foocoin", 10))))
   132  
   133  	// validate coins with invalid denoms or negative values cannot be sent
   134  	// NOTE: We must use the Coin literal as the constructor does not allow
   135  	// negative values.
   136  	err = bank.SendCoins(ctx, addr, addr2, sdk.Coins{sdk.Coin{"FOOCOIN", -5}})
   137  	require.Error(t, err)
   138  }
   139  
   140  func TestViewKeeper(t *testing.T) {
   141  	t.Parallel()
   142  
   143  	env := setupTestEnv()
   144  	ctx := env.ctx
   145  	view := NewViewKeeper(env.acck)
   146  
   147  	addr := crypto.AddressFromPreimage([]byte("addr1"))
   148  	acc := env.acck.NewAccountWithAddress(ctx, addr)
   149  
   150  	// Test GetCoins/SetCoins
   151  	env.acck.SetAccount(ctx, acc)
   152  	require.True(t, view.GetCoins(ctx, addr).IsEqual(std.NewCoins()))
   153  
   154  	env.bank.SetCoins(ctx, addr, std.NewCoins(std.NewCoin("foocoin", 10)))
   155  	require.True(t, view.GetCoins(ctx, addr).IsEqual(std.NewCoins(std.NewCoin("foocoin", 10))))
   156  
   157  	// Test HasCoins
   158  	require.True(t, view.HasCoins(ctx, addr, std.NewCoins(std.NewCoin("foocoin", 10))))
   159  	require.True(t, view.HasCoins(ctx, addr, std.NewCoins(std.NewCoin("foocoin", 5))))
   160  	require.False(t, view.HasCoins(ctx, addr, std.NewCoins(std.NewCoin("foocoin", 15))))
   161  	require.False(t, view.HasCoins(ctx, addr, std.NewCoins(std.NewCoin("barcoin", 5))))
   162  }