Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
a59bb053
Commit
a59bb053
authored
Mar 20, 2015
by
obscuren
Browse files
Options
Browse Files
Download
Plain Diff
merge
parents
deee9cb1
28e19712
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
635 additions
and
730 deletions
+635
-730
filter.go
core/filter.go
+2
-2
eth_filter.go
event/filter/eth_filter.go
+7
-4
api.go
rpc/api.go
+177
-558
api_test.go
rpc/api_test.go
+32
-32
args.go
rpc/args.go
+18
-8
args_test.go
rpc/args_test.go
+16
-16
http.go
rpc/http.go
+8
-8
messages_test.go
rpc/messages_test.go
+41
-0
responses.go
rpc/responses.go
+26
-0
util.go
rpc/util.go
+0
-86
xeth.go
xeth/xeth.go
+308
-16
No files found.
core/filter.go
View file @
a59bb053
...
@@ -34,7 +34,7 @@ type Filter struct {
...
@@ -34,7 +34,7 @@ type Filter struct {
topics
[][]
common
.
Hash
topics
[][]
common
.
Hash
BlockCallback
func
(
*
types
.
Block
,
state
.
Logs
)
BlockCallback
func
(
*
types
.
Block
,
state
.
Logs
)
PendingCallback
func
(
*
types
.
Block
,
state
.
Logs
)
PendingCallback
func
(
*
types
.
Transaction
)
LogsCallback
func
(
state
.
Logs
)
LogsCallback
func
(
state
.
Logs
)
}
}
...
@@ -46,7 +46,7 @@ func NewFilter(eth Backend) *Filter {
...
@@ -46,7 +46,7 @@ func NewFilter(eth Backend) *Filter {
// SetOptions copies the filter options to the filter it self. The reason for this "silly" copy
// SetOptions copies the filter options to the filter it self. The reason for this "silly" copy
// is simply because named arguments in this case is extremely nice and readable.
// is simply because named arguments in this case is extremely nice and readable.
func
(
self
*
Filter
)
SetOptions
(
options
FilterOptions
)
{
func
(
self
*
Filter
)
SetOptions
(
options
*
FilterOptions
)
{
self
.
earliest
=
options
.
Earliest
self
.
earliest
=
options
.
Earliest
self
.
latest
=
options
.
Latest
self
.
latest
=
options
.
Latest
self
.
skip
=
options
.
Skip
self
.
skip
=
options
.
Skip
...
...
event/filter/eth_filter.go
View file @
a59bb053
...
@@ -48,7 +48,9 @@ func (self *FilterManager) InstallFilter(filter *core.Filter) (id int) {
...
@@ -48,7 +48,9 @@ func (self *FilterManager) InstallFilter(filter *core.Filter) (id int) {
func
(
self
*
FilterManager
)
UninstallFilter
(
id
int
)
{
func
(
self
*
FilterManager
)
UninstallFilter
(
id
int
)
{
self
.
filterMu
.
Lock
()
self
.
filterMu
.
Lock
()
defer
self
.
filterMu
.
Unlock
()
defer
self
.
filterMu
.
Unlock
()
if
_
,
ok
:=
self
.
filters
[
id
];
ok
{
delete
(
self
.
filters
,
id
)
delete
(
self
.
filters
,
id
)
}
}
}
// GetFilter retrieves a filter installed using InstallFilter.
// GetFilter retrieves a filter installed using InstallFilter.
...
@@ -62,8 +64,9 @@ func (self *FilterManager) GetFilter(id int) *core.Filter {
...
@@ -62,8 +64,9 @@ func (self *FilterManager) GetFilter(id int) *core.Filter {
func
(
self
*
FilterManager
)
filterLoop
()
{
func
(
self
*
FilterManager
)
filterLoop
()
{
// Subscribe to events
// Subscribe to events
events
:=
self
.
eventMux
.
Subscribe
(
events
:=
self
.
eventMux
.
Subscribe
(
core
.
PendingBlockEvent
{},
//
core.PendingBlockEvent{},
core
.
ChainEvent
{},
core
.
ChainEvent
{},
core
.
TxPreEvent
{},
state
.
Logs
(
nil
))
state
.
Logs
(
nil
))
out
:
out
:
...
@@ -82,11 +85,11 @@ out:
...
@@ -82,11 +85,11 @@ out:
}
}
self
.
filterMu
.
RUnlock
()
self
.
filterMu
.
RUnlock
()
case
core
.
PendingBlock
Event
:
case
core
.
TxPre
Event
:
self
.
filterMu
.
RLock
()
self
.
filterMu
.
RLock
()
for
_
,
filter
:=
range
self
.
filters
{
for
_
,
filter
:=
range
self
.
filters
{
if
filter
.
PendingCallback
!=
nil
{
if
filter
.
PendingCallback
!=
nil
{
filter
.
PendingCallback
(
event
.
Block
,
event
.
Logs
)
filter
.
PendingCallback
(
event
.
Tx
)
}
}
}
}
self
.
filterMu
.
RUnlock
()
self
.
filterMu
.
RUnlock
()
...
...
rpc/api.go
View file @
a59bb053
...
@@ -2,491 +2,49 @@ package rpc
...
@@ -2,491 +2,49 @@ package rpc
import
(
import
(
"encoding/json"
"encoding/json"
"fmt"
"math/big"
"math/big"
"path"
"path"
"strings"
"sync"
"sync"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/event/filter"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/xeth"
"github.com/ethereum/go-ethereum/xeth"
)
)
var
(
defaultGasPrice
=
big
.
NewInt
(
150000000000
)
defaultGas
=
big
.
NewInt
(
500000
)
filterTickerTime
=
5
*
time
.
Minute
)
type
EthereumApi
struct
{
type
EthereumApi
struct
{
eth
*
xeth
.
XEth
eth
*
xeth
.
XEth
xethMu
sync
.
RWMutex
xethMu
sync
.
RWMutex
mux
*
event
.
TypeMux
quit
chan
struct
{}
filterManager
*
filter
.
FilterManager
logMut
sync
.
RWMutex
logs
map
[
int
]
*
logFilter
messagesMut
sync
.
RWMutex
messages
map
[
int
]
*
whisperFilter
// Register keeps a list of accounts and transaction data
regmut
sync
.
Mutex
register
map
[
string
][]
*
NewTxArgs
db
common
.
Database
db
common
.
Database
}
}
func
NewEthereumApi
(
eth
*
xeth
.
XEth
,
dataDir
string
)
*
EthereumApi
{
func
NewEthereumApi
(
eth
*
xeth
.
XEth
,
dataDir
string
)
*
EthereumApi
{
// What about when dataDir is empty?
db
,
_
:=
ethdb
.
NewLDBDatabase
(
path
.
Join
(
dataDir
,
"dapps"
))
db
,
_
:=
ethdb
.
NewLDBDatabase
(
path
.
Join
(
dataDir
,
"dapps"
))
api
:=
&
EthereumApi
{
api
:=
&
EthereumApi
{
eth
:
eth
,
eth
:
eth
,
mux
:
eth
.
Backend
()
.
EventMux
(),
quit
:
make
(
chan
struct
{}),
filterManager
:
filter
.
NewFilterManager
(
eth
.
Backend
()
.
EventMux
()),
logs
:
make
(
map
[
int
]
*
logFilter
),
messages
:
make
(
map
[
int
]
*
whisperFilter
),
db
:
db
,
db
:
db
,
}
}
go
api
.
filterManager
.
Start
()
go
api
.
start
()
return
api
return
api
}
}
func
(
self
*
EthereumApi
)
xethWithStateNum
(
num
int64
)
*
xeth
.
XEth
{
func
(
self
*
EthereumApi
)
xeth
()
*
xeth
.
XEth
{
chain
:=
self
.
xeth
()
.
Backend
()
.
ChainManager
()
self
.
xethMu
.
RLock
()
var
block
*
types
.
Block
defer
self
.
xethMu
.
RUnlock
()
if
num
<
0
{
num
=
chain
.
CurrentBlock
()
.
Number
()
.
Int64
()
+
num
+
1
}
block
=
chain
.
GetBlockByNumber
(
uint64
(
num
))
var
st
*
state
.
StateDB
if
block
!=
nil
{
st
=
state
.
New
(
block
.
Root
(),
self
.
xeth
()
.
Backend
()
.
StateDb
())
}
else
{
st
=
chain
.
State
()
}
return
self
.
xeth
()
.
WithState
(
st
)
}
func
(
self
*
EthereumApi
)
getStateWithNum
(
num
int64
)
*
xeth
.
State
{
return
self
.
xethWithStateNum
(
num
)
.
State
()
}
func
(
self
*
EthereumApi
)
start
()
{
timer
:=
time
.
NewTicker
(
2
*
time
.
Second
)
done
:
for
{
select
{
case
<-
timer
.
C
:
self
.
logMut
.
Lock
()
self
.
messagesMut
.
Lock
()
for
id
,
filter
:=
range
self
.
logs
{
if
time
.
Since
(
filter
.
timeout
)
>
filterTickerTime
{
self
.
filterManager
.
UninstallFilter
(
id
)
delete
(
self
.
logs
,
id
)
}
}
for
id
,
filter
:=
range
self
.
messages
{
if
time
.
Since
(
filter
.
timeout
)
>
filterTickerTime
{
self
.
xeth
()
.
Whisper
()
.
Unwatch
(
id
)
delete
(
self
.
messages
,
id
)
}
}
self
.
messagesMut
.
Unlock
()
self
.
logMut
.
Unlock
()
case
<-
self
.
quit
:
break
done
}
}
}
func
(
self
*
EthereumApi
)
stop
()
{
close
(
self
.
quit
)
}
// func (self *EthereumApi) Register(args string, reply *interface{}) error {
// self.regmut.Lock()
// defer self.regmut.Unlock()
// if _, ok := self.register[args]; ok {
// self.register[args] = nil // register with empty
// }
// return nil
// }
// func (self *EthereumApi) Unregister(args string, reply *interface{}) error {
// self.regmut.Lock()
// defer self.regmut.Unlock()
// delete(self.register, args)
// return nil
// }
// func (self *EthereumApi) WatchTx(args string, reply *interface{}) error {
// self.regmut.Lock()
// defer self.regmut.Unlock()
// txs := self.register[args]
// self.register[args] = nil
// *reply = txs
// return nil
// }
func
(
self
*
EthereumApi
)
NewFilter
(
args
*
FilterOptions
,
reply
*
interface
{})
error
{
var
id
int
filter
:=
core
.
NewFilter
(
self
.
xeth
()
.
Backend
())
filter
.
SetOptions
(
toFilterOptions
(
args
))
filter
.
LogsCallback
=
func
(
logs
state
.
Logs
)
{
self
.
logMut
.
Lock
()
defer
self
.
logMut
.
Unlock
()
self
.
logs
[
id
]
.
add
(
logs
...
)
}
id
=
self
.
filterManager
.
InstallFilter
(
filter
)
self
.
logs
[
id
]
=
&
logFilter
{
timeout
:
time
.
Now
()}
*
reply
=
common
.
ToHex
(
big
.
NewInt
(
int64
(
id
))
.
Bytes
())
return
nil
}
func
(
self
*
EthereumApi
)
UninstallFilter
(
id
int
,
reply
*
interface
{})
error
{
if
_
,
ok
:=
self
.
logs
[
id
];
ok
{
delete
(
self
.
logs
,
id
)
}
self
.
filterManager
.
UninstallFilter
(
id
)
*
reply
=
true
return
nil
}
func
(
self
*
EthereumApi
)
NewFilterString
(
args
*
FilterStringArgs
,
reply
*
interface
{})
error
{
var
id
int
filter
:=
core
.
NewFilter
(
self
.
xeth
()
.
Backend
())
callback
:=
func
(
block
*
types
.
Block
,
logs
state
.
Logs
)
{
self
.
logMut
.
Lock
()
defer
self
.
logMut
.
Unlock
()
for
_
,
log
:=
range
logs
{
self
.
logs
[
id
]
.
add
(
log
)
}
self
.
logs
[
id
]
.
add
(
&
state
.
StateLog
{})
}
switch
args
.
Word
{
case
"pending"
:
filter
.
PendingCallback
=
callback
case
"latest"
:
filter
.
BlockCallback
=
callback
default
:
return
NewValidationError
(
"Word"
,
"Must be `latest` or `pending`"
)
}
id
=
self
.
filterManager
.
InstallFilter
(
filter
)
self
.
logs
[
id
]
=
&
logFilter
{
timeout
:
time
.
Now
()}
*
reply
=
common
.
ToHex
(
big
.
NewInt
(
int64
(
id
))
.
Bytes
())
return
nil
}
func
(
self
*
EthereumApi
)
FilterChanged
(
id
int
,
reply
*
interface
{})
error
{
self
.
logMut
.
Lock
()
defer
self
.
logMut
.
Unlock
()
if
self
.
logs
[
id
]
!=
nil
{
*
reply
=
toLogs
(
self
.
logs
[
id
]
.
get
())
}
return
nil
}
func
(
self
*
EthereumApi
)
Logs
(
id
int
,
reply
*
interface
{})
error
{
self
.
logMut
.
Lock
()
defer
self
.
logMut
.
Unlock
()
filter
:=
self
.
filterManager
.
GetFilter
(
id
)
if
filter
!=
nil
{
*
reply
=
toLogs
(
filter
.
Find
())
}
return
nil
}
func
(
self
*
EthereumApi
)
AllLogs
(
args
*
FilterOptions
,
reply
*
interface
{})
error
{
filter
:=
core
.
NewFilter
(
self
.
xeth
()
.
Backend
())
filter
.
SetOptions
(
toFilterOptions
(
args
))
*
reply
=
toLogs
(
filter
.
Find
())
return
nil
}
func
(
p
*
EthereumApi
)
Transact
(
args
*
NewTxArgs
,
reply
*
interface
{})
(
err
error
)
{
// 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)
}
*/
if
err
:=
args
.
requirements
();
err
!=
nil
{
return
err
}
// TODO: align default values to have the same type, e.g. not depend on
// common.Value conversions later on
if
args
.
Gas
.
Cmp
(
big
.
NewInt
(
0
))
==
0
{
args
.
Gas
=
defaultGas
}
if
args
.
GasPrice
.
Cmp
(
big
.
NewInt
(
0
))
==
0
{
args
.
GasPrice
=
defaultGasPrice
}
*
reply
,
err
=
p
.
xeth
()
.
Transact
(
args
.
From
,
args
.
To
,
args
.
Value
.
String
(),
args
.
Gas
.
String
(),
args
.
GasPrice
.
String
(),
args
.
Data
)
if
err
!=
nil
{
fmt
.
Println
(
"err:"
,
err
)
return
err
}
return
nil
}
func
(
p
*
EthereumApi
)
Call
(
args
*
NewTxArgs
,
reply
*
interface
{})
error
{
result
,
err
:=
p
.
xethWithStateNum
(
args
.
BlockNumber
)
.
Call
(
args
.
From
,
args
.
To
,
args
.
Value
.
String
(),
args
.
Gas
.
String
(),
args
.
GasPrice
.
String
(),
args
.
Data
)
if
err
!=
nil
{
return
err
}
*
reply
=
result
return
nil
}
func
(
p
*
EthereumApi
)
GetBalance
(
args
*
GetBalanceArgs
,
reply
*
interface
{})
error
{
if
err
:=
args
.
requirements
();
err
!=
nil
{
return
err
}
state
:=
p
.
getStateWithNum
(
args
.
BlockNumber
)
.
SafeGet
(
args
.
Address
)
*
reply
=
common
.
ToHex
(
state
.
Balance
()
.
Bytes
())
return
nil
}
func
(
p
*
EthereumApi
)
GetStorage
(
args
*
GetStorageArgs
,
reply
*
interface
{})
error
{
if
err
:=
args
.
requirements
();
err
!=
nil
{
return
err
}
*
reply
=
p
.
getStateWithNum
(
args
.
BlockNumber
)
.
SafeGet
(
args
.
Address
)
.
Storage
()
return
nil
}
func
(
p
*
EthereumApi
)
GetStorageAt
(
args
*
GetStorageAtArgs
,
reply
*
interface
{})
error
{
if
err
:=
args
.
requirements
();
err
!=
nil
{
return
err
}
state
:=
p
.
getStateWithNum
(
args
.
BlockNumber
)
.
SafeGet
(
args
.
Address
)
value
:=
state
.
StorageString
(
args
.
Key
)
var
hx
string
if
strings
.
Index
(
args
.
Key
,
"0x"
)
==
0
{
hx
=
string
([]
byte
(
args
.
Key
)[
2
:
])
}
else
{
// Convert the incoming string (which is a bigint) into hex
i
,
_
:=
new
(
big
.
Int
)
.
SetString
(
args
.
Key
,
10
)
hx
=
common
.
Bytes2Hex
(
i
.
Bytes
())
}
rpclogger
.
Debugf
(
"GetStateAt(%s, %s)
\n
"
,
args
.
Address
,
hx
)
*
reply
=
map
[
string
]
string
{
args
.
Key
:
value
.
Str
()}
return
nil
}
func
(
p
*
EthereumApi
)
GetTxCountAt
(
args
*
GetTxCountArgs
,
reply
*
interface
{})
error
{
err
:=
args
.
requirements
()
if
err
!=
nil
{
return
err
}
*
reply
=
p
.
xethWithStateNum
(
args
.
BlockNumber
)
.
TxCountAt
(
args
.
Address
)
return
nil
}
func
(
p
*
EthereumApi
)
GetData
(
args
*
GetDataArgs
,
reply
*
interface
{})
error
{
if
err
:=
args
.
requirements
();
err
!=
nil
{
return
err
}
*
reply
=
p
.
xethWithStateNum
(
args
.
BlockNumber
)
.
CodeAt
(
args
.
Address
)
return
nil
}
func
(
p
*
EthereumApi
)
GetCompilers
(
reply
*
interface
{})
error
{
c
:=
[]
string
{
""
}
*
reply
=
c
return
nil
}
func
(
p
*
EthereumApi
)
DbPut
(
args
*
DbArgs
,
reply
*
interface
{})
error
{
if
err
:=
args
.
requirements
();
err
!=
nil
{
return
err
}
p
.
db
.
Put
([]
byte
(
args
.
Database
+
args
.
Key
),
[]
byte
(
args
.
Value
))
*
reply
=
true
return
nil
}
func
(
p
*
EthereumApi
)
DbGet
(
args
*
DbArgs
,
reply
*
interface
{})
error
{
if
err
:=
args
.
requirements
();
err
!=
nil
{
return
err
}
res
,
_
:=
p
.
db
.
Get
([]
byte
(
args
.
Database
+
args
.
Key
))
*
reply
=
string
(
res
)
return
nil
}
func
(
p
*
EthereumApi
)
NewWhisperIdentity
(
reply
*
interface
{})
error
{
*
reply
=
p
.
xeth
()
.
Whisper
()
.
NewIdentity
()
return
nil
}
// func (p *EthereumApi) RemoveWhisperIdentity(args *WhisperIdentityArgs, reply *interface{}) error {
// *reply = p.xeth().Whisper().RemoveIdentity(args.Identity)
// return nil
// }
func
(
p
*
EthereumApi
)
NewWhisperFilter
(
args
*
WhisperFilterArgs
,
reply
*
interface
{})
error
{
var
id
int
opts
:=
new
(
xeth
.
Options
)
opts
.
From
=
args
.
From
opts
.
To
=
args
.
To
opts
.
Topics
=
args
.
Topics
opts
.
Fn
=
func
(
msg
xeth
.
WhisperMessage
)
{
p
.
messagesMut
.
Lock
()
defer
p
.
messagesMut
.
Unlock
()
p
.
messages
[
id
]
.
add
(
msg
)
// = append(p.messages[id], msg)
}
id
=
p
.
xeth
()
.
Whisper
()
.
Watch
(
opts
)
p
.
messages
[
id
]
=
&
whisperFilter
{
timeout
:
time
.
Now
()}
*
reply
=
common
.
ToHex
(
big
.
NewInt
(
int64
(
id
))
.
Bytes
())
return
nil
}
func
(
p
*
EthereumApi
)
UninstallWhisperFilter
(
id
int
,
reply
*
interface
{})
error
{
delete
(
p
.
messages
,
id
)
*
reply
=
true
return
nil
}
func
(
self
*
EthereumApi
)
MessagesChanged
(
id
int
,
reply
*
interface
{})
error
{
self
.
messagesMut
.
Lock
()
defer
self
.
messagesMut
.
Unlock
()
if
self
.
messages
[
id
]
!=
nil
{
*
reply
=
self
.
messages
[
id
]
.
get
()
}
return
nil
}
func
(
p
*
EthereumApi
)
WhisperPost
(
args
*
WhisperMessageArgs
,
reply
*
interface
{})
error
{
err
:=
p
.
xeth
()
.
Whisper
()
.
Post
(
args
.
Payload
,
args
.
To
,
args
.
From
,
args
.
Topics
,
args
.
Priority
,
args
.
Ttl
)
if
err
!=
nil
{
return
err
}
*
reply
=
true
return
nil
}
func
(
p
*
EthereumApi
)
HasWhisperIdentity
(
args
string
,
reply
*
interface
{})
error
{
*
reply
=
p
.
xeth
()
.
Whisper
()
.
HasIdentity
(
args
)
return
nil
}
func
(
p
*
EthereumApi
)
WhisperMessages
(
id
int
,
reply
*
interface
{})
error
{
*
reply
=
p
.
xeth
()
.
Whisper
()
.
Messages
(
id
)
return
nil
}
func
(
p
*
EthereumApi
)
GetTransactionByHash
(
hash
string
,
reply
*
interface
{})
error
{
tx
:=
p
.
xeth
()
.
EthTransactionByHash
(
hash
)
if
tx
!=
nil
{
*
reply
=
NewTransactionRes
(
tx
)
}
return
nil
}
func
(
p
*
EthereumApi
)
GetBlockByHash
(
blockhash
string
,
includetx
bool
)
(
*
BlockRes
,
error
)
{
block
:=
p
.
xeth
()
.
EthBlockByHash
(
blockhash
)
br
:=
NewBlockRes
(
block
)
br
.
fullTx
=
includetx
return
br
,
nil
}
func
(
p
*
EthereumApi
)
GetBlockByNumber
(
blocknum
int64
,
includetx
bool
)
(
*
BlockRes
,
error
)
{
block
:=
p
.
xeth
()
.
EthBlockByNumber
(
blocknum
)
br
:=
NewBlockRes
(
block
)
br
.
fullTx
=
includetx
return
br
,
nil
}
func
(
p
*
EthereumApi
)
GetBlockTransactionCountByHash
(
blockhash
string
)
(
int64
,
error
)
{
block
:=
p
.
xeth
()
.
EthBlockByHash
(
blockhash
)
br
:=
NewBlockRes
(
block
)
return
int64
(
len
(
br
.
Transactions
)),
nil
}
func
(
p
*
EthereumApi
)
GetBlockTransactionCountByNumber
(
blocknum
int64
)
(
int64
,
error
)
{
block
:=
p
.
xeth
()
.
EthBlockByNumber
(
blocknum
)
br
:=
NewBlockRes
(
block
)
return
int64
(
len
(
br
.
Transactions
)),
nil
}
func
(
p
*
EthereumApi
)
GetBlockUncleCountByHash
(
blockhash
string
)
(
int64
,
error
)
{
return
self
.
eth
block
:=
p
.
xeth
()
.
EthBlockByHash
(
blockhash
)
br
:=
NewBlockRes
(
block
)
return
int64
(
len
(
br
.
Uncles
)),
nil
}
}
func
(
p
*
EthereumApi
)
GetBlockUncleCountByNumber
(
blocknum
int64
)
(
int64
,
error
)
{
func
(
self
*
EthereumApi
)
xethAtStateNum
(
num
int64
)
*
xeth
.
XEth
{
block
:=
p
.
xeth
()
.
EthBlockByNumber
(
blocknum
)
return
self
.
xeth
()
.
AtStateNum
(
num
)
br
:=
NewBlockRes
(
block
)
return
int64
(
len
(
br
.
Uncles
)),
nil
}
}
func
(
p
*
EthereumApi
)
GetRequestReply
(
req
*
RpcRequest
,
reply
*
interface
{})
error
{
func
(
p
*
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/Generic-JSON-RPC
rpclogger
.
Debugf
(
"%s %s"
,
req
.
Method
,
req
.
Params
)
rpclogger
.
Debugf
(
"%s %s"
,
req
.
Method
,
req
.
Params
)
switch
req
.
Method
{
switch
req
.
Method
{
case
"web3_sha3"
:
case
"web3_sha3"
:
args
:=
new
(
Sha3Args
)
args
:=
new
(
Sha3Args
)
...
@@ -501,7 +59,8 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
...
@@ -501,7 +59,8 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
case
"net_listening"
:
case
"net_listening"
:
*
reply
=
p
.
xeth
()
.
IsListening
()
*
reply
=
p
.
xeth
()
.
IsListening
()
case
"net_peerCount"
:
case
"net_peerCount"
:
*
reply
=
common
.
ToHex
(
big
.
NewInt
(
int64
(
p
.
xeth
()
.
PeerCount
()))
.
Bytes
())
v
:=
p
.
xeth
()
.
PeerCount
()
*
reply
=
common
.
ToHex
(
big
.
NewInt
(
int64
(
v
))
.
Bytes
())
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
:=
p
.
xeth
()
.
Coinbase
()
res
:=
p
.
xeth
()
.
Coinbase
()
...
@@ -513,97 +72,131 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
...
@@ -513,97 +72,131 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
case
"eth_mining"
:
case
"eth_mining"
:
*
reply
=
p
.
xeth
()
.
IsMining
()
*
reply
=
p
.
xeth
()
.
IsMining
()
case
"eth_gasPrice"
:
case
"eth_gasPrice"
:
*
reply
=
common
.
ToHex
(
defaultGasPrice
.
Bytes
())
v
:=
p
.
xeth
()
.
DefaultGas
()
*
reply
=
common
.
ToHex
(
v
.
Bytes
())
case
"eth_accounts"
:
case
"eth_accounts"
:
*
reply
=
p
.
xeth
()
.
Accounts
()
*
reply
=
p
.
xeth
()
.
Accounts
()
case
"eth_blockNumber"
:
case
"eth_blockNumber"
:
*
reply
=
common
.
ToHex
(
p
.
xeth
()
.
Backend
()
.
ChainManager
()
.
CurrentBlock
()
.
Number
()
.
Bytes
())
v
:=
p
.
xeth
()
.
Backend
()
.
ChainManager
()
.
CurrentBlock
()
.
Number
()
*
reply
=
common
.
ToHex
(
v
.
Bytes
())
case
"eth_getBalance"
:
case
"eth_getBalance"
:
args
:=
new
(
GetBalanceArgs
)
args
:=
new
(
GetBalanceArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
return
p
.
GetBalance
(
args
,
reply
)
if
err
:=
args
.
requirements
();
err
!=
nil
{
return
err
}
v
:=
p
.
xethAtStateNum
(
args
.
BlockNumber
)
.
State
()
.
SafeGet
(
args
.
Address
)
.
Balance
()
*
reply
=
common
.
ToHex
(
v
.
Bytes
())
case
"eth_getStorage"
,
"eth_storageAt"
:
case
"eth_getStorage"
,
"eth_storageAt"
:
args
:=
new
(
GetStorageArgs
)
args
:=
new
(
GetStorageArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
return
p
.
GetStorage
(
args
,
reply
)
if
err
:=
args
.
requirements
();
err
!=
nil
{
return
err
}
*
reply
=
p
.
xethAtStateNum
(
args
.
BlockNumber
)
.
State
()
.
SafeGet
(
args
.
Address
)
.
Storage
()
case
"eth_getStorageAt"
:
case
"eth_getStorageAt"
:
args
:=
new
(
GetStorageAtArgs
)
args
:=
new
(
GetStorageAtArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
return
p
.
GetStorageAt
(
args
,
reply
)
if
err
:=
args
.
requirements
();
err
!=
nil
{
return
err
}
state
:=
p
.
xethAtStateNum
(
args
.
BlockNumber
)
.
State
()
.
SafeGet
(
args
.
Address
)
value
:=
state
.
StorageString
(
args
.
Key
)
*
reply
=
common
.
Bytes2Hex
(
value
.
Bytes
())
case
"eth_getTransactionCount"
:
case
"eth_getTransactionCount"
:
args
:=
new
(
GetTxCountArgs
)
args
:=
new
(
GetTxCountArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
return
p
.
GetTxCountAt
(
args
,
reply
)
err
:=
args
.
requirements
()
if
err
!=
nil
{
return
err
}
*
reply
=
p
.
xethAtStateNum
(
args
.
BlockNumber
)
.
TxCountAt
(
args
.
Address
)
case
"eth_getBlockTransactionCountByHash"
:
case
"eth_getBlockTransactionCountByHash"
:
args
:=
new
(
GetBlockByHashArgs
)
args
:=
new
(
GetBlockByHashArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
v
,
err
:=
p
.
GetBlockTransactionCountByHash
(
args
.
BlockHash
)
block
:=
NewBlockRes
(
p
.
xeth
()
.
EthBlockByHash
(
args
.
BlockHash
))
if
err
!=
nil
{
*
reply
=
common
.
ToHex
(
big
.
NewInt
(
int64
(
len
(
block
.
Transactions
)))
.
Bytes
())
return
err
}
*
reply
=
common
.
ToHex
(
big
.
NewInt
(
v
)
.
Bytes
())
case
"eth_getBlockTransactionCountByNumber"
:
case
"eth_getBlockTransactionCountByNumber"
:
args
:=
new
(
GetBlockByNumberArgs
)
args
:=
new
(
GetBlockByNumberArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
v
,
err
:=
p
.
GetBlockTransactionCountByNumber
(
args
.
BlockNumber
)
block
:=
NewBlockRes
(
p
.
xeth
()
.
EthBlockByNumber
(
args
.
BlockNumber
))
if
err
!=
nil
{
*
reply
=
common
.
ToHex
(
big
.
NewInt
(
int64
(
len
(
block
.
Transactions
)))
.
Bytes
())
return
err
}
*
reply
=
common
.
ToHex
(
big
.
NewInt
(
v
)
.
Bytes
())
case
"eth_getUncleCountByBlockHash"
:
case
"eth_getUncleCountByBlockHash"
:
args
:=
new
(
GetBlockByHashArgs
)
args
:=
new
(
GetBlockByHashArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
v
,
err
:=
p
.
GetBlockUncleCountByHash
(
args
.
BlockHash
)
block
:=
p
.
xeth
()
.
EthBlockByHash
(
args
.
BlockHash
)
if
err
!=
nil
{
br
:=
NewBlockRes
(
block
)
return
err
*
reply
=
common
.
ToHex
(
big
.
NewInt
(
int64
(
len
(
br
.
Uncles
)))
.
Bytes
())
}
*
reply
=
common
.
ToHex
(
big
.
NewInt
(
v
)
.
Bytes
())
case
"eth_getUncleCountByBlockNumber"
:
case
"eth_getUncleCountByBlockNumber"
:
args
:=
new
(
GetBlockByNumberArgs
)
args
:=
new
(
GetBlockByNumberArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
v
,
err
:=
p
.
GetBlockUncleCountByNumber
(
args
.
BlockNumber
)
block
:=
p
.
xeth
()
.
EthBlockByNumber
(
args
.
BlockNumber
)
if
err
!=
nil
{
br
:=
NewBlockRes
(
block
)
return
err
*
reply
=
common
.
ToHex
(
big
.
NewInt
(
int64
(
len
(
br
.
Uncles
)))
.
Bytes
())
}
*
reply
=
common
.
ToHex
(
big
.
NewInt
(
v
)
.
Bytes
())
case
"eth_getData"
,
"eth_getCode"
:
case
"eth_getData"
,
"eth_getCode"
:
args
:=
new
(
GetDataArgs
)
args
:=
new
(
GetDataArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
return
p
.
GetData
(
args
,
reply
)
if
err
:=
args
.
requirements
();
err
!=
nil
{
return
err
}
*
reply
=
p
.
xethAtStateNum
(
args
.
BlockNumber
)
.
CodeAt
(
args
.
Address
)
case
"eth_sendTransaction"
,
"eth_transact"
:
case
"eth_sendTransaction"
,
"eth_transact"
:
args
:=
new
(
NewTxArgs
)
args
:=
new
(
NewTxArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
return
p
.
Transact
(
args
,
reply
)
if
err
:=
args
.
requirements
();
err
!=
nil
{
return
err
}
v
,
err
:=
p
.
xeth
()
.
Transact
(
args
.
From
,
args
.
To
,
args
.
Value
.
String
(),
args
.
Gas
.
String
(),
args
.
GasPrice
.
String
(),
args
.
Data
)
if
err
!=
nil
{
return
err
}
*
reply
=
v
case
"eth_call"
:
case
"eth_call"
:
args
:=
new
(
NewTxArgs
)
args
:=
new
(
NewTxArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
return
p
.
Call
(
args
,
reply
)
v
,
err
:=
p
.
xethAtStateNum
(
args
.
BlockNumber
)
.
Call
(
args
.
From
,
args
.
To
,
args
.
Value
.
String
(),
args
.
Gas
.
String
(),
args
.
GasPrice
.
String
(),
args
.
Data
)
if
err
!=
nil
{
return
err
}
*
reply
=
v
case
"eth_flush"
:
case
"eth_flush"
:
return
NewNotImplementedError
(
req
.
Method
)
return
NewNotImplementedError
(
req
.
Method
)
case
"eth_getBlockByHash"
:
case
"eth_getBlockByHash"
:
...
@@ -612,52 +205,55 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
...
@@ -612,52 +205,55 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
return
err
return
err
}
}
v
,
err
:=
p
.
GetBlockByHash
(
args
.
BlockHash
,
args
.
Transactions
)
block
:=
p
.
xeth
()
.
EthBlockByHash
(
args
.
BlockHash
)
if
err
!=
nil
{
br
:=
NewBlockRes
(
block
)
return
err
br
.
fullTx
=
args
.
IncludeTxs
}
*
reply
=
v
*
reply
=
br
case
"eth_getBlockByNumber"
:
case
"eth_getBlockByNumber"
:
args
:=
new
(
GetBlockByNumberArgs
)
args
:=
new
(
GetBlockByNumberArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
v
,
err
:=
p
.
GetBlockByNumber
(
args
.
BlockNumber
,
args
.
Transactions
)
block
:=
p
.
xeth
()
.
EthBlockByNumber
(
args
.
BlockNumber
)
if
err
!=
nil
{
br
:=
NewBlockRes
(
block
)
return
err
br
.
fullTx
=
args
.
IncludeTxs
}
*
reply
=
v
*
reply
=
br
case
"eth_getTransactionByHash"
:
case
"eth_getTransactionByHash"
:
// HashIndexArgs used, but only the "Hash" part we need.
// HashIndexArgs used, but only the "Hash" part we need.
args
:=
new
(
HashIndexArgs
)
args
:=
new
(
HashIndexArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
}
}
return
p
.
GetTransactionByHash
(
args
.
Hash
,
reply
)
tx
:=
p
.
xeth
()
.
EthTransactionByHash
(
args
.
Hash
)
if
tx
!=
nil
{
*
reply
=
NewTransactionRes
(
tx
)
}
case
"eth_getTransactionByBlockHashAndIndex"
:
case
"eth_getTransactionByBlockHashAndIndex"
:
args
:=
new
(
HashIndexArgs
)
args
:=
new
(
HashIndexArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
v
,
err
:=
p
.
GetBlockByHash
(
args
.
Hash
,
true
)
block
:=
p
.
xeth
()
.
EthBlockByHash
(
args
.
Hash
)
if
err
!=
nil
{
br
:=
NewBlockRes
(
block
)
return
err
br
.
fullTx
=
true
}
if
args
.
Index
>
int64
(
len
(
v
.
Transactions
))
||
args
.
Index
<
0
{
if
args
.
Index
>
int64
(
len
(
br
.
Transactions
))
||
args
.
Index
<
0
{
return
NewValidationError
(
"Index"
,
"does not exist"
)
return
NewValidationError
(
"Index"
,
"does not exist"
)
}
}
*
reply
=
v
.
Transactions
[
args
.
Index
]
*
reply
=
br
.
Transactions
[
args
.
Index
]
case
"eth_getTransactionByBlockNumberAndIndex"
:
case
"eth_getTransactionByBlockNumberAndIndex"
:
args
:=
new
(
BlockNumIndexArgs
)
args
:=
new
(
BlockNumIndexArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
v
,
err
:=
p
.
GetBlockByNumber
(
args
.
BlockNumber
,
true
)
block
:=
p
.
xeth
()
.
EthBlockByNumber
(
args
.
BlockNumber
)
if
err
!=
nil
{
v
:=
NewBlockRes
(
block
)
return
err
v
.
fullTx
=
true
}
if
args
.
Index
>
int64
(
len
(
v
.
Transactions
))
||
args
.
Index
<
0
{
if
args
.
Index
>
int64
(
len
(
v
.
Transactions
))
||
args
.
Index
<
0
{
return
NewValidationError
(
"Index"
,
"does not exist"
)
return
NewValidationError
(
"Index"
,
"does not exist"
)
}
}
...
@@ -668,18 +264,15 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
...
@@ -668,18 +264,15 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
return
err
return
err
}
}
v
,
err
:=
p
.
GetBlockByHash
(
args
.
Hash
,
false
)
br
:=
NewBlockRes
(
p
.
xeth
()
.
EthBlockByHash
(
args
.
Hash
))
if
err
!=
nil
{
return
err
if
args
.
Index
>
int64
(
len
(
br
.
Uncles
))
||
args
.
Index
<
0
{
}
if
args
.
Index
>
int64
(
len
(
v
.
Uncles
))
||
args
.
Index
<
0
{
return
NewValidationError
(
"Index"
,
"does not exist"
)
return
NewValidationError
(
"Index"
,
"does not exist"
)
}
}
uncle
,
err
:=
p
.
GetBlockByHash
(
v
.
Uncles
[
args
.
Index
]
.
Hex
(),
false
)
uhash
:=
br
.
Uncles
[
args
.
Index
]
.
Hex
()
if
err
!=
nil
{
uncle
:=
NewBlockRes
(
p
.
xeth
()
.
EthBlockByHash
(
uhash
))
return
err
}
*
reply
=
uncle
*
reply
=
uncle
case
"eth_getUncleByBlockNumberAndIndex"
:
case
"eth_getUncleByBlockNumberAndIndex"
:
args
:=
new
(
BlockNumIndexArgs
)
args
:=
new
(
BlockNumIndexArgs
)
...
@@ -687,59 +280,68 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
...
@@ -687,59 +280,68 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
return
err
return
err
}
}
v
,
err
:=
p
.
GetBlockByNumber
(
args
.
BlockNumber
,
true
)
block
:=
p
.
xeth
()
.
EthBlockByNumber
(
args
.
BlockNumber
)
if
err
!=
nil
{
v
:=
NewBlockRes
(
block
)
return
err
v
.
fullTx
=
true
}
if
args
.
Index
>
int64
(
len
(
v
.
Uncles
))
||
args
.
Index
<
0
{
if
args
.
Index
>
int64
(
len
(
v
.
Uncles
))
||
args
.
Index
<
0
{
return
NewValidationError
(
"Index"
,
"does not exist"
)
return
NewValidationError
(
"Index"
,
"does not exist"
)
}
}
uncle
,
err
:=
p
.
GetBlockByHash
(
v
.
Uncles
[
args
.
Index
]
.
Hex
(),
false
)
uhash
:=
v
.
Uncles
[
args
.
Index
]
.
Hex
()
if
err
!=
nil
{
uncle
:=
NewBlockRes
(
p
.
xeth
()
.
EthBlockByHash
(
uhash
))
return
err
}
*
reply
=
uncle
*
reply
=
uncle
case
"eth_getCompilers"
:
case
"eth_getCompilers"
:
return
p
.
GetCompilers
(
reply
)
c
:=
[]
string
{
""
}
*
reply
=
c
case
"eth_compileSolidity"
,
"eth_compileLLL"
,
"eth_compileSerpent"
:
case
"eth_compileSolidity"
,
"eth_compileLLL"
,
"eth_compileSerpent"
:
return
NewNotImplementedError
(
req
.
Method
)
return
NewNotImplementedError
(
req
.
Method
)
case
"eth_newFilter"
:
case
"eth_newFilter"
:
args
:=
new
(
FilterOption
s
)
args
:=
new
(
BlockFilterArg
s
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
return
p
.
NewFilter
(
args
,
reply
)
opts
:=
toFilterOptions
(
args
)
id
:=
p
.
xeth
()
.
RegisterFilter
(
opts
)
*
reply
=
common
.
ToHex
(
big
.
NewInt
(
int64
(
id
))
.
Bytes
())
case
"eth_newBlockFilter"
:
case
"eth_newBlockFilter"
:
args
:=
new
(
FilterStringArgs
)
args
:=
new
(
FilterStringArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
return
p
.
NewFilterString
(
args
,
reply
)
if
err
:=
args
.
requirements
();
err
!=
nil
{
return
err
}
id
:=
p
.
xeth
()
.
NewFilterString
(
args
.
Word
)
*
reply
=
common
.
ToHex
(
big
.
NewInt
(
int64
(
id
))
.
Bytes
())
case
"eth_uninstallFilter"
:
case
"eth_uninstallFilter"
:
args
:=
new
(
FilterIdArgs
)
args
:=
new
(
FilterIdArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
return
p
.
UninstallFilter
(
args
.
Id
,
reply
)
*
reply
=
p
.
xeth
()
.
UninstallFilter
(
args
.
Id
)
case
"eth_getFilterChanges"
:
case
"eth_getFilterChanges"
:
args
:=
new
(
FilterIdArgs
)
args
:=
new
(
FilterIdArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
return
p
.
FilterChanged
(
args
.
Id
,
reply
)
*
reply
=
NewLogsRes
(
p
.
xeth
()
.
FilterChanged
(
args
.
Id
)
)
case
"eth_getFilterLogs"
:
case
"eth_getFilterLogs"
:
args
:=
new
(
FilterIdArgs
)
args
:=
new
(
FilterIdArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
return
p
.
Logs
(
args
.
Id
,
reply
)
*
reply
=
NewLogsRes
(
p
.
xeth
()
.
Logs
(
args
.
Id
)
)
case
"eth_getLogs"
:
case
"eth_getLogs"
:
args
:=
new
(
FilterOption
s
)
args
:=
new
(
BlockFilterArg
s
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
return
p
.
AllLogs
(
args
,
reply
)
opts
:=
toFilterOptions
(
args
)
*
reply
=
NewLogsRes
(
p
.
xeth
()
.
AllLogs
(
opts
))
case
"eth_getWork"
,
"eth_submitWork"
:
case
"eth_getWork"
,
"eth_submitWork"
:
return
NewNotImplementedError
(
req
.
Method
)
return
NewNotImplementedError
(
req
.
Method
)
case
"db_putString"
:
case
"db_putString"
:
...
@@ -747,13 +349,25 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
...
@@ -747,13 +349,25 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
return
p
.
DbPut
(
args
,
reply
)
if
err
:=
args
.
requirements
();
err
!=
nil
{
return
err
}
p
.
db
.
Put
([]
byte
(
args
.
Database
+
args
.
Key
),
[]
byte
(
args
.
Value
))
*
reply
=
true
case
"db_getString"
:
case
"db_getString"
:
args
:=
new
(
DbArgs
)
args
:=
new
(
DbArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
return
p
.
DbGet
(
args
,
reply
)
if
err
:=
args
.
requirements
();
err
!=
nil
{
return
err
}
res
,
_
:=
p
.
db
.
Get
([]
byte
(
args
.
Database
+
args
.
Key
))
*
reply
=
string
(
res
)
case
"db_putHex"
,
"db_getHex"
:
case
"db_putHex"
,
"db_getHex"
:
return
NewNotImplementedError
(
req
.
Method
)
return
NewNotImplementedError
(
req
.
Method
)
case
"shh_post"
:
case
"shh_post"
:
...
@@ -761,21 +375,27 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
...
@@ -761,21 +375,27 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
return
p
.
WhisperPost
(
args
,
reply
)
err
:=
p
.
xeth
()
.
Whisper
()
.
Post
(
args
.
Payload
,
args
.
To
,
args
.
From
,
args
.
Topics
,
args
.
Priority
,
args
.
Ttl
)
if
err
!=
nil
{
return
err
}
*
reply
=
true
case
"shh_newIdentity"
:
case
"shh_newIdentity"
:
return
p
.
NewWhisperIdentity
(
reply
)
*
reply
=
p
.
xeth
()
.
Whisper
()
.
NewIdentity
(
)
// case "shh_removeIdentity":
// case "shh_removeIdentity":
// args := new(WhisperIdentityArgs)
// args := new(WhisperIdentityArgs)
// if err := json.Unmarshal(req.Params, &args); err != nil {
// if err := json.Unmarshal(req.Params, &args); err != nil {
// return err
// return err
// }
// }
//
return p.RemoveWhisperIdentity(args, repl
y)
//
*reply = p.xeth().Whisper().RemoveIdentity(args.Identit
y)
case
"shh_hasIdentity"
:
case
"shh_hasIdentity"
:
args
:=
new
(
WhisperIdentityArgs
)
args
:=
new
(
WhisperIdentityArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
return
p
.
HasWhisperIdentity
(
args
.
Identity
,
repl
y
)
*
reply
=
p
.
xeth
()
.
Whisper
()
.
HasIdentity
(
args
.
Identit
y
)
case
"shh_newGroup"
,
"shh_addToGroup"
:
case
"shh_newGroup"
,
"shh_addToGroup"
:
return
NewNotImplementedError
(
req
.
Method
)
return
NewNotImplementedError
(
req
.
Method
)
case
"shh_newFilter"
:
case
"shh_newFilter"
:
...
@@ -783,43 +403,49 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
...
@@ -783,43 +403,49 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
return
p
.
NewWhisperFilter
(
args
,
reply
)
opts
:=
new
(
xeth
.
Options
)
opts
.
From
=
args
.
From
opts
.
To
=
args
.
To
opts
.
Topics
=
args
.
Topics
id
:=
p
.
xeth
()
.
NewWhisperFilter
(
opts
)
*
reply
=
common
.
ToHex
(
big
.
NewInt
(
int64
(
id
))
.
Bytes
())
case
"shh_uninstallFilter"
:
case
"shh_uninstallFilter"
:
args
:=
new
(
FilterIdArgs
)
args
:=
new
(
FilterIdArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
return
p
.
UninstallWhisperFilter
(
args
.
Id
,
reply
)
*
reply
=
p
.
xeth
()
.
UninstallWhisperFilter
(
args
.
Id
)
case
"shh_getFilterChanges"
:
case
"shh_getFilterChanges"
:
args
:=
new
(
FilterIdArgs
)
args
:=
new
(
FilterIdArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
return
p
.
MessagesChanged
(
args
.
Id
,
reply
)
*
reply
=
p
.
xeth
()
.
MessagesChanged
(
args
.
Id
)
case
"shh_getMessages"
:
case
"shh_getMessages"
:
args
:=
new
(
FilterIdArgs
)
args
:=
new
(
FilterIdArgs
)
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
req
.
Params
,
&
args
);
err
!=
nil
{
return
err
return
err
}
}
return
p
.
WhisperMessages
(
args
.
Id
,
reply
)
*
reply
=
p
.
xeth
()
.
Whisper
()
.
Messages
(
args
.
Id
)
// case "eth_register":
// case "eth_register":
// args, err := req.ToRegisterArgs()
// // Placeholder for actual type
// if err != nil {
// args := new(HashIndexArgs)
// if err := json.Unmarshal(req.Params, &args); err != nil {
// return err
// return err
// }
// }
//
return p.Register(args, reply
)
//
*reply = p.xeth().Register(args.Hash
)
// case "eth_unregister":
// case "eth_unregister":
// args
, err := req.ToRegisterArgs(
)
// args
:= new(HashIndexArgs
)
// if err != nil {
// if err
:= json.Unmarshal(req.Params, &args); err
!= nil {
// return err
// return err
// }
// }
//
return p.Unregister(args, reply
)
//
*reply = p.xeth().Unregister(args.Hash
)
// case "eth_watchTx":
// case "eth_watchTx":
// args
, err := req.ToWatchTxArgs(
)
// args
:= new(HashIndexArgs
)
// if err != nil {
// if err
:= json.Unmarshal(req.Params, &args); err
!= nil {
// return err
// return err
// }
// }
//
return p.WatchTx(args, reply
)
//
*reply = p.xeth().PullWatchTx(args.Hash
)
default
:
default
:
return
NewNotImplementedError
(
req
.
Method
)
return
NewNotImplementedError
(
req
.
Method
)
}
}
...
@@ -828,14 +454,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
...
@@ -828,14 +454,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
return
nil
return
nil
}
}
func
(
self
*
EthereumApi
)
xeth
()
*
xeth
.
XEth
{
func
toFilterOptions
(
options
*
BlockFilterArgs
)
*
core
.
FilterOptions
{
self
.
xethMu
.
RLock
()
defer
self
.
xethMu
.
RUnlock
()
return
self
.
eth
}
func
toFilterOptions
(
options
*
FilterOptions
)
core
.
FilterOptions
{
var
opts
core
.
FilterOptions
var
opts
core
.
FilterOptions
// Convert optional address slice/string to byte slice
// Convert optional address slice/string to byte slice
...
@@ -867,5 +486,5 @@ func toFilterOptions(options *FilterOptions) core.FilterOptions {
...
@@ -867,5 +486,5 @@ func toFilterOptions(options *FilterOptions) core.FilterOptions {
}
}
opts
.
Topics
=
topics
opts
.
Topics
=
topics
return
opts
return
&
opts
}
}
rpc/api_test.go
View file @
a59bb053
...
@@ -2,9 +2,9 @@ package rpc
...
@@ -2,9 +2,9 @@ package rpc
import
(
import
(
"encoding/json"
"encoding/json"
"sync"
//
"sync"
"testing"
"testing"
"time"
//
"time"
)
)
func
TestWeb3Sha3
(
t
*
testing
.
T
)
{
func
TestWeb3Sha3
(
t
*
testing
.
T
)
{
...
@@ -24,33 +24,33 @@ func TestWeb3Sha3(t *testing.T) {
...
@@ -24,33 +24,33 @@ func TestWeb3Sha3(t *testing.T) {
}
}
}
}
func
TestFilterClose
(
t
*
testing
.
T
)
{
//
func TestFilterClose(t *testing.T) {
t
.
Skip
()
//
t.Skip()
api
:=
&
EthereumApi
{
//
api := &EthereumApi{
logs
:
make
(
map
[
int
]
*
logFilter
),
//
logs: make(map[int]*logFilter),
messages
:
make
(
map
[
int
]
*
whisperFilter
),
//
messages: make(map[int]*whisperFilter),
quit
:
make
(
chan
struct
{}),
//
quit: make(chan struct{}),
}
//
}
filterTickerTime
=
1
//
filterTickerTime = 1
api
.
logs
[
0
]
=
&
logFilter
{}
//
api.logs[0] = &logFilter{}
api
.
messages
[
0
]
=
&
whisperFilter
{}
//
api.messages[0] = &whisperFilter{}
var
wg
sync
.
WaitGroup
//
var wg sync.WaitGroup
wg
.
Add
(
1
)
//
wg.Add(1)
go
api
.
start
()
//
go api.start()
go
func
()
{
//
go func() {
select
{
//
select {
case
<-
time
.
After
(
500
*
time
.
Millisecond
)
:
//
case <-time.After(500 * time.Millisecond):
api
.
stop
()
//
api.stop()
wg
.
Done
()
//
wg.Done()
}
//
}
}()
//
}()
wg
.
Wait
()
//
wg.Wait()
if
len
(
api
.
logs
)
!=
0
{
//
if len(api.logs) != 0 {
t
.
Error
(
"expected logs to be empty"
)
//
t.Error("expected logs to be empty")
}
//
}
if
len
(
api
.
messages
)
!=
0
{
//
if len(api.messages) != 0 {
t
.
Error
(
"expected messages to be empty"
)
//
t.Error("expected messages to be empty")
}
//
}
}
//
}
rpc/args.go
View file @
a59bb053
...
@@ -36,7 +36,7 @@ func blockAge(raw interface{}, number *int64) (err error) {
...
@@ -36,7 +36,7 @@ func blockAge(raw interface{}, number *int64) (err error) {
type
GetBlockByHashArgs
struct
{
type
GetBlockByHashArgs
struct
{
BlockHash
string
BlockHash
string
Transaction
s
bool
IncludeTx
s
bool
}
}
func
(
args
*
GetBlockByHashArgs
)
UnmarshalJSON
(
b
[]
byte
)
(
err
error
)
{
func
(
args
*
GetBlockByHashArgs
)
UnmarshalJSON
(
b
[]
byte
)
(
err
error
)
{
...
@@ -57,7 +57,7 @@ func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) {
...
@@ -57,7 +57,7 @@ func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) {
args
.
BlockHash
=
argstr
args
.
BlockHash
=
argstr
if
len
(
obj
)
>
1
{
if
len
(
obj
)
>
1
{
args
.
Transaction
s
=
obj
[
1
]
.
(
bool
)
args
.
IncludeTx
s
=
obj
[
1
]
.
(
bool
)
}
}
return
nil
return
nil
...
@@ -65,7 +65,7 @@ func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) {
...
@@ -65,7 +65,7 @@ func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) {
type
GetBlockByNumberArgs
struct
{
type
GetBlockByNumberArgs
struct
{
BlockNumber
int64
BlockNumber
int64
Transactions
bool
IncludeTxs
bool
}
}
func
(
args
*
GetBlockByNumberArgs
)
UnmarshalJSON
(
b
[]
byte
)
(
err
error
)
{
func
(
args
*
GetBlockByNumberArgs
)
UnmarshalJSON
(
b
[]
byte
)
(
err
error
)
{
...
@@ -86,7 +86,7 @@ func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) {
...
@@ -86,7 +86,7 @@ func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) {
}
}
if
len
(
obj
)
>
1
{
if
len
(
obj
)
>
1
{
args
.
Transaction
s
=
obj
[
1
]
.
(
bool
)
args
.
IncludeTx
s
=
obj
[
1
]
.
(
bool
)
}
}
return
nil
return
nil
...
@@ -433,7 +433,7 @@ func (args *Sha3Args) UnmarshalJSON(b []byte) (err error) {
...
@@ -433,7 +433,7 @@ func (args *Sha3Args) UnmarshalJSON(b []byte) (err error) {
return
nil
return
nil
}
}
type
FilterOption
s
struct
{
type
BlockFilterArg
s
struct
{
Earliest
int64
Earliest
int64
Latest
int64
Latest
int64
Address
interface
{}
Address
interface
{}
...
@@ -442,7 +442,7 @@ type FilterOptions struct {
...
@@ -442,7 +442,7 @@ type FilterOptions struct {
Max
int
Max
int
}
}
func
(
args
*
FilterOption
s
)
UnmarshalJSON
(
b
[]
byte
)
(
err
error
)
{
func
(
args
*
BlockFilterArg
s
)
UnmarshalJSON
(
b
[]
byte
)
(
err
error
)
{
var
obj
[]
struct
{
var
obj
[]
struct
{
FromBlock
interface
{}
`json:"fromBlock"`
FromBlock
interface
{}
`json:"fromBlock"`
ToBlock
interface
{}
`json:"toBlock"`
ToBlock
interface
{}
`json:"toBlock"`
...
@@ -609,6 +609,16 @@ func (args *FilterStringArgs) UnmarshalJSON(b []byte) (err error) {
...
@@ -609,6 +609,16 @@ func (args *FilterStringArgs) UnmarshalJSON(b []byte) (err error) {
return
nil
return
nil
}
}
func
(
args
*
FilterStringArgs
)
requirements
()
error
{
switch
args
.
Word
{
case
"latest"
,
"pending"
:
break
default
:
return
NewValidationError
(
"Word"
,
"Must be `latest` or `pending`"
)
}
return
nil
}
type
FilterIdArgs
struct
{
type
FilterIdArgs
struct
{
Id
int
Id
int
}
}
...
...
rpc/args_test.go
View file @
a59bb053
...
@@ -82,7 +82,7 @@ func TestGetBlockByHashArgs(t *testing.T) {
...
@@ -82,7 +82,7 @@ func TestGetBlockByHashArgs(t *testing.T) {
input
:=
`["0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", true]`
input
:=
`["0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", true]`
expected
:=
new
(
GetBlockByHashArgs
)
expected
:=
new
(
GetBlockByHashArgs
)
expected
.
BlockHash
=
"0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331"
expected
.
BlockHash
=
"0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331"
expected
.
Transaction
s
=
true
expected
.
IncludeTx
s
=
true
args
:=
new
(
GetBlockByHashArgs
)
args
:=
new
(
GetBlockByHashArgs
)
if
err
:=
json
.
Unmarshal
([]
byte
(
input
),
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
([]
byte
(
input
),
&
args
);
err
!=
nil
{
...
@@ -93,8 +93,8 @@ func TestGetBlockByHashArgs(t *testing.T) {
...
@@ -93,8 +93,8 @@ func TestGetBlockByHashArgs(t *testing.T) {
t
.
Errorf
(
"BlockHash should be %v but is %v"
,
expected
.
BlockHash
,
args
.
BlockHash
)
t
.
Errorf
(
"BlockHash should be %v but is %v"
,
expected
.
BlockHash
,
args
.
BlockHash
)
}
}
if
args
.
Transactions
!=
expected
.
Transaction
s
{
if
args
.
IncludeTxs
!=
expected
.
IncludeTx
s
{
t
.
Errorf
(
"
Transactions should be %v but is %v"
,
expected
.
Transactions
,
args
.
Transaction
s
)
t
.
Errorf
(
"
IncludeTxs should be %v but is %v"
,
expected
.
IncludeTxs
,
args
.
IncludeTx
s
)
}
}
}
}
...
@@ -112,7 +112,7 @@ func TestGetBlockByNumberArgs(t *testing.T) {
...
@@ -112,7 +112,7 @@ func TestGetBlockByNumberArgs(t *testing.T) {
input
:=
`["0x1b4", false]`
input
:=
`["0x1b4", false]`
expected
:=
new
(
GetBlockByNumberArgs
)
expected
:=
new
(
GetBlockByNumberArgs
)
expected
.
BlockNumber
=
436
expected
.
BlockNumber
=
436
expected
.
Transaction
s
=
false
expected
.
IncludeTx
s
=
false
args
:=
new
(
GetBlockByNumberArgs
)
args
:=
new
(
GetBlockByNumberArgs
)
if
err
:=
json
.
Unmarshal
([]
byte
(
input
),
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
([]
byte
(
input
),
&
args
);
err
!=
nil
{
...
@@ -123,8 +123,8 @@ func TestGetBlockByNumberArgs(t *testing.T) {
...
@@ -123,8 +123,8 @@ func TestGetBlockByNumberArgs(t *testing.T) {
t
.
Errorf
(
"BlockHash should be %v but is %v"
,
expected
.
BlockNumber
,
args
.
BlockNumber
)
t
.
Errorf
(
"BlockHash should be %v but is %v"
,
expected
.
BlockNumber
,
args
.
BlockNumber
)
}
}
if
args
.
Transactions
!=
expected
.
Transaction
s
{
if
args
.
IncludeTxs
!=
expected
.
IncludeTx
s
{
t
.
Errorf
(
"
Transactions should be %v but is %v"
,
expected
.
Transactions
,
args
.
Transaction
s
)
t
.
Errorf
(
"
IncludeTxs should be %v but is %v"
,
expected
.
IncludeTxs
,
args
.
IncludeTx
s
)
}
}
}
}
...
@@ -388,7 +388,7 @@ func TestGetDataEmptyArgs(t *testing.T) {
...
@@ -388,7 +388,7 @@ func TestGetDataEmptyArgs(t *testing.T) {
}
}
}
}
func
Test
FilterOption
s
(
t
*
testing
.
T
)
{
func
Test
BlockFilterArg
s
(
t
*
testing
.
T
)
{
input
:=
`[{
input
:=
`[{
"fromBlock": "0x1",
"fromBlock": "0x1",
"toBlock": "0x2",
"toBlock": "0x2",
...
@@ -396,7 +396,7 @@ func TestFilterOptions(t *testing.T) {
...
@@ -396,7 +396,7 @@ func TestFilterOptions(t *testing.T) {
"offset": "0x0",
"offset": "0x0",
"address": "0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8",
"address": "0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8",
"topics": ["0x12341234"]}]`
"topics": ["0x12341234"]}]`
expected
:=
new
(
FilterOption
s
)
expected
:=
new
(
BlockFilterArg
s
)
expected
.
Earliest
=
1
expected
.
Earliest
=
1
expected
.
Latest
=
2
expected
.
Latest
=
2
expected
.
Max
=
3
expected
.
Max
=
3
...
@@ -404,7 +404,7 @@ func TestFilterOptions(t *testing.T) {
...
@@ -404,7 +404,7 @@ func TestFilterOptions(t *testing.T) {
expected
.
Address
=
"0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8"
expected
.
Address
=
"0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8"
// expected.Topics = []string{"0x12341234"}
// expected.Topics = []string{"0x12341234"}
args
:=
new
(
FilterOption
s
)
args
:=
new
(
BlockFilterArg
s
)
if
err
:=
json
.
Unmarshal
([]
byte
(
input
),
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
([]
byte
(
input
),
&
args
);
err
!=
nil
{
t
.
Error
(
err
)
t
.
Error
(
err
)
}
}
...
@@ -434,16 +434,16 @@ func TestFilterOptions(t *testing.T) {
...
@@ -434,16 +434,16 @@ func TestFilterOptions(t *testing.T) {
// }
// }
}
}
func
Test
FilterOption
sWords
(
t
*
testing
.
T
)
{
func
Test
BlockFilterArg
sWords
(
t
*
testing
.
T
)
{
input
:=
`[{
input
:=
`[{
"fromBlock": "latest",
"fromBlock": "latest",
"toBlock": "pending"
"toBlock": "pending"
}]`
}]`
expected
:=
new
(
FilterOption
s
)
expected
:=
new
(
BlockFilterArg
s
)
expected
.
Earliest
=
0
expected
.
Earliest
=
0
expected
.
Latest
=
-
1
expected
.
Latest
=
-
1
args
:=
new
(
FilterOption
s
)
args
:=
new
(
BlockFilterArg
s
)
if
err
:=
json
.
Unmarshal
([]
byte
(
input
),
&
args
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
([]
byte
(
input
),
&
args
);
err
!=
nil
{
t
.
Error
(
err
)
t
.
Error
(
err
)
}
}
...
@@ -457,13 +457,13 @@ func TestFilterOptionsWords(t *testing.T) {
...
@@ -457,13 +457,13 @@ func TestFilterOptionsWords(t *testing.T) {
}
}
}
}
func
Test
FilterOption
sNums
(
t
*
testing
.
T
)
{
func
Test
BlockFilterArg
sNums
(
t
*
testing
.
T
)
{
input
:=
`[{
input
:=
`[{
"fromBlock": 2,
"fromBlock": 2,
"toBlock": 3
"toBlock": 3
}]`
}]`
args
:=
new
(
FilterOption
s
)
args
:=
new
(
BlockFilterArg
s
)
err
:=
json
.
Unmarshal
([]
byte
(
input
),
&
args
)
err
:=
json
.
Unmarshal
([]
byte
(
input
),
&
args
)
switch
err
.
(
type
)
{
switch
err
.
(
type
)
{
case
*
DecodeParamError
:
case
*
DecodeParamError
:
...
@@ -474,10 +474,10 @@ func TestFilterOptionsNums(t *testing.T) {
...
@@ -474,10 +474,10 @@ func TestFilterOptionsNums(t *testing.T) {
}
}
func
Test
FilterOption
sEmptyArgs
(
t
*
testing
.
T
)
{
func
Test
BlockFilterArg
sEmptyArgs
(
t
*
testing
.
T
)
{
input
:=
`[]`
input
:=
`[]`
args
:=
new
(
FilterOption
s
)
args
:=
new
(
BlockFilterArg
s
)
err
:=
json
.
Unmarshal
([]
byte
(
input
),
&
args
)
err
:=
json
.
Unmarshal
([]
byte
(
input
),
&
args
)
if
err
==
nil
{
if
err
==
nil
{
t
.
Error
(
"Expected error but didn't get one"
)
t
.
Error
(
"Expected error but didn't get one"
)
...
...
rpc/http.go
View file @
a59bb053
...
@@ -10,7 +10,7 @@ import (
...
@@ -10,7 +10,7 @@ import (
"github.com/ethereum/go-ethereum/xeth"
"github.com/ethereum/go-ethereum/xeth"
)
)
var
rpc
httplogger
=
logger
.
NewLogger
(
"RPC-HTTP
"
)
var
rpc
logger
=
logger
.
NewLogger
(
"RPC
"
)
const
(
const
(
jsonrpcver
=
"2.0"
jsonrpcver
=
"2.0"
...
@@ -28,7 +28,7 @@ func JSONRPC(pipe *xeth.XEth, dataDir string) http.Handler {
...
@@ -28,7 +28,7 @@ func JSONRPC(pipe *xeth.XEth, dataDir string) http.Handler {
// Limit request size to resist DoS
// Limit request size to resist DoS
if
req
.
ContentLength
>
maxSizeReqLength
{
if
req
.
ContentLength
>
maxSizeReqLength
{
jsonerr
:=
&
RpcErrorObject
{
-
32700
,
"Request too large"
}
jsonerr
:=
&
RpcErrorObject
{
-
32700
,
"Request too large"
}
S
end
(
w
,
&
RpcErrorResponse
{
Jsonrpc
:
jsonrpcver
,
Id
:
nil
,
Error
:
jsonerr
})
s
end
(
w
,
&
RpcErrorResponse
{
Jsonrpc
:
jsonrpcver
,
Id
:
nil
,
Error
:
jsonerr
})
return
return
}
}
...
@@ -37,14 +37,14 @@ func JSONRPC(pipe *xeth.XEth, dataDir string) http.Handler {
...
@@ -37,14 +37,14 @@ func JSONRPC(pipe *xeth.XEth, dataDir string) http.Handler {
body
,
err
:=
ioutil
.
ReadAll
(
req
.
Body
)
body
,
err
:=
ioutil
.
ReadAll
(
req
.
Body
)
if
err
!=
nil
{
if
err
!=
nil
{
jsonerr
:=
&
RpcErrorObject
{
-
32700
,
"Could not read request body"
}
jsonerr
:=
&
RpcErrorObject
{
-
32700
,
"Could not read request body"
}
S
end
(
w
,
&
RpcErrorResponse
{
Jsonrpc
:
jsonrpcver
,
Id
:
nil
,
Error
:
jsonerr
})
s
end
(
w
,
&
RpcErrorResponse
{
Jsonrpc
:
jsonrpcver
,
Id
:
nil
,
Error
:
jsonerr
})
}
}
// Try to parse the request as a single
// Try to parse the request as a single
var
reqSingle
RpcRequest
var
reqSingle
RpcRequest
if
err
:=
json
.
Unmarshal
(
body
,
&
reqSingle
);
err
==
nil
{
if
err
:=
json
.
Unmarshal
(
body
,
&
reqSingle
);
err
==
nil
{
response
:=
RpcResponse
(
api
,
&
reqSingle
)
response
:=
RpcResponse
(
api
,
&
reqSingle
)
S
end
(
w
,
&
response
)
s
end
(
w
,
&
response
)
return
return
}
}
...
@@ -57,13 +57,13 @@ func JSONRPC(pipe *xeth.XEth, dataDir string) http.Handler {
...
@@ -57,13 +57,13 @@ func JSONRPC(pipe *xeth.XEth, dataDir string) http.Handler {
response
:=
RpcResponse
(
api
,
&
request
)
response
:=
RpcResponse
(
api
,
&
request
)
resBatch
[
i
]
=
response
resBatch
[
i
]
=
response
}
}
S
end
(
w
,
resBatch
)
s
end
(
w
,
resBatch
)
return
return
}
}
// Not a batch or single request, error
// Not a batch or single request, error
jsonerr
:=
&
RpcErrorObject
{
-
32600
,
"Could not decode request"
}
jsonerr
:=
&
RpcErrorObject
{
-
32600
,
"Could not decode request"
}
S
end
(
w
,
&
RpcErrorResponse
{
Jsonrpc
:
jsonrpcver
,
Id
:
nil
,
Error
:
jsonerr
})
s
end
(
w
,
&
RpcErrorResponse
{
Jsonrpc
:
jsonrpcver
,
Id
:
nil
,
Error
:
jsonerr
})
})
})
}
}
...
@@ -84,11 +84,11 @@ func RpcResponse(api *EthereumApi, request *RpcRequest) *interface{} {
...
@@ -84,11 +84,11 @@ func RpcResponse(api *EthereumApi, request *RpcRequest) *interface{} {
response
=
&
RpcErrorResponse
{
Jsonrpc
:
jsonrpcver
,
Id
:
request
.
Id
,
Error
:
jsonerr
}
response
=
&
RpcErrorResponse
{
Jsonrpc
:
jsonrpcver
,
Id
:
request
.
Id
,
Error
:
jsonerr
}
}
}
rpc
http
logger
.
DebugDetailf
(
"Generated response: %T %s"
,
response
,
response
)
rpclogger
.
DebugDetailf
(
"Generated response: %T %s"
,
response
,
response
)
return
&
response
return
&
response
}
}
func
S
end
(
writer
io
.
Writer
,
v
interface
{})
(
n
int
,
err
error
)
{
func
s
end
(
writer
io
.
Writer
,
v
interface
{})
(
n
int
,
err
error
)
{
var
payload
[]
byte
var
payload
[]
byte
payload
,
err
=
json
.
MarshalIndent
(
v
,
""
,
"
\t
"
)
payload
,
err
=
json
.
MarshalIndent
(
v
,
""
,
"
\t
"
)
if
err
!=
nil
{
if
err
!=
nil
{
...
...
rpc/messages_test.go
0 → 100644
View file @
a59bb053
package
rpc
import
(
"testing"
)
func
TestInsufficientParamsError
(
t
*
testing
.
T
)
{
err
:=
NewInsufficientParamsError
(
0
,
1
)
expected
:=
"insufficient params, want 1 have 0"
if
err
.
Error
()
!=
expected
{
t
.
Error
(
err
.
Error
())
}
}
func
TestNotImplementedError
(
t
*
testing
.
T
)
{
err
:=
NewNotImplementedError
(
"foo"
)
expected
:=
"foo method not implemented"
if
err
.
Error
()
!=
expected
{
t
.
Error
(
err
.
Error
())
}
}
func
TestDecodeParamError
(
t
*
testing
.
T
)
{
err
:=
NewDecodeParamError
(
"foo"
)
expected
:=
"could not decode, foo"
if
err
.
Error
()
!=
expected
{
t
.
Error
(
err
.
Error
())
}
}
func
TestValidationError
(
t
*
testing
.
T
)
{
err
:=
NewValidationError
(
"foo"
,
"should be `bar`"
)
expected
:=
"foo not valid, should be `bar`"
if
err
.
Error
()
!=
expected
{
t
.
Error
(
err
.
Error
())
}
}
rpc/responses.go
View file @
a59bb053
...
@@ -7,6 +7,7 @@ import (
...
@@ -7,6 +7,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/state"
)
)
type
BlockRes
struct
{
type
BlockRes
struct
{
...
@@ -215,3 +216,28 @@ type FilterWhisperRes struct {
...
@@ -215,3 +216,28 @@ type FilterWhisperRes struct {
Payload
string
`json:"payload"`
Payload
string
`json:"payload"`
WorkProved
string
`json:"workProved"`
WorkProved
string
`json:"workProved"`
}
}
type
LogRes
struct
{
Address
string
`json:"address"`
Topic
[]
string
`json:"topic"`
Data
string
`json:"data"`
Number
uint64
`json:"number"`
}
func
NewLogsRes
(
logs
state
.
Logs
)
(
ls
[]
LogRes
)
{
ls
=
make
([]
LogRes
,
len
(
logs
))
for
i
,
log
:=
range
logs
{
var
l
LogRes
l
.
Topic
=
make
([]
string
,
len
(
log
.
Topics
()))
l
.
Address
=
log
.
Address
()
.
Hex
()
l
.
Data
=
common
.
ToHex
(
log
.
Data
())
l
.
Number
=
log
.
Number
()
for
j
,
topic
:=
range
log
.
Topics
()
{
l
.
Topic
[
j
]
=
topic
.
Hex
()
}
ls
[
i
]
=
l
}
return
}
rpc/util.go
deleted
100644 → 0
View file @
deee9cb1
/*
This file is part of go-ethereum
go-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
go-ethereum 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
package
rpc
import
(
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/xeth"
)
var
rpclogger
=
logger
.
NewLogger
(
"RPC"
)
type
Log
struct
{
Address
string
`json:"address"`
Topic
[]
string
`json:"topic"`
Data
string
`json:"data"`
Number
uint64
`json:"number"`
}
func
toLogs
(
logs
state
.
Logs
)
(
ls
[]
Log
)
{
ls
=
make
([]
Log
,
len
(
logs
))
for
i
,
log
:=
range
logs
{
var
l
Log
l
.
Topic
=
make
([]
string
,
len
(
log
.
Topics
()))
l
.
Address
=
log
.
Address
()
.
Hex
()
l
.
Data
=
common
.
ToHex
(
log
.
Data
())
l
.
Number
=
log
.
Number
()
for
j
,
topic
:=
range
log
.
Topics
()
{
l
.
Topic
[
j
]
=
topic
.
Hex
()
}
ls
[
i
]
=
l
}
return
}
type
whisperFilter
struct
{
messages
[]
xeth
.
WhisperMessage
timeout
time
.
Time
id
int
}
func
(
w
*
whisperFilter
)
add
(
msgs
...
xeth
.
WhisperMessage
)
{
w
.
messages
=
append
(
w
.
messages
,
msgs
...
)
}
func
(
w
*
whisperFilter
)
get
()
[]
xeth
.
WhisperMessage
{
w
.
timeout
=
time
.
Now
()
tmp
:=
w
.
messages
w
.
messages
=
nil
return
tmp
}
type
logFilter
struct
{
logs
state
.
Logs
timeout
time
.
Time
id
int
}
func
(
l
*
logFilter
)
add
(
logs
...
state
.
Log
)
{
l
.
logs
=
append
(
l
.
logs
,
logs
...
)
}
func
(
l
*
logFilter
)
get
()
state
.
Logs
{
l
.
timeout
=
time
.
Now
()
tmp
:=
l
.
logs
l
.
logs
=
nil
return
tmp
}
xeth/xeth.go
View file @
a59bb053
...
@@ -6,6 +6,8 @@ import (
...
@@ -6,6 +6,8 @@ import (
"encoding/json"
"encoding/json"
"fmt"
"fmt"
"math/big"
"math/big"
"sync"
"time"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
...
@@ -13,13 +15,19 @@ import (
...
@@ -13,13 +15,19 @@ import (
"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/event"
"github.com/ethereum/go-ethereum/event/filter"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/whisper"
"github.com/ethereum/go-ethereum/whisper"
)
)
var
pipelogger
=
logger
.
NewLogger
(
"XETH"
)
var
(
pipelogger
=
logger
.
NewLogger
(
"XETH"
)
filterTickerTime
=
5
*
time
.
Minute
defaultGasPrice
=
big
.
NewInt
(
10000000000000
)
//150000000000
defaultGas
=
big
.
NewInt
(
90000
)
//500000
)
// to resolve the import cycle
// to resolve the import cycle
type
Backend
interface
{
type
Backend
interface
{
...
@@ -62,6 +70,13 @@ type Frontend interface {
...
@@ -62,6 +70,13 @@ type Frontend interface {
ConfirmTransaction
(
tx
*
types
.
Transaction
)
bool
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
eth
Backend
blockProcessor
*
core
.
BlockProcessor
blockProcessor
*
core
.
BlockProcessor
...
@@ -71,14 +86,19 @@ type XEth struct {
...
@@ -71,14 +86,19 @@ type XEth struct {
whisper
*
Whisper
whisper
*
Whisper
frontend
Frontend
frontend
Frontend
}
// dummyFrontend is a non-interactive frontend that allows all
quit
chan
struct
{}
// transactions but cannot not unlock any keys.
filterManager
*
filter
.
FilterManager
type
dummyFrontend
struct
{}
func
(
dummyFrontend
)
UnlockAccount
([]
byte
)
bool
{
return
false
}
logMut
sync
.
RWMutex
func
(
dummyFrontend
)
ConfirmTransaction
(
*
types
.
Transaction
)
bool
{
return
true
}
logs
map
[
int
]
*
logFilter
messagesMut
sync
.
RWMutex
messages
map
[
int
]
*
whisperFilter
// regmut sync.Mutex
// register map[string][]*interface{} // TODO improve return type
}
// 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
...
@@ -90,15 +110,76 @@ func New(eth Backend, frontend Frontend) *XEth {
...
@@ -90,15 +110,76 @@ func New(eth Backend, frontend Frontend) *XEth {
chainManager
:
eth
.
ChainManager
(),
chainManager
:
eth
.
ChainManager
(),
accountManager
:
eth
.
AccountManager
(),
accountManager
:
eth
.
AccountManager
(),
whisper
:
NewWhisper
(
eth
.
Whisper
()),
whisper
:
NewWhisper
(
eth
.
Whisper
()),
quit
:
make
(
chan
struct
{}),
filterManager
:
filter
.
NewFilterManager
(
eth
.
EventMux
()),
frontend
:
frontend
,
frontend
:
frontend
,
logs
:
make
(
map
[
int
]
*
logFilter
),
messages
:
make
(
map
[
int
]
*
whisperFilter
),
}
}
if
frontend
==
nil
{
if
frontend
==
nil
{
xeth
.
frontend
=
dummyFrontend
{}
xeth
.
frontend
=
dummyFrontend
{}
}
}
xeth
.
state
=
NewState
(
xeth
,
xeth
.
chainManager
.
TransState
())
xeth
.
state
=
NewState
(
xeth
,
xeth
.
chainManager
.
TransState
())
go
xeth
.
start
()
go
xeth
.
filterManager
.
Start
()
return
xeth
return
xeth
}
}
func
(
self
*
XEth
)
start
()
{
timer
:=
time
.
NewTicker
(
2
*
time
.
Second
)
done
:
for
{
select
{
case
<-
timer
.
C
:
self
.
logMut
.
Lock
()
self
.
messagesMut
.
Lock
()
for
id
,
filter
:=
range
self
.
logs
{
if
time
.
Since
(
filter
.
timeout
)
>
filterTickerTime
{
self
.
filterManager
.
UninstallFilter
(
id
)
delete
(
self
.
logs
,
id
)
}
}
for
id
,
filter
:=
range
self
.
messages
{
if
time
.
Since
(
filter
.
timeout
)
>
filterTickerTime
{
self
.
Whisper
()
.
Unwatch
(
id
)
delete
(
self
.
messages
,
id
)
}
}
self
.
messagesMut
.
Unlock
()
self
.
logMut
.
Unlock
()
case
<-
self
.
quit
:
break
done
}
}
}
func
(
self
*
XEth
)
stop
()
{
close
(
self
.
quit
)
}
func
(
self
*
XEth
)
DefaultGas
()
*
big
.
Int
{
return
defaultGas
}
func
(
self
*
XEth
)
DefaultGasPrice
()
*
big
.
Int
{
return
defaultGasPrice
}
func
(
self
*
XEth
)
AtStateNum
(
num
int64
)
*
XEth
{
chain
:=
self
.
Backend
()
.
ChainManager
()
var
block
*
types
.
Block
if
num
<
0
{
num
=
chain
.
CurrentBlock
()
.
Number
()
.
Int64
()
+
num
+
1
}
block
=
chain
.
GetBlockByNumber
(
uint64
(
num
))
var
st
*
state
.
StateDB
if
block
!=
nil
{
st
=
state
.
New
(
block
.
Root
(),
self
.
Backend
()
.
StateDb
())
}
else
{
st
=
chain
.
State
()
}
return
self
.
WithState
(
st
)
}
func
(
self
*
XEth
)
Backend
()
Backend
{
return
self
.
eth
}
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
{
...
@@ -241,6 +322,157 @@ func (self *XEth) SecretToAddress(key string) string {
...
@@ -241,6 +322,157 @@ func (self *XEth) SecretToAddress(key string) string {
return
common
.
ToHex
(
pair
.
Address
())
return
common
.
ToHex
(
pair
.
Address
())
}
}
func
(
self
*
XEth
)
RegisterFilter
(
args
*
core
.
FilterOptions
)
int
{
var
id
int
filter
:=
core
.
NewFilter
(
self
.
Backend
())
filter
.
SetOptions
(
args
)
filter
.
LogsCallback
=
func
(
logs
state
.
Logs
)
{
self
.
logMut
.
Lock
()
defer
self
.
logMut
.
Unlock
()
self
.
logs
[
id
]
.
add
(
logs
...
)
}
id
=
self
.
filterManager
.
InstallFilter
(
filter
)
self
.
logs
[
id
]
=
&
logFilter
{
timeout
:
time
.
Now
()}
return
id
}
func
(
self
*
XEth
)
UninstallFilter
(
id
int
)
bool
{
if
_
,
ok
:=
self
.
logs
[
id
];
ok
{
delete
(
self
.
logs
,
id
)
self
.
filterManager
.
UninstallFilter
(
id
)
return
true
}
return
false
}
func
(
self
*
XEth
)
NewFilterString
(
word
string
)
int
{
var
id
int
filter
:=
core
.
NewFilter
(
self
.
Backend
())
switch
word
{
case
"pending"
:
filter
.
PendingCallback
=
func
(
tx
*
types
.
Transaction
)
{
self
.
logMut
.
Lock
()
defer
self
.
logMut
.
Unlock
()
self
.
logs
[
id
]
.
add
(
&
state
.
StateLog
{})
}
case
"latest"
:
filter
.
BlockCallback
=
func
(
block
*
types
.
Block
,
logs
state
.
Logs
)
{
self
.
logMut
.
Lock
()
defer
self
.
logMut
.
Unlock
()
for
_
,
log
:=
range
logs
{
self
.
logs
[
id
]
.
add
(
log
)
}
self
.
logs
[
id
]
.
add
(
&
state
.
StateLog
{})
}
}
id
=
self
.
filterManager
.
InstallFilter
(
filter
)
self
.
logs
[
id
]
=
&
logFilter
{
timeout
:
time
.
Now
()}
return
id
}
func
(
self
*
XEth
)
FilterChanged
(
id
int
)
state
.
Logs
{
self
.
logMut
.
Lock
()
defer
self
.
logMut
.
Unlock
()
if
self
.
logs
[
id
]
!=
nil
{
return
self
.
logs
[
id
]
.
get
()
}
return
nil
}
func
(
self
*
XEth
)
Logs
(
id
int
)
state
.
Logs
{
self
.
logMut
.
Lock
()
defer
self
.
logMut
.
Unlock
()
filter
:=
self
.
filterManager
.
GetFilter
(
id
)
if
filter
!=
nil
{
return
filter
.
Find
()
}
return
nil
}
func
(
self
*
XEth
)
AllLogs
(
args
*
core
.
FilterOptions
)
state
.
Logs
{
filter
:=
core
.
NewFilter
(
self
.
Backend
())
filter
.
SetOptions
(
args
)
return
filter
.
Find
()
}
func
(
p
*
XEth
)
NewWhisperFilter
(
opts
*
Options
)
int
{
var
id
int
opts
.
Fn
=
func
(
msg
WhisperMessage
)
{
p
.
messagesMut
.
Lock
()
defer
p
.
messagesMut
.
Unlock
()
p
.
messages
[
id
]
.
add
(
msg
)
// = append(p.messages[id], msg)
}
id
=
p
.
Whisper
()
.
Watch
(
opts
)
p
.
messages
[
id
]
=
&
whisperFilter
{
timeout
:
time
.
Now
()}
return
id
}
func
(
p
*
XEth
)
UninstallWhisperFilter
(
id
int
)
bool
{
if
_
,
ok
:=
p
.
messages
[
id
];
ok
{
delete
(
p
.
messages
,
id
)
return
true
}
return
false
}
func
(
self
*
XEth
)
MessagesChanged
(
id
int
)
[]
WhisperMessage
{
self
.
messagesMut
.
Lock
()
defer
self
.
messagesMut
.
Unlock
()
if
self
.
messages
[
id
]
!=
nil
{
return
self
.
messages
[
id
]
.
get
()
}
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
{
type
KeyVal
struct
{
Key
string
`json:"key"`
Key
string
`json:"key"`
Value
string
`json:"value"`
Value
string
`json:"value"`
...
@@ -298,11 +530,6 @@ func (self *XEth) PushTx(encodedTx string) (string, error) {
...
@@ -298,11 +530,6 @@ func (self *XEth) PushTx(encodedTx string) (string, error) {
return
tx
.
Hash
()
.
Hex
(),
nil
return
tx
.
Hash
()
.
Hex
(),
nil
}
}
var
(
defaultGasPrice
=
big
.
NewInt
(
10000000000000
)
defaultGas
=
big
.
NewInt
(
90000
)
)
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.chainManager.TransState()
msg
:=
callmsg
{
msg
:=
callmsg
{
...
@@ -333,12 +560,44 @@ func (self *XEth) Transact(fromStr, toStr, valueStr, gasStr, gasPriceStr, codeSt
...
@@ -333,12 +560,44 @@ func (self *XEth) Transact(fromStr, toStr, valueStr, gasStr, gasPriceStr, codeSt
from
=
common
.
HexToAddress
(
fromStr
)
from
=
common
.
HexToAddress
(
fromStr
)
to
=
common
.
HexToAddress
(
toStr
)
to
=
common
.
HexToAddress
(
toStr
)
value
=
common
.
NewValue
(
valueStr
)
value
=
common
.
NewValue
(
valueStr
)
gas
=
common
.
NewValue
(
gasStr
)
gas
=
common
.
Big
(
gasStr
)
price
=
common
.
NewValue
(
gasPriceStr
)
price
=
common
.
Big
(
gasPriceStr
)
data
[]
byte
data
[]
byte
contractCreation
bool
contractCreation
bool
)
)
// 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)
}
*/
// 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
{
gas
=
defaultGas
}
if
price
.
Cmp
(
big
.
NewInt
(
0
))
==
0
{
price
=
defaultGasPrice
}
data
=
common
.
FromHex
(
codeStr
)
data
=
common
.
FromHex
(
codeStr
)
if
len
(
toStr
)
==
0
{
if
len
(
toStr
)
==
0
{
contractCreation
=
true
contractCreation
=
true
...
@@ -346,9 +605,9 @@ func (self *XEth) Transact(fromStr, toStr, valueStr, gasStr, gasPriceStr, codeSt
...
@@ -346,9 +605,9 @@ func (self *XEth) Transact(fromStr, toStr, valueStr, gasStr, gasPriceStr, codeSt
var
tx
*
types
.
Transaction
var
tx
*
types
.
Transaction
if
contractCreation
{
if
contractCreation
{
tx
=
types
.
NewContractCreationTx
(
value
.
BigInt
(),
gas
.
BigInt
(),
price
.
BigInt
()
,
data
)
tx
=
types
.
NewContractCreationTx
(
value
.
BigInt
(),
gas
,
price
,
data
)
}
else
{
}
else
{
tx
=
types
.
NewTransactionMessage
(
to
,
value
.
BigInt
(),
gas
.
BigInt
(),
price
.
BigInt
()
,
data
)
tx
=
types
.
NewTransactionMessage
(
to
,
value
.
BigInt
(),
gas
,
price
,
data
)
}
}
state
:=
self
.
chainManager
.
TxState
()
state
:=
self
.
chainManager
.
TxState
()
...
@@ -407,3 +666,36 @@ func (m callmsg) GasPrice() *big.Int { return m.gasPrice }
...
@@ -407,3 +666,36 @@ func (m callmsg) GasPrice() *big.Int { return m.gasPrice }
func
(
m
callmsg
)
Gas
()
*
big
.
Int
{
return
m
.
gas
}
func
(
m
callmsg
)
Gas
()
*
big
.
Int
{
return
m
.
gas
}
func
(
m
callmsg
)
Value
()
*
big
.
Int
{
return
m
.
value
}
func
(
m
callmsg
)
Value
()
*
big
.
Int
{
return
m
.
value
}
func
(
m
callmsg
)
Data
()
[]
byte
{
return
m
.
data
}
func
(
m
callmsg
)
Data
()
[]
byte
{
return
m
.
data
}
type
whisperFilter
struct
{
messages
[]
WhisperMessage
timeout
time
.
Time
id
int
}
func
(
w
*
whisperFilter
)
add
(
msgs
...
WhisperMessage
)
{
w
.
messages
=
append
(
w
.
messages
,
msgs
...
)
}
func
(
w
*
whisperFilter
)
get
()
[]
WhisperMessage
{
w
.
timeout
=
time
.
Now
()
tmp
:=
w
.
messages
w
.
messages
=
nil
return
tmp
}
type
logFilter
struct
{
logs
state
.
Logs
timeout
time
.
Time
id
int
}
func
(
l
*
logFilter
)
add
(
logs
...
state
.
Log
)
{
l
.
logs
=
append
(
l
.
logs
,
logs
...
)
}
func
(
l
*
logFilter
)
get
()
state
.
Logs
{
l
.
timeout
=
time
.
Now
()
tmp
:=
l
.
logs
l
.
logs
=
nil
return
tmp
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment