xeth.go 25.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
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
)

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

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

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

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

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

	blockMu    sync.RWMutex
	blockQueue map[int]*hashQueue

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

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

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

T
Taylor Gerring 已提交
70
	agent *miner.RemoteAgent
O
obscuren 已提交
71
}
O
obscuren 已提交
72

73 74 75 76 77 78 79
func NewTest(eth *eth.Ethereum, frontend Frontend) *XEth {
	return &XEth{
		backend:  eth,
		frontend: frontend,
	}
}

80 81 82
// 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.
83
func New(eth *eth.Ethereum, frontend Frontend) *XEth {
O
obscuren 已提交
84
	xeth := &XEth{
85 86 87 88 89 90 91 92 93
		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 已提交
94
	}
95 96 97
	if eth.Whisper() != nil {
		xeth.whisper = NewWhisper(eth.Whisper())
	}
98
	eth.Miner().Register(xeth.agent)
O
obscuren 已提交
99
	if frontend == nil {
100
		xeth.frontend = dummyFrontend{}
O
obscuren 已提交
101
	}
T
Taylor Gerring 已提交
102
	xeth.state = NewState(xeth, xeth.backend.ChainManager().TransState())
T
Shuffle  
Taylor Gerring 已提交
103

T
Taylor Gerring 已提交
104 105 106
	go xeth.start()
	go xeth.filterManager.Start()

O
obscuren 已提交
107 108 109
	return xeth
}

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

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

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

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

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

T
Taylor Gerring 已提交
182 183
func (self *XEth) AtStateNum(num int64) *XEth {
	var st *state.StateDB
O
obscuren 已提交
184 185 186 187 188 189 190 191 192
	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 已提交
193
	}
T
Taylor Gerring 已提交
194

195
	return self.WithState(st)
T
Taylor Gerring 已提交
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 221 222 223 224 225
// 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
}

226
func (self *XEth) WithState(statedb *state.StateDB) *XEth {
O
wip  
obscuren 已提交
227
	xeth := &XEth{
228 229
		backend:  self.backend,
		frontend: self.frontend,
O
wip  
obscuren 已提交
230 231 232 233 234
	}

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

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

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 271 272 273 274 275
// 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
}

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

T
Taylor Gerring 已提交
278 279 280
func (self *XEth) getBlockByHeight(height int64) *types.Block {
	var num uint64

O
obscuren 已提交
281 282 283 284 285 286 287 288 289 290
	switch height {
	case -2:
		return self.backend.Miner().PendingBlock()
	case -1:
		return self.CurrentBlock()
	default:
		if height < 0 {
			return nil
		}

T
Taylor Gerring 已提交
291 292 293 294 295 296
		num = uint64(height)
	}

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

O
obscuren 已提交
297
func (self *XEth) BlockByHash(strHash string) *Block {
O
obscuren 已提交
298
	hash := common.HexToHash(strHash)
T
Taylor Gerring 已提交
299
	block := self.backend.ChainManager().GetBlock(hash)
O
obscuren 已提交
300

O
obscuren 已提交
301
	return NewBlock(block)
O
obscuren 已提交
302 303
}

T
Taylor Gerring 已提交
304 305
func (self *XEth) EthBlockByHash(strHash string) *types.Block {
	hash := common.HexToHash(strHash)
T
Taylor Gerring 已提交
306
	block := self.backend.ChainManager().GetBlock(hash)
T
Taylor Gerring 已提交
307 308 309 310

	return block
}

311
func (self *XEth) EthTransactionByHash(hash string) (tx *types.Transaction, blhash common.Hash, blnum *big.Int, txi uint64) {
T
Taylor Gerring 已提交
312 313
	// 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 已提交
314
	data, _ := self.backend.ExtraDb().Get(common.FromHex(hash))
O
obscuren 已提交
315
	if len(data) != 0 {
316
		tx = types.NewTransactionFromBytes(data)
317 318
	} else { // check pending transactions
		tx = self.backend.TxPool().GetTransaction(common.HexToHash(hash))
O
obscuren 已提交
319
	}
320

T
Taylor Gerring 已提交
321 322 323
	// meta
	var txExtra struct {
		BlockHash  common.Hash
T
Taylor Gerring 已提交
324
		BlockIndex uint64
T
Taylor Gerring 已提交
325
		Index      uint64
326
	}
T
Taylor Gerring 已提交
327

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

	return
O
obscuren 已提交
344 345
}

T
Taylor Gerring 已提交
346
func (self *XEth) BlockByNumber(num int64) *Block {
T
Taylor Gerring 已提交
347
	return NewBlock(self.getBlockByHeight(num))
O
obscuren 已提交
348 349
}

T
Taylor Gerring 已提交
350
func (self *XEth) EthBlockByNumber(num int64) *types.Block {
T
Taylor Gerring 已提交
351
	return self.getBlockByHeight(num)
T
Taylor Gerring 已提交
352 353
}

T
Taylor Gerring 已提交
354 355 356 357
func (self *XEth) CurrentBlock() *types.Block {
	return self.backend.ChainManager().CurrentBlock()
}

Z
zsfelfoldi 已提交
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
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
}

