Cleanup/reorg
This commit is contained in:
		
							parent
							
								
									c5d6fcbaba
								
							
						
					
					
						commit
						b6d40a9312
					
				| @ -5,10 +5,6 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var baseDir = filepath.Join(".", "files") |  | ||||||
| var blockTestDir = filepath.Join(baseDir, "BlockTests") |  | ||||||
| 
 |  | ||||||
| // TODO: refactor test setup & execution to better align with vm and tx tests
 |  | ||||||
| func TestBcValidBlockTests(t *testing.T) { | func TestBcValidBlockTests(t *testing.T) { | ||||||
| 	runBlockTestsInFile(filepath.Join(blockTestDir, "bcValidBlockTest.json"), []string{"SimpleTx3"}) | 	runBlockTestsInFile(filepath.Join(blockTestDir, "bcValidBlockTest.json"), []string{"SimpleTx3"}) | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,25 +1,21 @@ | |||||||
| package tests | package tests | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"bytes" |  | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"fmt" |  | ||||||
| 	"io" | 	"io" | ||||||
| 	"io/ioutil" | 	"io/ioutil" | ||||||
| 	// "log"
 |  | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"os" | 	"os" | ||||||
| 
 | 	"path/filepath" | ||||||
| 	// logpkg "github.com/ethereum/go-ethereum/logger"
 |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // var Logger *logpkg.StdLogSystem
 | var ( | ||||||
| // var Log = logpkg.NewLogger("TEST")
 | 	baseDir            = filepath.Join(".", "files") | ||||||
| 
 | 	blockTestDir       = filepath.Join(baseDir, "BlockTests") | ||||||
| // func init() {
 | 	stateTestDir       = filepath.Join(baseDir, "StateTests") | ||||||
| // 	Logger = logpkg.NewStdLogSystem(os.Stdout, log.LstdFlags, logpkg.InfoLevel)
 | 	transactionTestDir = filepath.Join(baseDir, "TransactionTests") | ||||||
| // 	logpkg.AddLogSystem(Logger)
 | 	vmTestDir          = filepath.Join(baseDir, "VMTests") | ||||||
| // }
 | ) | ||||||
| 
 | 
 | ||||||
| func readJSON(reader io.Reader, value interface{}) error { | func readJSON(reader io.Reader, value interface{}) error { | ||||||
| 	data, err := ioutil.ReadAll(reader) | 	data, err := ioutil.ReadAll(reader) | ||||||
| @ -57,4 +53,3 @@ func CreateFileTests(fn string, value interface{}) error { | |||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| } |  | ||||||
|  | |||||||
| @ -6,8 +6,6 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var stateTestDir = filepath.Join(baseDir, "StateTests") |  | ||||||
| 
 |  | ||||||
| func TestStateSystemOperations(t *testing.T) { | func TestStateSystemOperations(t *testing.T) { | ||||||
| 	fn := filepath.Join(stateTestDir, "stSystemOperationsTest.json") | 	fn := filepath.Join(stateTestDir, "stSystemOperationsTest.json") | ||||||
| 	if err := RunStateTest(fn); err != nil { | 	if err := RunStateTest(fn); err != nil { | ||||||
|  | |||||||
| @ -2,20 +2,16 @@ package tests | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
| 	// "errors"
 |  | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"math/big" | 	"math/big" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	// "testing"
 |  | ||||||
| 
 | 
 | ||||||
| 	"github.com/ethereum/go-ethereum/common" | 	"github.com/ethereum/go-ethereum/common" | ||||||
| 	"github.com/ethereum/go-ethereum/core" | 	"github.com/ethereum/go-ethereum/core" | ||||||
| 	"github.com/ethereum/go-ethereum/core/state" | 	"github.com/ethereum/go-ethereum/core/state" | ||||||
| 	// "github.com/ethereum/go-ethereum/core/types"
 |  | ||||||
| 	"github.com/ethereum/go-ethereum/core/vm" | 	"github.com/ethereum/go-ethereum/core/vm" | ||||||
| 	"github.com/ethereum/go-ethereum/crypto" | 	"github.com/ethereum/go-ethereum/crypto" | ||||||
| 	"github.com/ethereum/go-ethereum/ethdb" | 	"github.com/ethereum/go-ethereum/ethdb" | ||||||
| 	// "github.com/ethereum/go-ethereum/logger"
 |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func RunStateTest(p string) error { | func RunStateTest(p string) error { | ||||||
| @ -109,7 +105,7 @@ func RunStateTest(p string) error { | |||||||
| 
 | 
 | ||||||
| 		// check logs
 | 		// check logs
 | ||||||
| 		if len(test.Logs) > 0 { | 		if len(test.Logs) > 0 { | ||||||
| 			lerr := CheckLogs(test.Logs, logs, t) | 			lerr := checkLogs(test.Logs, logs) | ||||||
| 			if lerr != nil { | 			if lerr != nil { | ||||||
| 				return fmt.Errorf("'%s' ", name, lerr.Error()) | 				return fmt.Errorf("'%s' ", name, lerr.Error()) | ||||||
| 			} | 			} | ||||||
| @ -118,39 +114,6 @@ func RunStateTest(p string) error { | |||||||
| 		fmt.Println("State test passed: ", name) | 		fmt.Println("State test passed: ", name) | ||||||
| 		//fmt.Println(string(statedb.Dump()))
 | 		//fmt.Println(string(statedb.Dump()))
 | ||||||
| 	} | 	} | ||||||
| 	// logger.Flush()
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func CheckLogs(tlog []Log, logs state.Logs, t *testing.T) error { |  | ||||||
| 
 |  | ||||||
| 	if len(tlog) != len(logs) { |  | ||||||
| 		return fmt.Errorf("log length mismatch. Expected %d, got %d", len(tlog), len(logs)) |  | ||||||
| 	} else { |  | ||||||
| 		for i, log := range tlog { |  | ||||||
| 			if common.HexToAddress(log.AddressF) != logs[i].Address { |  | ||||||
| 				return fmt.Errorf("log address expected %v got %x", log.AddressF, logs[i].Address) |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			if !bytes.Equal(logs[i].Data, common.FromHex(log.DataF)) { |  | ||||||
| 				return fmt.Errorf("log data expected %v got %x", log.DataF, logs[i].Data) |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			if len(log.TopicsF) != len(logs[i].Topics) { |  | ||||||
| 				return fmt.Errorf("log topics length expected %d got %d", len(log.TopicsF), logs[i].Topics) |  | ||||||
| 			} else { |  | ||||||
| 				for j, topic := range log.TopicsF { |  | ||||||
| 					if common.HexToHash(topic) != logs[i].Topics[j] { |  | ||||||
| 						return fmt.Errorf("log topic[%d] expected %v got %x", j, topic, logs[i].Topics[j]) |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 			genBloom := common.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 256) |  | ||||||
| 
 |  | ||||||
| 			if !bytes.Equal(genBloom, common.Hex2Bytes(log.BloomF)) { |  | ||||||
| 				return fmt.Errorf("bloom mismatch") |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -5,8 +5,6 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var transactionTestDir = filepath.Join(baseDir, "TransactionTests") |  | ||||||
| 
 |  | ||||||
| func TestTransactions(t *testing.T) { | func TestTransactions(t *testing.T) { | ||||||
| 	notWorking := make(map[string]bool, 100) | 	notWorking := make(map[string]bool, 100) | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										252
									
								
								tests/util.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										252
									
								
								tests/util.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,252 @@ | |||||||
|  | package tests | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"errors" | ||||||
|  | 	"fmt" | ||||||
|  | 	"math/big" | ||||||
|  | 
 | ||||||
|  | 	"github.com/ethereum/go-ethereum/common" | ||||||
|  | 	"github.com/ethereum/go-ethereum/core" | ||||||
|  | 	"github.com/ethereum/go-ethereum/core/state" | ||||||
|  | 	"github.com/ethereum/go-ethereum/core/types" | ||||||
|  | 	"github.com/ethereum/go-ethereum/core/vm" | ||||||
|  | 	"github.com/ethereum/go-ethereum/crypto" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func checkLogs(tlog []Log, logs state.Logs) error { | ||||||
|  | 
 | ||||||
|  | 	if len(tlog) != len(logs) { | ||||||
|  | 		return fmt.Errorf("log length mismatch. Expected %d, got %d", len(tlog), len(logs)) | ||||||
|  | 	} else { | ||||||
|  | 		for i, log := range tlog { | ||||||
|  | 			if common.HexToAddress(log.AddressF) != logs[i].Address { | ||||||
|  | 				return fmt.Errorf("log address expected %v got %x", log.AddressF, logs[i].Address) | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if !bytes.Equal(logs[i].Data, common.FromHex(log.DataF)) { | ||||||
|  | 				return fmt.Errorf("log data expected %v got %x", log.DataF, logs[i].Data) | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if len(log.TopicsF) != len(logs[i].Topics) { | ||||||
|  | 				return fmt.Errorf("log topics length expected %d got %d", len(log.TopicsF), logs[i].Topics) | ||||||
|  | 			} else { | ||||||
|  | 				for j, topic := range log.TopicsF { | ||||||
|  | 					if common.HexToHash(topic) != logs[i].Topics[j] { | ||||||
|  | 						return fmt.Errorf("log topic[%d] expected %v got %x", j, topic, logs[i].Topics[j]) | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			genBloom := common.LeftPadBytes(types.LogsBloom(state.Logs{logs[i]}).Bytes(), 256) | ||||||
|  | 
 | ||||||
|  | 			if !bytes.Equal(genBloom, common.Hex2Bytes(log.BloomF)) { | ||||||
|  | 				return fmt.Errorf("bloom mismatch") | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type Account struct { | ||||||
|  | 	Balance string | ||||||
|  | 	Code    string | ||||||
|  | 	Nonce   string | ||||||
|  | 	Storage map[string]string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type Log struct { | ||||||
|  | 	AddressF string   `json:"address"` | ||||||
|  | 	DataF    string   `json:"data"` | ||||||
|  | 	TopicsF  []string `json:"topics"` | ||||||
|  | 	BloomF   string   `json:"bloom"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (self Log) Address() []byte      { return common.Hex2Bytes(self.AddressF) } | ||||||
|  | func (self Log) Data() []byte         { return common.Hex2Bytes(self.DataF) } | ||||||
|  | func (self Log) RlpData() interface{} { return nil } | ||||||
|  | func (self Log) Topics() [][]byte { | ||||||
|  | 	t := make([][]byte, len(self.TopicsF)) | ||||||
|  | 	for i, topic := range self.TopicsF { | ||||||
|  | 		t[i] = common.Hex2Bytes(topic) | ||||||
|  | 	} | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func StateObjectFromAccount(db common.Database, addr string, account Account) *state.StateObject { | ||||||
|  | 	obj := state.NewStateObject(common.HexToAddress(addr), db) | ||||||
|  | 	obj.SetBalance(common.Big(account.Balance)) | ||||||
|  | 
 | ||||||
|  | 	if common.IsHex(account.Code) { | ||||||
|  | 		account.Code = account.Code[2:] | ||||||
|  | 	} | ||||||
|  | 	obj.SetCode(common.Hex2Bytes(account.Code)) | ||||||
|  | 	obj.SetNonce(common.Big(account.Nonce).Uint64()) | ||||||
|  | 
 | ||||||
|  | 	return obj | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type VmEnv struct { | ||||||
|  | 	CurrentCoinbase   string | ||||||
|  | 	CurrentDifficulty string | ||||||
|  | 	CurrentGasLimit   string | ||||||
|  | 	CurrentNumber     string | ||||||
|  | 	CurrentTimestamp  interface{} | ||||||
|  | 	PreviousHash      string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type VmTest struct { | ||||||
|  | 	Callcreates interface{} | ||||||
|  | 	//Env         map[string]string
 | ||||||
|  | 	Env           VmEnv | ||||||
|  | 	Exec          map[string]string | ||||||
|  | 	Transaction   map[string]string | ||||||
|  | 	Logs          []Log | ||||||
|  | 	Gas           string | ||||||
|  | 	Out           string | ||||||
|  | 	Post          map[string]Account | ||||||
|  | 	Pre           map[string]Account | ||||||
|  | 	PostStateRoot string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type Env struct { | ||||||
|  | 	depth        int | ||||||
|  | 	state        *state.StateDB | ||||||
|  | 	skipTransfer bool | ||||||
|  | 	initial      bool | ||||||
|  | 	Gas          *big.Int | ||||||
|  | 
 | ||||||
|  | 	origin common.Address | ||||||
|  | 	//parent   common.Hash
 | ||||||
|  | 	coinbase common.Address | ||||||
|  | 
 | ||||||
|  | 	number     *big.Int | ||||||
|  | 	time       int64 | ||||||
|  | 	difficulty *big.Int | ||||||
|  | 	gasLimit   *big.Int | ||||||
|  | 
 | ||||||
|  | 	logs state.Logs | ||||||
|  | 
 | ||||||
|  | 	vmTest bool | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func NewEnv(state *state.StateDB) *Env { | ||||||
|  | 	return &Env{ | ||||||
|  | 		state: state, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func NewEnvFromMap(state *state.StateDB, envValues map[string]string, exeValues map[string]string) *Env { | ||||||
|  | 	env := NewEnv(state) | ||||||
|  | 
 | ||||||
|  | 	env.origin = common.HexToAddress(exeValues["caller"]) | ||||||
|  | 	//env.parent = common.Hex2Bytes(envValues["previousHash"])
 | ||||||
|  | 	env.coinbase = common.HexToAddress(envValues["currentCoinbase"]) | ||||||
|  | 	env.number = common.Big(envValues["currentNumber"]) | ||||||
|  | 	env.time = common.Big(envValues["currentTimestamp"]).Int64() | ||||||
|  | 	env.difficulty = common.Big(envValues["currentDifficulty"]) | ||||||
|  | 	env.gasLimit = common.Big(envValues["currentGasLimit"]) | ||||||
|  | 	env.Gas = new(big.Int) | ||||||
|  | 
 | ||||||
|  | 	return env | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (self *Env) Origin() common.Address { return self.origin } | ||||||
|  | func (self *Env) BlockNumber() *big.Int  { return self.number } | ||||||
|  | 
 | ||||||
|  | //func (self *Env) PrevHash() []byte      { return self.parent }
 | ||||||
|  | func (self *Env) Coinbase() common.Address { return self.coinbase } | ||||||
|  | func (self *Env) Time() int64              { return self.time } | ||||||
|  | func (self *Env) Difficulty() *big.Int     { return self.difficulty } | ||||||
|  | func (self *Env) State() *state.StateDB    { return self.state } | ||||||
|  | func (self *Env) GasLimit() *big.Int       { return self.gasLimit } | ||||||
|  | func (self *Env) VmType() vm.Type          { return vm.StdVmTy } | ||||||
|  | func (self *Env) GetHash(n uint64) common.Hash { | ||||||
|  | 	return common.BytesToHash(crypto.Sha3([]byte(big.NewInt(int64(n)).String()))) | ||||||
|  | } | ||||||
|  | func (self *Env) AddLog(log *state.Log) { | ||||||
|  | 	self.state.AddLog(log) | ||||||
|  | } | ||||||
|  | func (self *Env) Depth() int     { return self.depth } | ||||||
|  | func (self *Env) SetDepth(i int) { self.depth = i } | ||||||
|  | func (self *Env) Transfer(from, to vm.Account, amount *big.Int) error { | ||||||
|  | 	if self.skipTransfer { | ||||||
|  | 		// ugly hack
 | ||||||
|  | 		if self.initial { | ||||||
|  | 			self.initial = false | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if from.Balance().Cmp(amount) < 0 { | ||||||
|  | 			return errors.New("Insufficient balance in account") | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	return vm.Transfer(from, to, amount) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (self *Env) vm(addr *common.Address, data []byte, gas, price, value *big.Int) *core.Execution { | ||||||
|  | 	exec := core.NewExecution(self, addr, data, gas, price, value) | ||||||
|  | 
 | ||||||
|  | 	return exec | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (self *Env) Call(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) { | ||||||
|  | 	if self.vmTest && self.depth > 0 { | ||||||
|  | 		caller.ReturnGas(gas, price) | ||||||
|  | 
 | ||||||
|  | 		return nil, nil | ||||||
|  | 	} | ||||||
|  | 	exe := self.vm(&addr, data, gas, price, value) | ||||||
|  | 	ret, err := exe.Call(addr, caller) | ||||||
|  | 	self.Gas = exe.Gas | ||||||
|  | 
 | ||||||
|  | 	return ret, err | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | func (self *Env) CallCode(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) { | ||||||
|  | 	if self.vmTest && self.depth > 0 { | ||||||
|  | 		caller.ReturnGas(gas, price) | ||||||
|  | 
 | ||||||
|  | 		return nil, nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	caddr := caller.Address() | ||||||
|  | 	exe := self.vm(&caddr, data, gas, price, value) | ||||||
|  | 	return exe.Call(addr, caller) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (self *Env) Create(caller vm.ContextRef, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) { | ||||||
|  | 	exe := self.vm(nil, data, gas, price, value) | ||||||
|  | 	if self.vmTest { | ||||||
|  | 		caller.ReturnGas(gas, price) | ||||||
|  | 
 | ||||||
|  | 		nonce := self.state.GetNonce(caller.Address()) | ||||||
|  | 		obj := self.state.GetOrNewStateObject(crypto.CreateAddress(caller.Address(), nonce)) | ||||||
|  | 
 | ||||||
|  | 		return nil, nil, obj | ||||||
|  | 	} else { | ||||||
|  | 		return exe.Create(caller) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type Message struct { | ||||||
|  | 	from              common.Address | ||||||
|  | 	to                *common.Address | ||||||
|  | 	value, gas, price *big.Int | ||||||
|  | 	data              []byte | ||||||
|  | 	nonce             uint64 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func NewMessage(from common.Address, to *common.Address, data []byte, value, gas, price *big.Int, nonce uint64) Message { | ||||||
|  | 	return Message{from, to, value, gas, price, data, nonce} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (self Message) Hash() []byte                  { return nil } | ||||||
|  | func (self Message) From() (common.Address, error) { return self.from, nil } | ||||||
|  | func (self Message) To() *common.Address           { return self.to } | ||||||
|  | func (self Message) GasPrice() *big.Int            { return self.price } | ||||||
|  | func (self Message) Gas() *big.Int                 { return self.gas } | ||||||
|  | func (self Message) Value() *big.Int               { return self.value } | ||||||
|  | func (self Message) Nonce() uint64                 { return self.nonce } | ||||||
|  | func (self Message) Data() []byte                  { return self.data } | ||||||
| @ -5,8 +5,6 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var vmTestDir = filepath.Join(baseDir, "VMTests") |  | ||||||
| 
 |  | ||||||
| // I've created a new function for each tests so it's easier to identify where the problem lies if any of them fail.
 | // I've created a new function for each tests so it's easier to identify where the problem lies if any of them fail.
 | ||||||
| func TestVMArithmetic(t *testing.T) { | func TestVMArithmetic(t *testing.T) { | ||||||
| 	fn := filepath.Join(vmTestDir, "vmArithmeticTest.json") | 	fn := filepath.Join(vmTestDir, "vmArithmeticTest.json") | ||||||
|  | |||||||
| @ -2,83 +2,16 @@ package tests | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
| 	"errors" |  | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"math/big" | 	"math/big" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	// "testing"
 |  | ||||||
| 
 | 
 | ||||||
| 	"github.com/ethereum/go-ethereum/common" | 	"github.com/ethereum/go-ethereum/common" | ||||||
| 	"github.com/ethereum/go-ethereum/core" |  | ||||||
| 	"github.com/ethereum/go-ethereum/core/state" | 	"github.com/ethereum/go-ethereum/core/state" | ||||||
| 	// "github.com/ethereum/go-ethereum/core/types"
 |  | ||||||
| 	"github.com/ethereum/go-ethereum/core/vm" | 	"github.com/ethereum/go-ethereum/core/vm" | ||||||
| 	"github.com/ethereum/go-ethereum/crypto" |  | ||||||
| 	"github.com/ethereum/go-ethereum/ethdb" | 	"github.com/ethereum/go-ethereum/ethdb" | ||||||
| 	// "github.com/ethereum/go-ethereum/logger"
 |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type Account struct { |  | ||||||
| 	Balance string |  | ||||||
| 	Code    string |  | ||||||
| 	Nonce   string |  | ||||||
| 	Storage map[string]string |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type Log struct { |  | ||||||
| 	AddressF string   `json:"address"` |  | ||||||
| 	DataF    string   `json:"data"` |  | ||||||
| 	TopicsF  []string `json:"topics"` |  | ||||||
| 	BloomF   string   `json:"bloom"` |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (self Log) Address() []byte      { return common.Hex2Bytes(self.AddressF) } |  | ||||||
| func (self Log) Data() []byte         { return common.Hex2Bytes(self.DataF) } |  | ||||||
| func (self Log) RlpData() interface{} { return nil } |  | ||||||
| func (self Log) Topics() [][]byte { |  | ||||||
| 	t := make([][]byte, len(self.TopicsF)) |  | ||||||
| 	for i, topic := range self.TopicsF { |  | ||||||
| 		t[i] = common.Hex2Bytes(topic) |  | ||||||
| 	} |  | ||||||
| 	return t |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func StateObjectFromAccount(db common.Database, addr string, account Account) *state.StateObject { |  | ||||||
| 	obj := state.NewStateObject(common.HexToAddress(addr), db) |  | ||||||
| 	obj.SetBalance(common.Big(account.Balance)) |  | ||||||
| 
 |  | ||||||
| 	if common.IsHex(account.Code) { |  | ||||||
| 		account.Code = account.Code[2:] |  | ||||||
| 	} |  | ||||||
| 	obj.SetCode(common.Hex2Bytes(account.Code)) |  | ||||||
| 	obj.SetNonce(common.Big(account.Nonce).Uint64()) |  | ||||||
| 
 |  | ||||||
| 	return obj |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type VmEnv struct { |  | ||||||
| 	CurrentCoinbase   string |  | ||||||
| 	CurrentDifficulty string |  | ||||||
| 	CurrentGasLimit   string |  | ||||||
| 	CurrentNumber     string |  | ||||||
| 	CurrentTimestamp  interface{} |  | ||||||
| 	PreviousHash      string |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type VmTest struct { |  | ||||||
| 	Callcreates interface{} |  | ||||||
| 	//Env         map[string]string
 |  | ||||||
| 	Env           VmEnv |  | ||||||
| 	Exec          map[string]string |  | ||||||
| 	Transaction   map[string]string |  | ||||||
| 	Logs          []Log |  | ||||||
| 	Gas           string |  | ||||||
| 	Out           string |  | ||||||
| 	Post          map[string]Account |  | ||||||
| 	Pre           map[string]Account |  | ||||||
| 	PostStateRoot string |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func RunVmTest(p string) error { | func RunVmTest(p string) error { | ||||||
| 
 | 
 | ||||||
| 	tests := make(map[string]VmTest) | 	tests := make(map[string]VmTest) | ||||||
| @ -163,139 +96,19 @@ func RunVmTest(p string) error { | |||||||
| 
 | 
 | ||||||
| 		// check logs
 | 		// check logs
 | ||||||
| 		if len(test.Logs) > 0 { | 		if len(test.Logs) > 0 { | ||||||
| 			CheckLogs(test.Logs, logs, t) | 			lerr := checkLogs(test.Logs, logs) | ||||||
|  | 			if lerr != nil { | ||||||
|  | 				return fmt.Errorf("'%s' ", name, lerr.Error()) | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		fmt.Println("VM test passed: ", name) | 		fmt.Println("VM test passed: ", name) | ||||||
| 
 | 
 | ||||||
| 		//fmt.Println(string(statedb.Dump()))
 | 		//fmt.Println(string(statedb.Dump()))
 | ||||||
| 	} | 	} | ||||||
| 	// logger.Flush()
 |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type Env struct { |  | ||||||
| 	depth        int |  | ||||||
| 	state        *state.StateDB |  | ||||||
| 	skipTransfer bool |  | ||||||
| 	initial      bool |  | ||||||
| 	Gas          *big.Int |  | ||||||
| 
 |  | ||||||
| 	origin common.Address |  | ||||||
| 	//parent   common.Hash
 |  | ||||||
| 	coinbase common.Address |  | ||||||
| 
 |  | ||||||
| 	number     *big.Int |  | ||||||
| 	time       int64 |  | ||||||
| 	difficulty *big.Int |  | ||||||
| 	gasLimit   *big.Int |  | ||||||
| 
 |  | ||||||
| 	logs state.Logs |  | ||||||
| 
 |  | ||||||
| 	vmTest bool |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewEnv(state *state.StateDB) *Env { |  | ||||||
| 	return &Env{ |  | ||||||
| 		state: state, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewEnvFromMap(state *state.StateDB, envValues map[string]string, exeValues map[string]string) *Env { |  | ||||||
| 	env := NewEnv(state) |  | ||||||
| 
 |  | ||||||
| 	env.origin = common.HexToAddress(exeValues["caller"]) |  | ||||||
| 	//env.parent = common.Hex2Bytes(envValues["previousHash"])
 |  | ||||||
| 	env.coinbase = common.HexToAddress(envValues["currentCoinbase"]) |  | ||||||
| 	env.number = common.Big(envValues["currentNumber"]) |  | ||||||
| 	env.time = common.Big(envValues["currentTimestamp"]).Int64() |  | ||||||
| 	env.difficulty = common.Big(envValues["currentDifficulty"]) |  | ||||||
| 	env.gasLimit = common.Big(envValues["currentGasLimit"]) |  | ||||||
| 	env.Gas = new(big.Int) |  | ||||||
| 
 |  | ||||||
| 	return env |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (self *Env) Origin() common.Address { return self.origin } |  | ||||||
| func (self *Env) BlockNumber() *big.Int  { return self.number } |  | ||||||
| 
 |  | ||||||
| //func (self *Env) PrevHash() []byte      { return self.parent }
 |  | ||||||
| func (self *Env) Coinbase() common.Address { return self.coinbase } |  | ||||||
| func (self *Env) Time() int64              { return self.time } |  | ||||||
| func (self *Env) Difficulty() *big.Int     { return self.difficulty } |  | ||||||
| func (self *Env) State() *state.StateDB    { return self.state } |  | ||||||
| func (self *Env) GasLimit() *big.Int       { return self.gasLimit } |  | ||||||
| func (self *Env) VmType() vm.Type          { return vm.StdVmTy } |  | ||||||
| func (self *Env) GetHash(n uint64) common.Hash { |  | ||||||
| 	return common.BytesToHash(crypto.Sha3([]byte(big.NewInt(int64(n)).String()))) |  | ||||||
| } |  | ||||||
| func (self *Env) AddLog(log *state.Log) { |  | ||||||
| 	self.state.AddLog(log) |  | ||||||
| } |  | ||||||
| func (self *Env) Depth() int     { return self.depth } |  | ||||||
| func (self *Env) SetDepth(i int) { self.depth = i } |  | ||||||
| func (self *Env) Transfer(from, to vm.Account, amount *big.Int) error { |  | ||||||
| 	if self.skipTransfer { |  | ||||||
| 		// ugly hack
 |  | ||||||
| 		if self.initial { |  | ||||||
| 			self.initial = false |  | ||||||
| 			return nil |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		if from.Balance().Cmp(amount) < 0 { |  | ||||||
| 			return errors.New("Insufficient balance in account") |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	return vm.Transfer(from, to, amount) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (self *Env) vm(addr *common.Address, data []byte, gas, price, value *big.Int) *core.Execution { |  | ||||||
| 	exec := core.NewExecution(self, addr, data, gas, price, value) |  | ||||||
| 
 |  | ||||||
| 	return exec |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (self *Env) Call(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) { |  | ||||||
| 	if self.vmTest && self.depth > 0 { |  | ||||||
| 		caller.ReturnGas(gas, price) |  | ||||||
| 
 |  | ||||||
| 		return nil, nil |  | ||||||
| 	} |  | ||||||
| 	exe := self.vm(&addr, data, gas, price, value) |  | ||||||
| 	ret, err := exe.Call(addr, caller) |  | ||||||
| 	self.Gas = exe.Gas |  | ||||||
| 
 |  | ||||||
| 	return ret, err |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| func (self *Env) CallCode(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) { |  | ||||||
| 	if self.vmTest && self.depth > 0 { |  | ||||||
| 		caller.ReturnGas(gas, price) |  | ||||||
| 
 |  | ||||||
| 		return nil, nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	caddr := caller.Address() |  | ||||||
| 	exe := self.vm(&caddr, data, gas, price, value) |  | ||||||
| 	return exe.Call(addr, caller) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (self *Env) Create(caller vm.ContextRef, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) { |  | ||||||
| 	exe := self.vm(nil, data, gas, price, value) |  | ||||||
| 	if self.vmTest { |  | ||||||
| 		caller.ReturnGas(gas, price) |  | ||||||
| 
 |  | ||||||
| 		nonce := self.state.GetNonce(caller.Address()) |  | ||||||
| 		obj := self.state.GetOrNewStateObject(crypto.CreateAddress(caller.Address(), nonce)) |  | ||||||
| 
 |  | ||||||
| 		return nil, nil, obj |  | ||||||
| 	} else { |  | ||||||
| 		return exe.Create(caller) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Logs, *big.Int, error) { | func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Logs, *big.Int, error) { | ||||||
| 	var ( | 	var ( | ||||||
| 		to    = common.HexToAddress(exec["address"]) | 		to    = common.HexToAddress(exec["address"]) | ||||||
| @ -318,24 +131,3 @@ func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Log | |||||||
| 
 | 
 | ||||||
| 	return ret, vmenv.state.Logs(), vmenv.Gas, err | 	return ret, vmenv.state.Logs(), vmenv.Gas, err | ||||||
| } | } | ||||||
| 
 |  | ||||||
| type Message struct { |  | ||||||
| 	from              common.Address |  | ||||||
| 	to                *common.Address |  | ||||||
| 	value, gas, price *big.Int |  | ||||||
| 	data              []byte |  | ||||||
| 	nonce             uint64 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewMessage(from common.Address, to *common.Address, data []byte, value, gas, price *big.Int, nonce uint64) Message { |  | ||||||
| 	return Message{from, to, value, gas, price, data, nonce} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (self Message) Hash() []byte                  { return nil } |  | ||||||
| func (self Message) From() (common.Address, error) { return self.from, nil } |  | ||||||
| func (self Message) To() *common.Address           { return self.to } |  | ||||||
| func (self Message) GasPrice() *big.Int            { return self.price } |  | ||||||
| func (self Message) Gas() *big.Int                 { return self.gas } |  | ||||||
| func (self Message) Value() *big.Int               { return self.value } |  | ||||||
| func (self Message) Nonce() uint64                 { return self.nonce } |  | ||||||
| func (self Message) Data() []byte                  { return self.data } |  | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user