xeth.go 26.8 KB
Newer Older
F
Felix Lange 已提交
1
// Copyright 2014 The go-ethereum Authors
2
// This file is part of the go-ethereum library.
F
Felix Lange 已提交
3
//
4
// The go-ethereum library is free software: you can redistribute it and/or modify
F
Felix Lange 已提交
5 6 7 8
// 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.
//
9
// The go-ethereum library is distributed in the hope that it will be useful,
F
Felix Lange 已提交
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
F
Felix Lange 已提交
12 13 14
// GNU Lesser General Public License for more details.
//
// 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/>.
F
Felix Lange 已提交
16

17
// Package xeth is the interface to all Ethereum functionality.
O
obscuren 已提交
18 19
package xeth

O
obscuren 已提交
20 21 22
import (
	"bytes"
	"encoding/json"
23
	"errors"
24
	"fmt"
25
	"math/big"
26
	"regexp"
T
Taylor Gerring 已提交
27 28
	"sync"
	"time"
O
obscuren 已提交
29

30
	"github.com/ethereum/go-ethereum/accounts"
O
obscuren 已提交
31
	"github.com/ethereum/go-ethereum/common"
32
	"github.com/ethereum/go-ethereum/common/compiler"
O
obscuren 已提交
33
	"github.com/ethereum/go-ethereum/core"
T
Taylor Gerring 已提交
34
	"github.com/ethereum/go-ethereum/core/state"
O
obscuren 已提交
35
	"github.com/ethereum/go-ethereum/core/types"
36
	"github.com/ethereum/go-ethereum/core/vm"
O
obscuren 已提交
37
	"github.com/ethereum/go-ethereum/crypto"
38
	"github.com/ethereum/go-ethereum/eth"
39
	"github.com/ethereum/go-ethereum/eth/filters"
O
obscuren 已提交
40
	"github.com/ethereum/go-ethereum/logger"
O
obscuren 已提交
41
	"github.com/ethereum/go-ethereum/logger/glog"
42
	"github.com/ethereum/go-ethereum/miner"
T
Taylor Gerring 已提交
43
	"github.com/ethereum/go-ethereum/rlp"
O
obscuren 已提交
44
)
O
obscuren 已提交
45

T
Taylor Gerring 已提交
46 47
var (
	filterTickerTime = 5 * time.Minute
T
Taylor Gerring 已提交
48 49
	defaultGasPrice  = big.NewInt(10000000000000) //150000000000
	defaultGas       = big.NewInt(90000)          //500000
50
	dappStorePre     = []byte("dapp-")
51
	addrReg          = regexp.MustCompile(`^(0x)?[a-fA-F0-9]{40}$`)
T
Taylor Gerring 已提交
52
)
O
obscuren 已提交
53

54 55 56 57 58 59 60 61
// byte will be inferred
const (
	UnknownFilterTy = iota
	BlockFilterTy
	TransactionFilterTy
	LogFilterTy
)

Z
zsfelfoldi 已提交
62 63 64
func DefaultGas() *big.Int { return new(big.Int).Set(defaultGas) }

func (self *XEth) DefaultGasPrice() *big.Int {
Z
zsfelfoldi 已提交
65 66 67
	if self.gpo == nil {
		self.gpo = eth.NewGasPriceOracle(self.backend)
	}
Z
zsfelfoldi 已提交
68 69
	return self.gpo.SuggestPrice()
}
O
obscuren 已提交
70

O
obscuren 已提交
71
type XEth struct {
T
Shuffle  
Taylor Gerring 已提交
72 73 74
	backend  *eth.Ethereum
	frontend Frontend

T
Taylor Gerring 已提交
75 76
	state   *State
	whisper *Whisper
O
obscuren 已提交
77

T
Taylor Gerring 已提交
78
	quit          chan struct{}
79
	filterManager *filters.FilterSystem
O
obscuren 已提交
80

81 82 83 84 85 86 87 88
	logMu    sync.RWMutex
	logQueue map[int]*logQueue

	blockMu    sync.RWMutex
	blockQueue map[int]*hashQueue

	transactionMu    sync.RWMutex
	transactionQueue map[int]*hashQueue
T
Taylor Gerring 已提交
89

90 91
	messagesMu sync.RWMutex
	messages   map[int]*whisperFilter
T
Taylor Gerring 已提交
92

J
Jeffrey Wilcke 已提交
93
	transactMu sync.Mutex
94

T
Taylor Gerring 已提交
95
	agent *miner.RemoteAgent
Z
zsfelfoldi 已提交
96 97

	gpo *eth.GasPriceOracle
O
obscuren 已提交
98
}
O
obscuren 已提交
99

100 101 102 103 104 105 106
func NewTest(eth *eth.Ethereum, frontend Frontend) *XEth {
	return &XEth{
		backend:  eth,
		frontend: frontend,
	}
}

