xeth.go 21.3 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"
O
obscuren 已提交
14
	"github.com/ethereum/go-ethereum/core"
T
Taylor Gerring 已提交
15
	"github.com/ethereum/go-ethereum/core/state"
O
obscuren 已提交
16 17
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/crypto"
18
	"github.com/ethereum/go-ethereum/eth"
T
Taylor Gerring 已提交
19
	"github.com/ethereum/go-ethereum/event/filter"
O
obscuren 已提交
20
	"github.com/ethereum/go-ethereum/logger"
O
obscuren 已提交
21
	"github.com/ethereum/go-ethereum/logger/glog"
22
	"github.com/ethereum/go-ethereum/miner"
T
Taylor Gerring 已提交
23
	"github.com/ethereum/go-ethereum/rlp"
O
obscuren 已提交
24
)
O
obscuren 已提交
25

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

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

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

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

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

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

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

	blockMu    sync.RWMutex
	blockQueue map[int]*hashQueue

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

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

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

T
Taylor Gerring 已提交
68
	agent *miner.RemoteAgent
O
obscuren 已提交
69
}
O
obscuren 已提交
70

71 72 73
// 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.
74
func New(eth *eth.Ethereum, frontend Frontend) *XEth {
O
obscuren 已提交
75
	xeth := &XEth{
76 77 78 79 80 81 82 83 84 85
		backend:          eth,
		frontend:         frontend,
		whisper:          NewWhisper(eth.Whisper()),
		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 已提交
86
	}
87 88
	eth.Miner().Register(xeth.agent)

O
obscuren 已提交
89
	if frontend == nil {
90
		xeth.frontend = dummyFrontend{}
O
obscuren 已提交
91
	}
T
Taylor Gerring 已提交
92
	xeth.state = NewState(xeth, xeth.backend.ChainManager().TransState())
T
Shuffle  
Taylor Gerring 已提交
93

T
Taylor Gerring 已提交
94 95 96
	go xeth.start()
	go xeth.filterManager.Start()

O
obscuren 已提交
97 98 99
	return xeth
}