376 377 378 379
func (self *XEth) GasLimit() *big.Int {
	return self.backend.ChainManager().GasLimit()
}

O
obscuren 已提交
380
func (self *XEth) Block(v interface{}) *Block {
O
obscuren 已提交
381
	if n, ok := v.(int32); ok {
T
Taylor Gerring 已提交
382
		return self.BlockByNumber(int64(n))
O
obscuren 已提交
383 384
	} else if str, ok := v.(string); ok {
		return self.BlockByHash(str)
T
Taylor Gerring 已提交
385
	} else if f, ok := v.(float64); ok { // JSON numbers are represented as float64
T
Taylor Gerring 已提交
386
		return self.BlockByNumber(int64(f))
O
obscuren 已提交
387 388 389 390 391
	}

	return nil
}

O
obscuren 已提交
392
func (self *XEth) Accounts() []string {
393
	// TODO: check err?
T
Taylor Gerring 已提交
394
	accounts, _ := self.backend.AccountManager().Accounts()
395 396
	accountAddresses := make([]string, len(accounts))
	for i, ac := range accounts {
397
		accountAddresses[i] = ac.Address.Hex()
398 399
	}
	return accountAddresses
O
obscuren 已提交
400 401
}

402 403 404
// accessor for solidity compiler.
// memoized if available, retried on-demand if not
func (self *XEth) Solc() (*compiler.Solidity, error) {
405
	return self.backend.Solc()
406 407 408 409
}

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

414
// store DApp value in extra database
415
func (self *XEth) DbPut(key, val []byte) bool {
416
	self.backend.ExtraDb().Put(append(dappStorePre, key...), val)
417 418 419
	return true
}

420
// retrieve DApp value from extra database
421
func (self *XEth) DbGet(key []byte) ([]byte, error) {
422
	val, err := self.backend.ExtraDb().Get(append(dappStorePre, key...))
423 424 425
	return val, err
}

O
obscuren 已提交
426
func (self *XEth) PeerCount() int {
T
Taylor Gerring 已提交
427
	return self.backend.PeerCount()
O
obscuren 已提交
428 429
}

O
obscuren 已提交
430
func (self *XEth) IsMining() bool {
T
Taylor Gerring 已提交
431
	return self.backend.IsMining()
O
obscuren 已提交
432 433
}

K
Kobi Gurkan 已提交
434
func (self *XEth) HashRate() int64 {
435
	return self.backend.Miner().HashRate()
K
Kobi Gurkan 已提交
436 437
}

438
func (self *XEth) EthVersion() string {
439
	return fmt.Sprintf("%d", self.backend.EthVersion())
440 441
}

T
Taylor Gerring 已提交
442
func (self *XEth) NetworkVersion() string {
443
	return fmt.Sprintf("%d", self.backend.NetVersion())
444 445 446
}

func (self *XEth) WhisperVersion() string {
447
	return fmt.Sprintf("%d", self.backend.ShhVersion())
T
Taylor Gerring 已提交
448 449 450
}

func (self *XEth) ClientVersion() string {
451
	return self.backend.ClientVersion()
T
Taylor Gerring 已提交
452 453
}