107 108 109
// New creates an XEth that uses the given frontend.
// If a nil Frontend is provided, a default frontend which
// confirms all transactions will be used.
Z
zsfelfoldi 已提交
110
func New(ethereum *eth.Ethereum, frontend Frontend) *XEth {
O
obscuren 已提交
111
	xeth := &XEth{
Z
zsfelfoldi 已提交
112
		backend:          ethereum,
113 114
		frontend:         frontend,
		quit:             make(chan struct{}),
115
		filterManager:    filters.NewFilterSystem(ethereum.EventMux()),
116 117 118 119 120
		logQueue:         make(map[int]*logQueue),
		blockQueue:       make(map[int]*hashQueue),
		transactionQueue: make(map[int]*hashQueue),
		messages:         make(map[int]*whisperFilter),
		agent:            miner.NewRemoteAgent(),
O
obscuren 已提交
121
	}
Z
zsfelfoldi 已提交
122 123
	if ethereum.Whisper() != nil {
		xeth.whisper = NewWhisper(ethereum.Whisper())
124
	}
Z
zsfelfoldi 已提交
125
	ethereum.Miner().Register(xeth.agent)
O
obscuren 已提交
126
	if frontend == nil {
127
		xeth.frontend = dummyFrontend{}
O
obscuren 已提交
128
	}
129 130 131 132 133
	state, err := xeth.backend.BlockChain().State()
	if err != nil {
		return nil
	}
	xeth.state = NewState(xeth, state)
T
Shuffle  
Taylor Gerring 已提交
134

T
Taylor Gerring 已提交
135 136
	go xeth.start()

O
obscuren 已提交
137 138 139
	return xeth
}

T
Taylor Gerring 已提交
140 141 142 143 144 145
func (self *XEth) start() {
	timer := time.NewTicker(2 * time.Second)
done:
	for {
		select {
		case <-timer.C:
146 147 148
			self.logMu.Lock()
			for id, filter := range self.logQueue {
				if time.Since(filter.timeout) > filterTickerTime {
149
					self.filterManager.Remove(id)
150 151 152 153 154 155 156 157
					delete(self.logQueue, id)
				}
			}
			self.logMu.Unlock()

			self.blockMu.Lock()
			for id, filter := range self.blockQueue {
				if time.Since(filter.timeout) > filterTickerTime {
158
					self.filterManager.Remove(id)
159 160 161 162 163 164 165
					delete(self.blockQueue, id)
				}
			}
			self.blockMu.Unlock()

			self.transactionMu.Lock()
			for id, filter := range self.transactionQueue {
T
Taylor Gerring 已提交
166
				if time.Since(filter.timeout) > filterTickerTime {
167
					self.filterManager.Remove(id)
168
					delete(self.transactionQueue, id)
T
Taylor Gerring 已提交
169 170
				}
			}
171
			self.transactionMu.Unlock()
T
Taylor Gerring 已提交
172

173
			self.messagesMu.Lock()
T
Taylor Gerring 已提交
174
			for id, filter := range self.messages {
175
				if time.Since(filter.activity()) > filterTickerTime {
T
Taylor Gerring 已提交
176 177 178 179
					self.Whisper().Unwatch(id)
					delete(self.messages, id)
				}
			}
180
			self.messagesMu.Unlock()
T
Taylor Gerring 已提交
181 182 183 184 185 186 187 188 189 190
		case <-self.quit:
			break done
		}
	}
}

func (self *XEth) stop() {
	close(self.quit)
}

T
Taylor Gerring 已提交
191 192 193 194 195 196 197 198 199 200 201
func cAddress(a []string) []common.Address {
	bslice := make([]common.Address, len(a))
	for i, addr := range a {
		bslice[i] = common.HexToAddress(addr)
	}
	return bslice
}

func cTopics(t [][]string) [][]common.Hash {
	topics := make([][]common.Hash, len(t))
	for i, iv := range t {
202
		topics[i] = make([]common.Hash, len(iv))
T
Taylor Gerring 已提交
203 204 205 206 207 208 209
		for j, jv := range iv {
			topics[i][j] = common.HexToHash(jv)
		}
	}
	return topics
}

T
Taylor Gerring 已提交
210
func (self *XEth) RemoteMining() *miner.RemoteAgent { return self.agent }
211

T
Taylor Gerring 已提交
212 213
func (self *XEth) AtStateNum(num int64) *XEth {
	var st *state.StateDB
214
	var err error
O
obscuren 已提交
215 216 217 218 219
	switch num {
	case -2:
		st = self.backend.Miner().PendingState().Copy()
	default:
		if block := self.getBlockByHeight(num); block != nil {
220 221 222 223
			st, err = state.New(block.Root(), self.backend.ChainDb())
			if err != nil {
				return nil
			}
O
obscuren 已提交
224
		} else {
225 226 227 228
			st, err = state.New(self.backend.BlockChain().GetBlockByNumber(0).Root(), self.backend.ChainDb())
			if err != nil {
				return nil
			}
O
obscuren 已提交
229
		}
T
Taylor Gerring 已提交
230
	}
T
Taylor Gerring 已提交
231

232
	return self.WithState(st)
T
Taylor Gerring 已提交
233 234
}

235
func (self *XEth) WithState(statedb *state.StateDB) *XEth {
O
wip  
obscuren 已提交
236
	xeth := &XEth{
237 238
		backend:  self.backend,
		frontend: self.frontend,
Z
zsfelfoldi 已提交
239
		gpo:      self.gpo,
O
wip  
obscuren 已提交
240 241 242 243 244
	}

	xeth.state = NewState(xeth, statedb)
	return xeth
}
T
Shuffle  
Taylor Gerring 已提交
245

O
wip  
obscuren 已提交
246 247
func (self *XEth) State() *State { return self.state }

