The core protocol of WoopChain
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
woop/core/vm/contracts_write_test.go

291 lines
14 KiB

package vm
import (
"bytes"
"errors"
"fmt"
"math/big"
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/harmony-one/harmony/core/state"
"github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/internal/params"
stakingTypes "github.com/harmony-one/harmony/staking/types"
)
type writeCapablePrecompileTest struct {
input, expected []byte
name string
expectedError error
p *WriteCapablePrecompiledContract
value *big.Int
}
func CollectRewardsFn() CollectRewardsFunc {
return func(db StateDB, rosettaTracer RosettaTracer, collectRewards *stakingTypes.CollectRewards) error {
return nil
}
}
func DelegateFn() DelegateFunc {
return func(db StateDB, rosettaTracer RosettaTracer, delegate *stakingTypes.Delegate) error {
return nil
}
}
func UndelegateFn() UndelegateFunc {
return func(db StateDB, rosettaTracer RosettaTracer, undelegate *stakingTypes.Undelegate) error {
return nil
}
}
func CreateValidatorFn() CreateValidatorFunc {
return func(db StateDB, rosettaTracer RosettaTracer, createValidator *stakingTypes.CreateValidator) error {
return nil
}
}
func EditValidatorFn() EditValidatorFunc {
return func(db StateDB, rosettaTracer RosettaTracer, editValidator *stakingTypes.EditValidator) error {
return nil
}
}
//func MigrateDelegationsFn() MigrateDelegationsFunc {
// return func(db StateDB, migrationMsg *stakingTypes.MigrationMsg) ([]interface{}, error) {
// return nil, nil
// }
//}
func CalculateMigrationGasFn() CalculateMigrationGasFunc {
return func(db StateDB, migrationMsg *stakingTypes.MigrationMsg, homestead bool, istanbul bool) (uint64, error) {
return 0, nil
}
}
func testWriteCapablePrecompile(test writeCapablePrecompileTest, t *testing.T, env *EVM, p WriteCapablePrecompiledContract) {
t.Run(fmt.Sprintf("%s", test.name), func(t *testing.T) {
contract := NewContract(AccountRef(common.HexToAddress("1337")), AccountRef(common.HexToAddress("1338")), new(big.Int), 0)
gas, err := p.RequiredGas(env, contract, test.input)
if err != nil {
t.Error(err)
}
contract.Gas = gas
if res, err := RunWriteCapablePrecompiledContract(p, env, contract, test.input, false, test.value); err != nil {
if test.expectedError != nil {
if test.expectedError.Error() != err.Error() {
t.Errorf("Expected error %v, got %v", test.expectedError, err)
}
} else {
t.Error(err)
}
} else {
if test.expectedError != nil {
t.Errorf("Expected an error %v but instead got result %v", test.expectedError, res)
}
if bytes.Compare(res, test.expected) != 0 {
t.Errorf("Expected %v, got %v", test.expected, res)
}
}
})
}
func testStakingPrecompile(test writeCapablePrecompileTest, t *testing.T) {
var env = NewEVM(Context{CollectRewards: CollectRewardsFn(),
Delegate: DelegateFn(),
Undelegate: UndelegateFn(),
CreateValidator: CreateValidatorFn(),
EditValidator: EditValidatorFn(),
ShardID: 0,
//MigrateDelegations: MigrateDelegationsFn(),
CalculateMigrationGas: CalculateMigrationGasFn(),
}, nil, params.TestChainConfig, Config{})
p := &stakingPrecompile{}
testWriteCapablePrecompile(test, t, env, p)
}
var StakingPrecompileTests = []writeCapablePrecompileTest{
{
input: []byte{109, 107, 47, 120},
expectedError: errors.New("no method with id: 0x6d6b2f78"),
name: "badStakingKind",
},
{
input: []byte{0, 0},
expectedError: errors.New("data too short (2 bytes) for abi method lookup"),
name: "malformedInput",
},
{
input: []byte{109, 107, 47, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 55},
expected: nil,
name: "collectRewardsSuccess",
},
{
input: []byte{109, 107, 47, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 56},
expectedError: errors.New("[StakingPrecompile] Address mismatch, expected 0x0000000000000000000000000000000000001337 have 0x0000000000000000000000000000000000001338"),
name: "collectRewardsAddressMismatch",
},
{
input: []byte{109, 107, 47, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19},
expectedError: errors.New("abi: cannot marshal in to go type: length insufficient 31 require 32"),
name: "collectRewardsInvalidABI",
},
{
input: []byte{81, 11, 17, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 107, 199, 94, 45, 99, 16, 0, 0},
expected: nil,
name: "delegateSuccess",
},
{
input: []byte{81, 11, 17, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 107, 199, 94, 45, 99, 16, 0},
expectedError: errors.New("abi: cannot marshal in to go type: length insufficient 95 require 96"),
name: "delegateInvalidABI",
},
{
input: []byte{81, 11, 17, 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 107, 199, 94, 45, 99, 16, 0, 0},
expectedError: errors.New("[StakingPrecompile] Address mismatch, expected 0x0000000000000000000000000000000000001337 have 0x0000000000000000000000000000000000001338"),
name: "delegateAddressMismatch",
},
{
input: []byte{189, 168, 192, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 107, 199, 94, 45, 99, 16, 0, 0},
expected: nil,
name: "undelegateSuccess",
},
{
input: []byte{189, 168, 192, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 107, 199, 94, 45, 99, 16, 0},
expectedError: errors.New("abi: cannot marshal in to go type: length insufficient 95 require 96"),
name: "undelegateInvalidABI",
},
{
input: []byte{189, 168, 192, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 107, 199, 94, 45, 99, 16, 0, 0},
expectedError: errors.New("[StakingPrecompile] Address mismatch, expected 0x0000000000000000000000000000000000001337 have 0x0000000000000000000000000000000000001338"),
name: "undelegateAddressMismatch",
},
{
input: []byte{189, 168, 192, 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 107, 199, 94, 45, 99, 16, 0, 0},
expectedError: errors.New("[StakingPrecompile] Address mismatch, expected 0x0000000000000000000000000000000000001337 have 0x0000000000000000000000000000000000001338"),
name: "undelegateAddressMismatch",
},
//{
// input: []byte{42, 5, 187, 113},
// expectedError: errors.New("abi: attempting to unmarshall an empty string while arguments are expected"),
// name: "yesMethodNoData",
//},
//{
// input: []byte{0, 0},
// expectedError: errors.New("data too short (2 bytes) for abi method lookup"),
// name: "malformedInput",
//},
//{
// input: []byte{42, 5, 187, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 56},
// expected: nil,
// name: "migrationSuccess",
//},
//{
// input: []byte{42, 5, 187, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 55},
// expectedError: errors.New("[StakingPrecompile] Address mismatch, expected 0x0000000000000000000000000000000000001337 have 0x0000000000000000000000000000000000001338"),
// name: "migrationAddressMismatch",
//},
//{
// input: []byte{42, 6, 187, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 55},
// expectedError: errors.New("no method with id: 0x2a06bb71"),
// name: "migrationNoMatchingMethod",
//},
//{
// input: []byte{42, 5, 187, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19},
// expectedError: errors.New("abi: cannot marshal in to go type: length insufficient 63 require 64"),
// name: "migrationAddressMismatch",
//},
}
func TestStakingPrecompiles(t *testing.T) {
for _, test := range StakingPrecompileTests {
testStakingPrecompile(test, t)
}
}
func TestWriteCapablePrecompilesReadOnly(t *testing.T) {
p := &stakingPrecompile{}
expectedError := errWriteProtection
res, err := RunWriteCapablePrecompiledContract(p, nil, nil, []byte{}, true, nil)
if err != nil {
if err.Error() != expectedError.Error() {
t.Errorf("Expected error %v, got %v", expectedError, err)
}
} else {
t.Errorf("Expected an error %v but instead got result %v", expectedError, res)
}
}
func transfer(db StateDB, sender, recipient common.Address, amount *big.Int, txType types.TransactionType) {
}
func testCrossShardXferPrecompile(test writeCapablePrecompileTest, t *testing.T) {
// this EVM needs stateDB, Transfer, and NumShards
var db ethdb.Database
var err error
defer func() {
if db != nil {
db.Close()
}
}()
if db, err = rawdb.NewLevelDBDatabase("/tmp/harmony_shard_0", 256, 1024, ""); err != nil {
db = nil
t.Fatalf("Could not initialize db %s", err)
}
stateCache := state.NewDatabase(db)
state, err := state.New(common.Hash{}, stateCache)
if err != nil {
t.Fatalf("Error while initializing state %s", err)
}
var env = NewEVM(Context{
NumShards: 4,
Transfer: transfer,
}, state, params.TestChainConfig, Config{})
p := &crossShardXferPrecompile{}
testWriteCapablePrecompile(test, t, env, p)
}
func TestCrossShardXferPrecompile(t *testing.T) {
for _, test := range CrossShardXferPrecompileTests {
testCrossShardXferPrecompile(test, t)
}
}
var CrossShardXferPrecompileTests = []writeCapablePrecompileTest{
{
input: []byte{40, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 107, 199, 94, 45, 99, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 36, 21, 19, 218, 159, 68, 99, 241, 212, 135, 75, 84, 141, 251, 172, 41, 217, 31, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
expected: nil,
name: "crossShardSuccess",
value: new(big.Int).Mul(big.NewInt(100), big.NewInt(1e18)),
},
{
input: []byte{40, 72, 8, 1},
expectedError: errors.New("no method with id: 0x28480801"),
name: "crossShardMethodSigFail",
},
{
input: []byte{40, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 107, 199, 94, 45, 99, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 36, 21, 19, 218, 159, 68, 99, 241, 212, 135, 75, 84, 141, 251, 172, 41, 217, 31, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
expectedError: errors.New("abi: cannot marshal in to go type: length insufficient 95 require 96"),
name: "crossShardMalformedInputFail",
},
{
input: []byte{40, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 107, 199, 94, 45, 99, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 36, 21, 19, 218, 159, 68, 99, 241, 212, 135, 75, 84, 141, 251, 172, 41, 217, 31, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6},
expectedError: errors.New("toShardId out of bounds"),
name: "crossShardOutOfBoundsFail",
},
{
input: []byte{40, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 107, 199, 94, 45, 99, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 36, 21, 19, 218, 159, 68, 99, 241, 212, 135, 75, 84, 141, 251, 172, 41, 217, 31, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
expectedError: errors.New("from and to shard id can't be equal"),
name: "crossShardSameShardFail",
},
{
input: []byte{40, 72, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 107, 199, 94, 45, 99, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 36, 21, 19, 218, 159, 68, 99, 241, 212, 135, 75, 84, 141, 251, 172, 41, 217, 31, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
expectedError: errors.New("argument value and msg.value not equal"),
name: "crossShardDiffValueFail",
value: new(big.Int).Mul(big.NewInt(1000), big.NewInt(1e18)),
},
}