Merge branch 'develop' into poc8
This commit is contained in:
		
						commit
						e6fdf0c9f7
					
				| @ -152,6 +152,16 @@ func (bc *ChainManager) Reset() { | ||||
| 	bc.TD = ethutil.BigD(ethutil.Config.Db.LastKnownTD()) | ||||
| } | ||||
| 
 | ||||
| func (self *ChainManager) Export() []byte { | ||||
| 	chainlogger.Infoln("exporting", self.CurrentBlock.Number, "blocks") | ||||
| 
 | ||||
| 	blocks := make(types.Blocks, int(self.CurrentBlock.Number.Int64())+1) | ||||
| 	for block := self.CurrentBlock; block != nil; block = self.GetBlock(block.PrevHash) { | ||||
| 		blocks[block.Number.Int64()] = block | ||||
| 	} | ||||
| 	return ethutil.Encode(blocks) | ||||
| } | ||||
| 
 | ||||
| func (bc *ChainManager) insert(block *types.Block) { | ||||
| 	encodedBlock := block.RlpEncode() | ||||
| 	ethutil.Config.Db.Put([]byte("LastBlock"), encodedBlock) | ||||
| @ -185,7 +195,6 @@ func (self *ChainManager) GetBlockHashesFromHash(hash []byte, max uint64) (chain | ||||
| 
 | ||||
| 	// XXX Could be optimised by using a different database which only holds hashes (i.e., linked list)
 | ||||
| 	for i := uint64(0); i < max; i++ { | ||||
| 
 | ||||
| 		chain = append(chain, block.Hash()) | ||||
| 
 | ||||
| 		if block.Number.Cmp(ethutil.Big0) <= 0 { | ||||
|  | ||||
| @ -1 +1,19 @@ | ||||
| package core | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"path" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/ethereum/go-ethereum/ethutil" | ||||
| ) | ||||
| 
 | ||||
| func TestChainInsertions(t *testing.T) { | ||||
| 	c1, err := ethutil.ReadAllFile(path.Join("..", "_data", "chain1")) | ||||
| 	if err != nil { | ||||
| 		fmt.Println(err) | ||||
| 		t.FailNow() | ||||
| 	} | ||||
| 	data1, _ := ethutil.Decode([]byte(c1), 0) | ||||
| 	fmt.Println(data1) | ||||
| } | ||||
|  | ||||
| @ -4,7 +4,6 @@ import ( | ||||
| 	"fmt" | ||||
| 	"math/big" | ||||
| 
 | ||||
| 	"github.com/ethereum/go-ethereum/ethutil" | ||||
| 	"github.com/ethereum/go-ethereum/state" | ||||
| 	"github.com/ethereum/go-ethereum/vm" | ||||
| ) | ||||
| @ -36,38 +35,33 @@ func (self *Execution) exec(code, contextAddr []byte, caller vm.ClosureRef) (ret | ||||
| 	env := self.vm.Env() | ||||
| 	chainlogger.Debugf("pre state %x\n", env.State().Root()) | ||||
| 
 | ||||
| 	if self.vm.Env().Depth() == vm.MaxCallDepth { | ||||
| 		// Consume all gas (by not returning it) and return a depth error
 | ||||
| 		return nil, vm.DepthError{} | ||||
| 	} | ||||
| 
 | ||||
| 	from, to := env.State().GetStateObject(caller.Address()), env.State().GetOrNewStateObject(self.address) | ||||
| 	// Skipping transfer is used on testing for the initial call
 | ||||
| 	if !self.SkipTransfer { | ||||
| 		err = env.Transfer(from, to, self.value) | ||||
| 		if err != nil { | ||||
| 			caller.ReturnGas(self.Gas, self.price) | ||||
| 
 | ||||
| 			err = fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, from.Balance) | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	snapshot := env.State().Copy() | ||||
| 	defer func() { | ||||
| 		if vm.IsDepthErr(err) || vm.IsOOGErr(err) { | ||||
| 		if /*vm.IsDepthErr(err) ||*/ vm.IsOOGErr(err) { | ||||
| 			env.State().Set(snapshot) | ||||
| 		} | ||||
| 		chainlogger.Debugf("post state %x\n", env.State().Root()) | ||||
| 	}() | ||||
| 
 | ||||
| 	if err != nil { | ||||
| 		caller.ReturnGas(self.Gas, self.price) | ||||
| 
 | ||||
| 		err = fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, from.Balance) | ||||
| 	} else { | ||||
| 		self.object = to | ||||
| 		// Pre-compiled contracts (address.go) 1, 2 & 3.
 | ||||
| 		naddr := ethutil.BigD(contextAddr).Uint64() | ||||
| 		if p := vm.Precompiled[naddr]; p != nil { | ||||
| 			if self.Gas.Cmp(p.Gas(len(self.input))) >= 0 { | ||||
| 				ret = p.Call(self.input) | ||||
| 				self.vm.Printf("NATIVE_FUNC(%x) => %x", naddr, ret) | ||||
| 				self.vm.Endl() | ||||
| 			} | ||||
| 		} else { | ||||
| 			ret, err = self.vm.Run(to, caller, code, self.value, self.Gas, self.price, self.input) | ||||
| 		} | ||||
| 	} | ||||
| 	self.object = to | ||||
| 	ret, err = self.vm.Run(to, caller, code, self.value, self.Gas, self.price, self.input) | ||||
| 
 | ||||
| 	return | ||||
| } | ||||
|  | ||||
| @ -2,8 +2,10 @@ package ethutil | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/binary" | ||||
| 	"fmt" | ||||
| 	"math/big" | ||||
| 	"reflect" | ||||
| ) | ||||
| 
 | ||||
| type RlpEncode interface { | ||||
| @ -97,6 +99,14 @@ var ( | ||||
| 	zeroRlp   = big.NewInt(0x0) | ||||
| ) | ||||
| 
 | ||||
| func intlen(i int64) (length int) { | ||||
| 	for i > 0 { | ||||
| 		i = i >> 8 | ||||
| 		length++ | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func Encode(object interface{}) []byte { | ||||
| 	var buff bytes.Buffer | ||||
| 
 | ||||
| @ -168,6 +178,26 @@ func Encode(object interface{}) []byte { | ||||
| 			} | ||||
| 			WriteSliceHeader(len(b.Bytes())) | ||||
| 			buff.Write(b.Bytes()) | ||||
| 		default: | ||||
| 			// This is how it should have been from the start
 | ||||
| 			// needs refactoring (@fjl)
 | ||||
| 			v := reflect.ValueOf(t) | ||||
| 			switch v.Kind() { | ||||
| 			case reflect.Slice: | ||||
| 				var b bytes.Buffer | ||||
| 				for i := 0; i < v.Len(); i++ { | ||||
| 					b.Write(Encode(v.Index(i).Interface())) | ||||
| 				} | ||||
| 
 | ||||
| 				blen := b.Len() | ||||
| 				if blen < 56 { | ||||
| 					buff.WriteByte(byte(blen) + 0xc0) | ||||
| 				} else { | ||||
| 					buff.WriteByte(byte(intlen(int64(blen))) + 0xf7) | ||||
| 					binary.Write(&buff, binary.BigEndian, int64(blen)) | ||||
| 				} | ||||
| 				buff.ReadFrom(&b) | ||||
| 			} | ||||
| 		} | ||||
| 	} else { | ||||
| 		// Empty list for nil
 | ||||
|  | ||||
| @ -7,6 +7,16 @@ import ( | ||||
| 	"testing" | ||||
| ) | ||||
| 
 | ||||
| func TestNonInterfaceSlice(t *testing.T) { | ||||
| 	vala := []string{"value1", "value2", "value3"} | ||||
| 	valb := []interface{}{"value1", "value2", "value3"} | ||||
| 	resa := Encode(vala) | ||||
| 	resb := Encode(valb) | ||||
| 	if !bytes.Equal(resa, resb) { | ||||
| 		t.Errorf("expected []string & []interface{} to be equal") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestRlpValueEncoding(t *testing.T) { | ||||
| 	val := EmptyValue() | ||||
| 	val.AppendList().Append(1).Append(2).Append(3) | ||||
|  | ||||
| @ -121,6 +121,7 @@ func (self *JSRE) initStdFuncs() { | ||||
| 	eth.Set("startMining", self.startMining) | ||||
| 	eth.Set("execBlock", self.execBlock) | ||||
| 	eth.Set("dump", self.dump) | ||||
| 	eth.Set("export", self.export) | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| @ -236,3 +237,20 @@ func (self *JSRE) execBlock(call otto.FunctionCall) otto.Value { | ||||
| 
 | ||||
| 	return otto.TrueValue() | ||||
| } | ||||
| 
 | ||||
| func (self *JSRE) export(call otto.FunctionCall) otto.Value { | ||||
| 	fn, err := call.Argument(0).ToString() | ||||
| 	if err != nil { | ||||
| 		fmt.Println(err) | ||||
| 		return otto.FalseValue() | ||||
| 	} | ||||
| 
 | ||||
| 	data := self.ethereum.ChainManager().Export() | ||||
| 
 | ||||
| 	if err := ethutil.WriteFile(fn, data); err != nil { | ||||
| 		fmt.Println(err) | ||||
| 		return otto.FalseValue() | ||||
| 	} | ||||
| 
 | ||||
| 	return otto.TrueValue() | ||||
| } | ||||
|  | ||||
| @ -11,25 +11,25 @@ type Address interface { | ||||
| 	Call(in []byte) []byte | ||||
| } | ||||
| 
 | ||||
| type PrecompiledAddress struct { | ||||
| type PrecompiledAccount struct { | ||||
| 	Gas func(l int) *big.Int | ||||
| 	fn  func(in []byte) []byte | ||||
| } | ||||
| 
 | ||||
| func (self PrecompiledAddress) Call(in []byte) []byte { | ||||
| func (self PrecompiledAccount) Call(in []byte) []byte { | ||||
| 	return self.fn(in) | ||||
| } | ||||
| 
 | ||||
| var Precompiled = map[uint64]*PrecompiledAddress{ | ||||
| 	1: &PrecompiledAddress{func(l int) *big.Int { | ||||
| var Precompiled = map[string]*PrecompiledAccount{ | ||||
| 	string(ethutil.LeftPadBytes([]byte{1}, 20)): &PrecompiledAccount{func(l int) *big.Int { | ||||
| 		return GasEcrecover | ||||
| 	}, ecrecoverFunc}, | ||||
| 	2: &PrecompiledAddress{func(l int) *big.Int { | ||||
| 	string(ethutil.LeftPadBytes([]byte{2}, 20)): &PrecompiledAccount{func(l int) *big.Int { | ||||
| 		n := big.NewInt(int64(l+31)/32 + 1) | ||||
| 		n.Mul(n, GasSha256) | ||||
| 		return n | ||||
| 	}, sha256Func}, | ||||
| 	3: &PrecompiledAddress{func(l int) *big.Int { | ||||
| 	string(ethutil.LeftPadBytes([]byte{3}, 20)): &PrecompiledAccount{func(l int) *big.Int { | ||||
| 		n := big.NewInt(int64(l+31)/32 + 1) | ||||
| 		n.Mul(n, GasRipemd) | ||||
| 		return n | ||||
|  | ||||
| @ -48,7 +48,7 @@ var ( | ||||
| 	S256 = ethutil.S256 | ||||
| ) | ||||
| 
 | ||||
| const MaxCallDepth = 1025 | ||||
| const MaxCallDepth = 1024 | ||||
| 
 | ||||
| func calcMemSize(off, l *big.Int) *big.Int { | ||||
| 	if l.Cmp(ethutil.Big0) == 0 { | ||||
|  | ||||
| @ -48,9 +48,8 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * | ||||
| 	}) | ||||
| 	closure := NewClosure(msg, caller, me, code, gas, price) | ||||
| 
 | ||||
| 	if self.env.Depth() == MaxCallDepth { | ||||
| 		//closure.UseGas(gas)
 | ||||
| 		return closure.Return(nil), DepthError{} | ||||
| 	if p := Precompiled[string(me.Address())]; p != nil { | ||||
| 		return self.RunPrecompiled(p, callData, closure) | ||||
| 	} | ||||
| 
 | ||||
| 	if self.Recoverable { | ||||
| @ -941,6 +940,25 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (self *DebugVm) RunPrecompiled(p *PrecompiledAccount, callData []byte, closure *Closure) (ret []byte, err error) { | ||||
| 	gas := p.Gas(len(callData)) | ||||
| 	if closure.UseGas(gas) { | ||||
| 		ret = p.Call(callData) | ||||
| 		self.Printf("NATIVE_FUNC => %x", ret) | ||||
| 		self.Endl() | ||||
| 
 | ||||
| 		return closure.Return(ret), nil | ||||
| 	} else { | ||||
| 		self.Endl() | ||||
| 
 | ||||
| 		tmp := new(big.Int).Set(closure.Gas) | ||||
| 
 | ||||
| 		closure.UseGas(closure.Gas) | ||||
| 
 | ||||
| 		return closure.Return(nil), OOG(gas, tmp) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (self *DebugVm) Printf(format string, v ...interface{}) VirtualMachine { | ||||
| 	if self.logTy == LogTyPretty { | ||||
| 		self.logStr += fmt.Sprintf(format, v...) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user