T
Taylor Gerring 已提交
100 101 102 103 104 105
func (self *XEth) start() {
	timer := time.NewTicker(2 * time.Second)
done:
	for {
		select {
		case <-timer.C:
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
			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 已提交
126 127
				if time.Since(filter.timeout) > filterTickerTime {
					self.filterManager.UninstallFilter(id)
128
					delete(self.transactionQueue, id)
T
Taylor Gerring 已提交
129 130
				}
			}
131
			self.transactionMu.Unlock()
T
Taylor Gerring 已提交
132

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

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

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

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

T
Taylor Gerring 已提交
172 173
func (self *XEth) AtStateNum(num int64) *XEth {
	var st *state.StateDB
O
obscuren 已提交
174 175 176 177 178 179 180 181 182
	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 已提交
183
	}
T
Taylor Gerring 已提交
184

185
	return self.WithState(st)
T
Taylor Gerring 已提交
186 187
}

188
func (self *XEth) WithState(statedb *state.StateDB) *XEth {
O
wip  
obscuren 已提交
189
	xeth := &XEth{
T
Taylor Gerring 已提交
190
		backend: self.backend,
O
wip  
obscuren 已提交
191 192 193 194 195
	}

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

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

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

T
Taylor Gerring 已提交
201 202 203
func (self *XEth) getBlockByHeight(height int64) *types.Block {
	var num uint64

O
obscuren 已提交
204 205 206 207 208 209 210 211 212 213
	switch height {
	case -2:
		return self.backend.Miner().PendingBlock()
	case -1:
		return self.CurrentBlock()
	default:
		if height < 0 {
			return nil
		}

T
Taylor Gerring 已提交
214 215 216 217 218 219
		num = uint64(height)
	}

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

O
obscuren 已提交
220
func (self *XEth) BlockByHash(strHash string) *Block {
O
obscuren 已提交
221
	hash := common.HexToHash(strHash)
T
Taylor Gerring 已提交
222
	block := self.backend.ChainManager().GetBlock(hash)
O
obscuren 已提交
223

O
obscuren 已提交
224
	return NewBlock(block)
O
obscuren 已提交
225 226
}

T
Taylor Gerring 已提交
227 228
func (self *XEth) EthBlockByHash(strHash string) *types.Block {
	hash := common.HexToHash(strHash)
T
Taylor Gerring 已提交
229
	block := self.backend.ChainManager().GetBlock(hash)
T
Taylor Gerring 已提交
230 231 232 233

	return block
}

234
func (self *XEth) EthTransactionByHash(hash string) (tx *types.Transaction, blhash common.Hash, blnum *big.Int, txi uint64) {
T
Taylor Gerring 已提交
235
	data, _ := self.backend.ExtraDb().Get(common.FromHex(hash))
O
obscuren 已提交
236
	if len(data) != 0 {
237
		tx = types.NewTransactionFromBytes(data)
O
obscuren 已提交
238
	}
239

T
Taylor Gerring 已提交
240 241 242
	// meta
	var txExtra struct {
		BlockHash  common.Hash
T
Taylor Gerring 已提交
243
		BlockIndex uint64
T
Taylor Gerring 已提交
244
		Index      uint64
245
	}
T
Taylor Gerring 已提交
246 247 248 249 250 251

	v, _ := self.backend.ExtraDb().Get(append(common.FromHex(hash), 0x0001))
	r := bytes.NewReader(v)
	err := rlp.Decode(r, &txExtra)
	if err == nil {
		blhash = txExtra.BlockHash
T
Taylor Gerring 已提交
252
		blnum = big.NewInt(int64(txExtra.BlockIndex))
T
Taylor Gerring 已提交
253
		txi = txExtra.Index
T
Taylor Gerring 已提交
254
	} else {
O
obscuren 已提交
255
		glog.V(logger.Error).Infoln(err)
256 257 258
	}

	return
O
obscuren 已提交
259 260
}

T
Taylor Gerring 已提交
261
func (self *XEth) BlockByNumber(num int64) *Block {
T
Taylor Gerring 已提交
262
	return NewBlock(self.getBlockByHeight(num))
O
obscuren 已提交
263 264
}

T
Taylor Gerring 已提交
265
func (self *XEth) EthBlockByNumber(num int64) *types.Block {
T
Taylor Gerring 已提交
266
	return self.getBlockByHeight(num)
T
Taylor Gerring 已提交
267 268
}

T
Taylor Gerring 已提交
269 270 271 272
func (self *XEth) CurrentBlock() *types.Block {
	return self.backend.ChainManager().CurrentBlock()
}

273 274 275 276
func (self *XEth) GasLimit() *big.Int {
	return self.backend.ChainManager().GasLimit()
}

O
obscuren 已提交
277
func (self *XEth) Block(v interface{}) *Block {
O
obscuren 已提交
278
	if n, ok := v.(int32); ok {
T
Taylor Gerring 已提交
279
		return self.BlockByNumber(int64(n))
O
obscuren 已提交
280 281 282
	} else if str, ok := v.(string); ok {
		return self.BlockByHash(str)
	} else if f, ok := v.(float64); ok { // Don't ask ...
T
Taylor Gerring 已提交
283
		return self.BlockByNumber(int64(f))
O
obscuren 已提交
284 285 286 287 288
	}

	return nil
}

O
obscuren 已提交
289
func (self *XEth) Accounts() []string {
290
	// TODO: check err?
T
Taylor Gerring 已提交
291
	accounts, _ := self.backend.AccountManager().Accounts()
292 293
	accountAddresses := make([]string, len(accounts))
	for i, ac := range accounts {
294
		accountAddresses[i] = common.ToHex(ac.Address)
295 296
	}
	return accountAddresses
O
obscuren 已提交
297 298
}

299 300 301 302 303 304 305 306 307 308
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 已提交
309
func (self *XEth) PeerCount() int {
T
Taylor Gerring 已提交
310
	return self.backend.PeerCount()
O
obscuren 已提交
311 312
}

O
obscuren 已提交
313
func (self *XEth) IsMining() bool {
T
Taylor Gerring 已提交
314
	return self.backend.IsMining()
O
obscuren 已提交
315 316
}

K
Kobi Gurkan 已提交
317
func (self *XEth) HashRate() int64 {
318
	return self.backend.Miner().HashRate()
K
Kobi Gurkan 已提交
319 320
}

321
func (self *XEth) EthVersion() string {
322
	return fmt.Sprintf("%d", self.backend.EthVersion())
323 324
}

T
Taylor Gerring 已提交
325
func (self *XEth) NetworkVersion() string {
326
	return fmt.Sprintf("%d", self.backend.NetVersion())
327 328 329
}

func (self *XEth) WhisperVersion() string {
330
	return fmt.Sprintf("%d", self.backend.ShhVersion())
T
Taylor Gerring 已提交
331 332 333
}

func (self *XEth) ClientVersion() string {
334
	return self.backend.ClientVersion()
T
Taylor Gerring 已提交
335 336
}

T
Taylor Gerring 已提交
337
func (self *XEth) SetMining(shouldmine bool) bool {
T
Taylor Gerring 已提交
338
	ismining := self.backend.IsMining()
T
Taylor Gerring 已提交
339
	if shouldmine && !ismining {
T
Taylor Gerring 已提交
340
		err := self.backend.StartMining()
341
		return err == nil
T
Taylor Gerring 已提交
342 343
	}
	if ismining && !shouldmine {
T
Taylor Gerring 已提交
344
		self.backend.StopMining()
T
Taylor Gerring 已提交
345
	}
T
Taylor Gerring 已提交
346
	return self.backend.IsMining()
T
Taylor Gerring 已提交
347 348
}

O
obscuren 已提交
349
func (self *XEth) IsListening() bool {
T
Taylor Gerring 已提交
350
	return self.backend.IsListening()
O
obscuren 已提交
351 352
}

O
obscuren 已提交
353
func (self *XEth) Coinbase() string {
Z
zelig 已提交
354 355
	eb, _ := self.backend.Etherbase()
	return eb.Hex()
O
obscuren 已提交
356 357
}

O
obscuren 已提交
358
func (self *XEth) NumberToHuman(balance string) string {
O
obscuren 已提交
359
	b := common.Big(balance)
O
obscuren 已提交
360

O
obscuren 已提交
361
	return common.CurrencyToString(b)
O
obscuren 已提交
362 363
}

O
obscuren 已提交
364
func (self *XEth) StorageAt(addr, storageAddr string) string {
365
	return common.ToHex(self.State().state.GetState(common.HexToAddress(addr), common.HexToHash(storageAddr)))
O
obscuren 已提交
366 367
}

O
obscuren 已提交
368
func (self *XEth) BalanceAt(addr string) string {
O
obscuren 已提交
369
	return common.ToHex(self.State().state.GetBalance(common.HexToAddress(addr)).Bytes())
O
obscuren 已提交
370 371
}

O
obscuren 已提交
372
func (self *XEth) TxCountAt(address string) int {
373
	return int(self.State().state.GetNonce(common.HexToAddress(address)))
O
obscuren 已提交
374 375
}

O
obscuren 已提交
376
func (self *XEth) CodeAt(address string) string {
377
	return common.ToHex(self.State().state.GetCode(common.HexToAddress(address)))
O
obscuren 已提交
378 379
}

T
Taylor Gerring 已提交
380 381 382 383
func (self *XEth) CodeAtBytes(address string) []byte {
	return self.State().SafeGet(address).Code()
}

O
obscuren 已提交
384
func (self *XEth) IsContract(address string) bool {
385
	return len(self.State().SafeGet(address).Code()) > 0
O
obscuren 已提交
386 387
}

O
obscuren 已提交
388
func (self *XEth) SecretToAddress(key string) string {
O
obscuren 已提交
389
	pair, err := crypto.NewKeyPairFromSec(common.FromHex(key))
O
obscuren 已提交
390 391 392 393
	if err != nil {
		return ""
	}

394
	return common.ToHex(pair.Address())
O
obscuren 已提交
395 396
}

397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422
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 已提交
423
	var id int
T
Taylor Gerring 已提交
424
	filter := core.NewFilter(self.backend)
T
Taylor Gerring 已提交
425 426 427 428 429 430
	filter.SetEarliestBlock(earliest)
	filter.SetLatestBlock(latest)
	filter.SetSkip(skip)
	filter.SetMax(max)
	filter.SetAddress(cAddress(address))
	filter.SetTopics(cTopics(topics))
T
Taylor Gerring 已提交
431
	filter.LogsCallback = func(logs state.Logs) {
432 433
		self.logMu.Lock()
		defer self.logMu.Unlock()
T
Taylor Gerring 已提交
434

435
		self.logQueue[id].add(logs...)
T
Taylor Gerring 已提交
436 437
	}
	id = self.filterManager.InstallFilter(filter)
438
	self.logQueue[id] = &logQueue{timeout: time.Now()}
T
Taylor Gerring 已提交
439 440 441 442

	return id
}

443 444 445 446 447 448
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 已提交
449

450 451 452 453 454
		self.transactionQueue[id].add(tx.Hash())
	}
	id = self.filterManager.InstallFilter(filter)
	self.transactionQueue[id] = &hashQueue{timeout: time.Now()}
	return id
T
Taylor Gerring 已提交
455 456
}

