| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // Copyright 2015 The go-ethereum Authors | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // This file is part of the go-ethereum library. | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // | 
					
						
							|  |  |  | // go-ethereum is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | // it under the terms of the GNU Lesser General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // The go-ethereum library is distributed in the hope that it will be useful, | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | package api | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"io" | 
					
						
							| 
									
										
										
										
											2015-06-23 15:48:33 +01:00
										 |  |  | 	"math/big" | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2015-06-23 15:48:33 +01:00
										 |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-23 15:48:33 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/common" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/common/compiler" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/common/docserver" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/common/natspec" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/common/registrar" | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/core" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/core/types" | 
					
						
							| 
									
										
										
										
											2015-06-23 15:48:33 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/crypto" | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/eth" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/logger/glog" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/rlp" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/rpc/codec" | 
					
						
							| 
									
										
										
										
											2015-06-22 12:47:32 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/rpc/comms" | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/rpc/shared" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/xeth" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const ( | 
					
						
							| 
									
										
										
										
											2015-06-10 09:42:14 +02:00
										 |  |  | 	AdminApiversion = "1.0" | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | 	importBatchSize = 2500 | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var ( | 
					
						
							|  |  |  | 	// mapping between methods and handlers | 
					
						
							|  |  |  | 	AdminMapping = map[string]adminhandler{ | 
					
						
							| 
									
										
										
										
											2015-06-23 15:48:33 +01:00
										 |  |  | 		"admin_addPeer":            (*adminApi).AddPeer, | 
					
						
							|  |  |  | 		"admin_peers":              (*adminApi).Peers, | 
					
						
							|  |  |  | 		"admin_nodeInfo":           (*adminApi).NodeInfo, | 
					
						
							|  |  |  | 		"admin_exportChain":        (*adminApi).ExportChain, | 
					
						
							|  |  |  | 		"admin_importChain":        (*adminApi).ImportChain, | 
					
						
							|  |  |  | 		"admin_verbosity":          (*adminApi).Verbosity, | 
					
						
							|  |  |  | 		"admin_chainSyncStatus":    (*adminApi).ChainSyncStatus, | 
					
						
							|  |  |  | 		"admin_setSolc":            (*adminApi).SetSolc, | 
					
						
							|  |  |  | 		"admin_datadir":            (*adminApi).DataDir, | 
					
						
							|  |  |  | 		"admin_startRPC":           (*adminApi).StartRPC, | 
					
						
							|  |  |  | 		"admin_stopRPC":            (*adminApi).StopRPC, | 
					
						
							|  |  |  | 		"admin_setGlobalRegistrar": (*adminApi).SetGlobalRegistrar, | 
					
						
							|  |  |  | 		"admin_setHashReg":         (*adminApi).SetHashReg, | 
					
						
							|  |  |  | 		"admin_setUrlHint":         (*adminApi).SetUrlHint, | 
					
						
							|  |  |  | 		"admin_saveInfo":           (*adminApi).SaveInfo, | 
					
						
							|  |  |  | 		"admin_register":           (*adminApi).Register, | 
					
						
							|  |  |  | 		"admin_registerUrl":        (*adminApi).RegisterUrl, | 
					
						
							|  |  |  | 		"admin_startNatSpec":       (*adminApi).StartNatSpec, | 
					
						
							|  |  |  | 		"admin_stopNatSpec":        (*adminApi).StopNatSpec, | 
					
						
							|  |  |  | 		"admin_getContractInfo":    (*adminApi).GetContractInfo, | 
					
						
							|  |  |  | 		"admin_httpGet":            (*adminApi).HttpGet, | 
					
						
							| 
									
										
										
										
											2015-07-02 16:38:48 +01:00
										 |  |  | 		"admin_sleepBlocks":        (*adminApi).SleepBlocks, | 
					
						
							|  |  |  | 		"admin_sleep":              (*adminApi).Sleep, | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // admin callback handler | 
					
						
							|  |  |  | type adminhandler func(*adminApi, *shared.Request) (interface{}, error) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // admin api provider | 
					
						
							|  |  |  | type adminApi struct { | 
					
						
							|  |  |  | 	xeth     *xeth.XEth | 
					
						
							|  |  |  | 	ethereum *eth.Ethereum | 
					
						
							| 
									
										
										
										
											2015-06-22 12:47:32 +02:00
										 |  |  | 	codec    codec.Codec | 
					
						
							|  |  |  | 	coder    codec.ApiCoder | 
					
						
							| 
									
										
										
										
											2015-06-23 15:48:33 +01:00
										 |  |  | 	ds       *docserver.DocServer | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // create a new admin api instance | 
					
						
							| 
									
										
										
										
											2015-06-22 12:47:32 +02:00
										 |  |  | func NewAdminApi(xeth *xeth.XEth, ethereum *eth.Ethereum, codec codec.Codec) *adminApi { | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | 	return &adminApi{ | 
					
						
							|  |  |  | 		xeth:     xeth, | 
					
						
							|  |  |  | 		ethereum: ethereum, | 
					
						
							| 
									
										
										
										
											2015-06-22 12:47:32 +02:00
										 |  |  | 		codec:    codec, | 
					
						
							|  |  |  | 		coder:    codec.New(nil), | 
					
						
							| 
									
										
										
										
											2015-06-23 15:48:33 +01:00
										 |  |  | 		ds:       docserver.New("/"), | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // collection with supported methods | 
					
						
							|  |  |  | func (self *adminApi) Methods() []string { | 
					
						
							| 
									
										
										
										
											2015-06-22 12:47:32 +02:00
										 |  |  | 	methods := make([]string, len(AdminMapping)) | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | 	i := 0 | 
					
						
							| 
									
										
										
										
											2015-06-22 12:47:32 +02:00
										 |  |  | 	for k := range AdminMapping { | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | 		methods[i] = k | 
					
						
							|  |  |  | 		i++ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return methods | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Execute given request | 
					
						
							|  |  |  | func (self *adminApi) Execute(req *shared.Request) (interface{}, error) { | 
					
						
							| 
									
										
										
										
											2015-06-22 12:47:32 +02:00
										 |  |  | 	if callback, ok := AdminMapping[req.Method]; ok { | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | 		return callback(self, req) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil, &shared.NotImplementedError{req.Method} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *adminApi) Name() string { | 
					
						
							| 
									
										
										
										
											2015-06-22 12:47:32 +02:00
										 |  |  | 	return shared.AdminApiName | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-10 09:42:14 +02:00
										 |  |  | func (self *adminApi) ApiVersion() string { | 
					
						
							|  |  |  | 	return AdminApiversion | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | func (self *adminApi) AddPeer(req *shared.Request) (interface{}, error) { | 
					
						
							|  |  |  | 	args := new(AddPeerArgs) | 
					
						
							| 
									
										
										
										
											2015-06-22 12:47:32 +02:00
										 |  |  | 	if err := self.coder.Decode(req.Params, &args); err != nil { | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | 		return nil, shared.NewDecodeParamError(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := self.ethereum.AddPeer(args.Url) | 
					
						
							|  |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		return true, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false, err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *adminApi) Peers(req *shared.Request) (interface{}, error) { | 
					
						
							|  |  |  | 	return self.ethereum.PeersInfo(), nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *adminApi) NodeInfo(req *shared.Request) (interface{}, error) { | 
					
						
							|  |  |  | 	return self.ethereum.NodeInfo(), nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-10 11:29:52 +02:00
										 |  |  | func (self *adminApi) DataDir(req *shared.Request) (interface{}, error) { | 
					
						
							|  |  |  | 	return self.ethereum.DataDir, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | func hasAllBlocks(chain *core.ChainManager, bs []*types.Block) bool { | 
					
						
							|  |  |  | 	for _, b := range bs { | 
					
						
							|  |  |  | 		if !chain.HasBlock(b.Hash()) { | 
					
						
							|  |  |  | 			return false | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return true | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *adminApi) ImportChain(req *shared.Request) (interface{}, error) { | 
					
						
							|  |  |  | 	args := new(ImportExportChainArgs) | 
					
						
							| 
									
										
										
										
											2015-06-22 12:47:32 +02:00
										 |  |  | 	if err := self.coder.Decode(req.Params, &args); err != nil { | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | 		return nil, shared.NewDecodeParamError(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fh, err := os.Open(args.Filename) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return false, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer fh.Close() | 
					
						
							|  |  |  | 	stream := rlp.NewStream(fh, 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Run actual the import. | 
					
						
							|  |  |  | 	blocks := make(types.Blocks, importBatchSize) | 
					
						
							|  |  |  | 	n := 0 | 
					
						
							|  |  |  | 	for batch := 0; ; batch++ { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		i := 0 | 
					
						
							|  |  |  | 		for ; i < importBatchSize; i++ { | 
					
						
							|  |  |  | 			var b types.Block | 
					
						
							|  |  |  | 			if err := stream.Decode(&b); err == io.EOF { | 
					
						
							|  |  |  | 				break | 
					
						
							|  |  |  | 			} else if err != nil { | 
					
						
							|  |  |  | 				return false, fmt.Errorf("at block %d: %v", n, err) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			blocks[i] = &b | 
					
						
							|  |  |  | 			n++ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if i == 0 { | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// Import the batch. | 
					
						
							|  |  |  | 		if hasAllBlocks(self.ethereum.ChainManager(), blocks[:i]) { | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if _, err := self.ethereum.ChainManager().InsertChain(blocks[:i]); err != nil { | 
					
						
							|  |  |  | 			return false, fmt.Errorf("invalid block %d: %v", n, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return true, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *adminApi) ExportChain(req *shared.Request) (interface{}, error) { | 
					
						
							|  |  |  | 	args := new(ImportExportChainArgs) | 
					
						
							| 
									
										
										
										
											2015-06-22 12:47:32 +02:00
										 |  |  | 	if err := self.coder.Decode(req.Params, &args); err != nil { | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | 		return nil, shared.NewDecodeParamError(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fh, err := os.OpenFile(args.Filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return false, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer fh.Close() | 
					
						
							|  |  |  | 	if err := self.ethereum.ChainManager().Export(fh); err != nil { | 
					
						
							|  |  |  | 		return false, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return true, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *adminApi) Verbosity(req *shared.Request) (interface{}, error) { | 
					
						
							|  |  |  | 	args := new(VerbosityArgs) | 
					
						
							| 
									
										
										
										
											2015-06-22 12:47:32 +02:00
										 |  |  | 	if err := self.coder.Decode(req.Params, &args); err != nil { | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | 		return nil, shared.NewDecodeParamError(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	glog.SetV(args.Level) | 
					
						
							|  |  |  | 	return true, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-10 11:29:52 +02:00
										 |  |  | func (self *adminApi) ChainSyncStatus(req *shared.Request) (interface{}, error) { | 
					
						
							| 
									
										
										
										
											2015-06-10 09:42:14 +02:00
										 |  |  | 	pending, cached, importing, estimate := self.ethereum.Downloader().Stats() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return map[string]interface{}{ | 
					
						
							| 
									
										
										
										
											2015-06-16 14:59:39 +02:00
										 |  |  | 		"blocksAvailable":        pending, | 
					
						
							| 
									
										
										
										
											2015-06-10 09:42:14 +02:00
										 |  |  | 		"blocksWaitingForImport": cached, | 
					
						
							| 
									
										
										
										
											2015-06-16 14:59:39 +02:00
										 |  |  | 		"importing":              importing, | 
					
						
							|  |  |  | 		"estimate":               estimate.String(), | 
					
						
							| 
									
										
										
										
											2015-06-10 09:42:14 +02:00
										 |  |  | 	}, nil | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *adminApi) SetSolc(req *shared.Request) (interface{}, error) { | 
					
						
							|  |  |  | 	args := new(SetSolcArgs) | 
					
						
							| 
									
										
										
										
											2015-06-22 12:47:32 +02:00
										 |  |  | 	if err := self.coder.Decode(req.Params, &args); err != nil { | 
					
						
							| 
									
										
										
										
											2015-06-09 16:06:51 +02:00
										 |  |  | 		return nil, shared.NewDecodeParamError(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	solc, err := self.xeth.SetSolc(args.Path) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return solc.Info(), nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-06-22 12:47:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | func (self *adminApi) StartRPC(req *shared.Request) (interface{}, error) { | 
					
						
							|  |  |  | 	args := new(StartRPCArgs) | 
					
						
							|  |  |  | 	if err := self.coder.Decode(req.Params, &args); err != nil { | 
					
						
							|  |  |  | 		return nil, shared.NewDecodeParamError(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cfg := comms.HttpConfig{ | 
					
						
							|  |  |  | 		ListenAddress: args.ListenAddress, | 
					
						
							|  |  |  | 		ListenPort:    args.ListenPort, | 
					
						
							|  |  |  | 		CorsDomain:    args.CorsDomain, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-23 08:26:17 +02:00
										 |  |  | 	apis, err := ParseApiString(args.Apis, self.codec, self.xeth, self.ethereum) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return false, err | 
					
						
							| 
									
										
										
										
											2015-06-22 12:47:32 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-23 08:26:17 +02:00
										 |  |  | 	err = comms.StartHttp(cfg, self.codec, Merge(apis...)) | 
					
						
							| 
									
										
										
										
											2015-06-22 12:47:32 +02:00
										 |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		return true, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false, err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *adminApi) StopRPC(req *shared.Request) (interface{}, error) { | 
					
						
							|  |  |  | 	comms.StopHttp() | 
					
						
							|  |  |  | 	return true, nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-06-23 15:48:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | func (self *adminApi) SleepBlocks(req *shared.Request) (interface{}, error) { | 
					
						
							|  |  |  | 	args := new(SleepBlocksArgs) | 
					
						
							|  |  |  | 	if err := self.coder.Decode(req.Params, &args); err != nil { | 
					
						
							|  |  |  | 		return nil, shared.NewDecodeParamError(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	var timer <-chan time.Time | 
					
						
							|  |  |  | 	var height *big.Int | 
					
						
							|  |  |  | 	var err error | 
					
						
							|  |  |  | 	if args.Timeout > 0 { | 
					
						
							|  |  |  | 		timer = time.NewTimer(time.Duration(args.Timeout) * time.Second).C | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	height = new(big.Int).Add(self.xeth.CurrentBlock().Number(), big.NewInt(args.N)) | 
					
						
							|  |  |  | 	height, err = sleepBlocks(self.xeth.UpdateState(), height, timer) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return height.Uint64(), nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func sleepBlocks(wait chan *big.Int, height *big.Int, timer <-chan time.Time) (newHeight *big.Int, err error) { | 
					
						
							|  |  |  | 	wait <- height | 
					
						
							|  |  |  | 	select { | 
					
						
							|  |  |  | 	case <-timer: | 
					
						
							|  |  |  | 		// if times out make sure the xeth loop does not block | 
					
						
							|  |  |  | 		go func() { | 
					
						
							|  |  |  | 			select { | 
					
						
							|  |  |  | 			case wait <- nil: | 
					
						
							|  |  |  | 			case <-wait: | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}() | 
					
						
							|  |  |  | 		return nil, fmt.Errorf("timeout") | 
					
						
							|  |  |  | 	case newHeight = <-wait: | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-02 16:38:48 +01:00
										 |  |  | func (self *adminApi) Sleep(req *shared.Request) (interface{}, error) { | 
					
						
							|  |  |  | 	args := new(SleepArgs) | 
					
						
							|  |  |  | 	if err := self.coder.Decode(req.Params, &args); err != nil { | 
					
						
							|  |  |  | 		return nil, shared.NewDecodeParamError(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	time.Sleep(time.Duration(args.S) * time.Second) | 
					
						
							|  |  |  | 	return nil, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-23 15:48:33 +01:00
										 |  |  | func (self *adminApi) SetGlobalRegistrar(req *shared.Request) (interface{}, error) { | 
					
						
							|  |  |  | 	args := new(SetGlobalRegistrarArgs) | 
					
						
							|  |  |  | 	if err := self.coder.Decode(req.Params, &args); err != nil { | 
					
						
							|  |  |  | 		return nil, shared.NewDecodeParamError(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sender := common.HexToAddress(args.ContractAddress) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	reg := registrar.New(self.xeth) | 
					
						
							| 
									
										
										
										
											2015-07-07 06:00:58 +01:00
										 |  |  | 	txhash, err := reg.SetGlobalRegistrar(args.NameReg, sender) | 
					
						
							| 
									
										
										
										
											2015-06-23 15:48:33 +01:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return false, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-07 06:00:58 +01:00
										 |  |  | 	return txhash, nil | 
					
						
							| 
									
										
										
										
											2015-06-23 15:48:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *adminApi) SetHashReg(req *shared.Request) (interface{}, error) { | 
					
						
							|  |  |  | 	args := new(SetHashRegArgs) | 
					
						
							|  |  |  | 	if err := self.coder.Decode(req.Params, &args); err != nil { | 
					
						
							|  |  |  | 		return nil, shared.NewDecodeParamError(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	reg := registrar.New(self.xeth) | 
					
						
							|  |  |  | 	sender := common.HexToAddress(args.Sender) | 
					
						
							| 
									
										
										
										
											2015-07-07 06:00:58 +01:00
										 |  |  | 	txhash, err := reg.SetHashReg(args.HashReg, sender) | 
					
						
							| 
									
										
										
										
											2015-06-23 15:48:33 +01:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return false, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-07 06:00:58 +01:00
										 |  |  | 	return txhash, nil | 
					
						
							| 
									
										
										
										
											2015-06-23 15:48:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *adminApi) SetUrlHint(req *shared.Request) (interface{}, error) { | 
					
						
							|  |  |  | 	args := new(SetUrlHintArgs) | 
					
						
							|  |  |  | 	if err := self.coder.Decode(req.Params, &args); err != nil { | 
					
						
							|  |  |  | 		return nil, shared.NewDecodeParamError(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	urlHint := args.UrlHint | 
					
						
							|  |  |  | 	sender := common.HexToAddress(args.Sender) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	reg := registrar.New(self.xeth) | 
					
						
							| 
									
										
										
										
											2015-07-07 06:00:58 +01:00
										 |  |  | 	txhash, err := reg.SetUrlHint(urlHint, sender) | 
					
						
							| 
									
										
										
										
											2015-06-23 15:48:33 +01:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-07 06:00:58 +01:00
										 |  |  | 	return txhash, nil | 
					
						
							| 
									
										
										
										
											2015-06-23 15:48:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *adminApi) SaveInfo(req *shared.Request) (interface{}, error) { | 
					
						
							|  |  |  | 	args := new(SaveInfoArgs) | 
					
						
							|  |  |  | 	if err := self.coder.Decode(req.Params, &args); err != nil { | 
					
						
							|  |  |  | 		return nil, shared.NewDecodeParamError(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	contenthash, err := compiler.SaveInfo(&args.ContractInfo, args.Filename) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return contenthash.Hex(), nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *adminApi) Register(req *shared.Request) (interface{}, error) { | 
					
						
							|  |  |  | 	args := new(RegisterArgs) | 
					
						
							|  |  |  | 	if err := self.coder.Decode(req.Params, &args); err != nil { | 
					
						
							|  |  |  | 		return nil, shared.NewDecodeParamError(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sender := common.HexToAddress(args.Sender) | 
					
						
							|  |  |  | 	// sender and contract address are passed as hex strings | 
					
						
							|  |  |  | 	codeb := self.xeth.CodeAtBytes(args.Address) | 
					
						
							|  |  |  | 	codeHash := common.BytesToHash(crypto.Sha3(codeb)) | 
					
						
							|  |  |  | 	contentHash := common.HexToHash(args.ContentHashHex) | 
					
						
							|  |  |  | 	registry := registrar.New(self.xeth) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_, err := registry.SetHashToHash(sender, codeHash, contentHash) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return false, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return true, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *adminApi) RegisterUrl(req *shared.Request) (interface{}, error) { | 
					
						
							|  |  |  | 	args := new(RegisterUrlArgs) | 
					
						
							|  |  |  | 	if err := self.coder.Decode(req.Params, &args); err != nil { | 
					
						
							|  |  |  | 		return nil, shared.NewDecodeParamError(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sender := common.HexToAddress(args.Sender) | 
					
						
							|  |  |  | 	registry := registrar.New(self.xeth) | 
					
						
							|  |  |  | 	_, err := registry.SetUrlToHash(sender, common.HexToHash(args.ContentHash), args.Url) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return false, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return true, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *adminApi) StartNatSpec(req *shared.Request) (interface{}, error) { | 
					
						
							|  |  |  | 	self.ethereum.NatSpec = true | 
					
						
							|  |  |  | 	return true, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *adminApi) StopNatSpec(req *shared.Request) (interface{}, error) { | 
					
						
							|  |  |  | 	self.ethereum.NatSpec = false | 
					
						
							|  |  |  | 	return true, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *adminApi) GetContractInfo(req *shared.Request) (interface{}, error) { | 
					
						
							|  |  |  | 	args := new(GetContractInfoArgs) | 
					
						
							|  |  |  | 	if err := self.coder.Decode(req.Params, &args); err != nil { | 
					
						
							|  |  |  | 		return nil, shared.NewDecodeParamError(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	infoDoc, err := natspec.FetchDocsForContract(args.Contract, self.xeth, self.ds) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var info interface{} | 
					
						
							|  |  |  | 	err = self.coder.Decode(infoDoc, &info) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return info, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *adminApi) HttpGet(req *shared.Request) (interface{}, error) { | 
					
						
							|  |  |  | 	args := new(HttpGetArgs) | 
					
						
							|  |  |  | 	if err := self.coder.Decode(req.Params, &args); err != nil { | 
					
						
							|  |  |  | 		return nil, shared.NewDecodeParamError(err.Error()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	resp, err := self.ds.Get(args.Uri, args.Path) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return string(resp), nil | 
					
						
							|  |  |  | } |