xeth.go 25.9 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
31
	dappStorePre     = []byte("dapp-")
T
Taylor Gerring 已提交
32
)
O
obscuren 已提交
33

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

Z
zsfelfoldi 已提交
42 43 44
func DefaultGas() *big.Int { return new(big.Int).Set(defaultGas) }

func (self *XEth) DefaultGasPrice() *big.Int {
Z
zsfelfoldi 已提交
45 46 47
	if self.gpo == nil {
		self.gpo = eth.NewGasPriceOracle(self.backend)
	}
Z
zsfelfoldi 已提交
48 49
	return self.gpo.SuggestPrice()
}
O
obscuren 已提交
50

O
obscuren 已提交
51
type XEth struct {
T
Shuffle  
Taylor Gerring 已提交
52 53 54
	backend  *eth.Ethereum
	frontend Frontend

T
Taylor Gerring 已提交
55 56
	state   *State
	whisper *Whisper
O
obscuren 已提交
57

T
Taylor Gerring 已提交
58 59
	quit          chan struct{}
	filterManager *filter.FilterManager
O
obscuren 已提交
60

61 62 63 64 65 66 67 68
	logMu    sync.RWMutex
	logQueue map[int]*logQueue

	blockMu    sync.RWMutex
	blockQueue map[int]*hashQueue

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

70 71
	messagesMu sync.RWMutex
	messages   map[int]*whisperFilter
T
Taylor Gerring 已提交
72 73 74

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

T
Taylor Gerring 已提交
76
	agent *miner.RemoteAgent
Z
zsfelfoldi 已提交
77 78

	gpo *eth.GasPriceOracle
O
obscuren 已提交
79
}
O
obscuren 已提交
80

81 82 83 84 85 86 87
func NewTest(eth *eth.Ethereum, frontend Frontend) *XEth {
	return &XEth{
		backend:  eth,
		frontend: frontend,
	}
}

88 89 90
// 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 已提交
91
func New(ethereum *eth.Ethereum, frontend Frontend) *XEth {
O
obscuren 已提交
92
	xeth := &XEth{
Z
zsfelfoldi 已提交
93
		backend:          ethereum,
94 95
		frontend:         frontend,
		quit:             make(chan struct{}),
Z
zsfelfoldi 已提交
96
		filterManager:    filter.NewFilterManager(ethereum.EventMux()),
97 98 99 100 101
		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 已提交
102
	}
Z
zsfelfoldi 已提交
103 104
	if ethereum.Whisper() != nil {
		xeth.whisper = NewWhisper(ethereum.Whisper())
105
	}
Z
zsfelfoldi 已提交
106
	ethereum.Miner().Register(xeth.agent)
O
obscuren 已提交
107
	if frontend == nil {
108
		xeth.frontend = dummyFrontend{}
O
obscuren 已提交
109
	}
T
Taylor Gerring 已提交
110
	xeth.state = NewState(xeth, xeth.backend.ChainManager().TransState())
T
Shuffle  
Taylor Gerring 已提交
111

T
Taylor Gerring 已提交
112 113 114
	go xeth.start()
	go xeth.filterManager.Start()

O
obscuren 已提交
115 116 117
	return xeth
}

T
Taylor Gerring 已提交
118 119 120 121 122 123
func (self *XEth) start() {
	timer := time.NewTicker(2 * time.Second)
done:
	for {
		select {
		case <-timer.C:
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
			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 已提交
144 145
				if time.Since(filter.timeout) > filterTickerTime {
					self.filterManager.UninstallFilter(id)
146
					delete(self.transactionQueue, id)
T
Taylor Gerring 已提交
147 148
				}
			}
149
			self.transactionMu.Unlock()
T
Taylor Gerring 已提交
150

151
			self.messagesMu.Lock()
T
Taylor Gerring 已提交
152
			for id, filter := range self.messages {
153
				if time.Since(filter.activity()) > filterTickerTime {
T
Taylor Gerring 已提交
154 155 156 157
					self.Whisper().Unwatch(id)
					delete(self.messages, id)
				}
			}
158
			self.messagesMu.Unlock()
T
Taylor Gerring 已提交
159 160 161 162 163 164 165 166 167 168
		case <-self.quit:
			break done
		}
	}
}

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

