xeth.go 24.6 KB
Newer Older
1
// eXtended ETHereum
O
obscuren 已提交
2 3
package xeth

O
obscuren 已提交
4 5 6
import (
	"bytes"
	"encoding/json"
7
	"fmt"
8
	"math/big"
T
Taylor Gerring 已提交
9 10
	"sync"
	"time"
O
obscuren 已提交
11

12
	"github.com/ethereum/go-ethereum/accounts"
O
obscuren 已提交
13
	"github.com/ethereum/go-ethereum/common"
14
	"github.com/ethereum/go-ethereum/common/compiler"
O
obscuren 已提交
15
	"github.com/ethereum/go-ethereum/core"
T
Taylor Gerring 已提交
16
	"github.com/ethereum/go-ethereum/core/state"
O
obscuren 已提交
17 18
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/crypto"
19
	"github.com/ethereum/go-ethereum/eth"
T
Taylor Gerring 已提交
20
	"github.com/ethereum/go-ethereum/event/filter"
O
obscuren 已提交
21
	"github.com/ethereum/go-ethereum/logger"
O
obscuren 已提交
22
	"github.com/ethereum/go-ethereum/logger/glog"
23
	"github.com/ethereum/go-ethereum/miner"
T
Taylor Gerring 已提交
24
	"github.com/ethereum/go-ethereum/rlp"
O
obscuren 已提交
25
)
O
obscuren 已提交
26

T
Taylor Gerring 已提交
27 28
var (
	filterTickerTime = 5 * time.Minute
T
Taylor Gerring 已提交
29 30
	defaultGasPrice  = big.NewInt(10000000000000) //150000000000
	defaultGas       = big.NewInt(90000)          //500000
T
Taylor Gerring 已提交
31
)
O
obscuren 已提交
32

33 34 35 36 37 38 39 40
// byte will be inferred
const (
	UnknownFilterTy = iota
	BlockFilterTy
	TransactionFilterTy
	LogFilterTy
)

O
obscuren 已提交
41 42 43
func DefaultGas() *big.Int      { return new(big.Int).Set(defaultGas) }
func DefaultGasPrice() *big.Int { return new(big.Int).Set(defaultGasPrice) }

O
obscuren 已提交
44
type XEth struct {
T
Shuffle  
Taylor Gerring 已提交
45 46 47
	backend  *eth.Ethereum
	frontend Frontend

T
Taylor Gerring 已提交
48 49
	state   *State
	whisper *Whisper
O
obscuren 已提交
50

T
Taylor Gerring 已提交
51 52
	quit          chan struct{}
	filterManager *filter.FilterManager
O
obscuren 已提交
53

54 55 56 57 58 59 60 61
	logMu    sync.RWMutex
	logQueue map[int]*logQueue

	blockMu    sync.RWMutex
	blockQueue map[int]*hashQueue

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

63 64
	messagesMu sync.RWMutex
	messages   map[int]*whisperFilter
T
Taylor Gerring 已提交
65 66 67

	// regmut   sync.Mutex
	// register map[string][]*interface{} // TODO improve return type
68

69 70 71
	solcPath string
	solc     *compiler.Solidity

T
Taylor Gerring 已提交
72
	agent *miner.RemoteAgent
O
obscuren 已提交
73
}
O
obscuren 已提交
74

75 76 77
// 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.
78
func New(eth *eth.Ethereum, frontend Frontend) *XEth {
O
obscuren 已提交
79
	xeth := &XEth{
80 81 82 83 84 85 86 87 88
		backend:          eth,
		frontend:         frontend,
		quit:             make(chan struct{}),
		filterManager:    filter.NewFilterManager(eth.EventMux()),
		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 已提交
89
	}
90 91 92
	if eth.Whisper() != nil {
		xeth.whisper = NewWhisper(eth.Whisper())
	}
93
	eth.Miner().Register(xeth.agent)
O
obscuren 已提交
94
	if frontend == nil {
95
		xeth.frontend = dummyFrontend{}
O
obscuren 已提交
96
	}
T
Taylor Gerring 已提交
97
	xeth.state = NewState(xeth, xeth.backend.ChainManager().TransState())
T
Shuffle  
Taylor Gerring 已提交
98

T
Taylor Gerring 已提交
99 100 101
	go xeth.start()
	go xeth.filterManager.Start()

O
obscuren 已提交
102 103 104
	return xeth
}

