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
b5a71d95
Commit
b5a71d95
authored
Mar 19, 2015
by
obscuren
Browse files
Options
Browse Files
Download
Plain Diff
merge
parents
ce063e8d
e540a750
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
275 additions
and
178 deletions
+275
-178
main.go
cmd/ethereum/main.go
+1
-1
block_processor.go
core/block_processor.go
+7
-11
chain_makers.go
core/chain_makers.go
+1
-1
chain_manager.go
core/chain_manager.go
+7
-9
events.go
core/events.go
+23
-6
filter.go
core/filter.go
+2
-2
common.go
core/types/common.go
+4
-2
eth_filter.go
event/filter/eth_filter.go
+3
-3
api.go
rpc/api.go
+16
-8
args.go
rpc/args.go
+132
-62
args_test.go
rpc/args_test.go
+79
-1
util.go
rpc/util.go
+0
-72
No files found.
cmd/ethereum/main.go
View file @
b5a71d95
...
...
@@ -42,7 +42,7 @@ import (
const
(
ClientIdentifier
=
"Ethereum(G)"
Version
=
"
Frontier -
0.9.1"
Version
=
"0.9.1"
)
var
(
...
...
core/block_processor.go
View file @
b5a71d95
...
...
@@ -16,10 +16,6 @@ import (
"gopkg.in/fatih/set.v0"
)
type
PendingBlockEvent
struct
{
Block
*
types
.
Block
}
var
statelogger
=
logger
.
NewLogger
(
"BLOCK"
)
type
BlockProcessor
struct
{
...
...
@@ -137,7 +133,7 @@ func (self *BlockProcessor) ApplyTransactions(coinbase *state.StateObject, state
block
.
Header
()
.
GasUsed
=
totalUsedGas
if
transientProcess
{
go
self
.
eventMux
.
Post
(
PendingBlockEvent
{
block
})
go
self
.
eventMux
.
Post
(
PendingBlockEvent
{
block
,
statedb
.
Logs
()
})
}
return
receipts
,
handled
,
unhandled
,
erroneous
,
err
...
...
@@ -146,25 +142,25 @@ func (self *BlockProcessor) ApplyTransactions(coinbase *state.StateObject, state
// Process block will attempt to process the given block's transactions and applies them
// on top of the block's parent state (given it exists) and will return wether it was
// successful or not.
func
(
sm
*
BlockProcessor
)
Process
(
block
*
types
.
Block
)
(
td
*
big
.
Int
,
err
error
)
{
func
(
sm
*
BlockProcessor
)
Process
(
block
*
types
.
Block
)
(
td
*
big
.
Int
,
logs
state
.
Logs
,
err
error
)
{
// Processing a blocks may never happen simultaneously
sm
.
mutex
.
Lock
()
defer
sm
.
mutex
.
Unlock
()
header
:=
block
.
Header
()
if
sm
.
bc
.
HasBlock
(
header
.
Hash
())
{
return
nil
,
&
KnownBlockError
{
header
.
Number
,
header
.
Hash
()}
return
nil
,
nil
,
&
KnownBlockError
{
header
.
Number
,
header
.
Hash
()}
}
if
!
sm
.
bc
.
HasBlock
(
header
.
ParentHash
)
{
return
nil
,
ParentError
(
header
.
ParentHash
)
return
nil
,
nil
,
ParentError
(
header
.
ParentHash
)
}
parent
:=
sm
.
bc
.
GetBlock
(
header
.
ParentHash
)
return
sm
.
processWithParent
(
block
,
parent
)
}
func
(
sm
*
BlockProcessor
)
processWithParent
(
block
,
parent
*
types
.
Block
)
(
td
*
big
.
Int
,
err
error
)
{
func
(
sm
*
BlockProcessor
)
processWithParent
(
block
,
parent
*
types
.
Block
)
(
td
*
big
.
Int
,
logs
state
.
Logs
,
err
error
)
{
sm
.
lastAttemptedBlock
=
block
// Create a new state based on the parent's root (e.g., create copy)
...
...
@@ -177,7 +173,7 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (td *big
// There can be at most two uncles
if
len
(
block
.
Uncles
())
>
2
{
return
nil
,
ValidationError
(
"Block can only contain one uncle (contained %v)"
,
len
(
block
.
Uncles
()))
return
nil
,
nil
,
ValidationError
(
"Block can only contain one uncle (contained %v)"
,
len
(
block
.
Uncles
()))
}
receipts
,
err
:=
sm
.
TransitionState
(
state
,
parent
,
block
,
false
)
...
...
@@ -236,7 +232,7 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (td *big
chainlogger
.
Infof
(
"processed block #%d (%x...)
\n
"
,
header
.
Number
,
block
.
Hash
()
.
Bytes
()[
0
:
4
])
return
td
,
nil
return
td
,
state
.
Logs
(),
nil
}
// Validates the current block. Returns an error if the block was invalid,
...
...
core/chain_makers.go
View file @
b5a71d95
...
...
@@ -93,7 +93,7 @@ func makeChain(bman *BlockProcessor, parent *types.Block, max int, db common.Dat
blocks
:=
make
(
types
.
Blocks
,
max
)
for
i
:=
0
;
i
<
max
;
i
++
{
block
:=
makeBlock
(
bman
,
parent
,
i
,
db
,
seed
)
td
,
err
:=
bman
.
processWithParent
(
block
,
parent
)
td
,
_
,
err
:=
bman
.
processWithParent
(
block
,
parent
)
if
err
!=
nil
{
fmt
.
Println
(
"process with parent failed"
,
err
)
panic
(
err
)
...
...
core/chain_manager.go
View file @
b5a71d95
...
...
@@ -410,7 +410,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
for
i
,
block
:=
range
chain
{
// Call in to the block processor and check for errors. It's likely that if one block fails
// all others will fail too (unless a known block is returned).
td
,
err
:=
self
.
processor
.
Process
(
block
)
td
,
logs
,
err
:=
self
.
processor
.
Process
(
block
)
if
err
!=
nil
{
if
IsKnownBlockErr
(
err
)
{
continue
...
...
@@ -438,29 +438,27 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
hash
:=
block
.
Hash
()
chainlogger
.
Infof
(
"Split detected. New head #%v (%x) TD=%v, was #%v (%x) TD=%v
\n
"
,
block
.
Header
()
.
Number
,
hash
[
:
4
],
td
,
cblock
.
Header
()
.
Number
,
chash
[
:
4
],
self
.
td
)
queue
[
i
]
=
ChainSplitEvent
{
block
}
queue
[
i
]
=
ChainSplitEvent
{
block
,
logs
}
queueEvent
.
splitCount
++
}
self
.
setTotalDifficulty
(
td
)
self
.
insert
(
block
)
/* XXX crashes
jsonlogger
.
LogJson
(
&
logger
.
EthChainNewHead
{
BlockHash:
common.Bytes2Hex(block.Hash()
),
BlockHash
:
block
.
Hash
()
.
Hex
(
),
BlockNumber
:
block
.
Number
(),
ChainHeadHash: c
ommon.Bytes2Hex(cblock.Hash()
),
BlockPrevHash:
common.Bytes2Hex(block.ParentHash()
),
ChainHeadHash
:
c
block
.
Hash
()
.
Hex
(
),
BlockPrevHash
:
block
.
ParentHash
()
.
Hex
(
),
})
*/
self
.
setTransState
(
state
.
New
(
block
.
Root
(),
self
.
stateDb
))
self
.
setTxState
(
state
.
New
(
block
.
Root
(),
self
.
stateDb
))
queue
[
i
]
=
ChainEvent
{
block
}
queue
[
i
]
=
ChainEvent
{
block
,
logs
}
queueEvent
.
canonicalCount
++
}
else
{
queue
[
i
]
=
ChainSideEvent
{
block
}
queue
[
i
]
=
ChainSideEvent
{
block
,
logs
}
queueEvent
.
sideCount
++
}
}
...
...
core/events.go
View file @
b5a71d95
package
core
import
"github.com/ethereum/go-ethereum/core/types"
import
(
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/state"
)
// TxPreEvent is posted when a transaction enters the transaction pool.
type
TxPreEvent
struct
{
Tx
*
types
.
Transaction
}
...
...
@@ -15,11 +18,25 @@ type NewBlockEvent struct{ Block *types.Block }
type
NewMinedBlockEvent
struct
{
Block
*
types
.
Block
}
// ChainSplit is posted when a new head is detected
type
ChainSplitEvent
struct
{
Block
*
types
.
Block
}
type
ChainEvent
struct
{
Block
*
types
.
Block
}
type
ChainSideEvent
struct
{
Block
*
types
.
Block
}
type
ChainSplitEvent
struct
{
Block
*
types
.
Block
Logs
state
.
Logs
}
type
ChainEvent
struct
{
Block
*
types
.
Block
Logs
state
.
Logs
}
type
ChainSideEvent
struct
{
Block
*
types
.
Block
Logs
state
.
Logs
}
type
PendingBlockEvent
struct
{
Block
*
types
.
Block
Logs
state
.
Logs
}
type
ChainHeadEvent
struct
{
Block
*
types
.
Block
}
...
...
core/filter.go
View file @
b5a71d95
...
...
@@ -33,8 +33,8 @@ type Filter struct {
max
int
topics
[][]
common
.
Hash
BlockCallback
func
(
*
types
.
Block
)
PendingCallback
func
(
*
types
.
Block
)
BlockCallback
func
(
*
types
.
Block
,
state
.
Logs
)
PendingCallback
func
(
*
types
.
Block
,
state
.
Logs
)
LogsCallback
func
(
state
.
Logs
)
}
...
...
core/types/common.go
View file @
b5a71d95
package
types
import
(
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/common"
"fmt"
)
type
BlockProcessor
interface
{
Process
(
*
Block
)
(
*
big
.
Int
,
error
)
Process
(
*
Block
)
(
*
big
.
Int
,
state
.
Logs
,
error
)
}
const
bloomLength
=
256
...
...
event/filter/eth_filter.go
View file @
b5a71d95
...
...
@@ -63,7 +63,7 @@ func (self *FilterManager) filterLoop() {
// Subscribe to events
events
:=
self
.
eventMux
.
Subscribe
(
core
.
PendingBlockEvent
{},
//
core.ChainEvent{},
core
.
ChainEvent
{},
state
.
Logs
(
nil
))
out
:
...
...
@@ -77,7 +77,7 @@ out:
self
.
filterMu
.
RLock
()
for
_
,
filter
:=
range
self
.
filters
{
if
filter
.
BlockCallback
!=
nil
{
filter
.
BlockCallback
(
event
.
Block
)
filter
.
BlockCallback
(
event
.
Block
,
event
.
Logs
)
}
}
self
.
filterMu
.
RUnlock
()
...
...
@@ -86,7 +86,7 @@ out:
self
.
filterMu
.
RLock
()
for
_
,
filter
:=
range
self
.
filters
{
if
filter
.
PendingCallback
!=
nil
{
filter
.
PendingCallback
(
event
.
Block
)
filter
.
PendingCallback
(
event
.
Block
,
event
.
Logs
)
}
}
self
.
filterMu
.
RUnlock
()
...
...
rpc/api.go
View file @
b5a71d95
...
...
@@ -86,7 +86,7 @@ func (self *EthereumApi) getStateWithNum(num int64) *xeth.State {
}
func
(
self
*
EthereumApi
)
start
()
{
timer
:=
time
.
NewTicker
(
filterTickerTime
)
timer
:=
time
.
NewTicker
(
2
*
time
.
Second
)
done
:
for
{
select
{
...
...
@@ -94,20 +94,20 @@ done:
self
.
logMut
.
Lock
()
self
.
messagesMut
.
Lock
()
for
id
,
filter
:=
range
self
.
logs
{
if
time
.
Since
(
filter
.
timeout
)
>
20
*
time
.
Second
{
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
)
>
20
*
time
.
Second
{
if
time
.
Since
(
filter
.
timeout
)
>
filterTickerTime
{
self
.
xeth
()
.
Whisper
()
.
Unwatch
(
id
)
delete
(
self
.
messages
,
id
)
}
}
self
.
logMut
.
Unlock
()
self
.
messagesMut
.
Unlock
()
self
.
logMut
.
Unlock
()
case
<-
self
.
quit
:
break
done
}
...
...
@@ -161,7 +161,7 @@ func (self *EthereumApi) NewFilter(args *FilterOptions, reply *interface{}) erro
id
=
self
.
filterManager
.
InstallFilter
(
filter
)
self
.
logs
[
id
]
=
&
logFilter
{
timeout
:
time
.
Now
()}
*
reply
=
i2hex
(
id
)
*
reply
=
common
.
ToHex
(
big
.
NewInt
(
int64
(
id
))
.
Bytes
()
)
return
nil
}
...
...
@@ -180,10 +180,13 @@ func (self *EthereumApi) NewFilterString(args *FilterStringArgs, reply *interfac
var
id
int
filter
:=
core
.
NewFilter
(
self
.
xeth
()
.
Backend
())
callback
:=
func
(
block
*
types
.
Block
)
{
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
{})
}
...
...
@@ -198,7 +201,7 @@ func (self *EthereumApi) NewFilterString(args *FilterStringArgs, reply *interfac
id
=
self
.
filterManager
.
InstallFilter
(
filter
)
self
.
logs
[
id
]
=
&
logFilter
{
timeout
:
time
.
Now
()}
*
reply
=
i2hex
(
id
)
*
reply
=
common
.
ToHex
(
big
.
NewInt
(
int64
(
id
))
.
Bytes
()
)
return
nil
}
...
...
@@ -257,6 +260,11 @@ func (p *EthereumApi) Transact(args *NewTxArgs, reply *interface{}) (err error)
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
{
...
...
@@ -478,7 +486,7 @@ func (p *EthereumApi) GetBlockUncleCountByNumber(blocknum int64) (int64, error)
func
(
p
*
EthereumApi
)
GetRequestReply
(
req
*
RpcRequest
,
reply
*
interface
{})
error
{
// Spec at https://github.com/ethereum/wiki/wiki/Generic-JSON-RPC
rpclogger
.
Debug
f
(
"%s %s"
,
req
.
Method
,
req
.
Params
)
rpclogger
.
Info
f
(
"%s %s"
,
req
.
Method
,
req
.
Params
)
switch
req
.
Method
{
case
"web3_sha3"
:
args
:=
new
(
Sha3Args
)
...
...
rpc/args.go
View file @
b5a71d95
...
...
@@ -8,10 +8,18 @@ import (
"github.com/ethereum/go-ethereum/common"
)
func
blockNumber
(
raw
json
.
RawMessage
,
number
*
int64
)
(
err
error
)
{
var
str
string
if
err
=
json
.
Unmarshal
(
raw
,
&
str
);
err
!=
nil
{
return
NewDecodeParamError
(
err
.
Error
())
func
blockAge
(
raw
interface
{},
number
*
int64
)
(
err
error
)
{
// Parse as integer
num
,
ok
:=
raw
.
(
float64
)
if
ok
{
*
number
=
int64
(
num
)
return
nil
}
// Parse as string/hexstring
str
,
ok
:=
raw
.
(
string
)
if
!
ok
{
return
NewDecodeParamError
(
"BlockNumber is not a string"
)
}
switch
str
{
...
...
@@ -22,6 +30,7 @@ func blockNumber(raw json.RawMessage, number *int64) (err error) {
default
:
*
number
=
common
.
String2Big
(
str
)
.
Int64
()
}
return
nil
}
...
...
@@ -95,18 +104,51 @@ type NewTxArgs struct {
}
func
(
args
*
NewTxArgs
)
UnmarshalJSON
(
b
[]
byte
)
(
err
error
)
{
var
obj
struct
{
From
,
To
,
Value
,
Gas
,
GasPrice
,
Data
string
}
if
err
=
UnmarshalRawMessages
(
b
,
&
obj
,
&
args
.
BlockNumber
);
err
!=
nil
{
return
err
var
obj
[]
json
.
RawMessage
var
ext
struct
{
From
,
To
,
Value
,
Gas
,
GasPrice
,
Data
string
}
// Decode byte slice to array of RawMessages
if
err
:=
json
.
Unmarshal
(
b
,
&
obj
);
err
!=
nil
{
return
NewDecodeParamError
(
err
.
Error
())
}
// Check for sufficient params
if
len
(
obj
)
<
1
{
return
NewInsufficientParamsError
(
len
(
obj
),
1
)
}
// Decode 0th RawMessage to temporary struct
if
err
:=
json
.
Unmarshal
(
obj
[
0
],
&
ext
);
err
!=
nil
{
return
NewDecodeParamError
(
err
.
Error
())
}
// var ok bool
args
.
From
=
ext
.
From
args
.
To
=
ext
.
To
args
.
Value
=
common
.
String2Big
(
ext
.
Value
)
args
.
Gas
=
common
.
String2Big
(
ext
.
Gas
)
args
.
GasPrice
=
common
.
String2Big
(
ext
.
GasPrice
)
args
.
Data
=
ext
.
Data
// Check for optional BlockNumber param
if
len
(
obj
)
>
1
{
var
raw
interface
{}
if
err
=
json
.
Unmarshal
(
obj
[
1
],
&
raw
);
err
!=
nil
{
return
NewDecodeParamError
(
err
.
Error
())
}
if
err
:=
blockAge
(
raw
,
&
args
.
BlockNumber
);
err
!=
nil
{
return
err
}
}
args
.
From
=
obj
.
From
args
.
To
=
obj
.
To
args
.
Value
=
common
.
Big
(
obj
.
Value
)
args
.
Gas
=
common
.
Big
(
obj
.
Gas
)
args
.
GasPrice
=
common
.
Big
(
obj
.
GasPrice
)
args
.
Data
=
obj
.
Data
return
nil
}
func
(
args
*
NewTxArgs
)
requirements
()
error
{
if
len
(
args
.
From
)
==
0
{
return
NewValidationError
(
"From"
,
"Is required"
)
}
return
nil
}
...
...
@@ -116,10 +158,27 @@ type GetStorageArgs struct {
}
func
(
args
*
GetStorageArgs
)
UnmarshalJSON
(
b
[]
byte
)
(
err
error
)
{
if
err
=
UnmarshalRawMessages
(
b
,
&
args
.
Address
,
&
args
.
BlockNumber
);
err
!=
nil
{
var
obj
[]
interface
{}
if
err
:=
json
.
Unmarshal
(
b
,
&
obj
);
err
!=
nil
{
return
NewDecodeParamError
(
err
.
Error
())
}
if
len
(
obj
)
<
1
{
return
NewInsufficientParamsError
(
len
(
obj
),
1
)
}
addstr
,
ok
:=
obj
[
0
]
.
(
string
)
if
!
ok
{
return
NewDecodeParamError
(
"Address is not a string"
)
}
args
.
Address
=
addstr
if
len
(
obj
)
>
1
{
if
err
:=
blockAge
(
obj
[
1
],
&
args
.
BlockNumber
);
err
!=
nil
{
return
err
}
}
return
nil
}
...
...
@@ -137,16 +196,32 @@ type GetStorageAtArgs struct {
}
func
(
args
*
GetStorageAtArgs
)
UnmarshalJSON
(
b
[]
byte
)
(
err
error
)
{
var
obj
[]
string
if
err
=
UnmarshalRawMessages
(
b
,
&
obj
,
&
args
.
BlockNumber
);
err
!=
nil
{
var
obj
[]
interface
{}
if
err
:=
json
.
Unmarshal
(
b
,
&
obj
);
err
!=
nil
{
return
NewDecodeParamError
(
err
.
Error
())
}
if
len
(
obj
)
<
2
{
return
NewInsufficientParamsError
(
len
(
obj
),
2
)
}
args
.
Address
=
obj
[
0
]
args
.
Key
=
obj
[
1
]
addstr
,
ok
:=
obj
[
0
]
.
(
string
)
if
!
ok
{
return
NewDecodeParamError
(
"Address is not a string"
)
}
args
.
Address
=
addstr
keystr
,
ok
:=
obj
[
1
]
.
(
string
)
if
!
ok
{
return
NewDecodeParamError
(
"Key is not a string"
)
}
args
.
Key
=
keystr
if
len
(
obj
)
>
2
{
if
err
:=
blockAge
(
obj
[
2
],
&
args
.
BlockNumber
);
err
!=
nil
{
return
err
}
}
return
nil
}
...
...
@@ -168,10 +243,27 @@ type GetTxCountArgs struct {
}
func
(
args
*
GetTxCountArgs
)
UnmarshalJSON
(
b
[]
byte
)
(
err
error
)
{
if
err
=
UnmarshalRawMessages
(
b
,
&
args
.
Address
,
&
args
.
BlockNumber
);
err
!=
nil
{
var
obj
[]
interface
{}
if
err
:=
json
.
Unmarshal
(
b
,
&
obj
);
err
!=
nil
{
return
NewDecodeParamError
(
err
.
Error
())
}
if
len
(
obj
)
<
1
{
return
NewInsufficientParamsError
(
len
(
obj
),
1
)
}
addstr
,
ok
:=
obj
[
0
]
.
(
string
)
if
!
ok
{
return
NewDecodeParamError
(
"Address is not a string"
)
}
args
.
Address
=
addstr
if
len
(
obj
)
>
1
{
if
err
:=
blockAge
(
obj
[
1
],
&
args
.
BlockNumber
);
err
!=
nil
{
return
err
}
}
return
nil
}
...
...
@@ -189,8 +281,7 @@ type GetBalanceArgs struct {
func
(
args
*
GetBalanceArgs
)
UnmarshalJSON
(
b
[]
byte
)
(
err
error
)
{
var
obj
[]
interface
{}
r
:=
bytes
.
NewReader
(
b
)
if
err
:=
json
.
NewDecoder
(
r
)
.
Decode
(
&
obj
);
err
!=
nil
{
if
err
:=
json
.
Unmarshal
(
b
,
&
obj
);
err
!=
nil
{
return
NewDecodeParamError
(
err
.
Error
())
}
...
...
@@ -205,17 +296,11 @@ func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) {
args
.
Address
=
addstr
if
len
(
obj
)
>
1
{
if
obj
[
1
]
.
(
string
)
==
"latest"
{
args
.
BlockNumber
=
-
1
}
else
{
args
.
BlockNumber
=
common
.
Big
(
obj
[
1
]
.
(
string
))
.
Int64
()
if
err
:=
blockAge
(
obj
[
1
],
&
args
.
BlockNumber
);
err
!=
nil
{
return
err
}
}
// if err = UnmarshalRawMessages(b, &args.Address, &args.BlockNumber); err != nil {
// return NewDecodeParamError(err.Error())
// }
return
nil
}
...
...
@@ -232,10 +317,27 @@ type GetDataArgs struct {
}
func
(
args
*
GetDataArgs
)
UnmarshalJSON
(
b
[]
byte
)
(
err
error
)
{
if
err
=
UnmarshalRawMessages
(
b
,
&
args
.
Address
,
&
args
.
BlockNumber
);
err
!=
nil
{
var
obj
[]
interface
{}
if
err
:=
json
.
Unmarshal
(
b
,
&
obj
);
err
!=
nil
{
return
NewDecodeParamError
(
err
.
Error
())
}
if
len
(
obj
)
<
1
{
return
NewInsufficientParamsError
(
len
(
obj
),
1
)
}
addstr
,
ok
:=
obj
[
0
]
.
(
string
)
if
!
ok
{
return
NewDecodeParamError
(
"Address is not a string"
)
}
args
.
Address
=
addstr
if
len
(
obj
)
>
1
{
if
err
:=
blockAge
(
obj
[
1
],
&
args
.
BlockNumber
);
err
!=
nil
{
return
err
}
}
return
nil
}
...
...
@@ -392,10 +494,6 @@ func (args *FilterOptions) UnmarshalJSON(b []byte) (err error) {
return
nil
}
// type FilterChangedArgs struct {
// n int
// }
type
DbArgs
struct
{
Database
string
Key
string
...
...
@@ -578,31 +676,3 @@ func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) {
return
nil
}
// func (req *RpcRequest) ToRegisterArgs() (string, error) {
// if len(req.Params) < 1 {
// return "", errArguments
// }
// var args string
// err := json.Unmarshal(req.Params, &args)
// if err != nil {
// return "", err
// }
// return args, nil
// }
// func (req *RpcRequest) ToWatchTxArgs() (string, error) {
// if len(req.Params) < 1 {
// return "", errArguments
// }
// var args string
// err := json.Unmarshal(req.Params, &args)
// if err != nil {
// return "", err
// }
// return args, nil
// }
rpc/args_test.go
View file @
b5a71d95
...
...
@@ -43,6 +43,30 @@ func TestGetBalanceArgs(t *testing.T) {
}
}
func
TestGetBalanceArgsLatest
(
t
*
testing
.
T
)
{
input
:=
`["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "latest"]`
expected
:=
new
(
GetBalanceArgs
)
expected
.
Address
=
"0x407d73d8a49eeb85d32cf465507dd71d507100c1"
expected
.
BlockNumber
=
-
1
args
:=
new
(
GetBalanceArgs
)
if
err
:=
json
.
Unmarshal
([]
byte
(
input
),
&
args
);
err
!=
nil
{
t
.
Error
(
err
)
}
if
err
:=
args
.
requirements
();
err
!=
nil
{
t
.
Error
(
err
)
}
if
args
.
Address
!=
expected
.
Address
{
t
.
Errorf
(
"Address should be %v but is %v"
,
expected
.
Address
,
args
.
Address
)
}
if
args
.
BlockNumber
!=
expected
.
BlockNumber
{
t
.
Errorf
(
"BlockNumber should be %v but is %v"
,
expected
.
BlockNumber
,
args
.
BlockNumber
)
}
}
func
TestGetBalanceEmptyArgs
(
t
*
testing
.
T
)
{
input
:=
`[]`
...
...
@@ -120,7 +144,8 @@ func TestNewTxArgs(t *testing.T) {
"gas": "0x76c0",
"gasPrice": "0x9184e72a000",
"value": "0x9184e72a000",
"data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"}]`
"data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"},
"0x10"]`
expected
:=
new
(
NewTxArgs
)
expected
.
From
=
"0xb60e8dd61c5d32be8058bb8eb970870f07233155"
expected
.
To
=
"0xd46e8dd67c5d32be8058bb8eb970870f072445675"
...
...
@@ -128,6 +153,7 @@ func TestNewTxArgs(t *testing.T) {
expected
.
GasPrice
=
big
.
NewInt
(
10000000000000
)
expected
.
Value
=
big
.
NewInt
(
10000000000000
)
expected
.
Data
=
"0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
expected
.
BlockNumber
=
big
.
NewInt
(
16
)
.
Int64
()
args
:=
new
(
NewTxArgs
)
if
err
:=
json
.
Unmarshal
([]
byte
(
input
),
&
args
);
err
!=
nil
{
...
...
@@ -157,6 +183,30 @@ func TestNewTxArgs(t *testing.T) {
if
expected
.
Data
!=
args
.
Data
{
t
.
Errorf
(
"Data shoud be %#v but is %#v"
,
expected
.
Data
,
args
.
Data
)
}
if
expected
.
BlockNumber
!=
args
.
BlockNumber
{
t
.
Errorf
(
"BlockNumber shoud be %#v but is %#v"
,
expected
.
BlockNumber
,
args
.
BlockNumber
)
}
}
func
TestNewTxArgsBlockInt
(
t
*
testing
.
T
)
{
input
:=
`[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155"}, 5]`
expected
:=
new
(
NewTxArgs
)
expected
.
From
=
"0xb60e8dd61c5d32be8058bb8eb970870f07233155"
expected
.
BlockNumber
=
big
.
NewInt
(
5
)
.
Int64
()
args
:=
new
(
NewTxArgs
)
if
err
:=
json
.
Unmarshal
([]
byte
(
input
),
&
args
);
err
!=
nil
{
t
.
Error
(
err
)
}
if
expected
.
From
!=
args
.
From
{
t
.
Errorf
(
"From shoud be %#v but is %#v"
,
expected
.
From
,
args
.
From
)
}
if
expected
.
BlockNumber
!=
args
.
BlockNumber
{
t
.
Errorf
(
"BlockNumber shoud be %#v but is %#v"
,
expected
.
BlockNumber
,
args
.
BlockNumber
)
}
}
func
TestNewTxArgsEmpty
(
t
*
testing
.
T
)
{
...
...
@@ -169,6 +219,34 @@ func TestNewTxArgsEmpty(t *testing.T) {
}
}
func
TestNewTxArgsReqs
(
t
*
testing
.
T
)
{
args
:=
new
(
NewTxArgs
)
args
.
From
=
"0xb60e8dd61c5d32be8058bb8eb970870f07233155"
err
:=
args
.
requirements
()
switch
err
.
(
type
)
{
case
nil
:
break
default
:
t
.
Errorf
(
"Get %T"
,
err
)
}
}
func
TestNewTxArgsReqsFromBlank
(
t
*
testing
.
T
)
{
args
:=
new
(
NewTxArgs
)
args
.
From
=
""
err
:=
args
.
requirements
()
switch
err
.
(
type
)
{
case
nil
:
t
.
Error
(
"Expected error but didn't get one"
)
case
*
ValidationError
:
break
default
:
t
.
Error
(
"Wrong type of error"
)
}
}
func
TestGetStorageArgs
(
t
*
testing
.
T
)
{
input
:=
`["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "latest"]`
expected
:=
new
(
GetStorageArgs
)
...
...
rpc/util.go
View file @
b5a71d95
...
...
@@ -17,10 +17,6 @@
package
rpc
import
(
"encoding/json"
"fmt"
"math/big"
"reflect"
"time"
"github.com/ethereum/go-ethereum/common"
...
...
@@ -31,74 +27,6 @@ import (
var
rpclogger
=
logger
.
NewLogger
(
"RPC"
)
// Unmarshal state is a helper method which has the ability to decode messsages
// that use the `defaultBlock` (https://github.com/ethereum/wiki/wiki/JSON-RPC#the-default-block-parameter)
// For example a `call`: [{to: "0x....", data:"0x..."}, "latest"]. The first argument is the transaction
// message and the second one refers to the block height (or state) to which to apply this `call`.
func
UnmarshalRawMessages
(
b
[]
byte
,
iface
interface
{},
number
*
int64
)
(
err
error
)
{
var
data
[]
json
.
RawMessage
if
err
=
json
.
Unmarshal
(
b
,
&
data
);
err
!=
nil
&&
len
(
data
)
==
0
{
return
NewDecodeParamError
(
err
.
Error
())
}
// Hrm... Occurs when no params
if
len
(
data
)
==
0
{
return
NewDecodeParamError
(
"No data"
)
}
// Number index determines the index in the array for a possible block number
numberIndex
:=
0
value
:=
reflect
.
ValueOf
(
iface
)
rvalue
:=
reflect
.
Indirect
(
value
)
switch
rvalue
.
Kind
()
{
case
reflect
.
Slice
:
// This is a bit of a cheat, but `data` is expected to be larger than 2 if iface is a slice
if
number
!=
nil
{
numberIndex
=
len
(
data
)
-
1
}
else
{
numberIndex
=
len
(
data
)
}
slice
:=
reflect
.
MakeSlice
(
rvalue
.
Type
(),
numberIndex
,
numberIndex
)
for
i
,
raw
:=
range
data
[
0
:
numberIndex
]
{
v
:=
slice
.
Index
(
i
)
.
Interface
()
if
err
=
json
.
Unmarshal
(
raw
,
&
v
);
err
!=
nil
{
fmt
.
Println
(
err
,
v
)
return
err
}
slice
.
Index
(
i
)
.
Set
(
reflect
.
ValueOf
(
v
))
}
reflect
.
Indirect
(
rvalue
)
.
Set
(
slice
)
//value.Set(slice)
case
reflect
.
Struct
:
fallthrough
default
:
if
err
=
json
.
Unmarshal
(
data
[
0
],
iface
);
err
!=
nil
{
return
NewDecodeParamError
(
err
.
Error
())
}
numberIndex
=
1
}
// <0 index means out of bound for block number
if
numberIndex
>=
0
&&
len
(
data
)
>
numberIndex
{
if
err
=
blockNumber
(
data
[
numberIndex
],
number
);
err
!=
nil
{
return
NewDecodeParamError
(
err
.
Error
())
}
}
return
nil
}
func
i2hex
(
n
int
)
string
{
return
common
.
ToHex
(
big
.
NewInt
(
int64
(
n
))
.
Bytes
())
}
type
RpcServer
interface
{
Start
()
Stop
()
}
type
Log
struct
{
Address
string
`json:"address"`
Topic
[]
string
`json:"topic"`
...
...
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