248 249 250 251 252 253 254 255 256 257
// subscribes to new head block events and
// waits until blockchain height is greater n at any time
// given the current head, waits for the next chain event
// sets the state to the current head
// loop is async and quit by closing the channel
// used in tests and JS console debug module to control advancing private chain manually
// Note: this is not threadsafe, only called in JS single process and tests
func (self *XEth) UpdateState() (wait chan *big.Int) {
	wait = make(chan *big.Int)
	go func() {
258 259 260
		eventSub := self.backend.EventMux().Subscribe(core.ChainHeadEvent{})
		defer eventSub.Unsubscribe()

261 262
		var m, n *big.Int
		var ok bool
263 264

		eventCh := eventSub.Chan()
265 266
		for {
			select {
267 268 269 270 271 272 273 274 275
			case event, ok := <-eventCh:
				if !ok {
					// Event subscription closed, set the channel to nil to stop spinning
					eventCh = nil
					continue
				}
				// A real event arrived, process if new head block assignment
				if event, ok := event.Data.(core.ChainHeadEvent); ok {
					m = event.Block.Number()
276 277 278 279
					if n != nil && n.Cmp(m) < 0 {
						wait <- n
						n = nil
					}
280 281 282 283 284
					statedb, err := state.New(event.Block.Root(), self.backend.ChainDb())
					if err != nil {
						glog.V(logger.Error).Infoln("Could not create new state: %v", err)
						return
					}
285 286 287 288
					self.state = NewState(self, statedb)
				}
			case n, ok = <-wait:
				if !ok {
289
					return
290 291 292 293 294 295 296
				}
			}
		}
	}()
	return
}

297
func (self *XEth) Whisper() *Whisper { return self.whisper }
O
obscuren 已提交
298

T
Taylor Gerring 已提交
299 300 301
func (self *XEth) getBlockByHeight(height int64) *types.Block {
	var num uint64

O
obscuren 已提交
302 303 304 305 306 307 308 309 310 311
	switch height {
	case -2:
		return self.backend.Miner().PendingBlock()
	case -1:
		return self.CurrentBlock()
	default:
		if height < 0 {
			return nil
		}

T
Taylor Gerring 已提交
312 313 314
		num = uint64(height)
	}

315
	return self.backend.BlockChain().GetBlockByNumber(num)
T
Taylor Gerring 已提交
316 317
}

O
obscuren 已提交
318
func (self *XEth) BlockByHash(strHash string) *Block {
O
obscuren 已提交
319
	hash := common.HexToHash(strHash)
320
	block := self.backend.BlockChain().GetBlock(hash)
O
obscuren 已提交
321

O
obscuren 已提交
322
	return NewBlock(block)
O
obscuren 已提交
323 324
}

T
Taylor Gerring 已提交
325 326
func (self *XEth) EthBlockByHash(strHash string) *types.Block {
	hash := common.HexToHash(strHash)
327
	block := self.backend.BlockChain().GetBlock(hash)
T
Taylor Gerring 已提交
328 329 330 331

	return block
}

332
func (self *XEth) EthTransactionByHash(hash string) (tx *types.Transaction, blhash common.Hash, blnum *big.Int, txi uint64) {
T
Taylor Gerring 已提交
333 334
	// Due to increasing return params and need to determine if this is from transaction pool or
	// some chain, this probably needs to be refactored for more expressiveness
335
	data, _ := self.backend.ChainDb().Get(common.FromHex(hash))
O
obscuren 已提交
336
	if len(data) != 0 {
337 338 339 340 341 342
		dtx := new(types.Transaction)
		if err := rlp.DecodeBytes(data, dtx); err != nil {
			glog.V(logger.Error).Infoln(err)
			return
		}
		tx = dtx
343 344
	} else { // check pending transactions
		tx = self.backend.TxPool().GetTransaction(common.HexToHash(hash))
O
obscuren 已提交
345
	}
346

T
Taylor Gerring 已提交
347 348 349
	// meta
	var txExtra struct {
		BlockHash  common.Hash
T
Taylor Gerring 已提交
350
		BlockIndex uint64
T
Taylor Gerring 已提交
351
		Index      uint64
352
	}
T
Taylor Gerring 已提交
353

354
	v, dberr := self.backend.ChainDb().Get(append(common.FromHex(hash), 0x0001))
355 356 357 358
	// TODO check specifically for ErrNotFound
	if dberr != nil {
		return
	}
T
Taylor Gerring 已提交
359 360 361 362
	r := bytes.NewReader(v)
	err := rlp.Decode(r, &txExtra)
	if err == nil {
		blhash = txExtra.BlockHash
T
Taylor Gerring 已提交
363
		blnum = big.NewInt(int64(txExtra.BlockIndex))
T
Taylor Gerring 已提交
364
		txi = txExtra.Index
T
Taylor Gerring 已提交
365
	} else {
O
obscuren 已提交
366
		glog.V(logger.Error).Infoln(err)
367 368 369
	}

	return
O
obscuren 已提交
370 371
}

T
Taylor Gerring 已提交
372
func (self *XEth) BlockByNumber(num int64) *Block {
T
Taylor Gerring 已提交
373
	return NewBlock(self.getBlockByHeight(num))
O
obscuren 已提交
374 375
}

T
Taylor Gerring 已提交
376
func (self *XEth) EthBlockByNumber(num int64) *types.Block {
T
Taylor Gerring 已提交
377
	return self.getBlockByHeight(num)
T
Taylor Gerring 已提交
378 379
}

380
func (self *XEth) Td(hash common.Hash) *big.Int {
381
	return self.backend.BlockChain().GetTd(hash)
382 383
}

T
Taylor Gerring 已提交
384
func (self *XEth) CurrentBlock() *types.Block {
385
	return self.backend.BlockChain().CurrentBlock()
T
Taylor Gerring 已提交
386 387
}

388
func (self *XEth) GetBlockReceipts(bhash common.Hash) types.Receipts {
Z
zsfelfoldi 已提交
389 390 391
	return self.backend.BlockProcessor().GetBlockReceipts(bhash)
}

392
func (self *XEth) GetTxReceipt(txhash common.Hash) *types.Receipt {
393
	return core.GetReceipt(self.backend.ChainDb(), txhash)
Z
zsfelfoldi 已提交
394 395
}

