X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=protocol%2Fvalidation%2Fvalidation_test.go;h=182db3aff12ab306081e83ff1b8a0ca7f71aa7ed;hb=01180396e6e36d20c8a666286c985637e6186bfd;hp=4eb91cc40d060b1b2c8b8c78565ac93f09fb55d4;hpb=5314f3eba22336d2984cfedac9fc21778540ea13;p=bytom%2Fbytom.git diff --git a/protocol/validation/validation_test.go b/protocol/validation/validation_test.go index 4eb91cc4..182db3af 100644 --- a/protocol/validation/validation_test.go +++ b/protocol/validation/validation_test.go @@ -4,18 +4,18 @@ import ( "fmt" "math" "testing" - "time" + "github.com/davecgh/go-spew/spew" + "github.com/golang/protobuf/proto" + + "github.com/bytom/consensus" "github.com/bytom/crypto/sha3pool" "github.com/bytom/errors" "github.com/bytom/protocol/bc" - "github.com/bytom/protocol/bc/legacy" - "github.com/bytom/protocol/validation" + "github.com/bytom/protocol/bc/types" "github.com/bytom/protocol/vm" + "github.com/bytom/protocol/vm/vmutil" "github.com/bytom/testutil" - - "github.com/davecgh/go-spew/spew" - "github.com/golang/protobuf/proto" ) func init() { @@ -24,100 +24,100 @@ func init() { func TestGasStatus(t *testing.T) { cases := []struct { - input *gasState - output *gasState - f func(*gasState) error + input *GasState + output *GasState + f func(*GasState) error err error }{ { - input: &gasState{ - gasLeft: 10000, - gasUsed: 0, + input: &GasState{ + GasLeft: 10000, + GasUsed: 0, BTMValue: 0, }, - output: &gasState{ - gasLeft: 10000 / gasRate, - gasUsed: 0, + output: &GasState{ + GasLeft: 10000 / consensus.VMGasRate, + GasUsed: 0, BTMValue: 10000, }, - f: func(input *gasState) error { - return input.setGas(10000) + f: func(input *GasState) error { + return input.setGas(10000, 0) }, err: nil, }, { - input: &gasState{ - gasLeft: 10000, - gasUsed: 0, + input: &GasState{ + GasLeft: 10000, + GasUsed: 0, BTMValue: 0, }, - output: &gasState{ - gasLeft: 10000, - gasUsed: 0, + output: &GasState{ + GasLeft: 10000, + GasUsed: 0, BTMValue: 0, }, - f: func(input *gasState) error { - return input.setGas(-10000) + f: func(input *GasState) error { + return input.setGas(-10000, 0) }, err: errGasCalculate, }, { - input: &gasState{ - gasLeft: defaultGasLimit, - gasUsed: 0, + input: &GasState{ + GasLeft: consensus.DefaultGasCredit, + GasUsed: 0, BTMValue: 0, }, - output: &gasState{ - gasLeft: defaultGasLimit, - gasUsed: 0, + output: &GasState{ + GasLeft: 100000, + GasUsed: 0, BTMValue: 80000000000, }, - f: func(input *gasState) error { - return input.setGas(80000000000) + f: func(input *GasState) error { + return input.setGas(80000000000, 0) }, err: nil, }, { - input: &gasState{ - gasLeft: 10000, - gasUsed: 0, + input: &GasState{ + GasLeft: 10000, + GasUsed: 0, BTMValue: 0, }, - output: &gasState{ - gasLeft: 10000, - gasUsed: 0, + output: &GasState{ + GasLeft: 10000, + GasUsed: 0, BTMValue: 0, }, - f: func(input *gasState) error { + f: func(input *GasState) error { return input.updateUsage(-1) }, err: errGasCalculate, }, { - input: &gasState{ - gasLeft: 10000, - gasUsed: 0, + input: &GasState{ + GasLeft: 10000, + GasUsed: 0, BTMValue: 0, }, - output: &gasState{ - gasLeft: 9999, - gasUsed: 1, + output: &GasState{ + GasLeft: 9999, + GasUsed: 1, BTMValue: 0, }, - f: func(input *gasState) error { + f: func(input *GasState) error { return input.updateUsage(9999) }, err: nil, }, } - for _, c := range cases { + for i, c := range cases { err := c.f(c.input) - if err != c.err { - t.Errorf("got error %s, want %s", err, c.err) + if rootErr(err) != c.err { + t.Errorf("case %d: got error %s, want %s", i, err, c.err) } else if *c.input != *c.output { - t.Errorf("got gasStatus %s, want %s;", c.input, c.output) + t.Errorf("case %d: gasStatus %v, want %v;", i, c.input, c.output) } } } @@ -241,9 +241,8 @@ func TestTxValidation(t *testing.T) { // identical second transaction in order to get a similar but // not equal output entry for the mux to falsely point // to. That entry must be added to the first tx's Entries map. - fixture.txOutputs[0].ReferenceData = []byte{1} fixture2 := sample(t, fixture) - tx2 := legacy.NewTx(*fixture2.tx).Tx + tx2 := types.NewTx(*fixture2.tx).Tx out2ID := tx2.ResultIds[0] out2 := tx2.Entries[*out2ID].(*bc.Output) tx.Entries[*out2ID] = out2 @@ -378,14 +377,14 @@ func TestTxValidation(t *testing.T) { for _, c := range cases { t.Run(c.desc, func(t *testing.T) { fixture = sample(t, nil) - tx = legacy.NewTx(*fixture.tx).Tx + tx = types.NewTx(*fixture.tx).Tx vs = &validationState{ block: mockBlock(), tx: tx, entryID: tx.ID, - gas: &gasState{ - gasLeft: int64(80000), - gasUsed: 0, + gasStatus: &GasState{ + GasLeft: int64(80000), + GasUsed: 0, }, cache: make(map[bc.Hash]error), } @@ -413,43 +412,41 @@ func TestValidateBlock(t *testing.T) { { block: &bc.Block{ BlockHeader: &bc.BlockHeader{ - Height: 1, + Height: 0, + Bits: 2305843009230471167, + PreviousBlockId: &bc.Hash{}, }, - Transactions: []*bc.Tx{mockCoinbaseTx(624000000000)}, + Transactions: []*bc.Tx{mockCoinbaseTx(1470000000000000000)}, }, err: nil, }, { block: &bc.Block{ BlockHeader: &bc.BlockHeader{ - Height: 1, + Height: 0, + Bits: 2305843009230471167, + PreviousBlockId: &bc.Hash{}, }, Transactions: []*bc.Tx{mockCoinbaseTx(1)}, }, err: errWrongCoinbaseTransaction, }, - { - block: &bc.Block{ - BlockHeader: &bc.BlockHeader{ - Height: 1, - SerializedSize: 88888888, - }, - Transactions: []*bc.Tx{mockCoinbaseTx(1)}, - }, - err: errWrongBlockSize, - }, } + txStatus := bc.NewTransactionStatus() + txStatusHash := bc.EntryID(txStatus) + for _, c := range cases { txRoot, err := bc.MerkleRoot(c.block.Transactions) if err != nil { - t.Errorf("computing transaction merkle root", err) + t.Errorf("computing transaction merkle root error: %v", err) continue } + c.block.BlockHeader.TransactionStatus = bc.NewTransactionStatus() c.block.TransactionsRoot = &txRoot - err = ValidateBlock(c.block, nil) + c.block.TransactionStatusHash = &txStatusHash - if rootErr(err) != c.err { + if err = ValidateBlock(c.block, nil, &bc.Hash{}, nil); rootErr(err) != c.err { t.Errorf("got error %s, want %s", err, c.err) } } @@ -457,58 +454,86 @@ func TestValidateBlock(t *testing.T) { func TestCoinbase(t *testing.T) { CbTx := mockCoinbaseTx(5000000000) - errCbTx := legacy.MapTx(&legacy.TxData{ - Outputs: []*legacy.TxOutput{ - legacy.NewTxOutput(bc.AssetID{ - V0: uint64(18446744073709551611), - V1: uint64(18446744073709551615), - V2: uint64(18446744073709551615), - V3: uint64(18446744073709551615), - }, 800000000000, []byte{1}, nil), - }, - }) cases := []struct { - block *bc.Block - tx *bc.Tx - err error + block *bc.Block + tx *bc.Tx + GasVaild bool + err error }{ { block: &bc.Block{ BlockHeader: &bc.BlockHeader{ Height: 666, }, - Transactions: []*bc.Tx{errCbTx}, + Transactions: []*bc.Tx{CbTx}, }, - tx: CbTx, - err: errWrongCoinbaseTransaction, + tx: CbTx, + GasVaild: true, + err: nil, }, + } + + for i, c := range cases { + gasStatus, err := ValidateTx(c.tx, c.block) + + if rootErr(err) != c.err { + t.Errorf("#%d got error %s, want %s", i, err, c.err) + } + if c.GasVaild != gasStatus.GasVaild { + t.Errorf("#%d got GasVaild %t, want %t", i, gasStatus.GasVaild, c.GasVaild) + } + } +} + +func TestTimeRange(t *testing.T) { + cases := []struct { + timeRange uint64 + err bool + }{ { - block: &bc.Block{ - BlockHeader: &bc.BlockHeader{ - Height: 666, - }, - Transactions: []*bc.Tx{CbTx}, - }, - tx: CbTx, - err: nil, + timeRange: 0, + err: false, }, { - block: &bc.Block{ - BlockHeader: &bc.BlockHeader{ - Height: 666, - }, - Transactions: []*bc.Tx{errCbTx}, - }, - tx: errCbTx, - err: errWrongCoinbaseAsset, + timeRange: 334, + err: false, + }, + { + timeRange: 332, + err: true, + }, + { + timeRange: 1521625824, + err: false, + }, + { + timeRange: 1421625824, + err: true, }, } - for _, c := range cases { - _, err := ValidateTx(c.tx, c.block) + block := &bc.Block{ + BlockHeader: &bc.BlockHeader{ + Height: 333, + Timestamp: 1521625823, + }, + } - if rootErr(err) != c.err { - t.Errorf("got error %s, want %s", err, c.err) + tx := types.MapTx(&types.TxData{ + SerializedSize: 1, + TimeRange: 0, + Inputs: []*types.TxInput{ + mockGasTxInput(), + }, + Outputs: []*types.TxOutput{ + types.NewTxOutput(*consensus.BTMAssetID, 1, []byte{0x6a}), + }, + }) + + for i, c := range cases { + tx.TimeRange = c.timeRange + if _, err := ValidateTx(tx, block); (err != nil) != c.err { + t.Errorf("#%d got error %s, want %s", i, !c.err, c.err) } } } @@ -546,17 +571,16 @@ func TestBlockHeaderValid(t *testing.T) { // affect the transaction that's built. The components of the // transaction are the fields of txFixture. type txFixture struct { - initialBlockID bc.Hash - issuanceProg bc.Program - issuanceArgs [][]byte - assetDef []byte - assetID bc.AssetID - txVersion uint64 - txInputs []*legacy.TxInput - txOutputs []*legacy.TxOutput - txMinTime, txMaxTime uint64 - txRefData []byte - tx *legacy.TxData + initialBlockID bc.Hash + issuanceProg bc.Program + issuanceArgs [][]byte + assetDef []byte + assetID bc.AssetID + txVersion uint64 + txInputs []*types.TxInput + txOutputs []*types.TxOutput + txRefData []byte + tx *types.TxData } // Produces a sample transaction in a txFixture object (see above). A @@ -602,7 +626,7 @@ func sample(tb testing.TB, in *txFixture) *txFixture { } if result.assetID.IsZero() { refdatahash := hashData(result.assetDef) - result.assetID = bc.ComputeAssetID(result.issuanceProg.Code, &result.initialBlockID, result.issuanceProg.VmVersion, &refdatahash) + result.assetID = bc.ComputeAssetID(result.issuanceProg.Code, result.issuanceProg.VmVersion, &refdatahash) } if result.txVersion == 0 { @@ -621,10 +645,10 @@ func sample(tb testing.TB, in *txFixture) *txFixture { } args2 := [][]byte{[]byte{6}, []byte{7}} - result.txInputs = []*legacy.TxInput{ - legacy.NewIssuanceInput([]byte{3}, 10, []byte{4}, result.initialBlockID, result.issuanceProg.Code, result.issuanceArgs, result.assetDef), - legacy.NewSpendInput(args1, *newHash(5), result.assetID, 20, 0, cp1, *newHash(6), []byte{7}), - legacy.NewSpendInput(args2, *newHash(8), result.assetID, 40, 0, cp2, *newHash(9), []byte{10}), + result.txInputs = []*types.TxInput{ + types.NewIssuanceInput([]byte{3}, 10, result.issuanceProg.Code, result.issuanceArgs, result.assetDef), + types.NewSpendInput(args1, *newHash(5), result.assetID, 20, 0, cp1), + types.NewSpendInput(args2, *newHash(8), result.assetID, 40, 0, cp2), } } @@ -640,28 +664,19 @@ func sample(tb testing.TB, in *txFixture) *txFixture { tb.Fatal(err) } - result.txOutputs = []*legacy.TxOutput{ - legacy.NewTxOutput(result.assetID, 25, cp1, []byte{11}), - legacy.NewTxOutput(result.assetID, 45, cp2, []byte{12}), + result.txOutputs = []*types.TxOutput{ + types.NewTxOutput(result.assetID, 25, cp1), + types.NewTxOutput(result.assetID, 45, cp2), } } - if result.txMinTime == 0 { - result.txMinTime = bc.Millis(time.Now().Add(-time.Minute)) - } - if result.txMaxTime == 0 { - result.txMaxTime = bc.Millis(time.Now().Add(time.Minute)) - } if len(result.txRefData) == 0 { result.txRefData = []byte{13} } - result.tx = &legacy.TxData{ - Version: result.txVersion, - Inputs: result.txInputs, - Outputs: result.txOutputs, - MinTime: result.txMinTime, - MaxTime: result.txMaxTime, - ReferenceData: result.txRefData, + result.tx = &types.TxData{ + Version: result.txVersion, + Inputs: result.txInputs, + Outputs: result.txOutputs, } return &result @@ -676,15 +691,21 @@ func mockBlock() *bc.Block { } func mockCoinbaseTx(amount uint64) *bc.Tx { - return legacy.MapTx(&legacy.TxData{ - Outputs: []*legacy.TxOutput{ - legacy.NewTxOutput(*BTMAssetID, amount, []byte{1}, nil), + cp, _ := vmutil.DefaultCoinbaseProgram() + return types.MapTx(&types.TxData{ + SerializedSize: 1, + Inputs: []*types.TxInput{ + types.NewCoinbaseInput(nil), + }, + Outputs: []*types.TxOutput{ + types.NewTxOutput(*consensus.BTMAssetID, amount, cp), }, }) } -func mockGasTxInput() *legacy.TxInput { - return legacy.NewSpendInput([][]byte{}, *newHash(8), *validation.BTMAssetID, 100000000, 0, []byte{byte(vm.OP_TRUE)}, *newHash(9), []byte{}) +func mockGasTxInput() *types.TxInput { + cp, _ := vmutil.DefaultCoinbaseProgram() + return types.NewSpendInput([][]byte{}, *newHash(8), *consensus.BTMAssetID, 100000000, 0, cp) } // Like errors.Root, but also unwraps vm.Error objects.