These changes ensure that the JS tests run without networking and fixes the block chain export and its associated test.
		
			
				
	
	
		
			418 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			418 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package main
 | 
						|
 | 
						|
import (
 | 
						|
	"errors"
 | 
						|
	"fmt"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/ethereum/go-ethereum/cmd/utils"
 | 
						|
	"github.com/ethereum/go-ethereum/common"
 | 
						|
	"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/logger/glog"
 | 
						|
	"github.com/ethereum/go-ethereum/rlp"
 | 
						|
	"github.com/ethereum/go-ethereum/rpc"
 | 
						|
	"github.com/ethereum/go-ethereum/xeth"
 | 
						|
	"github.com/robertkrimen/otto"
 | 
						|
)
 | 
						|
 | 
						|
/*
 | 
						|
node admin bindings
 | 
						|
*/
 | 
						|
 | 
						|
func (js *jsre) adminBindings() {
 | 
						|
	js.re.Set("admin", struct{}{})
 | 
						|
	t, _ := js.re.Get("admin")
 | 
						|
	admin := t.Object()
 | 
						|
	admin.Set("suggestPeer", js.suggestPeer)
 | 
						|
	admin.Set("startRPC", js.startRPC)
 | 
						|
	admin.Set("stopRPC", js.stopRPC)
 | 
						|
	admin.Set("nodeInfo", js.nodeInfo)
 | 
						|
	admin.Set("peers", js.peers)
 | 
						|
	admin.Set("newAccount", js.newAccount)
 | 
						|
	admin.Set("unlock", js.unlock)
 | 
						|
	admin.Set("import", js.importChain)
 | 
						|
	admin.Set("export", js.exportChain)
 | 
						|
	admin.Set("verbosity", js.verbosity)
 | 
						|
	admin.Set("backtrace", js.backtrace)
 | 
						|
	admin.Set("progress", js.downloadProgress)
 | 
						|
 | 
						|
	admin.Set("miner", struct{}{})
 | 
						|
	t, _ = admin.Get("miner")
 | 
						|
	miner := t.Object()
 | 
						|
	miner.Set("start", js.startMining)
 | 
						|
	miner.Set("stop", js.stopMining)
 | 
						|
	miner.Set("hashrate", js.hashrate)
 | 
						|
	miner.Set("setExtra", js.setExtra)
 | 
						|
 | 
						|
	admin.Set("debug", struct{}{})
 | 
						|
	t, _ = admin.Get("debug")
 | 
						|
	debug := t.Object()
 | 
						|
	debug.Set("printBlock", js.printBlock)
 | 
						|
	debug.Set("dumpBlock", js.dumpBlock)
 | 
						|
	debug.Set("getBlockRlp", js.getBlockRlp)
 | 
						|
	debug.Set("setHead", js.setHead)
 | 
						|
	debug.Set("block", js.debugBlock)
 | 
						|
}
 | 
						|
 | 
						|
func (js *jsre) getBlock(call otto.FunctionCall) (*types.Block, error) {
 | 
						|
	var block *types.Block
 | 
						|
	if len(call.ArgumentList) > 0 {
 | 
						|
		if call.Argument(0).IsNumber() {
 | 
						|
			num, _ := call.Argument(0).ToInteger()
 | 
						|
			block = js.ethereum.ChainManager().GetBlockByNumber(uint64(num))
 | 
						|
		} else if call.Argument(0).IsString() {
 | 
						|
			hash, _ := call.Argument(0).ToString()
 | 
						|
			block = js.ethereum.ChainManager().GetBlock(common.HexToHash(hash))
 | 
						|
		} else {
 | 
						|
			return nil, errors.New("invalid argument for dump. Either hex string or number")
 | 
						|
		}
 | 
						|
		return block, nil
 | 
						|
	}
 | 
						|
 | 
						|
	return nil, errors.New("requires block number or block hash as argument")
 | 
						|
}
 | 
						|
 | 
						|