396
func (self *XEth) GasLimit() *big.Int {
397
	return self.backend.BlockChain().GasLimit()
398 399
}

O
obscuren 已提交
400
func (self *XEth) Block(v interface{}) *Block {
O
obscuren 已提交
401
	if n, ok := v.(int32); ok {
T
Taylor Gerring 已提交
402
		return self.BlockByNumber(int64(n))
O
obscuren 已提交
403 404
	} else if str, ok := v.(string); ok {
		return self.BlockByHash(str)
T
Taylor Gerring 已提交
405
	} else if f, ok := v.(float64); ok { // JSON numbers are represented as float64
T
Taylor Gerring 已提交
406
		return self.BlockByNumber(int64(f))
O
obscuren 已提交
407 408 409 410 411
	}

	return nil
}

O
obscuren 已提交
412
func (self *XEth) Accounts() []string {
413
	// TODO: check err?
T
Taylor Gerring 已提交
414
	accounts, _ := self.backend.AccountManager().Accounts()
415 416
	accountAddresses := make([]string, len(accounts))
	for i, ac := range accounts {
417
		accountAddresses[i] = ac.Address.Hex()
418 419
	}
	return accountAddresses
O
obscuren 已提交
420 421
}

422 423 424
// accessor for solidity compiler.
// memoized if available, retried on-demand if not
func (self *XEth) Solc() (*compiler.Solidity, error) {
425
	return self.backend.Solc()
426 427 428 429
}

// set in js console via admin interface or wrapper from cli flags
func (self *XEth) SetSolc(solcPath string) (*compiler.Solidity, error) {
430
	self.backend.SetSolc(solcPath)
431 432 433
	return self.Solc()
}

434
// store DApp value in extra database
435
func (self *XEth) DbPut(key, val []byte) bool {
436
	self.backend.DappDb().Put(append(dappStorePre, key...), val)
437 438 439
	return true
}

440
// retrieve DApp value from extra database
441
func (self *XEth) DbGet(key []byte) ([]byte, error) {
442
	val, err := self.backend.DappDb().Get(append(dappStorePre, key...))
443 444 445
	return val, err
}

O
obscuren 已提交
446
func (self *XEth) PeerCount() int {
T
Taylor Gerring 已提交
447
	return self.backend.PeerCount()
O
obscuren 已提交
448 449
}

O
obscuren 已提交
450
func (self *XEth) IsMining() bool {
T
Taylor Gerring 已提交
451
	return self.backend.IsMining()
O
obscuren 已提交
452 453
}

K
Kobi Gurkan 已提交
454
func (self *XEth) HashRate() int64 {
455
	return self.backend.Miner().HashRate()
K
Kobi Gurkan 已提交
456 457
}

458
func (self *XEth) EthVersion() string {
459
	return fmt.Sprintf("%d", self.backend.EthVersion())
460 461
}

T
Taylor Gerring 已提交
462
func (self *XEth) NetworkVersion() string {
463
	return fmt.Sprintf("%d", self.backend.NetVersion())
464 465 466
}

func (self *XEth) WhisperVersion() string {
467
	return fmt.Sprintf("%d", self.backend.ShhVersion())
T
Taylor Gerring 已提交
468 469 470
}

func (self *XEth) ClientVersion() string {
471
	return self.backend.ClientVersion()
T
Taylor Gerring 已提交
472 473
}

474
func (self *XEth) SetMining(shouldmine bool, threads int) bool {
T
Taylor Gerring 已提交
475
	ismining := self.backend.IsMining()
T
Taylor Gerring 已提交
476
	if shouldmine && !ismining {
477
		err := self.backend.StartMining(threads)
478
		return err == nil
T
Taylor Gerring 已提交
479 480
	}
	if ismining && !shouldmine {
T
Taylor Gerring 已提交
481
		self.backend.StopMining()
T
Taylor Gerring 已提交
482
	}
T
Taylor Gerring 已提交
483
	return self.backend.IsMining()
T
Taylor Gerring 已提交
484 485
}

O
obscuren 已提交
486
func (self *XEth) IsListening() bool {
T
Taylor Gerring 已提交
487
	return self.backend.IsListening()
O
obscuren 已提交
488 489
}

O
obscuren 已提交
490
func (self *XEth) Coinbase() string {
491 492 493 494
	eb, err := self.backend.Etherbase()
	if err != nil {
		return "0x0"
	}
Z
zelig 已提交
495
	return eb.Hex()
O
obscuren 已提交
496 497
}

O
obscuren 已提交
498
func (self *XEth) NumberToHuman(balance string) string {
O
obscuren 已提交
499
	b := common.Big(balance)
O
obscuren 已提交
500

O
obscuren 已提交
501
	return common.CurrencyToString(b)
O
obscuren 已提交
502 503
}

O
obscuren 已提交
504
func (self *XEth) StorageAt(addr, storageAddr string) string {
O
obscuren 已提交
505
	return self.State().state.GetState(common.HexToAddress(addr), common.HexToHash(storageAddr)).Hex()
O
obscuren 已提交
506 507
}

O
obscuren 已提交
508
func (self *XEth) BalanceAt(addr string) string {
O
obscuren 已提交
509
	return common.ToHex(self.State().state.GetBalance(common.HexToAddress(addr)).Bytes())
O
obscuren 已提交
510 511
}

O
obscuren 已提交
512
func (self *XEth) TxCountAt(address string) int {
513
	return int(self.State().state.GetNonce(common.HexToAddress(address)))
O
obscuren 已提交
514 515
}

O
obscuren 已提交
516
func (self *XEth) CodeAt(address string) string {
517
	return common.ToHex(self.State().state.GetCode(common.HexToAddress(address)))
O
obscuren 已提交
518 519
}

