import (
"encoding/hex"
- "math"
- "reflect"
"testing"
- "github.com/davecgh/go-spew/spew"
-
"github.com/vapor/consensus"
- "github.com/vapor/crypto/ed25519/chainkd"
"github.com/vapor/errors"
"github.com/vapor/math/checked"
"github.com/vapor/protocol/bc"
"github.com/vapor/testutil"
)
-func TestApplyTransaction(t *testing.T) {
- testXpub, _ := hex.DecodeString("a8018a1ba4d85fc7118bbd065612da78b2c503e61a1a093d9c659567c5d3a591b3752569fbcafa951b2304b8f576f3f220e03b957ca819840e7c29e4b7fb2c4d")
-
- cases := []struct {
- desc string
- tx *types.Tx
- prevConsensusResult *ConsensusResult
- postConsensusResult *ConsensusResult
- wantErr error
- }{
- {
- desc: "test num Of vote overflow",
- tx: &types.Tx{
- TxData: types.TxData{
- Inputs: []*types.TxInput{types.NewSpendInput(nil, bc.NewHash([32]byte{0xff}), *consensus.BTMAssetID, 600000000, 0, nil)},
- Outputs: []*types.TxOutput{types.NewVoteOutput(*consensus.BTMAssetID, math.MaxUint64-1000, []byte{0x51}, testXpub)},
- },
- },
- prevConsensusResult: &ConsensusResult{
- NumOfVote: map[string]uint64{
- hex.EncodeToString(testXpub): 1000000,
- },
- },
- postConsensusResult: &ConsensusResult{
- NumOfVote: map[string]uint64{},
- },
- wantErr: checked.ErrOverflow,
- },
- {
- desc: "test num Of veto overflow",
- tx: &types.Tx{
- TxData: types.TxData{
- Inputs: []*types.TxInput{types.NewVetoInput(nil, bc.NewHash([32]byte{0xff}), *consensus.BTMAssetID, 100000000, 0, []byte{0x51}, testXpub)},
- Outputs: []*types.TxOutput{types.NewIntraChainOutput(*consensus.BTMAssetID, 100000000, []byte{0x51})},
- },
- },
- prevConsensusResult: &ConsensusResult{
- NumOfVote: map[string]uint64{
- hex.EncodeToString(testXpub): 1000000,
- },
- },
- postConsensusResult: &ConsensusResult{
- NumOfVote: map[string]uint64{},
- },
- wantErr: checked.ErrOverflow,
- },
- {
- desc: "test del pubkey from NumOfVote",
- tx: &types.Tx{
- TxData: types.TxData{
- Inputs: []*types.TxInput{types.NewVetoInput(nil, bc.NewHash([32]byte{0xff}), *consensus.BTMAssetID, 1000000, 0, []byte{0x51}, testXpub)},
- Outputs: []*types.TxOutput{types.NewIntraChainOutput(*consensus.BTMAssetID, 100000000, []byte{0x51})},
- },
- },
- prevConsensusResult: &ConsensusResult{
- NumOfVote: map[string]uint64{
- hex.EncodeToString(testXpub): 1000000,
- },
- },
- postConsensusResult: &ConsensusResult{
- NumOfVote: map[string]uint64{},
- },
- wantErr: nil,
- },
- }
-
- for i, c := range cases {
- if err := c.prevConsensusResult.ApplyTransaction(c.tx); err != nil {
- if err != c.wantErr {
- t.Errorf("test case #%d want err = %v, got err = %v", i, c.wantErr, err)
- }
- continue
- }
-
- if !testutil.DeepEqual(c.prevConsensusResult, c.postConsensusResult) {
- t.Errorf("test case #%d, want %v, got %v", i, c.postConsensusResult, c.prevConsensusResult)
- }
- }
-}
-
-func TestAttachCoinbaseReward(t *testing.T) {
- cases := []struct {
- desc string
- block *types.Block
- prevConsensusResult *ConsensusResult
- postConsensusResult *ConsensusResult
- wantErr error
- }{
- {
- desc: "normal test with block contain coinbase tx and other tx",
- block: &types.Block{
- BlockHeader: types.BlockHeader{
- Height: 1,
- },
- Transactions: []*types.Tx{
- {
- TxData: types.TxData{
- Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
- Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51})},
- },
- },
- {
- TxData: types.TxData{
- Inputs: []*types.TxInput{types.NewSpendInput(nil, bc.NewHash([32]byte{0xff}), *consensus.BTMAssetID, 300000000, 0, nil)},
- Outputs: []*types.TxOutput{types.NewIntraChainOutput(*consensus.BTMAssetID, 250000000, []byte{0x51})},
- },
- },
- },
- },
- prevConsensusResult: &ConsensusResult{
- CoinbaseReward: map[string]uint64{
- hex.EncodeToString([]byte{0x51}): 50000000,
- hex.EncodeToString([]byte{0x52}): 80000000,
- },
- },
- postConsensusResult: &ConsensusResult{
- CoinbaseReward: map[string]uint64{
- hex.EncodeToString([]byte{0x51}): consensus.BlockSubsidy(1) + 50000000,
- },
- },
- wantErr: nil,
- },
- {
- desc: "test cal coinbase reward overflow",
- block: &types.Block{
- BlockHeader: types.BlockHeader{
- Height: 100,
- },
- Transactions: []*types.Tx{
- {
- TxData: types.TxData{
- Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
- Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51})},
- },
- },
- {
- TxData: types.TxData{
- Inputs: []*types.TxInput{types.NewSpendInput(nil, bc.NewHash([32]byte{0xff}), *consensus.BTMAssetID, math.MaxUint64, 0, nil)},
- Outputs: []*types.TxOutput{types.NewIntraChainOutput(*consensus.BTMAssetID, 0, []byte{0x52})},
- },
- },
- },
- },
- prevConsensusResult: &ConsensusResult{
- CoinbaseReward: map[string]uint64{
- hex.EncodeToString([]byte{0x51}): 50000000,
- hex.EncodeToString([]byte{0x52}): 80000000,
- },
- },
- postConsensusResult: &ConsensusResult{
- CoinbaseReward: map[string]uint64{
- hex.EncodeToString([]byte{0x51}): consensus.BlockSubsidy(1) + 50000000,
- },
- },
- wantErr: checked.ErrOverflow,
- },
- {
- desc: "test coinbase reward overflow",
- block: &types.Block{
- BlockHeader: types.BlockHeader{
- Height: 100,
- },
- Transactions: []*types.Tx{
- {
- TxData: types.TxData{
- Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
- Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51})},
- },
- },
- {
- TxData: types.TxData{
- Inputs: []*types.TxInput{types.NewSpendInput(nil, bc.NewHash([32]byte{0xff}), *consensus.BTMAssetID, math.MaxUint64-80000000, 0, nil)},
- Outputs: []*types.TxOutput{types.NewIntraChainOutput(*consensus.BTMAssetID, 0, []byte{0x52})},
- },
- },
- },
- },
- prevConsensusResult: &ConsensusResult{
- CoinbaseReward: map[string]uint64{
- hex.EncodeToString([]byte{0x51}): 80000000,
- hex.EncodeToString([]byte{0x52}): 50000000,
- },
- },
- postConsensusResult: &ConsensusResult{
- CoinbaseReward: map[string]uint64{
- hex.EncodeToString([]byte{0x51}): consensus.BlockSubsidy(1) + 50000000,
- },
- },
- wantErr: checked.ErrOverflow,
- },
- }
-
- for i, c := range cases {
- if err := c.prevConsensusResult.AttachCoinbaseReward(c.block); err != nil {
- if err != c.wantErr {
- t.Errorf("test case #%d want err = %v, got err = %v", i, c.wantErr, err)
- }
- continue
- }
-
- if !testutil.DeepEqual(c.prevConsensusResult, c.postConsensusResult) {
- t.Errorf("test case #%d, want %v, got %v", i, c.postConsensusResult, c.prevConsensusResult)
- }
- }
-}
-
func TestCalCoinbaseReward(t *testing.T) {
cases := []struct {
desc string
},
wantErr: errors.New("not found coinbase receiver"),
},
- {
- desc: "test number of vote overflow",
- block: &types.Block{
- BlockHeader: types.BlockHeader{
- Height: consensus.MainNetParams.RoundVoteBlockNums - 1,
- PreviousBlockHash: bc.Hash{V0: 1},
- },
- Transactions: []*types.Tx{
- &types.Tx{
- TxData: types.TxData{
- Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
- Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51})},
- },
- },
- &types.Tx{
- TxData: types.TxData{
- Inputs: []*types.TxInput{types.NewSpendInput(nil, bc.NewHash([32]byte{0xff}), *consensus.BTMAssetID, 600000000, 0, nil)},
- Outputs: []*types.TxOutput{types.NewVoteOutput(*consensus.BTMAssetID, 600000000, []byte{0x51}, testXpub)},
- },
- },
- },
- },
- consensusResult: &ConsensusResult{
- BlockHash: testutil.MustDecodeHash("4ebd9e7c00d3e0370931689c6eb9e2131c6700fe66e6b9718028dd75d7a4e329"),
- CoinbaseReward: map[string]uint64{
- "51": 100000000,
- },
- NumOfVote: map[string]uint64{},
- },
- wantErr: checked.ErrOverflow,
- },
- {
- desc: "test number of veto overflow",
- block: &types.Block{
- BlockHeader: types.BlockHeader{
- Height: consensus.MainNetParams.RoundVoteBlockNums - 1,
- PreviousBlockHash: bc.Hash{V0: 1},
- },
- Transactions: []*types.Tx{
- &types.Tx{
- TxData: types.TxData{
- Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
- Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51})},
- },
- },
- &types.Tx{
- TxData: types.TxData{
- Inputs: []*types.TxInput{types.NewVetoInput(nil, bc.NewHash([32]byte{0xff}), *consensus.BTMAssetID, math.MaxUint64, 0, []byte{0x51}, testXpub)},
- Outputs: []*types.TxOutput{types.NewIntraChainOutput(*consensus.BTMAssetID, math.MaxUint64, []byte{0x51})},
- },
- },
- },
- },
- consensusResult: &ConsensusResult{
- BlockHash: testutil.MustDecodeHash("4ebd9e7c00d3e0370931689c6eb9e2131c6700fe66e6b9718028dd75d7a4e329"),
- CoinbaseReward: map[string]uint64{
- "51": 100000000,
- },
- NumOfVote: map[string]uint64{
- "a8018a1ba4d85fc7118bbd065612da78b2c503e61a1a093d9c659567c5d3a591b3752569fbcafa951b2304b8f576f3f220e03b957ca819840e7c29e4b7fb2c4d": 100,
- },
- },
- wantErr: checked.ErrOverflow,
- },
- {
- desc: "test detch coinbase overflow",
- block: &types.Block{
- BlockHeader: types.BlockHeader{
- Height: consensus.MainNetParams.RoundVoteBlockNums - 1,
- PreviousBlockHash: bc.Hash{V0: 1},
- },
- Transactions: []*types.Tx{
- &types.Tx{
- TxData: types.TxData{
- Inputs: []*types.TxInput{types.NewCoinbaseInput([]byte{0x01})},
- Outputs: []*types.TxOutput{types.NewIntraChainOutput(bc.AssetID{}, 0, []byte{0x51})},
- },
- },
- &types.Tx{
- TxData: types.TxData{
- Inputs: []*types.TxInput{types.NewVetoInput(nil, bc.NewHash([32]byte{0xff}), *consensus.BTMAssetID, math.MaxUint64, 0, []byte{0x51}, testXpub)},
- Outputs: []*types.TxOutput{types.NewIntraChainOutput(*consensus.BTMAssetID, math.MaxUint64, []byte{0x51})},
- },
- },
- },
- },
- consensusResult: &ConsensusResult{
- BlockHash: testutil.MustDecodeHash("4ebd9e7c00d3e0370931689c6eb9e2131c6700fe66e6b9718028dd75d7a4e329"),
- CoinbaseReward: map[string]uint64{},
- NumOfVote: map[string]uint64{},
- },
- wantErr: checked.ErrOverflow,
- },
}
+
for i, c := range cases {
if err := c.consensusResult.DetachBlock(c.block); err != nil {
if err.Error() != c.wantErr.Error() {
}
}
}
-
-func TestConsensusNodes(t *testing.T) {
- var xpub1, xpub2, xpub3, xpub4, xpub5, xpub6, xpub7 chainkd.XPub
- strPub1 := "0f8669abbd3cc0a167156188e428f940088d5b2f36bb3449df71d2bdc5e077814ea3f68628eef279ed435f51ee26cff00f8bd28fabfd500bedb2a9e369f5c825"
- strPub2 := "e7f458ee8d2ba19b0fdc7410d1fd57e9c2e1a79377c661d66c55effe49d7ffc920e40510442d4a10b7bea06c09fb0b41f52601135adaaa7136204db36106c093"
- strPub3 := "1bec3a35da038ec7a76c40986e80b5af2dcef60341970e3fc58b4db0797bd4ca9b2cbf3d7ab820832e22a80b5b86ae1427f7f706a7780089958b2862e7bc0842"
- strPub4 := "b7f463446a31b3792cd168d52b7a89b3657bca3e25d6854db1488c389ab6fc8d538155c25c1ee6975cc7def19710908c7d9b7463ca34a22058b456b45e498db9"
- strPub5 := "b928e46bb01e834fdf167185e31b15de7cc257af8bbdf17f9c7fefd5bb97b306d048b6bc0da2097152c1c2ff38333c756a543adbba7030a447dcc776b8ac64ef"
- strPub6 := "36695997983028c279c3360ca345a90e3af1f9e3df2506119fca31cdc844be31630f9a421f4d1658e15d67a15ce29c36332dd45020d2a0147fcce4949ccd9a67"
- strPub7 := "123"
-
- xpub1.UnmarshalText([]byte(strPub1))
- xpub2.UnmarshalText([]byte(strPub2))
- xpub3.UnmarshalText([]byte(strPub3))
- xpub4.UnmarshalText([]byte(strPub4))
- xpub5.UnmarshalText([]byte(strPub5))
- xpub6.UnmarshalText([]byte(strPub6))
- xpub7.UnmarshalText([]byte(strPub7))
-
- cases := []struct {
- consensusResult *ConsensusResult
- consensusNode map[string]*ConsensusNode
- wantErr error
- }{
- {
- consensusResult: &ConsensusResult{
- NumOfVote: map[string]uint64{
- strPub1: 838063475500000, //1
- strPub2: 474794800000000, //3
- strPub3: 833812985000000, //2
- strPub4: 285918061999999, //4
- strPub5: 1228455289930297, //0
- strPub6: 274387690000000, //5
- strPub7: 1028455289930297,
- },
- },
- consensusNode: map[string]*ConsensusNode{
- strPub1: &ConsensusNode{XPub: xpub1, VoteNum: 838063475500000, Order: 1},
- strPub2: &ConsensusNode{XPub: xpub2, VoteNum: 474794800000000, Order: 3},
- strPub3: &ConsensusNode{XPub: xpub3, VoteNum: 833812985000000, Order: 2},
- strPub4: &ConsensusNode{XPub: xpub4, VoteNum: 285918061999999, Order: 4},
- strPub5: &ConsensusNode{XPub: xpub5, VoteNum: 1228455289930297, Order: 0},
- strPub6: &ConsensusNode{XPub: xpub6, VoteNum: 274387690000000, Order: 5},
- },
- },
- }
-
- for i, c := range cases {
- consensusNode, err := c.consensusResult.ConsensusNodes()
- if err != nil {
- if err != c.wantErr {
- t.Errorf("test case #%d want err = %v, got err = %v", i, c.wantErr, err)
- }
- continue
- }
-
- if !testutil.DeepEqual(consensusNode, c.consensusNode) {
- t.Errorf("test case #%d, want %v, got %v", i, c.consensusNode, consensusNode)
- }
- }
-}
-
-func TestFork(t *testing.T) {
- consensusResult := &ConsensusResult{
- Seq: 100,
- NumOfVote: map[string]uint64{
- "a": 100,
- "b": 200,
- },
- CoinbaseReward: map[string]uint64{
- "c": 300,
- "d": 400,
- },
- BlockHash: bc.NewHash([32]byte{0x1, 0x2}),
- BlockHeight: 1024,
- }
- copy := consensusResult.Fork()
-
- if !reflect.DeepEqual(consensusResult, copy) {
- t.Fatalf("failed on test consensusResult got %s want %s", spew.Sdump(copy), spew.Sdump(consensusResult))
- }
-}