T
Taylor Gerring 已提交
169 170 171 172 173 174 175 176 177 178 179
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 {
180
		topics[i] = make([]common.Hash, len(iv))
T
Taylor Gerring 已提交
181 182 183 184 185 186 187
		for j, jv := range iv {
			topics[i][j] = common.HexToHash(jv)
		}
	}
	return topics
}

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

T
Taylor Gerring 已提交
190 191
func (self *XEth) AtStateNum(num int64) *XEth {
	var st *state.StateDB
O
obscuren 已提交
192 193 194 195 196 197 198 199 200
	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 已提交
201
	}
T
Taylor Gerring 已提交
202

203
	return self.WithState(st)
T
Taylor Gerring 已提交
204 205
}

206 207 208 209 210 211 212 213 214
// 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)
215
	coinbase.SetGasLimit(big.NewInt(10000000))
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
	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
}

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

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

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

247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
// 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
}

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

T
Taylor Gerring 已提交
287 288 289
func (self *XEth) getBlockByHeight(height int64) *types.Block {
	var num uint64

O
obscuren 已提交
290 291 292 293 294 295 296 297 298 299
	switch height {
	case -2:
		return self.backend.Miner().PendingBlock()
	case -1:
		return self.CurrentBlock()
	default:
		if height < 0 {
			return nil
		}

T
Taylor Gerring 已提交
300 301 302 303 304 305
		num = uint64(height)
	}

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

O
obscuren 已提交
306
func (self *XEth) BlockByHash(strHash string) *Block {
O
obscuren 已提交
307
	hash := common.HexToHash(strHash)
T
Taylor Gerring 已提交
308
	block := self.backend.ChainManager().GetBlock(hash)
O
obscuren 已提交
309

O
obscuren 已提交
310
	return NewBlock(block)
O
obscuren 已提交
311 312
}

T
Taylor Gerring 已提交
313 314
func (self *XEth) EthBlockByHash(strHash string) *types.Block {
	hash := common.HexToHash(strHash)
T
Taylor Gerring 已提交
315
	block := self.backend.ChainManager().GetBlock(hash)
T
Taylor Gerring 已提交
316 317 318 319

	return block
}

320
func (self *XEth) EthTransactionByHash(hash string) (tx *types.Transaction, blhash common.Hash, blnum *big.Int, txi uint64) {
T
Taylor Gerring 已提交
321 322
	// 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
T
Taylor Gerring 已提交
323
	data, _ := self.backend.ExtraDb().Get(common.FromHex(hash))
O
obscuren 已提交
324
	if len(data) != 0 {
325
		tx = types.NewTransactionFromBytes(data)
326 327
	} else { // check pending transactions
		tx = self.backend.TxPool().GetTransaction(common.HexToHash(hash))
O
obscuren 已提交
328
	}
329

T
Taylor Gerring 已提交
330 331 332
	// meta
	var txExtra struct {
		BlockHash  common.Hash
T
Taylor Gerring 已提交
333
		BlockIndex uint64
T
Taylor Gerring 已提交
334
		Index      uint64
335
	}
T
Taylor Gerring 已提交
336

337 338 339 340 341
	v, dberr := self.backend.ExtraDb().Get(append(common.FromHex(hash), 0x0001))
	// TODO check specifically for ErrNotFound
	if dberr != nil {
		return
	}
T
Taylor Gerring 已提交
342 343 344 345
	r := bytes.NewReader(v)
	err := rlp.Decode(r, &txExtra)
	if err == nil {
		blhash = txExtra.BlockHash
T
Taylor Gerring 已提交
346
		blnum = big.NewInt(int64(txExtra.BlockIndex))
T
Taylor Gerring 已提交
347
		txi = txExtra.Index
T
Taylor Gerring 已提交
348
	} else {
O
obscuren 已提交
349
		glog.V(logger.Error).Infoln(err)
350 351 352
	}

	return
O
obscuren 已提交
353 354
}

T
Taylor Gerring 已提交
355
func (self *XEth) BlockByNumber(num int64) *Block {
T
Taylor Gerring 已提交
356
	return NewBlock(self.getBlockByHeight(num))
O
obscuren 已提交
357 358
}

T
Taylor Gerring 已提交
359
func (self *XEth) EthBlockByNumber(num int64) *types.Block {
T
Taylor Gerring 已提交
360
	return self.getBlockByHeight(num)
T
Taylor Gerring 已提交
361 362
}

T
Taylor Gerring 已提交
363 364 365 366
func (self *XEth) CurrentBlock() *types.Block {
	return self.backend.ChainManager().CurrentBlock()
}

Z
zsfelfoldi 已提交
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
func (self *XEth) GetBlockReceipts(bhash common.Hash) (receipts types.Receipts, err error) {
	return self.backend.BlockProcessor().GetBlockReceipts(bhash)
}

func (self *XEth) GetTxReceipt(txhash common.Hash) (receipt *types.Receipt, err error) {
	_, bhash, _, txi := self.EthTransactionByHash(common.ToHex(txhash[:]))
	var receipts types.Receipts
	receipts, err = self.backend.BlockProcessor().GetBlockReceipts(bhash)
	if err == nil {
		if txi < uint64(len(receipts)) {
			receipt = receipts[txi]
		} else {
			err = fmt.Errorf("Invalid tx index")
		}
	}
	return
}

385 386 387 388
func (self *XEth) GasLimit() *big.Int {
	return self.backend.ChainManager().GasLimit()
}

O
obscuren 已提交
389
func (self *XEth) Block(v interface{}) *Block {
O
obscuren 已提交
390
	if n, ok := v.(int32); ok {
T
Taylor Gerring 已提交
391
		return self.BlockByNumber(int64(n))
O
obscuren 已提交
392 393
	} else if str, ok := v.(string); ok {
		return self.BlockByHash(str)
T
Taylor Gerring 已提交
394
	} else if f, ok := v.(float64); ok { // JSON numbers are represented as float64
T
Taylor Gerring 已提交
395
		return self.BlockByNumber(int64(f))
O
obscuren 已提交
396 397 398 399 400
	}

	return nil
}

O
obscuren 已提交
401
func (self *XEth) Accounts() []string {
402
	// TODO: check err?
T
Taylor Gerring 已提交
403
	accounts, _ := self.backend.AccountManager().Accounts()
404 405
	accountAddresses := make([]string, len(accounts))
	for i, ac := range accounts {
406
		accountAddresses[i] = ac.Address.Hex()
407 408
	}
	return accountAddresses
O
obscuren 已提交
409 410
}

411 412 413
// accessor for solidity compiler.
// memoized if available, retried on-demand if not
func (self *XEth) Solc() (*compiler.Solidity, error) {
414
	return self.backend.Solc()
415 416 417 418
}

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

423
// store DApp value in extra database
424
func (self *XEth) DbPut(key, val []byte) bool {
425
	self.backend.ExtraDb().Put(append(dappStorePre, key...), val)
426 427 428
	return true
}

429
// retrieve DApp value from extra database
430
func (self *XEth) DbGet(key []byte) ([]byte, error) {
431
	val, err := self.backend.ExtraDb().Get(append(dappStorePre, key...))
432 433 434
	return val, err
}

O
obscuren 已提交
435
func (self *XEth) PeerCount() int {
T
Taylor Gerring 已提交
436
	return self.backend.PeerCount()
O
obscuren 已提交
437 438
}

O
obscuren 已提交
439
func (self *XEth) IsMining() bool {
T
Taylor Gerring 已提交
440
	return self.backend.IsMining()
O
obscuren 已提交
441 442
}

K
Kobi Gurkan 已提交
443
func (self *XEth) HashRate() int64 {
444
	return self.backend.Miner().HashRate()
K
Kobi Gurkan 已提交
445 446
}

447
func (self *XEth) EthVersion() string {
448
	return fmt.Sprintf("%d", self.backend.EthVersion())
449 450
}

T
Taylor Gerring 已提交
451
func (self *XEth) NetworkVersion() string {
452
	return fmt.Sprintf("%d", self.backend.NetVersion())
453 454 455
}

func (self *XEth) WhisperVersion() string {
456
	return fmt.Sprintf("%d", self.backend.ShhVersion())
T
Taylor Gerring 已提交
457 458 459
}

func (self *XEth) ClientVersion() string {
460
	return self.backend.ClientVersion()
T
Taylor Gerring 已提交
461 462
}

463
func (self *XEth) SetMining(shouldmine bool, threads int) bool {
T
Taylor Gerring 已提交
464
	ismining := self.backend.IsMining()
T
Taylor Gerring 已提交
465
	if shouldmine && !ismining {
466
		err := self.backend.StartMining(threads)
467
		return err == nil
T
Taylor Gerring 已提交
468 469
	}
	if ismining && !shouldmine {
T
Taylor Gerring 已提交
470
		self.backend.StopMining()
T
Taylor Gerring 已提交
471
	}
T
Taylor Gerring 已提交
472
	return self.backend.IsMining()
T
Taylor Gerring 已提交
473 474
}

O
obscuren 已提交
475
func (self *XEth) IsListening() bool {
T
Taylor Gerring 已提交
476
	return self.backend.IsListening()
O
obscuren 已提交
477 478
}

O
obscuren 已提交
479
func (self *XEth) Coinbase() string {
Z
zelig 已提交
480 481
	eb, _ := self.backend.Etherbase()
	return eb.Hex()
O
obscuren 已提交
482 483
}

O
obscuren 已提交
484
func (self *XEth) NumberToHuman(balance string) string {
O
obscuren 已提交
485
	b := common.Big(balance)
O
obscuren 已提交
486

O
obscuren 已提交
487
	return common.CurrencyToString(b)
O
obscuren 已提交
488 489
}

O
obscuren 已提交
490
func (self *XEth) StorageAt(addr, storageAddr string) string {
O
obscuren 已提交
491
	return self.State().state.GetState(common.HexToAddress(addr), common.HexToHash(storageAddr)).Hex()
O
obscuren 已提交
492 493
}

O
obscuren 已提交
494
func (self *XEth) BalanceAt(addr string) string {
O
obscuren 已提交
495
	return common.ToHex(self.State().state.GetBalance(common.HexToAddress(addr)).Bytes())
O
obscuren 已提交
496 497
}

O
obscuren 已提交
498
func (self *XEth) TxCountAt(address string) int {
499
	return int(self.State().state.GetNonce(common.HexToAddress(address)))
O
obscuren 已提交
500 501
}

O
obscuren 已提交
502
func (self *XEth) CodeAt(address string) string {
503
	return common.ToHex(self.State().state.GetCode(common.HexToAddress(address)))
O
obscuren 已提交
504 505
}

T
Taylor Gerring 已提交
506 507 508 509
func (self *XEth) CodeAtBytes(address string) []byte {
	return self.State().SafeGet(address).Code()
}

O
obscuren 已提交
510
func (self *XEth) IsContract(address string) bool {
511
	return len(self.State().SafeGet(address).Code()) > 0
O
obscuren 已提交
512 513
}

O
obscuren 已提交
514
func (self *XEth) SecretToAddress(key string) string {
O
obscuren 已提交
515
	pair, err := crypto.NewKeyPairFromSec(common.FromHex(key))
O
obscuren 已提交
516 517 518 519
	if err != nil {
		return ""
	}

520
	return common.ToHex(pair.Address())
O
obscuren 已提交
521 522
}

523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548
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 已提交
549
	var id int
T
Taylor Gerring 已提交
550
	filter := core.NewFilter(self.backend)
T
Taylor Gerring 已提交
551 552 553 554 555 556
	filter.SetEarliestBlock(earliest)
	filter.SetLatestBlock(latest)
	filter.SetSkip(skip)
	filter.SetMax(max)
	filter.SetAddress(cAddress(address))
	filter.SetTopics(cTopics(topics))
T
Taylor Gerring 已提交
557
	filter.LogsCallback = func(logs state.Logs) {
558 559
		self.logMu.Lock()
		defer self.logMu.Unlock()
T
Taylor Gerring 已提交
560

561
		self.logQueue[id].add(logs...)
T
Taylor Gerring 已提交
562 563
	}
	id = self.filterManager.InstallFilter(filter)
564
	self.logQueue[id] = &logQueue{timeout: time.Now()}
T
Taylor Gerring 已提交
565 566 567 568

	return id
}