func (js *jsre) debugBlock(call otto.FunctionCall) otto.Value {
 | 
						|
	block, err := js.getBlock(call)
 | 
						|
	if err != nil {
 | 
						|
		fmt.Println(err)
 | 
						|
		return otto.UndefinedValue()
 | 
						|
	}
 | 
						|
 | 
						|
	if block == nil {
 | 
						|
		fmt.Println("block not found")
 | 
						|
		return otto.UndefinedValue()
 | 
						|
	}
 | 
						|
 | 
						|
	old := vm.Debug
 | 
						|
	vm.Debug = true
 | 
						|
	_, err = js.ethereum.BlockProcessor().RetryProcess(block)
 | 
						|
	if err != nil {
 | 
						|
		glog.Infoln(err)
 | 
						|
	}
 | 
						|
	vm.Debug = old
 | 
						|
 | 
						|
	return otto.UndefinedValue()
 | 
						|
}
 | 
						|
 | 
						|
func (js *jsre) setHead(call otto.FunctionCall) otto.Value {
 | 
						|
	block, err := js.getBlock(call)
 | 
						|
	if err != nil {
 | 
						|
		fmt.Println(err)
 | 
						|
		return otto.UndefinedValue()
 | 
						|
	}
 | 
						|
 | 
						|
	if block == nil {
 | 
						|
		fmt.Println("block not found")
 | 
						|
		return otto.UndefinedValue()
 | 
						|
	}
 | 
						|
 | 
						|
	js.ethereum.ChainManager().SetHead(block)
 | 
						|
	return otto.UndefinedValue()
 | 
						|
}
 | 
						|
 | 
						|
func (js *jsre) downloadProgress(call otto.FunctionCall) otto.Value {
 | 
						|
	current, max := js.ethereum.Downloader().Stats()
 | 
						|
 | 
						|
	return js.re.ToVal(fmt.Sprintf("%d/%d", current, max))
 | 
						|
}
 | 
						|
 | 
						|
func (js *jsre) getBlockRlp(call otto.FunctionCall) otto.Value {
 | 
						|
	block, err := js.getBlock(call)
 | 
						|
	if err != nil {
 | 
						|
		fmt.Println(err)
 | 
						|
		return otto.UndefinedValue()
 | 
						|
	}
 | 
						|
 | 
						|
	if block == nil {
 | 
						|
		fmt.Println("block not found")
 | 
						|
		return otto.UndefinedValue()
 | 
						|
	}
 | 
						|
 | 
						|
	encoded, _ := rlp.EncodeToBytes(block)
 | 
						|
	return js.re.ToVal(fmt.Sprintf("%x", encoded))
 | 
						|
}
 | 
						|
 | 
						|
func (js *jsre) setExtra(call otto.FunctionCall) otto.Value {
 | 
						|
	extra, err := call.Argument(0).ToString()
 | 
						|
	if err != nil {
 | 
						|
		fmt.Println(err)
 | 
						|
		return otto.UndefinedValue()
 | 
						|
	}
 | 
						|
 | 
						|
	if len(extra) > 1024 {
 | 
						|
		fmt.Println("error: cannot exceed 1024 bytes")
 | 
						|
		return otto.UndefinedValue()
 | 
						|
	}
 | 
						|
 | 
						|
	js.ethereum.Miner().SetExtra([]byte(extra))
 | 
						|
	return otto.UndefinedValue()
 | 
						|
}
 | 
						|
 | 
						|
func (js *jsre) hashrate(otto.FunctionCall) otto.Value {
 | 
						|
	return js.re.ToVal(js.ethereum.Miner().HashRate())
 | 
						|
}
 | 
						|
 | 
						|
func (js *jsre) backtrace(call otto.FunctionCall) otto.Value {
 | 
						|
	tracestr, err := call.Argument(0).ToString()
 | 
						|
	if err != nil {
 | 
						|
		fmt.Println(err)
 | 
						|
		return otto.UndefinedValue()
 | 
						|
	}
 | 
						|
	glog.GetTraceLocation().Set(tracestr)
 | 
						|
 | 
						|
	return otto.UndefinedValue()
 | 
						|
}
 | 
						|
 | 
						|
