2020-06-15 18:13:32 +00:00
|
|
|
package core
|
|
|
|
|
|
|
|
import (
|
|
|
|
"math/big"
|
|
|
|
"testing"
|
|
|
|
|
2020-11-23 11:09:00 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/internal/random"
|
2020-10-02 15:15:16 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
2020-12-14 09:18:59 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
2020-06-15 18:13:32 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/native"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
2020-10-02 15:15:16 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/network/payload"
|
2020-06-15 18:13:32 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
2020-07-31 12:48:35 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
2020-11-27 10:55:48 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
2020-06-15 18:13:32 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestMaxTransactionsPerBlock(t *testing.T) {
|
|
|
|
chain := newTestChain(t)
|
|
|
|
defer chain.Close()
|
2020-11-19 10:00:46 +00:00
|
|
|
policyHash := chain.contracts.Policy.Metadata().Hash
|
2020-06-15 18:13:32 +00:00
|
|
|
|
|
|
|
t.Run("get, internal method", func(t *testing.T) {
|
|
|
|
n := chain.contracts.Policy.GetMaxTransactionsPerBlockInternal(chain.dao)
|
|
|
|
require.Equal(t, 512, int(n))
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("get, contract method", func(t *testing.T) {
|
2020-11-19 10:00:46 +00:00
|
|
|
res, err := invokeContractMethod(chain, 100000000, policyHash, "getMaxTransactionsPerBlock")
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, err)
|
2020-07-31 12:48:35 +00:00
|
|
|
checkResult(t, res, stackitem.NewBigInteger(big.NewInt(512)))
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, chain.persist())
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("set", func(t *testing.T) {
|
2020-11-19 10:00:46 +00:00
|
|
|
res, err := invokeContractMethod(chain, 100000000, policyHash, "setMaxTransactionsPerBlock", bigint.ToBytes(big.NewInt(1024)))
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, err)
|
2020-07-31 12:48:35 +00:00
|
|
|
checkResult(t, res, stackitem.NewBool(true))
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, chain.persist())
|
|
|
|
n := chain.contracts.Policy.GetMaxTransactionsPerBlockInternal(chain.dao)
|
|
|
|
require.Equal(t, 1024, int(n))
|
|
|
|
})
|
2020-10-02 15:15:16 +00:00
|
|
|
|
|
|
|
t.Run("set, too big value", func(t *testing.T) {
|
2020-11-19 10:00:46 +00:00
|
|
|
res, err := invokeContractMethod(chain, 100000000, policyHash, "setMaxTransactionsPerBlock", bigint.ToBytes(big.NewInt(block.MaxContentsPerBlock)))
|
2020-10-02 15:15:16 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
checkFAULTState(t, res)
|
|
|
|
})
|
2020-11-27 10:55:48 +00:00
|
|
|
|
|
|
|
t.Run("set, not signed by committee", func(t *testing.T) {
|
|
|
|
signer, err := wallet.NewAccount()
|
|
|
|
require.NoError(t, err)
|
|
|
|
invokeRes, err := invokeContractMethodBy(t, chain, signer, policyHash, "setMaxTransactionsPerBlock", bigint.ToBytes(big.NewInt(1024)))
|
|
|
|
checkResult(t, invokeRes, stackitem.NewBool(false))
|
|
|
|
})
|
2020-06-15 18:13:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestMaxBlockSize(t *testing.T) {
|
|
|
|
chain := newTestChain(t)
|
|
|
|
defer chain.Close()
|
2020-11-19 10:00:46 +00:00
|
|
|
policyHash := chain.contracts.Policy.Metadata().Hash
|
2020-06-15 18:13:32 +00:00
|
|
|
|
2020-08-03 15:49:22 +00:00
|
|
|
t.Run("get, internal method", func(t *testing.T) {
|
|
|
|
n := chain.contracts.Policy.GetMaxBlockSizeInternal(chain.dao)
|
|
|
|
require.Equal(t, 1024*256, int(n))
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("get, contract method", func(t *testing.T) {
|
2020-11-19 10:00:46 +00:00
|
|
|
res, err := invokeContractMethod(chain, 100000000, policyHash, "getMaxBlockSize")
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, err)
|
2020-07-31 12:48:35 +00:00
|
|
|
checkResult(t, res, stackitem.NewBigInteger(big.NewInt(1024*256)))
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, chain.persist())
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("set", func(t *testing.T) {
|
2020-11-19 10:00:46 +00:00
|
|
|
res, err := invokeContractMethod(chain, 100000000, policyHash, "setMaxBlockSize", bigint.ToBytes(big.NewInt(102400)))
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, err)
|
2020-07-31 12:48:35 +00:00
|
|
|
checkResult(t, res, stackitem.NewBool(true))
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, chain.persist())
|
2020-11-19 10:00:46 +00:00
|
|
|
res, err = invokeContractMethod(chain, 100000000, policyHash, "getMaxBlockSize")
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, err)
|
2020-07-31 12:48:35 +00:00
|
|
|
checkResult(t, res, stackitem.NewBigInteger(big.NewInt(102400)))
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, chain.persist())
|
|
|
|
})
|
2020-10-02 15:15:16 +00:00
|
|
|
|
|
|
|
t.Run("set, too big value", func(t *testing.T) {
|
2020-11-19 10:00:46 +00:00
|
|
|
res, err := invokeContractMethod(chain, 100000000, policyHash, "setMaxBlockSize", bigint.ToBytes(big.NewInt(payload.MaxSize+1)))
|
2020-10-02 15:15:16 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
checkFAULTState(t, res)
|
|
|
|
})
|
2020-11-27 10:55:48 +00:00
|
|
|
|
|
|
|
t.Run("set, not signed by committee", func(t *testing.T) {
|
|
|
|
signer, err := wallet.NewAccount()
|
|
|
|
require.NoError(t, err)
|
|
|
|
invokeRes, err := invokeContractMethodBy(t, chain, signer, policyHash, "setMaxBlockSize", bigint.ToBytes(big.NewInt(102400)))
|
|
|
|
checkResult(t, invokeRes, stackitem.NewBool(false))
|
|
|
|
})
|
2020-06-15 18:13:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestFeePerByte(t *testing.T) {
|
|
|
|
chain := newTestChain(t)
|
|
|
|
defer chain.Close()
|
2020-11-19 10:00:46 +00:00
|
|
|
policyHash := chain.contracts.Policy.Metadata().Hash
|
2020-06-15 18:13:32 +00:00
|
|
|
|
|
|
|
t.Run("get, internal method", func(t *testing.T) {
|
|
|
|
n := chain.contracts.Policy.GetFeePerByteInternal(chain.dao)
|
|
|
|
require.Equal(t, 1000, int(n))
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("get, contract method", func(t *testing.T) {
|
2020-11-19 10:00:46 +00:00
|
|
|
res, err := invokeContractMethod(chain, 100000000, policyHash, "getFeePerByte")
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, err)
|
2020-07-31 12:48:35 +00:00
|
|
|
checkResult(t, res, stackitem.NewBigInteger(big.NewInt(1000)))
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, chain.persist())
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("set", func(t *testing.T) {
|
2020-11-19 10:00:46 +00:00
|
|
|
res, err := invokeContractMethod(chain, 100000000, policyHash, "setFeePerByte", bigint.ToBytes(big.NewInt(1024)))
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, err)
|
2020-07-31 12:48:35 +00:00
|
|
|
checkResult(t, res, stackitem.NewBool(true))
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, chain.persist())
|
|
|
|
n := chain.contracts.Policy.GetFeePerByteInternal(chain.dao)
|
|
|
|
require.Equal(t, 1024, int(n))
|
|
|
|
})
|
2020-10-02 15:15:16 +00:00
|
|
|
|
|
|
|
t.Run("set, negative value", func(t *testing.T) {
|
2020-11-19 10:00:46 +00:00
|
|
|
res, err := invokeContractMethod(chain, 100000000, policyHash, "setFeePerByte", bigint.ToBytes(big.NewInt(-1)))
|
2020-10-02 15:15:16 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
checkFAULTState(t, res)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("set, too big value", func(t *testing.T) {
|
2020-11-19 10:00:46 +00:00
|
|
|
res, err := invokeContractMethod(chain, 100000000, policyHash, "setFeePerByte", bigint.ToBytes(big.NewInt(100_000_000+1)))
|
2020-10-02 15:15:16 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
checkFAULTState(t, res)
|
|
|
|
})
|
2020-11-27 10:55:48 +00:00
|
|
|
|
|
|
|
t.Run("set, not signed by committee", func(t *testing.T) {
|
|
|
|
signer, err := wallet.NewAccount()
|
|
|
|
require.NoError(t, err)
|
|
|
|
invokeRes, err := invokeContractMethodBy(t, chain, signer, policyHash, "setFeePerByte", bigint.ToBytes(big.NewInt(1024)))
|
|
|
|
checkResult(t, invokeRes, stackitem.NewBool(false))
|
|
|
|
})
|
2020-06-15 18:13:32 +00:00
|
|
|
}
|
|
|
|
|
2020-12-14 09:18:59 +00:00
|
|
|
func TestExecFeeFactor(t *testing.T) {
|
|
|
|
chain := newTestChain(t)
|
|
|
|
defer chain.Close()
|
|
|
|
policyHash := chain.contracts.Policy.Metadata().Hash
|
|
|
|
|
|
|
|
t.Run("get, internal method", func(t *testing.T) {
|
|
|
|
n := chain.contracts.Policy.GetExecFeeFactorInternal(chain.dao)
|
|
|
|
require.EqualValues(t, interop.DefaultBaseExecFee, n)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("get", func(t *testing.T) {
|
|
|
|
res, err := invokeContractMethod(chain, 100000000, policyHash, "getExecFeeFactor")
|
|
|
|
require.NoError(t, err)
|
|
|
|
checkResult(t, res, stackitem.NewBigInteger(big.NewInt(interop.DefaultBaseExecFee)))
|
|
|
|
require.NoError(t, chain.persist())
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("set, zero fee", func(t *testing.T) {
|
|
|
|
res, err := invokeContractMethod(chain, 100000000, policyHash, "setExecFeeFactor", int64(0))
|
|
|
|
require.NoError(t, err)
|
|
|
|
checkFAULTState(t, res)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("set, too big fee", func(t *testing.T) {
|
|
|
|
res, err := invokeContractMethod(chain, 100000000, policyHash, "setExecFeeFactor", int64(1001))
|
|
|
|
require.NoError(t, err)
|
|
|
|
checkFAULTState(t, res)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("set, success", func(t *testing.T) {
|
|
|
|
// Set and get in the same block.
|
|
|
|
txSet, err := prepareContractMethodInvoke(chain, 100000000, policyHash, "setExecFeeFactor", int64(123))
|
|
|
|
require.NoError(t, err)
|
|
|
|
txGet1, err := prepareContractMethodInvoke(chain, 100000000, policyHash, "getExecFeeFactor")
|
|
|
|
require.NoError(t, err)
|
|
|
|
aers, err := persistBlock(chain, txSet, txGet1)
|
|
|
|
require.NoError(t, err)
|
|
|
|
checkResult(t, aers[0], stackitem.NewBool(true))
|
|
|
|
checkResult(t, aers[1], stackitem.Make(123))
|
|
|
|
require.NoError(t, chain.persist())
|
|
|
|
|
|
|
|
// Get in the next block.
|
|
|
|
res, err := invokeContractMethod(chain, 100000000, policyHash, "getExecFeeFactor")
|
|
|
|
require.NoError(t, err)
|
|
|
|
checkResult(t, res, stackitem.NewBigInteger(big.NewInt(123)))
|
|
|
|
require.NoError(t, chain.persist())
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("set, not signed by committee", func(t *testing.T) {
|
|
|
|
signer, err := wallet.NewAccount()
|
|
|
|
require.NoError(t, err)
|
|
|
|
invokeRes, err := invokeContractMethodBy(t, chain, signer, policyHash, "setExecFeeFactor", int64(100))
|
|
|
|
checkResult(t, invokeRes, stackitem.NewBool(false))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-08-03 13:35:05 +00:00
|
|
|
func TestBlockSystemFee(t *testing.T) {
|
|
|
|
chain := newTestChain(t)
|
|
|
|
defer chain.Close()
|
2020-11-19 10:00:46 +00:00
|
|
|
policyHash := chain.contracts.Policy.Metadata().Hash
|
2020-08-03 13:35:05 +00:00
|
|
|
|
|
|
|
t.Run("get, internal method", func(t *testing.T) {
|
|
|
|
n := chain.contracts.Policy.GetMaxBlockSystemFeeInternal(chain.dao)
|
|
|
|
require.Equal(t, 9000*native.GASFactor, int(n))
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("get", func(t *testing.T) {
|
2020-11-19 10:00:46 +00:00
|
|
|
res, err := invokeContractMethod(chain, 100000000, policyHash, "getMaxBlockSystemFee")
|
2020-08-03 13:35:05 +00:00
|
|
|
require.NoError(t, err)
|
2020-08-04 12:05:31 +00:00
|
|
|
checkResult(t, res, stackitem.NewBigInteger(big.NewInt(9000*native.GASFactor)))
|
2020-08-03 13:35:05 +00:00
|
|
|
require.NoError(t, chain.persist())
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("set, too low fee", func(t *testing.T) {
|
2020-11-19 10:00:46 +00:00
|
|
|
res, err := invokeContractMethod(chain, 100000000, policyHash, "setMaxBlockSystemFee", bigint.ToBytes(big.NewInt(4007600)))
|
2020-08-03 13:35:05 +00:00
|
|
|
require.NoError(t, err)
|
2020-10-02 15:15:16 +00:00
|
|
|
checkFAULTState(t, res)
|
2020-08-03 13:35:05 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("set, success", func(t *testing.T) {
|
2020-11-19 10:00:46 +00:00
|
|
|
res, err := invokeContractMethod(chain, 100000000, policyHash, "setMaxBlockSystemFee", bigint.ToBytes(big.NewInt(100000000)))
|
2020-08-03 13:35:05 +00:00
|
|
|
require.NoError(t, err)
|
2020-08-04 12:05:31 +00:00
|
|
|
checkResult(t, res, stackitem.NewBool(true))
|
2020-08-03 13:35:05 +00:00
|
|
|
require.NoError(t, chain.persist())
|
2020-11-19 10:00:46 +00:00
|
|
|
res, err = invokeContractMethod(chain, 100000000, policyHash, "getMaxBlockSystemFee")
|
2020-08-03 13:35:05 +00:00
|
|
|
require.NoError(t, err)
|
2020-08-04 12:05:31 +00:00
|
|
|
checkResult(t, res, stackitem.NewBigInteger(big.NewInt(100000000)))
|
2020-08-03 13:35:05 +00:00
|
|
|
require.NoError(t, chain.persist())
|
|
|
|
})
|
2020-11-27 10:55:48 +00:00
|
|
|
|
|
|
|
t.Run("set, not signed by committee", func(t *testing.T) {
|
|
|
|
signer, err := wallet.NewAccount()
|
|
|
|
require.NoError(t, err)
|
|
|
|
invokeRes, err := invokeContractMethodBy(t, chain, signer, policyHash, "setMaxBlockSystemFee", bigint.ToBytes(big.NewInt(100000000)))
|
|
|
|
checkResult(t, invokeRes, stackitem.NewBool(false))
|
|
|
|
})
|
2020-08-03 13:35:05 +00:00
|
|
|
}
|
|
|
|
|
2020-06-15 18:13:32 +00:00
|
|
|
func TestBlockedAccounts(t *testing.T) {
|
|
|
|
chain := newTestChain(t)
|
|
|
|
defer chain.Close()
|
|
|
|
account := util.Uint160{1, 2, 3}
|
2020-11-19 10:00:46 +00:00
|
|
|
policyHash := chain.contracts.Policy.Metadata().Hash
|
2020-06-15 18:13:32 +00:00
|
|
|
|
2020-10-21 12:51:59 +00:00
|
|
|
t.Run("isBlocked, internal method", func(t *testing.T) {
|
|
|
|
isBlocked := chain.contracts.Policy.IsBlockedInternal(chain.dao, random.Uint160())
|
|
|
|
require.Equal(t, false, isBlocked)
|
2020-06-15 18:13:32 +00:00
|
|
|
})
|
|
|
|
|
2020-10-21 12:51:59 +00:00
|
|
|
t.Run("isBlocked, contract method", func(t *testing.T) {
|
2020-11-19 10:00:46 +00:00
|
|
|
res, err := invokeContractMethod(chain, 100000000, policyHash, "isBlocked", random.Uint160())
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, err)
|
2020-10-21 12:51:59 +00:00
|
|
|
checkResult(t, res, stackitem.NewBool(false))
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, chain.persist())
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("block-unblock account", func(t *testing.T) {
|
2020-11-19 10:00:46 +00:00
|
|
|
res, err := invokeContractMethod(chain, 100000000, policyHash, "blockAccount", account.BytesBE())
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, err)
|
2020-07-31 12:48:35 +00:00
|
|
|
checkResult(t, res, stackitem.NewBool(true))
|
2020-06-15 18:13:32 +00:00
|
|
|
|
2020-10-21 12:51:59 +00:00
|
|
|
isBlocked := chain.contracts.Policy.IsBlockedInternal(chain.dao, account)
|
|
|
|
require.Equal(t, isBlocked, true)
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, chain.persist())
|
|
|
|
|
2020-11-19 10:00:46 +00:00
|
|
|
res, err = invokeContractMethod(chain, 100000000, policyHash, "unblockAccount", account.BytesBE())
|
2020-08-14 09:08:57 +00:00
|
|
|
require.NoError(t, err)
|
2020-07-31 12:48:35 +00:00
|
|
|
checkResult(t, res, stackitem.NewBool(true))
|
2020-06-15 18:13:32 +00:00
|
|
|
|
2020-10-21 12:51:59 +00:00
|
|
|
isBlocked = chain.contracts.Policy.IsBlockedInternal(chain.dao, account)
|
|
|
|
require.Equal(t, false, isBlocked)
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, chain.persist())
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("double-block", func(t *testing.T) {
|
|
|
|
// block
|
2020-11-19 10:00:46 +00:00
|
|
|
res, err := invokeContractMethod(chain, 100000000, policyHash, "blockAccount", account.BytesBE())
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, err)
|
2020-07-31 12:48:35 +00:00
|
|
|
checkResult(t, res, stackitem.NewBool(true))
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, chain.persist())
|
|
|
|
|
|
|
|
// double-block should fail
|
2020-11-19 10:00:46 +00:00
|
|
|
res, err = invokeContractMethod(chain, 100000000, policyHash, "blockAccount", account.BytesBE())
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, err)
|
2020-07-31 12:48:35 +00:00
|
|
|
checkResult(t, res, stackitem.NewBool(false))
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, chain.persist())
|
|
|
|
|
|
|
|
// unblock
|
2020-11-19 10:00:46 +00:00
|
|
|
res, err = invokeContractMethod(chain, 100000000, policyHash, "unblockAccount", account.BytesBE())
|
2020-08-14 09:08:57 +00:00
|
|
|
require.NoError(t, err)
|
2020-07-31 12:48:35 +00:00
|
|
|
checkResult(t, res, stackitem.NewBool(true))
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, chain.persist())
|
|
|
|
|
|
|
|
// unblock the same account should fail as we don't have it blocked
|
2020-11-19 10:00:46 +00:00
|
|
|
res, err = invokeContractMethod(chain, 100000000, policyHash, "unblockAccount", account.BytesBE())
|
2020-08-14 09:08:57 +00:00
|
|
|
require.NoError(t, err)
|
2020-07-31 12:48:35 +00:00
|
|
|
checkResult(t, res, stackitem.NewBool(false))
|
2020-06-15 18:13:32 +00:00
|
|
|
require.NoError(t, chain.persist())
|
|
|
|
})
|
2020-11-27 10:55:48 +00:00
|
|
|
|
|
|
|
t.Run("not signed by committee", func(t *testing.T) {
|
|
|
|
signer, err := wallet.NewAccount()
|
|
|
|
require.NoError(t, err)
|
|
|
|
invokeRes, err := invokeContractMethodBy(t, chain, signer, policyHash, "blockAccount", account.BytesBE())
|
|
|
|
checkResult(t, invokeRes, stackitem.NewBool(false))
|
|
|
|
})
|
2020-06-15 18:13:32 +00:00
|
|
|
}
|