T
Taylor Gerring 已提交
105 106 107 108 109 110
func (self *XEth) start() {
	timer := time.NewTicker(2 * time.Second)
done:
	for {
		select {
		case <-timer.C:
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
			self.logMu.Lock()
			for id, filter := range self.logQueue {
				if time.Since(filter.timeout) > filterTickerTime {
					self.filterManager.UninstallFilter(id)
					delete(self.logQueue, id)
				}
			}
			self.logMu.Unlock()

			self.blockMu.Lock()
			for id, filter := range self.blockQueue {
				if time.Since(filter.timeout) > filterTickerTime {
					self.filterManager.UninstallFilter(id)
					delete(self.blockQueue, id)
				}
			}
			self.blockMu.Unlock()

			self.transactionMu.Lock()
			for id, filter := range self.transactionQueue {
T
Taylor Gerring 已提交
131 132
				if time.Since(filter.timeout) > filterTickerTime {
					self.filterManager.UninstallFilter(id)
133
					delete(self.transactionQueue, id)
T
Taylor Gerring 已提交
134 135
				}
			}
136
			self.transactionMu.Unlock()
T
Taylor Gerring 已提交
137

138
			self.messagesMu.Lock()
T
Taylor Gerring 已提交
139
			for id, filter := range self.messages {
140
				if time.Since(filter.activity()) > filterTickerTime {
T
Taylor Gerring 已提交
141 142 143 144
					self.Whisper().Unwatch(id)
					delete(self.messages, id)
				}
			}
145
			self.messagesMu.Unlock()
T
Taylor Gerring 已提交
146 147 148 149 150 151 152 153 154 155
		case <-self.quit:
			break done
		}
	}
}

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

T
Taylor Gerring 已提交
156 157 158 159 160 161 162 163 164 165 166
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 {
167
		topics[i] = make([]common.Hash, len(iv))
T
Taylor Gerring 已提交
168 169 170 171 172 173 174
		for j, jv := range iv {
			topics[i][j] = common.HexToHash(jv)
		}
	}
	return topics
}

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

T
Taylor Gerring 已提交
177 178
func (self *XEth) AtStateNum(num int64) *XEth {
	var st *state.StateDB
O
obscuren 已提交
179 180 181 182 183 184 185 186 187
	switch num {
	case -2:
		st = self.backend.Miner().PendingState().Copy()
	default:
		if block := self.getBlockByHeight(num); block != nil {
			st = state.New(block.Root(), self.backend.StateDb())
		} else {
			st = state.New(self.backend.ChainManager().GetBlockByNumber(0).Root(), self.backend.StateDb())
		}
T
Taylor Gerring 已提交
188
	}
T
Taylor Gerring 已提交
189

190
	return self.WithState(st)
T
Taylor Gerring 已提交
191 192
}

193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
// applies queued transactions originating from address onto the latest state
// and creates a block
// only used in tests
// - could be removed in favour of mining on testdag (natspec e2e + networking)
// + filters
func (self *XEth) ApplyTestTxs(statedb *state.StateDB, address common.Address, txc uint64) (uint64, *XEth) {

	block := self.backend.ChainManager().NewBlock(address)
	coinbase := statedb.GetStateObject(address)
	coinbase.SetGasPool(big.NewInt(10000000))
	txs := self.backend.TxPool().GetQueuedTransactions()

	for i := 0; i < len(txs); i++ {
		for _, tx := range txs {
			if tx.Nonce() == txc {
				_, _, err := core.ApplyMessage(core.NewEnv(statedb, self.backend.ChainManager(), tx, block), tx, coinbase)
				if err != nil {
					panic(err)
				}
				txc++
			}
		}
	}

	xeth := self.WithState(statedb)
	return txc, xeth
}

221
func (self *XEth) WithState(statedb *state.StateDB) *XEth {
O
wip  
obscuren 已提交
222
	xeth := &XEth{
223 224
		backend:  self.backend,
		frontend: self.frontend,
O
wip  
obscuren 已提交
225 226 227 228 229
	}

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

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

233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
// 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() {
		sub := self.backend.EventMux().Subscribe(core.ChainHeadEvent{})
		var m, n *big.Int
		var ok bool
	out:
		for {
			select {
			case event := <-sub.Chan():
				ev, ok := event.(core.ChainHeadEvent)
				if ok {
					m = ev.Block.Number()
					if n != nil && n.Cmp(m) < 0 {
						wait <- n
						n = nil
					}
					statedb := state.New(ev.Block.Root(), self.backend.StateDb())
					self.state = NewState(self, statedb)
				}
			case n, ok = <-wait:
				if !ok {
					break out
				}
			}
		}
		sub.Unsubscribe()
	}()
	return
}

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

