Merge pull request #988 from rlan35/rj_fork

Remove Difficulty and Nonce from block header
pull/984/head
Rongjian Lan 6 years ago committed by GitHub
commit 157bfaa229
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      api/proto/node/node_test.go
  2. 3
      consensus/consensus_service.go
  3. 24
      core/blockchain.go
  4. 5
      core/chain_makers.go
  5. 5
      core/genesis.go
  6. 83
      core/headerchain.go
  7. 2
      core/resharding.go
  8. 15
      core/types/block.go
  9. 19
      core/types/gen_header_json.go
  10. 4
      internal/hmyapi/types.go

@ -74,14 +74,12 @@ func TestConstructBlocksSyncMessage(t *testing.T) {
root := statedb.IntermediateRoot(false)
head := &types.Header{
Number: new(big.Int).SetUint64(uint64(10000)),
Nonce: types.EncodeNonce(uint64(10000)),
Epoch: big.NewInt(0),
ShardID: 0,
Time: new(big.Int).SetUint64(uint64(100000)),
Root: root,
}
head.GasLimit = 10000000000
head.Difficulty = params.GenesisDifficulty
if _, err := statedb.Commit(false); err != nil {
t.Fatalf("statedb.Commit() failed: %s", err)

@ -60,7 +60,7 @@ func (consensus *Consensus) GetNextRnd() ([32]byte, [32]byte, error) {
// SealHash returns the hash of a block prior to it being sealed.
func (consensus *Consensus) SealHash(header *types.Header) (hash common.Hash) {
hasher := sha3.NewLegacyKeccak256()
// TODO: update with new fields
if err := rlp.Encode(hasher, []interface{}{
header.ParentHash,
header.Coinbase,
@ -68,7 +68,6 @@ func (consensus *Consensus) SealHash(header *types.Header) (hash common.Hash) {
header.TxHash,
header.ReceiptHash,
header.Bloom,
header.Difficulty,
header.Number,
header.GasLimit,
header.GasUsed,

@ -457,9 +457,6 @@ func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error {
defer bc.mu.Unlock()
// Prepare the genesis block and reinitialise the chain
if err := bc.hc.WriteTd(genesis.Hash(), genesis.NumberU64(), genesis.Difficulty()); err != nil {
log.Crit("Failed to write genesis block TD", "err", err)
}
rawdb.WriteBlock(bc.db, genesis)
bc.genesisBlock = genesis
@ -1189,17 +1186,18 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
continue
case err == consensus_engine.ErrPrunedAncestor:
// TODO: add fork choice mechanism
// Block competing with the canonical chain, store in the db, but don't process
// until the competitor TD goes above the canonical TD
currentBlock := bc.CurrentBlock()
localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64())
externTd := new(big.Int).Add(bc.GetTd(block.ParentHash(), block.NumberU64()-1), block.Difficulty())
if localTd.Cmp(externTd) > 0 {
if err = bc.WriteBlockWithoutState(block, externTd); err != nil {
return i, events, coalescedLogs, err
}
continue
}
//currentBlock := bc.CurrentBlock()
//localTd := bc.GetTd(currentBlock.Hash(), currentBlock.NumberU64())
//externTd := new(big.Int).Add(bc.GetTd(block.ParentHash(), block.NumberU64()-1), block.Difficulty())
//if localTd.Cmp(externTd) > 0 {
// if err = bc.WriteBlockWithoutState(block, externTd); err != nil {
// return i, events, coalescedLogs, err
// }
// continue
//}
// Competitor chain beat canonical, gather all blocks from the common ancestor
var winner []*types.Block
@ -1270,7 +1268,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
bc.gcproc += proctime
case SideStatTy:
log.Debug("Inserted forked block", "number", block.Number(), "hash", block.Hash(), "diff", block.Difficulty(), "elapsed",
log.Debug("Inserted forked block", "number", block.Number(), "hash", block.Hash(), "elapsed",
common.PrettyDuration(time.Since(bstart)), "txs", len(block.Transactions()), "gas", block.GasUsed(), "uncles", len(block.Uncles()))
blockInsertTimer.UpdateSince(bstart)

@ -66,11 +66,6 @@ func (b *BlockGen) SetExtra(data []byte) {
b.header.Extra = data
}
// SetNonce sets the nonce field of the generated block.
func (b *BlockGen) SetNonce(nonce types.BlockNonce) {
b.header.Nonce = nonce
}
// SetShardID sets the shardID field of the generated block.
func (b *BlockGen) SetShardID(shardID uint32) {
b.header.ShardID = shardID

@ -240,7 +240,6 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
root := statedb.IntermediateRoot(false)
head := &types.Header{
Number: new(big.Int).SetUint64(g.Number),
Nonce: types.EncodeNonce(g.Nonce),
Epoch: big.NewInt(0),
ShardID: g.ShardID,
Time: new(big.Int).SetUint64(g.Timestamp),
@ -248,7 +247,6 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
Extra: g.ExtraData,
GasLimit: g.GasLimit,
GasUsed: g.GasUsed,
Difficulty: g.Difficulty,
MixDigest: g.Mixhash,
Coinbase: g.Coinbase,
Root: root,
@ -258,9 +256,6 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
if g.GasLimit == 0 {
head.GasLimit = 10000000000 // TODO(RJ): figure out better solution. // params.GenesisGasLimit
}
if g.Difficulty == nil {
head.Difficulty = params.GenesisDifficulty
}
statedb.Commit(false)
statedb.Database().TrieDB().Commit(root, true)

@ -142,54 +142,55 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er
if ptd == nil {
return NonStatTy, consensus_engine.ErrUnknownAncestor
}
localTd := hc.GetTd(hc.currentHeaderHash, hc.CurrentHeader().Number.Uint64())
externTd := new(big.Int).Add(header.Difficulty, ptd)
// TODO: implement fork choice mechanism
//localTd := hc.GetTd(hc.currentHeaderHash, hc.CurrentHeader().Number.Uint64())
//externTd := new(big.Int).Add(header.Difficulty, ptd)
// Irrelevant of the canonical status, write the td and header to the database
if err := hc.WriteTd(hash, number, externTd); err != nil {
log.Crit("Failed to write header total difficulty", "err", err)
}
//if err := hc.WriteTd(hash, number, externTd); err != nil {
// // log.Crit("Failed to write header total difficulty", "err", err)
// //}
//rawdb.WriteHeader(hc.chainDb, header)
// If the total difficulty is higher than our known, add it to the canonical chain
// Second clause in the if statement reduces the vulnerability to selfish mining.
// Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf
if externTd.Cmp(localTd) > 0 || (externTd.Cmp(localTd) == 0 && mrand.Float64() < 0.5) {
// Delete any canonical number assignments above the new head
batch := hc.chainDb.NewBatch()
for i := number + 1; ; i++ {
hash := rawdb.ReadCanonicalHash(hc.chainDb, i)
if hash == (common.Hash{}) {
break
}
rawdb.DeleteCanonicalHash(batch, i)
}
batch.Write()
// Overwrite any stale canonical number assignments
var (
headHash = header.ParentHash
headNumber = header.Number.Uint64() - 1
headHeader = hc.GetHeader(headHash, headNumber)
)
for rawdb.ReadCanonicalHash(hc.chainDb, headNumber) != headHash {
rawdb.WriteCanonicalHash(hc.chainDb, headHash, headNumber)
headHash = headHeader.ParentHash
headNumber = headHeader.Number.Uint64() - 1
headHeader = hc.GetHeader(headHash, headNumber)
}
// Extend the canonical chain with the new header
rawdb.WriteCanonicalHash(hc.chainDb, hash, number)
rawdb.WriteHeadHeaderHash(hc.chainDb, hash)
hc.currentHeaderHash = hash
hc.currentHeader.Store(types.CopyHeader(header))
status = CanonStatTy
} else {
status = SideStatTy
}
//if externTd.Cmp(localTd) > 0 || (externTd.Cmp(localTd) == 0 && mrand.Float64() < 0.5) {
// // Delete any canonical number assignments above the new head
// batch := hc.chainDb.NewBatch()
// for i := number + 1; ; i++ {
// hash := rawdb.ReadCanonicalHash(hc.chainDb, i)
// if hash == (common.Hash{}) {
// break
// }
// rawdb.DeleteCanonicalHash(batch, i)
// }
// batch.Write()
//
// // Overwrite any stale canonical number assignments
// var (
// headHash = header.ParentHash
// headNumber = header.Number.Uint64() - 1
// headHeader = hc.GetHeader(headHash, headNumber)
// )
// for rawdb.ReadCanonicalHash(hc.chainDb, headNumber) != headHash {
// rawdb.WriteCanonicalHash(hc.chainDb, headHash, headNumber)
//
// headHash = headHeader.ParentHash
// headNumber = headHeader.Number.Uint64() - 1
// headHeader = hc.GetHeader(headHash, headNumber)
// }
// // Extend the canonical chain with the new header
// rawdb.WriteCanonicalHash(hc.chainDb, hash, number)
// rawdb.WriteHeadHeaderHash(hc.chainDb, hash)
//
// hc.currentHeaderHash = hash
// hc.currentHeader.Store(types.CopyHeader(header))
//
// status = CanonStatTy
//} else {
// status = SideStatTy
//}
hc.headerCache.Add(hash, header)
hc.numberCache.Add(hash, number)

@ -27,7 +27,7 @@ const (
// GenesisShardNum is the number of shard at genesis
GenesisShardNum = 4
// GenesisShardSize is the size of each shard at genesis
GenesisShardSize = 100
GenesisShardSize = 10
// CuckooRate is the percentage of nodes getting reshuffled in the second step of cuckoo resharding.
CuckooRate = 0.1
)

@ -77,14 +77,12 @@ type Header struct {
TxHash common.Hash `json:"transactionsRoot" gencodec:"required"`
ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"`
Bloom ethtypes.Bloom `json:"logsBloom" gencodec:"required"`
Difficulty *big.Int `json:"difficulty" gencodec:"required"`
Number *big.Int `json:"number" gencodec:"required"`
GasLimit uint64 `json:"gasLimit" gencodec:"required"`
GasUsed uint64 `json:"gasUsed" gencodec:"required"`
Time *big.Int `json:"timestamp" gencodec:"required"`
Extra []byte `json:"extraData" gencodec:"required"`
MixDigest common.Hash `json:"mixHash" gencodec:"required"`
Nonce BlockNonce `json:"nonce" gencodec:"required"`
// Additional Fields
Epoch *big.Int `json:"epoch" gencodec:"required"`
ShardID uint32 `json:"shardID" gencodec:"required"`
@ -118,7 +116,8 @@ func (h *Header) Hash() common.Hash {
// Size returns the approximate memory used by all internal contents. It is used
// to approximate and limit the memory consumption of various caches.
func (h *Header) Size() common.StorageSize {
return common.StorageSize(unsafe.Sizeof(*h)) + common.StorageSize(len(h.Extra)+(h.Difficulty.BitLen()+h.Number.BitLen()+h.Time.BitLen())/8)
// TODO: update with new fields
return common.StorageSize(unsafe.Sizeof(*h)) + common.StorageSize(len(h.Extra)+(h.Number.BitLen()+h.Time.BitLen())/8)
}
// Logger returns a sub-logger with block contexts added.
@ -255,13 +254,11 @@ func NewBlockWithHeader(header *Header) *Block {
// CopyHeader creates a deep copy of a block header to prevent side effects from
// modifying a header variable.
func CopyHeader(h *Header) *Header {
// TODO: update with new fields
cpy := *h
if cpy.Time = new(big.Int); h.Time != nil {
cpy.Time.Set(h.Time)
}
if cpy.Difficulty = new(big.Int); h.Difficulty != nil {
cpy.Difficulty.Set(h.Difficulty)
}
if cpy.Number = new(big.Int); h.Number != nil {
cpy.Number.Set(h.Number)
}
@ -333,9 +330,6 @@ func (b *Block) GasLimit() uint64 { return b.header.GasLimit }
// GasUsed returns header gas used.
func (b *Block) GasUsed() uint64 { return b.header.GasUsed }
// Difficulty is the header difficulty.
func (b *Block) Difficulty() *big.Int { return new(big.Int).Set(b.header.Difficulty) }
// Time is header time.
func (b *Block) Time() *big.Int { return new(big.Int).Set(b.header.Time) }
@ -345,9 +339,6 @@ func (b *Block) NumberU64() uint64 { return b.header.Number.Uint64() }
// MixDigest is the header mix digest.
func (b *Block) MixDigest() common.Hash { return b.header.MixDigest }
// Nonce is the header nonce.
func (b *Block) Nonce() uint64 { return binary.BigEndian.Uint64(b.header.Nonce[:]) }
// ShardID is the header ShardID
func (b *Block) ShardID() uint32 { return b.header.ShardID }

@ -15,6 +15,7 @@ import (
var _ = (*headerMarshaling)(nil)
func (h Header) MarshalJSON() ([]byte, error) {
// TODO: update with new fields
type Header struct {
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
Coinbase common.Address `json:"miner" gencodec:"required"`
@ -22,14 +23,12 @@ func (h Header) MarshalJSON() ([]byte, error) {
TxHash common.Hash `json:"transactionsRoot" gencodec:"required"`
ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"`
Bloom ethtypes.Bloom `json:"logsBloom" gencodec:"required"`
Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"`
Number *hexutil.Big `json:"number" gencodec:"required"`
GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"`
GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
Time *hexutil.Big `json:"timestamp" gencodec:"required"`
Extra hexutil.Bytes `json:"extraData" gencodec:"required"`
MixDigest common.Hash `json:"mixHash" gencodec:"required"`
Nonce BlockNonce `json:"nonce" gencodec:"required"`
Hash common.Hash `json:"hash"`
}
var enc Header
@ -39,19 +38,18 @@ func (h Header) MarshalJSON() ([]byte, error) {
enc.TxHash = h.TxHash
enc.ReceiptHash = h.ReceiptHash
enc.Bloom = h.Bloom
enc.Difficulty = (*hexutil.Big)(h.Difficulty)
enc.Number = (*hexutil.Big)(h.Number)
enc.GasLimit = hexutil.Uint64(h.GasLimit)
enc.GasUsed = hexutil.Uint64(h.GasUsed)
enc.Time = (*hexutil.Big)(h.Time)
enc.Extra = h.Extra
enc.MixDigest = h.MixDigest
enc.Nonce = h.Nonce
enc.Hash = h.Hash()
return json.Marshal(&enc)
}
func (h *Header) UnmarshalJSON(input []byte) error {
// TODO: update with new fields
type Header struct {
ParentHash *common.Hash `json:"parentHash" gencodec:"required"`
Coinbase *common.Address `json:"miner" gencodec:"required"`
@ -59,14 +57,12 @@ func (h *Header) UnmarshalJSON(input []byte) error {
TxHash *common.Hash `json:"transactionsRoot" gencodec:"required"`
ReceiptHash *common.Hash `json:"receiptsRoot" gencodec:"required"`
Bloom *ethtypes.Bloom `json:"logsBloom" gencodec:"required"`
Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"`
Number *hexutil.Big `json:"number" gencodec:"required"`
GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"`
GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
Time *hexutil.Big `json:"timestamp" gencodec:"required"`
Extra *hexutil.Bytes `json:"extraData" gencodec:"required"`
MixDigest *common.Hash `json:"mixHash" gencodec:"required"`
Nonce *BlockNonce `json:"nonce" gencodec:"required"`
}
var dec Header
if err := json.Unmarshal(input, &dec); err != nil {
@ -96,13 +92,6 @@ func (h *Header) UnmarshalJSON(input []byte) error {
return errors.New("missing required field 'logsBloom' for Header")
}
h.Bloom = *dec.Bloom
if dec.Difficulty == nil {
return errors.New("missing required field 'difficulty' for Header")
}
h.Difficulty = (*big.Int)(dec.Difficulty)
if dec.Number == nil {
return errors.New("missing required field 'number' for Header")
}
h.Number = (*big.Int)(dec.Number)
if dec.GasLimit == nil {
return errors.New("missing required field 'gasLimit' for Header")
@ -124,9 +113,5 @@ func (h *Header) UnmarshalJSON(input []byte) error {
return errors.New("missing required field 'mixHash' for Header")
}
h.MixDigest = *dec.MixDigest
if dec.Nonce == nil {
return errors.New("missing required field 'nonce' for Header")
}
h.Nonce = *dec.Nonce
return nil
}

@ -95,12 +95,12 @@ func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]inter
"number": (*hexutil.Big)(head.Number),
"hash": b.Hash(),
"parentHash": head.ParentHash,
"nonce": head.Nonce,
"nonce": 0, // Remove this because we don't have it in our header
"mixHash": head.MixDigest,
"logsBloom": head.Bloom,
"stateRoot": head.Root,
"miner": head.Coinbase,
"difficulty": (*hexutil.Big)(head.Difficulty),
"difficulty": 0, // Remove this because we don't have it in our header
"extraData": hexutil.Bytes(head.Extra),
"size": hexutil.Uint64(b.Size()),
"gasLimit": hexutil.Uint64(head.GasLimit),

Loading…
Cancel
Save