github.com/karalabe/go-ethereum@v0.8.5/tests/vm/gh_test.go (about)

     1  package vm
     2  
     3  import (
     4  	"bytes"
     5  	"math/big"
     6  	"strconv"
     7  	"testing"
     8  
     9  	"github.com/ethereum/go-ethereum/core/types"
    10  	"github.com/ethereum/go-ethereum/ethdb"
    11  	"github.com/ethereum/go-ethereum/ethutil"
    12  	"github.com/ethereum/go-ethereum/logger"
    13  	"github.com/ethereum/go-ethereum/state"
    14  	"github.com/ethereum/go-ethereum/tests/helper"
    15  )
    16  
    17  type Account struct {
    18  	Balance string
    19  	Code    string
    20  	Nonce   string
    21  	Storage map[string]string
    22  }
    23  
    24  type Log struct {
    25  	AddressF string   `json:"address"`
    26  	DataF    string   `json:"data"`
    27  	TopicsF  []string `json:"topics"`
    28  	BloomF   string   `json:"bloom"`
    29  }
    30  
    31  func (self Log) Address() []byte      { return ethutil.Hex2Bytes(self.AddressF) }
    32  func (self Log) Data() []byte         { return ethutil.Hex2Bytes(self.DataF) }
    33  func (self Log) RlpData() interface{} { return nil }
    34  func (self Log) Topics() [][]byte {
    35  	t := make([][]byte, len(self.TopicsF))
    36  	for i, topic := range self.TopicsF {
    37  		t[i] = ethutil.Hex2Bytes(topic)
    38  	}
    39  	return t
    40  }
    41  
    42  func StateObjectFromAccount(db ethutil.Database, addr string, account Account) *state.StateObject {
    43  	obj := state.NewStateObject(ethutil.Hex2Bytes(addr), db)
    44  	obj.SetBalance(ethutil.Big(account.Balance))
    45  
    46  	if ethutil.IsHex(account.Code) {
    47  		account.Code = account.Code[2:]
    48  	}
    49  	obj.SetCode(ethutil.Hex2Bytes(account.Code))
    50  	obj.SetNonce(ethutil.Big(account.Nonce).Uint64())
    51  
    52  	return obj
    53  }
    54  
    55  type Env struct {
    56  	CurrentCoinbase   string
    57  	CurrentDifficulty string
    58  	CurrentGasLimit   string
    59  	CurrentNumber     string
    60  	CurrentTimestamp  interface{}
    61  	PreviousHash      string
    62  }
    63  
    64  type VmTest struct {
    65  	Callcreates interface{}
    66  	//Env         map[string]string
    67  	Env         Env
    68  	Exec        map[string]string
    69  	Transaction map[string]string
    70  	Logs        []Log
    71  	Gas         string
    72  	Out         string
    73  	Post        map[string]Account
    74  	Pre         map[string]Account
    75  }
    76  
    77  func RunVmTest(p string, t *testing.T) {
    78  	tests := make(map[string]VmTest)
    79  	helper.CreateFileTests(t, p, &tests)
    80  
    81  	for name, test := range tests {
    82  		helper.Logger.SetLogLevel(4)
    83  		if name != "TransactionNonceCheck2" {
    84  			continue
    85  		}
    86  		db, _ := ethdb.NewMemDatabase()
    87  		statedb := state.New(nil, db)
    88  		for addr, account := range test.Pre {
    89  			obj := StateObjectFromAccount(db, addr, account)
    90  			statedb.SetStateObject(obj)
    91  			for a, v := range account.Storage {
    92  				obj.SetState(helper.FromHex(a), ethutil.NewValue(helper.FromHex(v)))
    93  			}
    94  		}
    95  
    96  		// XXX Yeah, yeah...
    97  		env := make(map[string]string)
    98  		env["currentCoinbase"] = test.Env.CurrentCoinbase
    99  		env["currentDifficulty"] = test.Env.CurrentDifficulty
   100  		env["currentGasLimit"] = test.Env.CurrentGasLimit
   101  		env["currentNumber"] = test.Env.CurrentNumber
   102  		env["previousHash"] = test.Env.PreviousHash
   103  		if n, ok := test.Env.CurrentTimestamp.(float64); ok {
   104  			env["currentTimestamp"] = strconv.Itoa(int(n))
   105  		} else {
   106  			env["currentTimestamp"] = test.Env.CurrentTimestamp.(string)
   107  		}
   108  
   109  		var (
   110  			ret  []byte
   111  			gas  *big.Int
   112  			err  error
   113  			logs state.Logs
   114  		)
   115  
   116  		isVmTest := len(test.Exec) > 0
   117  		if isVmTest {
   118  			ret, logs, gas, err = helper.RunVm(statedb, env, test.Exec)
   119  		} else {
   120  			ret, logs, gas, err = helper.RunState(statedb, env, test.Transaction)
   121  		}
   122  
   123  		rexp := helper.FromHex(test.Out)
   124  		if bytes.Compare(rexp, ret) != 0 {
   125  			t.Errorf("%s's return failed. Expected %x, got %x\n", name, rexp, ret)
   126  		}
   127  
   128  		if isVmTest {
   129  			if len(test.Gas) == 0 && err == nil {
   130  				t.Errorf("%s's gas unspecified, indicating an error. VM returned (incorrectly) successfull", name)
   131  			} else {
   132  				gexp := ethutil.Big(test.Gas)
   133  				if gexp.Cmp(gas) != 0 {
   134  					t.Errorf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas)
   135  				}
   136  			}
   137  		}
   138  
   139  		for addr, account := range test.Post {
   140  			obj := statedb.GetStateObject(helper.FromHex(addr))
   141  			if obj == nil {
   142  				continue
   143  			}
   144  
   145  			if len(test.Exec) == 0 {
   146  				if obj.Balance().Cmp(ethutil.Big(account.Balance)) != 0 {
   147  					t.Errorf("%s's : (%x) balance failed. Expected %v, got %v => %v\n", name, obj.Address()[:4], account.Balance, obj.Balance(), new(big.Int).Sub(ethutil.Big(account.Balance), obj.Balance()))
   148  				}
   149  			}
   150  
   151  			for addr, value := range account.Storage {
   152  				v := obj.GetState(helper.FromHex(addr)).Bytes()
   153  				vexp := helper.FromHex(value)
   154  
   155  				if bytes.Compare(v, vexp) != 0 {
   156  					t.Errorf("%s's : (%x: %s) storage failed. Expected %x, got %x (%v %v)\n", name, obj.Address()[0:4], addr, vexp, v, ethutil.BigD(vexp), ethutil.BigD(v))
   157  				}
   158  			}
   159  		}
   160  
   161  		if len(test.Logs) > 0 {
   162  			for i, log := range test.Logs {
   163  				genBloom := ethutil.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 64)
   164  				if !bytes.Equal(genBloom, ethutil.Hex2Bytes(log.BloomF)) {
   165  					t.Errorf("bloom mismatch")
   166  				}
   167  			}
   168  		}
   169  	}
   170  	logger.Flush()
   171  }
   172  
   173  // I've created a new function for each tests so it's easier to identify where the problem lies if any of them fail.
   174  func TestVMArithmetic(t *testing.T) {
   175  	const fn = "../files/VMTests/vmArithmeticTest.json"
   176  	RunVmTest(fn, t)
   177  }
   178  
   179  func TestSystemOperations(t *testing.T) {
   180  	const fn = "../files/VMTests/vmSystemOperationsTest.json"
   181  	RunVmTest(fn, t)
   182  }
   183  
   184  func TestBitwiseLogicOperation(t *testing.T) {
   185  	const fn = "../files/VMTests/vmBitwiseLogicOperationTest.json"
   186  	RunVmTest(fn, t)
   187  }
   188  
   189  func TestBlockInfo(t *testing.T) {
   190  	const fn = "../files/VMTests/vmBlockInfoTest.json"
   191  	RunVmTest(fn, t)
   192  }
   193  
   194  func TestEnvironmentalInfo(t *testing.T) {
   195  	const fn = "../files/VMTests/vmEnvironmentalInfoTest.json"
   196  	RunVmTest(fn, t)
   197  }
   198  
   199  func TestFlowOperation(t *testing.T) {
   200  	const fn = "../files/VMTests/vmIOandFlowOperationsTest.json"
   201  	RunVmTest(fn, t)
   202  }
   203  
   204  func TestPushDupSwap(t *testing.T) {
   205  	const fn = "../files/VMTests/vmPushDupSwapTest.json"
   206  	RunVmTest(fn, t)
   207  }
   208  
   209  func TestVMSha3(t *testing.T) {
   210  	const fn = "../files/VMTests/vmSha3Test.json"
   211  	RunVmTest(fn, t)
   212  }
   213  
   214  func TestVm(t *testing.T) {
   215  	const fn = "../files/VMTests/vmtests.json"
   216  	RunVmTest(fn, t)
   217  }
   218  
   219  func TestVmLog(t *testing.T) {
   220  	const fn = "../files/VMTests/vmLogTest.json"
   221  	RunVmTest(fn, t)
   222  }
   223  
   224  func TestStateSystemOperations(t *testing.T) {
   225  	const fn = "../files/StateTests/stSystemOperationsTest.json"
   226  	RunVmTest(fn, t)
   227  }
   228  
   229  func TestStatePreCompiledContracts(t *testing.T) {
   230  	const fn = "../files/StateTests/stPreCompiledContracts.json"
   231  	RunVmTest(fn, t)
   232  }
   233  
   234  func TestStateRecursiveCreate(t *testing.T) {
   235  	const fn = "../files/StateTests/stRecursiveCreate.json"
   236  	RunVmTest(fn, t)
   237  }
   238  
   239  func TestStateSpecial(t *testing.T) {
   240  	const fn = "../files/StateTests/stSpecialTest.json"
   241  	RunVmTest(fn, t)
   242  }
   243  
   244  func TestStateRefund(t *testing.T) {
   245  	const fn = "../files/StateTests/stRefundTest.json"
   246  	RunVmTest(fn, t)
   247  }
   248  
   249  func TestStateBlockHash(t *testing.T) {
   250  	const fn = "../files/StateTests/stBlockHashTest.json"
   251  	RunVmTest(fn, t)
   252  }
   253  
   254  func TestStateInitCode(t *testing.T) {
   255  	const fn = "../files/StateTests/stInitCodeTest.json"
   256  	RunVmTest(fn, t)
   257  }
   258  
   259  func TestStateLog(t *testing.T) {
   260  	const fn = "../files/StateTests/stLogTests.json"
   261  	RunVmTest(fn, t)
   262  }
   263  
   264  func TestStateTransaction(t *testing.T) {
   265  	t.Skip()
   266  	const fn = "../files/StateTests/stTransactionTest.json"
   267  	RunVmTest(fn, t)
   268  }