T
Taylor Gerring 已提交
273 274 275
func (self *XEth) getBlockByHeight(height int64) *types.Block {
	var num uint64

O
obscuren 已提交
276 277 278 279 280 281 282 283 284 285
	switch height {
	case -2:
		return self.backend.Miner().PendingBlock()
	case -1:
		return self.CurrentBlock()
	default:
		if height < 0 {
			return nil
		}

T
Taylor Gerring 已提交
286 287 288 289 290 291
		num = uint64(height)
	}

	return self.backend.ChainManager().GetBlockByNumber(num)
}

O
obscuren 已提交
292
func (self *XEth) BlockByHash(strHash string) *Block {
O
obscuren 已提交
293
	hash := common.HexToHash(strHash)
T
Taylor Gerring 已提交
294
	block := self.backend.ChainManager().GetBlock(hash)
O
obscuren 已提交
295

O
obscuren 已提交
296
	return NewBlock(block)
O
obscuren 已提交
297 298
}

T
Taylor Gerring 已提交
299 300
func (self *XEth) EthBlockByHash(strHash string) *types.Block {
	hash := common.HexToHash(strHash)
T
Taylor Gerring 已提交
301
	block := self.backend.ChainManager().GetBlock(hash)
T
Taylor Gerring 已提交
302 303 304 305

	return block
}

306
func (self *XEth) EthTransactionByHash(hash string) (tx *types.Transaction, blhash common.Hash, blnum *big.Int, txi uint64) {
T
Taylor Gerring 已提交
307
	data, _ := self.backend.ExtraDb().Get(common.FromHex(hash))
O
obscuren 已提交
308
	if len(data) != 0 {
309
		tx = types.NewTransactionFromBytes(data)
310 311
	} else { // check pending transactions
		tx = self.backend.TxPool().GetTransaction(common.HexToHash(hash))
O
obscuren 已提交
312
	}
313

T
Taylor Gerring 已提交
314 315 316
	// meta
	var txExtra struct {
		BlockHash  common.Hash
T
Taylor Gerring 已提交
317
		BlockIndex uint64
T
Taylor Gerring 已提交
318
		Index      uint64
319
	}
T
Taylor Gerring 已提交
320

321 322 323 324 325
	v, dberr := self.backend.ExtraDb().Get(append(common.FromHex(hash), 0x0001))
	// TODO check specifically for ErrNotFound
	if dberr != nil {
		return
	}
T
Taylor Gerring 已提交
326 327 328 329
	r := bytes.NewReader(v)
	err := rlp.Decode(r, &txExtra)
	if err == nil {
		blhash = txExtra.BlockHash
T
Taylor Gerring 已提交
330
		blnum = big.NewInt(int64(txExtra.BlockIndex))
T
Taylor Gerring 已提交
331
		txi = txExtra.Index
T
Taylor Gerring 已提交
332
	} else {
O
obscuren 已提交
333
		glog.V(logger.Error).Infoln(err)
334 335 336
	}

	return
O
obscuren 已提交
337 338
}

T
Taylor Gerring 已提交
339
func (self *XEth) BlockByNumber(num int64) *Block {
T
Taylor Gerring 已提交
340
	return NewBlock(self.getBlockByHeight(num))
O
obscuren 已提交
341 342
}

T
Taylor Gerring 已提交
343
func (self *XEth) EthBlockByNumber(num int64) *types.Block {
T
Taylor Gerring 已提交
344
	return self.getBlockByHeight(num)
T
Taylor Gerring 已提交
345 346
}

T
Taylor Gerring 已提交
347 348 349 350
func (self *XEth) CurrentBlock() *types.Block {
	return self.backend.ChainManager().CurrentBlock()
}

351 352 353 354
func (self *XEth) GasLimit() *big.Int {
	return self.backend.ChainManager().GasLimit()
}

O
obscuren 已提交
355
func (self *XEth) Block(v interface{}) *Block {
O
obscuren 已提交
356
	if n, ok := v.(int32); ok {
T
Taylor Gerring 已提交
357
		return self.BlockByNumber(int64(n))
O
obscuren 已提交
358 359 360
	} else if str, ok := v.(string); ok {
		return self.BlockByHash(str)
	} else if f, ok := v.(float64); ok { // Don't ask ...
T
Taylor Gerring 已提交
361
		return self.BlockByNumber(int64(f))
O
obscuren 已提交
362 363 364 365 366
	}

	return nil
}