457
func (self *XEth) NewBlockFilter() int {
T
Taylor Gerring 已提交
458
	var id int
T
Taylor Gerring 已提交
459
	filter := core.NewFilter(self.backend)
460 461 462
	filter.BlockCallback = func(block *types.Block, logs state.Logs) {
		self.blockMu.Lock()
		defer self.blockMu.Unlock()
T
Taylor Gerring 已提交
463

464 465 466 467 468 469
		self.blockQueue[id].add(block.Hash())
	}
	id = self.filterManager.InstallFilter(filter)
	self.blockQueue[id] = &hashQueue{timeout: time.Now()}
	return id
}
470

471 472 473 474 475 476 477
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 已提交
478 479
	}

480 481
	return UnknownFilterTy
}
T
Taylor Gerring 已提交
482

483 484 485 486 487 488 489 490
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 已提交
491 492
}

493 494 495
func (self *XEth) BlockFilterChanged(id int) []common.Hash {
	self.blockMu.Lock()
	defer self.blockMu.Unlock()
T
Taylor Gerring 已提交
496

497 498
	if self.blockQueue[id] != nil {
		return self.blockQueue[id].get()
T
Taylor Gerring 已提交
499
	}
500 501 502 503 504 505
	return nil
}

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

507
	if self.transactionQueue[id] != nil {
508 509
		return self.transactionQueue[id].get()
	}
