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
d513584e
Unverified
Commit
d513584e
authored
Nov 17, 2020
by
Martin Holst Swende
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cmd/geth: remove retesteth
parent
92c56eb8
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
0 additions
and
1068 deletions
+0
-1068
main.go
cmd/geth/main.go
+0
-2
retesteth.go
cmd/geth/retesteth.go
+0
-918
retesteth_copypaste.go
cmd/geth/retesteth_copypaste.go
+0
-148
No files found.
cmd/geth/main.go
View file @
d513584e
...
...
@@ -244,8 +244,6 @@ func init() {
licenseCommand
,
// See config.go
dumpConfigCommand
,
// See retesteth.go
retestethCommand
,
// See cmd/utils/flags_legacy.go
utils
.
ShowDeprecated
,
}
...
...
cmd/geth/retesteth.go
deleted
100644 → 0
View file @
92c56eb8
// Copyright 2019 The go-ethereum Authors
// 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
main
import
(
"bytes"
"context"
"fmt"
"math/big"
"os"
"os/signal"
"time"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/consensus/misc"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/trie"
cli
"gopkg.in/urfave/cli.v1"
)
var
(
rpcPortFlag
=
cli
.
IntFlag
{
Name
:
"rpcport"
,
Usage
:
"HTTP-RPC server listening port"
,
Value
:
node
.
DefaultHTTPPort
,
}
retestethCommand
=
cli
.
Command
{
Action
:
utils
.
MigrateFlags
(
retesteth
),
Name
:
"retesteth"
,
Usage
:
"Launches geth in retesteth mode"
,
ArgsUsage
:
""
,
Flags
:
[]
cli
.
Flag
{
rpcPortFlag
},
Category
:
"MISCELLANEOUS COMMANDS"
,
Description
:
`Launches geth in retesteth mode (no database, no network, only retesteth RPC interface)`
,
}
)
type
RetestethTestAPI
interface
{
SetChainParams
(
ctx
context
.
Context
,
chainParams
ChainParams
)
(
bool
,
error
)
MineBlocks
(
ctx
context
.
Context
,
number
uint64
)
(
bool
,
error
)
ModifyTimestamp
(
ctx
context
.
Context
,
interval
uint64
)
(
bool
,
error
)
ImportRawBlock
(
ctx
context
.
Context
,
rawBlock
hexutil
.
Bytes
)
(
common
.
Hash
,
error
)
RewindToBlock
(
ctx
context
.
Context
,
number
uint64
)
(
bool
,
error
)
GetLogHash
(
ctx
context
.
Context
,
txHash
common
.
Hash
)
(
common
.
Hash
,
error
)
}
type
RetestethEthAPI
interface
{
SendRawTransaction
(
ctx
context
.
Context
,
rawTx
hexutil
.
Bytes
)
(
common
.
Hash
,
error
)
BlockNumber
(
ctx
context
.
Context
)
(
uint64
,
error
)
GetBlockByNumber
(
ctx
context
.
Context
,
blockNr
math
.
HexOrDecimal64
,
fullTx
bool
)
(
map
[
string
]
interface
{},
error
)
GetBlockByHash
(
ctx
context
.
Context
,
blockHash
common
.
Hash
,
fullTx
bool
)
(
map
[
string
]
interface
{},
error
)
GetBalance
(
ctx
context
.
Context
,
address
common
.
Address
,
blockNr
math
.
HexOrDecimal64
)
(
*
math
.
HexOrDecimal256
,
error
)
GetCode
(
ctx
context
.
Context
,
address
common
.
Address
,
blockNr
math
.
HexOrDecimal64
)
(
hexutil
.
Bytes
,
error
)
GetTransactionCount
(
ctx
context
.
Context
,
address
common
.
Address
,
blockNr
math
.
HexOrDecimal64
)
(
uint64
,
error
)
}
type
RetestethDebugAPI
interface
{
AccountRange
(
ctx
context
.
Context
,
blockHashOrNumber
*
math
.
HexOrDecimal256
,
txIndex
uint64
,
addressHash
*
math
.
HexOrDecimal256
,
maxResults
uint64
,
)
(
AccountRangeResult
,
error
)
StorageRangeAt
(
ctx
context
.
Context
,
blockHashOrNumber
*
math
.
HexOrDecimal256
,
txIndex
uint64
,
address
common
.
Address
,
begin
*
math
.
HexOrDecimal256
,
maxResults
uint64
,
)
(
StorageRangeResult
,
error
)
}
type
RetestWeb3API
interface
{
ClientVersion
(
ctx
context
.
Context
)
(
string
,
error
)
}
type
RetestethAPI
struct
{
ethDb
ethdb
.
Database
db
state
.
Database
chainConfig
*
params
.
ChainConfig
author
common
.
Address
extraData
[]
byte
genesisHash
common
.
Hash
engine
*
NoRewardEngine
blockchain
*
core
.
BlockChain
txMap
map
[
common
.
Address
]
map
[
uint64
]
*
types
.
Transaction
// Sender -> Nonce -> Transaction
txSenders
map
[
common
.
Address
]
struct
{}
// Set of transaction senders
blockInterval
uint64
}
type
ChainParams
struct
{
SealEngine
string
`json:"sealEngine"`
Params
CParamsParams
`json:"params"`
Genesis
CParamsGenesis
`json:"genesis"`
Accounts
map
[
common
.
Address
]
CParamsAccount
`json:"accounts"`
}
type
CParamsParams
struct
{
AccountStartNonce
math
.
HexOrDecimal64
`json:"accountStartNonce"`
HomesteadForkBlock
*
math
.
HexOrDecimal64
`json:"homesteadForkBlock"`
EIP150ForkBlock
*
math
.
HexOrDecimal64
`json:"EIP150ForkBlock"`
EIP158ForkBlock
*
math
.
HexOrDecimal64
`json:"EIP158ForkBlock"`
DaoHardforkBlock
*
math
.
HexOrDecimal64
`json:"daoHardforkBlock"`
ByzantiumForkBlock
*
math
.
HexOrDecimal64
`json:"byzantiumForkBlock"`
ConstantinopleForkBlock
*
math
.
HexOrDecimal64
`json:"constantinopleForkBlock"`
ConstantinopleFixForkBlock
*
math
.
HexOrDecimal64
`json:"constantinopleFixForkBlock"`
IstanbulBlock
*
math
.
HexOrDecimal64
`json:"istanbulForkBlock"`
ChainID
*
math
.
HexOrDecimal256
`json:"chainID"`
MaximumExtraDataSize
math
.
HexOrDecimal64
`json:"maximumExtraDataSize"`
TieBreakingGas
bool
`json:"tieBreakingGas"`
MinGasLimit
math
.
HexOrDecimal64
`json:"minGasLimit"`
MaxGasLimit
math
.
HexOrDecimal64
`json:"maxGasLimit"`
GasLimitBoundDivisor
math
.
HexOrDecimal64
`json:"gasLimitBoundDivisor"`
MinimumDifficulty
math
.
HexOrDecimal256
`json:"minimumDifficulty"`
DifficultyBoundDivisor
math
.
HexOrDecimal256
`json:"difficultyBoundDivisor"`
DurationLimit
math
.
HexOrDecimal256
`json:"durationLimit"`
BlockReward
math
.
HexOrDecimal256
`json:"blockReward"`
NetworkID
math
.
HexOrDecimal256
`json:"networkID"`
}
type
CParamsGenesis
struct
{
Nonce
math
.
HexOrDecimal64
`json:"nonce"`
Difficulty
*
math
.
HexOrDecimal256
`json:"difficulty"`
MixHash
*
math
.
HexOrDecimal256
`json:"mixHash"`
Author
common
.
Address
`json:"author"`
Timestamp
math
.
HexOrDecimal64
`json:"timestamp"`
ParentHash
common
.
Hash
`json:"parentHash"`
ExtraData
hexutil
.
Bytes
`json:"extraData"`
GasLimit
math
.
HexOrDecimal64
`json:"gasLimit"`
}
type
CParamsAccount
struct
{
Balance
*
math
.
HexOrDecimal256
`json:"balance"`
Precompiled
*
CPAccountPrecompiled
`json:"precompiled"`
Code
hexutil
.
Bytes
`json:"code"`
Storage
map
[
string
]
string
`json:"storage"`
Nonce
*
math
.
HexOrDecimal64
`json:"nonce"`
}
type
CPAccountPrecompiled
struct
{
Name
string
`json:"name"`
StartingBlock
math
.
HexOrDecimal64
`json:"startingBlock"`
Linear
*
CPAPrecompiledLinear
`json:"linear"`
}
type
CPAPrecompiledLinear
struct
{
Base
uint64
`json:"base"`
Word
uint64
`json:"word"`
}
type
AccountRangeResult
struct
{
AddressMap
map
[
common
.
Hash
]
common
.
Address
`json:"addressMap"`
NextKey
common
.
Hash
`json:"nextKey"`
}
type
StorageRangeResult
struct
{
Complete
bool
`json:"complete"`
Storage
map
[
common
.
Hash
]
SRItem
`json:"storage"`
}
type
SRItem
struct
{
Key
string
`json:"key"`
Value
string
`json:"value"`
}
type
NoRewardEngine
struct
{
inner
consensus
.
Engine
rewardsOn
bool
}
func
(
e
*
NoRewardEngine
)
Author
(
header
*
types
.
Header
)
(
common
.
Address
,
error
)
{
return
e
.
inner
.
Author
(
header
)
}
func
(
e
*
NoRewardEngine
)
VerifyHeader
(
chain
consensus
.
ChainHeaderReader
,
header
*
types
.
Header
,
seal
bool
)
error
{
return
e
.
inner
.
VerifyHeader
(
chain
,
header
,
seal
)
}
func
(
e
*
NoRewardEngine
)
VerifyHeaders
(
chain
consensus
.
ChainHeaderReader
,
headers
[]
*
types
.
Header
,
seals
[]
bool
)
(
chan
<-
struct
{},
<-
chan
error
)
{
return
e
.
inner
.
VerifyHeaders
(
chain
,
headers
,
seals
)
}
func
(
e
*
NoRewardEngine
)
VerifyUncles
(
chain
consensus
.
ChainReader
,
block
*
types
.
Block
)
error
{
return
e
.
inner
.
VerifyUncles
(
chain
,
block
)
}
func
(
e
*
NoRewardEngine
)
VerifySeal
(
chain
consensus
.
ChainHeaderReader
,
header
*
types
.
Header
)
error
{
return
e
.
inner
.
VerifySeal
(
chain
,
header
)
}
func
(
e
*
NoRewardEngine
)
Prepare
(
chain
consensus
.
ChainHeaderReader
,
header
*
types
.
Header
)
error
{
return
e
.
inner
.
Prepare
(
chain
,
header
)
}
func
(
e
*
NoRewardEngine
)
accumulateRewards
(
config
*
params
.
ChainConfig
,
state
*
state
.
StateDB
,
header
*
types
.
Header
,
uncles
[]
*
types
.
Header
)
{
// Simply touch miner and uncle coinbase accounts
reward
:=
big
.
NewInt
(
0
)
for
_
,
uncle
:=
range
uncles
{
state
.
AddBalance
(
uncle
.
Coinbase
,
reward
)
}
state
.
AddBalance
(
header
.
Coinbase
,
reward
)
}
func
(
e
*
NoRewardEngine
)
Finalize
(
chain
consensus
.
ChainHeaderReader
,
header
*
types
.
Header
,
statedb
*
state
.
StateDB
,
txs
[]
*
types
.
Transaction
,
uncles
[]
*
types
.
Header
)
{
if
e
.
rewardsOn
{
e
.
inner
.
Finalize
(
chain
,
header
,
statedb
,
txs
,
uncles
)
}
else
{
e
.
accumulateRewards
(
chain
.
Config
(),
statedb
,
header
,
uncles
)
header
.
Root
=
statedb
.
IntermediateRoot
(
chain
.
Config
()
.
IsEIP158
(
header
.
Number
))
}
}
func
(
e
*
NoRewardEngine
)
FinalizeAndAssemble
(
chain
consensus
.
ChainHeaderReader
,
header
*
types
.
Header
,
statedb
*
state
.
StateDB
,
txs
[]
*
types
.
Transaction
,
uncles
[]
*
types
.
Header
,
receipts
[]
*
types
.
Receipt
)
(
*
types
.
Block
,
error
)
{
if
e
.
rewardsOn
{
return
e
.
inner
.
FinalizeAndAssemble
(
chain
,
header
,
statedb
,
txs
,
uncles
,
receipts
)
}
else
{
e
.
accumulateRewards
(
chain
.
Config
(),
statedb
,
header
,
uncles
)
header
.
Root
=
statedb
.
IntermediateRoot
(
chain
.
Config
()
.
IsEIP158
(
header
.
Number
))
// Header seems complete, assemble into a block and return
return
types
.
NewBlock
(
header
,
txs
,
uncles
,
receipts
,
new
(
trie
.
Trie
)),
nil
}
}
func
(
e
*
NoRewardEngine
)
Seal
(
chain
consensus
.
ChainHeaderReader
,
block
*
types
.
Block
,
results
chan
<-
*
types
.
Block
,
stop
<-
chan
struct
{})
error
{
return
e
.
inner
.
Seal
(
chain
,
block
,
results
,
stop
)
}
func
(
e
*
NoRewardEngine
)
SealHash
(
header
*
types
.
Header
)
common
.
Hash
{
return
e
.
inner
.
SealHash
(
header
)
}
func
(
e
*
NoRewardEngine
)
CalcDifficulty
(
chain
consensus
.
ChainHeaderReader
,
time
uint64
,
parent
*
types
.
Header
)
*
big
.
Int
{
return
e
.
inner
.
CalcDifficulty
(
chain
,
time
,
parent
)
}
func
(
e
*
NoRewardEngine
)
APIs
(
chain
consensus
.
ChainHeaderReader
)
[]
rpc
.
API
{
return
e
.
inner
.
APIs
(
chain
)
}
func
(
e
*
NoRewardEngine
)
Close
()
error
{
return
e
.
inner
.
Close
()
}
func
(
api
*
RetestethAPI
)
SetChainParams
(
ctx
context
.
Context
,
chainParams
ChainParams
)
(
bool
,
error
)
{
// Clean up
if
api
.
blockchain
!=
nil
{
api
.
blockchain
.
Stop
()
}
if
api
.
engine
!=
nil
{
api
.
engine
.
Close
()
}
if
api
.
ethDb
!=
nil
{
api
.
ethDb
.
Close
()
}
ethDb
:=
rawdb
.
NewMemoryDatabase
()
accounts
:=
make
(
core
.
GenesisAlloc
)
for
address
,
account
:=
range
chainParams
.
Accounts
{
balance
:=
big
.
NewInt
(
0
)
if
account
.
Balance
!=
nil
{
balance
.
Set
((
*
big
.
Int
)(
account
.
Balance
))
}
var
nonce
uint64
if
account
.
Nonce
!=
nil
{
nonce
=
uint64
(
*
account
.
Nonce
)
}
if
account
.
Precompiled
==
nil
||
account
.
Balance
!=
nil
{
storage
:=
make
(
map
[
common
.
Hash
]
common
.
Hash
)
for
k
,
v
:=
range
account
.
Storage
{
storage
[
common
.
HexToHash
(
k
)]
=
common
.
HexToHash
(
v
)
}
accounts
[
address
]
=
core
.
GenesisAccount
{
Balance
:
balance
,
Code
:
account
.
Code
,
Nonce
:
nonce
,
Storage
:
storage
,
}
}
}
chainId
:=
big
.
NewInt
(
1
)
if
chainParams
.
Params
.
ChainID
!=
nil
{
chainId
.
Set
((
*
big
.
Int
)(
chainParams
.
Params
.
ChainID
))
}
var
(
homesteadBlock
*
big
.
Int
daoForkBlock
*
big
.
Int
eip150Block
*
big
.
Int
eip155Block
*
big
.
Int
eip158Block
*
big
.
Int
byzantiumBlock
*
big
.
Int
constantinopleBlock
*
big
.
Int
petersburgBlock
*
big
.
Int
istanbulBlock
*
big
.
Int
)
if
chainParams
.
Params
.
HomesteadForkBlock
!=
nil
{
homesteadBlock
=
big
.
NewInt
(
int64
(
*
chainParams
.
Params
.
HomesteadForkBlock
))
}
if
chainParams
.
Params
.
DaoHardforkBlock
!=
nil
{
daoForkBlock
=
big
.
NewInt
(
int64
(
*
chainParams
.
Params
.
DaoHardforkBlock
))
}
if
chainParams
.
Params
.
EIP150ForkBlock
!=
nil
{
eip150Block
=
big
.
NewInt
(
int64
(
*
chainParams
.
Params
.
EIP150ForkBlock
))
}
if
chainParams
.
Params
.
EIP158ForkBlock
!=
nil
{
eip158Block
=
big
.
NewInt
(
int64
(
*
chainParams
.
Params
.
EIP158ForkBlock
))
eip155Block
=
eip158Block
}
if
chainParams
.
Params
.
ByzantiumForkBlock
!=
nil
{
byzantiumBlock
=
big
.
NewInt
(
int64
(
*
chainParams
.
Params
.
ByzantiumForkBlock
))
}
if
chainParams
.
Params
.
ConstantinopleForkBlock
!=
nil
{
constantinopleBlock
=
big
.
NewInt
(
int64
(
*
chainParams
.
Params
.
ConstantinopleForkBlock
))
}
if
chainParams
.
Params
.
ConstantinopleFixForkBlock
!=
nil
{
petersburgBlock
=
big
.
NewInt
(
int64
(
*
chainParams
.
Params
.
ConstantinopleFixForkBlock
))
}
if
constantinopleBlock
!=
nil
&&
petersburgBlock
==
nil
{
petersburgBlock
=
big
.
NewInt
(
100000000000
)
}
if
chainParams
.
Params
.
IstanbulBlock
!=
nil
{
istanbulBlock
=
big
.
NewInt
(
int64
(
*
chainParams
.
Params
.
IstanbulBlock
))
}
genesis
:=
&
core
.
Genesis
{
Config
:
&
params
.
ChainConfig
{
ChainID
:
chainId
,
HomesteadBlock
:
homesteadBlock
,
DAOForkBlock
:
daoForkBlock
,
DAOForkSupport
:
true
,
EIP150Block
:
eip150Block
,
EIP155Block
:
eip155Block
,
EIP158Block
:
eip158Block
,
ByzantiumBlock
:
byzantiumBlock
,
ConstantinopleBlock
:
constantinopleBlock
,
PetersburgBlock
:
petersburgBlock
,
IstanbulBlock
:
istanbulBlock
,
},
Nonce
:
uint64
(
chainParams
.
Genesis
.
Nonce
),
Timestamp
:
uint64
(
chainParams
.
Genesis
.
Timestamp
),
ExtraData
:
chainParams
.
Genesis
.
ExtraData
,
GasLimit
:
uint64
(
chainParams
.
Genesis
.
GasLimit
),
Difficulty
:
big
.
NewInt
(
0
)
.
Set
((
*
big
.
Int
)(
chainParams
.
Genesis
.
Difficulty
)),
Mixhash
:
common
.
BigToHash
((
*
big
.
Int
)(
chainParams
.
Genesis
.
MixHash
)),
Coinbase
:
chainParams
.
Genesis
.
Author
,
ParentHash
:
chainParams
.
Genesis
.
ParentHash
,
Alloc
:
accounts
,
}
chainConfig
,
genesisHash
,
err
:=
core
.
SetupGenesisBlock
(
ethDb
,
genesis
)
if
err
!=
nil
{
return
false
,
err
}
fmt
.
Printf
(
"Chain config: %v
\n
"
,
chainConfig
)
var
inner
consensus
.
Engine
switch
chainParams
.
SealEngine
{
case
"NoProof"
,
"NoReward"
:
inner
=
ethash
.
NewFaker
()
case
"Ethash"
:
inner
=
ethash
.
New
(
ethash
.
Config
{
CacheDir
:
"ethash"
,
CachesInMem
:
2
,
CachesOnDisk
:
3
,
CachesLockMmap
:
false
,
DatasetsInMem
:
1
,
DatasetsOnDisk
:
2
,
DatasetsLockMmap
:
false
,
},
nil
,
false
)
default
:
return
false
,
fmt
.
Errorf
(
"unrecognised seal engine: %s"
,
chainParams
.
SealEngine
)
}
engine
:=
&
NoRewardEngine
{
inner
:
inner
,
rewardsOn
:
chainParams
.
SealEngine
!=
"NoReward"
}
blockchain
,
err
:=
core
.
NewBlockChain
(
ethDb
,
nil
,
chainConfig
,
engine
,
vm
.
Config
{},
nil
,
nil
)
if
err
!=
nil
{
return
false
,
err
}
api
.
chainConfig
=
chainConfig
api
.
genesisHash
=
genesisHash
api
.
author
=
chainParams
.
Genesis
.
Author
api
.
extraData
=
chainParams
.
Genesis
.
ExtraData
api
.
ethDb
=
ethDb
api
.
engine
=
engine
api
.
blockchain
=
blockchain
api
.
db
=
state
.
NewDatabase
(
api
.
ethDb
)
api
.
txMap
=
make
(
map
[
common
.
Address
]
map
[
uint64
]
*
types
.
Transaction
)
api
.
txSenders
=
make
(
map
[
common
.
Address
]
struct
{})
api
.
blockInterval
=
0
return
true
,
nil
}
func
(
api
*
RetestethAPI
)
SendRawTransaction
(
ctx
context
.
Context
,
rawTx
hexutil
.
Bytes
)
(
common
.
Hash
,
error
)
{
tx
:=
new
(
types
.
Transaction
)
if
err
:=
rlp
.
DecodeBytes
(
rawTx
,
tx
);
err
!=
nil
{
// Return nil is not by mistake - some tests include sending transaction where gasLimit overflows uint64
return
common
.
Hash
{},
nil
}
signer
:=
types
.
MakeSigner
(
api
.
chainConfig
,
big
.
NewInt
(
int64
(
api
.
currentNumber
())))
sender
,
err
:=
types
.
Sender
(
signer
,
tx
)
if
err
!=
nil
{
return
common
.
Hash
{},
err
}
if
nonceMap
,
ok
:=
api
.
txMap
[
sender
];
ok
{
nonceMap
[
tx
.
Nonce
()]
=
tx
}
else
{
nonceMap
=
make
(
map
[
uint64
]
*
types
.
Transaction
)
nonceMap
[
tx
.
Nonce
()]
=
tx
api
.
txMap
[
sender
]
=
nonceMap
}
api
.
txSenders
[
sender
]
=
struct
{}{}
return
tx
.
Hash
(),
nil
}
func
(
api
*
RetestethAPI
)
MineBlocks
(
ctx
context
.
Context
,
number
uint64
)
(
bool
,
error
)
{
for
i
:=
0
;
i
<
int
(
number
);
i
++
{
if
err
:=
api
.
mineBlock
();
err
!=
nil
{
return
false
,
err
}
}
fmt
.
Printf
(
"Mined %d blocks
\n
"
,
number
)
return
true
,
nil
}
func
(
api
*
RetestethAPI
)
currentNumber
()
uint64
{
if
current
:=
api
.
blockchain
.
CurrentBlock
();
current
!=
nil
{
return
current
.
NumberU64
()
}
return
0
}
func
(
api
*
RetestethAPI
)
mineBlock
()
error
{
number
:=
api
.
currentNumber
()
parentHash
:=
rawdb
.
ReadCanonicalHash
(
api
.
ethDb
,
number
)
parent
:=
rawdb
.
ReadBlock
(
api
.
ethDb
,
parentHash
,
number
)
var
timestamp
uint64
if
api
.
blockInterval
==
0
{
timestamp
=
uint64
(
time
.
Now
()
.
Unix
())
}
else
{
timestamp
=
parent
.
Time
()
+
api
.
blockInterval
}
gasLimit
:=
core
.
CalcGasLimit
(
parent
,
9223372036854775807
,
9223372036854775807
)
header
:=
&
types
.
Header
{
ParentHash
:
parent
.
Hash
(),
Number
:
big
.
NewInt
(
int64
(
number
+
1
)),
GasLimit
:
gasLimit
,
Extra
:
api
.
extraData
,
Time
:
timestamp
,
}
header
.
Coinbase
=
api
.
author
if
api
.
engine
!=
nil
{
api
.
engine
.
Prepare
(
api
.
blockchain
,
header
)
}
// If we are care about TheDAO hard-fork check whether to override the extra-data or not
if
daoBlock
:=
api
.
chainConfig
.
DAOForkBlock
;
daoBlock
!=
nil
{
// Check whether the block is among the fork extra-override range
limit
:=
new
(
big
.
Int
)
.
Add
(
daoBlock
,
params
.
DAOForkExtraRange
)
if
header
.
Number
.
Cmp
(
daoBlock
)
>=
0
&&
header
.
Number
.
Cmp
(
limit
)
<
0
{
// Depending whether we support or oppose the fork, override differently
if
api
.
chainConfig
.
DAOForkSupport
{
header
.
Extra
=
common
.
CopyBytes
(
params
.
DAOForkBlockExtra
)
}
else
if
bytes
.
Equal
(
header
.
Extra
,
params
.
DAOForkBlockExtra
)
{
header
.
Extra
=
[]
byte
{}
// If miner opposes, don't let it use the reserved extra-data
}
}
}
statedb
,
err
:=
api
.
blockchain
.
StateAt
(
parent
.
Root
())
if
err
!=
nil
{
return
err
}
if
api
.
chainConfig
.
DAOForkSupport
&&
api
.
chainConfig
.
DAOForkBlock
!=
nil
&&
api
.
chainConfig
.
DAOForkBlock
.
Cmp
(
header
.
Number
)
==
0
{
misc
.
ApplyDAOHardFork
(
statedb
)
}
gasPool
:=
new
(
core
.
GasPool
)
.
AddGas
(
header
.
GasLimit
)
txCount
:=
0
var
txs
[]
*
types
.
Transaction
var
receipts
[]
*
types
.
Receipt
var
blockFull
=
gasPool
.
Gas
()
<
params
.
TxGas
for
address
:=
range
api
.
txSenders
{
if
blockFull
{
break
}
m
:=
api
.
txMap
[
address
]
for
nonce
:=
statedb
.
GetNonce
(
address
);
;
nonce
++
{
if
tx
,
ok
:=
m
[
nonce
];
ok
{
// Try to apply transactions to the state
statedb
.
Prepare
(
tx
.
Hash
(),
common
.
Hash
{},
txCount
)
snap
:=
statedb
.
Snapshot
()
receipt
,
err
:=
core
.
ApplyTransaction
(
api
.
chainConfig
,
api
.
blockchain
,
&
api
.
author
,
gasPool
,
statedb
,
header
,
tx
,
&
header
.
GasUsed
,
*
api
.
blockchain
.
GetVMConfig
(),
)
if
err
!=
nil
{
statedb
.
RevertToSnapshot
(
snap
)
break
}
txs
=
append
(
txs
,
tx
)
receipts
=
append
(
receipts
,
receipt
)
delete
(
m
,
nonce
)
if
len
(
m
)
==
0
{
// Last tx for the sender
delete
(
api
.
txMap
,
address
)
delete
(
api
.
txSenders
,
address
)
}
txCount
++
if
gasPool
.
Gas
()
<
params
.
TxGas
{
blockFull
=
true
break
}
}
else
{
break
// Gap in the nonces
}
}
}
block
,
err
:=
api
.
engine
.
FinalizeAndAssemble
(
api
.
blockchain
,
header
,
statedb
,
txs
,
[]
*
types
.
Header
{},
receipts
)
if
err
!=
nil
{
return
err
}
return
api
.
importBlock
(
block
)
}
func
(
api
*
RetestethAPI
)
importBlock
(
block
*
types
.
Block
)
error
{
if
_
,
err
:=
api
.
blockchain
.
InsertChain
([]
*
types
.
Block
{
block
});
err
!=
nil
{
return
err
}
fmt
.
Printf
(
"Imported block %d, head is %d
\n
"
,
block
.
NumberU64
(),
api
.
currentNumber
())
return
nil
}
func
(
api
*
RetestethAPI
)
ModifyTimestamp
(
ctx
context
.
Context
,
interval
uint64
)
(
bool
,
error
)
{
api
.
blockInterval
=
interval
return
true
,
nil
}
func
(
api
*
RetestethAPI
)
ImportRawBlock
(
ctx
context
.
Context
,
rawBlock
hexutil
.
Bytes
)
(
common
.
Hash
,
error
)
{
block
:=
new
(
types
.
Block
)
if
err
:=
rlp
.
DecodeBytes
(
rawBlock
,
block
);
err
!=
nil
{
return
common
.
Hash
{},
err
}
fmt
.
Printf
(
"Importing block %d with parent hash: %x, genesisHash: %x
\n
"
,
block
.
NumberU64
(),
block
.
ParentHash
(),
api
.
genesisHash
)
if
err
:=
api
.
importBlock
(
block
);
err
!=
nil
{
return
common
.
Hash
{},
err
}
return
block
.
Hash
(),
nil
}
func
(
api
*
RetestethAPI
)
RewindToBlock
(
ctx
context
.
Context
,
newHead
uint64
)
(
bool
,
error
)
{
if
err
:=
api
.
blockchain
.
SetHead
(
newHead
);
err
!=
nil
{
return
false
,
err
}
// When we rewind, the transaction pool should be cleaned out.
api
.
txMap
=
make
(
map
[
common
.
Address
]
map
[
uint64
]
*
types
.
Transaction
)
api
.
txSenders
=
make
(
map
[
common
.
Address
]
struct
{})
return
true
,
nil
}
var
emptyListHash
common
.
Hash
=
common
.
HexToHash
(
"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
)
func
(
api
*
RetestethAPI
)
GetLogHash
(
ctx
context
.
Context
,
txHash
common
.
Hash
)
(
common
.
Hash
,
error
)
{
receipt
,
_
,
_
,
_
:=
rawdb
.
ReadReceipt
(
api
.
ethDb
,
txHash
,
api
.
chainConfig
)
if
receipt
==
nil
{
return
emptyListHash
,
nil
}
else
{
if
logListRlp
,
err
:=
rlp
.
EncodeToBytes
(
receipt
.
Logs
);
err
!=
nil
{
return
common
.
Hash
{},
err
}
else
{
return
common
.
BytesToHash
(
crypto
.
Keccak256
(
logListRlp
)),
nil
}
}
}
func
(
api
*
RetestethAPI
)
BlockNumber
(
ctx
context
.
Context
)
(
uint64
,
error
)
{
return
api
.
currentNumber
(),
nil
}
func
(
api
*
RetestethAPI
)
GetBlockByNumber
(
ctx
context
.
Context
,
blockNr
math
.
HexOrDecimal64
,
fullTx
bool
)
(
map
[
string
]
interface
{},
error
)
{
block
:=
api
.
blockchain
.
GetBlockByNumber
(
uint64
(
blockNr
))
if
block
!=
nil
{
response
,
err
:=
RPCMarshalBlock
(
block
,
true
,
fullTx
)
if
err
!=
nil
{
return
nil
,
err
}
response
[
"author"
]
=
response
[
"miner"
]
response
[
"totalDifficulty"
]
=
(
*
hexutil
.
Big
)(
api
.
blockchain
.
GetTd
(
block
.
Hash
(),
uint64
(
blockNr
)))
return
response
,
err
}
return
nil
,
fmt
.
Errorf
(
"block %d not found"
,
blockNr
)
}
func
(
api
*
RetestethAPI
)
GetBlockByHash
(
ctx
context
.
Context
,
blockHash
common
.
Hash
,
fullTx
bool
)
(
map
[
string
]
interface
{},
error
)
{
block
:=
api
.
blockchain
.
GetBlockByHash
(
blockHash
)
if
block
!=
nil
{
response
,
err
:=
RPCMarshalBlock
(
block
,
true
,
fullTx
)
if
err
!=
nil
{
return
nil
,
err
}
response
[
"author"
]
=
response
[
"miner"
]
response
[
"totalDifficulty"
]
=
(
*
hexutil
.
Big
)(
api
.
blockchain
.
GetTd
(
block
.
Hash
(),
block
.
Number
()
.
Uint64
()))
return
response
,
err
}
return
nil
,
fmt
.
Errorf
(
"block 0x%x not found"
,
blockHash
)
}
func
(
api
*
RetestethAPI
)
AccountRange
(
ctx
context
.
Context
,
blockHashOrNumber
*
math
.
HexOrDecimal256
,
txIndex
uint64
,
addressHash
*
math
.
HexOrDecimal256
,
maxResults
uint64
,
)
(
AccountRangeResult
,
error
)
{
var
(
header
*
types
.
Header
block
*
types
.
Block
)
if
(
*
big
.
Int
)(
blockHashOrNumber
)
.
Cmp
(
big
.
NewInt
(
math
.
MaxInt64
))
>
0
{
blockHash
:=
common
.
BigToHash
((
*
big
.
Int
)(
blockHashOrNumber
))
header
=
api
.
blockchain
.
GetHeaderByHash
(
blockHash
)
block
=
api
.
blockchain
.
GetBlockByHash
(
blockHash
)
//fmt.Printf("Account range: %x, txIndex %d, start: %x, maxResults: %d\n", blockHash, txIndex, common.BigToHash((*big.Int)(addressHash)), maxResults)
}
else
{
blockNumber
:=
(
*
big
.
Int
)(
blockHashOrNumber
)
.
Uint64
()
header
=
api
.
blockchain
.
GetHeaderByNumber
(
blockNumber
)
block
=
api
.
blockchain
.
GetBlockByNumber
(
blockNumber
)
//fmt.Printf("Account range: %d, txIndex %d, start: %x, maxResults: %d\n", blockNumber, txIndex, common.BigToHash((*big.Int)(addressHash)), maxResults)
}
parentHeader
:=
api
.
blockchain
.
GetHeaderByHash
(
header
.
ParentHash
)
var
root
common
.
Hash
var
statedb
*
state
.
StateDB
var
err
error
if
parentHeader
==
nil
||
int
(
txIndex
)
>=
len
(
block
.
Transactions
())
{
root
=
header
.
Root
statedb
,
err
=
api
.
blockchain
.
StateAt
(
root
)
if
err
!=
nil
{
return
AccountRangeResult
{},
err
}
}
else
{
root
=
parentHeader
.
Root
statedb
,
err
=
api
.
blockchain
.
StateAt
(
root
)
if
err
!=
nil
{
return
AccountRangeResult
{},
err
}
// Recompute transactions up to the target index.
signer
:=
types
.
MakeSigner
(
api
.
blockchain
.
Config
(),
block
.
Number
())
context
:=
core
.
NewEVMBlockContext
(
block
.
Header
(),
api
.
blockchain
,
nil
)
for
idx
,
tx
:=
range
block
.
Transactions
()
{
// Assemble the transaction call message and return if the requested offset
msg
,
_
:=
tx
.
AsMessage
(
signer
)
txContext
:=
core
.
NewEVMTxContext
(
msg
)
// Not yet the searched for transaction, execute on top of the current state
vmenv
:=
vm
.
NewEVM
(
context
,
txContext
,
statedb
,
api
.
blockchain
.
Config
(),
vm
.
Config
{})
if
_
,
err
:=
core
.
ApplyMessage
(
vmenv
,
msg
,
new
(
core
.
GasPool
)
.
AddGas
(
tx
.
Gas
()));
err
!=
nil
{
return
AccountRangeResult
{},
fmt
.
Errorf
(
"transaction %#x failed: %v"
,
tx
.
Hash
(),
err
)
}
// Ensure any modifications are committed to the state
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
root
=
statedb
.
IntermediateRoot
(
vmenv
.
ChainConfig
()
.
IsEIP158
(
block
.
Number
()))
if
idx
==
int
(
txIndex
)
{
// This is to make sure root can be opened by OpenTrie
root
,
err
=
statedb
.
Commit
(
api
.
chainConfig
.
IsEIP158
(
block
.
Number
()))
if
err
!=
nil
{
return
AccountRangeResult
{},
err
}
break
}
}
}
accountTrie
,
err
:=
statedb
.
Database
()
.
OpenTrie
(
root
)
if
err
!=
nil
{
return
AccountRangeResult
{},
err
}
it
:=
trie
.
NewIterator
(
accountTrie
.
NodeIterator
(
common
.
BigToHash
((
*
big
.
Int
)(
addressHash
))
.
Bytes
()))
result
:=
AccountRangeResult
{
AddressMap
:
make
(
map
[
common
.
Hash
]
common
.
Address
)}
for
i
:=
0
;
i
<
int
(
maxResults
)
&&
it
.
Next
();
i
++
{
if
preimage
:=
accountTrie
.
GetKey
(
it
.
Key
);
preimage
!=
nil
{
result
.
AddressMap
[
common
.
BytesToHash
(
it
.
Key
)]
=
common
.
BytesToAddress
(
preimage
)
}
}
//fmt.Printf("Number of entries returned: %d\n", len(result.AddressMap))
// Add the 'next key' so clients can continue downloading.
if
it
.
Next
()
{
next
:=
common
.
BytesToHash
(
it
.
Key
)
result
.
NextKey
=
next
}
return
result
,
nil
}
func
(
api
*
RetestethAPI
)
GetBalance
(
ctx
context
.
Context
,
address
common
.
Address
,
blockNr
math
.
HexOrDecimal64
)
(
*
math
.
HexOrDecimal256
,
error
)
{
//fmt.Printf("GetBalance %x, block %d\n", address, blockNr)
header
:=
api
.
blockchain
.
GetHeaderByNumber
(
uint64
(
blockNr
))
statedb
,
err
:=
api
.
blockchain
.
StateAt
(
header
.
Root
)
if
err
!=
nil
{
return
nil
,
err
}
return
(
*
math
.
HexOrDecimal256
)(
statedb
.
GetBalance
(
address
)),
nil
}
func
(
api
*
RetestethAPI
)
GetCode
(
ctx
context
.
Context
,
address
common
.
Address
,
blockNr
math
.
HexOrDecimal64
)
(
hexutil
.
Bytes
,
error
)
{
header
:=
api
.
blockchain
.
GetHeaderByNumber
(
uint64
(
blockNr
))
statedb
,
err
:=
api
.
blockchain
.
StateAt
(
header
.
Root
)
if
err
!=
nil
{
return
nil
,
err
}
return
statedb
.
GetCode
(
address
),
nil
}
func
(
api
*
RetestethAPI
)
GetTransactionCount
(
ctx
context
.
Context
,
address
common
.
Address
,
blockNr
math
.
HexOrDecimal64
)
(
uint64
,
error
)
{
header
:=
api
.
blockchain
.
GetHeaderByNumber
(
uint64
(
blockNr
))
statedb
,
err
:=
api
.
blockchain
.
StateAt
(
header
.
Root
)
if
err
!=
nil
{
return
0
,
err
}
return
statedb
.
GetNonce
(
address
),
nil
}
func
(
api
*
RetestethAPI
)
StorageRangeAt
(
ctx
context
.
Context
,
blockHashOrNumber
*
math
.
HexOrDecimal256
,
txIndex
uint64
,
address
common
.
Address
,
begin
*
math
.
HexOrDecimal256
,
maxResults
uint64
,
)
(
StorageRangeResult
,
error
)
{
var
(
header
*
types
.
Header
block
*
types
.
Block
)
if
(
*
big
.
Int
)(
blockHashOrNumber
)
.
Cmp
(
big
.
NewInt
(
math
.
MaxInt64
))
>
0
{
blockHash
:=
common
.
BigToHash
((
*
big
.
Int
)(
blockHashOrNumber
))
header
=
api
.
blockchain
.
GetHeaderByHash
(
blockHash
)
block
=
api
.
blockchain
.
GetBlockByHash
(
blockHash
)
//fmt.Printf("Storage range: %x, txIndex %d, addr: %x, start: %x, maxResults: %d\n",
// blockHash, txIndex, address, common.BigToHash((*big.Int)(begin)), maxResults)
}
else
{
blockNumber
:=
(
*
big
.
Int
)(
blockHashOrNumber
)
.
Uint64
()
header
=
api
.
blockchain
.
GetHeaderByNumber
(
blockNumber
)
block
=
api
.
blockchain
.
GetBlockByNumber
(
blockNumber
)
//fmt.Printf("Storage range: %d, txIndex %d, addr: %x, start: %x, maxResults: %d\n",
// blockNumber, txIndex, address, common.BigToHash((*big.Int)(begin)), maxResults)
}
parentHeader
:=
api
.
blockchain
.
GetHeaderByHash
(
header
.
ParentHash
)
var
root
common
.
Hash
var
statedb
*
state
.
StateDB
var
err
error
if
parentHeader
==
nil
||
int
(
txIndex
)
>=
len
(
block
.
Transactions
())
{
root
=
header
.
Root
statedb
,
err
=
api
.
blockchain
.
StateAt
(
root
)
if
err
!=
nil
{
return
StorageRangeResult
{},
err
}
}
else
{
root
=
parentHeader
.
Root
statedb
,
err
=
api
.
blockchain
.
StateAt
(
root
)
if
err
!=
nil
{
return
StorageRangeResult
{},
err
}
// Recompute transactions up to the target index.
signer
:=
types
.
MakeSigner
(
api
.
blockchain
.
Config
(),
block
.
Number
())
context
:=
core
.
NewEVMBlockContext
(
block
.
Header
(),
api
.
blockchain
,
nil
)
for
idx
,
tx
:=
range
block
.
Transactions
()
{
// Assemble the transaction call message and return if the requested offset
msg
,
_
:=
tx
.
AsMessage
(
signer
)
txContext
:=
core
.
NewEVMTxContext
(
msg
)
// Not yet the searched for transaction, execute on top of the current state
vmenv
:=
vm
.
NewEVM
(
context
,
txContext
,
statedb
,
api
.
blockchain
.
Config
(),
vm
.
Config
{})
if
_
,
err
:=
core
.
ApplyMessage
(
vmenv
,
msg
,
new
(
core
.
GasPool
)
.
AddGas
(
tx
.
Gas
()));
err
!=
nil
{
return
StorageRangeResult
{},
fmt
.
Errorf
(
"transaction %#x failed: %v"
,
tx
.
Hash
(),
err
)
}
// Ensure any modifications are committed to the state
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
_
=
statedb
.
IntermediateRoot
(
vmenv
.
ChainConfig
()
.
IsEIP158
(
block
.
Number
()))
if
idx
==
int
(
txIndex
)
{
// This is to make sure root can be opened by OpenTrie
_
,
err
=
statedb
.
Commit
(
vmenv
.
ChainConfig
()
.
IsEIP158
(
block
.
Number
()))
if
err
!=
nil
{
return
StorageRangeResult
{},
err
}
}
}
}
storageTrie
:=
statedb
.
StorageTrie
(
address
)
it
:=
trie
.
NewIterator
(
storageTrie
.
NodeIterator
(
common
.
BigToHash
((
*
big
.
Int
)(
begin
))
.
Bytes
()))
result
:=
StorageRangeResult
{
Storage
:
make
(
map
[
common
.
Hash
]
SRItem
)}
for
i
:=
0
;
/*i < int(maxResults) && */
it
.
Next
();
i
++
{
if
preimage
:=
storageTrie
.
GetKey
(
it
.
Key
);
preimage
!=
nil
{
key
:=
(
*
math
.
HexOrDecimal256
)(
big
.
NewInt
(
0
)
.
SetBytes
(
preimage
))
v
,
_
,
err
:=
rlp
.
SplitString
(
it
.
Value
)
if
err
!=
nil
{
return
StorageRangeResult
{},
err
}
value
:=
(
*
math
.
HexOrDecimal256
)(
big
.
NewInt
(
0
)
.
SetBytes
(
v
))
ks
,
_
:=
key
.
MarshalText
()
vs
,
_
:=
value
.
MarshalText
()
if
len
(
ks
)
%
2
!=
0
{
ks
=
append
(
append
(
append
([]
byte
{},
ks
[
:
2
]
...
),
byte
(
'0'
)),
ks
[
2
:
]
...
)
}
if
len
(
vs
)
%
2
!=
0
{
vs
=
append
(
append
(
append
([]
byte
{},
vs
[
:
2
]
...
),
byte
(
'0'
)),
vs
[
2
:
]
...
)
}
result
.
Storage
[
common
.
BytesToHash
(
it
.
Key
)]
=
SRItem
{
Key
:
string
(
ks
),
Value
:
string
(
vs
),
}
}
}
if
it
.
Next
()
{
result
.
Complete
=
false
}
else
{
result
.
Complete
=
true
}
return
result
,
nil
}
func
(
api
*
RetestethAPI
)
ClientVersion
(
ctx
context
.
Context
)
(
string
,
error
)
{
return
"Geth-"
+
params
.
VersionWithCommit
(
gitCommit
,
gitDate
),
nil
}
func
retesteth
(
ctx
*
cli
.
Context
)
error
{
log
.
Info
(
"Welcome to retesteth!"
)
// register signer API with server
var
(
extapiURL
string
)
apiImpl
:=
&
RetestethAPI
{}
var
testApi
RetestethTestAPI
=
apiImpl
var
ethApi
RetestethEthAPI
=
apiImpl
var
debugApi
RetestethDebugAPI
=
apiImpl
var
web3Api
RetestWeb3API
=
apiImpl
rpcAPI
:=
[]
rpc
.
API
{
{
Namespace
:
"test"
,
Public
:
true
,
Service
:
testApi
,
Version
:
"1.0"
,
},
{
Namespace
:
"eth"
,
Public
:
true
,
Service
:
ethApi
,
Version
:
"1.0"
,
},
{
Namespace
:
"debug"
,
Public
:
true
,
Service
:
debugApi
,
Version
:
"1.0"
,
},
{
Namespace
:
"web3"
,
Public
:
true
,
Service
:
web3Api
,
Version
:
"1.0"
,
},
}
vhosts
:=
utils
.
SplitAndTrim
(
ctx
.
GlobalString
(
utils
.
HTTPVirtualHostsFlag
.
Name
))
cors
:=
utils
.
SplitAndTrim
(
ctx
.
GlobalString
(
utils
.
HTTPCORSDomainFlag
.
Name
))
// register apis and create handler stack
srv
:=
rpc
.
NewServer
()
err
:=
node
.
RegisterApisFromWhitelist
(
rpcAPI
,
[]
string
{
"test"
,
"eth"
,
"debug"
,
"web3"
},
srv
,
false
)
if
err
!=
nil
{
utils
.
Fatalf
(
"Could not register RPC apis: %w"
,
err
)
}
handler
:=
node
.
NewHTTPHandlerStack
(
srv
,
cors
,
vhosts
)
// start http server
var
RetestethHTTPTimeouts
=
rpc
.
HTTPTimeouts
{
ReadTimeout
:
120
*
time
.
Second
,
WriteTimeout
:
120
*
time
.
Second
,
IdleTimeout
:
120
*
time
.
Second
,
}
httpEndpoint
:=
fmt
.
Sprintf
(
"%s:%d"
,
ctx
.
GlobalString
(
utils
.
HTTPListenAddrFlag
.
Name
),
ctx
.
Int
(
rpcPortFlag
.
Name
))
httpServer
,
_
,
err
:=
node
.
StartHTTPEndpoint
(
httpEndpoint
,
RetestethHTTPTimeouts
,
handler
)
if
err
!=
nil
{
utils
.
Fatalf
(
"Could not start RPC api: %v"
,
err
)
}
extapiURL
=
fmt
.
Sprintf
(
"http://%s"
,
httpEndpoint
)
log
.
Info
(
"HTTP endpoint opened"
,
"url"
,
extapiURL
)
defer
func
()
{
// Don't bother imposing a timeout here.
httpServer
.
Shutdown
(
context
.
Background
())
log
.
Info
(
"HTTP endpoint closed"
,
"url"
,
httpEndpoint
)
}()
abortChan
:=
make
(
chan
os
.
Signal
,
11
)
signal
.
Notify
(
abortChan
,
os
.
Interrupt
)
sig
:=
<-
abortChan
log
.
Info
(
"Exiting..."
,
"signal"
,
sig
)
return
nil
}
cmd/geth/retesteth_copypaste.go
deleted
100644 → 0
View file @
92c56eb8
// Copyright 2019 The go-ethereum Authors
// 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
main
import
(
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
)
// RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction
type
RPCTransaction
struct
{
BlockHash
common
.
Hash
`json:"blockHash"`
BlockNumber
*
hexutil
.
Big
`json:"blockNumber"`
From
common
.
Address
`json:"from"`
Gas
hexutil
.
Uint64
`json:"gas"`
GasPrice
*
hexutil
.
Big
`json:"gasPrice"`
Hash
common
.
Hash
`json:"hash"`
Input
hexutil
.
Bytes
`json:"input"`
Nonce
hexutil
.
Uint64
`json:"nonce"`
To
*
common
.
Address
`json:"to"`
TransactionIndex
hexutil
.
Uint
`json:"transactionIndex"`
Value
*
hexutil
.
Big
`json:"value"`
V
*
hexutil
.
Big
`json:"v"`
R
*
hexutil
.
Big
`json:"r"`
S
*
hexutil
.
Big
`json:"s"`
}
// newRPCTransaction returns a transaction that will serialize to the RPC
// representation, with the given location metadata set (if available).
func
newRPCTransaction
(
tx
*
types
.
Transaction
,
blockHash
common
.
Hash
,
blockNumber
uint64
,
index
uint64
)
*
RPCTransaction
{
var
signer
types
.
Signer
=
types
.
FrontierSigner
{}
if
tx
.
Protected
()
{
signer
=
types
.
NewEIP155Signer
(
tx
.
ChainId
())
}
from
,
_
:=
types
.
Sender
(
signer
,
tx
)
v
,
r
,
s
:=
tx
.
RawSignatureValues
()
result
:=
&
RPCTransaction
{
From
:
from
,
Gas
:
hexutil
.
Uint64
(
tx
.
Gas
()),
GasPrice
:
(
*
hexutil
.
Big
)(
tx
.
GasPrice
()),
Hash
:
tx
.
Hash
(),
Input
:
hexutil
.
Bytes
(
tx
.
Data
()),
Nonce
:
hexutil
.
Uint64
(
tx
.
Nonce
()),
To
:
tx
.
To
(),
Value
:
(
*
hexutil
.
Big
)(
tx
.
Value
()),
V
:
(
*
hexutil
.
Big
)(
v
),
R
:
(
*
hexutil
.
Big
)(
r
),
S
:
(
*
hexutil
.
Big
)(
s
),
}
if
blockHash
!=
(
common
.
Hash
{})
{
result
.
BlockHash
=
blockHash
result
.
BlockNumber
=
(
*
hexutil
.
Big
)(
new
(
big
.
Int
)
.
SetUint64
(
blockNumber
))
result
.
TransactionIndex
=
hexutil
.
Uint
(
index
)
}
return
result
}
// newRPCTransactionFromBlockIndex returns a transaction that will serialize to the RPC representation.
func
newRPCTransactionFromBlockIndex
(
b
*
types
.
Block
,
index
uint64
)
*
RPCTransaction
{
txs
:=
b
.
Transactions
()
if
index
>=
uint64
(
len
(
txs
))
{
return
nil
}
return
newRPCTransaction
(
txs
[
index
],
b
.
Hash
(),
b
.
NumberU64
(),
index
)
}
// newRPCTransactionFromBlockHash returns a transaction that will serialize to the RPC representation.
func
newRPCTransactionFromBlockHash
(
b
*
types
.
Block
,
hash
common
.
Hash
)
*
RPCTransaction
{
for
idx
,
tx
:=
range
b
.
Transactions
()
{
if
tx
.
Hash
()
==
hash
{
return
newRPCTransactionFromBlockIndex
(
b
,
uint64
(
idx
))
}
}
return
nil
}
// RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are
// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain
// transaction hashes.
func
RPCMarshalBlock
(
b
*
types
.
Block
,
inclTx
bool
,
fullTx
bool
)
(
map
[
string
]
interface
{},
error
)
{
head
:=
b
.
Header
()
// copies the header once
fields
:=
map
[
string
]
interface
{}{
"number"
:
(
*
hexutil
.
Big
)(
head
.
Number
),
"hash"
:
b
.
Hash
(),
"parentHash"
:
head
.
ParentHash
,
"nonce"
:
head
.
Nonce
,
"mixHash"
:
head
.
MixDigest
,
"sha3Uncles"
:
head
.
UncleHash
,
"logsBloom"
:
head
.
Bloom
,
"stateRoot"
:
head
.
Root
,
"miner"
:
head
.
Coinbase
,
"difficulty"
:
(
*
hexutil
.
Big
)(
head
.
Difficulty
),
"extraData"
:
hexutil
.
Bytes
(
head
.
Extra
),
"size"
:
hexutil
.
Uint64
(
b
.
Size
()),
"gasLimit"
:
hexutil
.
Uint64
(
head
.
GasLimit
),
"gasUsed"
:
hexutil
.
Uint64
(
head
.
GasUsed
),
"timestamp"
:
hexutil
.
Uint64
(
head
.
Time
),
"transactionsRoot"
:
head
.
TxHash
,
"receiptsRoot"
:
head
.
ReceiptHash
,
}
if
inclTx
{
formatTx
:=
func
(
tx
*
types
.
Transaction
)
(
interface
{},
error
)
{
return
tx
.
Hash
(),
nil
}
if
fullTx
{
formatTx
=
func
(
tx
*
types
.
Transaction
)
(
interface
{},
error
)
{
return
newRPCTransactionFromBlockHash
(
b
,
tx
.
Hash
()),
nil
}
}
txs
:=
b
.
Transactions
()
transactions
:=
make
([]
interface
{},
len
(
txs
))
var
err
error
for
i
,
tx
:=
range
txs
{
if
transactions
[
i
],
err
=
formatTx
(
tx
);
err
!=
nil
{
return
nil
,
err
}
}
fields
[
"transactions"
]
=
transactions
}
uncles
:=
b
.
Uncles
()
uncleHashes
:=
make
([]
common
.
Hash
,
len
(
uncles
))
for
i
,
uncle
:=
range
uncles
{
uncleHashes
[
i
]
=
uncle
.
Hash
()
}
fields
[
"uncles"
]
=
uncleHashes
return
fields
,
nil
}
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