O
obscuren 已提交
367
func (self *XEth) Accounts() []string {
368
	// TODO: check err?
T
Taylor Gerring 已提交
369
	accounts, _ := self.backend.AccountManager().Accounts()
370 371
	accountAddresses := make([]string, len(accounts))
	for i, ac := range accounts {
372
		accountAddresses[i] = ac.Address.Hex()
373 374
	}
	return accountAddresses
O
obscuren 已提交
375 376
}

377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393
// accessor for solidity compiler.
// memoized if available, retried on-demand if not
func (self *XEth) Solc() (*compiler.Solidity, error) {
	var err error
	if self.solc == nil {
		self.solc, err = compiler.New(self.solcPath)
	}
	return self.solc, err
}

// set in js console via admin interface or wrapper from cli flags
func (self *XEth) SetSolc(solcPath string) (*compiler.Solidity, error) {
	self.solcPath = solcPath
	self.solc = nil
	return self.Solc()
}

394 395 396 397 398 399 400 401 402 403
func (self *XEth) DbPut(key, val []byte) bool {
	self.backend.ExtraDb().Put(key, val)
	return true
}

func (self *XEth) DbGet(key []byte) ([]byte, error) {
	val, err := self.backend.ExtraDb().Get(key)
	return val, err
}

O
obscuren 已提交
404
func (self *XEth) PeerCount() int {
T
Taylor Gerring 已提交
405
	return self.backend.PeerCount()
O
obscuren 已提交
406 407
}

O
obscuren 已提交
408
func (self *XEth) IsMining() bool {
T
Taylor Gerring 已提交
409
	return self.backend.IsMining()
O
obscuren 已提交
410 411
}

K
Kobi Gurkan 已提交
412
func (self *XEth) HashRate() int64 {
413
	return self.backend.Miner().HashRate()
K
Kobi Gurkan 已提交
414 415
}

416
func (self *XEth) EthVersion() string {
417
	return fmt.Sprintf("%d", self.backend.EthVersion())
418 419
}

T
Taylor Gerring 已提交
420
func (self *XEth) NetworkVersion() string {
421
	return fmt.Sprintf("%d", self.backend.NetVersion())
422 423 424
}

func (self *XEth) WhisperVersion() string {
425
	return fmt.Sprintf("%d", self.backend.ShhVersion())
T
Taylor Gerring 已提交
426 427 428
}

func (self *XEth) ClientVersion() string {
429
	return self.backend.ClientVersion()
T
Taylor Gerring 已提交
430 431
}

432
func (self *XEth) SetMining(shouldmine bool, threads int) bool {
T
Taylor Gerring 已提交
433
	ismining := self.backend.IsMining()
T
Taylor Gerring 已提交
434
	if shouldmine && !ismining {
435
		err := self.backend.StartMining(threads)
436
		return err == nil
T
Taylor Gerring 已提交
437 438
	}
	if ismining && !shouldmine {
T
Taylor Gerring 已提交
439
		self.backend.StopMining()
T
Taylor Gerring 已提交
440
	}
T
Taylor Gerring 已提交
441
	return self.backend.IsMining()
T
Taylor Gerring 已提交
442 443
}

O
obscuren 已提交
444
func (self *XEth) IsListening() bool {
T
Taylor Gerring 已提交
445
	return self.backend.IsListening()
O
obscuren 已提交
446 447
}

O
obscuren 已提交
448
func (self *XEth) Coinbase() string {
Z
zelig 已提交
449 450
	eb, _ := self.backend.Etherbase()
	return eb.Hex()
O
obscuren 已提交
451 452
}

O
obscuren 已提交
453
func (self *XEth) NumberToHuman(balance string) string {
O
obscuren 已提交
454
	b := common.Big(balance)
O
obscuren 已提交
455

O
obscuren 已提交
456
	return common.CurrencyToString(b)
O
obscuren 已提交
457 458
}

O
obscuren 已提交
459
func (self *XEth) StorageAt(addr, storageAddr string) string {
460
	return common.ToHex(self.State().state.GetState(common.HexToAddress(addr), common.HexToHash(storageAddr)))
O
obscuren 已提交
461 462
}