T
Taylor Gerring 已提交
520 521 522 523
func (self *XEth) CodeAtBytes(address string) []byte {
	return self.State().SafeGet(address).Code()
}

O
obscuren 已提交
524
func (self *XEth) IsContract(address string) bool {
525
	return len(self.State().SafeGet(address).Code()) > 0
O
obscuren 已提交
526 527
}

528
func (self *XEth) UninstallFilter(id int) bool {
529
	defer self.filterManager.Remove(id)
530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553

	if _, ok := self.logQueue[id]; ok {
		self.logMu.Lock()
		defer self.logMu.Unlock()
		delete(self.logQueue, id)
		return true
	}
	if _, ok := self.blockQueue[id]; ok {
		self.blockMu.Lock()
		defer self.blockMu.Unlock()
		delete(self.blockQueue, id)
		return true
	}
	if _, ok := self.transactionQueue[id]; ok {
		self.transactionMu.Lock()
		defer self.transactionMu.Unlock()
		delete(self.transactionQueue, id)
		return true
	}

	return false
}

func (self *XEth) NewLogFilter(earliest, latest int64, skip, max int, address []string, topics [][]string) int {
554 555 556
	self.logMu.Lock()
	defer self.logMu.Unlock()

557 558
	filter := filters.New(self.backend.ChainDb())
	id := self.filterManager.Add(filter)
559 560
	self.logQueue[id] = &logQueue{timeout: time.Now()}

T
Taylor Gerring 已提交
561 562 563 564 565 566
	filter.SetEarliestBlock(earliest)
	filter.SetLatestBlock(latest)
	filter.SetSkip(skip)
	filter.SetMax(max)
	filter.SetAddress(cAddress(address))
	filter.SetTopics(cTopics(topics))
567
	filter.LogsCallback = func(logs vm.Logs) {
568 569
		self.logMu.Lock()
		defer self.logMu.Unlock()
T
Taylor Gerring 已提交
570

571 572 573
		if queue := self.logQueue[id]; queue != nil {
			queue.add(logs...)
		}
T
Taylor Gerring 已提交
574 575 576 577 578
	}

	return id
}

579
func (self *XEth) NewTransactionFilter() int {
580 581 582
	self.transactionMu.Lock()
	defer self.transactionMu.Unlock()

583 584
	filter := filters.New(self.backend.ChainDb())
	id := self.filterManager.Add(filter)
585 586
	self.transactionQueue[id] = &hashQueue{timeout: time.Now()}

587 588 589
	filter.TransactionCallback = func(tx *types.Transaction) {
		self.transactionMu.Lock()
		defer self.transactionMu.Unlock()
T
Taylor Gerring 已提交
590

591 592 593
		if queue := self.transactionQueue[id]; queue != nil {
			queue.add(tx.Hash())
		}
594 595
	}
	return id
T
Taylor Gerring 已提交
596 597
}

598
func (self *XEth) NewBlockFilter() int {
599 600 601
	self.blockMu.Lock()
	defer self.blockMu.Unlock()

602 603
	filter := filters.New(self.backend.ChainDb())
	id := self.filterManager.Add(filter)
604 605
	self.blockQueue[id] = &hashQueue{timeout: time.Now()}

606
	filter.BlockCallback = func(block *types.Block, logs vm.Logs) {
607 608
		self.blockMu.Lock()
		defer self.blockMu.Unlock()
T
Taylor Gerring 已提交
609

610 611 612
		if queue := self.blockQueue[id]; queue != nil {
			queue.add(block.Hash())
		}
613 614 615
	}
	return id
}
616

617 618 619 620 621 622 623
func (self *XEth) GetFilterType(id int) byte {
	if _, ok := self.blockQueue[id]; ok {
		return BlockFilterTy
	} else if _, ok := self.transactionQueue[id]; ok {
		return TransactionFilterTy
	} else if _, ok := self.logQueue[id]; ok {
		return LogFilterTy
T
Taylor Gerring 已提交
624 625
	}

626 627
	return UnknownFilterTy
}
T
Taylor Gerring 已提交
628

629
func (self *XEth) LogFilterChanged(id int) vm.Logs {
630 631 632 633 634 635 636
	self.logMu.Lock()
	defer self.logMu.Unlock()

	if self.logQueue[id] != nil {
		return self.logQueue[id].get()
	}
	return nil
T
Taylor Gerring 已提交
637 638
}

639 640 641
func (self *XEth) BlockFilterChanged(id int) []common.Hash {
	self.blockMu.Lock()
	defer self.blockMu.Unlock()
T
Taylor Gerring 已提交
642

643 644
	if self.blockQueue[id] != nil {
		return self.blockQueue[id].get()
T
Taylor Gerring 已提交
645
	}
646 647 648 649 650 651
	return nil
}

func (self *XEth) TransactionFilterChanged(id int) []common.Hash {
	self.blockMu.Lock()
	defer self.blockMu.Unlock()
T
Taylor Gerring 已提交
652

653
	if self.transactionQueue[id] != nil {
654 655
		return self.transactionQueue[id].get()
	}
T
Taylor Gerring 已提交
656 657 658
	return nil
}

659
func (self *XEth) Logs(id int) vm.Logs {
660
	filter := self.filterManager.Get(id)
T
Taylor Gerring 已提交
661 662 663 664 665 666 667
	if filter != nil {
		return filter.Find()
	}

	return nil
}

