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.
213 lines
9.9 KiB
213 lines
9.9 KiB
package vm
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"fmt"
|
|
"math/big"
|
|
"testing"
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
"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
|
|
}
|
|
|
|
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 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{})
|
|
// use required gas to avoid out of gas errors
|
|
p := &stakingPrecompile{}
|
|
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); 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 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)
|
|
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)
|
|
}
|
|
}
|
|
|
|
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",
|
|
//},
|
|
}
|
|
|