O
obscuren 已提交
463
func (self *XEth) BalanceAt(addr string) string {
O
obscuren 已提交
464
	return common.ToHex(self.State().state.GetBalance(common.HexToAddress(addr)).Bytes())
O
obscuren 已提交
465 466
}

O
obscuren 已提交
467
func (self *XEth) TxCountAt(address string) int {
468
	return int(self.State().state.GetNonce(common.HexToAddress(address)))
O
obscuren 已提交
469 470
}

O
obscuren 已提交
471
func (self *XEth) CodeAt(address string) string {
472
	return common.ToHex(self.State().state.GetCode(common.HexToAddress(address)))
O
obscuren 已提交
473 474
}

T
Taylor Gerring 已提交
475 476 477 478
func (self *XEth) CodeAtBytes(address string) []byte {
	return self.State().SafeGet(address).Code()
}

O
obscuren 已提交
479
func (self *XEth) IsContract(address string) bool {
480
	return len(self.State().SafeGet(address).Code()) > 0
O
obscuren 已提交
481 482
}

O
obscuren 已提交
483
func (self *XEth) SecretToAddress(key string) string {
O
obscuren 已提交
484
	pair, err := crypto.NewKeyPairFromSec(common.FromHex(key))
O
obscuren 已提交
485 486 487 488
	if err != nil {
		return ""
	}

489
	return common.ToHex(pair.Address())
O
obscuren 已提交
490 491
}

492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517
func (self *XEth) UninstallFilter(id int) bool {
	defer self.filterManager.UninstallFilter(id)

	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 {
T
Taylor Gerring 已提交
518
	var id int
T
Taylor Gerring 已提交
519
	filter := core.NewFilter(self.backend)
T
Taylor Gerring 已提交
520 521 522 523 524 525
	filter.SetEarliestBlock(earliest)
	filter.SetLatestBlock(latest)
	filter.SetSkip(skip)
	filter.SetMax(max)
	filter.SetAddress(cAddress(address))
	filter.SetTopics(cTopics(topics))
T
Taylor Gerring 已提交
526
	filter.LogsCallback = func(logs state.Logs) {
527 528
		self.logMu.Lock()
		defer self.logMu.Unlock()
T
Taylor Gerring 已提交
529

530
		self.logQueue[id].add(logs...)
T
Taylor Gerring 已提交
531 532
	}
	id = self.filterManager.InstallFilter(filter)
533
	self.logQueue[id] = &logQueue{timeout: time.Now()}
T
Taylor Gerring 已提交
534 535 536 537

	return id
}

538 539 540 541 542 543
func (self *XEth) NewTransactionFilter() int {
	var id int
	filter := core.NewFilter(self.backend)
	filter.TransactionCallback = func(tx *types.Transaction) {
		self.transactionMu.Lock()
		defer self.transactionMu.Unlock()
T
Taylor Gerring 已提交
544

545 546 547 548 549
		self.transactionQueue[id].add(tx.Hash())
	}
	id = self.filterManager.InstallFilter(filter)
	self.transactionQueue[id] = &hashQueue{timeout: time.Now()}
	return id
T
Taylor Gerring 已提交
550 551
}

552
func (self *XEth) NewBlockFilter() int {
T
Taylor Gerring 已提交
553
	var id int
T
Taylor Gerring 已提交
554
	filter := core.NewFilter(self.backend)
555 556 557
	filter.BlockCallback = func(block *types.Block, logs state.Logs) {
		self.blockMu.Lock()
		defer self.blockMu.Unlock()
T
Taylor Gerring 已提交
558

559 560 561 562 563 564
		self.blockQueue[id].add(block.Hash())
	}
	id = self.filterManager.InstallFilter(filter)
	self.blockQueue[id] = &hashQueue{timeout: time.Now()}
	return id
}
565

566 567 568 569 570 571 572
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 已提交
573 574
	}

575 576
	return UnknownFilterTy
}
T
Taylor Gerring 已提交
577

578 579 580 581 582 583 584 585
func (self *XEth) LogFilterChanged(id int) state.Logs {
	self.logMu.Lock()
	defer self.logMu.Unlock()

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

588 589 590
func (self *XEth) BlockFilterChanged(id int) []common.Hash {
	self.blockMu.Lock()
	defer self.blockMu.Unlock()
T
Taylor Gerring 已提交
591

592 593
	if self.blockQueue[id] != nil {
		return self.blockQueue[id].get()
T
Taylor Gerring 已提交
594
	}
595 596 597 598 599 600
	return nil
}

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

602
	if self.transactionQueue[id] != nil {
603 604
		return self.transactionQueue[id].get()
	}
T
Taylor Gerring 已提交
605 606 607 608
	return nil
}