668
func (self *XEth) AllLogs(earliest, latest int64, skip, max int, address []string, topics [][]string) vm.Logs {
669
	filter := filters.New(self.backend.ChainDb())
T
Taylor Gerring 已提交
670 671 672 673 674 675
	filter.SetEarliestBlock(earliest)
	filter.SetLatestBlock(latest)
	filter.SetSkip(skip)
	filter.SetMax(max)
	filter.SetAddress(cAddress(address))
	filter.SetTopics(cTopics(topics))
T
Taylor Gerring 已提交
676 677 678 679

	return filter.Find()
}

680 681 682
// NewWhisperFilter creates and registers a new message filter to watch for
// inbound whisper messages. All parameters at this point are assumed to be
// HEX encoded.
683
func (p *XEth) NewWhisperFilter(to, from string, topics [][]string) int {
684
	// Pre-define the id to be filled later
T
Taylor Gerring 已提交
685
	var id int
686

687 688
	// Callback to delegate core whisper messages to this xeth filter
	callback := func(msg WhisperMessage) {
689 690
		p.messagesMu.RLock() // Only read lock to the filter pool
		defer p.messagesMu.RUnlock()
691
		p.messages[id].insert(msg)
T
Taylor Gerring 已提交
692
	}
693
	// Initialize the core whisper filter and wrap into xeth
694
	id = p.Whisper().Watch(to, from, topics, callback)
695

696
	p.messagesMu.Lock()
697
	p.messages[id] = newWhisperFilter(id, p.Whisper())
698
	p.messagesMu.Unlock()
699

T
Taylor Gerring 已提交
700 701 702
	return id
}

703
// UninstallWhisperFilter disables and removes an existing filter.
T
Taylor Gerring 已提交
704
func (p *XEth) UninstallWhisperFilter(id int) bool {
705 706
	p.messagesMu.Lock()
	defer p.messagesMu.Unlock()
707

T
Taylor Gerring 已提交
708 709 710 711 712 713 714
	if _, ok := p.messages[id]; ok {
		delete(p.messages, id)
		return true
	}
	return false
}

715 716
// WhisperMessages retrieves all the known messages that match a specific filter.
func (self *XEth) WhisperMessages(id int) []WhisperMessage {
717 718
	self.messagesMu.RLock()
	defer self.messagesMu.RUnlock()
T
Taylor Gerring 已提交
719 720

	if self.messages[id] != nil {
721
		return self.messages[id].messages()
T
Taylor Gerring 已提交
722
	}
723 724 725
	return nil
}

726 727 728
// WhisperMessagesChanged retrieves all the new messages matched by a filter
// since the last retrieval
func (self *XEth) WhisperMessagesChanged(id int) []WhisperMessage {
729 730
	self.messagesMu.RLock()
	defer self.messagesMu.RUnlock()
T
Taylor Gerring 已提交
731

732
	if self.messages[id] != nil {
733
		return self.messages[id].retrieve()
734
	}
T
Taylor Gerring 已提交
735 736 737
	return nil
}

T
Taylor Gerring 已提交
738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770
// func (self *XEth) Register(args string) bool {
// 	self.regmut.Lock()
// 	defer self.regmut.Unlock()

// 	if _, ok := self.register[args]; ok {
// 		self.register[args] = nil // register with empty
// 	}
// 	return true
// }

// func (self *XEth) Unregister(args string) bool {
// 	self.regmut.Lock()
// 	defer self.regmut.Unlock()

// 	if _, ok := self.register[args]; ok {
// 		delete(self.register, args)
// 		return true
// 	}

// 	return false
// }

// // TODO improve return type
// func (self *XEth) PullWatchTx(args string) []*interface{} {
// 	self.regmut.Lock()
// 	defer self.regmut.Unlock()

// 	txs := self.register[args]
// 	self.register[args] = nil

// 	return txs
// }

O
obscuren 已提交
771 772 773 774 775
type KeyVal struct {
	Key   string `json:"key"`
	Value string `json:"value"`
}

O
obscuren 已提交
776
func (self *XEth) EachStorage(addr string) string {
O
obscuren 已提交
777 778 779 780
	var values []KeyVal
	object := self.State().SafeGet(addr)
	it := object.Trie().Iterator()
	for it.Next() {
O
obscuren 已提交
781
		values = append(values, KeyVal{common.ToHex(object.Trie().GetKey(it.Key)), common.ToHex(it.Value)})
O
obscuren 已提交
782 783 784 785 786 787 788 789 790 791
	}

	valuesJson, err := json.Marshal(values)
	if err != nil {
		return ""
	}

	return string(valuesJson)
}

O
obscuren 已提交
792
func (self *XEth) ToAscii(str string) string {
O
obscuren 已提交
793
	padded := common.RightPadBytes([]byte(str), 32)
O
obscuren 已提交
794

795
	return "0x" + common.ToHex(padded)
O
obscuren 已提交
796 797
}

O
obscuren 已提交
798
func (self *XEth) FromAscii(str string) string {
O
obscuren 已提交
799
	if common.IsHex(str) {
O
obscuren 已提交
800 801 802
		str = str[2:]
	}

O
obscuren 已提交
803
	return string(bytes.Trim(common.FromHex(str), "\x00"))
O
obscuren 已提交
804 805
}

O
obscuren 已提交
806
func (self *XEth) FromNumber(str string) string {
O
obscuren 已提交
807
	if common.IsHex(str) {
O
obscuren 已提交
808 809 810
		str = str[2:]
	}

O
obscuren 已提交
811
	return common.BigD(common.FromHex(str)).String()
O
obscuren 已提交
812 813
}