T
Taylor Gerring 已提交
510 511 512 513
	return nil
}

func (self *XEth) Logs(id int) state.Logs {
514 515
	self.logMu.Lock()
	defer self.logMu.Unlock()
T
Taylor Gerring 已提交
516 517 518 519 520 521 522 523 524

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

	return nil
}

T
Taylor Gerring 已提交
525
func (self *XEth) AllLogs(earliest, latest int64, skip, max int, address []string, topics [][]string) state.Logs {
T
Taylor Gerring 已提交
526
	filter := core.NewFilter(self.backend)
T
Taylor Gerring 已提交
527 528 529 530 531 532
	filter.SetEarliestBlock(earliest)
	filter.SetLatestBlock(latest)
	filter.SetSkip(skip)
	filter.SetMax(max)
	filter.SetAddress(cAddress(address))
	filter.SetTopics(cTopics(topics))
T
Taylor Gerring 已提交
533 534 535 536

	return filter.Find()
}

537 538 539
// 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.
540
func (p *XEth) NewWhisperFilter(to, from string, topics [][]string) int {
541
	// Pre-define the id to be filled later
T
Taylor Gerring 已提交
542
	var id int
543

544 545
	// Callback to delegate core whisper messages to this xeth filter
	callback := func(msg WhisperMessage) {
546 547
		p.messagesMu.RLock() // Only read lock to the filter pool
		defer p.messagesMu.RUnlock()
548
		p.messages[id].insert(msg)
T
Taylor Gerring 已提交
549
	}
550
	// Initialize the core whisper filter and wrap into xeth
551
	id = p.Whisper().Watch(to, from, topics, callback)
552

553
	p.messagesMu.Lock()
554
	p.messages[id] = newWhisperFilter(id, p.Whisper())
555
	p.messagesMu.Unlock()
556

T
Taylor Gerring 已提交
557 558 559
	return id
}

560
// UninstallWhisperFilter disables and removes an existing filter.
T
Taylor Gerring 已提交
561
func (p *XEth) UninstallWhisperFilter(id int) bool {
562 563
	p.messagesMu.Lock()
	defer p.messagesMu.Unlock()
564

T
Taylor Gerring 已提交
565 566 567 568 569 570 571
	if _, ok := p.messages[id]; ok {
		delete(p.messages, id)
		return true
	}
	return false
}

