commit
aa1eae67ec
|
@ -138,11 +138,12 @@ type Ethereum struct {
|
||||||
|
|
||||||
// logger logger.LogSystem
|
// logger logger.LogSystem
|
||||||
|
|
||||||
Mining bool
|
Mining bool
|
||||||
DataDir string
|
DataDir string
|
||||||
version string
|
clientVersion string
|
||||||
protocolVersion int
|
ethVersionId int
|
||||||
networkId int
|
netVersionId int
|
||||||
|
shhVersionId int
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(config *Config) (*Ethereum, error) {
|
func New(config *Config) (*Ethereum, error) {
|
||||||
|
@ -177,16 +178,16 @@ func New(config *Config) (*Ethereum, error) {
|
||||||
servlogger.Infof("Protocol Version: %v, Network Id: %v", config.ProtocolVersion, config.NetworkId)
|
servlogger.Infof("Protocol Version: %v, Network Id: %v", config.ProtocolVersion, config.NetworkId)
|
||||||
|
|
||||||
eth := &Ethereum{
|
eth := &Ethereum{
|
||||||
shutdownChan: make(chan bool),
|
shutdownChan: make(chan bool),
|
||||||
blockDb: blockDb,
|
blockDb: blockDb,
|
||||||
stateDb: stateDb,
|
stateDb: stateDb,
|
||||||
extraDb: extraDb,
|
extraDb: extraDb,
|
||||||
eventMux: &event.TypeMux{},
|
eventMux: &event.TypeMux{},
|
||||||
accountManager: config.AccountManager,
|
accountManager: config.AccountManager,
|
||||||
DataDir: config.DataDir,
|
DataDir: config.DataDir,
|
||||||
version: config.Name, // TODO should separate from Name
|
clientVersion: config.Name, // TODO should separate from Name
|
||||||
protocolVersion: config.ProtocolVersion,
|
ethVersionId: config.ProtocolVersion,
|
||||||
networkId: config.NetworkId,
|
netVersionId: config.NetworkId,
|
||||||
}
|
}
|
||||||
|
|
||||||
eth.chainManager = core.NewChainManager(blockDb, stateDb, eth.EventMux())
|
eth.chainManager = core.NewChainManager(blockDb, stateDb, eth.EventMux())
|
||||||
|
@ -195,6 +196,7 @@ func New(config *Config) (*Ethereum, error) {
|
||||||
eth.blockProcessor = core.NewBlockProcessor(stateDb, extraDb, eth.pow, eth.txPool, eth.chainManager, eth.EventMux())
|
eth.blockProcessor = core.NewBlockProcessor(stateDb, extraDb, eth.pow, eth.txPool, eth.chainManager, eth.EventMux())
|
||||||
eth.chainManager.SetProcessor(eth.blockProcessor)
|
eth.chainManager.SetProcessor(eth.blockProcessor)
|
||||||
eth.whisper = whisper.New()
|
eth.whisper = whisper.New()
|
||||||
|
eth.shhVersionId = int(eth.whisper.Version())
|
||||||
eth.miner = miner.New(eth, eth.pow, config.MinerThreads)
|
eth.miner = miner.New(eth, eth.pow, config.MinerThreads)
|
||||||
|
|
||||||
hasBlock := eth.chainManager.HasBlock
|
hasBlock := eth.chainManager.HasBlock
|
||||||
|
@ -324,9 +326,10 @@ func (s *Ethereum) IsListening() bool { return true } // Alwa
|
||||||
func (s *Ethereum) PeerCount() int { return s.net.PeerCount() }
|
func (s *Ethereum) PeerCount() int { return s.net.PeerCount() }
|
||||||
func (s *Ethereum) Peers() []*p2p.Peer { return s.net.Peers() }
|
func (s *Ethereum) Peers() []*p2p.Peer { return s.net.Peers() }
|
||||||
func (s *Ethereum) MaxPeers() int { return s.net.MaxPeers }
|
func (s *Ethereum) MaxPeers() int { return s.net.MaxPeers }
|
||||||
func (s *Ethereum) Version() string { return s.version }
|
func (s *Ethereum) ClientVersion() string { return s.clientVersion }
|
||||||
func (s *Ethereum) ProtocolVersion() int { return s.protocolVersion }
|
func (s *Ethereum) EthVersion() int { return s.ethVersionId }
|
||||||
func (s *Ethereum) NetworkId() int { return s.networkId }
|
func (s *Ethereum) NetVersion() int { return s.netVersionId }
|
||||||
|
func (s *Ethereum) ShhVersion() int { return s.shhVersionId }
|
||||||
|
|
||||||
// Start the ethereum
|
// Start the ethereum
|
||||||
func (s *Ethereum) Start() error {
|
func (s *Ethereum) Start() error {
|
||||||
|
|
12
rpc/api.go
12
rpc/api.go
|
@ -49,7 +49,7 @@ func (api *EthereumApi) Close() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error {
|
func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error {
|
||||||
// Spec at https://github.com/ethereum/wiki/wiki/Generic-JSON-RPC
|
// Spec at https://github.com/ethereum/wiki/wiki/JSON-RPC
|
||||||
rpclogger.Debugf("%s %s", req.Method, req.Params)
|
rpclogger.Debugf("%s %s", req.Method, req.Params)
|
||||||
|
|
||||||
switch req.Method {
|
switch req.Method {
|
||||||
|
@ -60,14 +60,16 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
|
||||||
}
|
}
|
||||||
*reply = common.ToHex(crypto.Sha3(common.FromHex(args.Data)))
|
*reply = common.ToHex(crypto.Sha3(common.FromHex(args.Data)))
|
||||||
case "web3_clientVersion":
|
case "web3_clientVersion":
|
||||||
*reply = api.xeth().Backend().Version()
|
*reply = api.xeth().ClientVersion()
|
||||||
case "net_version":
|
case "net_version":
|
||||||
*reply = string(api.xeth().Backend().ProtocolVersion())
|
*reply = api.xeth().NetworkVersion()
|
||||||
case "net_listening":
|
case "net_listening":
|
||||||
*reply = api.xeth().IsListening()
|
*reply = api.xeth().IsListening()
|
||||||
case "net_peerCount":
|
case "net_peerCount":
|
||||||
v := api.xeth().PeerCount()
|
v := api.xeth().PeerCount()
|
||||||
*reply = common.ToHex(big.NewInt(int64(v)).Bytes())
|
*reply = common.ToHex(big.NewInt(int64(v)).Bytes())
|
||||||
|
case "eth_version":
|
||||||
|
*reply = api.xeth().EthVersion()
|
||||||
case "eth_coinbase":
|
case "eth_coinbase":
|
||||||
// TODO handling of empty coinbase due to lack of accounts
|
// TODO handling of empty coinbase due to lack of accounts
|
||||||
res := api.xeth().Coinbase()
|
res := api.xeth().Coinbase()
|
||||||
|
@ -84,7 +86,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
|
||||||
case "eth_accounts":
|
case "eth_accounts":
|
||||||
*reply = api.xeth().Accounts()
|
*reply = api.xeth().Accounts()
|
||||||
case "eth_blockNumber":
|
case "eth_blockNumber":
|
||||||
v := api.xeth().Backend().ChainManager().CurrentBlock().Number()
|
v := api.xeth().CurrentBlock().Number()
|
||||||
*reply = common.ToHex(v.Bytes())
|
*reply = common.ToHex(v.Bytes())
|
||||||
case "eth_getBalance":
|
case "eth_getBalance":
|
||||||
args := new(GetBalanceArgs)
|
args := new(GetBalanceArgs)
|
||||||
|
@ -406,6 +408,8 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
|
||||||
|
|
||||||
res, _ := api.db.Get([]byte(args.Database + args.Key))
|
res, _ := api.db.Get([]byte(args.Database + args.Key))
|
||||||
*reply = common.ToHex(res)
|
*reply = common.ToHex(res)
|
||||||
|
case "shh_version":
|
||||||
|
*reply = api.xeth().WhisperVersion()
|
||||||
case "shh_post":
|
case "shh_post":
|
||||||
args := new(WhisperMessageArgs)
|
args := new(WhisperMessageArgs)
|
||||||
if err := json.Unmarshal(req.Params, &args); err != nil {
|
if err := json.Unmarshal(req.Params, &args); err != nil {
|
||||||
|
|
|
@ -16,8 +16,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
statusMsg = 0x0
|
statusMsg = 0x0
|
||||||
envelopesMsg = 0x01
|
envelopesMsg = 0x01
|
||||||
|
whisperVersion = 0x02
|
||||||
)
|
)
|
||||||
|
|
||||||
type MessageEvent struct {
|
type MessageEvent struct {
|
||||||
|
@ -56,7 +57,7 @@ func New() *Whisper {
|
||||||
// p2p whisper sub protocol handler
|
// p2p whisper sub protocol handler
|
||||||
whisper.protocol = p2p.Protocol{
|
whisper.protocol = p2p.Protocol{
|
||||||
Name: "shh",
|
Name: "shh",
|
||||||
Version: 2,
|
Version: uint(whisperVersion),
|
||||||
Length: 2,
|
Length: 2,
|
||||||
Run: whisper.msgHandler,
|
Run: whisper.msgHandler,
|
||||||
}
|
}
|
||||||
|
@ -64,6 +65,10 @@ func New() *Whisper {
|
||||||
return whisper
|
return whisper
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *Whisper) Version() uint {
|
||||||
|
return self.protocol.Version
|
||||||
|
}
|
||||||
|
|
||||||
func (self *Whisper) Start() {
|
func (self *Whisper) Start() {
|
||||||
wlogger.Infoln("Whisper started")
|
wlogger.Infoln("Whisper started")
|
||||||
go self.update()
|
go self.update()
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package xeth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Frontend should be implemented by users of XEth. Its methods are
|
||||||
|
// called whenever XEth makes a decision that requires user input.
|
||||||
|
type Frontend interface {
|
||||||
|
// 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 *types.Transaction) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// dummyFrontend is a non-interactive frontend that allows all
|
||||||
|
// transactions but cannot not unlock any keys.
|
||||||
|
type dummyFrontend struct{}
|
||||||
|
|
||||||
|
func (dummyFrontend) UnlockAccount([]byte) bool { return false }
|
||||||
|
func (dummyFrontend) ConfirmTransaction(*types.Transaction) bool { return true }
|
|
@ -29,7 +29,7 @@ func (self *State) SafeGet(addr string) *Object {
|
||||||
func (self *State) safeGet(addr string) *state.StateObject {
|
func (self *State) safeGet(addr string) *state.StateObject {
|
||||||
object := self.state.GetStateObject(common.HexToAddress(addr))
|
object := self.state.GetStateObject(common.HexToAddress(addr))
|
||||||
if object == nil {
|
if object == nil {
|
||||||
object = state.NewStateObject(common.HexToAddress(addr), self.xeth.eth.StateDb())
|
object = state.NewStateObject(common.HexToAddress(addr), self.xeth.backend.StateDb())
|
||||||
}
|
}
|
||||||
|
|
||||||
return object
|
return object
|
||||||
|
|
218
xeth/xeth.go
218
xeth/xeth.go
|
@ -15,12 +15,10 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/eth"
|
||||||
"github.com/ethereum/go-ethereum/event/filter"
|
"github.com/ethereum/go-ethereum/event/filter"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/miner"
|
"github.com/ethereum/go-ethereum/miner"
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
|
||||||
"github.com/ethereum/go-ethereum/whisper"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -30,67 +28,13 @@ var (
|
||||||
defaultGas = big.NewInt(90000) //500000
|
defaultGas = big.NewInt(90000) //500000
|
||||||
)
|
)
|
||||||
|
|
||||||
// to resolve the import cycle
|
|
||||||
type Backend interface {
|
|
||||||
BlockProcessor() *core.BlockProcessor
|
|
||||||
ChainManager() *core.ChainManager
|
|
||||||
AccountManager() *accounts.Manager
|
|
||||||
TxPool() *core.TxPool
|
|
||||||
PeerCount() int
|
|
||||||
IsListening() bool
|
|
||||||
Peers() []*p2p.Peer
|
|
||||||
BlockDb() common.Database
|
|
||||||
StateDb() common.Database
|
|
||||||
ExtraDb() common.Database
|
|
||||||
EventMux() *event.TypeMux
|
|
||||||
Whisper() *whisper.Whisper
|
|
||||||
Miner() *miner.Miner
|
|
||||||
|
|
||||||
IsMining() bool
|
|
||||||
StartMining() error
|
|
||||||
StopMining()
|
|
||||||
Version() string
|
|
||||||
ProtocolVersion() int
|
|
||||||
NetworkId() int
|
|
||||||
}
|
|
||||||
|
|
||||||
// Frontend should be implemented by users of XEth. Its methods are
|
|
||||||
// called whenever XEth makes a decision that requires user input.
|
|
||||||
type Frontend interface {
|
|
||||||
// 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 *types.Transaction) bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// dummyFrontend is a non-interactive frontend that allows all
|
|
||||||
// transactions but cannot not unlock any keys.
|
|
||||||
type dummyFrontend struct{}
|
|
||||||
|
|
||||||
func (dummyFrontend) UnlockAccount([]byte) bool { return false }
|
|
||||||
func (dummyFrontend) ConfirmTransaction(*types.Transaction) bool { return true }
|
|
||||||
|
|
||||||
type XEth struct {
|
type XEth struct {
|
||||||
eth Backend
|
backend *eth.Ethereum
|
||||||
blockProcessor *core.BlockProcessor
|
|
||||||
chainManager *core.ChainManager
|
|
||||||
accountManager *accounts.Manager
|
|
||||||
state *State
|
|
||||||
whisper *Whisper
|
|
||||||
|
|
||||||
frontend Frontend
|
frontend Frontend
|
||||||
|
|
||||||
|
state *State
|
||||||
|
whisper *Whisper
|
||||||
|
|
||||||
quit chan struct{}
|
quit chan struct{}
|
||||||
filterManager *filter.FilterManager
|
filterManager *filter.FilterManager
|
||||||
|
|
||||||
|
@ -103,33 +47,30 @@ type XEth struct {
|
||||||
// regmut sync.Mutex
|
// regmut sync.Mutex
|
||||||
// register map[string][]*interface{} // TODO improve return type
|
// register map[string][]*interface{} // TODO improve return type
|
||||||
|
|
||||||
// Miner agent
|
|
||||||
agent *miner.RemoteAgent
|
agent *miner.RemoteAgent
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates an XEth that uses the given frontend.
|
// New creates an XEth that uses the given frontend.
|
||||||
// If a nil Frontend is provided, a default frontend which
|
// If a nil Frontend is provided, a default frontend which
|
||||||
// confirms all transactions will be used.
|
// confirms all transactions will be used.
|
||||||
func New(eth Backend, frontend Frontend) *XEth {
|
func New(eth *eth.Ethereum, frontend Frontend) *XEth {
|
||||||
xeth := &XEth{
|
xeth := &XEth{
|
||||||
eth: eth,
|
backend: eth,
|
||||||
blockProcessor: eth.BlockProcessor(),
|
frontend: frontend,
|
||||||
chainManager: eth.ChainManager(),
|
whisper: NewWhisper(eth.Whisper()),
|
||||||
accountManager: eth.AccountManager(),
|
quit: make(chan struct{}),
|
||||||
whisper: NewWhisper(eth.Whisper()),
|
filterManager: filter.NewFilterManager(eth.EventMux()),
|
||||||
quit: make(chan struct{}),
|
logs: make(map[int]*logFilter),
|
||||||
filterManager: filter.NewFilterManager(eth.EventMux()),
|
messages: make(map[int]*whisperFilter),
|
||||||
frontend: frontend,
|
agent: miner.NewRemoteAgent(),
|
||||||
logs: make(map[int]*logFilter),
|
|
||||||
messages: make(map[int]*whisperFilter),
|
|
||||||
agent: miner.NewRemoteAgent(),
|
|
||||||
}
|
}
|
||||||
eth.Miner().Register(xeth.agent)
|
eth.Miner().Register(xeth.agent)
|
||||||
|
|
||||||
if frontend == nil {
|
if frontend == nil {
|
||||||
xeth.frontend = dummyFrontend{}
|
xeth.frontend = dummyFrontend{}
|
||||||
}
|
}
|
||||||
xeth.state = NewState(xeth, xeth.chainManager.TransState())
|
xeth.state = NewState(xeth, xeth.backend.ChainManager().TransState())
|
||||||
|
|
||||||
go xeth.start()
|
go xeth.start()
|
||||||
go xeth.filterManager.Start()
|
go xeth.filterManager.Start()
|
||||||
|
|
||||||
|
@ -175,58 +116,63 @@ func (self *XEth) DefaultGasPrice() *big.Int { return defaultGasPrice }
|
||||||
func (self *XEth) RemoteMining() *miner.RemoteAgent { return self.agent }
|
func (self *XEth) RemoteMining() *miner.RemoteAgent { return self.agent }
|
||||||
|
|
||||||
func (self *XEth) AtStateNum(num int64) *XEth {
|
func (self *XEth) AtStateNum(num int64) *XEth {
|
||||||
chain := self.Backend().ChainManager()
|
block := self.getBlockByHeight(num)
|
||||||
var block *types.Block
|
|
||||||
|
|
||||||
// -1 generally means "latest"
|
|
||||||
// -2 means "pending", which has no blocknum
|
|
||||||
if num < 0 {
|
|
||||||
num = chain.CurrentBlock().Number().Int64()
|
|
||||||
}
|
|
||||||
|
|
||||||
block = chain.GetBlockByNumber(uint64(num))
|
|
||||||
|
|
||||||
var st *state.StateDB
|
var st *state.StateDB
|
||||||
if block != nil {
|
if block != nil {
|
||||||
st = state.New(block.Root(), self.Backend().StateDb())
|
st = state.New(block.Root(), self.backend.StateDb())
|
||||||
} else {
|
} else {
|
||||||
st = chain.State()
|
st = self.backend.ChainManager().State()
|
||||||
}
|
}
|
||||||
return self.WithState(st)
|
|
||||||
|
return self.withState(st)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *XEth) Backend() Backend { return self.eth }
|
func (self *XEth) withState(statedb *state.StateDB) *XEth {
|
||||||
func (self *XEth) WithState(statedb *state.StateDB) *XEth {
|
|
||||||
xeth := &XEth{
|
xeth := &XEth{
|
||||||
eth: self.eth,
|
backend: self.backend,
|
||||||
blockProcessor: self.blockProcessor,
|
|
||||||
chainManager: self.chainManager,
|
|
||||||
whisper: self.whisper,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xeth.state = NewState(xeth, statedb)
|
xeth.state = NewState(xeth, statedb)
|
||||||
return xeth
|
return xeth
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *XEth) State() *State { return self.state }
|
func (self *XEth) State() *State { return self.state }
|
||||||
|
|
||||||
func (self *XEth) Whisper() *Whisper { return self.whisper }
|
func (self *XEth) Whisper() *Whisper { return self.whisper }
|
||||||
|
|
||||||
|
func (self *XEth) getBlockByHeight(height int64) *types.Block {
|
||||||
|
var num uint64
|
||||||
|
|
||||||
|
// -1 means "latest"
|
||||||
|
// -2 means "pending", which has no blocknum
|
||||||
|
if height <= -2 {
|
||||||
|
return &types.Block{}
|
||||||
|
} else if height == -1 {
|
||||||
|
num = self.CurrentBlock().NumberU64()
|
||||||
|
} else {
|
||||||
|
num = uint64(height)
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.backend.ChainManager().GetBlockByNumber(num)
|
||||||
|
}
|
||||||
|
|
||||||
func (self *XEth) BlockByHash(strHash string) *Block {
|
func (self *XEth) BlockByHash(strHash string) *Block {
|
||||||
hash := common.HexToHash(strHash)
|
hash := common.HexToHash(strHash)
|
||||||
block := self.chainManager.GetBlock(hash)
|
block := self.backend.ChainManager().GetBlock(hash)
|
||||||
|
|
||||||
return NewBlock(block)
|
return NewBlock(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *XEth) EthBlockByHash(strHash string) *types.Block {
|
func (self *XEth) EthBlockByHash(strHash string) *types.Block {
|
||||||
hash := common.HexToHash(strHash)
|
hash := common.HexToHash(strHash)
|
||||||
block := self.chainManager.GetBlock(hash)
|
block := self.backend.ChainManager().GetBlock(hash)
|
||||||
|
|
||||||
return block
|
return block
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *XEth) EthTransactionByHash(hash string) *types.Transaction {
|
func (self *XEth) EthTransactionByHash(hash string) *types.Transaction {
|
||||||
data, _ := self.eth.ExtraDb().Get(common.FromHex(hash))
|
data, _ := self.backend.ExtraDb().Get(common.FromHex(hash))
|
||||||
if len(data) != 0 {
|
if len(data) != 0 {
|
||||||
return types.NewTransactionFromBytes(data)
|
return types.NewTransactionFromBytes(data)
|
||||||
}
|
}
|
||||||
|
@ -234,29 +180,15 @@ func (self *XEth) EthTransactionByHash(hash string) *types.Transaction {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *XEth) BlockByNumber(num int64) *Block {
|
func (self *XEth) BlockByNumber(num int64) *Block {
|
||||||
if num == -2 {
|
return NewBlock(self.getBlockByHeight(num))
|
||||||
// "pending" is non-existant
|
|
||||||
return &Block{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if num == -1 {
|
|
||||||
return NewBlock(self.chainManager.CurrentBlock())
|
|
||||||
}
|
|
||||||
|
|
||||||
return NewBlock(self.chainManager.GetBlockByNumber(uint64(num)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *XEth) EthBlockByNumber(num int64) *types.Block {
|
func (self *XEth) EthBlockByNumber(num int64) *types.Block {
|
||||||
if num == -2 {
|
return self.getBlockByHeight(num)
|
||||||
// "pending" is non-existant
|
}
|
||||||
return &types.Block{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if num == -1 {
|
func (self *XEth) CurrentBlock() *types.Block {
|
||||||
return self.chainManager.CurrentBlock()
|
return self.backend.ChainManager().CurrentBlock()
|
||||||
}
|
|
||||||
|
|
||||||
return self.chainManager.GetBlockByNumber(uint64(num))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *XEth) Block(v interface{}) *Block {
|
func (self *XEth) Block(v interface{}) *Block {
|
||||||
|
@ -273,7 +205,7 @@ func (self *XEth) Block(v interface{}) *Block {
|
||||||
|
|
||||||
func (self *XEth) Accounts() []string {
|
func (self *XEth) Accounts() []string {
|
||||||
// TODO: check err?
|
// TODO: check err?
|
||||||
accounts, _ := self.eth.AccountManager().Accounts()
|
accounts, _ := self.backend.AccountManager().Accounts()
|
||||||
accountAddresses := make([]string, len(accounts))
|
accountAddresses := make([]string, len(accounts))
|
||||||
for i, ac := range accounts {
|
for i, ac := range accounts {
|
||||||
accountAddresses[i] = common.ToHex(ac.Address)
|
accountAddresses[i] = common.ToHex(ac.Address)
|
||||||
|
@ -282,31 +214,47 @@ func (self *XEth) Accounts() []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *XEth) PeerCount() int {
|
func (self *XEth) PeerCount() int {
|
||||||
return self.eth.PeerCount()
|
return self.backend.PeerCount()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *XEth) IsMining() bool {
|
func (self *XEth) IsMining() bool {
|
||||||
return self.eth.IsMining()
|
return self.backend.IsMining()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *XEth) EthVersion() string {
|
||||||
|
return string(self.backend.EthVersion())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *XEth) NetworkVersion() string {
|
||||||
|
return string(self.backend.NetVersion())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *XEth) WhisperVersion() string {
|
||||||
|
return string(self.backend.ShhVersion())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *XEth) ClientVersion() string {
|
||||||
|
return self.backend.ClientVersion()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *XEth) SetMining(shouldmine bool) bool {
|
func (self *XEth) SetMining(shouldmine bool) bool {
|
||||||
ismining := self.eth.IsMining()
|
ismining := self.backend.IsMining()
|
||||||
if shouldmine && !ismining {
|
if shouldmine && !ismining {
|
||||||
err := self.eth.StartMining()
|
err := self.backend.StartMining()
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
if ismining && !shouldmine {
|
if ismining && !shouldmine {
|
||||||
self.eth.StopMining()
|
self.backend.StopMining()
|
||||||
}
|
}
|
||||||
return self.eth.IsMining()
|
return self.backend.IsMining()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *XEth) IsListening() bool {
|
func (self *XEth) IsListening() bool {
|
||||||
return self.eth.IsListening()
|
return self.backend.IsListening()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *XEth) Coinbase() string {
|
func (self *XEth) Coinbase() string {
|
||||||
cb, _ := self.eth.AccountManager().Coinbase()
|
cb, _ := self.backend.AccountManager().Coinbase()
|
||||||
return common.ToHex(cb)
|
return common.ToHex(cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,7 +297,7 @@ func (self *XEth) SecretToAddress(key string) string {
|
||||||
|
|
||||||
func (self *XEth) RegisterFilter(args *core.FilterOptions) int {
|
func (self *XEth) RegisterFilter(args *core.FilterOptions) int {
|
||||||
var id int
|
var id int
|
||||||
filter := core.NewFilter(self.Backend())
|
filter := core.NewFilter(self.backend)
|
||||||
filter.SetOptions(args)
|
filter.SetOptions(args)
|
||||||
filter.LogsCallback = func(logs state.Logs) {
|
filter.LogsCallback = func(logs state.Logs) {
|
||||||
self.logMut.Lock()
|
self.logMut.Lock()
|
||||||
|
@ -375,7 +323,7 @@ func (self *XEth) UninstallFilter(id int) bool {
|
||||||
|
|
||||||
func (self *XEth) NewFilterString(word string) int {
|
func (self *XEth) NewFilterString(word string) int {
|
||||||
var id int
|
var id int
|
||||||
filter := core.NewFilter(self.Backend())
|
filter := core.NewFilter(self.backend)
|
||||||
|
|
||||||
switch word {
|
switch word {
|
||||||
case "pending":
|
case "pending":
|
||||||
|
@ -427,7 +375,7 @@ func (self *XEth) Logs(id int) state.Logs {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *XEth) AllLogs(args *core.FilterOptions) state.Logs {
|
func (self *XEth) AllLogs(args *core.FilterOptions) state.Logs {
|
||||||
filter := core.NewFilter(self.Backend())
|
filter := core.NewFilter(self.backend)
|
||||||
filter.SetOptions(args)
|
filter.SetOptions(args)
|
||||||
|
|
||||||
return filter.Find()
|
return filter.Find()
|
||||||
|
@ -543,7 +491,7 @@ func (self *XEth) FromNumber(str string) string {
|
||||||
|
|
||||||
func (self *XEth) PushTx(encodedTx string) (string, error) {
|
func (self *XEth) PushTx(encodedTx string) (string, error) {
|
||||||
tx := types.NewTransactionFromBytes(common.FromHex(encodedTx))
|
tx := types.NewTransactionFromBytes(common.FromHex(encodedTx))
|
||||||
err := self.eth.TxPool().Add(tx)
|
err := self.backend.TxPool().Add(tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -556,7 +504,7 @@ func (self *XEth) PushTx(encodedTx string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr string) (string, error) {
|
func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr string) (string, error) {
|
||||||
statedb := self.State().State() //self.chainManager.TransState()
|
statedb := self.State().State() //self.eth.ChainManager().TransState()
|
||||||
msg := callmsg{
|
msg := callmsg{
|
||||||
from: statedb.GetOrNewStateObject(common.HexToAddress(fromStr)),
|
from: statedb.GetOrNewStateObject(common.HexToAddress(fromStr)),
|
||||||
to: common.HexToAddress(toStr),
|
to: common.HexToAddress(toStr),
|
||||||
|
@ -573,8 +521,8 @@ func (self *XEth) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr, dataStr st
|
||||||
msg.gasPrice = defaultGasPrice
|
msg.gasPrice = defaultGasPrice
|
||||||
}
|
}
|
||||||
|
|
||||||
block := self.chainManager.CurrentBlock()
|
block := self.CurrentBlock()
|
||||||
vmenv := core.NewEnv(statedb, self.chainManager, msg, block)
|
vmenv := core.NewEnv(statedb, self.backend.ChainManager(), msg, block)
|
||||||
|
|
||||||
res, err := vmenv.Call(msg.from, msg.to, msg.data, msg.gas, msg.gasPrice, msg.value)
|
res, err := vmenv.Call(msg.from, msg.to, msg.data, msg.gas, msg.gasPrice, msg.value)
|
||||||
return common.ToHex(res), err
|
return common.ToHex(res), err
|
||||||
|
@ -635,14 +583,14 @@ func (self *XEth) Transact(fromStr, toStr, valueStr, gasStr, gasPriceStr, codeSt
|
||||||
tx = types.NewTransactionMessage(to, value.BigInt(), gas, price, data)
|
tx = types.NewTransactionMessage(to, value.BigInt(), gas, price, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
state := self.chainManager.TxState()
|
state := self.backend.ChainManager().TxState()
|
||||||
nonce := state.NewNonce(from)
|
nonce := state.NewNonce(from)
|
||||||
tx.SetNonce(nonce)
|
tx.SetNonce(nonce)
|
||||||
|
|
||||||
if err := self.sign(tx, from, false); err != nil {
|
if err := self.sign(tx, from, false); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
if err := self.eth.TxPool().Add(tx); err != nil {
|
if err := self.backend.TxPool().Add(tx); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -656,7 +604,7 @@ func (self *XEth) Transact(fromStr, toStr, valueStr, gasStr, gasPriceStr, codeSt
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *XEth) sign(tx *types.Transaction, from common.Address, didUnlock bool) error {
|
func (self *XEth) sign(tx *types.Transaction, from common.Address, didUnlock bool) error {
|
||||||
sig, err := self.accountManager.Sign(accounts.Account{Address: from.Bytes()}, tx.Hash().Bytes())
|
sig, err := self.backend.AccountManager().Sign(accounts.Account{Address: from.Bytes()}, tx.Hash().Bytes())
|
||||||
if err == accounts.ErrLocked {
|
if err == accounts.ErrLocked {
|
||||||
if didUnlock {
|
if didUnlock {
|
||||||
return fmt.Errorf("sender account still locked after successful unlock")
|
return fmt.Errorf("sender account still locked after successful unlock")
|
||||||
|
|
Loading…
Reference in New Issue