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 }