572 573
// WhisperMessages retrieves all the known messages that match a specific filter.
func (self *XEth) WhisperMessages(id int) []WhisperMessage {
574 575
	self.messagesMu.RLock()
	defer self.messagesMu.RUnlock()
T
Taylor Gerring 已提交
576 577

	if self.messages[id] != nil {
578
		return self.messages[id].messages()
T
Taylor Gerring 已提交
579
	}
580 581 582
	return nil
}

583 584 585
// WhisperMessagesChanged retrieves all the new messages matched by a filter
// since the last retrieval
func (self *XEth) WhisperMessagesChanged(id int) []WhisperMessage {
586 587
	self.messagesMu.RLock()
	defer self.messagesMu.RUnlock()
T
Taylor Gerring 已提交
588

589
	if self.messages[id] != nil {
590
		return self.messages[id].retrieve()
591
	}
T
Taylor Gerring 已提交
592 593 594
	return nil
}

T
Taylor Gerring 已提交
595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627
// 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 已提交
628 629 630 631 632
type KeyVal struct {
	Key   string `json:"key"`
	Value string `json:"value"`
}

O
obscuren 已提交
633
func (self *XEth) EachStorage(addr string) string {
O
obscuren 已提交
634 635 636 637
	var values []KeyVal
	object := self.State().SafeGet(addr)
	it := object.Trie().Iterator()
	for it.Next() {
O
obscuren 已提交
638
		values = append(values, KeyVal{common.ToHex(object.Trie().GetKey(it.Key)), common.ToHex(it.Value)})
O
obscuren 已提交
639 640 641 642 643 644 645 646 647 648
	}

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

	return string(valuesJson)
}

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

652
	return "0x" + common.ToHex(padded)
O
obscuren 已提交
653 654
}

O
obscuren 已提交
655
func (self *XEth) FromAscii(str string) string {
O
obscuren 已提交
656
	if common.IsHex(str) {
O
obscuren 已提交
657 658 659
		str = str[2:]
	}

O
obscuren 已提交
660
	return string(bytes.Trim(common.FromHex(str), "\x00"))
O
obscuren 已提交
661 662
}

O
obscuren 已提交
663
func (self *XEth) FromNumber(str string) string {
O
obscuren 已提交
664
	if common.IsHex(str) {
O
obscuren 已提交
665 666 667
		str = str[2:]
	}

O
obscuren 已提交
668
	return common.BigD(common.FromHex(str)).String()
O
obscuren 已提交
669 670
}

O
obscuren 已提交
671
func (self *XEth) PushTx(encodedTx string) (string, error) {
O
obscuren 已提交
672
	tx := types.NewTransactionFromBytes(common.FromHex(encodedTx))
T
Taylor Gerring 已提交
673
	err := self.backend.TxPool().Add(tx)
O
obscuren 已提交
674 675 676 677 678 679
	if err != nil {
		return "", err
	}

	if tx.To() == nil {
		addr := core.AddressFromMessage(tx)
O
obscuren 已提交
680
		return addr.Hex(), nil
O
obscuren 已提交
681
	}
O
obscuren 已提交
682
	return tx.Hash().Hex(), nil
O
obscuren 已提交
683
}
684

685
func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr string) (string, error) {
T
Taylor Gerring 已提交
686
	statedb := self.State().State() //self.eth.ChainManager().TransState()
687 688 689 690 691 692 693 694 695 696 697 698
	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 {
			from = statedb.GetOrNewStateObject(common.BytesToAddress(accounts[0].Address))
		}
	} else {
		from = statedb.GetOrNewStateObject(common.HexToAddress(fromStr))
	}

699
	msg := callmsg{
700
		from:     from,
O
obscuren 已提交
701
		to:       common.HexToAddress(toStr),
O
obscuren 已提交
702 703 704 705
		gas:      common.Big(gasStr),
		gasPrice: common.Big(gasPriceStr),
		value:    common.Big(valueStr),
		data:     common.FromHex(dataStr),
706
	}
B
Bas van Kervel 已提交
707