569 570 571 572 573 574
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 已提交
575

576 577 578 579 580
		self.transactionQueue[id].add(tx.Hash())
	}
	id = self.filterManager.InstallFilter(filter)
	self.transactionQueue[id] = &hashQueue{timeout: time.Now()}
	return id
T
Taylor Gerring 已提交
581 582
}

583
func (self *XEth) NewBlockFilter() int {
T
Taylor Gerring 已提交
584
	var id int
T
Taylor Gerring 已提交
585
	filter := core.NewFilter(self.backend)
586 587 588
	filter.BlockCallback = func(block *types.Block, logs state.Logs) {
		self.blockMu.Lock()
		defer self.blockMu.Unlock()
T
Taylor Gerring 已提交
589

590 591 592 593 594 595
		self.blockQueue[id].add(block.Hash())
	}
	id = self.filterManager.InstallFilter(filter)
	self.blockQueue[id] = &hashQueue{timeout: time.Now()}
	return id
}
596

597 598 599 600 601 602 603
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 已提交
604 605
	}

606 607
	return UnknownFilterTy
}
T
Taylor Gerring 已提交
608

609 610 611 612 613 614 615 616
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 已提交
617 618
}

619 620 621
func (self *XEth) BlockFilterChanged(id int) []common.Hash {
	self.blockMu.Lock()
	defer self.blockMu.Unlock()
T
Taylor Gerring 已提交
622

623 624
	if self.blockQueue[id] != nil {
		return self.blockQueue[id].get()
T
Taylor Gerring 已提交
625
	}
626 627 628 629 630 631
	return nil
}

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