func (self *XEth) Logs(id int) state.Logs {
609 610
	self.logMu.Lock()
	defer self.logMu.Unlock()
T
Taylor Gerring 已提交
611 612 613 614 615 616 617 618 619

	filter := self.filterManager.GetFilter(id)
	if filter != nil {
		return filter.Find()
	}

	return nil
}

T
Taylor Gerring 已提交
620
func (self *XEth) AllLogs(earliest, latest int64, skip, max int, address []string, topics [][]string) state.Logs {
T
Taylor Gerring 已提交
621
	filter := core.NewFilter(self.backend)
T
Taylor Gerring 已提交
622 623 624 625 626 627
	filter.SetEarliestBlock(earliest)
	filter.SetLatestBlock(latest)
	filter.SetSkip(skip)
	filter.SetMax(max)
	filter.SetAddress(cAddress(address))
	filter.SetTopics(cTopics(topics))
T
Taylor Gerring 已提交
628 629 630 631

	return filter.Find()
}

632 633 634
// 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.
635
func (p *XEth) NewWhisperFilter(to, from string, topics [][]string) int {
636
	// Pre-define the id to be filled later
T
Taylor Gerring 已提交
637
	var id int
638

639 640
	// Callback to delegate core whisper messages to this xeth filter
	callback := func(msg WhisperMessage) {
641 642
		p.messagesMu.RLock() // Only read lock to the filter pool
		defer p.messagesMu.RUnlock()
643
		p.messages[id].insert(msg)
T
Taylor Gerring 已提交
644
	}
645
	// Initialize the core whisper filter and wrap into xeth
646
	id = p.Whisper().Watch(to, from, topics, callback)
647

648
	p.messagesMu.Lock()
649
	p.messages[id] = newWhisperFilter(id, p.Whisper())
650
	p.messagesMu.Unlock()
651

T
Taylor Gerring 已提交
652 653 654
	return id
}

655
// UninstallWhisperFilter disables and removes an existing filter.
T
Taylor Gerring 已提交
656
func (p *XEth) UninstallWhisperFilter(id int) bool {
657 658
	p.messagesMu.Lock()
	defer p.messagesMu.Unlock()
659

T
Taylor Gerring 已提交
660 661 662 663 664 665 666
	if _, ok := p.messages[id]; ok {
		delete(p.messages, id)
		return true
	}
	return false
}

667 668
// WhisperMessages retrieves all the known messages that match a specific filter.
func (self *XEth) WhisperMessages(id int) []WhisperMessage {
669 670
	self.messagesMu.RLock()
	defer self.messagesMu.RUnlock()
T
Taylor Gerring 已提交
671 672

	if self.messages[id] != nil {
673
		return self.messages[id].messages()
T
Taylor Gerring 已提交
674
	}
675 676 677
	return nil
}

678 679 680
// WhisperMessagesChanged retrieves all the new messages matched by a filter
// since the last retrieval
func (self *XEth) WhisperMessagesChanged(id int) []WhisperMessage {
681 682
	self.messagesMu.RLock()
	defer self.messagesMu.RUnlock()
T
Taylor Gerring 已提交
683

684
	if self.messages[id] != nil {
685
		return self.messages[id].retrieve()
686
	}
T
Taylor Gerring 已提交
687 688 689
	return nil
}

T
Taylor Gerring 已提交
690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722
// 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 已提交
723 724 725 726 727
type KeyVal struct {
	Key   string `json:"key"`
	Value string `json:"value"`
}

O
obscuren 已提交
728
func (self *XEth) EachStorage(addr string) string {
O
obscuren 已提交
729 730 731 732
	var values []KeyVal
	object := self.State().SafeGet(addr)
	it := object.Trie().Iterator()
	for it.Next() {
O
obscuren 已提交
733
		values = append(values, KeyVal{common.ToHex(object.Trie().GetKey(it.Key)), common.ToHex(it.Value)})
O
obscuren 已提交
734 735 736 737 738 739 740 741 742 743
	}

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

	return string(valuesJson)
}

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

747
	return "0x" + common.ToHex(padded)
O
obscuren 已提交
748 749
}