708
	if msg.gas.Cmp(big.NewInt(0)) == 0 {
O
obscuren 已提交
709
		msg.gas = DefaultGas()
710 711 712
	}

	if msg.gasPrice.Cmp(big.NewInt(0)) == 0 {
O
obscuren 已提交
713
		msg.gasPrice = DefaultGasPrice()
714 715
	}

716
	block := self.CurrentBlock()
T
Taylor Gerring 已提交
717
	vmenv := core.NewEnv(statedb, self.backend.ChainManager(), msg, block)
718

719
	res, err := vmenv.Call(msg.from, msg.to, msg.data, msg.gas, msg.gasPrice, msg.value)
720
	return common.ToHex(res), err
721 722
}

723 724 725 726 727 728
func (self *XEth) ConfirmTransaction(tx string) bool {

	return self.frontend.ConfirmTransaction(tx)

}

729
func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) {
730
	var (
O
obscuren 已提交
731 732
		from             = common.HexToAddress(fromStr)
		to               = common.HexToAddress(toStr)
O
obscuren 已提交
733
		value            = common.NewValue(valueStr)
T
Taylor Gerring 已提交
734 735
		gas              = common.Big(gasStr)
		price            = common.Big(gasPriceStr)
736 737 738 739
		data             []byte
		contractCreation bool
	)

T
Taylor Gerring 已提交
740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761
	// 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 已提交
762 763 764
	// 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 已提交
765
		gas = DefaultGas()
T
Taylor Gerring 已提交
766 767 768
	}

	if price.Cmp(big.NewInt(0)) == 0 {
O
obscuren 已提交
769
		price = DefaultGasPrice()
T
Taylor Gerring 已提交
770 771
	}

O
obscuren 已提交
772
	data = common.FromHex(codeStr)
O
obscuren 已提交
773
	if len(toStr) == 0 {
774 775 776 777 778
		contractCreation = true
	}

	var tx *types.Transaction
	if contractCreation {
T
Taylor Gerring 已提交
779
		tx = types.NewContractCreationTx(value.BigInt(), gas, price, data)
780
	} else {
T
Taylor Gerring 已提交
781
		tx = types.NewTransactionMessage(to, value.BigInt(), gas, price, data)
782 783
	}

T
Taylor Gerring 已提交
784
	state := self.backend.ChainManager().TxState()
785 786 787 788 789 790 791

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

794
	if err := self.sign(tx, from, false); err != nil {
795 796
		return "", err
	}
T
Taylor Gerring 已提交
797
	if err := self.backend.TxPool().Add(tx); err != nil {
798 799
		return "", err
	}
800 801 802

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

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

O
obscuren 已提交
812
func (self *XEth) sign(tx *types.Transaction, from common.Address, didUnlock bool) error {
T
Taylor Gerring 已提交
813
	sig, err := self.backend.AccountManager().Sign(accounts.Account{Address: from.Bytes()}, tx.Hash().Bytes())
814 815 816 817
	if err == accounts.ErrLocked {
		if didUnlock {
			return fmt.Errorf("sender account still locked after successful unlock")
		}
O
obscuren 已提交
818
		if !self.frontend.UnlockAccount(from.Bytes()) {
819 820 821
			return fmt.Errorf("could not unlock sender account")
		}
		// retry signing, the account should now be unlocked.
822
		return self.sign(tx, from, true)
823 824 825 826 827 828 829
	} else if err != nil {
		return err
	}
	tx.SetSignatureValues(sig)
	return nil
}

830 831 832
// callmsg is the message type used for call transations.
type callmsg struct {
	from          *state.StateObject
O
obscuren 已提交
833
	to            common.Address
834 835 836 837 838 839
	gas, gasPrice *big.Int
	value         *big.Int
	data          []byte
}

// accessor boilerplate to implement core.Message
O
obscuren 已提交
840 841 842 843 844 845 846
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 已提交
847

848
type logQueue struct {
T
Taylor Gerring 已提交
849 850 851 852 853
	logs    state.Logs
	timeout time.Time
	id      int
}

854
func (l *logQueue) add(logs ...*state.Log) {
T
Taylor Gerring 已提交
855 856 857
	l.logs = append(l.logs, logs...)
}

858
func (l *logQueue) get() state.Logs {
T
Taylor Gerring 已提交
859 860 861 862 863
	l.timeout = time.Now()
	tmp := l.logs
	l.logs = nil
	return tmp
}
864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880

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
}