633
	if self.transactionQueue[id] != nil {
634 635
		return self.transactionQueue[id].get()
	}
T
Taylor Gerring 已提交
636 637 638 639
	return nil
}

func (self *XEth) Logs(id int) state.Logs {
640 641
	self.logMu.Lock()
	defer self.logMu.Unlock()
T
Taylor Gerring 已提交
642 643 644 645 646 647 648 649 650

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

	return nil
}

T
Taylor Gerring 已提交
651
func (self *XEth) AllLogs(earliest, latest int64, skip, max int, address []string, topics [][]string) state.Logs {
T
Taylor Gerring 已提交
652
	filter := core.NewFilter(self.backend)
T
Taylor Gerring 已提交
653 654 655 656 657 658
	filter.SetEarliestBlock(earliest)
	filter.SetLatestBlock(latest)
	filter.SetSkip(skip)
	filter.SetMax(max)
	filter.SetAddress(cAddress(address))
	filter.SetTopics(cTopics(topics))
T
Taylor Gerring 已提交
659 660 661 662

	return filter.Find()
}

663 664 665
// 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.
666
func (p *XEth) NewWhisperFilter(to, from string, topics [][]string) int {
667
	// Pre-define the id to be filled later
T
Taylor Gerring 已提交
668
	var id int
669

670 671
	// Callback to delegate core whisper messages to this xeth filter
	callback := func(msg WhisperMessage) {
672 673
		p.messagesMu.RLock() // Only read lock to the filter pool
		defer p.messagesMu.RUnlock()
674
		p.messages[id].insert(msg)
T
Taylor Gerring 已提交
675
	}
676
	// Initialize the core whisper filter and wrap into xeth
677
	id = p.Whisper().Watch(to, from, topics, callback)
678

679
	p.messagesMu.Lock()
680
	p.messages[id] = newWhisperFilter(id, p.Whisper())
681
	p.messagesMu.Unlock()
682

T
Taylor Gerring 已提交
683 684 685
	return id
}