func (js *jsre) verbosity(call otto.FunctionCall) otto.Value {
 | 
						|
	v, err := call.Argument(0).ToInteger()
 | 
						|
	if err != nil {
 | 
						|
		fmt.Println(err)
 | 
						|
		return otto.UndefinedValue()
 | 
						|
	}
 | 
						|
 | 
						|
	glog.SetV(int(v))
 | 
						|
	return otto.UndefinedValue()
 | 
						|
}
 | 
						|
 | 
						|
func (js *jsre) startMining(call otto.FunctionCall) otto.Value {
 | 
						|
	_, err := call.Argument(0).ToInteger()
 | 
						|
	if err != nil {
 | 
						|
		fmt.Println(err)
 | 
						|
		return otto.FalseValue()
 | 
						|
	}
 | 
						|
	// threads now ignored
 | 
						|
	err = js.ethereum.StartMining()
 | 
						|
	if err != nil {
 | 
						|
		fmt.Println(err)
 | 
						|
		return otto.FalseValue()
 | 
						|
	}
 | 
						|
	return otto.TrueValue()
 | 
						|
}
 | 
						|
 | 
						|
func (js *jsre) stopMining(call otto.FunctionCall) otto.Value {
 | 
						|
	js.ethereum.StopMining()
 | 
						|
	return otto.TrueValue()
 | 
						|
}
 | 
						|
 | 
						|
func (js *jsre) startRPC(call otto.FunctionCall) otto.Value {
 | 
						|
	addr, err := call.Argument(0).ToString()
 | 
						|
	if err != nil {
 | 
						|
		fmt.Println(err)
 | 
						|
		return otto.FalseValue()
 | 
						|
	}
 | 
						|
	port, err := call.Argument(1).ToInteger()
 | 
						|
	if err != nil {
 | 
						|
		fmt.Println(err)
 | 
						|
		return otto.FalseValue()
 | 
						|
	}
 | 
						|
 | 
						|
	config := rpc.RpcConfig{
 | 
						|
		ListenAddress: addr,
 | 
						|
		ListenPort:    uint(port),
 | 
						|
		// CorsDomain:    ctx.GlobalString(RPCCORSDomainFlag.Name),
 | 
						|
	}
 | 
						|
 | 
						|
	xeth := xeth.New(js.ethereum, nil)
 | 
						|
	err = rpc.Start(xeth, config)
 | 
						|
 | 
						|
	if err != nil {
 | 
						|
		fmt.Printf(err.Error())
 | 
						|
		return otto.FalseValue()
 | 
						|
	}
 | 
						|
 | 
						|
	return otto.TrueValue()
 | 
						|
}
 | 
						|
 | 
						|
func (js *jsre) stopRPC(call otto.FunctionCall) otto.Value {
 | 
						|
	if rpc.Stop() == nil {
 | 
						|
		return otto.TrueValue()
 | 
						|
	}
 | 
						|
	return otto.FalseValue()
 | 
						|
}
 | 
						|
 | 
						|
func (js *jsre) suggestPeer(call otto.FunctionCall) otto.Value {
 | 
						|
	nodeURL, err := call.Argument(0).ToString()
 | 
						|
	if err != nil {
 | 
						|
		fmt.Println(err)
 | 
						|
		return otto.FalseValue()
 | 
						|
	}
 | 
						|
	err = js.ethereum.SuggestPeer(nodeURL)
 | 
						|
	if err != nil {
 | 
						|
		fmt.Println(err)
 | 
						|
		return otto.FalseValue()
 | 
						|
	}
 | 
						|
	return otto.TrueValue()
 | 
						|
}
 | 
						|
 | 
						|