O
obscuren 已提交
814
func (self *XEth) PushTx(encodedTx string) (string, error) {
815 816 817 818 819 820 821 822
	tx := new(types.Transaction)
	err := rlp.DecodeBytes(common.FromHex(encodedTx), tx)
	if err != nil {
		glog.V(logger.Error).Infoln(err)
		return "", err
	}

	err = self.backend.TxPool().Add(tx)
O
obscuren 已提交
823 824 825 826 827
	if err != nil {
		return "", err
	}

	if tx.To() == nil {
828 829 830 831 832 833
		from, err := tx.From()
		if err != nil {
			return "", err
		}

		addr := crypto.CreateAddress(from, tx.Nonce())
834 835 836
		glog.V(logger.Info).Infof("Tx(%x) created: %x\n", tx.Hash(), addr)
	} else {
		glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To())
O
obscuren 已提交
837
	}
838

O
obscuren 已提交
839
	return tx.Hash().Hex(), nil
O
obscuren 已提交
840
}
841

842
func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr string) (string, string, error) {
T
Taylor Gerring 已提交
843
	statedb := self.State().State().Copy()
844 845 846 847 848 849
	var from *state.StateObject
	if len(fromStr) == 0 {
		accounts, err := self.backend.AccountManager().Accounts()
		if err != nil || len(accounts) == 0 {
			from = statedb.GetOrNewStateObject(common.Address{})
		} else {
850
			from = statedb.GetOrNewStateObject(accounts[0].Address)
851 852 853 854 855
		}
	} else {
		from = statedb.GetOrNewStateObject(common.HexToAddress(fromStr))
	}

856
	from.SetBalance(common.MaxBig)
J
Jeffrey Wilcke 已提交
857 858
	from.SetGasLimit(common.MaxBig)

859
	msg := callmsg{
860
		from:     from,
O
obscuren 已提交
861 862 863 864
		gas:      common.Big(gasStr),
		gasPrice: common.Big(gasPriceStr),
		value:    common.Big(valueStr),
		data:     common.FromHex(dataStr),
865
	}
J
Jeffrey Wilcke 已提交
866 867 868 869
	if len(toStr) > 0 {
		addr := common.HexToAddress(toStr)
		msg.to = &addr
	}
B
Bas van Kervel 已提交
870

871
	if msg.gas.Cmp(big.NewInt(0)) == 0 {
J
Jeffrey Wilcke 已提交
872
		msg.gas = big.NewInt(50000000)
873 874 875
	}

	if msg.gasPrice.Cmp(big.NewInt(0)) == 0 {
Z
zsfelfoldi 已提交
876
		msg.gasPrice = self.DefaultGasPrice()
877 878
	}

F
Felix Lange 已提交
879
	header := self.CurrentBlock().Header()
880
	vmenv := core.NewEnv(statedb, self.backend.BlockChain(), msg, header)
881

882 883
	res, gas, err := core.ApplyMessage(vmenv, msg, from)
	return common.ToHex(res), gas.String(), err
884 885
}

886 887 888 889
func (self *XEth) ConfirmTransaction(tx string) bool {
	return self.frontend.ConfirmTransaction(tx)
}

890
func (self *XEth) doSign(from common.Address, hash common.Hash, didUnlock bool) ([]byte, error) {
891
	sig, err := self.backend.AccountManager().Sign(accounts.Account{Address: from}, hash.Bytes())
D
Daniel A. Nagy 已提交
892 893
	if err == accounts.ErrLocked {
		if didUnlock {
894
			return nil, fmt.Errorf("signer account still locked after successful unlock")
D
Daniel A. Nagy 已提交
895 896
		}
		if !self.frontend.UnlockAccount(from.Bytes()) {
897
			return nil, fmt.Errorf("could not unlock signer account")
D
Daniel A. Nagy 已提交
898 899
		}
		// retry signing, the account should now be unlocked.
900
		return self.doSign(from, hash, true)
D
Daniel A. Nagy 已提交
901
	} else if err != nil {
902 903 904 905 906 907 908 909 910 911
		return nil, err
	}
	return sig, nil
}

func (self *XEth) Sign(fromStr, hashStr string, didUnlock bool) (string, error) {
	var (
		from = common.HexToAddress(fromStr)
		hash = common.HexToHash(hashStr)
	)
912
	sig, err := self.doSign(from, hash, didUnlock)
913
	if err != nil {
914
		return "", err
D
Daniel A. Nagy 已提交
915
	}
916
	return common.ToHex(sig), nil
D
Daniel A. Nagy 已提交
917 918
}

919 920 921 922
func isAddress(addr string) bool {
	return addrReg.MatchString(addr)
}

B
Bas van Kervel 已提交
923 924 925 926
func (self *XEth) Frontend() Frontend {
	return self.frontend
}