686
// UninstallWhisperFilter disables and removes an existing filter.
T
Taylor Gerring 已提交
687
func (p *XEth) UninstallWhisperFilter(id int) bool {
688 689
	p.messagesMu.Lock()
	defer p.messagesMu.Unlock()
690

T
Taylor Gerring 已提交
691 692 693 694 695 696 697
	if _, ok := p.messages[id]; ok {
		delete(p.messages, id)
		return true
	}
	return false
}

698 699
// WhisperMessages retrieves all the known messages that match a specific filter.
func (self *XEth) WhisperMessages(id int) []WhisperMessage {
700 701
	self.messagesMu.RLock()
	defer self.messagesMu.RUnlock()
T
Taylor Gerring 已提交
702 703

	if self.messages[id] != nil {
704
		return self.messages[id].messages()
T
Taylor Gerring 已提交
705
	}
706 707 708
	return nil
}

709 710 711
// WhisperMessagesChanged retrieves all the new messages matched by a filter
// since the last retrieval
func (self *XEth) WhisperMessagesChanged(id int) []WhisperMessage {
712 713
	self.messagesMu.RLock()
	defer self.messagesMu.RUnlock()
T
Taylor Gerring 已提交
714

715
	if self.messages[id] != nil {
716
		return self.messages[id].retrieve()
717
	}
T
Taylor Gerring 已提交
718 719 720
	return nil
}

T
Taylor Gerring 已提交
721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753
// 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 已提交
754 755 756 757 758
type KeyVal struct {
	Key   string `json:"key"`
	Value string `json:"value"`
}