454
func (self *XEth) SetMining(shouldmine bool, threads int) bool {
T
Taylor Gerring 已提交
455
	ismining := self.backend.IsMining()
T
Taylor Gerring 已提交
456
	if shouldmine && !ismining {
457
		err := self.backend.StartMining(threads)
458
		return err == nil
T
Taylor Gerring 已提交
459 460
	}
	if ismining && !shouldmine {
T
Taylor Gerring 已提交
461
		self.backend.StopMining()
T
Taylor Gerring 已提交
462
	}
T
Taylor Gerring 已提交
463
	return self.backend.IsMining()
T
Taylor Gerring 已提交
464 465
}

O
obscuren 已提交
466
func (self *XEth) IsListening() bool {
T
Taylor Gerring 已提交
467
	return self.backend.IsListening()
O
obscuren 已提交
468 469
}

O
obscuren 已提交
470
func (self *XEth) Coinbase() string {
Z
zelig 已提交
471 472
	eb, _ := self.backend.Etherbase()
	return eb.Hex()
O
obscuren 已提交
473 474
}

O
obscuren 已提交
475
func (self *XEth) NumberToHuman(balance string) string {
O
obscuren 已提交
476
	b := common.Big(balance)
O
obscuren 已提交
477

O
obscuren 已提交
478
	return common.CurrencyToString(b)
O
obscuren 已提交
479 480
}

O
obscuren 已提交
481
func (self *XEth) StorageAt(addr, storageAddr string) string {
482
	return common.ToHex(self.State().state.GetState(common.HexToAddress(addr), common.HexToHash(storageAddr)))
O
obscuren 已提交
483 484
}

O
obscuren 已提交
485
func (self *XEth) BalanceAt(addr string) string {
O
obscuren 已提交
486
	return common.ToHex(self.State().state.GetBalance(common.HexToAddress(addr)).Bytes())
O
obscuren 已提交
487 488
}

O
obscuren 已提交
489
func (self *XEth) TxCountAt(address string) int {
490
	return int(self.State().state.GetNonce(common.HexToAddress(address)))
O
obscuren 已提交
491 492
}

O
obscuren 已提交
493
func (self *XEth) CodeAt(address string) string {
494
	return common.ToHex(self.State().state.GetCode(common.HexToAddress(address)))
O
obscuren 已提交
495 496
}

T
Taylor Gerring 已提交
497 498 499 500
func (self *XEth) CodeAtBytes(address string) []byte {
	return self.State().SafeGet(address).Code()
}

O
obscuren 已提交
501
func (self *XEth) IsContract(address string) bool {
502
	return len(self.State().SafeGet(address).Code()) > 0
O
obscuren 已提交
503 504
}

O
obscuren 已提交
505
func (self *XEth) SecretToAddress(key string) string {
O
obscuren 已提交
506
	pair, err := crypto.NewKeyPairFromSec(common.FromHex(key))
O
obscuren 已提交
507 508 509 510
	if err != nil {
		return ""
	}

511
	return common.ToHex(pair.Address())
O
obscuren 已提交
512 513
}

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

552
		self.logQueue[id].add(logs...)
T
Taylor Gerring 已提交
553 554
	}
	id = self.filterManager.InstallFilter(filter)
555
	self.logQueue[id] = &logQueue{timeout: time.Now()}
T
Taylor Gerring 已提交
556 557 558 559

	return id
}

560 561 562 563 564 565
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 已提交
566

567 568 569 570 571
		self.transactionQueue[id].add(tx.Hash())
	}
	id = self.filterManager.InstallFilter(filter)
	self.transactionQueue[id] = &hashQueue{timeout: time.Now()}
	return id
T
Taylor Gerring 已提交
572 573
}

574
func (self *XEth) NewBlockFilter() int {
T
Taylor Gerring 已提交
575
	var id int
T
Taylor Gerring 已提交
576
	filter := core.NewFilter(self.backend)
577 578 579
	filter.BlockCallback = func(block *types.Block, logs state.Logs) {
		self.blockMu.Lock()
		defer self.blockMu.Unlock()
T
Taylor Gerring 已提交
580

581 582 583 584 585 586
		self.blockQueue[id].add(block.Hash())
	}
	id = self.filterManager.InstallFilter(filter)
	self.blockQueue[id] = &hashQueue{timeout: time.Now()}
	return id
}
587