927
func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) {
928 929 930 931 932 933 934 935

	// this minimalistic recoding is enough (works for natspec.js)
	var jsontx = fmt.Sprintf(`{"params":[{"to":"%s","data": "%s"}]}`, toStr, codeStr)
	if !self.ConfirmTransaction(jsontx) {
		err := fmt.Errorf("Transaction not confirmed")
		return "", err
	}

J
Jeffrey Wilcke 已提交
936
	if len(toStr) > 0 && toStr != "0x" && !isAddress(toStr) {
937 938 939
		return "", errors.New("Invalid address")
	}

940
	var (
O
obscuren 已提交
941 942
		from             = common.HexToAddress(fromStr)
		to               = common.HexToAddress(toStr)
O
obscuren 已提交
943
		value            = common.Big(valueStr)
944 945
		gas              *big.Int
		price            *big.Int
946 947 948 949
		data             []byte
		contractCreation bool
	)

950 951 952 953 954 955 956
	if len(gasStr) == 0 {
		gas = DefaultGas()
	} else {
		gas = common.Big(gasStr)
	}

	if len(gasPriceStr) == 0 {
Z
zsfelfoldi 已提交
957
		price = self.DefaultGasPrice()
958 959 960 961 962 963 964 965 966
	} else {
		price = common.Big(gasPriceStr)
	}

	data = common.FromHex(codeStr)
	if len(toStr) == 0 {
		contractCreation = true
	}

T
Taylor Gerring 已提交
967
	// 2015-05-18 Is this still needed?
T
Taylor Gerring 已提交
968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989
	// TODO if no_private_key then
	//if _, exists := p.register[args.From]; exists {
	//	p.register[args.From] = append(p.register[args.From], args)
	//} else {
	/*
		account := accounts.Get(common.FromHex(args.From))
		if account != nil {
			if account.Unlocked() {
				if !unlockAccount(account) {
					return
				}
			}

			result, _ := account.Transact(common.FromHex(args.To), common.FromHex(args.Value), common.FromHex(args.Gas), common.FromHex(args.GasPrice), common.FromHex(args.Data))
			if len(result) > 0 {
				*reply = common.ToHex(result)
			}
		} else if _, exists := p.register[args.From]; exists {
			p.register[ags.From] = append(p.register[args.From], args)
		}
	*/

J
Jeffrey Wilcke 已提交
990 991 992
	self.transactMu.Lock()
	defer self.transactMu.Unlock()

993 994 995 996
	var nonce uint64
	if len(nonceStr) != 0 {
		nonce = common.Big(nonceStr).Uint64()
	} else {
997
		state := self.backend.TxPool().State()
998
		nonce = state.GetNonce(from)
999
	}
1000 1001 1002 1003 1004 1005
	var tx *types.Transaction
	if contractCreation {
		tx = types.NewContractCreation(nonce, value, gas, price, data)
	} else {
		tx = types.NewTransaction(nonce, to, value, gas, price, data)
	}
1006

1007 1008
	signed, err := self.sign(tx, from, false)
	if err != nil {
1009 1010
		return "", err
	}
1011
	if err = self.backend.TxPool().Add(signed); err != nil {
1012 1013
		return "", err
	}
1014 1015

	if contractCreation {
1016
		addr := crypto.CreateAddress(from, nonce)
G
Gustav Simonsson 已提交
1017
		glog.V(logger.Info).Infof("Tx(%s) created: %s\n", signed.Hash().Hex(), addr.Hex())
O
obscuren 已提交
1018
	} else {
G
Gustav Simonsson 已提交
1019
		glog.V(logger.Info).Infof("Tx(%s) to: %s\n", signed.Hash().Hex(), tx.To().Hex())
1020
	}
1021

1022
	return signed.Hash().Hex(), nil
1023
}
1024

1025
func (self *XEth) sign(tx *types.Transaction, from common.Address, didUnlock bool) (*types.Transaction, error) {
1026
	hash := tx.SigHash()
1027 1028
	sig, err := self.doSign(from, hash, didUnlock)
	if err != nil {
1029
		return tx, err
1030
	}
1031
	return tx.WithSignature(sig)
1032 1033
}

1034 1035 1036
// callmsg is the message type used for call transations.
type callmsg struct {
	from          *state.StateObject
J
Jeffrey Wilcke 已提交
1037
	to            *common.Address
1038 1039 1040 1041 1042 1043
	gas, gasPrice *big.Int
	value         *big.Int
	data          []byte
}

// accessor boilerplate to implement core.Message
O
obscuren 已提交
1044 1045
func (m callmsg) From() (common.Address, error) { return m.from.Address(), nil }
func (m callmsg) Nonce() uint64                 { return m.from.Nonce() }
J
Jeffrey Wilcke 已提交
1046
func (m callmsg) To() *common.Address           { return m.to }
O
obscuren 已提交
1047 1048 1049 1050
func (m callmsg) GasPrice() *big.Int            { return m.gasPrice }
func (m callmsg) Gas() *big.Int                 { return m.gas }
func (m callmsg) Value() *big.Int               { return m.value }
func (m callmsg) Data() []byte                  { return m.data }
T
Taylor Gerring 已提交
1051

1052
type logQueue struct {
1053 1054
	mu sync.Mutex

1055
	logs    vm.Logs
T
Taylor Gerring 已提交
1056 1057 1058 1059
	timeout time.Time
	id      int
}

1060
func (l *logQueue) add(logs ...*vm.Log) {
1061 1062 1063
	l.mu.Lock()
	defer l.mu.Unlock()

T
Taylor Gerring 已提交
1064 1065 1066
	l.logs = append(l.logs, logs...)
}

1067
func (l *logQueue) get() vm.Logs {
1068 1069 1070
	l.mu.Lock()
	defer l.mu.Unlock()

T
Taylor Gerring 已提交
1071 1072 1073 1074 1075
	l.timeout = time.Now()
	tmp := l.logs
	l.logs = nil
	return tmp
}
1076 1077

type hashQueue struct {
1078 1079
	mu sync.Mutex

1080 1081 1082 1083 1084 1085
	hashes  []common.Hash
	timeout time.Time
	id      int
}

func (l *hashQueue) add(hashes ...common.Hash) {
1086 1087 1088
	l.mu.Lock()
	defer l.mu.Unlock()

1089 1090 1091 1092
	l.hashes = append(l.hashes, hashes...)
}

func (l *hashQueue) get() []common.Hash {
1093 1094 1095
	l.mu.Lock()
	defer l.mu.Unlock()

1096 1097 1098 1099 1100
	l.timeout = time.Now()
	tmp := l.hashes
	l.hashes = nil
	return tmp
}