O
obscuren 已提交
759
func (self *XEth) EachStorage(addr string) string {
O
obscuren 已提交
760 761 762 763
	var values []KeyVal
	object := self.State().SafeGet(addr)
	it := object.Trie().Iterator()
	for it.Next() {
O
obscuren 已提交
764
		values = append(values, KeyVal{common.ToHex(object.Trie().GetKey(it.Key)), common.ToHex(it.Value)})
O
obscuren 已提交
765 766 767 768 769 770 771 772 773 774
	}

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

	return string(valuesJson)
}

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

778
	return "0x" + common.ToHex(padded)
O
obscuren 已提交
779 780
}

O
obscuren 已提交
781
func (self *XEth) FromAscii(str string) string {
O
obscuren 已提交
782
	if common.IsHex(str) {
O
obscuren 已提交
783 784 785
		str = str[2:]
	}

O
obscuren 已提交
786
	return string(bytes.Trim(common.FromHex(str), "\x00"))
O
obscuren 已提交
787 788
}

O
obscuren 已提交
789
func (self *XEth) FromNumber(str string) string {
O
obscuren 已提交
790
	if common.IsHex(str) {
O
obscuren 已提交
791 792 793
		str = str[2:]
	}

O
obscuren 已提交
794
	return common.BigD(common.FromHex(str)).String()
O
obscuren 已提交
795 796
}

O
obscuren 已提交
797
func (self *XEth) PushTx(encodedTx string) (string, error) {
O
obscuren 已提交
798
	tx := types.NewTransactionFromBytes(common.FromHex(encodedTx))
T
Taylor Gerring 已提交
799
	err := self.backend.TxPool().Add(tx)
O
obscuren 已提交
800 801 802 803 804 805
	if err != nil {
		return "", err
	}

	if tx.To() == nil {
		addr := core.AddressFromMessage(tx)
806
		glog.V(logger.Info).Infof("Tx(%x) created: %x\n", tx.Hash(), addr)
O
obscuren 已提交
807
		return addr.Hex(), nil
808 809
	} else {
		glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To())
O
obscuren 已提交
810
	}
811

O
obscuren 已提交
812
	return tx.Hash().Hex(), nil
O
obscuren 已提交
813
}
814

815
func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr string) (string, string, error) {
T
Taylor Gerring 已提交
816
	statedb := self.State().State().Copy()
817 818 819 820 821 822
	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 {
823
			from = statedb.GetOrNewStateObject(accounts[0].Address)
824 825 826 827 828
		}
	} else {
		from = statedb.GetOrNewStateObject(common.HexToAddress(fromStr))
	}

829
	from.SetBalance(common.MaxBig)
830
	from.SetGasLimit(self.backend.ChainManager().GasLimit())
831
	msg := callmsg{
832
		from:     from,
O
obscuren 已提交
833
		to:       common.HexToAddress(toStr),
O
obscuren 已提交
834 835 836 837
		gas:      common.Big(gasStr),
		gasPrice: common.Big(gasPriceStr),
		value:    common.Big(valueStr),
		data:     common.FromHex(dataStr),
838
	}
B
Bas van Kervel 已提交
839

840
	if msg.gas.Cmp(big.NewInt(0)) == 0 {
O
obscuren 已提交
841
		msg.gas = DefaultGas()
842 843 844
	}

	if msg.gasPrice.Cmp(big.NewInt(0)) == 0 {
Z
zsfelfoldi 已提交
845
		msg.gasPrice = self.DefaultGasPrice()
846 847
	}

848
	block := self.CurrentBlock()
T
Taylor Gerring 已提交
849
	vmenv := core.NewEnv(statedb, self.backend.ChainManager(), msg, block)
850

851 852
	res, gas, err := core.ApplyMessage(vmenv, msg, from)
	return common.ToHex(res), gas.String(), err
853 854
}

855 856 857 858
func (self *XEth) ConfirmTransaction(tx string) bool {
	return self.frontend.ConfirmTransaction(tx)
}

