github.com/jeffallen/go-ethereum@v1.1.4-0.20150910155051-571d3236c49c/xeth/xeth.go (about)

     1  // Copyright 2014 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  // Package xeth is the interface to all Ethereum functionality.
    18  package xeth
    19  
    20  import (
    21  	"bytes"
    22  	"encoding/json"
    23  	"errors"
    24  	"fmt"
    25  	"math/big"
    26  	"regexp"
    27  	"sync"
    28  	"time"
    29  
    30  	"github.com/ethereum/go-ethereum/accounts"
    31  	"github.com/ethereum/go-ethereum/common"
    32  	"github.com/ethereum/go-ethereum/common/compiler"
    33  	"github.com/ethereum/go-ethereum/core"
    34  	"github.com/ethereum/go-ethereum/core/state"
    35  	"github.com/ethereum/go-ethereum/core/types"
    36  	"github.com/ethereum/go-ethereum/crypto"
    37  	"github.com/ethereum/go-ethereum/eth"
    38  	"github.com/ethereum/go-ethereum/event/filter"
    39  	"github.com/ethereum/go-ethereum/logger"
    40  	"github.com/ethereum/go-ethereum/logger/glog"
    41  	"github.com/ethereum/go-ethereum/miner"
    42  	"github.com/ethereum/go-ethereum/rlp"
    43  )
    44  
    45  var (
    46  	filterTickerTime = 5 * time.Minute
    47  	defaultGasPrice  = big.NewInt(10000000000000) //150000000000
    48  	defaultGas       = big.NewInt(90000)          //500000
    49  	dappStorePre     = []byte("dapp-")
    50  	addrReg          = regexp.MustCompile(`^(0x)?[a-fA-F0-9]{40}$`)
    51  )
    52  
    53  // byte will be inferred
    54  const (
    55  	UnknownFilterTy = iota
    56  	BlockFilterTy
    57  	TransactionFilterTy
    58  	LogFilterTy
    59  )
    60  
    61  func DefaultGas() *big.Int { return new(big.Int).Set(defaultGas) }
    62  
    63  func (self *XEth) DefaultGasPrice() *big.Int {
    64  	if self.gpo == nil {
    65  		self.gpo = eth.NewGasPriceOracle(self.backend)
    66  	}
    67  	return self.gpo.SuggestPrice()
    68  }
    69  
    70  type XEth struct {
    71  	backend  *eth.Ethereum
    72  	frontend Frontend
    73  
    74  	state   *State
    75  	whisper *Whisper
    76  
    77  	quit          chan struct{}
    78  	filterManager *filter.FilterManager
    79  
    80  	logMu    sync.RWMutex
    81  	logQueue map[int]*logQueue
    82  
    83  	blockMu    sync.RWMutex
    84  	blockQueue map[int]*hashQueue
    85  
    86  	transactionMu    sync.RWMutex
    87  	transactionQueue map[int]*hashQueue
    88  
    89  	messagesMu sync.RWMutex
    90  	messages   map[int]*whisperFilter
    91  
    92  	transactMu sync.Mutex
    93  
    94  	agent *miner.RemoteAgent
    95  
    96  	gpo *eth.GasPriceOracle
    97  }
    98  
    99  func NewTest(eth *eth.Ethereum, frontend Frontend) *XEth {
   100  	return &XEth{
   101  		backend:  eth,
   102  		frontend: frontend,
   103  	}
   104  }
   105  
   106  // New creates an XEth that uses the given frontend.
   107  // If a nil Frontend is provided, a default frontend which
   108  // confirms all transactions will be used.
   109  func New(ethereum *eth.Ethereum, frontend Frontend) *XEth {
   110  	xeth := &XEth{
   111  		backend:          ethereum,
   112  		frontend:         frontend,
   113  		quit:             make(chan struct{}),
   114  		filterManager:    filter.NewFilterManager(ethereum.EventMux()),
   115  		logQueue:         make(map[int]*logQueue),
   116  		blockQueue:       make(map[int]*hashQueue),
   117  		transactionQueue: make(map[int]*hashQueue),
   118  		messages:         make(map[int]*whisperFilter),
   119  		agent:            miner.NewRemoteAgent(),
   120  	}
   121  	if ethereum.Whisper() != nil {
   122  		xeth.whisper = NewWhisper(ethereum.Whisper())
   123  	}
   124  	ethereum.Miner().Register(xeth.agent)
   125  	if frontend == nil {
   126  		xeth.frontend = dummyFrontend{}
   127  	}
   128  	xeth.state = NewState(xeth, xeth.backend.ChainManager().State())
   129  
   130  	go xeth.start()
   131  	go xeth.filterManager.Start()
   132  
   133  	return xeth
   134  }
   135  
   136  func (self *XEth) start() {
   137  	timer := time.NewTicker(2 * time.Second)
   138  done:
   139  	for {
   140  		select {
   141  		case <-timer.C:
   142  			self.logMu.Lock()
   143  			for id, filter := range self.logQueue {
   144  				if time.Since(filter.timeout) > filterTickerTime {
   145  					self.filterManager.UninstallFilter(id)
   146  					delete(self.logQueue, id)
   147  				}
   148  			}
   149  			self.logMu.Unlock()
   150  
   151  			self.blockMu.Lock()
   152  			for id, filter := range self.blockQueue {
   153  				if time.Since(filter.timeout) > filterTickerTime {
   154  					self.filterManager.UninstallFilter(id)
   155  					delete(self.blockQueue, id)
   156  				}
   157  			}
   158  			self.blockMu.Unlock()
   159  
   160  			self.transactionMu.Lock()
   161  			for id, filter := range self.transactionQueue {
   162  				if time.Since(filter.timeout) > filterTickerTime {
   163  					self.filterManager.UninstallFilter(id)
   164  					delete(self.transactionQueue, id)
   165  				}
   166  			}
   167  			self.transactionMu.Unlock()
   168  
   169  			self.messagesMu.Lock()
   170  			for id, filter := range self.messages {
   171  				if time.Since(filter.activity()) > filterTickerTime {
   172  					self.Whisper().Unwatch(id)
   173  					delete(self.messages, id)
   174  				}
   175  			}
   176  			self.messagesMu.Unlock()
   177  		case <-self.quit:
   178  			break done
   179  		}
   180  	}
   181  }
   182  
   183  func (self *XEth) stop() {
   184  	close(self.quit)
   185  }
   186  
   187  func cAddress(a []string) []common.Address {
   188  	bslice := make([]common.Address, len(a))
   189  	for i, addr := range a {
   190  		bslice[i] = common.HexToAddress(addr)
   191  	}
   192  	return bslice
   193  }
   194  
   195  func cTopics(t [][]string) [][]common.Hash {
   196  	topics := make([][]common.Hash, len(t))
   197  	for i, iv := range t {
   198  		topics[i] = make([]common.Hash, len(iv))
   199  		for j, jv := range iv {
   200  			topics[i][j] = common.HexToHash(jv)
   201  		}
   202  	}
   203  	return topics
   204  }
   205  
   206  func (self *XEth) RemoteMining() *miner.RemoteAgent { return self.agent }
   207  
   208  func (self *XEth) AtStateNum(num int64) *XEth {
   209  	var st *state.StateDB
   210  	switch num {
   211  	case -2:
   212  		st = self.backend.Miner().PendingState().Copy()
   213  	default:
   214  		if block := self.getBlockByHeight(num); block != nil {
   215  			st = state.New(block.Root(), self.backend.ChainDb())
   216  		} else {
   217  			st = state.New(self.backend.ChainManager().GetBlockByNumber(0).Root(), self.backend.ChainDb())
   218  		}
   219  	}
   220  
   221  	return self.WithState(st)
   222  }
   223  
   224  func (self *XEth) WithState(statedb *state.StateDB) *XEth {
   225  	xeth := &XEth{
   226  		backend:  self.backend,
   227  		frontend: self.frontend,
   228  		gpo:      self.gpo,
   229  	}
   230  
   231  	xeth.state = NewState(xeth, statedb)
   232  	return xeth
   233  }
   234  
   235  func (self *XEth) State() *State { return self.state }
   236  
   237  // subscribes to new head block events and
   238  // waits until blockchain height is greater n at any time
   239  // given the current head, waits for the next chain event
   240  // sets the state to the current head
   241  // loop is async and quit by closing the channel
   242  // used in tests and JS console debug module to control advancing private chain manually
   243  // Note: this is not threadsafe, only called in JS single process and tests
   244  func (self *XEth) UpdateState() (wait chan *big.Int) {
   245  	wait = make(chan *big.Int)
   246  	go func() {
   247  		sub := self.backend.EventMux().Subscribe(core.ChainHeadEvent{})
   248  		var m, n *big.Int
   249  		var ok bool
   250  	out:
   251  		for {
   252  			select {
   253  			case event := <-sub.Chan():
   254  				ev, ok := event.(core.ChainHeadEvent)
   255  				if ok {
   256  					m = ev.Block.Number()
   257  					if n != nil && n.Cmp(m) < 0 {
   258  						wait <- n
   259  						n = nil
   260  					}
   261  					statedb := state.New(ev.Block.Root(), self.backend.ChainDb())
   262  					self.state = NewState(self, statedb)
   263  				}
   264  			case n, ok = <-wait:
   265  				if !ok {
   266  					break out
   267  				}
   268  			}
   269  		}
   270  		sub.Unsubscribe()
   271  	}()
   272  	return
   273  }
   274  
   275  func (self *XEth) Whisper() *Whisper { return self.whisper }
   276  
   277  func (self *XEth) getBlockByHeight(height int64) *types.Block {
   278  	var num uint64
   279  
   280  	switch height {
   281  	case -2:
   282  		return self.backend.Miner().PendingBlock()
   283  	case -1:
   284  		return self.CurrentBlock()
   285  	default:
   286  		if height < 0 {
   287  			return nil
   288  		}
   289  
   290  		num = uint64(height)
   291  	}
   292  
   293  	return self.backend.ChainManager().GetBlockByNumber(num)
   294  }
   295  
   296  func (self *XEth) BlockByHash(strHash string) *Block {
   297  	hash := common.HexToHash(strHash)
   298  	block := self.backend.ChainManager().GetBlock(hash)
   299  
   300  	return NewBlock(block)
   301  }
   302  
   303  func (self *XEth) EthBlockByHash(strHash string) *types.Block {
   304  	hash := common.HexToHash(strHash)
   305  	block := self.backend.ChainManager().GetBlock(hash)
   306  
   307  	return block
   308  }
   309  
   310  func (self *XEth) EthTransactionByHash(hash string) (tx *types.Transaction, blhash common.Hash, blnum *big.Int, txi uint64) {
   311  	// Due to increasing return params and need to determine if this is from transaction pool or
   312  	// some chain, this probably needs to be refactored for more expressiveness
   313  	data, _ := self.backend.ChainDb().Get(common.FromHex(hash))
   314  	if len(data) != 0 {
   315  		dtx := new(types.Transaction)
   316  		if err := rlp.DecodeBytes(data, dtx); err != nil {
   317  			glog.V(logger.Error).Infoln(err)
   318  			return
   319  		}
   320  		tx = dtx
   321  	} else { // check pending transactions
   322  		tx = self.backend.TxPool().GetTransaction(common.HexToHash(hash))
   323  	}
   324  
   325  	// meta
   326  	var txExtra struct {
   327  		BlockHash  common.Hash
   328  		BlockIndex uint64
   329  		Index      uint64
   330  	}
   331  
   332  	v, dberr := self.backend.ChainDb().Get(append(common.FromHex(hash), 0x0001))
   333  	// TODO check specifically for ErrNotFound
   334  	if dberr != nil {
   335  		return
   336  	}
   337  	r := bytes.NewReader(v)
   338  	err := rlp.Decode(r, &txExtra)
   339  	if err == nil {
   340  		blhash = txExtra.BlockHash
   341  		blnum = big.NewInt(int64(txExtra.BlockIndex))
   342  		txi = txExtra.Index
   343  	} else {
   344  		glog.V(logger.Error).Infoln(err)
   345  	}
   346  
   347  	return
   348  }
   349  
   350  func (self *XEth) BlockByNumber(num int64) *Block {
   351  	return NewBlock(self.getBlockByHeight(num))
   352  }
   353  
   354  func (self *XEth) EthBlockByNumber(num int64) *types.Block {
   355  	return self.getBlockByHeight(num)
   356  }
   357  
   358  func (self *XEth) CurrentBlock() *types.Block {
   359  	return self.backend.ChainManager().CurrentBlock()
   360  }
   361  
   362  func (self *XEth) GetBlockReceipts(bhash common.Hash) types.Receipts {
   363  	return self.backend.BlockProcessor().GetBlockReceipts(bhash)
   364  }
   365  
   366  func (self *XEth) GetTxReceipt(txhash common.Hash) *types.Receipt {
   367  	return core.GetReceipt(self.backend.ChainDb(), txhash)
   368  }
   369  
   370  func (self *XEth) GasLimit() *big.Int {
   371  	return self.backend.ChainManager().GasLimit()
   372  }
   373  
   374  func (self *XEth) Block(v interface{}) *Block {
   375  	if n, ok := v.(int32); ok {
   376  		return self.BlockByNumber(int64(n))
   377  	} else if str, ok := v.(string); ok {
   378  		return self.BlockByHash(str)
   379  	} else if f, ok := v.(float64); ok { // JSON numbers are represented as float64
   380  		return self.BlockByNumber(int64(f))
   381  	}
   382  
   383  	return nil
   384  }
   385  
   386  func (self *XEth) Accounts() []string {
   387  	// TODO: check err?
   388  	accounts, _ := self.backend.AccountManager().Accounts()
   389  	accountAddresses := make([]string, len(accounts))
   390  	for i, ac := range accounts {
   391  		accountAddresses[i] = ac.Address.Hex()
   392  	}
   393  	return accountAddresses
   394  }
   395  
   396  // accessor for solidity compiler.
   397  // memoized if available, retried on-demand if not
   398  func (self *XEth) Solc() (*compiler.Solidity, error) {
   399  	return self.backend.Solc()
   400  }
   401  
   402  // set in js console via admin interface or wrapper from cli flags
   403  func (self *XEth) SetSolc(solcPath string) (*compiler.Solidity, error) {
   404  	self.backend.SetSolc(solcPath)
   405  	return self.Solc()
   406  }
   407  
   408  // store DApp value in extra database
   409  func (self *XEth) DbPut(key, val []byte) bool {
   410  	self.backend.DappDb().Put(append(dappStorePre, key...), val)
   411  	return true
   412  }
   413  
   414  // retrieve DApp value from extra database
   415  func (self *XEth) DbGet(key []byte) ([]byte, error) {
   416  	val, err := self.backend.DappDb().Get(append(dappStorePre, key...))
   417  	return val, err
   418  }
   419  
   420  func (self *XEth) PeerCount() int {
   421  	return self.backend.PeerCount()
   422  }
   423  
   424  func (self *XEth) IsMining() bool {
   425  	return self.backend.IsMining()
   426  }
   427  
   428  func (self *XEth) HashRate() int64 {
   429  	return self.backend.Miner().HashRate()
   430  }
   431  
   432  func (self *XEth) EthVersion() string {
   433  	return fmt.Sprintf("%d", self.backend.EthVersion())
   434  }
   435  
   436  func (self *XEth) NetworkVersion() string {
   437  	return fmt.Sprintf("%d", self.backend.NetVersion())
   438  }
   439  
   440  func (self *XEth) WhisperVersion() string {
   441  	return fmt.Sprintf("%d", self.backend.ShhVersion())
   442  }
   443  
   444  func (self *XEth) ClientVersion() string {
   445  	return self.backend.ClientVersion()
   446  }
   447  
   448  func (self *XEth) SetMining(shouldmine bool, threads int) bool {
   449  	ismining := self.backend.IsMining()
   450  	if shouldmine && !ismining {
   451  		err := self.backend.StartMining(threads)
   452  		return err == nil
   453  	}
   454  	if ismining && !shouldmine {
   455  		self.backend.StopMining()
   456  	}
   457  	return self.backend.IsMining()
   458  }
   459  
   460  func (self *XEth) IsListening() bool {
   461  	return self.backend.IsListening()
   462  }
   463  
   464  func (self *XEth) Coinbase() string {
   465  	eb, err := self.backend.Etherbase()
   466  	if err != nil {
   467  		return "0x0"
   468  	}
   469  	return eb.Hex()
   470  }
   471  
   472  func (self *XEth) NumberToHuman(balance string) string {
   473  	b := common.Big(balance)
   474  
   475  	return common.CurrencyToString(b)
   476  }
   477  
   478  func (self *XEth) StorageAt(addr, storageAddr string) string {
   479  	return self.State().state.GetState(common.HexToAddress(addr), common.HexToHash(storageAddr)).Hex()
   480  }
   481  
   482  func (self *XEth) BalanceAt(addr string) string {
   483  	return common.ToHex(self.State().state.GetBalance(common.HexToAddress(addr)).Bytes())
   484  }
   485  
   486  func (self *XEth) TxCountAt(address string) int {
   487  	return int(self.State().state.GetNonce(common.HexToAddress(address)))
   488  }
   489  
   490  func (self *XEth) CodeAt(address string) string {
   491  	return common.ToHex(self.State().state.GetCode(common.HexToAddress(address)))
   492  }
   493  
   494  func (self *XEth) CodeAtBytes(address string) []byte {
   495  	return self.State().SafeGet(address).Code()
   496  }
   497  
   498  func (self *XEth) IsContract(address string) bool {
   499  	return len(self.State().SafeGet(address).Code()) > 0
   500  }
   501  
   502  func (self *XEth) UninstallFilter(id int) bool {
   503  	defer self.filterManager.UninstallFilter(id)
   504  
   505  	if _, ok := self.logQueue[id]; ok {
   506  		self.logMu.Lock()
   507  		defer self.logMu.Unlock()
   508  		delete(self.logQueue, id)
   509  		return true
   510  	}
   511  	if _, ok := self.blockQueue[id]; ok {
   512  		self.blockMu.Lock()
   513  		defer self.blockMu.Unlock()
   514  		delete(self.blockQueue, id)
   515  		return true
   516  	}
   517  	if _, ok := self.transactionQueue[id]; ok {
   518  		self.transactionMu.Lock()
   519  		defer self.transactionMu.Unlock()
   520  		delete(self.transactionQueue, id)
   521  		return true
   522  	}
   523  
   524  	return false
   525  }
   526  
   527  func (self *XEth) NewLogFilter(earliest, latest int64, skip, max int, address []string, topics [][]string) int {
   528  	self.logMu.Lock()
   529  	defer self.logMu.Unlock()
   530  
   531  	var id int
   532  	filter := core.NewFilter(self.backend)
   533  	filter.SetEarliestBlock(earliest)
   534  	filter.SetLatestBlock(latest)
   535  	filter.SetSkip(skip)
   536  	filter.SetMax(max)
   537  	filter.SetAddress(cAddress(address))
   538  	filter.SetTopics(cTopics(topics))
   539  	filter.LogsCallback = func(logs state.Logs) {
   540  		self.logMu.Lock()
   541  		defer self.logMu.Unlock()
   542  
   543  		self.logQueue[id].add(logs...)
   544  	}
   545  	id = self.filterManager.InstallFilter(filter)
   546  	self.logQueue[id] = &logQueue{timeout: time.Now()}
   547  
   548  	return id
   549  }
   550  
   551  func (self *XEth) NewTransactionFilter() int {
   552  	self.transactionMu.Lock()
   553  	defer self.transactionMu.Unlock()
   554  
   555  	var id int
   556  	filter := core.NewFilter(self.backend)
   557  	filter.TransactionCallback = func(tx *types.Transaction) {
   558  		self.transactionMu.Lock()
   559  		defer self.transactionMu.Unlock()
   560  
   561  		self.transactionQueue[id].add(tx.Hash())
   562  	}
   563  	id = self.filterManager.InstallFilter(filter)
   564  	self.transactionQueue[id] = &hashQueue{timeout: time.Now()}
   565  	return id
   566  }
   567  
   568  func (self *XEth) NewBlockFilter() int {
   569  	self.blockMu.Lock()
   570  	defer self.blockMu.Unlock()
   571  
   572  	var id int
   573  	filter := core.NewFilter(self.backend)
   574  	filter.BlockCallback = func(block *types.Block, logs state.Logs) {
   575  		self.blockMu.Lock()
   576  		defer self.blockMu.Unlock()
   577  
   578  		self.blockQueue[id].add(block.Hash())
   579  	}
   580  	id = self.filterManager.InstallFilter(filter)
   581  	self.blockQueue[id] = &hashQueue{timeout: time.Now()}
   582  	return id
   583  }
   584  
   585  func (self *XEth) GetFilterType(id int) byte {
   586  	if _, ok := self.blockQueue[id]; ok {
   587  		return BlockFilterTy
   588  	} else if _, ok := self.transactionQueue[id]; ok {
   589  		return TransactionFilterTy
   590  	} else if _, ok := self.logQueue[id]; ok {
   591  		return LogFilterTy
   592  	}
   593  
   594  	return UnknownFilterTy
   595  }
   596  
   597  func (self *XEth) LogFilterChanged(id int) state.Logs {
   598  	self.logMu.Lock()
   599  	defer self.logMu.Unlock()
   600  
   601  	if self.logQueue[id] != nil {
   602  		return self.logQueue[id].get()
   603  	}
   604  	return nil
   605  }
   606  
   607  func (self *XEth) BlockFilterChanged(id int) []common.Hash {
   608  	self.blockMu.Lock()
   609  	defer self.blockMu.Unlock()
   610  
   611  	if self.blockQueue[id] != nil {
   612  		return self.blockQueue[id].get()
   613  	}
   614  	return nil
   615  }
   616  
   617  func (self *XEth) TransactionFilterChanged(id int) []common.Hash {
   618  	self.blockMu.Lock()
   619  	defer self.blockMu.Unlock()
   620  
   621  	if self.transactionQueue[id] != nil {
   622  		return self.transactionQueue[id].get()
   623  	}
   624  	return nil
   625  }
   626  
   627  func (self *XEth) Logs(id int) state.Logs {
   628  	filter := self.filterManager.GetFilter(id)
   629  	if filter != nil {
   630  		return filter.Find()
   631  	}
   632  
   633  	return nil
   634  }
   635  
   636  func (self *XEth) AllLogs(earliest, latest int64, skip, max int, address []string, topics [][]string) state.Logs {
   637  	filter := core.NewFilter(self.backend)
   638  	filter.SetEarliestBlock(earliest)
   639  	filter.SetLatestBlock(latest)
   640  	filter.SetSkip(skip)
   641  	filter.SetMax(max)
   642  	filter.SetAddress(cAddress(address))
   643  	filter.SetTopics(cTopics(topics))
   644  
   645  	return filter.Find()
   646  }
   647  
   648  // NewWhisperFilter creates and registers a new message filter to watch for
   649  // inbound whisper messages. All parameters at this point are assumed to be
   650  // HEX encoded.
   651  func (p *XEth) NewWhisperFilter(to, from string, topics [][]string) int {
   652  	// Pre-define the id to be filled later
   653  	var id int
   654  
   655  	// Callback to delegate core whisper messages to this xeth filter
   656  	callback := func(msg WhisperMessage) {
   657  		p.messagesMu.RLock() // Only read lock to the filter pool
   658  		defer p.messagesMu.RUnlock()
   659  		p.messages[id].insert(msg)
   660  	}
   661  	// Initialize the core whisper filter and wrap into xeth
   662  	id = p.Whisper().Watch(to, from, topics, callback)
   663  
   664  	p.messagesMu.Lock()
   665  	p.messages[id] = newWhisperFilter(id, p.Whisper())
   666  	p.messagesMu.Unlock()
   667  
   668  	return id
   669  }
   670  
   671  // UninstallWhisperFilter disables and removes an existing filter.
   672  func (p *XEth) UninstallWhisperFilter(id int) bool {
   673  	p.messagesMu.Lock()
   674  	defer p.messagesMu.Unlock()
   675  
   676  	if _, ok := p.messages[id]; ok {
   677  		delete(p.messages, id)
   678  		return true
   679  	}
   680  	return false
   681  }
   682  
   683  // WhisperMessages retrieves all the known messages that match a specific filter.
   684  func (self *XEth) WhisperMessages(id int) []WhisperMessage {
   685  	self.messagesMu.RLock()
   686  	defer self.messagesMu.RUnlock()
   687  
   688  	if self.messages[id] != nil {
   689  		return self.messages[id].messages()
   690  	}
   691  	return nil
   692  }
   693  
   694  // WhisperMessagesChanged retrieves all the new messages matched by a filter
   695  // since the last retrieval
   696  func (self *XEth) WhisperMessagesChanged(id int) []WhisperMessage {
   697  	self.messagesMu.RLock()
   698  	defer self.messagesMu.RUnlock()
   699  
   700  	if self.messages[id] != nil {
   701  		return self.messages[id].retrieve()
   702  	}
   703  	return nil
   704  }
   705  
   706  // func (self *XEth) Register(args string) bool {
   707  // 	self.regmut.Lock()
   708  // 	defer self.regmut.Unlock()
   709  
   710  // 	if _, ok := self.register[args]; ok {
   711  // 		self.register[args] = nil // register with empty
   712  // 	}
   713  // 	return true
   714  // }
   715  
   716  // func (self *XEth) Unregister(args string) bool {
   717  // 	self.regmut.Lock()
   718  // 	defer self.regmut.Unlock()
   719  
   720  // 	if _, ok := self.register[args]; ok {
   721  // 		delete(self.register, args)
   722  // 		return true
   723  // 	}
   724  
   725  // 	return false
   726  // }
   727  
   728  // // TODO improve return type
   729  // func (self *XEth) PullWatchTx(args string) []*interface{} {
   730  // 	self.regmut.Lock()
   731  // 	defer self.regmut.Unlock()
   732  
   733  // 	txs := self.register[args]
   734  // 	self.register[args] = nil
   735  
   736  // 	return txs
   737  // }
   738  
   739  type KeyVal struct {
   740  	Key   string `json:"key"`
   741  	Value string `json:"value"`
   742  }
   743  
   744  func (self *XEth) EachStorage(addr string) string {
   745  	var values []KeyVal
   746  	object := self.State().SafeGet(addr)
   747  	it := object.Trie().Iterator()
   748  	for it.Next() {
   749  		values = append(values, KeyVal{common.ToHex(object.Trie().GetKey(it.Key)), common.ToHex(it.Value)})
   750  	}
   751  
   752  	valuesJson, err := json.Marshal(values)
   753  	if err != nil {
   754  		return ""
   755  	}
   756  
   757  	return string(valuesJson)
   758  }
   759  
   760  func (self *XEth) ToAscii(str string) string {
   761  	padded := common.RightPadBytes([]byte(str), 32)
   762  
   763  	return "0x" + common.ToHex(padded)
   764  }
   765  
   766  func (self *XEth) FromAscii(str string) string {
   767  	if common.IsHex(str) {
   768  		str = str[2:]
   769  	}
   770  
   771  	return string(bytes.Trim(common.FromHex(str), "\x00"))
   772  }
   773  
   774  func (self *XEth) FromNumber(str string) string {
   775  	if common.IsHex(str) {
   776  		str = str[2:]
   777  	}
   778  
   779  	return common.BigD(common.FromHex(str)).String()
   780  }
   781  
   782  func (self *XEth) PushTx(encodedTx string) (string, error) {
   783  	tx := new(types.Transaction)
   784  	err := rlp.DecodeBytes(common.FromHex(encodedTx), tx)
   785  	if err != nil {
   786  		glog.V(logger.Error).Infoln(err)
   787  		return "", err
   788  	}
   789  
   790  	err = self.backend.TxPool().Add(tx)
   791  	if err != nil {
   792  		return "", err
   793  	}
   794  
   795  	if tx.To() == nil {
   796  		from, err := tx.From()
   797  		if err != nil {
   798  			return "", err
   799  		}
   800  
   801  		addr := crypto.CreateAddress(from, tx.Nonce())
   802  		glog.V(logger.Info).Infof("Tx(%x) created: %x\n", tx.Hash(), addr)
   803  	} else {
   804  		glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To())
   805  	}
   806  
   807  	return tx.Hash().Hex(), nil
   808  }
   809  
   810  func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr string) (string, string, error) {
   811  	statedb := self.State().State().Copy()
   812  	var from *state.StateObject
   813  	if len(fromStr) == 0 {
   814  		accounts, err := self.backend.AccountManager().Accounts()
   815  		if err != nil || len(accounts) == 0 {
   816  			from = statedb.GetOrNewStateObject(common.Address{})
   817  		} else {
   818  			from = statedb.GetOrNewStateObject(accounts[0].Address)
   819  		}
   820  	} else {
   821  		from = statedb.GetOrNewStateObject(common.HexToAddress(fromStr))
   822  	}
   823  
   824  	from.SetBalance(common.MaxBig)
   825  	from.SetGasLimit(common.MaxBig)
   826  
   827  	msg := callmsg{
   828  		from:     from,
   829  		gas:      common.Big(gasStr),
   830  		gasPrice: common.Big(gasPriceStr),
   831  		value:    common.Big(valueStr),
   832  		data:     common.FromHex(dataStr),
   833  	}
   834  	if len(toStr) > 0 {
   835  		addr := common.HexToAddress(toStr)
   836  		msg.to = &addr
   837  	}
   838  
   839  	if msg.gas.Cmp(big.NewInt(0)) == 0 {
   840  		msg.gas = big.NewInt(50000000)
   841  	}
   842  
   843  	if msg.gasPrice.Cmp(big.NewInt(0)) == 0 {
   844  		msg.gasPrice = self.DefaultGasPrice()
   845  	}
   846  
   847  	header := self.CurrentBlock().Header()
   848  	vmenv := core.NewEnv(statedb, self.backend.ChainManager(), msg, header)
   849  
   850  	res, gas, err := core.ApplyMessage(vmenv, msg, from)
   851  	return common.ToHex(res), gas.String(), err
   852  }
   853  
   854  func (self *XEth) ConfirmTransaction(tx string) bool {
   855  	return self.frontend.ConfirmTransaction(tx)
   856  }
   857  
   858  func (self *XEth) doSign(from common.Address, hash common.Hash, didUnlock bool) ([]byte, error) {
   859  	sig, err := self.backend.AccountManager().Sign(accounts.Account{Address: from}, hash.Bytes())
   860  	if err == accounts.ErrLocked {
   861  		if didUnlock {
   862  			return nil, fmt.Errorf("signer account still locked after successful unlock")
   863  		}
   864  		if !self.frontend.UnlockAccount(from.Bytes()) {
   865  			return nil, fmt.Errorf("could not unlock signer account")
   866  		}
   867  		// retry signing, the account should now be unlocked.
   868  		return self.doSign(from, hash, true)
   869  	} else if err != nil {
   870  		return nil, err
   871  	}
   872  	return sig, nil
   873  }
   874  
   875  func (self *XEth) Sign(fromStr, hashStr string, didUnlock bool) (string, error) {
   876  	var (
   877  		from = common.HexToAddress(fromStr)
   878  		hash = common.HexToHash(hashStr)
   879  	)
   880  	sig, err := self.doSign(from, hash, didUnlock)
   881  	if err != nil {
   882  		return "", err
   883  	}
   884  	return common.ToHex(sig), nil
   885  }
   886  
   887  func isAddress(addr string) bool {
   888  	return addrReg.MatchString(addr)
   889  }
   890  
   891  func (self *XEth) Frontend() Frontend {
   892  	return self.frontend
   893  }
   894  
   895  func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) {
   896  
   897  	// this minimalistic recoding is enough (works for natspec.js)
   898  	var jsontx = fmt.Sprintf(`{"params":[{"to":"%s","data": "%s"}]}`, toStr, codeStr)
   899  	if !self.ConfirmTransaction(jsontx) {
   900  		err := fmt.Errorf("Transaction not confirmed")
   901  		return "", err
   902  	}
   903  
   904  	if len(toStr) > 0 && toStr != "0x" && !isAddress(toStr) {
   905  		return "", errors.New("Invalid address")
   906  	}
   907  
   908  	var (
   909  		from             = common.HexToAddress(fromStr)
   910  		to               = common.HexToAddress(toStr)
   911  		value            = common.Big(valueStr)
   912  		gas              *big.Int
   913  		price            *big.Int
   914  		data             []byte
   915  		contractCreation bool
   916  	)
   917  
   918  	if len(gasStr) == 0 {
   919  		gas = DefaultGas()
   920  	} else {
   921  		gas = common.Big(gasStr)
   922  	}
   923  
   924  	if len(gasPriceStr) == 0 {
   925  		price = self.DefaultGasPrice()
   926  	} else {
   927  		price = common.Big(gasPriceStr)
   928  	}
   929  
   930  	data = common.FromHex(codeStr)
   931  	if len(toStr) == 0 {
   932  		contractCreation = true
   933  	}
   934  
   935  	// 2015-05-18 Is this still needed?
   936  	// TODO if no_private_key then
   937  	//if _, exists := p.register[args.From]; exists {
   938  	//	p.register[args.From] = append(p.register[args.From], args)
   939  	//} else {
   940  	/*
   941  		account := accounts.Get(common.FromHex(args.From))
   942  		if account != nil {
   943  			if account.Unlocked() {
   944  				if !unlockAccount(account) {
   945  					return
   946  				}
   947  			}
   948  
   949  			result, _ := account.Transact(common.FromHex(args.To), common.FromHex(args.Value), common.FromHex(args.Gas), common.FromHex(args.GasPrice), common.FromHex(args.Data))
   950  			if len(result) > 0 {
   951  				*reply = common.ToHex(result)
   952  			}
   953  		} else if _, exists := p.register[args.From]; exists {
   954  			p.register[ags.From] = append(p.register[args.From], args)
   955  		}
   956  	*/
   957  
   958  	self.transactMu.Lock()
   959  	defer self.transactMu.Unlock()
   960  
   961  	var nonce uint64
   962  	if len(nonceStr) != 0 {
   963  		nonce = common.Big(nonceStr).Uint64()
   964  	} else {
   965  		state := self.backend.TxPool().State()
   966  		nonce = state.GetNonce(from)
   967  	}
   968  	var tx *types.Transaction
   969  	if contractCreation {
   970  		tx = types.NewContractCreation(nonce, value, gas, price, data)
   971  	} else {
   972  		tx = types.NewTransaction(nonce, to, value, gas, price, data)
   973  	}
   974  
   975  	signed, err := self.sign(tx, from, false)
   976  	if err != nil {
   977  		return "", err
   978  	}
   979  	if err = self.backend.TxPool().Add(signed); err != nil {
   980  		return "", err
   981  	}
   982  
   983  	if contractCreation {
   984  		addr := crypto.CreateAddress(from, nonce)
   985  		glog.V(logger.Info).Infof("Tx(%s) created: %s\n", signed.Hash().Hex(), addr.Hex())
   986  	} else {
   987  		glog.V(logger.Info).Infof("Tx(%s) to: %s\n", signed.Hash().Hex(), tx.To().Hex())
   988  	}
   989  
   990  	return signed.Hash().Hex(), nil
   991  }
   992  
   993  func (self *XEth) sign(tx *types.Transaction, from common.Address, didUnlock bool) (*types.Transaction, error) {
   994  	hash := tx.SigHash()
   995  	sig, err := self.doSign(from, hash, didUnlock)
   996  	if err != nil {
   997  		return tx, err
   998  	}
   999  	return tx.WithSignature(sig)
  1000  }
  1001  
  1002  // callmsg is the message type used for call transations.
  1003  type callmsg struct {
  1004  	from          *state.StateObject
  1005  	to            *common.Address
  1006  	gas, gasPrice *big.Int
  1007  	value         *big.Int
  1008  	data          []byte
  1009  }
  1010  
  1011  // accessor boilerplate to implement core.Message
  1012  func (m callmsg) From() (common.Address, error) { return m.from.Address(), nil }
  1013  func (m callmsg) Nonce() uint64                 { return m.from.Nonce() }
  1014  func (m callmsg) To() *common.Address           { return m.to }
  1015  func (m callmsg) GasPrice() *big.Int            { return m.gasPrice }
  1016  func (m callmsg) Gas() *big.Int                 { return m.gas }
  1017  func (m callmsg) Value() *big.Int               { return m.value }
  1018  func (m callmsg) Data() []byte                  { return m.data }
  1019  
  1020  type logQueue struct {
  1021  	logs    state.Logs
  1022  	timeout time.Time
  1023  	id      int
  1024  }
  1025  
  1026  func (l *logQueue) add(logs ...*state.Log) {
  1027  	l.logs = append(l.logs, logs...)
  1028  }
  1029  
  1030  func (l *logQueue) get() state.Logs {
  1031  	l.timeout = time.Now()
  1032  	tmp := l.logs
  1033  	l.logs = nil
  1034  	return tmp
  1035  }
  1036  
  1037  type hashQueue struct {
  1038  	hashes  []common.Hash
  1039  	timeout time.Time
  1040  	id      int
  1041  }
  1042  
  1043  func (l *hashQueue) add(hashes ...common.Hash) {
  1044  	l.hashes = append(l.hashes, hashes...)
  1045  }
  1046  
  1047  func (l *hashQueue) get() []common.Hash {
  1048  	l.timeout = time.Now()
  1049  	tmp := l.hashes
  1050  	l.hashes = nil
  1051  	return tmp
  1052  }