func (js *jsre) unlock(call otto.FunctionCall) otto.Value {
 | 
						|
	addr, err := call.Argument(0).ToString()
 | 
						|
	if err != nil {
 | 
						|
		fmt.Println(err)
 | 
						|
		return otto.FalseValue()
 | 
						|
	}
 | 
						|
	seconds, err := call.Argument(2).ToInteger()
 | 
						|
	if err != nil {
 | 
						|
		fmt.Println(err)
 | 
						|
		return otto.FalseValue()
 | 
						|
	}
 | 
						|
	arg := call.Argument(1)
 | 
						|
	var passphrase string
 | 
						|
	if arg.IsUndefined() {
 | 
						|
		fmt.Println("Please enter a passphrase now.")
 | 
						|
		passphrase, err = readPassword("Passphrase: ", true)
 | 
						|
		if err != nil {
 | 
						|
			utils.Fatalf("%v", err)
 | 
						|
		}
 | 
						|
	} else {
 | 
						|
		passphrase, err = arg.ToString()
 | 
						|
		if err != nil {
 | 
						|
			fmt.Println(err)
 | 
						|
			return otto.FalseValue()
 | 
						|
		}
 | 
						|
	}
 | 
						|
	am := js.ethereum.AccountManager()
 | 
						|
	// err := am.Unlock(common.FromHex(split[0]), split[1])
 | 
						|
	// if err != nil {
 | 
						|
	// 	utils.Fatalf("Unlock account failed '%v'", err)
 | 
						|
	// }
 | 
						|
	err = am.TimedUnlock(common.FromHex(addr), passphrase, time.Duration(seconds)*time.Second)
 | 
						|
	if err != nil {
 | 
						|
		fmt.Printf("Unlock account failed '%v'\n", err)
 | 
						|
		return otto.FalseValue()
 | 
						|
	}
 | 
						|
	return otto.TrueValue()
 | 
						|
}
 | 
						|
 | 
						|
func (js *jsre) newAccount(call otto.FunctionCall) otto.Value {
 | 
						|
	arg := call.Argument(0)
 | 
						|
	var passphrase string
 | 
						|
	if arg.IsUndefined() {
 | 
						|
		fmt.Println("The new account will be encrypted with a passphrase.")
 | 
						|
		fmt.Println("Please enter a passphrase now.")
 | 
						|
		auth, err := readPassword("Passphrase: ", true)
 | 
						|
		if err != nil {
 | 
						|
			utils.Fatalf("%v", err)
 | 
						|
		}
 | 
						|
		confirm, err := readPassword("Repeat Passphrase: ", false)
 | 
						|
		if err != nil {
 | 
						|
			utils.Fatalf("%v", err)
 | 
						|
		}
 | 
						|
		if auth != confirm {
 | 
						|
			utils.Fatalf("Passphrases did not match.")
 | 
						|
		}
 | 
						|
		passphrase = auth
 | 
						|
	} else {
 | 
						|
		var err error
 | 
						|
		passphrase, err = arg.ToString()
 | 
						|
		if err != nil {
 | 
						|
			fmt.Println(err)
 | 
						|
			return otto.FalseValue()
 | 
						|
		}
 | 
						|
	}
 | 
						|
	acct, err := js.ethereum.AccountManager().NewAccount(passphrase)
 | 
						|
	if err != nil {
 | 
						|
		fmt.Printf("Could not create the account: %v", err)
 | 
						|
		return otto.UndefinedValue()
 | 
						|
	}
 | 
						|
	return js.re.ToVal("0x" + common.Bytes2Hex(acct.Address))
 | 
						|
}
 | 
						|
 | 
						|
func (js *jsre) nodeInfo(call otto.FunctionCall) otto.Value {
 | 
						|
	return js.re.ToVal(js.ethereum.NodeInfo())
 | 
						|
}
 | 
						|
 | 
						|
func (js *jsre) peers(call otto.FunctionCall) otto.Value {
 | 
						|
	return js.re.ToVal(js.ethereum.PeersInfo())
 | 
						|
}
 | 
						|
 | 
						|