588 589 590 591 592 593 594
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 已提交
595 596
	}

597 598
	return UnknownFilterTy
}
T
Taylor Gerring 已提交
599

600 601 602 603 604 605 606 607
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 已提交
608 609
}

610 611 612
func (self *XEth) BlockFilterChanged(id int) []common.Hash {
	self.blockMu.Lock()
	defer self.blockMu.Unlock()
T
Taylor Gerring 已提交
613

614 615
	if self.blockQueue[id] != nil {
		return self.blockQueue[id].get()
T
Taylor Gerring 已提交
616
	}
617 618 619 620 621 622
	return nil
}

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

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

func (self *XEth) Logs(id int) state.Logs {
631 632
	self.logMu.Lock()
	defer self.logMu.Unlock()
T
Taylor Gerring 已提交
633 634 635 636 637 638 639 640 641

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

	return nil
}

T
Taylor Gerring 已提交
642
func (self *XEth) AllLogs(earliest, latest int64, skip, max int, address []string, topics [][]string) state.Logs {
T
Taylor Gerring 已提交
643
	filter := core.NewFilter(self.backend)
T
Taylor Gerring 已提交
644 645 646 647 648 649
	filter.SetEarliestBlock(earliest)
	filter.SetLatestBlock(latest)
	filter.SetSkip(skip)
	filter.SetMax(max)
	filter.SetAddress(cAddress(address))
	filter.SetTopics(cTopics(topics))
T
Taylor Gerring 已提交
650 651 652 653

	return filter.Find()
}

654 655 656
// 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.
657
func (p *XEth) NewWhisperFilter(to, from string, topics [][]string) int {
658
	// Pre-define the id to be filled later
T
Taylor Gerring 已提交
659
	var id int
660

661 662
	// Callback to delegate core whisper messages to this xeth filter
	callback := func(msg WhisperMessage) {
663 664
		p.messagesMu.RLock() // Only read lock to the filter pool
		defer p.messagesMu.RUnlock()
665
		p.messages[id].insert(msg)
T
Taylor Gerring 已提交
666
	}
667
	// Initialize the core whisper filter and wrap into xeth
668
	id = p.Whisper().Watch(to, from, topics, callback)
669

670
	p.messagesMu.Lock()
671
	p.messages[id] = newWhisperFilter(id, p.Whisper())
672
	p.messagesMu.Unlock()
673

T
Taylor Gerring 已提交
674 675 676
	return id
}

677
// UninstallWhisperFilter disables and removes an existing filter.
T
Taylor Gerring 已提交
678
func (p *XEth) UninstallWhisperFilter(id int) bool {
679 680
	p.messagesMu.Lock()
	defer p.messagesMu.Unlock()
681

T
Taylor Gerring 已提交
682 683 684 685 686 687 688
	if _, ok := p.messages[id]; ok {
		delete(p.messages, id)
		return true
	}
	return false
}

689 690
// WhisperMessages retrieves all the known messages that match a specific filter.
func (self *XEth) WhisperMessages(id int) []WhisperMessage {
691 692
	self.messagesMu.RLock()
	defer self.messagesMu.RUnlock()
T
Taylor Gerring 已提交
693 694

	if self.messages[id] != nil {
695
		return self.messages[id].messages()
T
Taylor Gerring 已提交
696
	}
697 698 699
	return nil
}