O
obscuren 已提交
750
func (self *XEth) FromAscii(str string) string {
O
obscuren 已提交
751
	if common.IsHex(str) {
O
obscuren 已提交
752 753 754
		str = str[2:]
	}

O
obscuren 已提交
755
	return string(bytes.Trim(common.FromHex(str), "\x00"))
O
obscuren 已提交
756 757
}

O
obscuren 已提交
758
func (self *XEth) FromNumber(str string) string {
O
obscuren 已提交
759
	if common.IsHex(str) {
O
obscuren 已提交
760 761 762
		str = str[2:]
	}

O
obscuren 已提交
763
	return common.BigD(common.FromHex(str)).String()
O
obscuren 已提交
764 765
}

O
obscuren 已提交
766
func (self *XEth) PushTx(encodedTx string) (string, error) {
O
obscuren 已提交
767
	tx := types.NewTransactionFromBytes(common.FromHex(encodedTx))
T
Taylor Gerring 已提交
768
	err := self.backend.TxPool().Add(tx)
O
obscuren 已提交
769 770 771 772 773 774
	if err != nil {
		return "", err
	}

	if tx.To() == nil {
		addr := core.AddressFromMessage(tx)
O
obscuren 已提交
775
		return addr.Hex(), nil
O
obscuren 已提交
776
	}
O
obscuren 已提交
777
	return tx.Hash().Hex(), nil
O
obscuren 已提交
778
}
779

780
func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr string) (string, string, error) {
T
Taylor Gerring 已提交
781
	statedb := self.State().State() //self.eth.ChainManager().TransState()
782 783 784 785 786 787
	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 {
788
			from = statedb.GetOrNewStateObject(accounts[0].Address)
789 790 791 792 793
		}
	} else {
		from = statedb.GetOrNewStateObject(common.HexToAddress(fromStr))
	}

794
	from.SetGasPool(self.backend.ChainManager().GasLimit())
795
	msg := callmsg{
796
		from:     from,
O
obscuren 已提交
797
		to:       common.HexToAddress(toStr),
O
obscuren 已提交
798 799 800 801
		gas:      common.Big(gasStr),
		gasPrice: common.Big(gasPriceStr),
		value:    common.Big(valueStr),
		data:     common.FromHex(dataStr),
802
	}
B
Bas van Kervel 已提交
803

804
	if msg.gas.Cmp(big.NewInt(0)) == 0 {
O
obscuren 已提交
805
		msg.gas = DefaultGas()
806 807 808
	}

	if msg.gasPrice.Cmp(big.NewInt(0)) == 0 {
O
obscuren 已提交
809
		msg.gasPrice = DefaultGasPrice()
810 811
	}

812
	block := self.CurrentBlock()
T
Taylor Gerring 已提交
813
	vmenv := core.NewEnv(statedb, self.backend.ChainManager(), msg, block)
814

815 816
	res, gas, err := core.ApplyMessage(vmenv, msg, from)
	return common.ToHex(res), gas.String(), err
817 818
}

819 820 821 822
func (self *XEth) ConfirmTransaction(tx string) bool {
	return self.frontend.ConfirmTransaction(tx)
}

823
func (self *XEth) doSign(from common.Address, hash common.Hash, didUnlock bool) ([]byte, error) {
824
	sig, err := self.backend.AccountManager().Sign(accounts.Account{Address: from}, hash.Bytes())
D
Daniel A. Nagy 已提交
825 826
	if err == accounts.ErrLocked {
		if didUnlock {
827
			return nil, fmt.Errorf("signer account still locked after successful unlock")
D
Daniel A. Nagy 已提交
828 829
		}
		if !self.frontend.UnlockAccount(from.Bytes()) {
830
			return nil, fmt.Errorf("could not unlock signer account")
D
Daniel A. Nagy 已提交
831 832
		}
		// retry signing, the account should now be unlocked.
833
		return self.doSign(from, hash, true)
D
Daniel A. Nagy 已提交
834
	} else if err != nil {
835 836 837 838 839 840 841 842 843 844
		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)
	)
845
	sig, err := self.doSign(from, hash, didUnlock)
846
	if err != nil {
847
		return "", err
D
Daniel A. Nagy 已提交
848
	}
849
	return common.ToHex(sig), nil
D
Daniel A. Nagy 已提交
850 851
}

852
func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) {
853 854 855 856 857 858 859 860

	// 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
	}

