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
cdc2662c
Commit
cdc2662c
authored
Sep 07, 2015
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: split out TD from database and all internals
parent
2b339cbb
Changes
19
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
590 additions
and
294 deletions
+590
-294
main.go
cmd/geth/main.go
+3
-4
chain_makers.go
core/chain_makers.go
+0
-1
chain_manager.go
core/chain_manager.go
+85
-65
chain_manager_test.go
core/chain_manager_test.go
+5
-9
chain_util.go
core/chain_util.go
+116
-96
chain_util_test.go
core/chain_util_test.go
+243
-0
genesis.go
core/genesis.go
+10
-10
block.go
core/types/block.go
+19
-16
backend.go
eth/backend.go
+14
-4
downloader.go
eth/downloader/downloader.go
+8
-3
downloader_test.go
eth/downloader/downloader_test.go
+31
-13
handler.go
eth/handler.go
+10
-9
peer.go
eth/peer.go
+3
-2
protocol.go
eth/protocol.go
+0
-16
worker.go
miner/worker.go
+1
-3
eth.go
rpc/api/eth.go
+34
-38
parsing.go
rpc/api/parsing.go
+2
-2
block_test_util.go
tests/block_test_util.go
+2
-3
xeth.go
xeth/xeth.go
+4
-0
No files found.
cmd/geth/main.go
View file @
cdc2662c
...
...
@@ -528,17 +528,16 @@ func blockRecovery(ctx *cli.Context) {
var
block
*
types
.
Block
if
arg
[
0
]
==
'#'
{
block
=
core
.
GetBlock
ByNumber
(
blockDb
,
common
.
String2Big
(
arg
[
1
:
])
.
Uint64
(
))
block
=
core
.
GetBlock
(
blockDb
,
core
.
GetCanonicalHash
(
blockDb
,
common
.
String2Big
(
arg
[
1
:
])
.
Uint64
()
))
}
else
{
block
=
core
.
GetBlock
ByHash
(
blockDb
,
common
.
HexToHash
(
arg
))
block
=
core
.
GetBlock
(
blockDb
,
common
.
HexToHash
(
arg
))
}
if
block
==
nil
{
glog
.
Fatalln
(
"block not found. Recovery failed"
)
}
err
=
core
.
WriteHead
(
blockDb
,
block
)
if
err
!=
nil
{
if
err
=
core
.
WriteHeadBlockHash
(
blockDb
,
block
.
Hash
());
err
!=
nil
{
glog
.
Fatalln
(
"block write err"
,
err
)
}
glog
.
Infof
(
"Recovery succesful. New HEAD %x
\n
"
,
block
.
Hash
())
...
...
core/chain_makers.go
View file @
cdc2662c
...
...
@@ -158,7 +158,6 @@ func GenerateChain(parent *types.Block, db common.Database, n int, gen func(int,
for
i
:=
0
;
i
<
n
;
i
++
{
header
:=
makeHeader
(
parent
,
statedb
)
block
:=
genblock
(
i
,
header
)
block
.
Td
=
CalcTD
(
block
,
parent
)
blocks
[
i
]
=
block
parent
=
block
}
...
...
core/chain_manager.go
View file @
cdc2662c
This diff is collapsed.
Click to expand it.
core/chain_manager_test.go
View file @
cdc2662c
...
...
@@ -77,6 +77,7 @@ func testFork(t *testing.T, bman *BlockProcessor, i, N int, f func(td1, td2 *big
bi1
:=
bman
.
bc
.
GetBlockByNumber
(
uint64
(
i
))
.
Hash
()
bi2
:=
bman2
.
bc
.
GetBlockByNumber
(
uint64
(
i
))
.
Hash
()
if
bi1
!=
bi2
{
fmt
.
Printf
(
"%+v
\n
%+v
\n\n
"
,
bi1
,
bi2
)
t
.
Fatal
(
"chains do not have the same hash at height"
,
i
)
}
bman2
.
bc
.
SetProcessor
(
bman2
)
...
...
@@ -110,7 +111,6 @@ func printChain(bc *ChainManager) {
// process blocks against a chain
func
testChain
(
chainB
types
.
Blocks
,
bman
*
BlockProcessor
)
(
*
big
.
Int
,
error
)
{
td
:=
new
(
big
.
Int
)
for
_
,
block
:=
range
chainB
{
_
,
_
,
err
:=
bman
.
bc
.
processor
.
Process
(
block
)
if
err
!=
nil
{
...
...
@@ -119,17 +119,12 @@ func testChain(chainB types.Blocks, bman *BlockProcessor) (*big.Int, error) {
}
return
nil
,
err
}
parent
:=
bman
.
bc
.
GetBlock
(
block
.
ParentHash
())
block
.
Td
=
CalcTD
(
block
,
parent
)
td
=
block
.
Td
bman
.
bc
.
mu
.
Lock
()
{
WriteBlock
(
bman
.
bc
.
chainDb
,
block
)
}
WriteTd
(
bman
.
bc
.
chainDb
,
block
.
Hash
(),
new
(
big
.
Int
)
.
Add
(
block
.
Difficulty
(),
bman
.
bc
.
GetTd
(
block
.
ParentHash
())))
WriteBlock
(
bman
.
bc
.
chainDb
,
block
)
bman
.
bc
.
mu
.
Unlock
()
}
return
td
,
nil
return
bman
.
bc
.
GetTd
(
chainB
[
len
(
chainB
)
-
1
]
.
Hash
())
,
nil
}
func
loadChain
(
fn
string
,
t
*
testing
.
T
)
(
types
.
Blocks
,
error
)
{
...
...
@@ -391,6 +386,7 @@ func chm(genesis *types.Block, db common.Database) *ChainManager {
bc
.
headerCache
,
_
=
lru
.
New
(
100
)
bc
.
bodyCache
,
_
=
lru
.
New
(
100
)
bc
.
bodyRLPCache
,
_
=
lru
.
New
(
100
)
bc
.
tdCache
,
_
=
lru
.
New
(
100
)
bc
.
blockCache
,
_
=
lru
.
New
(
100
)
bc
.
futureBlocks
,
_
=
lru
.
New
(
100
)
bc
.
processor
=
bproc
{}
...
...
core/chain_util.go
View file @
cdc2662c
This diff is collapsed.
Click to expand it.
core/chain_util_test.go
View file @
cdc2662c
...
...
@@ -23,6 +23,10 @@ import (
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto/sha3"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/rlp"
)
type
diffTest
struct
{
...
...
@@ -75,3 +79,242 @@ func TestDifficulty(t *testing.T) {
}
}
}
// Tests block header storage and retrieval operations.
func
TestHeaderStorage
(
t
*
testing
.
T
)
{
db
,
_
:=
ethdb
.
NewMemDatabase
()
// Create a test header to move around the database and make sure it's really new
header
:=
&
types
.
Header
{
Extra
:
[]
byte
(
"test header"
)}
if
entry
:=
GetHeader
(
db
,
header
.
Hash
());
entry
!=
nil
{
t
.
Fatalf
(
"Non existent header returned: %v"
,
entry
)
}
// Write and verify the header in the database
if
err
:=
WriteHeader
(
db
,
header
);
err
!=
nil
{
t
.
Fatalf
(
"Failed to write header into database: %v"
,
err
)
}
if
entry
:=
GetHeader
(
db
,
header
.
Hash
());
entry
==
nil
{
t
.
Fatalf
(
"Stored header not found"
)
}
else
if
entry
.
Hash
()
!=
header
.
Hash
()
{
t
.
Fatalf
(
"Retrieved header mismatch: have %v, want %v"
,
entry
,
header
)
}
if
entry
:=
GetHeaderRLP
(
db
,
header
.
Hash
());
entry
==
nil
{
t
.
Fatalf
(
"Stored header RLP not found"
)
}
else
{
hasher
:=
sha3
.
NewKeccak256
()
hasher
.
Write
(
entry
)
if
hash
:=
common
.
BytesToHash
(
hasher
.
Sum
(
nil
));
hash
!=
header
.
Hash
()
{
t
.
Fatalf
(
"Retrieved RLP header mismatch: have %v, want %v"
,
entry
,
header
)
}
}
// Delete the header and verify the execution
DeleteHeader
(
db
,
header
.
Hash
())
if
entry
:=
GetHeader
(
db
,
header
.
Hash
());
entry
!=
nil
{
t
.
Fatalf
(
"Deleted header returned: %v"
,
entry
)
}
}
// Tests block body storage and retrieval operations.
func
TestBodyStorage
(
t
*
testing
.
T
)
{
db
,
_
:=
ethdb
.
NewMemDatabase
()
// Create a test body to move around the database and make sure it's really new
body
:=
&
types
.
Body
{
Uncles
:
[]
*
types
.
Header
{{
Extra
:
[]
byte
(
"test header"
)}}}
hasher
:=
sha3
.
NewKeccak256
()
rlp
.
Encode
(
hasher
,
body
)
hash
:=
common
.
BytesToHash
(
hasher
.
Sum
(
nil
))
if
entry
:=
GetBody
(
db
,
hash
);
entry
!=
nil
{
t
.
Fatalf
(
"Non existent body returned: %v"
,
entry
)
}
// Write and verify the body in the database
if
err
:=
WriteBody
(
db
,
hash
,
body
);
err
!=
nil
{
t
.
Fatalf
(
"Failed to write body into database: %v"
,
err
)
}
if
entry
:=
GetBody
(
db
,
hash
);
entry
==
nil
{
t
.
Fatalf
(
"Stored body not found"
)
}
else
if
types
.
DeriveSha
(
types
.
Transactions
(
entry
.
Transactions
))
!=
types
.
DeriveSha
(
types
.
Transactions
(
body
.
Transactions
))
||
types
.
CalcUncleHash
(
entry
.
Uncles
)
!=
types
.
CalcUncleHash
(
body
.
Uncles
)
{
t
.
Fatalf
(
"Retrieved body mismatch: have %v, want %v"
,
entry
,
body
)
}
if
entry
:=
GetBodyRLP
(
db
,
hash
);
entry
==
nil
{
t
.
Fatalf
(
"Stored body RLP not found"
)
}
else
{
hasher
:=
sha3
.
NewKeccak256
()
hasher
.
Write
(
entry
)
if
calc
:=
common
.
BytesToHash
(
hasher
.
Sum
(
nil
));
calc
!=
hash
{
t
.
Fatalf
(
"Retrieved RLP body mismatch: have %v, want %v"
,
entry
,
body
)
}
}
// Delete the body and verify the execution
DeleteBody
(
db
,
hash
)
if
entry
:=
GetBody
(
db
,
hash
);
entry
!=
nil
{
t
.
Fatalf
(
"Deleted body returned: %v"
,
entry
)
}
}
// Tests block storage and retrieval operations.
func
TestBlockStorage
(
t
*
testing
.
T
)
{
db
,
_
:=
ethdb
.
NewMemDatabase
()
// Create a test block to move around the database and make sure it's really new
block
:=
types
.
NewBlockWithHeader
(
&
types
.
Header
{
Extra
:
[]
byte
(
"test block"
)})
if
entry
:=
GetBlock
(
db
,
block
.
Hash
());
entry
!=
nil
{
t
.
Fatalf
(
"Non existent block returned: %v"
,
entry
)
}
if
entry
:=
GetHeader
(
db
,
block
.
Hash
());
entry
!=
nil
{
t
.
Fatalf
(
"Non existent header returned: %v"
,
entry
)
}
if
entry
:=
GetBody
(
db
,
block
.
Hash
());
entry
!=
nil
{
t
.
Fatalf
(
"Non existent body returned: %v"
,
entry
)
}
// Write and verify the block in the database
if
err
:=
WriteBlock
(
db
,
block
);
err
!=
nil
{
t
.
Fatalf
(
"Failed to write block into database: %v"
,
err
)
}
if
entry
:=
GetBlock
(
db
,
block
.
Hash
());
entry
==
nil
{
t
.
Fatalf
(
"Stored block not found"
)
}
else
if
entry
.
Hash
()
!=
block
.
Hash
()
{
t
.
Fatalf
(
"Retrieved block mismatch: have %v, want %v"
,
entry
,
block
)
}
if
entry
:=
GetHeader
(
db
,
block
.
Hash
());
entry
==
nil
{
t
.
Fatalf
(
"Stored header not found"
)
}
else
if
entry
.
Hash
()
!=
block
.
Header
()
.
Hash
()
{
t
.
Fatalf
(
"Retrieved header mismatch: have %v, want %v"
,
entry
,
block
.
Header
())
}
if
entry
:=
GetBody
(
db
,
block
.
Hash
());
entry
==
nil
{
t
.
Fatalf
(
"Stored body not found"
)
}
else
if
types
.
DeriveSha
(
types
.
Transactions
(
entry
.
Transactions
))
!=
types
.
DeriveSha
(
block
.
Transactions
())
||
types
.
CalcUncleHash
(
entry
.
Uncles
)
!=
types
.
CalcUncleHash
(
block
.
Uncles
())
{
t
.
Fatalf
(
"Retrieved body mismatch: have %v, want %v"
,
entry
,
&
types
.
Body
{
block
.
Transactions
(),
block
.
Uncles
()})
}
// Delete the block and verify the execution
DeleteBlock
(
db
,
block
.
Hash
())
if
entry
:=
GetBlock
(
db
,
block
.
Hash
());
entry
!=
nil
{
t
.
Fatalf
(
"Deleted block returned: %v"
,
entry
)
}
if
entry
:=
GetHeader
(
db
,
block
.
Hash
());
entry
!=
nil
{
t
.
Fatalf
(
"Deleted header returned: %v"
,
entry
)
}
if
entry
:=
GetBody
(
db
,
block
.
Hash
());
entry
!=
nil
{
t
.
Fatalf
(
"Deleted body returned: %v"
,
entry
)
}
}
// Tests that partial block contents don't get reassembled into full blocks.
func
TestPartialBlockStorage
(
t
*
testing
.
T
)
{
db
,
_
:=
ethdb
.
NewMemDatabase
()
block
:=
types
.
NewBlockWithHeader
(
&
types
.
Header
{
Extra
:
[]
byte
(
"test block"
)})
// Store a header and check that it's not recognized as a block
if
err
:=
WriteHeader
(
db
,
block
.
Header
());
err
!=
nil
{
t
.
Fatalf
(
"Failed to write header into database: %v"
,
err
)
}
if
entry
:=
GetBlock
(
db
,
block
.
Hash
());
entry
!=
nil
{
t
.
Fatalf
(
"Non existent block returned: %v"
,
entry
)
}
DeleteHeader
(
db
,
block
.
Hash
())
// Store a body and check that it's not recognized as a block
if
err
:=
WriteBody
(
db
,
block
.
Hash
(),
&
types
.
Body
{
block
.
Transactions
(),
block
.
Uncles
()});
err
!=
nil
{
t
.
Fatalf
(
"Failed to write body into database: %v"
,
err
)
}
if
entry
:=
GetBlock
(
db
,
block
.
Hash
());
entry
!=
nil
{
t
.
Fatalf
(
"Non existent block returned: %v"
,
entry
)
}
DeleteBody
(
db
,
block
.
Hash
())
// Store a header and a body separately and check reassembly
if
err
:=
WriteHeader
(
db
,
block
.
Header
());
err
!=
nil
{
t
.
Fatalf
(
"Failed to write header into database: %v"
,
err
)
}
if
err
:=
WriteBody
(
db
,
block
.
Hash
(),
&
types
.
Body
{
block
.
Transactions
(),
block
.
Uncles
()});
err
!=
nil
{
t
.
Fatalf
(
"Failed to write body into database: %v"
,
err
)
}
if
entry
:=
GetBlock
(
db
,
block
.
Hash
());
entry
==
nil
{
t
.
Fatalf
(
"Stored block not found"
)
}
else
if
entry
.
Hash
()
!=
block
.
Hash
()
{
t
.
Fatalf
(
"Retrieved block mismatch: have %v, want %v"
,
entry
,
block
)
}
}
// Tests block total difficulty storage and retrieval operations.
func
TestTdStorage
(
t
*
testing
.
T
)
{
db
,
_
:=
ethdb
.
NewMemDatabase
()
// Create a test TD to move around the database and make sure it's really new
hash
,
td
:=
common
.
Hash
{},
big
.
NewInt
(
314
)
if
entry
:=
GetTd
(
db
,
hash
);
entry
!=
nil
{
t
.
Fatalf
(
"Non existent TD returned: %v"
,
entry
)
}
// Write and verify the TD in the database
if
err
:=
WriteTd
(
db
,
hash
,
td
);
err
!=
nil
{
t
.
Fatalf
(
"Failed to write TD into database: %v"
,
err
)
}
if
entry
:=
GetTd
(
db
,
hash
);
entry
==
nil
{
t
.
Fatalf
(
"Stored TD not found"
)
}
else
if
entry
.
Cmp
(
td
)
!=
0
{
t
.
Fatalf
(
"Retrieved TD mismatch: have %v, want %v"
,
entry
,
td
)
}
// Delete the TD and verify the execution
DeleteTd
(
db
,
hash
)
if
entry
:=
GetTd
(
db
,
hash
);
entry
!=
nil
{
t
.
Fatalf
(
"Deleted TD returned: %v"
,
entry
)
}
}
// Tests that canonical numbers can be mapped to hashes and retrieved.
func
TestCanonicalMappingStorage
(
t
*
testing
.
T
)
{
db
,
_
:=
ethdb
.
NewMemDatabase
()
// Create a test canonical number and assinged hash to move around
hash
,
number
:=
common
.
Hash
{
0
:
0xff
},
uint64
(
314
)
if
entry
:=
GetCanonicalHash
(
db
,
number
);
entry
!=
(
common
.
Hash
{})
{
t
.
Fatalf
(
"Non existent canonical mapping returned: %v"
,
entry
)
}
// Write and verify the TD in the database
if
err
:=
WriteCanonicalHash
(
db
,
hash
,
number
);
err
!=
nil
{
t
.
Fatalf
(
"Failed to write canonical mapping into database: %v"
,
err
)
}
if
entry
:=
GetCanonicalHash
(
db
,
number
);
entry
==
(
common
.
Hash
{})
{
t
.
Fatalf
(
"Stored canonical mapping not found"
)
}
else
if
entry
!=
hash
{
t
.
Fatalf
(
"Retrieved canonical mapping mismatch: have %v, want %v"
,
entry
,
hash
)
}
// Delete the TD and verify the execution
DeleteCanonicalHash
(
db
,
number
)
if
entry
:=
GetCanonicalHash
(
db
,
number
);
entry
!=
(
common
.
Hash
{})
{
t
.
Fatalf
(
"Deleted canonical mapping returned: %v"
,
entry
)
}
}
// Tests that head headers and head blocks can be assigned, individually.
func
TestHeadStorage
(
t
*
testing
.
T
)
{
db
,
_
:=
ethdb
.
NewMemDatabase
()
blockHead
:=
types
.
NewBlockWithHeader
(
&
types
.
Header
{
Extra
:
[]
byte
(
"test block header"
)})
blockFull
:=
types
.
NewBlockWithHeader
(
&
types
.
Header
{
Extra
:
[]
byte
(
"test block full"
)})
// Check that no head entries are in a pristine database
if
entry
:=
GetHeadHeaderHash
(
db
);
entry
!=
(
common
.
Hash
{})
{
t
.
Fatalf
(
"Non head header entry returned: %v"
,
entry
)
}
if
entry
:=
GetHeadBlockHash
(
db
);
entry
!=
(
common
.
Hash
{})
{
t
.
Fatalf
(
"Non head block entry returned: %v"
,
entry
)
}
// Assign separate entries for the head header and block
if
err
:=
WriteHeadHeaderHash
(
db
,
blockHead
.
Hash
());
err
!=
nil
{
t
.
Fatalf
(
"Failed to write head header hash: %v"
,
err
)
}
if
err
:=
WriteHeadBlockHash
(
db
,
blockFull
.
Hash
());
err
!=
nil
{
t
.
Fatalf
(
"Failed to write head block hash: %v"
,
err
)
}
// Check that both heads are present, and different (i.e. two heads maintained)
if
entry
:=
GetHeadHeaderHash
(
db
);
entry
!=
blockHead
.
Hash
()
{
t
.
Fatalf
(
"Head header hash mismatch: have %v, want %v"
,
entry
,
blockHead
.
Hash
())
}
if
entry
:=
GetHeadBlockHash
(
db
);
entry
!=
blockFull
.
Hash
()
{
t
.
Fatalf
(
"Head block hash mismatch: have %v, want %v"
,
entry
,
blockFull
.
Hash
())
}
}
core/genesis.go
View file @
cdc2662c
...
...
@@ -82,28 +82,29 @@ func WriteGenesisBlock(chainDb common.Database, reader io.Reader) (*types.Block,
Coinbase
:
common
.
HexToAddress
(
genesis
.
Coinbase
),
Root
:
statedb
.
Root
(),
},
nil
,
nil
,
nil
)
block
.
Td
=
difficulty
if
block
:=
GetBlock
ByHash
(
chainDb
,
block
.
Hash
());
block
!=
nil
{
if
block
:=
GetBlock
(
chainDb
,
block
.
Hash
());
block
!=
nil
{
glog
.
V
(
logger
.
Info
)
.
Infoln
(
"Genesis block already in chain. Writing canonical number"
)
err
:=
WriteCanon
Number
(
chainDb
,
block
.
Hash
(),
block
.
NumberU64
())
err
:=
WriteCanon
icalHash
(
chainDb
,
block
.
Hash
(),
block
.
NumberU64
())
if
err
!=
nil
{
return
nil
,
err
}
return
block
,
nil
}
statedb
.
Sync
()
err
=
WriteBlock
(
chainDb
,
block
)
if
err
!=
nil
{
if
err
:=
WriteTd
(
chainDb
,
block
.
Hash
(),
difficulty
);
err
!=
nil
{
return
nil
,
err
}
err
=
WriteHead
(
chainDb
,
block
)
if
err
!=
nil
{
if
err
:=
WriteBlock
(
chainDb
,
block
);
err
!=
nil
{
return
nil
,
err
}
if
err
:=
WriteCanonicalHash
(
chainDb
,
block
.
Hash
(),
block
.
NumberU64
());
err
!=
nil
{
return
nil
,
err
}
if
err
:=
WriteHeadBlockHash
(
chainDb
,
block
.
Hash
());
err
!=
nil
{
return
nil
,
err
}
return
block
,
nil
}
...
...
@@ -120,7 +121,6 @@ func GenesisBlockForTesting(db common.Database, addr common.Address, balance *bi
GasLimit
:
params
.
GenesisGasLimit
,
Root
:
statedb
.
Root
(),
},
nil
,
nil
,
nil
)
block
.
Td
=
params
.
GenesisDifficulty
return
block
}
...
...
core/types/block.go
View file @
cdc2662c
...
...
@@ -117,6 +117,13 @@ func rlpHash(x interface{}) (h common.Hash) {
return
h
}
// Body is a simple (mutable, non-safe) data container for storing and moving
// a block's data contents (transactions and uncles) together.
type
Body
struct
{
Transactions
[]
*
Transaction
Uncles
[]
*
Header
}
type
Block
struct
{
header
*
Header
uncles
[]
*
Header
...
...
@@ -129,12 +136,19 @@ type Block struct {
// Td is used by package core to store the total difficulty
// of the chain up to and including the block.
T
d
*
big
.
Int
t
d
*
big
.
Int
// ReceivedAt is used by package eth to track block propagation time.
ReceivedAt
time
.
Time
}
// DeprecatedTd is an old relic for extracting the TD of a block. It is in the
// code solely to facilitate upgrading the database from the old format to the
// new, after which it should be deleted. Do not use!
func
(
b
*
Block
)
DeprecatedTd
()
*
big
.
Int
{
return
b
.
td
}
// [deprecated by eth/63]
// StorageBlock defines the RLP encoding of a Block stored in the
// state database. The StorageBlock encoding contains fields that
...
...
@@ -170,7 +184,7 @@ var (
// are ignored and set to values derived from the given txs, uncles
// and receipts.
func
NewBlock
(
header
*
Header
,
txs
[]
*
Transaction
,
uncles
[]
*
Header
,
receipts
[]
*
Receipt
)
*
Block
{
b
:=
&
Block
{
header
:
copyHeader
(
header
),
T
d
:
new
(
big
.
Int
)}
b
:=
&
Block
{
header
:
copyHeader
(
header
),
t
d
:
new
(
big
.
Int
)}
// TODO: panic if len(txs) != len(receipts)
if
len
(
txs
)
==
0
{
...
...
@@ -276,20 +290,10 @@ func (b *StorageBlock) DecodeRLP(s *rlp.Stream) error {
if
err
:=
s
.
Decode
(
&
sb
);
err
!=
nil
{
return
err
}
b
.
header
,
b
.
uncles
,
b
.
transactions
,
b
.
T
d
=
sb
.
Header
,
sb
.
Uncles
,
sb
.
Txs
,
sb
.
TD
b
.
header
,
b
.
uncles
,
b
.
transactions
,
b
.
t
d
=
sb
.
Header
,
sb
.
Uncles
,
sb
.
Txs
,
sb
.
TD
return
nil
}
// [deprecated by eth/63]
func
(
b
*
StorageBlock
)
EncodeRLP
(
w
io
.
Writer
)
error
{
return
rlp
.
Encode
(
w
,
storageblock
{
Header
:
b
.
header
,
Txs
:
b
.
transactions
,
Uncles
:
b
.
uncles
,
TD
:
b
.
Td
,
})
}
// TODO: copies
func
(
b
*
Block
)
Uncles
()
[]
*
Header
{
return
b
.
uncles
}
func
(
b
*
Block
)
Transactions
()
Transactions
{
return
b
.
transactions
}
...
...
@@ -360,7 +364,6 @@ func (b *Block) WithMiningResult(nonce uint64, mixDigest common.Hash) *Block {
transactions
:
b
.
transactions
,
receipts
:
b
.
receipts
,
uncles
:
b
.
uncles
,
Td
:
b
.
Td
,
}
}
...
...
@@ -390,7 +393,7 @@ func (b *Block) Hash() common.Hash {
}
func
(
b
*
Block
)
String
()
string
{
str
:=
fmt
.
Sprintf
(
`Block(#%v): Size: %v
TD: %v
{
str
:=
fmt
.
Sprintf
(
`Block(#%v): Size: %v {
MinerHash: %x
%v
Transactions:
...
...
@@ -398,7 +401,7 @@ Transactions:
Uncles:
%v
}
`
,
b
.
Number
(),
b
.
Size
(),
b
.
Td
,
b
.
header
.
HashNoNonce
(),
b
.
header
,
b
.
transactions
,
b
.
uncles
)
`
,
b
.
Number
(),
b
.
Size
(),
b
.
header
.
HashNoNonce
(),
b
.
header
,
b
.
transactions
,
b
.
uncles
)
return
str
}
...
...
eth/backend.go
View file @
cdc2662c
...
...
@@ -316,9 +316,13 @@ func New(config *Config) (*Ethereum, error) {
if
err
!=
nil
{
return
nil
,
err
}
case
config
.
GenesisBlock
!=
nil
:
// This is for testing only.
}
// This is for testing only.
if
config
.
GenesisBlock
!=
nil
{
core
.
WriteTd
(
chainDb
,
config
.
GenesisBlock
.
Hash
(),
config
.
GenesisBlock
.
Difficulty
())
core
.
WriteBlock
(
chainDb
,
config
.
GenesisBlock
)
core
.
WriteHead
(
chainDb
,
config
.
GenesisBlock
)
core
.
WriteCanonicalHash
(
chainDb
,
config
.
GenesisBlock
.
Hash
(),
config
.
GenesisBlock
.
NumberU64
())
core
.
WriteHeadBlockHash
(
chainDb
,
config
.
GenesisBlock
.
Hash
())
}
if
!
config
.
SkipBcVersionCheck
{
...
...
@@ -752,7 +756,10 @@ func upgradeChainDatabase(db common.Database) error {
// Load the block, split and serialize (order!)
block
:=
core
.
GetBlockByHashOld
(
db
,
common
.
BytesToHash
(
bytes
.
TrimPrefix
(
it
.
Key
(),
blockPrefix
)))
if
err
:=
core
.
WriteBody
(
db
,
block
);
err
!=
nil
{
if
err
:=
core
.
WriteTd
(
db
,
block
.
Hash
(),
block
.
DeprecatedTd
());
err
!=
nil
{
return
err
}
if
err
:=
core
.
WriteBody
(
db
,
block
.
Hash
(),
&
types
.
Body
{
block
.
Transactions
(),
block
.
Uncles
()});
err
!=
nil
{
return
err
}
if
err
:=
core
.
WriteHeader
(
db
,
block
.
Header
());
err
!=
nil
{
...
...
@@ -765,7 +772,10 @@ func upgradeChainDatabase(db common.Database) error {
// Lastly, upgrade the head block, disabling the upgrade mechanism
current
:=
core
.
GetBlockByHashOld
(
db
,
head
)
if
err
:=
core
.
WriteBody
(
db
,
current
);
err
!=
nil
{
if
err
:=
core
.
WriteTd
(
db
,
current
.
Hash
(),
current
.
DeprecatedTd
());
err
!=
nil
{
return
err
}
if
err
:=
core
.
WriteBody
(
db
,
current
.
Hash
(),
&
types
.
Body
{
current
.
Transactions
(),
current
.
Uncles
()});
err
!=
nil
{
return
err
}
if
err
:=
core
.
WriteHeader
(
db
,
current
.
Header
());
err
!=
nil
{
...
...
eth/downloader/downloader.go
View file @
cdc2662c
...
...
@@ -87,6 +87,9 @@ type blockRetrievalFn func(common.Hash) *types.Block
// headRetrievalFn is a callback type for retrieving the head block from the local chain.
type
headRetrievalFn
func
()
*
types
.
Block
// tdRetrievalFn is a callback type for retrieving the total difficulty of a local block.
type
tdRetrievalFn
func
(
common
.
Hash
)
*
big
.
Int
// chainInsertFn is a callback type to insert a batch of blocks into the local chain.
type
chainInsertFn
func
(
types
.
Blocks
)
(
int
,
error
)
...
...
@@ -136,6 +139,7 @@ type Downloader struct {
hasBlock
hashCheckFn
// Checks if a block is present in the chain
getBlock
blockRetrievalFn
// Retrieves a block from the chain
headBlock
headRetrievalFn
// Retrieves the head block from the chain
getTd
tdRetrievalFn
// Retrieves the TD of a block from the chain
insertChain
chainInsertFn
// Injects a batch of blocks into the chain
dropPeer
peerDropFn
// Drops a peer for misbehaving
...
...
@@ -168,7 +172,7 @@ type Block struct {
}
// New creates a new downloader to fetch hashes and blocks from remote peers.
func
New
(
mux
*
event
.
TypeMux
,
hasBlock
hashCheckFn
,
getBlock
blockRetrievalFn
,
headBlock
headRetrievalFn
,
insertChain
chainInsertFn
,
dropPeer
peerDropFn
)
*
Downloader
{
func
New
(
mux
*
event
.
TypeMux
,
hasBlock
hashCheckFn
,
getBlock
blockRetrievalFn
,
headBlock
headRetrievalFn
,
getTd
tdRetrievalFn
,
insertChain
chainInsertFn
,
dropPeer
peerDropFn
)
*
Downloader
{
return
&
Downloader
{
mux
:
mux
,
queue
:
newQueue
(),
...
...
@@ -176,6 +180,7 @@ func New(mux *event.TypeMux, hasBlock hashCheckFn, getBlock blockRetrievalFn, he
hasBlock
:
hasBlock
,
getBlock
:
getBlock
,
headBlock
:
headBlock
,
getTd
:
getTd
,
insertChain
:
insertChain
,
dropPeer
:
dropPeer
,
newPeerCh
:
make
(
chan
*
peer
,
1
),
...
...
@@ -582,7 +587,7 @@ func (d *Downloader) fetchHashes61(p *peer, td *big.Int, from uint64) error {
// L: Sync begins, and finds common ancestor at 11
// L: Request new hashes up from 11 (R's TD was higher, it must have something)
// R: Nothing to give
if
!
gotHashes
&&
td
.
Cmp
(
d
.
headBlock
()
.
Td
)
>
0
{
if
!
gotHashes
&&
td
.
Cmp
(
d
.
getTd
(
d
.
headBlock
()
.
Hash
())
)
>
0
{
return
errStallingPeer
}
return
nil
...
...
@@ -958,7 +963,7 @@ func (d *Downloader) fetchHeaders(p *peer, td *big.Int, from uint64) error {
// L: Sync begins, and finds common ancestor at 11
// L: Request new headers up from 11 (R's TD was higher, it must have something)
// R: Nothing to give
if
!
gotHeaders
&&
td
.
Cmp
(
d
.
headBlock
()
.
Td
)
>
0
{
if
!
gotHeaders
&&
td
.
Cmp
(
d
.
getTd
(
d
.
headBlock
()
.
Hash
())
)
>
0
{
return
errStallingPeer
}
return
nil
...
...
eth/downloader/downloader_test.go
View file @
cdc2662c
...
...
@@ -93,21 +93,25 @@ func makeChainFork(n, f int, parent *types.Block) (h1, h2 []common.Hash, b1, b2
type
downloadTester
struct
{
downloader
*
Downloader
ownHashes
[]
common
.
Hash
// Hash chain belonging to the tester
ownBlocks
map
[
common
.
Hash
]
*
types
.
Block
// Blocks belonging to the tester
peerHashes
map
[
string
][]
common
.
Hash
// Hash chain belonging to different test peers
peerBlocks
map
[
string
]
map
[
common
.
Hash
]
*
types
.
Block
// Blocks belonging to different test peers
ownHashes
[]
common
.
Hash
// Hash chain belonging to the tester
ownBlocks
map
[
common
.
Hash
]
*
types
.
Block
// Blocks belonging to the tester
ownChainTd
map
[
common
.
Hash
]
*
big
.
Int
// Total difficulties of the blocks in the local chain
peerHashes
map
[
string
][]
common
.
Hash
// Hash chain belonging to different test peers
peerBlocks
map
[
string
]
map
[
common
.
Hash
]
*
types
.
Block
// Blocks belonging to different test peers
peerChainTds
map
[
string
]
map
[
common
.
Hash
]
*
big
.
Int
// Total difficulties of the blocks in the peer chains
}
// newTester creates a new downloader test mocker.
func
newTester
()
*
downloadTester
{
tester
:=
&
downloadTester
{
ownHashes
:
[]
common
.
Hash
{
genesis
.
Hash
()},
ownBlocks
:
map
[
common
.
Hash
]
*
types
.
Block
{
genesis
.
Hash
()
:
genesis
},
peerHashes
:
make
(
map
[
string
][]
common
.
Hash
),
peerBlocks
:
make
(
map
[
string
]
map
[
common
.
Hash
]
*
types
.
Block
),
ownHashes
:
[]
common
.
Hash
{
genesis
.
Hash
()},
ownBlocks
:
map
[
common
.
Hash
]
*
types
.
Block
{
genesis
.
Hash
()
:
genesis
},
ownChainTd
:
map
[
common
.
Hash
]
*
big
.
Int
{
genesis
.
Hash
()
:
genesis
.
Difficulty
()},
peerHashes
:
make
(
map
[
string
][]
common
.
Hash
),
peerBlocks
:
make
(
map
[
string
]
map
[
common
.
Hash
]
*
types
.
Block
),
peerChainTds
:
make
(
map
[
string
]
map
[
common
.
Hash
]
*
big
.
Int
),
}
tester
.
downloader
=
New
(
new
(
event
.
TypeMux
),
tester
.
hasBlock
,
tester
.
getBlock
,
tester
.
headBlock
,
tester
.
insertChain
,
tester
.
dropPeer
)
tester
.
downloader
=
New
(
new
(
event
.
TypeMux
),
tester
.
hasBlock
,
tester
.
getBlock
,
tester
.
headBlock
,
tester
.
getTd
,
tester
.
insertChain
,
tester
.
dropPeer
)
return
tester
}
...
...
@@ -119,8 +123,8 @@ func (dl *downloadTester) sync(id string, td *big.Int) error {
// If no particular TD was requested, load from the peer's blockchain
if
td
==
nil
{
td
=
big
.
NewInt
(
1
)
if
block
,
ok
:=
dl
.
peerBlock
s
[
id
][
hash
];
ok
{
td
=
block
.
Td
if
diff
,
ok
:=
dl
.
peerChainTd
s
[
id
][
hash
];
ok
{
td
=
diff
}
}
err
:=
dl
.
downloader
.
synchronise
(
id
,
hash
,
td
)
...
...
@@ -152,6 +156,11 @@ func (dl *downloadTester) headBlock() *types.Block {
return
dl
.
getBlock
(
dl
.
ownHashes
[
len
(
dl
.
ownHashes
)
-
1
])
}
// getTd retrieves the block's total difficulty from the canonical chain.
func
(
dl
*
downloadTester
)
getTd
(
hash
common
.
Hash
)
*
big
.
Int
{
return
dl
.
ownChainTd
[
hash
]
}
// insertChain injects a new batch of blocks into the simulated chain.
func
(
dl
*
downloadTester
)
insertChain
(
blocks
types
.
Blocks
)
(
int
,
error
)
{
for
i
,
block
:=
range
blocks
{
...
...
@@ -160,6 +169,7 @@ func (dl *downloadTester) insertChain(blocks types.Blocks) (int, error) {
}
dl
.
ownHashes
=
append
(
dl
.
ownHashes
,
block
.
Hash
())
dl
.
ownBlocks
[
block
.
Hash
()]
=
block
dl
.
ownChainTd
[
block
.
Hash
()]
=
dl
.
ownChainTd
[
block
.
ParentHash
()]
}
return
len
(
blocks
),
nil
}
...
...
@@ -180,9 +190,16 @@ func (dl *downloadTester) newSlowPeer(id string, version int, hashes []common.Ha
// Assign the owned hashes and blocks to the peer (deep copy)
dl
.
peerHashes
[
id
]
=
make
([]
common
.
Hash
,
len
(
hashes
))
copy
(
dl
.
peerHashes
[
id
],
hashes
)
dl
.
peerBlocks
[
id
]
=
make
(
map
[
common
.
Hash
]
*
types
.
Block
)
for
hash
,
block
:=
range
blocks
{
dl
.
peerBlocks
[
id
][
hash
]
=
block
dl
.
peerChainTds
[
id
]
=
make
(
map
[
common
.
Hash
]
*
big
.
Int
)
for
_
,
hash
:=
range
hashes
{
if
block
,
ok
:=
blocks
[
hash
];
ok
{
dl
.
peerBlocks
[
id
][
hash
]
=
block
if
parent
,
ok
:=
dl
.
peerBlocks
[
id
][
block
.
ParentHash
()];
ok
{
dl
.
peerChainTds
[
id
][
hash
]
=
new
(
big
.
Int
)
.
Add
(
block
.
Difficulty
(),
dl
.
peerChainTds
[
id
][
parent
.
Hash
()])
}
}
}
}
return
err
...
...
@@ -192,6 +209,7 @@ func (dl *downloadTester) newSlowPeer(id string, version int, hashes []common.Ha
func
(
dl
*
downloadTester
)
dropPeer
(
id
string
)
{
delete
(
dl
.
peerHashes
,
id
)
delete
(
dl
.
peerBlocks
,
id
)
delete
(
dl
.
peerChainTds
,
id
)
dl
.
downloader
.
UnregisterPeer
(
id
)
}
...
...
eth/handler.go
View file @
cdc2662c
...
...
@@ -36,8 +36,10 @@ import (
"github.com/ethereum/go-ethereum/rlp"
)
// This is the target maximum size of returned blocks, headers or node data.
const
softResponseLimit
=
2
*
1024
*
1024
const
(
softResponseLimit
=
2
*
1024
*
1024
// Target maximum size of returned blocks, headers or node data.
estHeaderRlpSize
=
500
// Approximate size of an RLP encoded block header
)
func
errResp
(
code
errCode
,
format
string
,
v
...
interface
{})
error
{
return
fmt
.
Errorf
(
"%v - %v"
,
code
,
fmt
.
Sprintf
(
format
,
v
...
))
...
...
@@ -113,7 +115,7 @@ func NewProtocolManager(networkId int, mux *event.TypeMux, txpool txPool, pow po
}
}
// Construct the different synchronisation mechanisms
manager
.
downloader
=
downloader
.
New
(
manager
.
eventMux
,
manager
.
chainman
.
HasBlock
,
manager
.
chainman
.
GetBlock
,
manager
.
chainman
.
CurrentBlock
,
manager
.
chainman
.
InsertChain
,
manager
.
removePeer
)
manager
.
downloader
=
downloader
.
New
(
manager
.
eventMux
,
manager
.
chainman
.
HasBlock
,
manager
.
chainman
.
GetBlock
,
manager
.
chainman
.
CurrentBlock
,
manager
.
chainman
.
GetTd
,
manager
.
chainman
.
InsertChain
,
manager
.
removePeer
)
validator
:=
func
(
block
*
types
.
Block
,
parent
*
types
.
Block
)
error
{
return
core
.
ValidateHeader
(
pow
,
block
.
Header
(),
parent
,
true
,
false
)
...
...
@@ -363,7 +365,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
break
}
headers
=
append
(
headers
,
origin
)
bytes
+=
500
// Approximate, should be good enough estimat
e
bytes
+=
estHeaderRlpSiz
e
// Advance to the next header of the query
switch
{
...
...
@@ -453,7 +455,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
var
(
hash
common
.
Hash
bytes
int
bodies
[]
*
blockBodyRLP
bodies
[]
rlp
.
RawValue
)
for
bytes
<
softResponseLimit
&&
len
(
bodies
)
<
downloader
.
MaxBlockFetch
{
// Retrieve the hash of the next block
...
...
@@ -464,9 +466,8 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
}
// Retrieve the requested block body, stopping if enough was found
if
data
:=
pm
.
chainman
.
GetBodyRLP
(
hash
);
len
(
data
)
!=
0
{
body
:=
blockBodyRLP
(
data
)
bodies
=
append
(
bodies
,
&
body
)
bytes
+=
len
(
body
)
bodies
=
append
(
bodies
,
data
)
bytes
+=
len
(
data
)
}
}
return
p
.
SendBlockBodiesRLP
(
bodies
)
...
...
@@ -644,7 +645,7 @@ func (pm *ProtocolManager) BroadcastBlock(block *types.Block, propagate bool) {
// Calculate the TD of the block (it's not imported yet, so block.Td is not valid)
var
td
*
big
.
Int
if
parent
:=
pm
.
chainman
.
GetBlock
(
block
.
ParentHash
());
parent
!=
nil
{
td
=
new
(
big
.
Int
)
.
Add
(
parent
.
Td
,
block
.
Difficulty
(
))
td
=
new
(
big
.
Int
)
.
Add
(
block
.
Difficulty
(),
pm
.
chainman
.
GetTd
(
block
.
ParentHash
()
))
}
else
{
glog
.
V
(
logger
.
Error
)
.
Infof
(
"propagating dangling block #%d [%x]"
,
block
.
NumberU64
(),
hash
[
:
4
])
return
...
...
eth/peer.go
View file @
cdc2662c
...
...
@@ -28,6 +28,7 @@ import (
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/rlp"
"gopkg.in/fatih/set.v0"
)
...
...
@@ -186,8 +187,8 @@ func (p *peer) SendBlockBodies(bodies []*blockBody) error {
// SendBlockBodiesRLP sends a batch of block contents to the remote peer from
// an already RLP encoded format.
func
(
p
*
peer
)
SendBlockBodiesRLP
(
bodies
[]
*
blockBodyRLP
)
error
{
return
p2p
.
Send
(
p
.
rw
,
BlockBodiesMsg
,
b
lockBodiesRLPData
(
bodies
)
)
func
(
p
*
peer
)
SendBlockBodiesRLP
(
bodies
[]
rlp
.
RawValue
)
error
{
return
p2p
.
Send
(
p
.
rw
,
BlockBodiesMsg
,
b
odies
)
}
// SendNodeData sends a batch of arbitrary internal data, corresponding to the
...
...
eth/protocol.go
View file @
cdc2662c
...
...
@@ -213,22 +213,6 @@ type blockBody struct {
// blockBodiesData is the network packet for block content distribution.
type
blockBodiesData
[]
*
blockBody
// blockBodyRLP represents the RLP encoded data content of a single block.
type
blockBodyRLP
[]
byte
// EncodeRLP is a specialized encoder for a block body to pass the already
// encoded body RLPs from the database on, without double encoding.
func
(
b
*
blockBodyRLP
)
EncodeRLP
(
w
io
.
Writer
)
error
{
if
_
,
err
:=
w
.
Write
([]
byte
(
*
b
));
err
!=
nil
{
return
err
}
return
nil
}
// blockBodiesRLPData is the network packet for block content distribution
// based on original RLP formatting (i.e. skip the db-decode/proto-encode).
type
blockBodiesRLPData
[]
*
blockBodyRLP
// nodeDataData is the network response packet for a node data retrieval.
type
nodeDataData
[]
struct
{
Value
[]
byte
...
...
miner/worker.go
View file @
cdc2662c
...
...
@@ -283,7 +283,7 @@ func (self *worker) wait() {
continue
}
stat
,
err
:=
self
.
chain
.
WriteBlock
(
block
,
false
)
stat
,
err
:=
self
.
chain
.
WriteBlock
(
block
)
if
err
!=
nil
{
glog
.
V
(
logger
.
Error
)
.
Infoln
(
"error writing block to chain"
,
err
)
continue
...
...
@@ -533,14 +533,12 @@ func (self *worker) commitNewWork() {
// create the new block whose nonce will be mined.
work
.
Block
=
types
.
NewBlock
(
header
,
work
.
txs
,
uncles
,
work
.
receipts
)
work
.
Block
.
Td
=
new
(
big
.
Int
)
.
Set
(
core
.
CalcTD
(
work
.
Block
,
self
.
chain
.
GetBlock
(
work
.
Block
.
ParentHash
())))
// We only care about logging if we're actually mining.
if
atomic
.
LoadInt32
(
&
self
.
mining
)
==
1
{
glog
.
V
(
logger
.
Info
)
.
Infof
(
"commit new work on block %v with %d txs & %d uncles. Took %v
\n
"
,
work
.
Block
.
Number
(),
work
.
tcount
,
len
(
uncles
),
time
.
Since
(
tstart
))
self
.
logLocalMinedBlocks
(
work
,
previous
)
}
self
.
push
(
work
)
}
...
...
rpc/api/eth.go
View file @
cdc2662c
...
...
@@ -204,7 +204,8 @@ func (self *ethApi) GetBlockTransactionCountByHash(req *shared.Request) (interfa
return
nil
,
shared
.
NewDecodeParamError
(
err
.
Error
())
}
block
:=
NewBlockRes
(
self
.
xeth
.
EthBlockByHash
(
args
.
Hash
),
false
)
raw
:=
self
.
xeth
.
EthBlockByHash
(
args
.
Hash
)
block
:=
NewBlockRes
(
raw
,
self
.
xeth
.
Td
(
raw
.
Hash
()),
false
)
if
block
==
nil
{
return
nil
,
nil
}
else
{
...
...
@@ -218,7 +219,8 @@ func (self *ethApi) GetBlockTransactionCountByNumber(req *shared.Request) (inter
return
nil
,
shared
.
NewDecodeParamError
(
err
.
Error
())
}
block
:=
NewBlockRes
(
self
.
xeth
.
EthBlockByNumber
(
args
.
BlockNumber
),
false
)
raw
:=
self
.
xeth
.
EthBlockByNumber
(
args
.
BlockNumber
)
block
:=
NewBlockRes
(
raw
,
self
.
xeth
.
Td
(
raw
.
Hash
()),
false
)
if
block
==
nil
{
return
nil
,
nil
}
else
{
...
...
@@ -232,12 +234,12 @@ func (self *ethApi) GetUncleCountByBlockHash(req *shared.Request) (interface{},
return
nil
,
shared
.
NewDecodeParamError
(
err
.
Error
())
}
block
:=
self
.
xeth
.
EthBlockByHash
(
args
.
Hash
)
b
r
:=
NewBlockRes
(
block
,
false
)
if
b
r
==
nil
{
raw
:=
self
.
xeth
.
EthBlockByHash
(
args
.
Hash
)
b
lock
:=
NewBlockRes
(
raw
,
self
.
xeth
.
Td
(
raw
.
Hash
())
,
false
)
if
b
lock
==
nil
{
return
nil
,
nil
}
return
newHexNum
(
big
.
NewInt
(
int64
(
len
(
b
r
.
Uncles
)))
.
Bytes
()),
nil
return
newHexNum
(
big
.
NewInt
(
int64
(
len
(
b
lock
.
Uncles
)))
.
Bytes
()),
nil
}
func
(
self
*
ethApi
)
GetUncleCountByBlockNumber
(
req
*
shared
.
Request
)
(
interface
{},
error
)
{
...
...
@@ -246,12 +248,12 @@ func (self *ethApi) GetUncleCountByBlockNumber(req *shared.Request) (interface{}
return
nil
,
shared
.
NewDecodeParamError
(
err
.
Error
())
}
block
:=
self
.
xeth
.
EthBlockByNumber
(
args
.
BlockNumber
)
b
r
:=
NewBlockRes
(
block
,
false
)
if
b
r
==
nil
{
raw
:=
self
.
xeth
.
EthBlockByNumber
(
args
.
BlockNumber
)
b
lock
:=
NewBlockRes
(
raw
,
self
.
xeth
.
Td
(
raw
.
Hash
())
,
false
)
if
b
lock
==
nil
{
return
nil
,
nil
}
return
newHexNum
(
big
.
NewInt
(
int64
(
len
(
b
r
.
Uncles
)))
.
Bytes
()),
nil
return
newHexNum
(
big
.
NewInt
(
int64
(
len
(
b
lock
.
Uncles
)))
.
Bytes
()),
nil
}
func
(
self
*
ethApi
)
GetData
(
req
*
shared
.
Request
)
(
interface
{},
error
)
{
...
...
@@ -362,7 +364,7 @@ func (self *ethApi) GetBlockByHash(req *shared.Request) (interface{}, error) {
}
block
:=
self
.
xeth
.
EthBlockByHash
(
args
.
BlockHash
)
return
NewBlockRes
(
block
,
args
.
IncludeTxs
),
nil
return
NewBlockRes
(
block
,
self
.
xeth
.
Td
(
block
.
Hash
()),
args
.
IncludeTxs
),
nil
}
func
(
self
*
ethApi
)
GetBlockByNumber
(
req
*
shared
.
Request
)
(
interface
{},
error
)
{
...
...
@@ -372,8 +374,7 @@ func (self *ethApi) GetBlockByNumber(req *shared.Request) (interface{}, error) {
}
block
:=
self
.
xeth
.
EthBlockByNumber
(
args
.
BlockNumber
)
br
:=
NewBlockRes
(
block
,
args
.
IncludeTxs
)
return
br
,
nil
return
NewBlockRes
(
block
,
self
.
xeth
.
Td
(
block
.
Hash
()),
args
.
IncludeTxs
),
nil
}
func
(
self
*
ethApi
)
GetTransactionByHash
(
req
*
shared
.
Request
)
(
interface
{},
error
)
{
...
...
@@ -402,16 +403,15 @@ func (self *ethApi) GetTransactionByBlockHashAndIndex(req *shared.Request) (inte
return
nil
,
shared
.
NewDecodeParamError
(
err
.
Error
())
}
block
:=
self
.
xeth
.
EthBlockByHash
(
args
.
Hash
)
b
r
:=
NewBlockRes
(
block
,
true
)
if
b
r
==
nil
{
raw
:=
self
.
xeth
.
EthBlockByHash
(
args
.
Hash
)
b
lock
:=
NewBlockRes
(
raw
,
self
.
xeth
.
Td
(
raw
.
Hash
())
,
true
)
if
b
lock
==
nil
{
return
nil
,
nil
}
if
args
.
Index
>=
int64
(
len
(
br
.
Transactions
))
||
args
.
Index
<
0
{
if
args
.
Index
>=
int64
(
len
(
block
.
Transactions
))
||
args
.
Index
<
0
{
return
nil
,
nil
}
else
{
return
b
r
.
Transactions
[
args
.
Index
],
nil
return
b
lock
.
Transactions
[
args
.
Index
],
nil
}
}
...
...
@@ -421,17 +421,16 @@ func (self *ethApi) GetTransactionByBlockNumberAndIndex(req *shared.Request) (in
return
nil
,
shared
.
NewDecodeParamError
(
err
.
Error
())
}
block
:=
self
.
xeth
.
EthBlockByNumber
(
args
.
BlockNumber
)
v
:=
NewBlockRes
(
block
,
true
)
if
v
==
nil
{
raw
:=
self
.
xeth
.
EthBlockByNumber
(
args
.
BlockNumber
)
block
:=
NewBlockRes
(
raw
,
self
.
xeth
.
Td
(
raw
.
Hash
())
,
true
)
if
block
==
nil
{
return
nil
,
nil
}
if
args
.
Index
>=
int64
(
len
(
v
.
Transactions
))
||
args
.
Index
<
0
{
if
args
.
Index
>=
int64
(
len
(
block
.
Transactions
))
||
args
.
Index
<
0
{
// return NewValidationError("Index", "does not exist")
return
nil
,
nil
}
return
v
.
Transactions
[
args
.
Index
],
nil
return
block
.
Transactions
[
args
.
Index
],
nil
}
func
(
self
*
ethApi
)
GetUncleByBlockHashAndIndex
(
req
*
shared
.
Request
)
(
interface
{},
error
)
{
...
...
@@ -440,17 +439,16 @@ func (self *ethApi) GetUncleByBlockHashAndIndex(req *shared.Request) (interface{
return
nil
,
shared
.
NewDecodeParamError
(
err
.
Error
())
}
br
:=
NewBlockRes
(
self
.
xeth
.
EthBlockByHash
(
args
.
Hash
),
false
)
if
br
==
nil
{
raw
:=
self
.
xeth
.
EthBlockByHash
(
args
.
Hash
)
block
:=
NewBlockRes
(
raw
,
self
.
xeth
.
Td
(
raw
.
Hash
()),
false
)
if
block
==
nil
{
return
nil
,
nil
}
if
args
.
Index
>=
int64
(
len
(
br
.
Uncles
))
||
args
.
Index
<
0
{
if
args
.
Index
>=
int64
(
len
(
block
.
Uncles
))
||
args
.
Index
<
0
{
// return NewValidationError("Index", "does not exist")
return
nil
,
nil
}
return
br
.
Uncles
[
args
.
Index
],
nil
return
block
.
Uncles
[
args
.
Index
],
nil
}
func
(
self
*
ethApi
)
GetUncleByBlockNumberAndIndex
(
req
*
shared
.
Request
)
(
interface
{},
error
)
{
...
...
@@ -459,17 +457,15 @@ func (self *ethApi) GetUncleByBlockNumberAndIndex(req *shared.Request) (interfac
return
nil
,
shared
.
NewDecodeParamError
(
err
.
Error
())
}
block
:=
self
.
xeth
.
EthBlockByNumber
(
args
.
BlockNumber
)
v
:=
NewBlockRes
(
block
,
true
)
if
v
==
nil
{
raw
:=
self
.
xeth
.
EthBlockByNumber
(
args
.
BlockNumber
)
block
:=
NewBlockRes
(
raw
,
self
.
xeth
.
Td
(
raw
.
Hash
()),
true
)
if
block
==
nil
{
return
nil
,
nil
}
if
args
.
Index
>=
int64
(
len
(
v
.
Uncles
))
||
args
.
Index
<
0
{
if
args
.
Index
>=
int64
(
len
(
block
.
Uncles
))
||
args
.
Index
<
0
{
return
nil
,
nil
}
else
{
return
v
.
Uncles
[
args
.
Index
],
nil
return
block
.
Uncles
[
args
.
Index
],
nil
}
}
...
...
rpc/api/parsing.go
View file @
cdc2662c
...
...
@@ -281,7 +281,7 @@ func (b *BlockRes) MarshalJSON() ([]byte, error) {
}
}
func
NewBlockRes
(
block
*
types
.
Block
,
fullTx
bool
)
*
BlockRes
{
func
NewBlockRes
(
block
*
types
.
Block
,
td
*
big
.
Int
,
fullTx
bool
)
*
BlockRes
{
if
block
==
nil
{
return
nil
}
...
...
@@ -299,7 +299,7 @@ func NewBlockRes(block *types.Block, fullTx bool) *BlockRes {
res
.
ReceiptRoot
=
newHexData
(
block
.
ReceiptHash
())
res
.
Miner
=
newHexData
(
block
.
Coinbase
())
res
.
Difficulty
=
newHexNum
(
block
.
Difficulty
())
res
.
TotalDifficulty
=
newHexNum
(
block
.
T
d
)
res
.
TotalDifficulty
=
newHexNum
(
t
d
)
res
.
Size
=
newHexNum
(
block
.
Size
()
.
Int64
())
res
.
ExtraData
=
newHexData
(
block
.
Extra
())
res
.
GasLimit
=
newHexNum
(
block
.
GasLimit
())
...
...
tests/block_test_util.go
View file @
cdc2662c
...
...
@@ -440,9 +440,8 @@ func convertBlockTest(in *btJSON) (out *BlockTest, err error) {
func
mustConvertGenesis
(
testGenesis
btHeader
)
*
types
.
Block
{
hdr
:=
mustConvertHeader
(
testGenesis
)
hdr
.
Number
=
big
.
NewInt
(
0
)
b
:=
types
.
NewBlockWithHeader
(
hdr
)
b
.
Td
=
new
(
big
.
Int
)
return
b
return
types
.
NewBlockWithHeader
(
hdr
)
}
func
mustConvertHeader
(
in
btHeader
)
*
types
.
Header
{
...
...
xeth/xeth.go
View file @
cdc2662c
...
...
@@ -355,6 +355,10 @@ func (self *XEth) EthBlockByNumber(num int64) *types.Block {
return
self
.
getBlockByHeight
(
num
)
}
func
(
self
*
XEth
)
Td
(
hash
common
.
Hash
)
*
big
.
Int
{
return
self
.
backend
.
ChainManager
()
.
GetTd
(
hash
)
}
func
(
self
*
XEth
)
CurrentBlock
()
*
types
.
Block
{
return
self
.
backend
.
ChainManager
()
.
CurrentBlock
()
}
...
...
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