700 701 702
// WhisperMessagesChanged retrieves all the new messages matched by a filter
// since the last retrieval
func (self *XEth) WhisperMessagesChanged(id int) []WhisperMessage {
703 704
	self.messagesMu.RLock()
	defer self.messagesMu.RUnlock()
T
Taylor Gerring 已提交
705

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

T
Taylor Gerring 已提交
712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744
// 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 已提交
745 746 747 748 749
type KeyVal struct {
	Key   string `json:"key"`
	Value string `json:"value"`
}

O
obscuren 已提交
750
func (self *XEth) EachStorage(addr string) string {
O
obscuren 已提交
751 752 753 754
	var values []KeyVal
	object := self.State().SafeGet(addr)
	it := object.Trie().Iterator()
	for it.Next() {
O
obscuren 已提交
755
		values = append(values, KeyVal{common.ToHex(object.Trie().GetKey(it.Key)), common.ToHex(it.Value)})
O
obscuren 已提交
756 757 758 759 760 761 762 763 764 765
	}

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

	return string(valuesJson)
}

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

769
	return "0x" + common.ToHex(padded)
O
obscuren 已提交
770 771
}

O
obscuren 已提交
772
func (self *XEth) FromAscii(str string) string {
O
obscuren 已提交
773
	if common.IsHex(str) {
O
obscuren 已提交
774 775 776
		str = str[2:]
	}

O
obscuren 已提交
777
	return string(bytes.Trim(common.FromHex(str), "\x00"))
O
obscuren 已提交
778 779
}

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

O
obscuren 已提交
785
	return common.BigD(common.FromHex(str)).String()
O
obscuren 已提交
786 787
}

O
obscuren 已提交
788
func (self *XEth) PushTx(encodedTx string) (string, error) {
O
obscuren 已提交
789
	tx := types.NewTransactionFromBytes(common.FromHex(encodedTx))
T
Taylor Gerring 已提交
790
	err := self.backend.TxPool().Add(tx)
O
obscuren 已提交
791 792 793 794 795 796
	if err != nil {
		return "", err
	}

	if tx.To() == nil {
		addr := core.AddressFromMessage(tx)
O
obscuren 已提交
797
		return addr.Hex(), nil
O
obscuren 已提交
798
	}
O
obscuren 已提交
799
	return tx.Hash().Hex(), nil
O
obscuren 已提交
800
}
801

802
func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr string) (string, string, error) {
T
Taylor Gerring 已提交
803
	statedb := self.State().State().Copy()
804 805 806 807 808 809
	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 {
810
			from = statedb.GetOrNewStateObject(accounts[0].Address)
811 812 813 814 815
		}
	} else {
		from = statedb.GetOrNewStateObject(common.HexToAddress(fromStr))
	}

816
	from.SetBalance(common.MaxBig)
817
	from.SetGasPool(self.backend.ChainManager().GasLimit())
818
	msg := callmsg{
819
		from:     from,
O
obscuren 已提交
820
		to:       common.HexToAddress(toStr),
O
obscuren 已提交
821 822 823 824
		gas:      common.Big(gasStr),
		gasPrice: common.Big(gasPriceStr),
		value:    common.Big(valueStr),
		data:     common.FromHex(dataStr),
825
	}
B
Bas van Kervel 已提交
826

827
	if msg.gas.Cmp(big.NewInt(0)) == 0 {
O
obscuren 已提交
828
		msg.gas = DefaultGas()
829 830 831
	}

	if msg.gasPrice.Cmp(big.NewInt(0)) == 0 {
O
obscuren 已提交
832
		msg.gasPrice = DefaultGasPrice()
833 834
	}

835
	block := self.CurrentBlock()
T
Taylor Gerring 已提交
836
	vmenv := core.NewEnv(statedb, self.backend.ChainManager(), msg, block)
837

838 839
	res, gas, err := core.ApplyMessage(vmenv, msg, from)
	return common.ToHex(res), gas.String(), err
840 841
}

842 843 844 845
func (self *XEth) ConfirmTransaction(tx string) bool {
	return self.frontend.ConfirmTransaction(tx)
}

846
func (self *XEth) doSign(from common.Address, hash common.Hash, didUnlock bool) ([]byte, error) {
847
	sig, err := self.backend.AccountManager().Sign(accounts.Account{Address: from}, hash.Bytes())
D
Daniel A. Nagy 已提交
848 849
	if err == accounts.ErrLocked {
		if didUnlock {
850
			return nil, fmt.Errorf("signer account still locked after successful unlock")
D
Daniel A. Nagy 已提交
851 852
		}
		if !self.frontend.UnlockAccount(from.Bytes()) {
853
			return nil, fmt.Errorf("could not unlock signer account")
D
Daniel A. Nagy 已提交
854 855
		}
		// retry signing, the account should now be unlocked.
856
		return self.doSign(from, hash, true)
D
Daniel A. Nagy 已提交
857
	} else if err != nil {
858 859 860 861 862 863 864 865 866 867
		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)
	)
