diff options
Diffstat (limited to 'xeth')
-rw-r--r-- | xeth/frontend.go | 48 | ||||
-rw-r--r-- | xeth/state.go | 51 | ||||
-rw-r--r-- | xeth/types.go | 237 | ||||
-rw-r--r-- | xeth/whisper.go | 121 | ||||
-rw-r--r-- | xeth/whisper_filter.go | 100 | ||||
-rw-r--r-- | xeth/whisper_message.go | 53 | ||||
-rw-r--r-- | xeth/xeth.go | 1137 | ||||
-rw-r--r-- | xeth/xeth_test.go | 26 |
8 files changed, 0 insertions, 1773 deletions
diff --git a/xeth/frontend.go b/xeth/frontend.go deleted file mode 100644 index 70d99ebc4..000000000 --- a/xeth/frontend.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package xeth - -// Frontend should be implemented by users of XEth. Its methods are -// called whenever XEth makes a decision that requires user input. -type Frontend interface { - // AskPassword is called when a new account is created or updated - AskPassword() (string, bool) - - // UnlockAccount is called when a transaction needs to be signed - // but the key corresponding to the transaction's sender is - // locked. - // - // It should unlock the account with the given address and return - // true if unlocking succeeded. - UnlockAccount(address []byte) bool - - // This is called for all transactions inititated through - // Transact. It should prompt the user to confirm the transaction - // and return true if the transaction was acknowledged. - // - // ConfirmTransaction is not used for Call transactions - // because they cannot change any state. - ConfirmTransaction(tx string) bool -} - -// dummyFrontend is a non-interactive frontend that allows all -// transactions but cannot not unlock any keys. -type dummyFrontend struct{} - -func (dummyFrontend) AskPassword() (string, bool) { return "", false } -func (dummyFrontend) UnlockAccount([]byte) bool { return false } -func (dummyFrontend) ConfirmTransaction(string) bool { return true } diff --git a/xeth/state.go b/xeth/state.go deleted file mode 100644 index 7daccb525..000000000 --- a/xeth/state.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package xeth - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" -) - -type State struct { - xeth *XEth - state *state.StateDB -} - -func NewState(xeth *XEth, statedb *state.StateDB) *State { - return &State{xeth, statedb} -} - -func (self *State) State() *state.StateDB { - return self.state -} - -func (self *State) Get(addr string) *Object { - return &Object{self.state.GetStateObject(common.HexToAddress(addr))} -} - -func (self *State) SafeGet(addr string) *Object { - return &Object{self.safeGet(addr)} -} - -func (self *State) safeGet(addr string) *state.StateObject { - object := self.state.GetStateObject(common.HexToAddress(addr)) - if object == nil { - object = state.NewStateObject(common.HexToAddress(addr), self.xeth.EthereumService().ChainDb()) - } - return object -} diff --git a/xeth/types.go b/xeth/types.go deleted file mode 100644 index 090115b7e..000000000 --- a/xeth/types.go +++ /dev/null @@ -1,237 +0,0 @@ -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -package xeth - -import ( - "bytes" - "fmt" - "math/big" - "strings" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/p2p" - "github.com/ethereum/go-ethereum/rlp" -) - -type Object struct { - *state.StateObject -} - -func NewObject(state *state.StateObject) *Object { - return &Object{state} -} - -func (self *Object) StorageString(str string) []byte { - if common.IsHex(str) { - return self.storage(common.Hex2Bytes(str[2:])) - } else { - return self.storage(common.RightPadBytes([]byte(str), 32)) - } -} - -func (self *Object) storage(addr []byte) []byte { - return self.StateObject.GetState(common.BytesToHash(addr)).Bytes() -} - -func (self *Object) Storage() (storage map[string]string) { - storage = make(map[string]string) - - it := self.StateObject.Trie().Iterator() - for it.Next() { - var data []byte - rlp.Decode(bytes.NewReader(it.Value), &data) - storage[common.ToHex(self.Trie().GetKey(it.Key))] = common.ToHex(data) - } - - return -} - -// Block interface exposed to QML -type Block struct { - //Transactions string `json:"transactions"` - ref *types.Block - Size string `json:"size"` - Number int `json:"number"` - Hash string `json:"hash"` - Transactions *common.List `json:"transactions"` - Uncles *common.List `json:"uncles"` - Time *big.Int `json:"time"` - Coinbase string `json:"coinbase"` - Name string `json:"name"` - GasLimit string `json:"gasLimit"` - GasUsed string `json:"gasUsed"` - PrevHash string `json:"prevHash"` - Bloom string `json:"bloom"` - Raw string `json:"raw"` -} - -// Creates a new QML Block from a chain block -func NewBlock(block *types.Block) *Block { - if block == nil { - return &Block{} - } - - ptxs := make([]*Transaction, len(block.Transactions())) - /* - for i, tx := range block.Transactions() { - ptxs[i] = NewTx(tx) - } - */ - txlist := common.NewList(ptxs) - - puncles := make([]*Block, len(block.Uncles())) - /* - for i, uncle := range block.Uncles() { - puncles[i] = NewBlock(types.NewBlockWithHeader(uncle)) - } - */ - ulist := common.NewList(puncles) - - return &Block{ - ref: block, Size: block.Size().String(), - Number: int(block.NumberU64()), GasUsed: block.GasUsed().String(), - GasLimit: block.GasLimit().String(), Hash: block.Hash().Hex(), - Transactions: txlist, Uncles: ulist, - Time: block.Time(), - Coinbase: block.Coinbase().Hex(), - PrevHash: block.ParentHash().Hex(), - Bloom: common.ToHex(block.Bloom().Bytes()), - Raw: block.String(), - } -} - -func (self *Block) ToString() string { - if self.ref != nil { - return self.ref.String() - } - - return "" -} - -func (self *Block) GetTransaction(hash string) *Transaction { - tx := self.ref.Transaction(common.HexToHash(hash)) - if tx == nil { - return nil - } - - return NewTx(tx) -} - -type Transaction struct { - ref *types.Transaction - - Value string `json:"value"` - Gas string `json:"gas"` - GasPrice string `json:"gasPrice"` - Hash string `json:"hash"` - Address string `json:"address"` - Sender string `json:"sender"` - RawData string `json:"rawData"` - Data string `json:"data"` - Contract bool `json:"isContract"` - CreatesContract bool `json:"createsContract"` - Confirmations int `json:"confirmations"` -} - -func NewTx(tx *types.Transaction) *Transaction { - sender, err := tx.From() - if err != nil { - return nil - } - hash := tx.Hash().Hex() - - var receiver string - if to := tx.To(); to != nil { - receiver = to.Hex() - } else { - from, _ := tx.From() - receiver = crypto.CreateAddress(from, tx.Nonce()).Hex() - } - createsContract := core.MessageCreatesContract(tx) - - var data string - if createsContract { - data = strings.Join(core.Disassemble(tx.Data()), "\n") - } else { - data = common.ToHex(tx.Data()) - } - - return &Transaction{ref: tx, Hash: hash, Value: common.CurrencyToString(tx.Value()), Address: receiver, Contract: createsContract, Gas: tx.Gas().String(), GasPrice: tx.GasPrice().String(), Data: data, Sender: sender.Hex(), CreatesContract: createsContract, RawData: common.ToHex(tx.Data())} -} - -func (self *Transaction) ToString() string { - return self.ref.String() -} - -type PReceipt struct { - CreatedContract bool `json:"createdContract"` - Address string `json:"address"` - Hash string `json:"hash"` - Sender string `json:"sender"` -} - -func NewPReciept(contractCreation bool, creationAddress, hash, address []byte) *PReceipt { - return &PReceipt{ - contractCreation, - common.ToHex(creationAddress), - common.ToHex(hash), - common.ToHex(address), - } -} - -// Peer interface exposed to QML - -type Peer struct { - ref *p2p.Peer - Ip string `json:"ip"` - Version string `json:"version"` - Caps string `json:"caps"` -} - -func NewPeer(peer *p2p.Peer) *Peer { - var caps []string - for _, cap := range peer.Caps() { - caps = append(caps, fmt.Sprintf("%s/%d", cap.Name, cap.Version)) - } - - return &Peer{ - ref: peer, - Ip: fmt.Sprintf("%v", peer.RemoteAddr()), - Version: fmt.Sprintf("%v", peer.ID()), - Caps: fmt.Sprintf("%v", caps), - } -} - -type Receipt struct { - CreatedContract bool `json:"createdContract"` - Address string `json:"address"` - Hash string `json:"hash"` - Sender string `json:"sender"` -} - -func NewReciept(contractCreation bool, creationAddress, hash, address []byte) *Receipt { - return &Receipt{ - contractCreation, - common.ToHex(creationAddress), - common.ToHex(hash), - common.ToHex(address), - } -} diff --git a/xeth/whisper.go b/xeth/whisper.go deleted file mode 100644 index e7130978f..000000000 --- a/xeth/whisper.go +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -// Contains the external API to the whisper sub-protocol. - -package xeth - -import ( - "fmt" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/logger" - "github.com/ethereum/go-ethereum/whisper" -) - -var qlogger = logger.NewLogger("XSHH") - -// Whisper represents the API wrapper around the internal whisper implementation. -type Whisper struct { - *whisper.Whisper -} - -// NewWhisper wraps an internal whisper client into an external API version. -func NewWhisper(w *whisper.Whisper) *Whisper { - return &Whisper{w} -} - -// NewIdentity generates a new cryptographic identity for the client, and injects -// it into the known identities for message decryption. -func (self *Whisper) NewIdentity() string { - identity := self.Whisper.NewIdentity() - return common.ToHex(crypto.FromECDSAPub(&identity.PublicKey)) -} - -// HasIdentity checks if the the whisper node is configured with the private key -// of the specified public pair. -func (self *Whisper) HasIdentity(key string) bool { - return self.Whisper.HasIdentity(crypto.ToECDSAPub(common.FromHex(key))) -} - -// Post injects a message into the whisper network for distribution. -func (self *Whisper) Post(payload string, to, from string, topics []string, priority, ttl uint32) error { - // Decode the topic strings - topicsDecoded := make([][]byte, len(topics)) - for i, topic := range topics { - topicsDecoded[i] = common.FromHex(topic) - } - // Construct the whisper message and transmission options - message := whisper.NewMessage(common.FromHex(payload)) - options := whisper.Options{ - To: crypto.ToECDSAPub(common.FromHex(to)), - TTL: time.Duration(ttl) * time.Second, - Topics: whisper.NewTopics(topicsDecoded...), - } - if len(from) != 0 { - if key := self.Whisper.GetIdentity(crypto.ToECDSAPub(common.FromHex(from))); key != nil { - options.From = key - } else { - return fmt.Errorf("unknown identity to send from: %s", from) - } - } - // Wrap and send the message - pow := time.Duration(priority) * time.Millisecond - envelope, err := message.Wrap(pow, options) - if err != nil { - return err - } - if err := self.Whisper.Send(envelope); err != nil { - return err - } - return nil -} - -// Watch installs a new message handler to run in case a matching packet arrives -// from the whisper network. -func (self *Whisper) Watch(to, from string, topics [][]string, fn func(WhisperMessage)) int { - // Decode the topic strings - topicsDecoded := make([][][]byte, len(topics)) - for i, condition := range topics { - topicsDecoded[i] = make([][]byte, len(condition)) - for j, topic := range condition { - topicsDecoded[i][j] = common.FromHex(topic) - } - } - // Assemble and inject the filter into the whisper client - filter := whisper.Filter{ - To: crypto.ToECDSAPub(common.FromHex(to)), - From: crypto.ToECDSAPub(common.FromHex(from)), - Topics: whisper.NewFilterTopics(topicsDecoded...), - } - filter.Fn = func(message *whisper.Message) { - fn(NewWhisperMessage(message)) - } - return self.Whisper.Watch(filter) -} - -// Messages retrieves all the currently pooled messages matching a filter id. -func (self *Whisper) Messages(id int) []WhisperMessage { - pool := self.Whisper.Messages(id) - - messages := make([]WhisperMessage, len(pool)) - for i, message := range pool { - messages[i] = NewWhisperMessage(message) - } - return messages -} diff --git a/xeth/whisper_filter.go b/xeth/whisper_filter.go deleted file mode 100644 index fdf5cebae..000000000 --- a/xeth/whisper_filter.go +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -// Contains the external API side message filter for watching, pooling and polling -// matched whisper messages, also serializing data access to avoid duplications. - -package xeth - -import ( - "sync" - "time" - - "github.com/ethereum/go-ethereum/common" -) - -// whisperFilter is the message cache matching a specific filter, accumulating -// inbound messages until the are requested by the client. -type whisperFilter struct { - id int // Filter identifier for old message retrieval - ref *Whisper // Whisper reference for old message retrieval - - cache []WhisperMessage // Cache of messages not yet polled - skip map[common.Hash]struct{} // List of retrieved messages to avoid duplication - update time.Time // Time of the last message query - - lock sync.RWMutex // Lock protecting the filter internals -} - -// newWhisperFilter creates a new serialized, poll based whisper topic filter. -func newWhisperFilter(id int, ref *Whisper) *whisperFilter { - return &whisperFilter{ - id: id, - ref: ref, - - update: time.Now(), - skip: make(map[common.Hash]struct{}), - } -} - -// messages retrieves all the cached messages from the entire pool matching the -// filter, resetting the filter's change buffer. -func (w *whisperFilter) messages() []WhisperMessage { - w.lock.Lock() - defer w.lock.Unlock() - - w.cache = nil - w.update = time.Now() - - w.skip = make(map[common.Hash]struct{}) - messages := w.ref.Messages(w.id) - for _, message := range messages { - w.skip[message.ref.Hash] = struct{}{} - } - return messages -} - -// insert injects a new batch of messages into the filter cache. -func (w *whisperFilter) insert(messages ...WhisperMessage) { - w.lock.Lock() - defer w.lock.Unlock() - - for _, message := range messages { - if _, ok := w.skip[message.ref.Hash]; !ok { - w.cache = append(w.cache, messages...) - } - } -} - -// retrieve fetches all the cached messages from the filter. -func (w *whisperFilter) retrieve() (messages []WhisperMessage) { - w.lock.Lock() - defer w.lock.Unlock() - - messages, w.cache = w.cache, nil - w.update = time.Now() - - return -} - -// activity returns the last time instance when client requests were executed on -// the filter. -func (w *whisperFilter) activity() time.Time { - w.lock.RLock() - defer w.lock.RUnlock() - - return w.update -} diff --git a/xeth/whisper_message.go b/xeth/whisper_message.go deleted file mode 100644 index b3014a697..000000000 --- a/xeth/whisper_message.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -// Contains the external API representation of a whisper message. - -package xeth - -import ( - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/whisper" -) - -// WhisperMessage is the external API representation of a whisper.Message. -type WhisperMessage struct { - ref *whisper.Message - - Payload string `json:"payload"` - To string `json:"to"` - From string `json:"from"` - Sent int64 `json:"sent"` - TTL int64 `json:"ttl"` - Hash string `json:"hash"` -} - -// NewWhisperMessage converts an internal message into an API version. -func NewWhisperMessage(message *whisper.Message) WhisperMessage { - return WhisperMessage{ - ref: message, - - Payload: common.ToHex(message.Payload), - From: common.ToHex(crypto.FromECDSAPub(message.Recover())), - To: common.ToHex(crypto.FromECDSAPub(message.To)), - Sent: message.Sent.Unix(), - TTL: int64(message.TTL / time.Second), - Hash: common.ToHex(message.Hash.Bytes()), - } -} diff --git a/xeth/xeth.go b/xeth/xeth.go deleted file mode 100644 index 5a5399a3e..000000000 --- a/xeth/xeth.go +++ /dev/null @@ -1,1137 +0,0 @@ -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. - -// Package xeth is the interface to all Ethereum functionality. -package xeth - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "math/big" - "regexp" - "sync" - "time" - - "github.com/ethereum/go-ethereum/accounts" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/compiler" - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/eth/filters" - "github.com/ethereum/go-ethereum/logger" - "github.com/ethereum/go-ethereum/logger/glog" - "github.com/ethereum/go-ethereum/miner" - "github.com/ethereum/go-ethereum/node" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/whisper" -) - -var ( - filterTickerTime = 5 * time.Minute - defaultGasPrice = big.NewInt(10000000000000) //150000000000 - defaultGas = big.NewInt(90000) //500000 - dappStorePre = []byte("dapp-") - addrReg = regexp.MustCompile(`^(0x)?[a-fA-F0-9]{40}$`) -) - -// byte will be inferred -const ( - UnknownFilterTy = iota - BlockFilterTy - TransactionFilterTy - LogFilterTy -) - -type XEth struct { - quit chan struct{} - - logMu sync.RWMutex - logQueue map[int]*logQueue - - blockMu sync.RWMutex - blockQueue map[int]*hashQueue - - transactionMu sync.RWMutex - transactionQueue map[int]*hashQueue - - messagesMu sync.RWMutex - messages map[int]*whisperFilter - - transactMu sync.Mutex - - // read-only fields - backend *node.Node - frontend Frontend - agent *miner.RemoteAgent - gpo *eth.GasPriceOracle - state *State - whisper *Whisper - filterManager *filters.FilterSystem -} - -func NewTest(stack *node.Node, frontend Frontend) *XEth { - return &XEth{backend: stack, frontend: frontend} -} - -// 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. -func New(stack *node.Node, frontend Frontend) *XEth { - var ( - ethereum *eth.Ethereum - whisper *whisper.Whisper - ) - stack.Service(ðereum) - stack.Service(&whisper) - - xeth := &XEth{ - backend: stack, - frontend: frontend, - quit: make(chan struct{}), - filterManager: filters.NewFilterSystem(stack.EventMux()), - logQueue: make(map[int]*logQueue), - blockQueue: make(map[int]*hashQueue), - transactionQueue: make(map[int]*hashQueue), - messages: make(map[int]*whisperFilter), - agent: miner.NewRemoteAgent(), - gpo: eth.NewGasPriceOracle(ethereum), - } - if whisper != nil { - xeth.whisper = NewWhisper(whisper) - } - ethereum.Miner().Register(xeth.agent) - if frontend == nil { - xeth.frontend = dummyFrontend{} - } - state, _ := ethereum.BlockChain().State() - xeth.state = NewState(xeth, state) - go xeth.start() - return xeth -} - -func (self *XEth) EthereumService() *eth.Ethereum { - var ethereum *eth.Ethereum - if err := self.backend.Service(ðereum); err != nil { - return nil - } - return ethereum -} - -func (self *XEth) WhisperService() *whisper.Whisper { - var whisper *whisper.Whisper - if err := self.backend.Service(&whisper); err != nil { - return nil - } - return whisper -} - -func (self *XEth) start() { - timer := time.NewTicker(2 * time.Second) - defer timer.Stop() -done: - for { - select { - case <-timer.C: - self.logMu.Lock() - for id, filter := range self.logQueue { - if time.Since(filter.timeout) > filterTickerTime { - self.filterManager.Remove(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.Remove(id) - delete(self.blockQueue, id) - } - } - self.blockMu.Unlock() - - self.transactionMu.Lock() - for id, filter := range self.transactionQueue { - if time.Since(filter.timeout) > filterTickerTime { - self.filterManager.Remove(id) - delete(self.transactionQueue, id) - } - } - self.transactionMu.Unlock() - - self.messagesMu.Lock() - for id, filter := range self.messages { - if time.Since(filter.activity()) > filterTickerTime { - self.Whisper().Unwatch(id) - delete(self.messages, id) - } - } - self.messagesMu.Unlock() - case <-self.quit: - break done - } - } -} - -// Stop releases any resources associated with self. -// It may not be called more than once. -func (self *XEth) Stop() { - close(self.quit) - self.filterManager.Stop() - self.EthereumService().Miner().Unregister(self.agent) -} - -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 { - topics[i] = make([]common.Hash, len(iv)) - for j, jv := range iv { - topics[i][j] = common.HexToHash(jv) - } - } - return topics -} - -func DefaultGas() *big.Int { return new(big.Int).Set(defaultGas) } - -func (self *XEth) DefaultGasPrice() *big.Int { - return self.gpo.SuggestPrice() -} - -func (self *XEth) RemoteMining() *miner.RemoteAgent { return self.agent } - -func (self *XEth) AtStateNum(num int64) *XEth { - var st *state.StateDB - var err error - switch num { - case -2: - st = self.EthereumService().Miner().PendingState().Copy() - default: - if block := self.getBlockByHeight(num); block != nil { - st, err = state.New(block.Root(), self.EthereumService().ChainDb()) - if err != nil { - return nil - } - } else { - st, err = state.New(self.EthereumService().BlockChain().GetBlockByNumber(0).Root(), self.EthereumService().ChainDb()) - if err != nil { - return nil - } - } - } - return self.WithState(st) -} - -func (self *XEth) WithState(statedb *state.StateDB) *XEth { - xeth := &XEth{ - backend: self.backend, - frontend: self.frontend, - gpo: self.gpo, - } - - xeth.state = NewState(xeth, statedb) - return xeth -} - -func (self *XEth) State() *State { return self.state } - -// 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() { - eventSub := self.backend.EventMux().Subscribe(core.ChainHeadEvent{}) - defer eventSub.Unsubscribe() - - var m, n *big.Int - var ok bool - - eventCh := eventSub.Chan() - for { - select { - case event, ok := <-eventCh: - if !ok { - // Event subscription closed, set the channel to nil to stop spinning - eventCh = nil - continue - } - // A real event arrived, process if new head block assignment - if event, ok := event.Data.(core.ChainHeadEvent); ok { - m = event.Block.Number() - if n != nil && n.Cmp(m) < 0 { - wait <- n - n = nil - } - statedb, err := state.New(event.Block.Root(), self.EthereumService().ChainDb()) - if err != nil { - glog.V(logger.Error).Infoln("Could not create new state: %v", err) - return - } - self.state = NewState(self, statedb) - } - case n, ok = <-wait: - if !ok { - return - } - } - } - }() - return -} - -func (self *XEth) Whisper() *Whisper { return self.whisper } - -func (self *XEth) getBlockByHeight(height int64) *types.Block { - var num uint64 - - switch height { - case -2: - return self.EthereumService().Miner().PendingBlock() - case -1: - return self.CurrentBlock() - default: - if height < 0 { - return nil - } - - num = uint64(height) - } - - return self.EthereumService().BlockChain().GetBlockByNumber(num) -} - -func (self *XEth) BlockByHash(strHash string) *Block { - hash := common.HexToHash(strHash) - block := self.EthereumService().BlockChain().GetBlock(hash) - - return NewBlock(block) -} - -func (self *XEth) EthBlockByHash(strHash string) *types.Block { - hash := common.HexToHash(strHash) - block := self.EthereumService().BlockChain().GetBlock(hash) - - return block -} - -func (self *XEth) EthTransactionByHash(hash string) (*types.Transaction, common.Hash, uint64, uint64) { - ethereum := self.EthereumService() - if tx, hash, number, index := core.GetTransaction(ethereum.ChainDb(), common.HexToHash(hash)); tx != nil { - return tx, hash, number, index - } - return ethereum.TxPool().GetTransaction(common.HexToHash(hash)), common.Hash{}, 0, 0 -} - -func (self *XEth) BlockByNumber(num int64) *Block { - return NewBlock(self.getBlockByHeight(num)) -} - -func (self *XEth) EthBlockByNumber(num int64) *types.Block { - return self.getBlockByHeight(num) -} - -func (self *XEth) Td(hash common.Hash) *big.Int { - return self.EthereumService().BlockChain().GetTd(hash) -} - -func (self *XEth) CurrentBlock() *types.Block { - return self.EthereumService().BlockChain().CurrentBlock() -} - -func (self *XEth) GetBlockReceipts(bhash common.Hash) types.Receipts { - return core.GetBlockReceipts(self.EthereumService().ChainDb(), bhash) -} - -func (self *XEth) GetTxReceipt(txhash common.Hash) *types.Receipt { - return core.GetReceipt(self.EthereumService().ChainDb(), txhash) -} - -func (self *XEth) GasLimit() *big.Int { - return self.EthereumService().BlockChain().GasLimit() -} - -func (self *XEth) Block(v interface{}) *Block { - if n, ok := v.(int32); ok { - return self.BlockByNumber(int64(n)) - } else if str, ok := v.(string); ok { - return self.BlockByHash(str) - } else if f, ok := v.(float64); ok { // JSON numbers are represented as float64 - return self.BlockByNumber(int64(f)) - } - - return nil -} - -func (self *XEth) Accounts() []string { - // TODO: check err? - accounts, _ := self.EthereumService().AccountManager().Accounts() - accountAddresses := make([]string, len(accounts)) - for i, ac := range accounts { - accountAddresses[i] = ac.Address.Hex() - } - return accountAddresses -} - -// accessor for solidity compiler. -// memoized if available, retried on-demand if not -func (self *XEth) Solc() (*compiler.Solidity, error) { - return self.EthereumService().Solc() -} - -// set in js console via admin interface or wrapper from cli flags -func (self *XEth) SetSolc(solcPath string) (*compiler.Solidity, error) { - self.EthereumService().SetSolc(solcPath) - return self.Solc() -} - -// store DApp value in extra database -func (self *XEth) DbPut(key, val []byte) bool { - self.EthereumService().DappDb().Put(append(dappStorePre, key...), val) - return true -} - -// retrieve DApp value from extra database -func (self *XEth) DbGet(key []byte) ([]byte, error) { - val, err := self.EthereumService().DappDb().Get(append(dappStorePre, key...)) - return val, err -} - -func (self *XEth) PeerCount() int { - return self.backend.Server().PeerCount() -} - -func (self *XEth) IsMining() bool { - return self.EthereumService().IsMining() -} - -func (self *XEth) HashRate() int64 { - return self.EthereumService().Miner().HashRate() -} - -func (self *XEth) EthVersion() string { - return fmt.Sprintf("%d", self.EthereumService().EthVersion()) -} - -func (self *XEth) NetworkVersion() string { - return fmt.Sprintf("%d", self.EthereumService().NetVersion()) -} - -func (self *XEth) WhisperVersion() string { - return fmt.Sprintf("%d", self.WhisperService().Version()) -} - -func (self *XEth) ClientVersion() string { - return self.backend.Server().Name -} - -func (self *XEth) SetMining(shouldmine bool, threads int) bool { - ismining := self.EthereumService().IsMining() - if shouldmine && !ismining { - err := self.EthereumService().StartMining(threads, "") - return err == nil - } - if ismining && !shouldmine { - self.EthereumService().StopMining() - } - return self.EthereumService().IsMining() -} - -func (self *XEth) IsListening() bool { - return true -} - -func (self *XEth) Coinbase() string { - eb, err := self.EthereumService().Etherbase() - if err != nil { - return "0x0" - } - return eb.Hex() -} - -func (self *XEth) NumberToHuman(balance string) string { - b := common.Big(balance) - - return common.CurrencyToString(b) -} - -func (self *XEth) StorageAt(addr, storageAddr string) string { - return self.State().state.GetState(common.HexToAddress(addr), common.HexToHash(storageAddr)).Hex() -} - -func (self *XEth) BalanceAt(addr string) string { - return common.ToHex(self.State().state.GetBalance(common.HexToAddress(addr)).Bytes()) -} - -func (self *XEth) TxCountAt(address string) int { - return int(self.State().state.GetNonce(common.HexToAddress(address))) -} - -func (self *XEth) CodeAt(address string) string { - return common.ToHex(self.State().state.GetCode(common.HexToAddress(address))) -} - -func (self *XEth) CodeAtBytes(address string) []byte { - return self.State().SafeGet(address).Code() -} - -func (self *XEth) IsContract(address string) bool { - return len(self.State().SafeGet(address).Code()) > 0 -} - -func (self *XEth) UninstallFilter(id int) bool { - defer self.filterManager.Remove(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 { - self.logMu.Lock() - defer self.logMu.Unlock() - - filter := filters.New(self.EthereumService().ChainDb()) - id := self.filterManager.Add(filter) - self.logQueue[id] = &logQueue{timeout: time.Now()} - - filter.SetBeginBlock(earliest) - filter.SetEndBlock(latest) - filter.SetAddresses(cAddress(address)) - filter.SetTopics(cTopics(topics)) - filter.LogsCallback = func(logs vm.Logs) { - self.logMu.Lock() - defer self.logMu.Unlock() - - if queue := self.logQueue[id]; queue != nil { - queue.add(logs...) - } - } - - return id -} - -func (self *XEth) NewTransactionFilter() int { - self.transactionMu.Lock() - defer self.transactionMu.Unlock() - - filter := filters.New(self.EthereumService().ChainDb()) - id := self.filterManager.Add(filter) - self.transactionQueue[id] = &hashQueue{timeout: time.Now()} - - filter.TransactionCallback = func(tx *types.Transaction) { - self.transactionMu.Lock() - defer self.transactionMu.Unlock() - - if queue := self.transactionQueue[id]; queue != nil { - queue.add(tx.Hash()) - } - } - return id -} - -func (self *XEth) NewBlockFilter() int { - self.blockMu.Lock() - defer self.blockMu.Unlock() - - filter := filters.New(self.EthereumService().ChainDb()) - id := self.filterManager.Add(filter) - self.blockQueue[id] = &hashQueue{timeout: time.Now()} - - filter.BlockCallback = func(block *types.Block, logs vm.Logs) { - self.blockMu.Lock() - defer self.blockMu.Unlock() - - if queue := self.blockQueue[id]; queue != nil { - queue.add(block.Hash()) - } - } - return id -} - -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 - } - - return UnknownFilterTy -} - -func (self *XEth) LogFilterChanged(id int) vm.Logs { - self.logMu.Lock() - defer self.logMu.Unlock() - - if self.logQueue[id] != nil { - return self.logQueue[id].get() - } - return nil -} - -func (self *XEth) BlockFilterChanged(id int) []common.Hash { - self.blockMu.Lock() - defer self.blockMu.Unlock() - - if self.blockQueue[id] != nil { - return self.blockQueue[id].get() - } - return nil -} - -func (self *XEth) TransactionFilterChanged(id int) []common.Hash { - self.blockMu.Lock() - defer self.blockMu.Unlock() - - if self.transactionQueue[id] != nil { - return self.transactionQueue[id].get() - } - return nil -} - -func (self *XEth) Logs(id int) vm.Logs { - filter := self.filterManager.Get(id) - if filter != nil { - return filter.Find() - } - - return nil -} - -func (self *XEth) AllLogs(earliest, latest int64, skip, max int, address []string, topics [][]string) vm.Logs { - filter := filters.New(self.EthereumService().ChainDb()) - filter.SetBeginBlock(earliest) - filter.SetEndBlock(latest) - filter.SetAddresses(cAddress(address)) - filter.SetTopics(cTopics(topics)) - - return filter.Find() -} - -// 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. -func (p *XEth) NewWhisperFilter(to, from string, topics [][]string) int { - // Pre-define the id to be filled later - var id int - - // Callback to delegate core whisper messages to this xeth filter - callback := func(msg WhisperMessage) { - p.messagesMu.RLock() // Only read lock to the filter pool - defer p.messagesMu.RUnlock() - if p.messages[id] != nil { - p.messages[id].insert(msg) - } - } - // Initialize the core whisper filter and wrap into xeth - id = p.Whisper().Watch(to, from, topics, callback) - - p.messagesMu.Lock() - p.messages[id] = newWhisperFilter(id, p.Whisper()) - p.messagesMu.Unlock() - - return id -} - -// UninstallWhisperFilter disables and removes an existing filter. -func (p *XEth) UninstallWhisperFilter(id int) bool { - p.messagesMu.Lock() - defer p.messagesMu.Unlock() - - if _, ok := p.messages[id]; ok { - delete(p.messages, id) - return true - } - return false -} - -// WhisperMessages retrieves all the known messages that match a specific filter. -func (self *XEth) WhisperMessages(id int) []WhisperMessage { - self.messagesMu.RLock() - defer self.messagesMu.RUnlock() - - if self.messages[id] != nil { - return self.messages[id].messages() - } - return nil -} - -// WhisperMessagesChanged retrieves all the new messages matched by a filter -// since the last retrieval -func (self *XEth) WhisperMessagesChanged(id int) []WhisperMessage { - self.messagesMu.RLock() - defer self.messagesMu.RUnlock() - - if self.messages[id] != nil { - return self.messages[id].retrieve() - } - return nil -} - -// 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 -// } - -type KeyVal struct { - Key string `json:"key"` - Value string `json:"value"` -} - -func (self *XEth) EachStorage(addr string) string { - var values []KeyVal - object := self.State().SafeGet(addr) - it := object.Trie().Iterator() - for it.Next() { - values = append(values, KeyVal{common.ToHex(object.Trie().GetKey(it.Key)), common.ToHex(it.Value)}) - } - - valuesJson, err := json.Marshal(values) - if err != nil { - return "" - } - - return string(valuesJson) -} - -func (self *XEth) ToAscii(str string) string { - padded := common.RightPadBytes([]byte(str), 32) - - return "0x" + common.ToHex(padded) -} - -func (self *XEth) FromAscii(str string) string { - if common.IsHex(str) { - str = str[2:] - } - - return string(bytes.Trim(common.FromHex(str), "\x00")) -} - -func (self *XEth) FromNumber(str string) string { - if common.IsHex(str) { - str = str[2:] - } - - return common.BigD(common.FromHex(str)).String() -} - -func (self *XEth) PushTx(encodedTx string) (string, error) { - tx := new(types.Transaction) - err := rlp.DecodeBytes(common.FromHex(encodedTx), tx) - if err != nil { - glog.V(logger.Error).Infoln(err) - return "", err - } - - err = self.EthereumService().TxPool().Add(tx) - if err != nil { - return "", err - } - - if tx.To() == nil { - from, err := tx.From() - if err != nil { - return "", err - } - - addr := crypto.CreateAddress(from, tx.Nonce()) - glog.V(logger.Info).Infof("Tx(%x) created: %x\n", tx.Hash(), addr) - } else { - glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To()) - } - - return tx.Hash().Hex(), nil -} - -func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr string) (string, string, error) { - statedb := self.State().State().Copy() - var from *state.StateObject - if len(fromStr) == 0 { - accounts, err := self.EthereumService().AccountManager().Accounts() - if err != nil || len(accounts) == 0 { - from = statedb.GetOrNewStateObject(common.Address{}) - } else { - from = statedb.GetOrNewStateObject(accounts[0].Address) - } - } else { - from = statedb.GetOrNewStateObject(common.HexToAddress(fromStr)) - } - - from.SetBalance(common.MaxBig) - - msg := callmsg{ - from: from, - gas: common.Big(gasStr), - gasPrice: common.Big(gasPriceStr), - value: common.Big(valueStr), - data: common.FromHex(dataStr), - } - if len(toStr) > 0 { - addr := common.HexToAddress(toStr) - msg.to = &addr - } - - if msg.gas.Cmp(big.NewInt(0)) == 0 { - msg.gas = big.NewInt(50000000) - } - - if msg.gasPrice.Cmp(big.NewInt(0)) == 0 { - msg.gasPrice = self.DefaultGasPrice() - } - - header := self.CurrentBlock().Header() - vmenv := core.NewEnv(statedb, self.EthereumService().BlockChain(), msg, header) - gp := new(core.GasPool).AddGas(common.MaxBig) - res, gas, err := core.ApplyMessage(vmenv, msg, gp) - return common.ToHex(res), gas.String(), err -} - -func (self *XEth) ConfirmTransaction(tx string) bool { - return self.frontend.ConfirmTransaction(tx) -} - -func (self *XEth) doSign(from common.Address, hash common.Hash, didUnlock bool) ([]byte, error) { - sig, err := self.EthereumService().AccountManager().Sign(accounts.Account{Address: from}, hash.Bytes()) - if err == accounts.ErrLocked { - if didUnlock { - return nil, fmt.Errorf("signer account still locked after successful unlock") - } - if !self.frontend.UnlockAccount(from.Bytes()) { - return nil, fmt.Errorf("could not unlock signer account") - } - // retry signing, the account should now be unlocked. - return self.doSign(from, hash, true) - } else if err != nil { - 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) - ) - sig, err := self.doSign(from, hash, didUnlock) - if err != nil { - return "", err - } - return common.ToHex(sig), nil -} - -func isAddress(addr string) bool { - return addrReg.MatchString(addr) -} - -func (self *XEth) Frontend() Frontend { - return self.frontend -} - -func (self *XEth) SignTransaction(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (*types.Transaction, error) { - if len(toStr) > 0 && toStr != "0x" && !isAddress(toStr) { - return nil, errors.New("Invalid address") - } - - var ( - from = common.HexToAddress(fromStr) - to = common.HexToAddress(toStr) - value = common.Big(valueStr) - gas *big.Int - price *big.Int - data []byte - contractCreation bool - ) - - if len(gasStr) == 0 { - gas = DefaultGas() - } else { - gas = common.Big(gasStr) - } - - if len(gasPriceStr) == 0 { - price = self.DefaultGasPrice() - } else { - price = common.Big(gasPriceStr) - } - - data = common.FromHex(codeStr) - if len(toStr) == 0 { - contractCreation = true - } - - var nonce uint64 - if len(nonceStr) != 0 { - nonce = common.Big(nonceStr).Uint64() - } else { - state := self.EthereumService().TxPool().State() - nonce = state.GetNonce(from) - } - var tx *types.Transaction - if contractCreation { - tx = types.NewContractCreation(nonce, value, gas, price, data) - } else { - tx = types.NewTransaction(nonce, to, value, gas, price, data) - } - - signed, err := self.sign(tx, from, false) - if err != nil { - return nil, err - } - - return signed, nil -} - -func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) { - - // 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 - } - - if len(toStr) > 0 && toStr != "0x" && !isAddress(toStr) { - return "", errors.New("Invalid address") - } - - var ( - from = common.HexToAddress(fromStr) - to = common.HexToAddress(toStr) - value = common.Big(valueStr) - gas *big.Int - price *big.Int - data []byte - contractCreation bool - ) - - if len(gasStr) == 0 { - gas = DefaultGas() - } else { - gas = common.Big(gasStr) - } - - if len(gasPriceStr) == 0 { - price = self.DefaultGasPrice() - } else { - price = common.Big(gasPriceStr) - } - - data = common.FromHex(codeStr) - if len(toStr) == 0 { - contractCreation = true - } - - // 2015-05-18 Is this still needed? - // 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) - } - */ - - self.transactMu.Lock() - defer self.transactMu.Unlock() - - var nonce uint64 - if len(nonceStr) != 0 { - nonce = common.Big(nonceStr).Uint64() - } else { - state := self.EthereumService().TxPool().State() - nonce = state.GetNonce(from) - } - var tx *types.Transaction - if contractCreation { - tx = types.NewContractCreation(nonce, value, gas, price, data) - } else { - tx = types.NewTransaction(nonce, to, value, gas, price, data) - } - - signed, err := self.sign(tx, from, false) - if err != nil { - return "", err - } - self.EthereumService().TxPool().SetLocal(signed) - if err = self.EthereumService().TxPool().Add(signed); err != nil { - return "", err - } - - if contractCreation { - addr := crypto.CreateAddress(from, nonce) - glog.V(logger.Info).Infof("Tx(%s) created: %s\n", signed.Hash().Hex(), addr.Hex()) - } else { - glog.V(logger.Info).Infof("Tx(%s) to: %s\n", signed.Hash().Hex(), tx.To().Hex()) - } - - return signed.Hash().Hex(), nil -} - -func (self *XEth) sign(tx *types.Transaction, from common.Address, didUnlock bool) (*types.Transaction, error) { - hash := tx.SigHash() - sig, err := self.doSign(from, hash, didUnlock) - if err != nil { - return tx, err - } - return tx.WithSignature(sig) -} - -// callmsg is the message type used for call transations. -type callmsg struct { - from *state.StateObject - to *common.Address - gas, gasPrice *big.Int - value *big.Int - data []byte -} - -// accessor boilerplate to implement core.Message -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 } - -type logQueue struct { - mu sync.Mutex - - logs vm.Logs - timeout time.Time - id int -} - -func (l *logQueue) add(logs ...*vm.Log) { - l.mu.Lock() - defer l.mu.Unlock() - - l.logs = append(l.logs, logs...) -} - -func (l *logQueue) get() vm.Logs { - l.mu.Lock() - defer l.mu.Unlock() - - l.timeout = time.Now() - tmp := l.logs - l.logs = nil - return tmp -} - -type hashQueue struct { - mu sync.Mutex - - hashes []common.Hash - timeout time.Time - id int -} - -func (l *hashQueue) add(hashes ...common.Hash) { - l.mu.Lock() - defer l.mu.Unlock() - - l.hashes = append(l.hashes, hashes...) -} - -func (l *hashQueue) get() []common.Hash { - l.mu.Lock() - defer l.mu.Unlock() - - l.timeout = time.Now() - tmp := l.hashes - l.hashes = nil - return tmp -} diff --git a/xeth/xeth_test.go b/xeth/xeth_test.go deleted file mode 100644 index e649d20ef..000000000 --- a/xeth/xeth_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package xeth - -import "testing" - -func TestIsAddress(t *testing.T) { - for _, invalid := range []string{ - "0x00", - "0xNN", - "0x00000000000000000000000000000000000000NN", - "0xAAar000000000000000000000000000000000000", - } { - if isAddress(invalid) { - t.Error("Expected", invalid, "to be invalid") - } - } - - for _, valid := range []string{ - "0x0000000000000000000000000000000000000000", - "0xAABBbbCCccff9900000000000000000000000000", - "AABBbbCCccff9900000000000000000000000000", - } { - if !isAddress(valid) { - t.Error("Expected", valid, "to be valid") - } - } -} |