github.com/aergoio/aergo@v1.3.1/contract/system/execute_test.go (about)

     1  /**
     2   *  @file
     3   *  @copyright defined in aergo/LICENSE.txt
     4   */
     5  package system
     6  
     7  import (
     8  	"math/big"
     9  	"testing"
    10  
    11  	"github.com/aergoio/aergo/types"
    12  	"github.com/mr-tron/base58/base58"
    13  	"github.com/stretchr/testify/assert"
    14  )
    15  
    16  func TestBasicExecute(t *testing.T) {
    17  	scs, sender, receiver := initTest(t)
    18  	defer deinitTest()
    19  
    20  	tx := &types.Tx{
    21  		Body: &types.TxBody{
    22  			Account:   sender.ID(),
    23  			Recipient: []byte(types.AergoSystem),
    24  			Amount:    types.StakingMinimum.Bytes(),
    25  			Payload:   []byte(`{"Name":"v1stake"}`),
    26  		},
    27  	}
    28  	sender.AddBalance(types.StakingMinimum)
    29  
    30  	emptytx := &types.TxBody{}
    31  	_, err := ExecuteSystemTx(scs, emptytx, sender, receiver, 0)
    32  	assert.EqualError(t, types.ErrTxInvalidPayload, err.Error(), "Execute system tx failed")
    33  
    34  	events, err := ExecuteSystemTx(scs, tx.GetBody(), sender, receiver, 0)
    35  	assert.NoError(t, err, "Execute system tx failed in staking")
    36  	assert.Equal(t, sender.Balance().Uint64(), uint64(0), "sender.Balance() should be 0 after staking")
    37  	assert.Equal(t, events[0].ContractAddress, types.AddressPadding([]byte(types.AergoSystem)), "check event")
    38  	assert.Equal(t, events[0].EventName, types.Stake[2:], "check event")
    39  	staking, err := getStaking(scs, tx.GetBody().GetAccount())
    40  	assert.Equal(t, types.StakingMinimum, new(big.Int).SetBytes(staking.Amount), "check amount of staking")
    41  
    42  	tx.Body.Payload = []byte(`{"Name":"v1voteBP","Args":["16Uiu2HAmBDcLEjBYeEnGU2qDD1KdpEdwDBtN7gqXzNZbHXo8Q841"]}`)
    43  	tx.Body.Amount = big.NewInt(0).Bytes()
    44  	events, err = ExecuteSystemTx(scs, tx.GetBody(), sender, receiver, VotingDelay)
    45  	assert.NoError(t, err, "Execute system tx failed in voting")
    46  	assert.Equal(t, events[0].ContractAddress, types.AddressPadding([]byte(types.AergoSystem)), "check event")
    47  	assert.Equal(t, events[0].EventName, types.VoteBP[2:], "check event")
    48  	tx.Body.Payload = []byte(`{"Name":"v1unstake"}`)
    49  	tx.Body.Amount = types.StakingMinimum.Bytes()
    50  	_, err = ExecuteSystemTx(scs, tx.GetBody(), sender, receiver, VotingDelay+StakingDelay)
    51  	assert.NoError(t, err, "Execute system tx failed in unstaking")
    52  	assert.Equal(t, types.StakingMinimum.Bytes(), sender.Balance().Bytes(),
    53  		"sender.Balance() should be turn back")
    54  	staking, err = getStaking(scs, tx.GetBody().GetAccount())
    55  	assert.Equal(t, big.NewInt(0), new(big.Int).SetBytes(staking.Amount), "check amount of staking")
    56  }
    57  
    58  func TestBalanceExecute(t *testing.T) {
    59  	scs, sender, receiver := initTest(t)
    60  	defer deinitTest()
    61  
    62  	tx := &types.Tx{
    63  		Body: &types.TxBody{
    64  			Account:   sender.ID(),
    65  			Recipient: []byte(types.AergoSystem),
    66  			Amount:    types.StakingMinimum.Bytes(),
    67  			Payload:   []byte(`{"Name":"v1stake"}`),
    68  		},
    69  	}
    70  	balance3 := new(big.Int).Mul(types.StakingMinimum, big.NewInt(3))
    71  	balance2 := new(big.Int).Mul(types.StakingMinimum, big.NewInt(2))
    72  	sender.AddBalance(balance3)
    73  
    74  	blockNo := uint64(0)
    75  	//staking 1
    76  	//balance 3-1=2
    77  	events, err := ExecuteSystemTx(scs, tx.GetBody(), sender, receiver, blockNo)
    78  	assert.NoError(t, err, "Execute system tx failed in staking")
    79  	assert.Equal(t, balance2, sender.Balance(), "sender.Balance() should be 0 after staking")
    80  	assert.Equal(t, events[0].ContractAddress, types.AddressPadding([]byte(types.AergoSystem)), "check event")
    81  	assert.Equal(t, events[0].EventName, types.Stake[2:], "check event")
    82  	staking, err := getStaking(scs, tx.GetBody().GetAccount())
    83  	assert.Equal(t, types.StakingMinimum, new(big.Int).SetBytes(staking.Amount), "check amount of staking")
    84  	assert.Equal(t, types.StakingMinimum, receiver.Balance(), "check amount of staking")
    85  
    86  	tx.Body.Payload = []byte(`{"Name":"v1voteBP","Args":["16Uiu2HAmBDcLEjBYeEnGU2qDD1KdpEdwDBtN7gqXzNZbHXo8Q841"]}`)
    87  	tx.Body.Amount = big.NewInt(0).Bytes()
    88  
    89  	blockNo += VotingDelay
    90  	//voting when 1
    91  	events, err = ExecuteSystemTx(scs, tx.GetBody(), sender, receiver, blockNo)
    92  	assert.NoError(t, err, "Execute system tx failed in voting")
    93  	assert.Equal(t, events[0].ContractAddress, types.AddressPadding([]byte(types.AergoSystem)), "check event")
    94  	assert.Equal(t, events[0].EventName, types.VoteBP[2:], "check event")
    95  
    96  	voteResult, err := getVoteResult(scs, defaultVoteKey, 1)
    97  	assert.NoError(t, err, "get vote result")
    98  	assert.Equal(t, types.StakingMinimum, new(big.Int).SetBytes(voteResult.Votes[0].Amount), "")
    99  
   100  	tx.Body.Payload = []byte(`{"Name":"v1stake"}`)
   101  	tx.Body.Amount = balance2.Bytes()
   102  
   103  	blockNo += StakingDelay
   104  	//staking 1+2 = 3
   105  	//balance 2-2 = 0
   106  	_, err = ExecuteSystemTx(scs, tx.GetBody(), sender, receiver, blockNo)
   107  	assert.NoError(t, err, "Execute system tx failed in staking")
   108  	assert.Equal(t, big.NewInt(0), sender.Balance(), "sender.Balance() should be 0 after staking")
   109  	staking, err = getStaking(scs, tx.GetBody().GetAccount())
   110  	assert.Equal(t, balance3, new(big.Int).SetBytes(staking.Amount), "check amount of staking")
   111  	assert.Equal(t, balance3, receiver.Balance(), "check amount of staking")
   112  
   113  	//voting still 1
   114  	voteResult, err = getVoteResult(scs, defaultVoteKey, 1)
   115  	assert.NoError(t, err, "get vote result")
   116  	assert.Equal(t, types.StakingMinimum, new(big.Int).SetBytes(voteResult.Votes[0].Amount), "")
   117  
   118  	tx.Body.Payload = []byte(`{"Name":"v1unstake"}`)
   119  	tx.Body.Amount = types.StakingMinimum.Bytes()
   120  	blockNo += StakingDelay
   121  	//unstaking 3-1 = 2
   122  	//balance 0+1 = 1
   123  	//voting still 1
   124  	_, err = ExecuteSystemTx(scs, tx.GetBody(), sender, receiver, blockNo)
   125  	assert.NoError(t, err, "Execute system tx failed in unstaking")
   126  	assert.Equal(t, types.StakingMinimum, new(big.Int).SetBytes(sender.Balance().Bytes()), "sender.Balance() should be turn back")
   127  	staking, err = getStaking(scs, tx.GetBody().GetAccount())
   128  	assert.Equal(t, balance2, new(big.Int).SetBytes(staking.Amount), "check amount of staking")
   129  	assert.Equal(t, balance2, receiver.Balance(), "check amount of staking")
   130  	voteResult, err = getVoteResult(scs, defaultVoteKey, 1)
   131  	assert.NoError(t, err, "get vote reulst")
   132  	assert.Equal(t, types.StakingMinimum, new(big.Int).SetBytes(voteResult.Votes[0].Amount), "")
   133  
   134  	//unstaking 2-3 = -1(fail)
   135  	//balance 1
   136  	//voting 1
   137  	tx.Body.Amount = balance3.Bytes()
   138  	blockNo += StakingDelay
   139  	_, err = ExecuteSystemTx(scs, tx.GetBody(), sender, receiver, blockNo)
   140  	assert.EqualError(t, types.ErrExceedAmount, err.Error(), "should return exceed error")
   141  	assert.Equal(t, types.StakingMinimum, new(big.Int).SetBytes(sender.Balance().Bytes()), "sender.Balance() should be turn back")
   142  	staking, err = getStaking(scs, tx.GetBody().GetAccount())
   143  	assert.Equal(t, balance2, new(big.Int).SetBytes(staking.Amount), "check amount of staking")
   144  	voteResult, err = getVoteResult(scs, defaultVoteKey, 1)
   145  	assert.NoError(t, err, "get vote reulst")
   146  	assert.Equal(t, types.StakingMinimum, new(big.Int).SetBytes(voteResult.Votes[0].Amount), "")
   147  
   148  	tx.Body.Amount = balance2.Bytes()
   149  	blockNo += StakingDelay
   150  	//unstaking 2-2 = 0
   151  	//balance 1+2 = 3
   152  	//voting 0
   153  	_, err = ExecuteSystemTx(scs, tx.GetBody(), sender, receiver, blockNo)
   154  	assert.NoError(t, err, "Execute system tx failed in unstaking")
   155  	assert.Equal(t, balance3, new(big.Int).SetBytes(sender.Balance().Bytes()), "sender.Balance() should be turn back")
   156  	staking, err = getStaking(scs, tx.GetBody().GetAccount())
   157  	assert.Equal(t, big.NewInt(0), new(big.Int).SetBytes(staking.Amount), "check amount of staking")
   158  	voteResult, err = getVoteResult(scs, defaultVoteKey, 1)
   159  	assert.NoError(t, err, "get vote reulst")
   160  	assert.Equal(t, big.NewInt(0), new(big.Int).SetBytes(voteResult.Votes[0].Amount), "")
   161  }
   162  
   163  func TestBasicFailedExecute(t *testing.T) {
   164  	scs, sender, receiver := initTest(t)
   165  	defer deinitTest()
   166  
   167  	tx := &types.Tx{
   168  		Body: &types.TxBody{
   169  			Account:   sender.ID(),
   170  			Recipient: []byte(types.AergoSystem),
   171  			Amount:    types.StakingMinimum.Bytes(),
   172  			Payload:   buildStakingPayload(false),
   173  		},
   174  	}
   175  	senderBalance := big.NewInt(0).Add(types.StakingMinimum, types.StakingMinimum)
   176  	sender.AddBalance(senderBalance)
   177  
   178  	emptytx := &types.TxBody{}
   179  	_, err := ExecuteSystemTx(scs, emptytx, sender, receiver, 0)
   180  	assert.EqualError(t, types.ErrTxInvalidPayload, err.Error(), "should error")
   181  
   182  	//staking 0+1 = 1
   183  	//balance 2-1 = 1
   184  	_, err = ExecuteSystemTx(scs, tx.GetBody(), sender, receiver, 0)
   185  	assert.Error(t, err, "Execute system tx failed in unstaking")
   186  	assert.Equal(t, sender.Balance(), senderBalance, "sender.Balance() should not chagned after failed unstaking")
   187  
   188  	tx.Body.Payload = buildStakingPayload(true)
   189  	_, err = ExecuteSystemTx(scs, tx.GetBody(), sender, receiver, 0)
   190  	assert.NoError(t, err, "Execute system tx failed in staking")
   191  	assert.Equal(t, sender.Balance(), types.StakingMinimum, "sender.Balance() should be 0 after staking")
   192  	staking, err := getStaking(scs, tx.GetBody().GetAccount())
   193  	assert.Equal(t, types.StakingMinimum, new(big.Int).SetBytes(staking.Amount), "check amount of staking")
   194  
   195  	_, err = ExecuteSystemTx(scs, tx.GetBody(), sender, receiver, StakingDelay-1)
   196  	assert.EqualError(t, types.ErrLessTimeHasPassed, err.Error(), "check staking delay")
   197  
   198  	tx.Body.Payload = buildVotingPayload(1)
   199  	_, err = ExecuteSystemTx(scs, tx.GetBody(), sender, receiver, VotingDelay)
   200  	assert.NoError(t, err, "Execute system tx failed in voting")
   201  	result, err := getVoteResult(scs, defaultVoteKey, 1)
   202  	assert.Equal(t, types.StakingMinimum, result.Votes[0].GetAmountBigInt(), "check vote result")
   203  	tx.Body.Payload = buildStakingPayload(false)
   204  	tx.Body.Amount = senderBalance.Bytes()
   205  	//staking 1-2 = -1 (fail)
   206  	//balance still 1
   207  	_, err = ExecuteSystemTx(scs, tx.GetBody(), sender, receiver, VotingDelay+StakingDelay)
   208  	assert.Error(t, err, "should failed with exceed error")
   209  	assert.Equal(t, types.StakingMinimum, sender.Balance(),
   210  		"sender.Balance() should be turn back")
   211  	staking, err = getStaking(scs, tx.GetBody().GetAccount())
   212  	assert.Equal(t, types.StakingMinimum, new(big.Int).SetBytes(staking.Amount), "check amount of staking")
   213  
   214  	//staking 1-1 = 0
   215  	//balance 1+1 = 2
   216  	tx.Body.Amount = types.StakingMinimum.Bytes()
   217  	_, err = ExecuteSystemTx(scs, tx.GetBody(), sender, receiver, VotingDelay+StakingDelay)
   218  	assert.NoError(t, err, "Execute system tx failed in staking")
   219  	staking, err = getStaking(scs, tx.GetBody().GetAccount())
   220  	assert.Equal(t, senderBalance, sender.Balance(),
   221  		"sender.Balance() should be turn back")
   222  	assert.Equal(t, big.NewInt(0), new(big.Int).SetBytes(staking.Amount), "check amount of staking")
   223  
   224  	//staking 0-1 = -1 (fail)
   225  	//balance still 2
   226  	_, err = ExecuteSystemTx(scs, tx.GetBody(), sender, receiver, VotingDelay+StakingDelay)
   227  	assert.EqualError(t, types.ErrMustStakeBeforeUnstake, err.Error(), "Execute system tx failed in unstaking")
   228  }
   229  
   230  func TestValidateSystemTxForStaking(t *testing.T) {
   231  	scs, sender, receiver := initTest(t)
   232  	defer deinitTest()
   233  
   234  	scs, err := cdb.GetStateDB().OpenContractStateAccount(types.ToAccountID([]byte("aergo.system")))
   235  	assert.NoError(t, err, "could not open contract state")
   236  
   237  	tx := &types.Tx{
   238  		Body: &types.TxBody{
   239  			Account:   sender.ID(),
   240  			Recipient: receiver.ID(),
   241  			Amount:    types.StakingMinimum.Bytes(),
   242  			Payload:   buildStakingPayload(true),
   243  		},
   244  	}
   245  	sender.AddBalance(types.StakingMinimum)
   246  	_, err = ValidateSystemTx(tx.Body.Account, tx.GetBody(), sender, scs, 0)
   247  	assert.NoError(t, err, "Validate system tx failed")
   248  	tx.Body.Amount = new(big.Int).Sub(types.StakingMinimum, new(big.Int).SetUint64(1)).Bytes()
   249  }
   250  
   251  func TestValidateSystemTxForUnstaking(t *testing.T) {
   252  	scs, sender, receiver := initTest(t)
   253  	defer deinitTest()
   254  	const testSender = "AmPNYHyzyh9zweLwDyuoiUuTVCdrdksxkRWDjVJS76WQLExa2Jr4"
   255  
   256  	scs, err := cdb.GetStateDB().OpenContractStateAccount(types.ToAccountID([]byte("aergo.system")))
   257  	assert.NoError(t, err, "could not open contract state")
   258  
   259  	account, err := types.DecodeAddress(testSender)
   260  	assert.NoError(t, err, "could not decode test address")
   261  	tx := &types.Tx{
   262  		Body: &types.TxBody{
   263  			Account: account,
   264  			Amount:  types.StakingMinimum.Bytes(),
   265  			Payload: buildStakingPayload(false),
   266  		},
   267  	}
   268  	_, err = ValidateSystemTx(tx.Body.Account, tx.GetBody(), nil, scs, 0)
   269  	assert.EqualError(t, types.ErrMustStakeBeforeUnstake, err.Error(), "Validate system tx failed")
   270  	tx.Body.Amount = new(big.Int).Sub(types.StakingMinimum, new(big.Int).SetUint64(1)).Bytes()
   271  	//_, err = ValidateSystemTx(tx.Body.Account, tx.GetBody(), nil, scs, 0)
   272  	//assert.EqualError(t, err, types.ErrMustStakeBeforeUnstake.Error(), "Validate system tx failed")
   273  
   274  	stakingTx := &types.Tx{
   275  		Body: &types.TxBody{
   276  			Account: account,
   277  			Amount:  types.StakingMinimum.Bytes(),
   278  			Payload: buildStakingPayload(true),
   279  			Type:    types.TxType_GOVERNANCE,
   280  		},
   281  	}
   282  	sender.AddBalance(types.StakingMinimum)
   283  
   284  	_, err = ExecuteSystemTx(scs, stakingTx.GetBody(), sender, receiver, 0)
   285  	assert.NoError(t, err, "could not execute system tx")
   286  
   287  	tx.Body.Amount = types.StakingMinimum.Bytes()
   288  	_, err = ValidateSystemTx(tx.Body.Account, tx.GetBody(), nil, scs, StakingDelay-1)
   289  	assert.EqualError(t, types.ErrLessTimeHasPassed, err.Error(), "Validate system tx failed")
   290  	_, err = ValidateSystemTx(tx.Body.Account, tx.GetBody(), nil, scs, StakingDelay)
   291  	assert.NoError(t, err, "failed to validate system tx for unstaking")
   292  }
   293  
   294  func TestValidateSystemTxForVoting(t *testing.T) {
   295  	scs, sender, receiver := initTest(t)
   296  	defer deinitTest()
   297  	const testSender = "AmPNYHyzyh9zweLwDyuoiUuTVCdrdksxkRWDjVJS76WQLExa2Jr4"
   298  	const testCandidate = "16Uiu2HAmUJhjwotQqm7eGyZh1ZHrVviQJrdm2roQouD329vxZEkx"
   299  	candidates, err := base58.Decode(testCandidate)
   300  	assert.NoError(t, err, "could not decode candidates")
   301  
   302  	account, err := types.DecodeAddress(testSender)
   303  	assert.NoError(t, err, "could not decode test address")
   304  
   305  	tx := &types.Tx{
   306  		Body: &types.TxBody{
   307  			Account: account,
   308  			Payload: buildVotingPayload(0),
   309  			Type:    types.TxType_GOVERNANCE,
   310  		},
   311  	}
   312  	_, err = ValidateSystemTx(tx.Body.Account, tx.GetBody(), nil, scs, 1)
   313  	assert.EqualError(t, err, types.ErrMustStakeBeforeVote.Error(), "Execute system tx failed")
   314  	tx.Body.Payload = append(tx.Body.Payload, candidates...)
   315  
   316  	sender.AddBalance(types.StakingMinimum)
   317  
   318  	stakingTx := &types.Tx{
   319  		Body: &types.TxBody{
   320  			Account: account,
   321  			Amount:  types.StakingMinimum.Bytes(),
   322  			Payload: buildStakingPayload(true),
   323  			Type:    types.TxType_GOVERNANCE,
   324  		},
   325  	}
   326  
   327  	unStakingTx := &types.Tx{
   328  		Body: &types.TxBody{
   329  			Account: account,
   330  			Amount:  types.StakingMinimum.Bytes(),
   331  			Payload: buildStakingPayload(false),
   332  			Type:    types.TxType_GOVERNANCE,
   333  		},
   334  	}
   335  	var blockNo uint64
   336  	blockNo = 1
   337  	_, err = ExecuteSystemTx(scs, stakingTx.GetBody(), sender, receiver, blockNo)
   338  	assert.NoError(t, err, "could not execute system tx")
   339  
   340  	blockNo += StakingDelay
   341  	_, err = ExecuteSystemTx(scs, stakingTx.GetBody(), sender, receiver, blockNo)
   342  	assert.EqualError(t, err, types.ErrInsufficientBalance.Error(), "2nd staking tx")
   343  
   344  	_, err = ValidateSystemTx(tx.Body.Account, tx.GetBody(), nil, scs, blockNo)
   345  	assert.Error(t, err, "empty vote should not allowed")
   346  
   347  	tx.Body.Payload = buildVotingPayload(10)
   348  	_, err = ValidateSystemTx(tx.Body.Account, tx.GetBody(), nil, scs, blockNo)
   349  	assert.NoError(t, err, "fisrt voting validation should success")
   350  
   351  	_, err = ExecuteSystemTx(scs, tx.GetBody(), sender, receiver, blockNo)
   352  	assert.NoError(t, err, "fisrt voting execution should success")
   353  
   354  	blockNo++
   355  	_, err = ValidateSystemTx(tx.Body.Account, tx.GetBody(), nil, scs, blockNo)
   356  	assert.Error(t, err, "not enough delay, voting should fail")
   357  
   358  	blockNo += VotingDelay
   359  	_, err = ValidateSystemTx(tx.Body.Account, tx.GetBody(), nil, scs, blockNo)
   360  	assert.NoError(t, err, "after delay, voting should success")
   361  
   362  	tx.Body.Payload[1] = '2'
   363  	_, err = ValidateSystemTx(tx.Body.Account, tx.GetBody(), nil, scs, blockNo)
   364  	t.Log(err.Error())
   365  	assert.NotNil(t, err, "failed to validate system tx for voting")
   366  
   367  	tx.Body.Payload = append(tx.Body.Payload, 'i')
   368  	_, err = ValidateSystemTx(tx.Body.Account, tx.GetBody(), nil, scs, blockNo)
   369  	assert.EqualError(t, types.ErrTxInvalidPayload, err.Error(), "failed to validate system tx for voting")
   370  
   371  	blockNo += StakingDelay
   372  	_, err = ExecuteSystemTx(scs, unStakingTx.GetBody(), sender, receiver, blockNo)
   373  	assert.NoError(t, err, "should execute unstaking system tx")
   374  }
   375  
   376  func TestRemainStakingMinimum(t *testing.T) {
   377  	scs, sender, receiver := initTest(t)
   378  	defer deinitTest()
   379  
   380  	balance0_5 := new(big.Int).Div(types.StakingMinimum, big.NewInt(2))
   381  	balance1 := types.StakingMinimum
   382  	balance1_5 := new(big.Int).Add(balance1, balance0_5)
   383  	balance2 := new(big.Int).Mul(balance1, big.NewInt(2))
   384  	balance3 := new(big.Int).Mul(balance1, big.NewInt(3))
   385  	sender.AddBalance(balance3)
   386  
   387  	stakingTx := &types.Tx{
   388  		Body: &types.TxBody{
   389  			Account: sender.ID(),
   390  			Payload: buildStakingPayload(true),
   391  			Type:    types.TxType_GOVERNANCE,
   392  		},
   393  	}
   394  
   395  	var blockNo uint64
   396  	blockNo = 1
   397  	stakingTx.Body.Amount = balance0_5.Bytes()
   398  	_, err := ExecuteSystemTx(scs, stakingTx.GetBody(), sender, receiver, blockNo)
   399  	assert.EqualError(t, err, types.ErrTooSmallAmount.Error(), "could not execute system tx")
   400  	//balance 3-1.5=1.5
   401  	//staking 0+1.5=1.5
   402  	stakingTx.Body.Amount = balance1_5.Bytes()
   403  	_, err = ExecuteSystemTx(scs, stakingTx.GetBody(), sender, receiver, blockNo)
   404  	assert.NoError(t, err, "could not execute system tx")
   405  
   406  	blockNo += StakingDelay
   407  	stakingTx.Body.Amount = balance0_5.Bytes()
   408  	//balance 1.5-0.5=1
   409  	//staking 1.5+1.5=3
   410  	_, err = ExecuteSystemTx(scs, stakingTx.GetBody(), sender, receiver, blockNo)
   411  	assert.NoError(t, err, "could not execute system tx")
   412  
   413  	stakingTx.Body.Amount = balance2.Bytes()
   414  	//balance 1-2=-1 (fail)
   415  	_, err = ExecuteSystemTx(scs, stakingTx.GetBody(), sender, receiver, blockNo+1)
   416  	assert.EqualError(t, err, types.ErrInsufficientBalance.Error(), "check error")
   417  
   418  	stakingTx.Body.Amount = balance1.Bytes()
   419  	//time fail
   420  	_, err = ExecuteSystemTx(scs, stakingTx.GetBody(), sender, receiver, blockNo+1)
   421  	assert.EqualError(t, err, types.ErrLessTimeHasPassed.Error(), "check error")
   422  
   423  	unStakingTx := &types.Tx{
   424  		Body: &types.TxBody{
   425  			Account: sender.ID(),
   426  			Amount:  balance0_5.Bytes(),
   427  			Payload: buildStakingPayload(false),
   428  			Type:    types.TxType_GOVERNANCE,
   429  		},
   430  	}
   431  	blockNo += StakingDelay - 1
   432  	_, err = ExecuteSystemTx(scs, unStakingTx.GetBody(), sender, receiver, blockNo)
   433  	assert.EqualError(t, err, types.ErrLessTimeHasPassed.Error(), "check error")
   434  
   435  	blockNo += 1
   436  	//balance 1+0.5 =1.5
   437  	//staking 2-0.5 =1.5
   438  	_, err = ExecuteSystemTx(scs, unStakingTx.GetBody(), sender, receiver, blockNo)
   439  	assert.NoError(t, err, "could not execute system tx")
   440  	staked, err := getStaking(scs, sender.ID())
   441  	assert.NoError(t, err, "could not get staking")
   442  	assert.Equal(t, balance1_5, sender.Balance(), "could not get staking")
   443  	assert.Equal(t, balance1_5, staked.GetAmountBigInt(), "could not get staking")
   444  
   445  	blockNo += StakingDelay
   446  	//balance 1.5+0.5 =2
   447  	//staking 1.5-0.5 =1
   448  	_, err = ExecuteSystemTx(scs, unStakingTx.GetBody(), sender, receiver, blockNo)
   449  	assert.NoError(t, err, "could not execute system tx")
   450  	staked, err = getStaking(scs, sender.ID())
   451  	assert.NoError(t, err, "could not get staking")
   452  	assert.Equal(t, balance2, sender.Balance(), "could not get staking")
   453  	assert.Equal(t, balance1, staked.GetAmountBigInt(), "could not get staking")
   454  
   455  	blockNo += StakingDelay
   456  	//staking 1-0.5 =0.5 (fail)
   457  	_, err = ExecuteSystemTx(scs, unStakingTx.GetBody(), sender, receiver, blockNo)
   458  	assert.EqualError(t, err, types.ErrTooSmallAmount.Error(), "staked aergo remain 0.5")
   459  	staked, err = getStaking(scs, sender.ID())
   460  	assert.NoError(t, err, "could not get staking")
   461  	assert.Equal(t, balance2, sender.Balance(), "could not get staking")
   462  	assert.Equal(t, balance1, staked.GetAmountBigInt(), "could not get staking")
   463  
   464  	blockNo += StakingDelay
   465  	unStakingTx.Body.Amount = balance1.Bytes()
   466  	//balance 2+1 =3
   467  	//staking 1-1 =0
   468  	_, err = ExecuteSystemTx(scs, unStakingTx.GetBody(), sender, receiver, blockNo)
   469  	assert.NoError(t, err, "could not execute system tx")
   470  	staked, err = getStaking(scs, sender.ID())
   471  	assert.NoError(t, err, "could not get staking")
   472  	assert.Equal(t, balance3, sender.Balance(), "could not get staking")
   473  	assert.Equal(t, big.NewInt(0), staked.GetAmountBigInt(), "could not get staking")
   474  
   475  	_, err = ExecuteSystemTx(scs, unStakingTx.GetBody(), sender, receiver, blockNo)
   476  	assert.EqualError(t, err, types.ErrMustStakeBeforeUnstake.Error(), "check error")
   477  }
   478  
   479  /*
   480  func TestValidateVoteNumpBP(t *testing.T) {
   481  scs,sender,receiver:=initTest(t)
   482  	defer deinitTest()
   483  	const testSender = "AmPNYHyzyh9zweLwDyuoiUuTVCdrdksxkRWDjVJS76WQLExa2Jr4"
   484  
   485  	scs, err := cdb.GetStateDB().OpenContractStateAccount(types.ToAccountID([]byte("aergo.system")))
   486  	assert.NoError(t, err, "could not open contract state")
   487  
   488  	account, err := types.DecodeAddress(testSender)
   489  	assert.NoError(t, err, "could not decode test address")
   490  	tx := &types.Tx{
   491  		Body: &types.TxBody{
   492  			Account: account,
   493  			Amount:  types.StakingMinimum.Bytes(),
   494  			Payload: buildStakingPayload(true),
   495  		},
   496  	}
   497  	sender, err := sdb.GetAccountStateV(tx.Body.Account)
   498  	assert.NoError(t, err, "could not get test address state")
   499  	receiver, err := sdb.GetAccountStateV(tx.Body.Recipient)
   500  	assert.NoError(t, err, "could not get test address state")
   501  	sender.AddBalance(types.StakingMinimum)
   502  
   503  	_, err = ExecuteSystemTx(scs, tx.GetBody(), sender, receiver, 0)
   504  	assert.NoError(t, err, "Execute system tx failed in staking")
   505  
   506  	tx.Body.Payload = buildVotingPayloadEx(1, types.VoteBP)
   507  	_, err = ExecuteSystemTx(scs, tx.GetBody(), sender, receiver, 1)
   508  	assert.NoError(t, err, "Execute system tx failed in voting")
   509  	tx.Body.Payload = buildVotingPayloadEx(1, types.VoteNumBP)
   510  	_, err = ExecuteSystemTx(scs, tx.GetBody(), sender, receiver, 2)
   511  	assert.NoError(t, err, "Execute system tx failed in voting")
   512  }
   513  */