861
	var (
O
obscuren 已提交
862 863
		from             = common.HexToAddress(fromStr)
		to               = common.HexToAddress(toStr)
O
obscuren 已提交
864
		value            = common.NewValue(valueStr)
T
Taylor Gerring 已提交
865 866
		gas              = common.Big(gasStr)
		price            = common.Big(gasPriceStr)
867 868 869 870
		data             []byte
		contractCreation bool
	)

T
Taylor Gerring 已提交
871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892
	// 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)
		}
	*/

T
Taylor Gerring 已提交
893 894 895
	// TODO: align default values to have the same type, e.g. not depend on
	// common.Value conversions later on
	if gas.Cmp(big.NewInt(0)) == 0 {
O
obscuren 已提交
896
		gas = DefaultGas()
T
Taylor Gerring 已提交
897 898 899
	}

	if price.Cmp(big.NewInt(0)) == 0 {
O
obscuren 已提交
900
		price = DefaultGasPrice()
T
Taylor Gerring 已提交
901 902
	}

O
obscuren 已提交
903
	data = common.FromHex(codeStr)
O
obscuren 已提交
904
	if len(toStr) == 0 {
905 906 907 908 909
		contractCreation = true
	}

	var tx *types.Transaction
	if contractCreation {
T
Taylor Gerring 已提交
910
		tx = types.NewContractCreationTx(value.BigInt(), gas, price, data)
911
	} else {
T
Taylor Gerring 已提交
912
		tx = types.NewTransactionMessage(to, value.BigInt(), gas, price, data)
913 914
	}

T
Taylor Gerring 已提交
915
	state := self.backend.ChainManager().TxState()
916 917 918 919 920 921 922

	var nonce uint64
	if len(nonceStr) != 0 {
		nonce = common.Big(nonceStr).Uint64()
	} else {
		nonce = state.NewNonce(from)
	}
923 924
	tx.SetNonce(nonce)

925
	if err := self.sign(tx, from, false); err != nil {
926 927
		return "", err
	}
T
Taylor Gerring 已提交
928
	if err := self.backend.TxPool().Add(tx); err != nil {
929 930
		return "", err
	}
931 932 933

	if contractCreation {
		addr := core.AddressFromMessage(tx)
O
obscuren 已提交
934
		glog.V(logger.Info).Infof("Tx(%x) created: %x\n", tx.Hash(), addr)
935

O
obscuren 已提交
936
		return core.AddressFromMessage(tx).Hex(), nil
O
obscuren 已提交
937 938
	} else {
		glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To())
939
	}
O
obscuren 已提交
940
	return tx.Hash().Hex(), nil
941
}
942

O
obscuren 已提交
943
func (self *XEth) sign(tx *types.Transaction, from common.Address, didUnlock bool) error {
944
	hash := tx.Hash()
945 946
	sig, err := self.doSign(from, hash, didUnlock)
	if err != nil {
947 948 949 950 951 952
		return err
	}
	tx.SetSignatureValues(sig)
	return nil
}

953 954 955
// callmsg is the message type used for call transations.
type callmsg struct {
	from          *state.StateObject
O
obscuren 已提交
956
	to            common.Address
957 958 959 960 961 962
	gas, gasPrice *big.Int
	value         *big.Int
	data          []byte
}

// accessor boilerplate to implement core.Message
O
obscuren 已提交
963 964 965 966 967 968 969
func (m callmsg) From() (common.Address, error) { return m.from.Address(), nil }
func (m callmsg) Nonce() uint64                 { return m.from.Nonce() }
func (m callmsg) To() *common.Address           { return &m.to }
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 已提交
970

971
type logQueue struct {
T
Taylor Gerring 已提交
972 973 974 975 976
	logs    state.Logs
	timeout time.Time
	id      int
}

977
func (l *logQueue) add(logs ...*state.Log) {
T
Taylor Gerring 已提交
978 979 980
	l.logs = append(l.logs, logs...)
}

981
func (l *logQueue) get() state.Logs {
T
Taylor Gerring 已提交
982 983 984 985 986
	l.timeout = time.Now()
	tmp := l.logs
	l.logs = nil
	return tmp
}
987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003

type hashQueue struct {
	hashes  []common.Hash
	timeout time.Time
	id      int
}

func (l *hashQueue) add(hashes ...common.Hash) {
	l.hashes = append(l.hashes, hashes...)
}

func (l *hashQueue) get() []common.Hash {
	l.timeout = time.Now()
	tmp := l.hashes
	l.hashes = nil
	return tmp
}