859
func (self *XEth) doSign(from common.Address, hash common.Hash, didUnlock bool) ([]byte, error) {
860
	sig, err := self.backend.AccountManager().Sign(accounts.Account{Address: from}, hash.Bytes())
D
Daniel A. Nagy 已提交
861 862
	if err == accounts.ErrLocked {
		if didUnlock {
863
			return nil, fmt.Errorf("signer account still locked after successful unlock")
D
Daniel A. Nagy 已提交
864 865
		}
		if !self.frontend.UnlockAccount(from.Bytes()) {
866
			return nil, fmt.Errorf("could not unlock signer account")
D
Daniel A. Nagy 已提交
867 868
		}
		// retry signing, the account should now be unlocked.
869
		return self.doSign(from, hash, true)
D
Daniel A. Nagy 已提交
870
	} else if err != nil {
871 872 873 874 875 876 877 878 879 880
		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)
	)
881
	sig, err := self.doSign(from, hash, didUnlock)
882
	if err != nil {
883
		return "", err
D
Daniel A. Nagy 已提交
884
	}
885
	return common.ToHex(sig), nil
D
Daniel A. Nagy 已提交
886 887
}

888
func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) {
889 890 891 892 893 894 895 896

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

897
	var (
O
obscuren 已提交
898 899
		from             = common.HexToAddress(fromStr)
		to               = common.HexToAddress(toStr)
O
obscuren 已提交
900
		value            = common.Big(valueStr)
901 902
		gas              *big.Int
		price            *big.Int
903 904 905 906
		data             []byte
		contractCreation bool
	)

907 908 909 910 911 912 913
	if len(gasStr) == 0 {
		gas = DefaultGas()
	} else {
		gas = common.Big(gasStr)
	}

	if len(gasPriceStr) == 0 {
Z
zsfelfoldi 已提交
914
		price = self.DefaultGasPrice()
915 916 917 918 919 920 921 922 923
	} else {
		price = common.Big(gasPriceStr)
	}

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

T
Taylor Gerring 已提交
924
	// 2015-05-18 Is this still needed?
T
Taylor Gerring 已提交
925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946
	// 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 已提交
947 948
	// TODO: align default values to have the same type, e.g. not depend on
	// common.Value conversions later on
949 950 951 952
	var nonce uint64
	if len(nonceStr) != 0 {
		nonce = common.Big(nonceStr).Uint64()
	} else {
953
		state := self.backend.TxPool().State()
954
		nonce = state.GetNonce(from)
955
	}
956 957 958 959 960 961
	var tx *types.Transaction
	if contractCreation {
		tx = types.NewContractCreation(nonce, value, gas, price, data)
	} else {
		tx = types.NewTransaction(nonce, to, value, gas, price, data)
	}
962

963 964
	signed, err := self.sign(tx, from, false)
	if err != nil {
965 966
		return "", err
	}
967
	if err = self.backend.TxPool().Add(signed); err != nil {
968 969
		return "", err
	}
970 971 972

	if contractCreation {
		addr := core.AddressFromMessage(tx)
O
obscuren 已提交
973
		glog.V(logger.Info).Infof("Tx(%x) created: %x\n", tx.Hash(), addr)
974
		return addr.Hex(), nil
O
obscuren 已提交
975 976
	} else {
		glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To())
977
	}
O
obscuren 已提交
978
	return tx.Hash().Hex(), nil
979
}
980

981
func (self *XEth) sign(tx *types.Transaction, from common.Address, didUnlock bool) (*types.Transaction, error) {
982
	hash := tx.Hash()
983 984
	sig, err := self.doSign(from, hash, didUnlock)
	if err != nil {
985
		return tx, err
986
	}
987
	return tx.WithSignature(sig)
988 989
}

990 991 992
// callmsg is the message type used for call transations.
type callmsg struct {
	from          *state.StateObject
O
obscuren 已提交
993
	to            common.Address
994 995 996 997 998 999
	gas, gasPrice *big.Int
	value         *big.Int
	data          []byte
}

// accessor boilerplate to implement core.Message
O
obscuren 已提交
1000 1001 1002 1003 1004 1005 1006
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 已提交
1007

1008
type logQueue struct {
T
Taylor Gerring 已提交
1009 1010 1011 1012 1013
	logs    state.Logs
	timeout time.Time
	id      int
}

1014
func (l *logQueue) add(logs ...*state.Log) {
T
Taylor Gerring 已提交
1015 1016 1017
	l.logs = append(l.logs, logs...)
}

1018
func (l *logQueue) get() state.Logs {
T
Taylor Gerring 已提交
1019 1020 1021 1022 1023
	l.timeout = time.Now()
	tmp := l.logs
	l.logs = nil
	return tmp
}
1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040

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
}