From 27a31953f9bb0c0c58b6a40399b25de43a403d2e Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Fri, 30 Jun 2017 20:00:27 +0200 Subject: [PATCH] Now solid validation tests for coin --- modules/coin/tx.go | 4 +- modules/coin/tx_test.go | 88 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 2 deletions(-) diff --git a/modules/coin/tx.go b/modules/coin/tx.go index 7f5be71654..6e7116ec0a 100644 --- a/modules/coin/tx.go +++ b/modules/coin/tx.go @@ -110,13 +110,13 @@ func (tx SendTx) ValidateBasic() error { if err := in.ValidateBasic(); err != nil { return err } - totalIn.Plus(in.Coins) + totalIn = totalIn.Plus(in.Coins) } for _, out := range tx.Outputs { if err := out.ValidateBasic(); err != nil { return err } - totalOut.Plus(out.Coins) + totalOut = totalOut.Plus(out.Coins) } // make sure inputs and outputs match if !totalIn.IsEqual(totalOut) { diff --git a/modules/coin/tx_test.go b/modules/coin/tx_test.go index 69780eecf2..0e1b85b908 100644 --- a/modules/coin/tx_test.go +++ b/modules/coin/tx_test.go @@ -83,3 +83,91 @@ func TestTxValidateOutput(t *testing.T) { } } } + +func TestTxValidateTx(t *testing.T) { + assert := assert.New(t) + + addr1 := basecoin.Actor{App: "coin", Address: []byte{1, 2}} + addr2 := basecoin.Actor{App: "coin", Address: []byte{3, 4}, ChainID: "over-there"} + addr3 := basecoin.Actor{App: "role", Address: []byte{7, 8}} + noAddr := basecoin.Actor{} + + noCoins := types.Coins{} + someCoins := types.Coins{{"atom", 123}} + moreCoins := types.Coins{{"atom", 124}} + otherCoins := types.Coins{{"btc", 15}} + bothCoins := someCoins.Plus(otherCoins) + minusCoins := types.Coins{{"eth", -34}} + + // cases: all valid (one), all valid (multi) + // no input, no outputs, invalid inputs, invalid outputs + // totals don't match + cases := []struct { + valid bool + tx SendTx + }{ + // 0-2. valid cases + {true, SendTx{ + Inputs: []TxInput{NewTxInput(addr1, someCoins, 2)}, + Outputs: []TxOutput{NewTxOutput(addr2, someCoins)}, + }}, + {true, SendTx{ + Inputs: []TxInput{NewTxInput(addr1, someCoins, 2), NewTxInput(addr2, otherCoins, 5)}, + Outputs: []TxOutput{NewTxOutput(addr3, bothCoins)}, + }}, + {true, SendTx{ + Inputs: []TxInput{NewTxInput(addr1, bothCoins, 42)}, + Outputs: []TxOutput{NewTxOutput(addr2, someCoins), NewTxOutput(addr3, otherCoins)}, + }}, + + // 3-4. missing cases + {false, SendTx{ + Outputs: []TxOutput{NewTxOutput(addr2, someCoins)}, + }}, + {false, SendTx{ + Inputs: []TxInput{NewTxInput(addr1, someCoins, 2)}, + }}, + + // 5-8. invalid inputs + {false, SendTx{ + Inputs: []TxInput{NewTxInput(noAddr, someCoins, 2)}, + Outputs: []TxOutput{NewTxOutput(addr2, someCoins)}, + }}, + {false, SendTx{ + Inputs: []TxInput{NewTxInput(addr1, someCoins, -1)}, + Outputs: []TxOutput{NewTxOutput(addr2, someCoins)}, + }}, + {false, SendTx{ + Inputs: []TxInput{NewTxInput(addr1, noCoins, 2)}, + Outputs: []TxOutput{NewTxOutput(addr2, noCoins)}, + }}, + {false, SendTx{ + Inputs: []TxInput{NewTxInput(addr1, minusCoins, 2)}, + Outputs: []TxOutput{NewTxOutput(addr2, minusCoins)}, + }}, + + // 9-11. totals don't match + {false, SendTx{ + Inputs: []TxInput{NewTxInput(addr1, someCoins, 7)}, + Outputs: []TxOutput{NewTxOutput(addr2, moreCoins)}, + }}, + {false, SendTx{ + Inputs: []TxInput{NewTxInput(addr1, someCoins, 2), NewTxInput(addr2, minusCoins, 5)}, + Outputs: []TxOutput{NewTxOutput(addr3, someCoins)}, + }}, + {false, SendTx{ + Inputs: []TxInput{NewTxInput(addr1, someCoins, 2), NewTxInput(addr2, moreCoins, 5)}, + Outputs: []TxOutput{NewTxOutput(addr3, bothCoins)}, + }}, + } + + for i, tc := range cases { + err := tc.tx.ValidateBasic() + if tc.valid { + assert.Nil(err, "%d: %+v", i, err) + } else { + assert.NotNil(err, "%d", i) + } + } + +}