func (js *jsre) importChain(call otto.FunctionCall) otto.Value {
 | 
						|
	if len(call.ArgumentList) == 0 {
 | 
						|
		fmt.Println("err: require file name")
 | 
						|
		return otto.FalseValue()
 | 
						|
	}
 | 
						|
	fn, err := call.Argument(0).ToString()
 | 
						|
	if err != nil {
 | 
						|
		fmt.Println(err)
 | 
						|
		return otto.FalseValue()
 | 
						|
	}
 | 
						|
	if err := utils.ImportChain(js.ethereum.ChainManager(), fn); err != nil {
 | 
						|
		fmt.Println("Import error: ", err)
 | 
						|
		return otto.FalseValue()
 | 
						|
	}
 | 
						|
	return otto.TrueValue()
 | 
						|
}
 | 
						|
 | 
						|
func (js *jsre) exportChain(call otto.FunctionCall) otto.Value {
 | 
						|
	if len(call.ArgumentList) == 0 {
 | 
						|
		fmt.Println("err: require file name")
 | 
						|
		return otto.FalseValue()
 | 
						|
	}
 | 
						|
 | 
						|
	fn, err := call.Argument(0).ToString()
 | 
						|
	if err != nil {
 | 
						|
		fmt.Println(err)
 | 
						|
		return otto.FalseValue()
 | 
						|
	}
 | 
						|
	if err := utils.ExportChain(js.ethereum.ChainManager(), fn); err != nil {
 | 
						|
		fmt.Println(err)
 | 
						|
		return otto.FalseValue()
 | 
						|
	}
 | 
						|
	return otto.TrueValue()
 | 
						|
}
 | 
						|
 | 
						|
func (js *jsre) printBlock(call otto.FunctionCall) otto.Value {
 | 
						|
	var block *types.Block
 | 
						|
	if len(call.ArgumentList) > 0 {
 | 
						|
		if call.Argument(0).IsNumber() {
 | 
						|
			num, _ := call.Argument(0).ToInteger()
 | 
						|
			block = js.ethereum.ChainManager().GetBlockByNumber(uint64(num))
 | 
						|
		} else if call.Argument(0).IsString() {
 | 
						|
			hash, _ := call.Argument(0).ToString()
 | 
						|
			block = js.ethereum.ChainManager().GetBlock(common.HexToHash(hash))
 | 
						|
		} else {
 | 
						|
			fmt.Println("invalid argument for dump. Either hex string or number")
 | 
						|
		}
 | 
						|
 | 
						|
	} else {
 | 
						|
		block = js.ethereum.ChainManager().CurrentBlock()
 | 
						|
	}
 | 
						|
	if block == nil {
 | 
						|
		fmt.Println("block not found")
 | 
						|
		return otto.UndefinedValue()
 | 
						|
	}
 | 
						|
 | 
						|
	fmt.Println(block)
 | 
						|
 | 
						|
	return otto.UndefinedValue()
 | 
						|
}
 | 
						|
 | 
						|
func (js *jsre) dumpBlock(call otto.FunctionCall) otto.Value {
 | 
						|
	var block *types.Block
 | 
						|
	if len(call.ArgumentList) > 0 {
 | 
						|
		if call.Argument(0).IsNumber() {
 | 
						|
			num, _ := call.Argument(0).ToInteger()
 | 
						|
			block = js.ethereum.ChainManager().GetBlockByNumber(uint64(num))
 | 
						|
		} else if call.Argument(0).IsString() {
 | 
						|
			hash, _ := call.Argument(0).ToString()
 | 
						|
			block = js.ethereum.ChainManager().GetBlock(common.HexToHash(hash))
 | 
						|
		} else {
 | 
						|
			fmt.Println("invalid argument for dump. Either hex string or number")
 | 
						|
		}
 | 
						|
 | 
						|
	} else {
 | 
						|
		block = js.ethereum.ChainManager().CurrentBlock()
 | 
						|
	}
 | 
						|
	if block == nil {
 | 
						|
		fmt.Println("block not found")
 | 
						|
		return otto.UndefinedValue()
 | 
						|
	}
 | 
						|
 | 
						|
	statedb := state.New(block.Root(), js.ethereum.StateDb())
 | 
						|
	dump := statedb.RawDump()
 | 
						|
	return js.re.ToVal(dump)
 | 
						|
 | 
						|
}
 |