github.com/datachainlab/burrow@v0.25.0/execution/evm/vm_test.go (about)

     1  // Copyright 2017 Monax Industries Limited
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package evm
    16  
    17  import (
    18  	"strconv"
    19  	"testing"
    20  	"time"
    21  
    22  	"fmt"
    23  
    24  	"github.com/hyperledger/burrow/acm/acmstate"
    25  
    26  	"github.com/hyperledger/burrow/acm"
    27  	"github.com/hyperledger/burrow/binary"
    28  	. "github.com/hyperledger/burrow/binary"
    29  	"github.com/hyperledger/burrow/crypto"
    30  	"github.com/hyperledger/burrow/execution/errors"
    31  	. "github.com/hyperledger/burrow/execution/evm/asm"
    32  	. "github.com/hyperledger/burrow/execution/evm/asm/bc"
    33  	"github.com/hyperledger/burrow/execution/exec"
    34  	"github.com/hyperledger/burrow/logging"
    35  	"github.com/hyperledger/burrow/permission"
    36  	"github.com/hyperledger/burrow/txs"
    37  	"github.com/stretchr/testify/assert"
    38  	"github.com/stretchr/testify/require"
    39  	hex "github.com/tmthrgd/go-hex"
    40  	"golang.org/x/crypto/ripemd160"
    41  )
    42  
    43  // Test output is a bit clearer if we /dev/null the logging, but can be re-enabled by uncommenting the below
    44  //var logger, _, _ = lifecycle.NewStdErrLogger()
    45  //
    46  var logger = logging.NewNoopLogger()
    47  
    48  type testState struct {
    49  	*State
    50  	BlockHashProvider func(blockNumber uint64) (Word256, error)
    51  }
    52  
    53  func NewTestState(st acmstate.ReaderWriter, blockHashGetter func(uint64) []byte) *testState {
    54  	evmState := NewState(st, blockHashGetter)
    55  	return &testState{
    56  		State:             evmState,
    57  		BlockHashProvider: evmState.GetBlockHash,
    58  	}
    59  }
    60  
    61  func newAppState() *FakeAppState {
    62  	fas := &FakeAppState{
    63  		accounts: make(map[crypto.Address]*acm.Account),
    64  		storage:  make(map[string]Word256),
    65  	}
    66  	// For default permissions
    67  	fas.accounts[acm.GlobalPermissionsAddress] = &acm.Account{
    68  		Permissions: permission.DefaultAccountPermissions,
    69  	}
    70  	return fas
    71  }
    72  
    73  func newParams() Params {
    74  	return Params{
    75  		BlockHeight: 0,
    76  		BlockTime:   0,
    77  		GasLimit:    0,
    78  	}
    79  }
    80  
    81  func newAddress(name string) crypto.Address {
    82  	hasher := ripemd160.New()
    83  	hasher.Write([]byte(name))
    84  	return crypto.MustAddressFromBytes(hasher.Sum(nil))
    85  }
    86  
    87  func newAccount(st Interface, name string) crypto.Address {
    88  	address := newAddress(name)
    89  	st.CreateAccount(address)
    90  	return address
    91  }
    92  
    93  func makeAccountWithCode(st Interface, name string, code []byte) crypto.Address {
    94  	address := newAddress(name)
    95  	st.CreateAccount(address)
    96  	st.InitCode(address, code)
    97  	st.AddToBalance(address, 9999999)
    98  	return address
    99  }
   100  
   101  // Runs a basic loop
   102  func TestVM(t *testing.T) {
   103  	cache := NewState(newAppState(), blockHashGetter)
   104  	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
   105  
   106  	// Create accounts
   107  	account1 := newAccount(cache, "1")
   108  	account2 := newAccount(cache, "101")
   109  
   110  	var gas uint64 = 100000
   111  
   112  	bytecode := MustSplice(PUSH1, 0x00, PUSH1, 0x20, MSTORE, JUMPDEST, PUSH2, 0x0F, 0x0F, PUSH1, 0x20, MLOAD,
   113  		SLT, ISZERO, PUSH1, 0x1D, JUMPI, PUSH1, 0x01, PUSH1, 0x20, MLOAD, ADD, PUSH1, 0x20,
   114  		MSTORE, PUSH1, 0x05, JUMP, JUMPDEST)
   115  
   116  	start := time.Now()
   117  	output, err := ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   118  	t.Logf("Output: %v Error: %v\n", output, err)
   119  	t.Logf("Call took: %v", time.Since(start))
   120  	require.NoError(t, err)
   121  	require.NoError(t, cache.Error())
   122  }
   123  
   124  func TestSHL(t *testing.T) {
   125  	cache := NewState(newAppState(), blockHashGetter)
   126  	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
   127  	account1 := newAccount(cache, "1")
   128  	account2 := newAccount(cache, "101")
   129  
   130  	var gas uint64 = 100000
   131  
   132  	//Shift left 0
   133  	bytecode := MustSplice(PUSH1, 0x01, PUSH1, 0x00, SHL, return1())
   134  	output, err := ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   135  	value := []uint8([]byte{0x1})
   136  	expected := LeftPadBytes(value, 32)
   137  	assert.Equal(t, expected, output)
   138  
   139  	t.Logf("Result: %v == %v\n", output, expected)
   140  
   141  	if err != nil {
   142  		t.Fatal(err)
   143  	}
   144  
   145  	//Alternative shift left 0
   146  	bytecode = MustSplice(PUSH32, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   147  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, PUSH1, 0x00, SHL, return1())
   148  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   149  	expected = []uint8([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   150  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF})
   151  
   152  	assert.Equal(t, expected, output)
   153  
   154  	t.Logf("Result: %v == %v\n", output, expected)
   155  
   156  	if err != nil {
   157  		t.Fatal(err)
   158  	}
   159  
   160  	//Shift left 1
   161  	bytecode = MustSplice(PUSH1, 0x01, PUSH1, 0x01, SHL, return1())
   162  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   163  	value = []uint8([]byte{0x2})
   164  	expected = LeftPadBytes(value, 32)
   165  	assert.Equal(t, expected, output)
   166  
   167  	t.Logf("Result: %v == %v\n", output, expected)
   168  
   169  	if err != nil {
   170  		t.Fatal(err)
   171  	}
   172  
   173  	//Alternative shift left 1
   174  	bytecode = MustSplice(PUSH32, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   175  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, PUSH1, 0x01, SHL, return1())
   176  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   177  	expected = []uint8([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   178  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE})
   179  
   180  	assert.Equal(t, expected, output)
   181  
   182  	t.Logf("Result: %v == %v\n", output, expected)
   183  
   184  	if err != nil {
   185  		t.Fatal(err)
   186  	}
   187  
   188  	//Alternative shift left 1
   189  	bytecode = MustSplice(PUSH32, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   190  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, PUSH1, 0x01, SHL, return1())
   191  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   192  	expected = []uint8([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   193  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE})
   194  
   195  	assert.Equal(t, expected, output)
   196  
   197  	t.Logf("Result: %v == %v\n", output, expected)
   198  
   199  	if err != nil {
   200  		t.Fatal(err)
   201  	}
   202  
   203  	//Shift left 255
   204  	bytecode = MustSplice(PUSH1, 0x01, PUSH1, 0xFF, SHL, return1())
   205  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   206  	value = []uint8([]byte{0x80})
   207  	expected = RightPadBytes(value, 32)
   208  	assert.Equal(t, expected, output)
   209  
   210  	t.Logf("Result: %v == %v\n", output, expected)
   211  
   212  	if err != nil {
   213  		t.Fatal(err)
   214  	}
   215  
   216  	//Alternative shift left 255
   217  	bytecode = MustSplice(PUSH32, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   218  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, PUSH1, 0xFF, SHL, return1())
   219  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   220  	value = []uint8([]byte{0x80})
   221  	expected = RightPadBytes(value, 32)
   222  	assert.Equal(t, expected, output)
   223  
   224  	t.Logf("Result: %v == %v\n", output, expected)
   225  
   226  	if err != nil {
   227  		t.Fatal(err)
   228  	}
   229  
   230  	//Shift left 256 (overflow)
   231  	bytecode = MustSplice(PUSH1, 0x01, PUSH2, 0x01, 0x00, SHL, return1())
   232  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   233  	value = []uint8([]byte{0x00})
   234  	expected = LeftPadBytes(value, 32)
   235  	assert.Equal(t, expected, output)
   236  
   237  	t.Logf("Result: %v == %v\n", output, expected)
   238  
   239  	if err != nil {
   240  		t.Fatal(err)
   241  	}
   242  
   243  	//Alternative shift left 256 (overflow)
   244  	bytecode = MustSplice(PUSH32, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   245  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, PUSH2, 0x01, 0x00, SHL,
   246  		return1())
   247  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   248  	value = []uint8([]byte{0x00})
   249  	expected = LeftPadBytes(value, 32)
   250  	assert.Equal(t, expected, output)
   251  
   252  	t.Logf("Result: %v == %v\n", output, expected)
   253  
   254  	if err != nil {
   255  		t.Fatal(err)
   256  	}
   257  
   258  	//Shift left 257 (overflow)
   259  	bytecode = MustSplice(PUSH1, 0x01, PUSH2, 0x01, 0x01, SHL, return1())
   260  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   261  	value = []uint8([]byte{0x00})
   262  	expected = LeftPadBytes(value, 32)
   263  	assert.Equal(t, expected, output)
   264  
   265  	t.Logf("Result: %v == %v\n", output, expected)
   266  
   267  	if err != nil {
   268  		t.Fatal(err)
   269  	}
   270  
   271  	require.NoError(t, cache.Error())
   272  }
   273  
   274  func TestSHR(t *testing.T) {
   275  	cache := NewState(newAppState(), blockHashGetter)
   276  	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
   277  	account1 := newAccount(cache, "1")
   278  	account2 := newAccount(cache, "101")
   279  
   280  	var gas uint64 = 100000
   281  
   282  	//Shift right 0
   283  	bytecode := MustSplice(PUSH1, 0x01, PUSH1, 0x00, SHR, return1())
   284  	output, err := ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   285  	value := []uint8([]byte{0x1})
   286  	expected := LeftPadBytes(value, 32)
   287  	assert.Equal(t, expected, output)
   288  
   289  	t.Logf("Result: %v == %v\n", output, expected)
   290  
   291  	if err != nil {
   292  		t.Fatal(err)
   293  	}
   294  
   295  	//Alternative shift right 0
   296  	bytecode = MustSplice(PUSH32, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   297  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, PUSH1, 0x00, SHR, return1())
   298  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   299  	expected = []uint8([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   300  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF})
   301  
   302  	assert.Equal(t, expected, output)
   303  
   304  	t.Logf("Result: %v == %v\n", output, expected)
   305  
   306  	if err != nil {
   307  		t.Fatal(err)
   308  	}
   309  
   310  	//Shift right 1
   311  	bytecode = MustSplice(PUSH1, 0x01, PUSH1, 0x01, SHR, return1())
   312  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   313  	value = []uint8([]byte{0x00})
   314  	expected = LeftPadBytes(value, 32)
   315  	assert.Equal(t, expected, output)
   316  
   317  	t.Logf("Result: %v == %v\n", output, expected)
   318  
   319  	if err != nil {
   320  		t.Fatal(err)
   321  	}
   322  
   323  	//Alternative shift right 1
   324  	bytecode = MustSplice(PUSH32, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   325  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, PUSH1, 0x01, SHR, return1())
   326  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   327  	value = []uint8([]byte{0x40})
   328  	expected = RightPadBytes(value, 32)
   329  	assert.Equal(t, expected, output)
   330  
   331  	t.Logf("Result: %v == %v\n", output, expected)
   332  
   333  	if err != nil {
   334  		t.Fatal(err)
   335  	}
   336  
   337  	//Alternative shift right 1
   338  	bytecode = MustSplice(PUSH32, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   339  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, PUSH1, 0x01, SHR, return1())
   340  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   341  	expected = []uint8([]byte{0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   342  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF})
   343  
   344  	assert.Equal(t, expected, output)
   345  
   346  	t.Logf("Result: %v == %v\n", output, expected)
   347  
   348  	if err != nil {
   349  		t.Fatal(err)
   350  	}
   351  
   352  	//Shift right 255
   353  	bytecode = MustSplice(PUSH32, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   354  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, PUSH1, 0xFF, SHR, return1())
   355  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   356  	value = []uint8([]byte{0x1})
   357  	expected = LeftPadBytes(value, 32)
   358  	assert.Equal(t, expected, output)
   359  
   360  	t.Logf("Result: %v == %v\n", output, expected)
   361  
   362  	if err != nil {
   363  		t.Fatal(err)
   364  	}
   365  
   366  	//Alternative shift right 255
   367  	bytecode = MustSplice(PUSH32, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   368  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, PUSH1, 0xFF, SHR, return1())
   369  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   370  	value = []uint8([]byte{0x1})
   371  	expected = LeftPadBytes(value, 32)
   372  	assert.Equal(t, expected, output)
   373  
   374  	t.Logf("Result: %v == %v\n", output, expected)
   375  
   376  	if err != nil {
   377  		t.Fatal(err)
   378  	}
   379  
   380  	//Shift right 256 (underflow)
   381  	bytecode = MustSplice(PUSH32, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   382  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, PUSH2, 0x01, 0x00, SHR,
   383  		return1())
   384  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   385  	value = []uint8([]byte{0x00})
   386  	expected = LeftPadBytes(value, 32)
   387  	assert.Equal(t, expected, output)
   388  
   389  	t.Logf("Result: %v == %v\n", output, expected)
   390  
   391  	if err != nil {
   392  		t.Fatal(err)
   393  	}
   394  
   395  	//Alternative shift right 256 (underflow)
   396  	bytecode = MustSplice(PUSH32, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   397  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, PUSH2, 0x01, 0x00, SHR,
   398  		return1())
   399  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   400  	value = []uint8([]byte{0x00})
   401  	expected = LeftPadBytes(value, 32)
   402  	assert.Equal(t, expected, output)
   403  
   404  	t.Logf("Result: %v == %v\n", output, expected)
   405  
   406  	if err != nil {
   407  		t.Fatal(err)
   408  	}
   409  
   410  	//Shift right 257 (underflow)
   411  	bytecode = MustSplice(PUSH32, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   412  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, PUSH2, 0x01, 0x01, SHR,
   413  		return1())
   414  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   415  	value = []uint8([]byte{0x00})
   416  	expected = LeftPadBytes(value, 32)
   417  	assert.Equal(t, expected, output)
   418  
   419  	t.Logf("Result: %v == %v\n", output, expected)
   420  
   421  	if err != nil {
   422  		t.Fatal(err)
   423  	}
   424  
   425  	require.NoError(t, cache.Error())
   426  }
   427  
   428  func TestSAR(t *testing.T) {
   429  	cache := NewState(newAppState(), blockHashGetter)
   430  	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
   431  	account1 := newAccount(cache, "1")
   432  	account2 := newAccount(cache, "101")
   433  
   434  	var gas uint64 = 100000
   435  
   436  	//Shift arith right 0
   437  	bytecode := MustSplice(PUSH1, 0x01, PUSH1, 0x00, SAR, return1())
   438  	output, err := ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   439  	value := []uint8([]byte{0x1})
   440  	expected := LeftPadBytes(value, 32)
   441  	assert.Equal(t, expected, output)
   442  
   443  	t.Logf("Result: %v == %v\n", output, expected)
   444  
   445  	if err != nil {
   446  		t.Fatal(err)
   447  	}
   448  
   449  	//Alternative arith shift right 0
   450  	bytecode = MustSplice(PUSH32, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   451  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, PUSH1, 0x00, SAR, return1())
   452  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   453  	expected = []uint8([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   454  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF})
   455  
   456  	assert.Equal(t, expected, output)
   457  
   458  	t.Logf("Result: %v == %v\n", output, expected)
   459  
   460  	if err != nil {
   461  		t.Fatal(err)
   462  	}
   463  
   464  	//Shift arith right 1
   465  	bytecode = MustSplice(PUSH1, 0x01, PUSH1, 0x01, SAR, return1())
   466  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   467  	value = []uint8([]byte{0x00})
   468  	expected = LeftPadBytes(value, 32)
   469  	assert.Equal(t, expected, output)
   470  
   471  	t.Logf("Result: %v == %v\n", output, expected)
   472  
   473  	if err != nil {
   474  		t.Fatal(err)
   475  	}
   476  
   477  	//Alternative shift arith right 1
   478  	bytecode = MustSplice(PUSH32, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   479  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, PUSH1, 0x01, SAR, return1())
   480  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   481  	value = []uint8([]byte{0xc0})
   482  	expected = RightPadBytes(value, 32)
   483  	assert.Equal(t, expected, output)
   484  
   485  	t.Logf("Result: %v == %v\n", output, expected)
   486  
   487  	if err != nil {
   488  		t.Fatal(err)
   489  	}
   490  
   491  	//Alternative shift arith right 1
   492  	bytecode = MustSplice(PUSH32, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   493  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, PUSH1, 0x01, SAR, return1())
   494  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   495  	expected = []uint8([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   496  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF})
   497  
   498  	assert.Equal(t, expected, output)
   499  
   500  	t.Logf("Result: %v == %v\n", output, expected)
   501  
   502  	if err != nil {
   503  		t.Fatal(err)
   504  	}
   505  
   506  	//Shift arith right 255
   507  	bytecode = MustSplice(PUSH32, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   508  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, PUSH1, 0xFF, SAR, return1())
   509  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   510  	expected = []uint8([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   511  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF})
   512  
   513  	assert.Equal(t, expected, output)
   514  
   515  	t.Logf("Result: %v == %v\n", output, expected)
   516  
   517  	if err != nil {
   518  		t.Fatal(err)
   519  	}
   520  
   521  	//Alternative shift arith right 255
   522  	bytecode = MustSplice(PUSH32, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   523  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, PUSH1, 0xFF, SAR, return1())
   524  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   525  	expected = []uint8([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   526  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF})
   527  
   528  	assert.Equal(t, expected, output)
   529  
   530  	t.Logf("Result: %v == %v\n", output, expected)
   531  
   532  	if err != nil {
   533  		t.Fatal(err)
   534  	}
   535  
   536  	//Alternative shift arith right 255
   537  	bytecode = MustSplice(PUSH32, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   538  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, PUSH1, 0xFF, SAR, return1())
   539  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   540  	value = []uint8([]byte{0x00})
   541  	expected = RightPadBytes(value, 32)
   542  	assert.Equal(t, expected, output)
   543  
   544  	t.Logf("Result: %v == %v\n", output, expected)
   545  
   546  	if err != nil {
   547  		t.Fatal(err)
   548  	}
   549  
   550  	//Shift arith right 256 (reset)
   551  	bytecode = MustSplice(PUSH32, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   552  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, PUSH2, 0x01, 0x00, SAR,
   553  		return1())
   554  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   555  	expected = []uint8([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   556  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF})
   557  
   558  	assert.Equal(t, expected, output)
   559  
   560  	t.Logf("Result: %v == %v\n", output, expected)
   561  
   562  	if err != nil {
   563  		t.Fatal(err)
   564  	}
   565  
   566  	//Alternative shift arith right 256 (reset)
   567  	bytecode = MustSplice(PUSH32, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   568  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, PUSH2, 0x01, 0x00, SAR,
   569  		return1())
   570  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   571  	value = []uint8([]byte{0x00})
   572  	expected = LeftPadBytes(value, 32)
   573  	assert.Equal(t, expected, output)
   574  
   575  	t.Logf("Result: %v == %v\n", output, expected)
   576  
   577  	if err != nil {
   578  		t.Fatal(err)
   579  	}
   580  
   581  	//Shift arith right 257 (reset)
   582  	bytecode = MustSplice(PUSH32, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   583  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, PUSH2, 0x01, 0x01, SAR,
   584  		return1())
   585  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   586  	expected = []uint8([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   587  		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF})
   588  
   589  	assert.Equal(t, expected, output)
   590  
   591  	t.Logf("Result: %v == %v\n", output, expected)
   592  
   593  	if err != nil {
   594  		t.Fatal(err)
   595  	}
   596  
   597  	require.NoError(t, cache.Error())
   598  }
   599  
   600  //Test attempt to jump to bad destination (position 16)
   601  func TestJumpErr(t *testing.T) {
   602  	cache := NewState(newAppState(), blockHashGetter)
   603  	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
   604  
   605  	// Create accounts
   606  	account1 := newAccount(cache, "1")
   607  	account2 := newAccount(cache, "2")
   608  
   609  	var gas uint64 = 100000
   610  
   611  	bytecode := MustSplice(PUSH1, 0x10, JUMP)
   612  
   613  	var err error
   614  	ch := make(chan struct{})
   615  	go func() {
   616  		_, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   617  		ch <- struct{}{}
   618  	}()
   619  	tick := time.NewTicker(time.Second * 2)
   620  	select {
   621  	case <-tick.C:
   622  		t.Fatal("VM ended up in an infinite loop from bad jump dest (it took too long!)")
   623  	case <-ch:
   624  		if err == nil {
   625  			t.Fatal("Expected invalid jump dest err")
   626  		}
   627  	}
   628  }
   629  
   630  // Tests the code for a subcurrency contract compiled by serpent
   631  func TestSubcurrency(t *testing.T) {
   632  	st := newAppState()
   633  	cache := NewState(st, blockHashGetter)
   634  	// Create accounts
   635  	account1 := newAccount(cache, "1, 2, 3")
   636  	account2 := newAccount(cache, "3, 2, 1")
   637  	cache.Sync()
   638  
   639  	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
   640  
   641  	var gas uint64 = 1000
   642  
   643  	bytecode := MustSplice(PUSH3, 0x0F, 0x42, 0x40, CALLER, SSTORE, PUSH29, 0x01, 0x00, 0x00, 0x00,
   644  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   645  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, PUSH1,
   646  		0x00, CALLDATALOAD, DIV, PUSH4, 0x15, 0xCF, 0x26, 0x84, DUP2, EQ, ISZERO, PUSH2,
   647  		0x00, 0x46, JUMPI, PUSH1, 0x04, CALLDATALOAD, PUSH1, 0x40, MSTORE, PUSH1, 0x40,
   648  		MLOAD, SLOAD, PUSH1, 0x60, MSTORE, PUSH1, 0x20, PUSH1, 0x60, RETURN, JUMPDEST,
   649  		PUSH4, 0x69, 0x32, 0x00, 0xCE, DUP2, EQ, ISZERO, PUSH2, 0x00, 0x87, JUMPI, PUSH1,
   650  		0x04, CALLDATALOAD, PUSH1, 0x80, MSTORE, PUSH1, 0x24, CALLDATALOAD, PUSH1, 0xA0,
   651  		MSTORE, CALLER, SLOAD, PUSH1, 0xC0, MSTORE, CALLER, PUSH1, 0xE0, MSTORE, PUSH1,
   652  		0xA0, MLOAD, PUSH1, 0xC0, MLOAD, SLT, ISZERO, ISZERO, PUSH2, 0x00, 0x86, JUMPI,
   653  		PUSH1, 0xA0, MLOAD, PUSH1, 0xC0, MLOAD, SUB, PUSH1, 0xE0, MLOAD, SSTORE, PUSH1,
   654  		0xA0, MLOAD, PUSH1, 0x80, MLOAD, SLOAD, ADD, PUSH1, 0x80, MLOAD, SSTORE, JUMPDEST,
   655  		JUMPDEST, POP, JUMPDEST, PUSH1, 0x00, PUSH1, 0x00, RETURN)
   656  
   657  	data := hex.MustDecodeString("693200CE0000000000000000000000004B4363CDE27C2EB05E66357DB05BC5C88F850C1A0000000000000000000000000000000000000000000000000000000000000005")
   658  	output, err := ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, data, 0, &gas)
   659  	t.Logf("Output: %v Error: %v\n", output, err)
   660  	if err != nil {
   661  		t.Fatal(err)
   662  	}
   663  	require.NoError(t, cache.Error())
   664  }
   665  
   666  //This test case is taken from EIP-140 (https://github.com/ethereum/EIPs/blob/master/EIPS/eip-140.md);
   667  //it is meant to test the implementation of the REVERT opcode
   668  func TestRevert(t *testing.T) {
   669  	cache := NewState(newAppState(), blockHashGetter)
   670  	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
   671  
   672  	// Create accounts
   673  	account1 := newAccount(cache, "1")
   674  	account2 := newAccount(cache, "1, 0, 1")
   675  
   676  	key, value := []byte{0x00}, []byte{0x00}
   677  	cache.SetStorage(account1, LeftPadWord256(key), LeftPadWord256(value))
   678  
   679  	var gas uint64 = 100000
   680  
   681  	bytecode := MustSplice(PUSH13, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x20, 0x64, 0x61, 0x74, 0x61,
   682  		PUSH1, 0x00, SSTORE, PUSH32, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x20, 0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
   683  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   684  		PUSH1, 0x00, MSTORE, PUSH1, 0x0E, PUSH1, 0x00, REVERT)
   685  
   686  	/*bytecode := MustSplice(PUSH32, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x20, 0x6D, 0x65, 0x73, 0x73, 0x61,
   687  	0x67, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   688  	0x00, 0x00, 0x00, PUSH1, 0x00, MSTORE, PUSH1, 0x0E, PUSH1, 0x00, REVERT)*/
   689  
   690  	output, cErr := ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
   691  	assert.Error(t, cErr, "Expected execution reverted error")
   692  
   693  	storageVal := cache.GetStorage(account1, LeftPadWord256(key))
   694  	assert.Equal(t, LeftPadWord256(value), storageVal)
   695  
   696  	t.Logf("Output: %v\n", output)
   697  }
   698  
   699  // Test sending tokens from a contract to another account
   700  func TestSendCall(t *testing.T) {
   701  	cache := NewState(newAppState(), blockHashGetter)
   702  	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
   703  
   704  	// Create accounts
   705  	account1 := newAccount(cache, "1")
   706  	account2 := newAccount(cache, "2")
   707  	account3 := newAccount(cache, "3")
   708  	cache.Sync()
   709  
   710  	// account1 will call account2 which will trigger CALL opcode to account3
   711  	addr := account3
   712  	contractCode := callContractCode(addr)
   713  
   714  	//----------------------------------------------
   715  	// account2 has insufficient balance, should fail
   716  	txe := runVM(cache, ourVm, account1, account2, contractCode, 100000)
   717  	exCalls := txe.ExceptionalCalls()
   718  	require.Len(t, exCalls, 1)
   719  	assertErrorCode(t, errors.ErrorCodeInsufficientBalance, exCalls[0].Header.Exception)
   720  
   721  	//----------------------------------------------
   722  	// give account2 sufficient balance, should pass
   723  	cache.AddToBalance(account2, 100000)
   724  	txe = runVM(cache, ourVm, account1, account2, contractCode, 1000)
   725  	assert.Nil(t, txe.Exception, "Should have sufficient balance")
   726  
   727  	//----------------------------------------------
   728  	// insufficient gas, should fail
   729  	txe = runVM(cache, ourVm, account1, account2, contractCode, 100)
   730  	assert.NotNil(t, txe.Exception, "Expected insufficient gas error")
   731  }
   732  
   733  // Test to ensure that contracts called with STATICCALL cannot modify state
   734  // as per https://github.com/ethereum/EIPs/blob/master/EIPS/eip-214.md
   735  func TestStaticCallReadOnly(t *testing.T) {
   736  	gas1, gas2 := byte(0x1), byte(0x1)
   737  	value := byte(0x69)
   738  	var inOff, inSize, retOff, retSize byte
   739  
   740  	logDefault := MustSplice(PUSH1, inSize, PUSH1, inOff)
   741  	testRecipient := newAddress("1")
   742  	// check all illegal state modifications in child staticcall frame
   743  	for _, illegalContractCode := range []acm.Bytecode{
   744  		MustSplice(PUSH9, "arbitrary", PUSH1, 0x00, SSTORE),
   745  		MustSplice(logDefault, LOG0),
   746  		MustSplice(logDefault, PUSH1, 0x1, LOG1),
   747  		MustSplice(logDefault, PUSH1, 0x1, PUSH1, 0x1, LOG2),
   748  		MustSplice(logDefault, PUSH1, 0x1, PUSH1, 0x1, PUSH1, 0x1, LOG3),
   749  		MustSplice(logDefault, PUSH1, 0x1, PUSH1, 0x1, PUSH1, 0x1, PUSH1, 0x1, LOG4),
   750  		MustSplice(PUSH1, 0x0, PUSH1, 0x0, PUSH1, 0x69, CREATE),
   751  		MustSplice(PUSH20, testRecipient, SELFDESTRUCT),
   752  	} {
   753  		// TODO: CREATE2
   754  
   755  		t.Logf("Testing state-modifying bytecode: %v", illegalContractCode.MustTokens())
   756  		cache := NewState(newAppState(), blockHashGetter)
   757  		ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger, DebugOpcodes)
   758  		callee := makeAccountWithCode(cache, "callee", MustSplice(illegalContractCode, PUSH1, 0x1, return1()))
   759  
   760  		// equivalent to CALL, but enforce state immutability for children
   761  		caller := makeAccountWithCode(cache, "caller",
   762  			MustSplice(PUSH1, retSize, PUSH1, retOff, PUSH1, inSize, PUSH1, inOff,
   763  				PUSH1, value, PUSH20, callee, PUSH2, gas1, gas2, STATICCALL, PUSH1, retSize,
   764  				PUSH1, retOff, RETURN))
   765  
   766  		txe := runVM(cache, ourVm, caller, callee, cache.GetCode(caller), 1000)
   767  		// the topmost caller can never *illegally* modify state
   768  		require.Error(t, txe.Exception)
   769  		assertErrorCode(t, errors.ErrorCodeIllegalWrite, txe.Exception,
   770  			"should get an error from child accounts that cache is read only")
   771  	}
   772  }
   773  
   774  func TestStaticCallWithValue(t *testing.T) {
   775  	gas1, gas2 := byte(0x1), byte(0x1)
   776  	value := byte(0x69)
   777  	var inOff, inSize, retOff, retSize byte
   778  
   779  	cache := NewState(newAppState(), blockHashGetter)
   780  	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
   781  
   782  	finalAddress := makeAccountWithCode(cache, "final", MustSplice(PUSH1, int64(20), return1()))
   783  
   784  	// intermediate account CALLs another contract *with* a value
   785  	callee := makeAccountWithCode(cache, "callee", MustSplice(PUSH1, retSize, PUSH1, retOff, PUSH1, inSize, PUSH1,
   786  		inOff, PUSH1, value, PUSH20, finalAddress, PUSH2, gas1, gas2, CALL, returnWord()))
   787  
   788  	caller := makeAccountWithCode(cache, "caller",
   789  		MustSplice(PUSH1, retSize, PUSH1, retOff, PUSH1, inSize, PUSH1,
   790  			inOff, PUSH1, value, PUSH20, callee, PUSH2, gas1, gas2, STATICCALL, PUSH1, retSize,
   791  			PUSH1, retOff, RETURN))
   792  
   793  	cache.AddToBalance(callee, 100000)
   794  	txe := runVM(cache, ourVm, caller, callee, cache.GetCode(caller), 1000)
   795  	require.NotNil(t, txe.Exception)
   796  	assertErrorCode(t, errors.ErrorCodeIllegalWrite, txe.Exception, "expected static call violation because of call with value")
   797  }
   798  
   799  func TestStaticCallNoValue(t *testing.T) {
   800  	gas1, gas2 := byte(0x1), byte(0x1)
   801  	value := byte(0x69)
   802  	var inOff, inSize, retOff, retSize byte
   803  
   804  	// this final test just checks that STATICCALL actually works
   805  	cache := NewState(newAppState(), blockHashGetter)
   806  	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
   807  
   808  	finalAddress := makeAccountWithCode(cache, "final", MustSplice(PUSH1, int64(20), return1()))
   809  	// intermediate account CALLs another contract *without* a value
   810  	callee := makeAccountWithCode(cache, "callee", MustSplice(PUSH1, retSize, PUSH1, retOff, PUSH1, inSize, PUSH1,
   811  		inOff, PUSH1, 0x00, PUSH20, finalAddress, PUSH2, gas1, gas2, CALL, returnWord()))
   812  
   813  	caller := makeAccountWithCode(cache, "caller",
   814  		MustSplice(PUSH1, retSize, PUSH1, retOff, PUSH1, inSize, PUSH1,
   815  			inOff, PUSH1, value, PUSH20, callee, PUSH2, gas1, gas2, STATICCALL, PUSH1, retSize,
   816  			PUSH1, retOff, RETURN))
   817  
   818  	cache.AddToBalance(callee, 100000)
   819  	txe := runVM(cache, ourVm, caller, callee, cache.GetCode(caller), 1000)
   820  	// no exceptions expected because value never set in children
   821  	require.NoError(t, txe.Exception.AsError())
   822  	exCalls := txe.ExceptionalCalls()
   823  	require.Len(t, exCalls, 0)
   824  }
   825  
   826  // Test evm account creation
   827  func TestCreate(t *testing.T) {
   828  	st := newAppState()
   829  	cache := NewState(st, blockHashGetter)
   830  	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
   831  
   832  	callee := makeAccountWithCode(cache, "callee", MustSplice(PUSH1, 0x0, PUSH1, 0x0, PUSH1, 0x0, CREATE, PUSH1, 0, MSTORE, PUSH1, 20, PUSH1, 12, RETURN))
   833  	// ensure pre-generated address has same sequence number
   834  	nonce := make([]byte, txs.HashLength+uint64Length)
   835  	copy(nonce, ourVm.nonce)
   836  	PutUint64BE(nonce[txs.HashLength:], ourVm.sequence+1)
   837  	addr := crypto.NewContractAddress(callee, nonce)
   838  
   839  	var gas uint64 = 100000
   840  	caller := newAccount(cache, "1, 2, 3")
   841  	output, err := ourVm.Call(cache, NewNoopEventSink(), caller, callee, cache.GetCode(callee), []byte{}, 0, &gas)
   842  	assert.NoError(t, err, "Should return new address without error")
   843  	assert.Equal(t, addr.Bytes(), output, "Addresses should be equal")
   844  }
   845  
   846  // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1014.md
   847  func TestCreate2(t *testing.T) {
   848  	st := newAppState()
   849  	cache := NewState(st, blockHashGetter)
   850  	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
   851  
   852  	// salt of 0s
   853  	var salt [32]byte
   854  	callee := makeAccountWithCode(cache, "callee", MustSplice(PUSH1, 0x0, PUSH1, 0x0, PUSH1, 0x0, PUSH32, salt[:], CREATE2, PUSH1, 0, MSTORE, PUSH1, 20, PUSH1, 12, RETURN))
   855  	addr := crypto.NewContractAddress2(callee, salt, cache.GetCode(callee))
   856  
   857  	var gas uint64 = 100000
   858  	caller := newAccount(cache, "1, 2, 3")
   859  	output, err := ourVm.Call(cache, NewNoopEventSink(), caller, callee, cache.GetCode(callee), []byte{}, 0, &gas)
   860  	assert.NoError(t, err, "Should return new address without error")
   861  	assert.Equal(t, addr.Bytes(), output, "Returned value not equal to create2 address")
   862  }
   863  
   864  // This test was introduced to cover an issues exposed in our handling of the
   865  // gas limit passed from caller to callee on various forms of CALL.
   866  // The idea of this test is to implement a simple DelegateCall in EVM code
   867  // We first run the DELEGATECALL with _just_ enough gas expecting a simple return,
   868  // and then run it with 1 gas unit less, expecting a failure
   869  func TestDelegateCallGas(t *testing.T) {
   870  	cache := NewState(newAppState(), blockHashGetter)
   871  	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
   872  
   873  	inOff := 0
   874  	inSize := 0 // no call data
   875  	retOff := 0
   876  	retSize := 32
   877  	calleeReturnValue := int64(20)
   878  
   879  	callee := makeAccountWithCode(cache, "callee",
   880  		MustSplice(PUSH1, calleeReturnValue, PUSH1, 0, MSTORE, PUSH1, 32, PUSH1, 0, RETURN))
   881  
   882  	// 6 op codes total
   883  	baseOpsCost := GasBaseOp * 6
   884  	// 4 pushes
   885  	pushCost := GasStackOp * 4
   886  	// 2 pushes 2 pops
   887  	returnCost := GasStackOp * 4
   888  	// To push success/failure
   889  	resumeCost := GasStackOp
   890  
   891  	// Gas is not allowed to drop to 0 so we add resumecost
   892  	delegateCallCost := baseOpsCost + pushCost + returnCost + resumeCost
   893  
   894  	// Here we split up the caller code so we can make a DELEGATE call with
   895  	// different amounts of gas. The value we sandwich in the middle is the amount
   896  	// we subtract from the available gas (that the caller has available), so:
   897  	// code := MustSplice(callerCodePrefix, <amount to subtract from GAS> , callerCodeSuffix)
   898  	// gives us the code to make the call
   899  	callerCodePrefix := MustSplice(PUSH1, retSize, PUSH1, retOff, PUSH1, inSize,
   900  		PUSH1, inOff, PUSH20, callee, PUSH1)
   901  	callerCodeSuffix := MustSplice(DELEGATECALL, returnWord())
   902  
   903  	// Perform a delegate call
   904  	caller := makeAccountWithCode(cache, "caller", MustSplice(callerCodePrefix,
   905  		// Give just enough gas to make the DELEGATECALL
   906  		delegateCallCost, callerCodeSuffix))
   907  
   908  	// Should pass
   909  	txe := runVM(cache, ourVm, caller, callee, cache.GetCode(caller), 100)
   910  	assert.Nil(t, txe.Exception, "Should have sufficient funds for call")
   911  	assert.Equal(t, Int64ToWord256(calleeReturnValue).Bytes(), txe.Result.Return)
   912  
   913  	caller2 := makeAccountWithCode(cache, "caller2", MustSplice(callerCodePrefix,
   914  		// Shouldn't be enough gas to make call
   915  		delegateCallCost-1, callerCodeSuffix))
   916  
   917  	// Should fail
   918  	txe = runVM(cache, ourVm, caller2, callee, cache.GetCode(caller2), 100)
   919  	assert.NotNil(t, txe.Exception, "Should have insufficient gas for call")
   920  }
   921  
   922  func TestMemoryBounds(t *testing.T) {
   923  	cache := NewState(newAppState(), blockHashGetter)
   924  	memoryProvider := func(err errors.Sink) Memory {
   925  		return NewDynamicMemory(1024, 2048, err)
   926  	}
   927  	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger, MemoryProvider(memoryProvider))
   928  	caller := makeAccountWithCode(cache, "caller", nil)
   929  	callee := makeAccountWithCode(cache, "callee", nil)
   930  	gas := uint64(100000)
   931  	// This attempts to store a value at the memory boundary and return it
   932  	word := One256
   933  	output, err := ourVm.Call(cache, NewNoopEventSink(), caller, callee,
   934  		MustSplice(pushWord(word), storeAtEnd(), MLOAD, storeAtEnd(), returnAfterStore()),
   935  		nil, 0, &gas)
   936  	assert.NoError(t, err)
   937  	assert.Equal(t, word.Bytes(), output)
   938  
   939  	// Same with number
   940  	word = Int64ToWord256(232234234432)
   941  	output, err = ourVm.Call(cache, NewNoopEventSink(), caller, callee,
   942  		MustSplice(pushWord(word), storeAtEnd(), MLOAD, storeAtEnd(), returnAfterStore()),
   943  		nil, 0, &gas)
   944  	assert.NoError(t, err)
   945  	assert.Equal(t, word.Bytes(), output)
   946  
   947  	// Now test a series of boundary stores
   948  	code := pushWord(word)
   949  	for i := 0; i < 10; i++ {
   950  		code = MustSplice(code, storeAtEnd(), MLOAD)
   951  	}
   952  	output, err = ourVm.Call(cache, NewNoopEventSink(), caller, callee, MustSplice(code, storeAtEnd(), returnAfterStore()),
   953  		nil, 0, &gas)
   954  	assert.NoError(t, err)
   955  	assert.Equal(t, word.Bytes(), output)
   956  
   957  	// Same as above but we should breach the upper memory limit set in memoryProvider
   958  	code = pushWord(word)
   959  	for i := 0; i < 100; i++ {
   960  		code = MustSplice(code, storeAtEnd(), MLOAD)
   961  	}
   962  	require.NoError(t, cache.Error())
   963  	output, err = ourVm.Call(cache, NewNoopEventSink(), caller, callee, MustSplice(code, storeAtEnd(), returnAfterStore()),
   964  		nil, 0, &gas)
   965  	assert.Error(t, err, "Should hit memory out of bounds")
   966  }
   967  
   968  func TestMsgSender(t *testing.T) {
   969  	st := newAppState()
   970  	cache := NewState(st, blockHashGetter)
   971  	account1 := newAccount(cache, "1, 2, 3")
   972  	account2 := newAccount(cache, "3, 2, 1")
   973  
   974  	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
   975  
   976  	var gas uint64 = 100000
   977  
   978  	/*
   979  			pragma solidity ^0.5.4;
   980  
   981  			contract SimpleStorage {
   982  		                function get() public constant returns (address) {
   983  		        	        return msg.sender;
   984  		    	        }
   985  			}
   986  	*/
   987  
   988  	// This bytecode is compiled from Solidity contract above using remix.ethereum.org online compiler
   989  	code := hex.MustDecodeString("6060604052341561000f57600080fd5b60ca8061001d6000396000f30060606040526004361060" +
   990  		"3f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680636d4ce63c14604457" +
   991  		"5b600080fd5b3415604e57600080fd5b60546096565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ff" +
   992  		"ffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6000339050905600a165627a" +
   993  		"7a72305820b9ebf49535372094ae88f56d9ad18f2a79c146c8f56e7ef33b9402924045071e0029")
   994  
   995  	// Run the contract initialisation code to obtain the contract code that would be mounted at account2
   996  	contractCode, err := ourVm.Call(cache, NewNoopEventSink(), account1, account2, code, code, 0, &gas)
   997  	require.NoError(t, err)
   998  
   999  	// Not needed for this test (since contract code is passed as argument to vm), but this is what an execution
  1000  	// framework must do
  1001  	cache.InitCode(account2, contractCode)
  1002  
  1003  	// Input is the function hash of `get()`
  1004  	input := hex.MustDecodeString("6d4ce63c")
  1005  
  1006  	output, err := ourVm.Call(cache, NewNoopEventSink(), account1, account2, contractCode, input, 0, &gas)
  1007  	require.NoError(t, err)
  1008  
  1009  	assert.Equal(t, account1.Word256().Bytes(), output)
  1010  
  1011  	require.NoError(t, cache.Error())
  1012  }
  1013  
  1014  func TestInvalid(t *testing.T) {
  1015  	cache := NewState(newAppState(), blockHashGetter)
  1016  	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
  1017  
  1018  	// Create accounts
  1019  	account1 := newAccount(cache, "1")
  1020  	account2 := newAccount(cache, "1, 0, 1")
  1021  
  1022  	var gas uint64 = 100000
  1023  
  1024  	bytecode := MustSplice(PUSH32, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x20, 0x6D, 0x65, 0x73, 0x73, 0x61,
  1025  		0x67, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1026  		0x00, 0x00, 0x00, PUSH1, 0x00, MSTORE, PUSH1, 0x0E, PUSH1, 0x00, INVALID)
  1027  
  1028  	output, err := ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
  1029  	assert.Equal(t, errors.ErrorCodeExecutionAborted, err.ErrorCode())
  1030  	t.Logf("Output: %v Error: %v\n", output, err)
  1031  }
  1032  
  1033  func TestReturnDataSize(t *testing.T) {
  1034  	cache := NewState(newAppState(), blockHashGetter)
  1035  	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
  1036  
  1037  	accountName := "account2addresstests"
  1038  
  1039  	ret := "My return message"
  1040  	callcode := MustSplice(PUSH32, RightPadWord256([]byte(ret)), PUSH1, 0x00, MSTORE, PUSH1, len(ret), PUSH1, 0x00, RETURN)
  1041  
  1042  	// Create accounts
  1043  	account1 := newAccount(cache, "1")
  1044  	account2 := makeAccountWithCode(cache, accountName, callcode)
  1045  
  1046  	var gas uint64 = 100000
  1047  
  1048  	gas1, gas2 := byte(0x1), byte(0x1)
  1049  	value := byte(0x69)
  1050  	inOff, inSize := byte(0x0), byte(0x0) // no call data
  1051  	retOff, retSize := byte(0x0), byte(len(ret))
  1052  
  1053  	bytecode := MustSplice(PUSH1, retSize, PUSH1, retOff, PUSH1, inSize, PUSH1, inOff, PUSH1, value,
  1054  		PUSH20, account2, PUSH2, gas1, gas2, CALL,
  1055  		RETURNDATASIZE, PUSH1, 0x00, MSTORE, PUSH1, 0x20, PUSH1, 0x00, RETURN)
  1056  
  1057  	expected := Uint64ToWord256(uint64(len(ret))).Bytes()
  1058  
  1059  	output, err := ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
  1060  	require.NoError(t, err)
  1061  	assert.Equal(t, expected, output)
  1062  
  1063  	t.Logf("Output: %v Error: %v\n", output, err)
  1064  
  1065  	if err != nil {
  1066  		t.Fatal(err)
  1067  	}
  1068  	require.NoError(t, cache.Error())
  1069  }
  1070  
  1071  func TestReturnDataCopy(t *testing.T) {
  1072  	cache := NewState(newAppState(), blockHashGetter)
  1073  	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
  1074  
  1075  	accountName := "account2addresstests"
  1076  
  1077  	ret := "My return message"
  1078  	callcode := MustSplice(PUSH32, RightPadWord256([]byte(ret)), PUSH1, 0x00, MSTORE, PUSH1, len(ret), PUSH1, 0x00, RETURN)
  1079  
  1080  	// Create accounts
  1081  	account1 := newAccount(cache, "1")
  1082  	account2 := makeAccountWithCode(cache, accountName, callcode)
  1083  
  1084  	var gas uint64 = 100000
  1085  
  1086  	gas1, gas2 := byte(0x1), byte(0x1)
  1087  	value := byte(0x69)
  1088  	inOff, inSize := byte(0x0), byte(0x0) // no call data
  1089  	retOff, retSize := byte(0x0), byte(len(ret))
  1090  
  1091  	bytecode := MustSplice(PUSH1, retSize, PUSH1, retOff, PUSH1, inSize, PUSH1, inOff, PUSH1, value,
  1092  		PUSH20, account2, PUSH2, gas1, gas2, CALL, RETURNDATASIZE, PUSH1, 0x00, PUSH1, 0x00, RETURNDATACOPY,
  1093  		RETURNDATASIZE, PUSH1, 0x00, RETURN)
  1094  
  1095  	expected := []byte(ret)
  1096  
  1097  	output, err := ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
  1098  	require.NoError(t, err)
  1099  	assert.Equal(t, expected, output)
  1100  
  1101  	t.Logf("Output: %v Error: %v\n", output, err)
  1102  
  1103  	require.NoError(t, cache.Error())
  1104  }
  1105  
  1106  func TestCallNonExistent(t *testing.T) {
  1107  	cache := NewState(newAppState(), blockHashGetter)
  1108  	account1 := newAccount(cache, "1")
  1109  	cache.AddToBalance(account1, 10000)
  1110  	unknownAddress := newAddress("nonexistent")
  1111  	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
  1112  	var gas uint64
  1113  	amt := uint64(100)
  1114  	_, err := ourVm.Call(cache, NewNoopEventSink(), account1, unknownAddress, nil, nil, amt, &gas)
  1115  	assertErrorCode(t, errors.ErrorCodeIllegalWrite, err,
  1116  		"Should not be able to call account before creating it (even before initialising)")
  1117  	assert.Equal(t, uint64(0), cache.GetBalance(unknownAddress))
  1118  }
  1119  
  1120  func (ts testState) GetBlockHash(blockNumber uint64) (binary.Word256, error) {
  1121  	return ts.BlockHashProvider(blockNumber)
  1122  }
  1123  
  1124  func TestGetBlockHash(t *testing.T) {
  1125  	cache := NewTestState(newAppState(), blockHashGetter)
  1126  	params := newParams()
  1127  
  1128  	// Create accounts
  1129  	account1 := newAccount(cache, "1")
  1130  	account2 := newAccount(cache, "101")
  1131  
  1132  	var gas uint64 = 100000
  1133  
  1134  	// Non existing block
  1135  	params.BlockHeight = 1
  1136  	ourVm := NewVM(params, crypto.ZeroAddress, nil, logger)
  1137  	bytecode := MustSplice(PUSH1, 2, BLOCKHASH)
  1138  	_, err := ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
  1139  	assertErrorCode(t, errors.ErrorCodeInvalidBlockNumber, err, "attempt to get block hash of a non-existent block")
  1140  
  1141  	// Excessive old block
  1142  	cache.error = nil
  1143  	params.BlockHeight = 258
  1144  	ourVm = NewVM(params, crypto.ZeroAddress, nil, logger)
  1145  	bytecode = MustSplice(PUSH1, 1, BLOCKHASH)
  1146  
  1147  	_, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
  1148  	assertErrorCode(t, errors.ErrorCodeBlockNumberOutOfRange, err, "attempt to get block hash of a block outside of allowed range")
  1149  
  1150  	// Get block hash
  1151  	cache.error = nil
  1152  	params.BlockHeight = 257
  1153  	cache.BlockHashProvider = func(blockNumber uint64) (Word256, error) {
  1154  		// Should be just within range 257 - 2 = 255 (and the first and last block count in that range so add one = 256)
  1155  		assert.Equal(t, uint64(2), blockNumber)
  1156  		return One256, nil
  1157  	}
  1158  	ourVm = NewVM(params, crypto.ZeroAddress, nil, logger)
  1159  	bytecode = MustSplice(PUSH1, 2, BLOCKHASH, return1())
  1160  
  1161  	output, err := ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
  1162  	assert.NoError(t, err)
  1163  	assert.Equal(t, One256, LeftPadWord256(output))
  1164  
  1165  	// Get block hash fail
  1166  	cache.error = nil
  1167  	params.BlockHeight = 3
  1168  	cache.BlockHashProvider = func(blockNumber uint64) (Word256, error) {
  1169  		assert.Equal(t, uint64(1), blockNumber)
  1170  		return Zero256, fmt.Errorf("unknown block %v", blockNumber)
  1171  	}
  1172  	ourVm = NewVM(params, crypto.ZeroAddress, nil, logger)
  1173  	bytecode = MustSplice(PUSH1, 1, BLOCKHASH, return1())
  1174  
  1175  	_, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
  1176  	assertErrorCode(t, errors.ErrorCodeInvalidBlockNumber, err, "attempt to get block hash failed")
  1177  }
  1178  
  1179  // These code segment helpers exercise the MSTORE MLOAD MSTORE cycle to test
  1180  // both of the memory operations. Each MSTORE is done on the memory boundary
  1181  // (at MSIZE) which Solidity uses to find guaranteed unallocated memory.
  1182  
  1183  // storeAtEnd expects the value to be stored to be on top of the stack, it then
  1184  // stores that value at the current memory boundary
  1185  func storeAtEnd() []byte {
  1186  	// Pull in MSIZE (to carry forward to MLOAD), swap in value to store, store it at MSIZE
  1187  	return MustSplice(MSIZE, SWAP1, DUP2, MSTORE)
  1188  }
  1189  
  1190  func returnAfterStore() []byte {
  1191  	return MustSplice(PUSH1, 32, DUP2, RETURN)
  1192  }
  1193  
  1194  // Store the top element of the stack (which is a 32-byte word) in memory
  1195  // and return it. Useful for a simple return value.
  1196  func return1() []byte {
  1197  	return MustSplice(PUSH1, 0, MSTORE, returnWord())
  1198  }
  1199  
  1200  func returnWord() []byte {
  1201  	// PUSH1 => return size, PUSH1 => return offset, RETURN
  1202  	return MustSplice(PUSH1, 32, PUSH1, 0, RETURN)
  1203  }
  1204  
  1205  // Subscribes to an AccCall, runs the vm, returns the output any direct exception
  1206  // and then waits for any exceptions transmitted by Data in the AccCall
  1207  // event (in the case of no direct error from call we will block waiting for
  1208  // at least 1 AccCall event)
  1209  func runVM(vmCache Interface, ourVm *VM, caller, callee crypto.Address, contractCode []byte,
  1210  	gas uint64) *exec.TxExecution {
  1211  	gasBefore := gas
  1212  	txe := new(exec.TxExecution)
  1213  	output, err := ourVm.Call(vmCache, txe, caller, callee, contractCode, []byte{}, 0, &gas)
  1214  	txe.PushError(err)
  1215  	for _, ev := range txe.ExceptionalCalls() {
  1216  		txe.PushError(ev.Header.Exception)
  1217  	}
  1218  	txe.Return(output, gasBefore-gas)
  1219  	return txe
  1220  }
  1221  
  1222  // this is code to call another contract (hardcoded as addr)
  1223  func callContractCode(addr crypto.Address) []byte {
  1224  	gas1, gas2 := byte(0x1), byte(0x1)
  1225  	value := byte(0x69)
  1226  	inOff, inSize := byte(0x0), byte(0x0) // no call data
  1227  	retOff, retSize := byte(0x0), byte(0x20)
  1228  	// this is the code we want to run (send funds to an account and return)
  1229  	return MustSplice(PUSH1, retSize, PUSH1, retOff, PUSH1, inSize, PUSH1,
  1230  		inOff, PUSH1, value, PUSH20, addr, PUSH2, gas1, gas2, CALL, PUSH1, retSize,
  1231  		PUSH1, retOff, RETURN)
  1232  }
  1233  
  1234  // Produce bytecode for a PUSH<N>, b_1, ..., b_N where the N is number of bytes
  1235  // contained in the unpadded word
  1236  func pushWord(word Word256) []byte {
  1237  	leadingZeros := byte(0)
  1238  	for leadingZeros < 32 {
  1239  		if word[leadingZeros] == 0 {
  1240  			leadingZeros++
  1241  		} else {
  1242  			return MustSplice(byte(PUSH32)-leadingZeros, word[leadingZeros:])
  1243  		}
  1244  	}
  1245  	return MustSplice(PUSH1, 0)
  1246  }
  1247  
  1248  func TestPushWord(t *testing.T) {
  1249  	word := Int64ToWord256(int64(2133213213))
  1250  	assert.Equal(t, MustSplice(PUSH4, 0x7F, 0x26, 0x40, 0x1D), pushWord(word))
  1251  	word[0] = 1
  1252  	assert.Equal(t, MustSplice(PUSH32,
  1253  		1, 0, 0, 0, 0, 0, 0, 0,
  1254  		0, 0, 0, 0, 0, 0, 0, 0,
  1255  		0, 0, 0, 0, 0, 0, 0, 0,
  1256  		0, 0, 0, 0, 0x7F, 0x26, 0x40, 0x1D), pushWord(word))
  1257  	assert.Equal(t, MustSplice(PUSH1, 0), pushWord(Word256{}))
  1258  	assert.Equal(t, MustSplice(PUSH1, 1), pushWord(Int64ToWord256(1)))
  1259  }
  1260  
  1261  // Kind of indirect test of Splice, but here to avoid import cycles
  1262  func TestBytecode(t *testing.T) {
  1263  	assert.Equal(t,
  1264  		MustSplice(1, 2, 3, 4, 5, 6),
  1265  		MustSplice(1, 2, 3, MustSplice(4, 5, 6)))
  1266  	assert.Equal(t,
  1267  		MustSplice(1, 2, 3, 4, 5, 6, 7, 8),
  1268  		MustSplice(1, 2, 3, MustSplice(4, MustSplice(5), 6), 7, 8))
  1269  	assert.Equal(t,
  1270  		MustSplice(PUSH1, 2),
  1271  		MustSplice(byte(PUSH1), 0x02))
  1272  	assert.Equal(t,
  1273  		[]byte{},
  1274  		MustSplice(MustSplice(MustSplice())))
  1275  
  1276  	contractAccount := &acm.Account{Address: crypto.AddressFromWord256(Int64ToWord256(102))}
  1277  	addr := contractAccount.Address
  1278  	gas1, gas2 := byte(0x1), byte(0x1)
  1279  	value := byte(0x69)
  1280  	inOff, inSize := byte(0x0), byte(0x0) // no call data
  1281  	retOff, retSize := byte(0x0), byte(0x20)
  1282  	contractCodeBytecode := MustSplice(PUSH1, retSize, PUSH1, retOff, PUSH1, inSize, PUSH1,
  1283  		inOff, PUSH1, value, PUSH20, addr, PUSH2, gas1, gas2, CALL, PUSH1, retSize,
  1284  		PUSH1, retOff, RETURN)
  1285  	contractCode := []byte{0x60, retSize, 0x60, retOff, 0x60, inSize, 0x60, inOff, 0x60, value, 0x73}
  1286  	contractCode = append(contractCode, addr[:]...)
  1287  	contractCode = append(contractCode, []byte{0x61, gas1, gas2, 0xf1, 0x60, 0x20, 0x60, 0x0, 0xf3}...)
  1288  	assert.Equal(t, contractCode, contractCodeBytecode)
  1289  }
  1290  
  1291  func TestConcat(t *testing.T) {
  1292  	assert.Equal(t,
  1293  		[]byte{0x01, 0x02, 0x03, 0x04},
  1294  		Concat([]byte{0x01, 0x02}, []byte{0x03, 0x04}))
  1295  }
  1296  
  1297  func TestSubslice(t *testing.T) {
  1298  	const size = 10
  1299  	data := make([]byte, size)
  1300  	for i := 0; i < size; i++ {
  1301  		data[i] = byte(i)
  1302  	}
  1303  	err := errors.FirstOnly()
  1304  	for n := int64(0); n < size; n++ {
  1305  		data = data[:n]
  1306  		for offset := int64(-size); offset < size; offset++ {
  1307  			for length := int64(-size); length < size; length++ {
  1308  				err.Reset()
  1309  				subslice(data, offset, length, err)
  1310  				if offset < 0 || length < 0 || n < offset {
  1311  					assert.NotNil(t, err.Error())
  1312  				} else {
  1313  					assert.Nil(t, err.Error())
  1314  				}
  1315  			}
  1316  		}
  1317  	}
  1318  
  1319  	err.Reset()
  1320  	assert.Equal(t, []byte{
  1321  		5, 6, 7, 8, 0, 0, 0, 0,
  1322  		0, 0, 0, 0, 0, 0, 0, 0,
  1323  		0, 0, 0, 0, 0, 0, 0, 0,
  1324  		0, 0, 0, 0, 0, 0, 0, 0,
  1325  	}, subslice([]byte{1, 2, 3, 4, 5, 6, 7, 8}, 4, 32, err))
  1326  }
  1327  
  1328  func TestHasPermission(t *testing.T) {
  1329  	st := newAppState()
  1330  	acc := &acm.Account{
  1331  		Address: newAddress("frog"),
  1332  		Permissions: permission.AccountPermissions{
  1333  			Base: BasePermissionsFromStrings(t,
  1334  				"00100000001000111",
  1335  				"11011100010111000"),
  1336  		},
  1337  	}
  1338  	require.NoError(t, st.UpdateAccount(acc))
  1339  	// Ensure we are falling through to global permissions on those bits not set
  1340  	cache := NewState(st, blockHashGetter)
  1341  	assert.True(t, HasPermission(cache, acc.Address, PermFlagFromString(t, "100000001000110")))
  1342  	require.NoError(t, cache.Error())
  1343  }
  1344  
  1345  func TestDataStackOverflow(t *testing.T) {
  1346  	st := newAppState()
  1347  	cache := NewState(st, blockHashGetter)
  1348  	account1 := newAccount(cache, "1, 2, 3")
  1349  	account2 := newAccount(cache, "3, 2, 1")
  1350  
  1351  	params := newParams()
  1352  	params.DataStackMaxDepth = 4
  1353  	ourVm := NewVM(params, crypto.ZeroAddress, nil, logger)
  1354  
  1355  	var gas uint64 = 100000
  1356  
  1357  	/*
  1358  		pragma solidity ^0.5.4;
  1359  
  1360  		contract SimpleStorage {
  1361  			function get() public constant returns (address) {
  1362  				return get();
  1363  			}
  1364  		}
  1365  	*/
  1366  
  1367  	// This bytecode is compiled from Solidity contract above using remix.ethereum.org online compiler
  1368  	code, err := hex.DecodeString("608060405234801561001057600080fd5b5060d18061001f6000396000f300608060405260043610" +
  1369  		"603f576000357c0100000000000000000000000000000000000000000000000000000000900463ff" +
  1370  		"ffffff1680636d4ce63c146044575b600080fd5b348015604f57600080fd5b5060566098565b6040" +
  1371  		"51808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffff" +
  1372  		"ffffffffffff16815260200191505060405180910390f35b600060a06098565b9050905600a16562" +
  1373  		"7a7a72305820daacfba0c21afacb5b67f26bc8021de63eaa560db82f98357d4e513f3249cf350029")
  1374  	require.NoError(t, err)
  1375  
  1376  	// Run the contract initialisation code to obtain the contract code that would be mounted at account2
  1377  	eventSink := NewNoopEventSink()
  1378  	contractCode, err := ourVm.Call(cache, eventSink, account1, account2, code, code, 0, &gas)
  1379  	require.NoError(t, err)
  1380  
  1381  	// Input is the function hash of `get()`
  1382  	input, err := hex.DecodeString("6d4ce63c")
  1383  
  1384  	_, err = ourVm.Call(cache, eventSink, account1, account2, contractCode, input, 0, &gas)
  1385  	assertErrorCode(t, errors.ErrorCodeDataStackOverflow, err, "Should be stack overflow")
  1386  }
  1387  
  1388  func TestCallStackOverflow(t *testing.T) {
  1389  	st := newAppState()
  1390  	cache := NewState(st, blockHashGetter)
  1391  	account1 := newAccount(cache, "1, 2, 3")
  1392  	account2 := newAccount(cache, "3, 2, 1")
  1393  
  1394  	params := newParams()
  1395  
  1396  	// Sender accepts lot of gaz but we run on a caped call stack node
  1397  	var gas uint64 = 100000
  1398  	params.CallStackMaxDepth = 2
  1399  
  1400  	ourVm := NewVM(params, crypto.ZeroAddress, nil, logger)
  1401  
  1402  	/*
  1403  		pragma solidity ^0.5.4;
  1404  
  1405  		contract A {
  1406  		   function callMeBack() public {
  1407  				return require(msg.sender.call(bytes4(keccak256("callMeBack()")),this));
  1408  			}
  1409  		}
  1410  	*/
  1411  
  1412  	// This bytecode is compiled from Solidity contract above using remix.ethereum.org online compiler
  1413  	code, err := hex.DecodeString("608060405234801561001057600080fd5b5061017a806100206000396000f3006080604052600436" +
  1414  		"10610041576000357c01000000000000000000000000000000000000000000000000000000009004" +
  1415  		"63ffffffff168063692c3b7c14610046575b600080fd5b34801561005257600080fd5b5061005b61" +
  1416  		"005d565b005b3373ffffffffffffffffffffffffffffffffffffffff1660405180807f63616c6c4d" +
  1417  		"654261636b28290000000000000000000000000000000000000000815250600c0190506040518091" +
  1418  		"0390207c010000000000000000000000000000000000000000000000000000000090043060405182" +
  1419  		"63ffffffff167c010000000000000000000000000000000000000000000000000000000002815260" +
  1420  		"0401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffff" +
  1421  		"ffffffffffffff1681526020019150506000604051808303816000875af192505050151561014c57" +
  1422  		"600080fd5b5600a165627a7a723058209315a40abb8b23b7c2a340e938b01367b419a23818475a2e" +
  1423  		"ee80d09da3f7ba780029")
  1424  	require.NoError(t, err)
  1425  
  1426  	// Run the contract initialisation code to obtain the contract code that would be mounted at account2
  1427  	contractCode, err := ourVm.Call(cache, NewNoopEventSink(), account1, account2, code, code, 0, &gas)
  1428  	require.NoError(t, err)
  1429  
  1430  	cache.InitCode(account1, contractCode)
  1431  	cache.InitCode(account2, contractCode)
  1432  
  1433  	// keccak256 hash of 'callMeBack()'
  1434  	input, err := hex.DecodeString("692c3b7c")
  1435  	require.NoError(t, err)
  1436  
  1437  	txe := new(exec.TxExecution)
  1438  	_, err = ourVm.Call(cache, txe, account1, account2, contractCode, input, 0, &gas)
  1439  	txe.PushError(err)
  1440  	require.Error(t, err)
  1441  	callError := txe.CallError()
  1442  	require.Error(t, callError)
  1443  	assertErrorCode(t, errors.ErrorCodeExecutionReverted, callError)
  1444  	// Errors are post-order so first is deepest
  1445  	deepestErr := callError.NestedErrors[0]
  1446  	assertErrorCode(t, errors.ErrorCodeCallStackOverflow, deepestErr)
  1447  	assert.Equal(t, params.CallStackMaxDepth, deepestErr.StackDepth)
  1448  	assert.Equal(t, account2, deepestErr.Callee)
  1449  	assert.Equal(t, account1, deepestErr.Caller)
  1450  }
  1451  
  1452  func TestExtCodeHash(t *testing.T) {
  1453  	cache := NewState(newAppState(), blockHashGetter)
  1454  	ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger)
  1455  	account1 := newAccount(cache, "1")
  1456  	account2 := newAccount(cache, "101")
  1457  
  1458  	var gas uint64 = 100000
  1459  
  1460  	// 1. The EXTCODEHASH of the account without code is c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
  1461  	//    what is the keccack256 hash of empty data.
  1462  	bytecode := MustSplice(PUSH20, account1, EXTCODEHASH, return1())
  1463  	output, err := ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
  1464  	assert.NoError(t, err)
  1465  	assert.Equal(t, hex.MustDecodeString("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"), output)
  1466  
  1467  	// 2. The EXTCODEHASH of non-existent account is 0.
  1468  	bytecode = MustSplice(PUSH1, 0x03, EXTCODEHASH, return1())
  1469  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
  1470  	assert.NoError(t, err)
  1471  	assert.Equal(t, LeftPadBytes([]uint8([]byte{0x00}), 32), output)
  1472  
  1473  	// 3. EXTCODEHASH is the hash of an account code
  1474  	acc := makeAccountWithCode(cache, "trustedCode", MustSplice(BLOCKHASH, return1()))
  1475  	bytecode = MustSplice(PUSH20, acc, EXTCODEHASH, return1())
  1476  	output, err = ourVm.Call(cache, NewNoopEventSink(), account1, account2, bytecode, []byte{}, 0, &gas)
  1477  	assert.NoError(t, err)
  1478  	assert.Equal(t, hex.MustDecodeString("010da270094b5199d3e54f89afe4c66cdd658dd8111a41998714227e14e171bd"), output)
  1479  }
  1480  
  1481  func BasePermissionsFromStrings(t *testing.T, perms, setBit string) permission.BasePermissions {
  1482  	return permission.BasePermissions{
  1483  		Perms:  PermFlagFromString(t, perms),
  1484  		SetBit: PermFlagFromString(t, setBit),
  1485  	}
  1486  }
  1487  
  1488  func PermFlagFromString(t *testing.T, binaryString string) permission.PermFlag {
  1489  	permFlag, err := strconv.ParseUint(binaryString, 2, 64)
  1490  	require.NoError(t, err)
  1491  	return permission.PermFlag(permFlag)
  1492  }
  1493  
  1494  func assertErrorCode(t *testing.T, expectedCode errors.Code, err error, msgAndArgs ...interface{}) {
  1495  	if assert.Error(t, err, msgAndArgs...) {
  1496  		actualCode := errors.AsException(err).Code
  1497  		if !assert.Equal(t, expectedCode, actualCode, "expected error code %v", expectedCode) {
  1498  			t.Logf("Expected '%v' but got '%v'", expectedCode, actualCode)
  1499  		}
  1500  	}
  1501  }