868
	sig, err := self.doSign(from, hash, didUnlock)
869
	if err != nil {
870
		return "", err
D
Daniel A. Nagy 已提交
871
	}
872
	return common.ToHex(sig), nil
D
Daniel A. Nagy 已提交
873 874
}

875
func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) {
876 877 878 879 880 881 882 883

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

884
	var (
O
obscuren 已提交
885 886
		from             = common.HexToAddress(fromStr)
		to               = common.HexToAddress(toStr)
O
obscuren 已提交
887
		value            = common.Big(valueStr)
888 889
		gas              *big.Int
		price            *big.Int
890 891 892 893
		data             []byte
		contractCreation bool
	)

894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910
	if len(gasStr) == 0 {
		gas = DefaultGas()
	} else {
		gas = common.Big(gasStr)
	}

	if len(gasPriceStr) == 0 {
		price = DefaultGasPrice()
	} else {
		price = common.Big(gasPriceStr)
	}

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

T
Taylor Gerring 已提交
911
	// 2015-05-18 Is this still needed?
T
Taylor Gerring 已提交
912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933
	// 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 已提交
934 935
	// TODO: align default values to have the same type, e.g. not depend on
	// common.Value conversions later on
936 937 938

	var tx *types.Transaction
	if contractCreation {
O
obscuren 已提交
939
		tx = types.NewContractCreationTx(value, gas, price, data)
940
	} else {
O
obscuren 已提交
941
		tx = types.NewTransactionMessage(to, value, gas, price, data)
942 943
	}

944
	state := self.backend.TxPool().State()
945 946 947 948 949

	var nonce uint64
	if len(nonceStr) != 0 {
		nonce = common.Big(nonceStr).Uint64()
	} else {
950
		nonce = state.GetNonce(from)
951
	}
952 953
	tx.SetNonce(nonce)

954
	if err := self.sign(tx, from, false); err != nil {
955 956
		return "", err
	}
T
Taylor Gerring 已提交
957
	if err := self.backend.TxPool().Add(tx); err != nil {
958 959
		return "", err
	}
960
	//state.SetNonce(from, nonce+1)
961 962 963

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

O
obscuren 已提交
966
		return core.AddressFromMessage(tx).Hex(), nil
O
obscuren 已提交
967
	} else {
S
SilentCicero 已提交
968
		glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To())
969
	}
O
obscuren 已提交
970
	return tx.Hash().Hex(), nil
971
}
972

O
obscuren 已提交
973
func (self *XEth) sign(tx *types.Transaction, from common.Address, didUnlock bool) error {
974
	hash := tx.Hash()
975 976
	sig, err := self.doSign(from, hash, didUnlock)
	if err != nil {
977 978 979 980 981 982
		return err
	}
	tx.SetSignatureValues(sig)
	return nil
}

983 984 985
// callmsg is the message type used for call transations.
type callmsg struct {
	from          *state.StateObject
O
obscuren 已提交
986
	to            common.Address
987 988 989 990 991 992
	gas, gasPrice *big.Int
	value         *big.Int
	data          []byte
}

// accessor boilerplate to implement core.Message
O
obscuren 已提交
993 994 995 996 997 998 999
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 已提交
1000

1001
type logQueue struct {
T
Taylor Gerring 已提交
1002 1003 1004 1005 1006
	logs    state.Logs
	timeout time.Time
	id      int
}

1007
func (l *logQueue) add(logs ...*state.Log) {
T
Taylor Gerring 已提交
1008 1009 1010
	l.logs = append(l.logs, logs...)
}

1011
func (l *logQueue) get() state.Logs {
T
Taylor Gerring 已提交
1012 1013 1014 1015 1016
	l.timeout = time.Now()
	tmp := l.logs
	l.logs = nil
	return tmp
}
1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033

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
}