Merge pull request #1538 from harmony-ek/version_headers

Version headers
pull/1540/head
Eugene Kim 5 years ago committed by GitHub
commit 506faf2985
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      api/client/service/server_test.go
  2. 5
      api/proto/node/node_test.go
  3. 6
      api/service/explorer/storage_test.go
  4. 4
      api/service/explorer/structs_test.go
  5. 50
      block/factory/factory.go
  6. 595
      block/header.go
  7. 538
      block/header_test.go
  8. 186
      block/headerfieldsetter.go
  9. 230
      block/interface/header.go
  10. 2
      block/v0/gen_header_json.go
  11. 433
      block/v0/header.go
  12. 117
      block/v1/gen_header_json.go
  13. 417
      block/v1/header.go
  14. 24
      consensus/consensus_v2.go
  15. 13
      core/chain_makers.go
  16. 16
      core/core_test.go
  17. 30
      core/genesis.go
  18. 16
      core/rawdb/accessors_chain_test.go
  19. 4
      core/rawdb/accessors_indexes_test.go
  20. 4
      core/tx_pool_test.go
  21. 6
      core/types/block.go
  22. 4
      core/types/block_test.go
  23. 4
      drand/drand_test.go
  24. 3
      go.mod
  25. 2
      node/node_genesis.go
  26. 16
      node/worker/worker.go
  27. 6
      node/worker/worker_test.go
  28. 5
      test/chain/main.go

@ -6,6 +6,7 @@ import (
"strings"
"testing"
blockfactory "github.com/harmony-one/harmony/block/factory"
"github.com/harmony-one/harmony/internal/chain"
"github.com/ethereum/go-ethereum/common"
@ -27,7 +28,8 @@ var (
testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey)
testBankFunds = big.NewInt(8000000000000000000)
chainConfig = params.TestChainConfig
chainConfig = params.TestChainConfig
blockFactory = blockfactory.NewFactory(chainConfig)
)
func TestGetFreeToken(test *testing.T) {
@ -56,6 +58,7 @@ func TestFetchAccountState(test *testing.T) {
database = ethdb.NewMemDatabase()
gspec = core.Genesis{
Config: chainConfig,
Factory: blockFactory,
Alloc: core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}},
ShardID: 10,
}
@ -93,6 +96,7 @@ func TestGetStakingContractInfo(test *testing.T) {
database = ethdb.NewMemDatabase()
gspec = core.Genesis{
Config: chainConfig,
Factory: blockFactory,
Alloc: core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}},
ShardID: 10,
}

@ -10,7 +10,7 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/harmony-one/harmony/block"
blockfactory "github.com/harmony-one/harmony/block/factory"
"github.com/harmony-one/harmony/core/state"
"github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/internal/params"
@ -60,9 +60,8 @@ func TestConstructBlocksSyncMessage(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
root := statedb.IntermediateRoot(false)
head := block.NewHeaderWith().
head := blockfactory.NewTestHeader().With().
Number(new(big.Int).SetUint64(uint64(10000))).
Epoch(big.NewInt(0)).
ShardID(0).
Time(new(big.Int).SetUint64(uint64(100000))).
Root(root).

@ -10,7 +10,7 @@ import (
"github.com/ethereum/go-ethereum/rlp"
"github.com/harmony-one/bls/ffi/go/bls"
block2 "github.com/harmony-one/harmony/block"
blockfactory "github.com/harmony-one/harmony/block/factory"
"github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/shard"
@ -58,7 +58,7 @@ func TestDump(t *testing.T) {
tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), 0, big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33})
txs := []*types.Transaction{tx1, tx2, tx3}
block := types.NewBlock(block2.NewHeaderWith().Number(big.NewInt(314)).Header(), txs, nil, nil, nil)
block := types.NewBlock(blockfactory.NewTestHeader().With().Number(big.NewInt(314)).Header(), txs, nil, nil, nil)
ins := GetStorageInstance("1.1.1.1", "3333", true)
ins.Dump(block, uint64(1))
db := ins.GetDB()
@ -116,7 +116,7 @@ func TestUpdateAddressStorage(t *testing.T) {
tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), 0, big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33})
txs := []*types.Transaction{tx1, tx2, tx3}
block := types.NewBlock(block2.NewHeaderWith().Number(big.NewInt(314)).Header(), txs, nil, nil, nil)
block := types.NewBlock(blockfactory.NewTestHeader().With().Number(big.NewInt(314)).Header(), txs, nil, nil, nil)
ins := GetStorageInstance("1.1.1.1", "3333", true)
ins.Dump(block, uint64(1))
db := ins.GetDB()

@ -9,7 +9,7 @@ import (
"github.com/ethereum/go-ethereum/common"
block2 "github.com/harmony-one/harmony/block"
blockfactory "github.com/harmony-one/harmony/block/factory"
"github.com/harmony-one/harmony/core/types"
common2 "github.com/harmony-one/harmony/internal/common"
)
@ -21,7 +21,7 @@ func TestGetTransaction(t *testing.T) {
tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), 0, big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33})
txs := []*types.Transaction{tx1, tx2, tx3}
block := types.NewBlock(block2.NewHeaderWith().Number(big.NewInt(314)).Header(), txs, nil, nil, nil)
block := types.NewBlock(blockfactory.NewTestHeader().With().Number(big.NewInt(314)).Header(), txs, nil, nil, nil)
tx := GetTransaction(tx1, block)
assert.Equal(t, tx.ID, tx1.Hash().Hex(), "should be equal tx1.Hash()")

@ -0,0 +1,50 @@
package blockfactory
import (
"math/big"
"github.com/harmony-one/harmony/block"
blockif "github.com/harmony-one/harmony/block/interface"
v0 "github.com/harmony-one/harmony/block/v0"
v1 "github.com/harmony-one/harmony/block/v1"
"github.com/harmony-one/harmony/internal/params"
)
// Factory is a data structure factory for a specific chain configuration.
type Factory interface {
// NewHeader creates a new, empty header object for the given epoch.
NewHeader(epoch *big.Int) *block.Header
}
type factory struct {
chainConfig *params.ChainConfig
}
// NewFactory creates a new factory for the given chain configuration.
func NewFactory(chainConfig *params.ChainConfig) Factory {
return &factory{chainConfig: chainConfig}
}
func (f *factory) NewHeader(epoch *big.Int) *block.Header {
var impl blockif.Header
switch {
case epoch.Cmp(f.chainConfig.CrossLinkEpoch) >= 0:
impl = v1.NewHeader()
default:
impl = v0.NewHeader()
}
return &block.Header{impl}
}
// Factories corresponding to well-known chain configurations.
var (
ForTest = NewFactory(params.TestChainConfig)
ForTestnet = NewFactory(params.TestnetChainConfig)
ForMainnet = NewFactory(params.MainnetChainConfig)
)
// NewTestHeader creates a new, empty header object for epoch 0 using the test
// factory. Use for unit tests.
func NewTestHeader() *block.Header {
return ForTest.NewHeader(new(big.Int))
}

@ -2,395 +2,55 @@ package block
import (
"io"
"math/big"
"unsafe"
"reflect"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
ethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/rlp"
"github.com/harmony-one/taggedrlp"
"github.com/pkg/errors"
"github.com/rs/zerolog"
blockif "github.com/harmony-one/harmony/block/interface"
v0 "github.com/harmony-one/harmony/block/v0"
v1 "github.com/harmony-one/harmony/block/v1"
"github.com/harmony-one/harmony/crypto/hash"
"github.com/harmony-one/harmony/shard"
)
// Header represents a block header in the Harmony blockchain.
type Header struct {
fields headerFields
blockif.Header
}
// EncodeRLP encodes the header fields into RLP format.
// EncodeRLP encodes the header using tagged RLP representation.
func (h *Header) EncodeRLP(w io.Writer) error {
return rlp.Encode(w, &h.fields)
return HeaderRegistry.Encode(w, h.Header)
}
// DecodeRLP decodes the given RLP decode stream into the header fields.
// DecodeRLP decodes the header using tagged RLP representation.
func (h *Header) DecodeRLP(s *rlp.Stream) error {
return s.Decode(&h.fields)
}
// NewHeader creates a new header object.
func NewHeader() *Header {
return &Header{headerFields{
Number: new(big.Int),
Time: new(big.Int),
ViewID: new(big.Int),
Epoch: new(big.Int),
}}
}
type headerFields struct {
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
Coinbase common.Address `json:"miner" gencodec:"required"`
Root common.Hash `json:"stateRoot" gencodec:"required"`
TxHash common.Hash `json:"transactionsRoot" gencodec:"required"`
ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"`
OutgoingReceiptHash common.Hash `json:"outgoingReceiptsRoot" gencodec:"required"`
IncomingReceiptHash common.Hash `json:"incomingReceiptsRoot" gencodec:"required"`
Bloom types.Bloom `json:"logsBloom" 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"`
// Additional Fields
ViewID *big.Int `json:"viewID" gencodec:"required"`
Epoch *big.Int `json:"epoch" gencodec:"required"`
ShardID uint32 `json:"shardID" gencodec:"required"`
LastCommitSignature [96]byte `json:"lastCommitSignature" gencodec:"required"`
LastCommitBitmap []byte `json:"lastCommitBitmap" gencodec:"required"` // Contains which validator signed
ShardStateHash common.Hash `json:"shardStateRoot"`
Vrf []byte `json:"vrf"`
Vdf []byte `json:"vdf"`
ShardState []byte `json:"shardState"`
CrossLinks []byte `json:"crossLink"`
}
// ParentHash is the header hash of the parent block. For the genesis block
// which has no parent by definition, this field is zeroed out.
func (h *Header) ParentHash() common.Hash {
return h.fields.ParentHash
}
// SetParentHash sets the parent hash field.
func (h *Header) SetParentHash(newParentHash common.Hash) {
h.fields.ParentHash = newParentHash
}
// Coinbase is the address of the node that proposed this block and all
// transactions in it.
func (h *Header) Coinbase() common.Address {
return h.fields.Coinbase
}
// SetCoinbase sets the coinbase address field.
func (h *Header) SetCoinbase(newCoinbase common.Address) {
h.fields.Coinbase = newCoinbase
}
// Root is the state (account) trie root hash.
func (h *Header) Root() common.Hash {
return h.fields.Root
}
// SetRoot sets the state trie root hash field.
func (h *Header) SetRoot(newRoot common.Hash) {
h.fields.Root = newRoot
}
// TxHash is the transaction trie root hash.
func (h *Header) TxHash() common.Hash {
return h.fields.TxHash
}
// SetTxHash sets the transaction trie root hash field.
func (h *Header) SetTxHash(newTxHash common.Hash) {
h.fields.TxHash = newTxHash
}
// ReceiptHash is the same-shard transaction receipt trie hash.
func (h *Header) ReceiptHash() common.Hash {
return h.fields.ReceiptHash
}
// SetReceiptHash sets the same-shard transaction receipt trie hash.
func (h *Header) SetReceiptHash(newReceiptHash common.Hash) {
h.fields.ReceiptHash = newReceiptHash
}
// OutgoingReceiptHash is the egress transaction receipt trie hash.
func (h *Header) OutgoingReceiptHash() common.Hash {
return h.fields.OutgoingReceiptHash
}
// SetOutgoingReceiptHash sets the egress transaction receipt trie hash.
func (h *Header) SetOutgoingReceiptHash(newOutgoingReceiptHash common.Hash) {
h.fields.OutgoingReceiptHash = newOutgoingReceiptHash
}
// IncomingReceiptHash is the ingress transaction receipt trie hash.
func (h *Header) IncomingReceiptHash() common.Hash {
return h.fields.IncomingReceiptHash
}
// SetIncomingReceiptHash sets the ingress transaction receipt trie hash.
func (h *Header) SetIncomingReceiptHash(newIncomingReceiptHash common.Hash) {
h.fields.IncomingReceiptHash = newIncomingReceiptHash
}
// Bloom is the Bloom filter that indexes accounts and topics logged by smart
// contract transactions (executions) in this block.
func (h *Header) Bloom() types.Bloom {
return h.fields.Bloom
}
// SetBloom sets the smart contract log Bloom filter for this block.
func (h *Header) SetBloom(newBloom types.Bloom) {
h.fields.Bloom = newBloom
}
// Number is the block number.
//
// The returned instance is a copy; the caller may do anything with it.
func (h *Header) Number() *big.Int {
return new(big.Int).Set(h.fields.Number)
}
// SetNumber sets the block number.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetNumber(newNumber *big.Int) {
h.fields.Number = new(big.Int).Set(newNumber)
}
// GasLimit is the gas limit for transactions in this block.
func (h *Header) GasLimit() uint64 {
return h.fields.GasLimit
}
// SetGasLimit sets the gas limit for transactions in this block.
func (h *Header) SetGasLimit(newGasLimit uint64) {
h.fields.GasLimit = newGasLimit
}
// GasUsed is the amount of gas used by transactions in this block.
func (h *Header) GasUsed() uint64 {
return h.fields.GasUsed
}
// SetGasUsed sets the amount of gas used by transactions in this block.
func (h *Header) SetGasUsed(newGasUsed uint64) {
h.fields.GasUsed = newGasUsed
}
// Time is the UNIX timestamp of this block.
//
// The returned instance is a copy; the caller may do anything with it.
func (h *Header) Time() *big.Int {
return new(big.Int).Set(h.fields.Time)
}
// SetTime sets the UNIX timestamp of this block.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetTime(newTime *big.Int) {
h.fields.Time = new(big.Int).Set(newTime)
}
// Extra is the extra data field of this block.
//
// The returned slice is a copy; the caller may do anything with it.
func (h *Header) Extra() []byte {
return append(h.fields.Extra[:0:0], h.fields.Extra...)
}
// SetExtra sets the extra data field of this block.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetExtra(newExtra []byte) {
h.fields.Extra = append(newExtra[:0:0], newExtra...)
}
// MixDigest is the mixhash.
//
// This field is a remnant from Ethereum, and Harmony does not use it and always
// zeroes it out.
func (h *Header) MixDigest() common.Hash {
return h.fields.MixDigest
}
// SetMixDigest sets the mixhash of this block.
func (h *Header) SetMixDigest(newMixDigest common.Hash) {
h.fields.MixDigest = newMixDigest
}
// ViewID is the ID of the view in which this block was originally proposed.
//
// It normally increases by one for each subsequent block, or by more than one
// if one or more PBFT/FBFT view changes have occurred.
//
// The returned instance is a copy; the caller may do anything with it.
func (h *Header) ViewID() *big.Int {
return new(big.Int).Set(h.fields.ViewID)
}
// SetViewID sets the view ID in which the block was originally proposed.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetViewID(newViewID *big.Int) {
h.fields.ViewID = new(big.Int).Set(newViewID)
}
// Epoch is the epoch number of this block.
//
// The returned instance is a copy; the caller may do anything with it.
func (h *Header) Epoch() *big.Int {
return new(big.Int).Set(h.fields.Epoch)
}
// SetEpoch sets the epoch number of this block.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetEpoch(newEpoch *big.Int) {
h.fields.Epoch = new(big.Int).Set(newEpoch)
}
// ShardID is the shard ID to which this block belongs.
func (h *Header) ShardID() uint32 {
return h.fields.ShardID
}
// SetShardID sets the shard ID to which this block belongs.
func (h *Header) SetShardID(newShardID uint32) {
h.fields.ShardID = newShardID
}
// LastCommitSignature is the FBFT commit group signature for the last block.
func (h *Header) LastCommitSignature() [96]byte {
return h.fields.LastCommitSignature
}
// SetLastCommitSignature sets the FBFT commit group signature for the last
// block.
func (h *Header) SetLastCommitSignature(newLastCommitSignature [96]byte) {
h.fields.LastCommitSignature = newLastCommitSignature
}
// LastCommitBitmap is the signatory bitmap of the previous block. Bit
// positions index into committee member array.
//
// The returned slice is a copy; the caller may do anything with it.
func (h *Header) LastCommitBitmap() []byte {
return append(h.fields.LastCommitBitmap[:0:0], h.fields.LastCommitBitmap...)
}
// SetLastCommitBitmap sets the signatory bitmap of the previous block.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetLastCommitBitmap(newLastCommitBitmap []byte) {
h.fields.LastCommitBitmap = append(newLastCommitBitmap[:0:0], newLastCommitBitmap...)
}
// ShardStateHash is the shard state hash.
func (h *Header) ShardStateHash() common.Hash {
return h.fields.ShardStateHash
}
// SetShardStateHash sets the shard state hash.
func (h *Header) SetShardStateHash(newShardStateHash common.Hash) {
h.fields.ShardStateHash = newShardStateHash
}
// Vrf is the output of the VRF for the epoch.
//
// The returned slice is a copy; the caller may do anything with it.
func (h *Header) Vrf() []byte {
return append(h.fields.Vrf[:0:0], h.fields.Vrf...)
}
// SetVrf sets the output of the VRF for the epoch.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetVrf(newVrf []byte) {
h.fields.Vrf = append(newVrf[:0:0], newVrf...)
}
// Vdf is the output of the VDF for the epoch.
//
// The returned slice is a copy; the caller may do anything with it.
func (h *Header) Vdf() []byte {
return append(h.fields.Vdf[:0:0], h.fields.Vdf...)
}
// SetVdf sets the output of the VDF for the epoch.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetVdf(newVdf []byte) {
h.fields.Vdf = append(newVdf[:0:0], newVdf...)
}
// ShardState is the RLP-encoded form of shard state (list of committees) for
// the next epoch.
//
// The returned slice is a copy; the caller may do anything with it.
func (h *Header) ShardState() []byte {
return append(h.fields.ShardState[:0:0], h.fields.ShardState...)
}
// SetShardState sets the RLP-encoded form of shard state
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetShardState(newShardState []byte) {
h.fields.ShardState = append(newShardState[:0:0], newShardState...)
}
// CrossLinks is the RLP-encoded form of non-beacon block headers chosen to be
// canonical by the beacon committee. This field is present only on beacon
// chain block headers.
//
// The returned slice is a copy; the caller may do anything with it.
func (h *Header) CrossLinks() []byte {
return append(h.fields.CrossLinks[:0:0], h.fields.CrossLinks...)
}
// SetCrossLinks sets the RLP-encoded form of non-beacon block headers chosen to
// be canonical by the beacon committee.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetCrossLinks(newCrossLinks []byte) {
h.fields.CrossLinks = append(newCrossLinks[:0:0], newCrossLinks...)
}
// field type overrides for gencodec
type headerMarshaling struct {
Difficulty *hexutil.Big
Number *hexutil.Big
GasLimit hexutil.Uint64
GasUsed hexutil.Uint64
Time *hexutil.Big
Extra hexutil.Bytes
Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON
decoded, err := HeaderRegistry.Decode(s)
if err != nil {
return err
}
hif, ok := decoded.(blockif.Header)
if !ok {
return errors.Errorf(
"decoded object (type %s) does not implement Header interface",
taggedrlp.TypeName(reflect.TypeOf(decoded)))
}
h.Header = hif
return nil
}
// Hash returns the block hash of the header, which is simply the keccak256 hash of its
// RLP encoding.
func (h *Header) Hash() common.Hash {
// Hash returns the block hash of the header. This uses HeaderRegistry to
// choose and return the right tagged RLP form of the header.
func (h *Header) Hash() ethcommon.Hash {
return hash.FromRLP(h)
}
// 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 {
// 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.
func (h *Header) Logger(logger *zerolog.Logger) *zerolog.Logger {
nlogger := logger.
With().
nlogger := logger.With().
Str("blockHash", h.Hash().Hex()).
Uint32("blockShard", h.ShardID()).
Uint64("blockEpoch", h.Epoch().Uint64()).
@ -399,205 +59,26 @@ func (h *Header) Logger(logger *zerolog.Logger) *zerolog.Logger {
return &nlogger
}
// GetShardState returns the deserialized shard state object.
func (h *Header) GetShardState() (shard.State, error) {
shardState := shard.State{}
err := rlp.DecodeBytes(h.ShardState(), &shardState)
if err != nil {
return nil, err
}
return shardState, nil
}
// HeaderFieldSetter is a header field setter.
//
// See NewHeaderWith for how it is used.
type HeaderFieldSetter struct {
h *Header
}
// NewHeaderWith creates a new header and returns its field setter context.
// With returns a field setter context for the header.
//
// Call a chain of setters on the returned field setter, followed by a call of
// Header method. Example:
//
// header := NewHeaderWith().
// header := NewHeader(epoch).With().
// ParentHash(parent.Hash()).
// Epoch(parent.Epoch()).
// ShardID(parent.ShardID()).
// Number(new(big.Int).Add(parent.Number(), big.NewInt(1)).
// Header()
func NewHeaderWith() *HeaderFieldSetter {
return (*HeaderFieldSetter)(&HeaderFieldSetter{h: NewHeader()})
}
// ParentHash sets the parent hash field.
func (s HeaderFieldSetter) ParentHash(newParentHash common.Hash) HeaderFieldSetter {
s.h.SetParentHash(newParentHash)
return s
}
// Coinbase sets the coinbase address field.
func (s HeaderFieldSetter) Coinbase(newCoinbase common.Address) HeaderFieldSetter {
s.h.SetCoinbase(newCoinbase)
return s
}
// Root sets the state trie root hash field.
func (s HeaderFieldSetter) Root(newRoot common.Hash) HeaderFieldSetter {
s.h.SetRoot(newRoot)
return s
}
// TxHash sets the transaction trie root hash field.
func (s HeaderFieldSetter) TxHash(newTxHash common.Hash) HeaderFieldSetter {
s.h.SetTxHash(newTxHash)
return s
}
// ReceiptHash sets the same-shard transaction receipt trie hash.
func (s HeaderFieldSetter) ReceiptHash(newReceiptHash common.Hash) HeaderFieldSetter {
s.h.SetReceiptHash(newReceiptHash)
return s
}
// OutgoingReceiptHash sets the egress transaction receipt trie hash.
func (s HeaderFieldSetter) OutgoingReceiptHash(newOutgoingReceiptHash common.Hash) HeaderFieldSetter {
s.h.SetOutgoingReceiptHash(newOutgoingReceiptHash)
return s
}
// IncomingReceiptHash sets the ingress transaction receipt trie hash.
func (s HeaderFieldSetter) IncomingReceiptHash(newIncomingReceiptHash common.Hash) HeaderFieldSetter {
s.h.SetIncomingReceiptHash(newIncomingReceiptHash)
return s
}
// Bloom sets the smart contract log Bloom filter for this block.
func (s HeaderFieldSetter) Bloom(newBloom types.Bloom) HeaderFieldSetter {
s.h.SetBloom(newBloom)
return s
}
// Number sets the block number.
//
// It stores a copy; the caller may freely modify the original.
func (s HeaderFieldSetter) Number(newNumber *big.Int) HeaderFieldSetter {
s.h.SetNumber(newNumber)
return s
}
// GasLimit sets the gas limit for transactions in this block.
func (s HeaderFieldSetter) GasLimit(newGasLimit uint64) HeaderFieldSetter {
s.h.SetGasLimit(newGasLimit)
return s
}
// GasUsed sets the amount of gas used by transactions in this block.
func (s HeaderFieldSetter) GasUsed(newGasUsed uint64) HeaderFieldSetter {
s.h.SetGasUsed(newGasUsed)
return s
}
// Time sets the UNIX timestamp of this block.
//
// It stores a copy; the caller may freely modify the original.
func (s HeaderFieldSetter) Time(newTime *big.Int) HeaderFieldSetter {
s.h.SetTime(newTime)
return s
}
// Extra sets the extra data field of this block.
//
// It stores a copy; the caller may freely modify the original.
func (s HeaderFieldSetter) Extra(newExtra []byte) HeaderFieldSetter {
s.h.SetExtra(newExtra)
return s
}
// MixDigest sets the mixhash of this block.
func (s HeaderFieldSetter) MixDigest(newMixDigest common.Hash) HeaderFieldSetter {
s.h.SetMixDigest(newMixDigest)
return s
}
// ViewID sets the view ID in which the block was originally proposed.
//
// It stores a copy; the caller may freely modify the original.
func (s HeaderFieldSetter) ViewID(newViewID *big.Int) HeaderFieldSetter {
s.h.SetViewID(newViewID)
return s
}
// Epoch sets the epoch number of this block.
//
// It stores a copy; the caller may freely modify the original.
func (s HeaderFieldSetter) Epoch(newEpoch *big.Int) HeaderFieldSetter {
s.h.SetEpoch(newEpoch)
return s
}
// ShardID sets the shard ID to which this block belongs.
func (s HeaderFieldSetter) ShardID(newShardID uint32) HeaderFieldSetter {
s.h.SetShardID(newShardID)
return s
}
// LastCommitSignature sets the FBFT commit group signature for the last block.
func (s HeaderFieldSetter) LastCommitSignature(newLastCommitSignature [96]byte) HeaderFieldSetter {
s.h.SetLastCommitSignature(newLastCommitSignature)
return s
}
// LastCommitBitmap sets the signatory bitmap of the previous block.
//
// It stores a copy; the caller may freely modify the original.
func (s HeaderFieldSetter) LastCommitBitmap(newLastCommitBitmap []byte) HeaderFieldSetter {
s.h.SetLastCommitBitmap(newLastCommitBitmap)
return s
}
// ShardStateHash sets the shard state hash.
func (s HeaderFieldSetter) ShardStateHash(newShardStateHash common.Hash) HeaderFieldSetter {
s.h.SetShardStateHash(newShardStateHash)
return s
}
// Vrf sets the output of the VRF for the epoch.
//
// It stores a copy; the caller may freely modify the original.
func (s HeaderFieldSetter) Vrf(newVrf []byte) HeaderFieldSetter {
s.h.SetVrf(newVrf)
return s
}
// Vdf sets the output of the VDF for the epoch.
//
// It stores a copy; the caller may freely modify the original.
func (s HeaderFieldSetter) Vdf(newVdf []byte) HeaderFieldSetter {
s.h.SetVdf(newVdf)
return s
}
// ShardState sets the RLP-encoded form of shard state
//
// It stores a copy; the caller may freely modify the original.
func (s HeaderFieldSetter) ShardState(newShardState []byte) HeaderFieldSetter {
s.h.SetShardState(newShardState)
return s
func (h *Header) With() HeaderFieldSetter {
return HeaderFieldSetter{h: h}
}
// CrossLinks sets the RLP-encoded form of non-beacon block headers chosen to be
// canonical by the beacon committee.
//
// It stores a copy; the caller may freely modify the original.
func (s HeaderFieldSetter) CrossLinks(newCrossLinks []byte) HeaderFieldSetter {
s.h.SetCrossLinks(newCrossLinks)
return s
}
// HeaderRegistry is the taggedrlp type registry for versioned headers.
var HeaderRegistry = taggedrlp.NewRegistry()
// Header returns the header whose fields have been set. Call this at the end
// of a field setter chain.
func (s HeaderFieldSetter) Header() *Header {
return s.h
func init() {
HeaderRegistry.MustRegister(taggedrlp.LegacyTag, v0.NewHeader())
HeaderRegistry.MustAddFactory(func() interface{} { return v0.NewHeader() })
HeaderRegistry.MustRegister("v1", v1.NewHeader())
HeaderRegistry.MustAddFactory(func() interface{} { return v1.NewHeader() })
}

@ -0,0 +1,538 @@
package block
import (
"bytes"
"reflect"
"testing"
"github.com/ethereum/go-ethereum/rlp"
blockif "github.com/harmony-one/harmony/block/interface"
v0 "github.com/harmony-one/harmony/block/v0"
v1 "github.com/harmony-one/harmony/block/v1"
)
func TestHeader_EncodeRLP(t *testing.T) {
type fields struct {
HeaderInterface blockif.Header
}
tests := []struct {
name string
fields fields
want []byte
wantErr bool
}{
{
"v0",
fields{v0.NewHeader()},
[]byte{
// BEGIN 586-byte Header
0xf9, 0x02, 0x4a,
0xa0, // 32-byte ParentHash
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x94, // 20-byte Coinbase
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa0, // 32-byte Root
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa0, // 32-byte TxHash
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa0, // 32-byte ReceiptHash
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xb9, 0x01, 0x00, // 256-byte Bloom
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, // 0-byte Number
0x80, // 0-byte GasLimit
0x80, // 0-byte GasUsed
0x80, // 0-byte Time
0x80, // 0-byte Extra
0xa0, // 32-byte MixDigest
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, // 0-byte ViewID
0x80, // 0-byte Epoch
0x80, // 0-byte ShardID
0xb8, 0x60, // 96-byte LastCommitSignature
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, // 0-byte LastCommitBitmap
0xa0, // 32-byte ShardStateHash
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, // 0-byte ShardState
// END Header
},
false,
},
{
"v1",
fields{v1.NewHeader()},
[]byte{
// BEGIN 669-byte tagged RLP envelope
0xf9, 0x02, 0x9d,
0x87, // 7-byte tagged RLP signature
'H', 'm', 'n', 'y', 'T', 'g', 'd',
0x82, // 2-byte v1 header tag
'v', '1',
// BEGIN 655-byte Header
0xf9, 0x02, 0x8f,
0xa0, // 32-byte ParentHash
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x94, // 20-byte Coinbase
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa0, // 32-byte Root
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa0, // 32-byte TxHash
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa0, // 32-byte ReceiptHash
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa0, // 32-byte OutgoingReceiptHash
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa0, // 32-byte IncomingReceiptHash
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xb9, 0x01, 0x00, // 256-byte Bloom
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, // 0-byte Number
0x80, // 0-byte GasLimit
0x80, // 0-byte GasUsed
0x80, // 0-byte Time
0x80, // 0-byte Extra
0xa0, // 32-byte MixDigest
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, // 0-byte ViewID
0x80, // 0-byte Epoch
0x80, // 0-byte ShardID
0xb8, 0x60, // 96-byte LastCommitSignature
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, // 0-byte LastCommitBitmap
0xa0, // 32-byte ShardStateHash
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, // 0-byte Vrf
0x80, // 0-byte Vdf
0x80, // 0-byte ShardState
0x80, // 0-byte CrossLinks
// END Header
// END tagged RLP envelope
},
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
h := &Header{Header: tt.fields.HeaderInterface}
w := &bytes.Buffer{}
err := h.EncodeRLP(w)
if (err != nil) != tt.wantErr {
t.Errorf("EncodeRLP() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got := w.Bytes(); bytes.Compare(got, tt.want) != 0 {
t.Errorf("EncodeRLP() got %x", got)
t.Errorf("EncodeRLP() want %x", tt.want)
}
})
}
}
func TestHeader_DecodeRLP(t *testing.T) {
type args struct {
s *rlp.Stream
}
tests := []struct {
name string
args args
want blockif.Header
wantErr bool
}{
{
"v0",
args{rlp.NewStream(bytes.NewBuffer([]byte{
// BEGIN 586-byte Header
0xf9, 0x02, 0x4a,
0xa0, // 32-byte ParentHash
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x94, // 20-byte Coinbase
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa0, // 32-byte Root
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa0, // 32-byte TxHash
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa0, // 32-byte ReceiptHash
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xb9, 0x01, 0x00, // 256-byte Bloom
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, // 0-byte Number
0x80, // 0-byte GasLimit
0x80, // 0-byte GasUsed
0x80, // 0-byte Time
0x80, // 0-byte Extra
0xa0, // 32-byte MixDigest
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, // 0-byte ViewID
0x80, // 0-byte Epoch
0x80, // 0-byte ShardID
0xb8, 0x60, // 96-byte LastCommitSignature
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, // 0-byte LastCommitBitmap
0xa0, // 32-byte ShardStateHash
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, // 0-byte ShardState
// END Header
}), 0)},
v0.NewHeader(),
false,
},
{
"v1",
args{rlp.NewStream(bytes.NewBuffer([]byte{
// BEGIN 669-byte tagged RLP envelope
0xf9, 0x02, 0x9d,
0x87, // 7-byte tagged RLP signature
'H', 'm', 'n', 'y', 'T', 'g', 'd',
0x82, // 2-byte v1 header tag
'v', '1',
// BEGIN 655-byte Header
0xf9, 0x02, 0x8f,
0xa0, // 32-byte ParentHash
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x94, // 20-byte Coinbase
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa0, // 32-byte Root
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa0, // 32-byte TxHash
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa0, // 32-byte ReceiptHash
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa0, // 32-byte OutgoingReceiptHash
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa0, // 32-byte IncomingReceiptHash
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xb9, 0x01, 0x00, // 256-byte Bloom
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, // 0-byte Number
0x80, // 0-byte GasLimit
0x80, // 0-byte GasUsed
0x80, // 0-byte Time
0x80, // 0-byte Extra
0xa0, // 32-byte MixDigest
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, // 0-byte ViewID
0x80, // 0-byte Epoch
0x80, // 0-byte ShardID
0xb8, 0x60, // 96-byte LastCommitSignature
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, // 0-byte LastCommitBitmap
0xa0, // 32-byte ShardStateHash
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, // 0-byte Vrf
0x80, // 0-byte Vdf
0x80, // 0-byte ShardState
0x80, // 0-byte CrossLinks
// END Header
// END tagged RLP envelope
}), 0)},
v1.NewHeader(),
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
h := &Header{}
if err := h.DecodeRLP(tt.args.s); (err != nil) != tt.wantErr {
t.Errorf("DecodeRLP() error = %v, wantErr %v", err, tt.wantErr)
}
if !compareHeaders(h.Header, tt.want) {
t.Errorf("DecodeRLP() got %#v", h.Header)
t.Errorf("DecodeRLP() want %#v", tt.want)
}
})
}
}
func equal(x, y interface{}) bool {
xv := reflect.ValueOf(x)
yv := reflect.ValueOf(y)
if xv.Type() == yv.Type() && xv.Type().Kind() == reflect.Slice && xv.Len() == 0 && yv.Len() == 0 {
return true
}
return reflect.DeepEqual(x, y)
}
func compareHeaders(x, y blockif.Header) bool {
return equal(x.ParentHash(), y.ParentHash()) &&
equal(x.Coinbase(), y.Coinbase()) &&
equal(x.Root(), y.Root()) &&
equal(x.TxHash(), y.TxHash()) &&
equal(x.ReceiptHash(), y.ReceiptHash()) &&
equal(x.OutgoingReceiptHash(), y.OutgoingReceiptHash()) &&
equal(x.IncomingReceiptHash(), y.IncomingReceiptHash()) &&
equal(x.Bloom(), y.Bloom()) &&
equal(x.Number(), y.Number()) &&
equal(x.GasLimit(), y.GasLimit()) &&
equal(x.GasUsed(), y.GasUsed()) &&
equal(x.Time(), y.Time()) &&
equal(x.Extra(), y.Extra()) &&
equal(x.MixDigest(), y.MixDigest()) &&
equal(x.ViewID(), y.ViewID()) &&
equal(x.Epoch(), y.Epoch()) &&
equal(x.ShardID(), y.ShardID()) &&
equal(x.LastCommitSignature(), y.LastCommitSignature()) &&
equal(x.LastCommitBitmap(), y.LastCommitBitmap()) &&
equal(x.ShardStateHash(), y.ShardStateHash()) &&
equal(x.Vrf(), y.Vrf()) &&
equal(x.Vdf(), y.Vdf()) &&
equal(x.ShardState(), y.ShardState()) &&
equal(x.CrossLinks(), y.CrossLinks())
}

@ -0,0 +1,186 @@
package block
import (
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
)
// HeaderFieldSetter is a header field setter.
//
// See NewHeaderWith for how it is used.
type HeaderFieldSetter struct {
h *Header
}
// ParentHash sets the parent hash field.
func (s HeaderFieldSetter) ParentHash(newParentHash common.Hash) HeaderFieldSetter {
s.h.SetParentHash(newParentHash)
return s
}
// Coinbase sets the coinbase address field.
func (s HeaderFieldSetter) Coinbase(newCoinbase common.Address) HeaderFieldSetter {
s.h.SetCoinbase(newCoinbase)
return s
}
// Root sets the state trie root hash field.
func (s HeaderFieldSetter) Root(newRoot common.Hash) HeaderFieldSetter {
s.h.SetRoot(newRoot)
return s
}
// TxHash sets the transaction trie root hash field.
func (s HeaderFieldSetter) TxHash(newTxHash common.Hash) HeaderFieldSetter {
s.h.SetTxHash(newTxHash)
return s
}
// ReceiptHash sets the same-shard transaction receipt trie hash.
func (s HeaderFieldSetter) ReceiptHash(newReceiptHash common.Hash) HeaderFieldSetter {
s.h.SetReceiptHash(newReceiptHash)
return s
}
// OutgoingReceiptHash sets the egress transaction receipt trie hash.
func (s HeaderFieldSetter) OutgoingReceiptHash(newOutgoingReceiptHash common.Hash) HeaderFieldSetter {
s.h.SetOutgoingReceiptHash(newOutgoingReceiptHash)
return s
}
// IncomingReceiptHash sets the ingress transaction receipt trie hash.
func (s HeaderFieldSetter) IncomingReceiptHash(newIncomingReceiptHash common.Hash) HeaderFieldSetter {
s.h.SetIncomingReceiptHash(newIncomingReceiptHash)
return s
}
// Bloom sets the smart contract log Bloom filter for this block.
func (s HeaderFieldSetter) Bloom(newBloom types.Bloom) HeaderFieldSetter {
s.h.SetBloom(newBloom)
return s
}
// Number sets the block number.
//
// It stores a copy; the caller may freely modify the original.
func (s HeaderFieldSetter) Number(newNumber *big.Int) HeaderFieldSetter {
s.h.SetNumber(newNumber)
return s
}
// GasLimit sets the gas limit for transactions in this block.
func (s HeaderFieldSetter) GasLimit(newGasLimit uint64) HeaderFieldSetter {
s.h.SetGasLimit(newGasLimit)
return s
}
// GasUsed sets the amount of gas used by transactions in this block.
func (s HeaderFieldSetter) GasUsed(newGasUsed uint64) HeaderFieldSetter {
s.h.SetGasUsed(newGasUsed)
return s
}
// Time sets the UNIX timestamp of this block.
//
// It stores a copy; the caller may freely modify the original.
func (s HeaderFieldSetter) Time(newTime *big.Int) HeaderFieldSetter {
s.h.SetTime(newTime)
return s
}
// Extra sets the extra data field of this block.
//
// It stores a copy; the caller may freely modify the original.
func (s HeaderFieldSetter) Extra(newExtra []byte) HeaderFieldSetter {
s.h.SetExtra(newExtra)
return s
}
// MixDigest sets the mixhash of this block.
func (s HeaderFieldSetter) MixDigest(newMixDigest common.Hash) HeaderFieldSetter {
s.h.SetMixDigest(newMixDigest)
return s
}
// ViewID sets the view ID in which the block was originally proposed.
//
// It stores a copy; the caller may freely modify the original.
func (s HeaderFieldSetter) ViewID(newViewID *big.Int) HeaderFieldSetter {
s.h.SetViewID(newViewID)
return s
}
// Epoch sets the epoch number of this block.
//
// It stores a copy; the caller may freely modify the original.
func (s HeaderFieldSetter) Epoch(newEpoch *big.Int) HeaderFieldSetter {
s.h.SetEpoch(newEpoch)
return s
}
// ShardID sets the shard ID to which this block belongs.
func (s HeaderFieldSetter) ShardID(newShardID uint32) HeaderFieldSetter {
s.h.SetShardID(newShardID)
return s
}
// LastCommitSignature sets the FBFT commit group signature for the last block.
func (s HeaderFieldSetter) LastCommitSignature(newLastCommitSignature [96]byte) HeaderFieldSetter {
s.h.SetLastCommitSignature(newLastCommitSignature)
return s
}
// LastCommitBitmap sets the signatory bitmap of the previous block.
//
// It stores a copy; the caller may freely modify the original.
func (s HeaderFieldSetter) LastCommitBitmap(newLastCommitBitmap []byte) HeaderFieldSetter {
s.h.SetLastCommitBitmap(newLastCommitBitmap)
return s
}
// ShardStateHash sets the shard state hash.
func (s HeaderFieldSetter) ShardStateHash(newShardStateHash common.Hash) HeaderFieldSetter {
s.h.SetShardStateHash(newShardStateHash)
return s
}
// Vrf sets the output of the VRF for the epoch.
//
// It stores a copy; the caller may freely modify the original.
func (s HeaderFieldSetter) Vrf(newVrf []byte) HeaderFieldSetter {
s.h.SetVrf(newVrf)
return s
}
// Vdf sets the output of the VDF for the epoch.
//
// It stores a copy; the caller may freely modify the original.
func (s HeaderFieldSetter) Vdf(newVdf []byte) HeaderFieldSetter {
s.h.SetVdf(newVdf)
return s
}
// ShardState sets the RLP-encoded form of shard state
//
// It stores a copy; the caller may freely modify the original.
func (s HeaderFieldSetter) ShardState(newShardState []byte) HeaderFieldSetter {
s.h.SetShardState(newShardState)
return s
}
// CrossLinks sets the RLP-encoded form of non-beacon block headers chosen to be
// canonical by the beacon committee.
//
// It stores a copy; the caller may freely modify the original.
func (s HeaderFieldSetter) CrossLinks(newCrossLinks []byte) HeaderFieldSetter {
s.h.SetCrossLinks(newCrossLinks)
return s
}
// Header returns the header whose fields have been set. Call this at the end
// of a field setter chain.
func (s HeaderFieldSetter) Header() *Header {
return s.h
}

@ -0,0 +1,230 @@
package blockif
import (
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/rs/zerolog"
"github.com/harmony-one/harmony/shard"
)
// Header defines the block header interface.
type Header interface {
// ParentHash is the header hash of the parent block. For the genesis block
// which has no parent by definition, this field is zeroed out.
ParentHash() common.Hash
// SetParentHash sets the parent hash field.
SetParentHash(newParentHash common.Hash)
// Coinbase is the address of the node that proposed this block and all
// transactions in it.
Coinbase() common.Address
// SetCoinbase sets the coinbase address field.
SetCoinbase(newCoinbase common.Address)
// Root is the state (account) trie root hash.
Root() common.Hash
// SetRoot sets the state trie root hash field.
SetRoot(newRoot common.Hash)
// TxHash is the transaction trie root hash.
TxHash() common.Hash
// SetTxHash sets the transaction trie root hash field.
SetTxHash(newTxHash common.Hash)
// ReceiptHash is the same-shard transaction receipt trie hash.
ReceiptHash() common.Hash
// SetReceiptHash sets the same-shard transaction receipt trie hash.
SetReceiptHash(newReceiptHash common.Hash)
// OutgoingReceiptHash is the egress transaction receipt trie hash.
OutgoingReceiptHash() common.Hash
// SetOutgoingReceiptHash sets the egress transaction receipt trie hash.
SetOutgoingReceiptHash(newOutgoingReceiptHash common.Hash)
// IncomingReceiptHash is the ingress transaction receipt trie hash.
IncomingReceiptHash() common.Hash
// SetIncomingReceiptHash sets the ingress transaction receipt trie hash.
SetIncomingReceiptHash(newIncomingReceiptHash common.Hash)
// Bloom is the Bloom filter that indexes accounts and topics logged by smart
// contract transactions (executions) in this block.
Bloom() types.Bloom
// SetBloom sets the smart contract log Bloom filter for this block.
SetBloom(newBloom types.Bloom)
// Number is the block number.
//
// The returned instance is a copy; the caller may do anything with it.
Number() *big.Int
// SetNumber sets the block number.
//
// It stores a copy; the caller may freely modify the original.
SetNumber(newNumber *big.Int)
// GasLimit is the gas limit for transactions in this block.
GasLimit() uint64
// SetGasLimit sets the gas limit for transactions in this block.
SetGasLimit(newGasLimit uint64)
// GasUsed is the amount of gas used by transactions in this block.
GasUsed() uint64
// SetGasUsed sets the amount of gas used by transactions in this block.
SetGasUsed(newGasUsed uint64)
// Time is the UNIX timestamp of this block.
//
// The returned instance is a copy; the caller may do anything with it.
Time() *big.Int
// SetTime sets the UNIX timestamp of this block.
//
// It stores a copy; the caller may freely modify the original.
SetTime(newTime *big.Int)
// Extra is the extra data field of this block.
//
// The returned slice is a copy; the caller may do anything with it.
Extra() []byte
// SetExtra sets the extra data field of this block.
//
// It stores a copy; the caller may freely modify the original.
SetExtra(newExtra []byte)
// MixDigest is the mixhash.
//
// This field is a remnant from Ethereum, and Harmony does not use it and always
// zeroes it out.
MixDigest() common.Hash
// SetMixDigest sets the mixhash of this block.
SetMixDigest(newMixDigest common.Hash)
// ViewID is the ID of the view in which this block was originally proposed.
//
// It normally increases by one for each subsequent block, or by more than one
// if one or more PBFT/FBFT view changes have occurred.
//
// The returned instance is a copy; the caller may do anything with it.
ViewID() *big.Int
// SetViewID sets the view ID in which the block was originally proposed.
//
// It stores a copy; the caller may freely modify the original.
SetViewID(newViewID *big.Int)
// Epoch is the epoch number of this block.
//
// The returned instance is a copy; the caller may do anything with it.
Epoch() *big.Int
// SetEpoch sets the epoch number of this block.
//
// It stores a copy; the caller may freely modify the original.
SetEpoch(newEpoch *big.Int)
// ShardID is the shard ID to which this block belongs.
ShardID() uint32
// SetShardID sets the shard ID to which this block belongs.
SetShardID(newShardID uint32)
// LastCommitSignature is the FBFT commit group signature for the last block.
LastCommitSignature() [96]byte
// SetLastCommitSignature sets the FBFT commit group signature for the last
// block.
SetLastCommitSignature(newLastCommitSignature [96]byte)
// LastCommitBitmap is the signatory bitmap of the previous block. Bit
// positions index into committee member array.
//
// The returned slice is a copy; the caller may do anything with it.
LastCommitBitmap() []byte
// SetLastCommitBitmap sets the signatory bitmap of the previous block.
//
// It stores a copy; the caller may freely modify the original.
SetLastCommitBitmap(newLastCommitBitmap []byte)
// ShardStateHash is the shard state hash.
ShardStateHash() common.Hash
// SetShardStateHash sets the shard state hash.
SetShardStateHash(newShardStateHash common.Hash)
// Vrf is the output of the VRF for the epoch.
//
// The returned slice is a copy; the caller may do anything with it.
Vrf() []byte
// SetVrf sets the output of the VRF for the epoch.
//
// It stores a copy; the caller may freely modify the original.
SetVrf(newVrf []byte)
// Vdf is the output of the VDF for the epoch.
//
// The returned slice is a copy; the caller may do anything with it.
Vdf() []byte
// SetVdf sets the output of the VDF for the epoch.
//
// It stores a copy; the caller may freely modify the original.
SetVdf(newVdf []byte)
// ShardState is the RLP-encoded form of shard state (list of committees) for
// the next epoch.
//
// The returned slice is a copy; the caller may do anything with it.
ShardState() []byte
// SetShardState sets the RLP-encoded form of shard state
//
// It stores a copy; the caller may freely modify the original.
SetShardState(newShardState []byte)
// CrossLinks is the RLP-encoded form of non-beacon block headers chosen to be
// canonical by the beacon committee. This field is present only on beacon
// chain block headers.
//
// The returned slice is a copy; the caller may do anything with it.
CrossLinks() []byte
// SetCrossLinks sets the RLP-encoded form of non-beacon block headers chosen to
// be canonical by the beacon committee.
//
// It stores a copy; the caller may freely modify the original.
SetCrossLinks(newCrossLinks []byte)
// Hash returns the block hash of the header, which is simply the legacy
// Keccak256 hash of its RLP encoding.
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.
Size() common.StorageSize
// Logger returns a sub-logger with block contexts added.
Logger(logger *zerolog.Logger) *zerolog.Logger
// GetShardState returns the deserialized shard state object.
GetShardState() (shard.State, error)
// Copy returns a copy of the header.
Copy() Header
}

@ -1,6 +1,6 @@
// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
package block
package v0
import (
"encoding/json"

@ -0,0 +1,433 @@
package v0
import (
"io"
"math/big"
"unsafe"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
"github.com/rs/zerolog"
blockif "github.com/harmony-one/harmony/block/interface"
"github.com/harmony-one/harmony/crypto/hash"
"github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/shard"
)
// Header is the V1 block header.
type Header struct {
fields headerFields
}
// EncodeRLP encodes the header fields into RLP format.
func (h *Header) EncodeRLP(w io.Writer) error {
return rlp.Encode(w, &h.fields)
}
// DecodeRLP decodes the given RLP decode stream into the header fields.
func (h *Header) DecodeRLP(s *rlp.Stream) error {
return s.Decode(&h.fields)
}
// NewHeader creates a new header object.
func NewHeader() *Header {
return &Header{headerFields{
Number: new(big.Int),
Time: new(big.Int),
ViewID: new(big.Int),
Epoch: new(big.Int),
}}
}
type headerFields struct {
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
Coinbase common.Address `json:"miner" gencodec:"required"`
Root common.Hash `json:"stateRoot" gencodec:"required"`
TxHash common.Hash `json:"transactionsRoot" gencodec:"required"`
ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"`
Bloom ethtypes.Bloom `json:"logsBloom" 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"`
// Additional Fields
ViewID *big.Int `json:"viewID" gencodec:"required"`
Epoch *big.Int `json:"epoch" gencodec:"required"`
ShardID uint32 `json:"shardID" gencodec:"required"`
LastCommitSignature [96]byte `json:"lastCommitSignature" gencodec:"required"`
LastCommitBitmap []byte `json:"lastCommitBitmap" gencodec:"required"` // Contains which validator signed
ShardStateHash common.Hash `json:"shardStateRoot"`
ShardState []byte `json:"shardState"`
}
// ParentHash is the header hash of the parent block. For the genesis block
// which has no parent by definition, this field is zeroed out.
func (h *Header) ParentHash() common.Hash {
return h.fields.ParentHash
}
// SetParentHash sets the parent hash field.
func (h *Header) SetParentHash(newParentHash common.Hash) {
h.fields.ParentHash = newParentHash
}
// Coinbase is the address of the node that proposed this block and all
// transactions in it.
func (h *Header) Coinbase() common.Address {
return h.fields.Coinbase
}
// SetCoinbase sets the coinbase address field.
func (h *Header) SetCoinbase(newCoinbase common.Address) {
h.fields.Coinbase = newCoinbase
}
// Root is the state (account) trie root hash.
func (h *Header) Root() common.Hash {
return h.fields.Root
}
// SetRoot sets the state trie root hash field.
func (h *Header) SetRoot(newRoot common.Hash) {
h.fields.Root = newRoot
}
// TxHash is the transaction trie root hash.
func (h *Header) TxHash() common.Hash {
return h.fields.TxHash
}
// SetTxHash sets the transaction trie root hash field.
func (h *Header) SetTxHash(newTxHash common.Hash) {
h.fields.TxHash = newTxHash
}
// ReceiptHash is the same-shard transaction receipt trie hash.
func (h *Header) ReceiptHash() common.Hash {
return h.fields.ReceiptHash
}
// SetReceiptHash sets the same-shard transaction receipt trie hash.
func (h *Header) SetReceiptHash(newReceiptHash common.Hash) {
h.fields.ReceiptHash = newReceiptHash
}
// OutgoingReceiptHash is the egress transaction receipt trie hash.
func (h *Header) OutgoingReceiptHash() common.Hash {
return ethtypes.EmptyRootHash
}
// SetOutgoingReceiptHash sets the egress transaction receipt trie hash.
func (h *Header) SetOutgoingReceiptHash(newOutgoingReceiptHash common.Hash) {
if newOutgoingReceiptHash != ethtypes.EmptyRootHash {
h.Logger(utils.Logger()).Warn().
Hex("outgoingReceiptHash", newOutgoingReceiptHash[:]).
Msg("non-empty outgoing receipt root hash provided but cannot be stored")
}
}
// IncomingReceiptHash is the ingress transaction receipt trie hash.
func (h *Header) IncomingReceiptHash() common.Hash {
return ethtypes.EmptyRootHash
}
// SetIncomingReceiptHash sets the ingress transaction receipt trie hash.
func (h *Header) SetIncomingReceiptHash(newIncomingReceiptHash common.Hash) {
if newIncomingReceiptHash != ethtypes.EmptyRootHash {
h.Logger(utils.Logger()).Warn().
Hex("incomingReceiptHash", newIncomingReceiptHash[:]).
Msg("non-empty outgoing receipt root hash provided but cannot be stored")
}
}
// Bloom is the Bloom filter that indexes accounts and topics logged by smart
// contract transactions (executions) in this block.
func (h *Header) Bloom() ethtypes.Bloom {
return h.fields.Bloom
}
// SetBloom sets the smart contract log Bloom filter for this block.
func (h *Header) SetBloom(newBloom ethtypes.Bloom) {
h.fields.Bloom = newBloom
}
// Number is the block number.
//
// The returned instance is a copy; the caller may do anything with it.
func (h *Header) Number() *big.Int {
return new(big.Int).Set(h.fields.Number)
}
// SetNumber sets the block number.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetNumber(newNumber *big.Int) {
h.fields.Number = new(big.Int).Set(newNumber)
}
// GasLimit is the gas limit for transactions in this block.
func (h *Header) GasLimit() uint64 {
return h.fields.GasLimit
}
// SetGasLimit sets the gas limit for transactions in this block.
func (h *Header) SetGasLimit(newGasLimit uint64) {
h.fields.GasLimit = newGasLimit
}
// GasUsed is the amount of gas used by transactions in this block.
func (h *Header) GasUsed() uint64 {
return h.fields.GasUsed
}
// SetGasUsed sets the amount of gas used by transactions in this block.
func (h *Header) SetGasUsed(newGasUsed uint64) {
h.fields.GasUsed = newGasUsed
}
// Time is the UNIX timestamp of this block.
//
// The returned instance is a copy; the caller may do anything with it.
func (h *Header) Time() *big.Int {
return new(big.Int).Set(h.fields.Time)
}
// SetTime sets the UNIX timestamp of this block.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetTime(newTime *big.Int) {
h.fields.Time = new(big.Int).Set(newTime)
}
// Extra is the extra data field of this block.
//
// The returned slice is a copy; the caller may do anything with it.
func (h *Header) Extra() []byte {
return append(h.fields.Extra[:0:0], h.fields.Extra...)
}
// SetExtra sets the extra data field of this block.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetExtra(newExtra []byte) {
h.fields.Extra = append(newExtra[:0:0], newExtra...)
}
// MixDigest is the mixhash.
//
// This field is a remnant from Ethereum, and Harmony does not use it and always
// zeroes it out.
func (h *Header) MixDigest() common.Hash {
return h.fields.MixDigest
}
// SetMixDigest sets the mixhash of this block.
func (h *Header) SetMixDigest(newMixDigest common.Hash) {
h.fields.MixDigest = newMixDigest
}
// ViewID is the ID of the view in which this block was originally proposed.
//
// It normally increases by one for each subsequent block, or by more than one
// if one or more PBFT/FBFT view changes have occurred.
//
// The returned instance is a copy; the caller may do anything with it.
func (h *Header) ViewID() *big.Int {
return new(big.Int).Set(h.fields.ViewID)
}
// SetViewID sets the view ID in which the block was originally proposed.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetViewID(newViewID *big.Int) {
h.fields.ViewID = new(big.Int).Set(newViewID)
}
// Epoch is the epoch number of this block.
//
// The returned instance is a copy; the caller may do anything with it.
func (h *Header) Epoch() *big.Int {
return new(big.Int).Set(h.fields.Epoch)
}
// SetEpoch sets the epoch number of this block.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetEpoch(newEpoch *big.Int) {
h.fields.Epoch = new(big.Int).Set(newEpoch)
}
// ShardID is the shard ID to which this block belongs.
func (h *Header) ShardID() uint32 {
return h.fields.ShardID
}
// SetShardID sets the shard ID to which this block belongs.
func (h *Header) SetShardID(newShardID uint32) {
h.fields.ShardID = newShardID
}
// LastCommitSignature is the FBFT commit group signature for the last block.
func (h *Header) LastCommitSignature() [96]byte {
return h.fields.LastCommitSignature
}
// SetLastCommitSignature sets the FBFT commit group signature for the last
// block.
func (h *Header) SetLastCommitSignature(newLastCommitSignature [96]byte) {
h.fields.LastCommitSignature = newLastCommitSignature
}
// LastCommitBitmap is the signatory bitmap of the previous block. Bit
// positions index into committee member array.
//
// The returned slice is a copy; the caller may do anything with it.
func (h *Header) LastCommitBitmap() []byte {
return append(h.fields.LastCommitBitmap[:0:0], h.fields.LastCommitBitmap...)
}
// SetLastCommitBitmap sets the signatory bitmap of the previous block.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetLastCommitBitmap(newLastCommitBitmap []byte) {
h.fields.LastCommitBitmap = append(newLastCommitBitmap[:0:0], newLastCommitBitmap...)
}
// ShardStateHash is the shard state hash.
func (h *Header) ShardStateHash() common.Hash {
return h.fields.ShardStateHash
}
// SetShardStateHash sets the shard state hash.
func (h *Header) SetShardStateHash(newShardStateHash common.Hash) {
h.fields.ShardStateHash = newShardStateHash
}
// Vrf is the output of the VRF for the epoch.
//
// The returned slice is a copy; the caller may do anything with it.
func (h *Header) Vrf() []byte {
return nil
}
// SetVrf sets the output of the VRF for the epoch.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetVrf(newVrf []byte) {
if len(newVrf) > 0 {
h.Logger(utils.Logger()).Warn().
Hex("vrf", newVrf).
Msg("non-empty VRF provided but cannot be stored")
}
}
// Vdf is the output of the VDF for the epoch.
//
// The returned slice is a copy; the caller may do anything with it.
func (h *Header) Vdf() []byte {
return nil
}
// SetVdf sets the output of the VDF for the epoch.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetVdf(newVdf []byte) {
if len(newVdf) > 0 {
h.Logger(utils.Logger()).Warn().
Hex("vdf", newVdf).
Msg("non-empty VDF provided but cannot be stored")
}
}
// ShardState is the RLP-encoded form of shard state (list of committees) for
// the next epoch.
//
// The returned slice is a copy; the caller may do anything with it.
func (h *Header) ShardState() []byte {
return append(h.fields.ShardState[:0:0], h.fields.ShardState...)
}
// SetShardState sets the RLP-encoded form of shard state
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetShardState(newShardState []byte) {
h.fields.ShardState = append(newShardState[:0:0], newShardState...)
}
// CrossLinks is the RLP-encoded form of non-beacon block headers chosen to be
// canonical by the beacon committee. This field is present only on beacon
// chain block headers.
//
// The returned slice is a copy; the caller may do anything with it.
func (h *Header) CrossLinks() []byte {
return nil
}
// SetCrossLinks sets the RLP-encoded form of non-beacon block headers chosen to
// be canonical by the beacon committee.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetCrossLinks(newCrossLinks []byte) {
if len(newCrossLinks) > 0 {
h.Logger(utils.Logger()).Warn().
Hex("crossLinks", newCrossLinks).
Msg("non-empty cross-chain links provided but cannot be stored")
}
}
// field type overrides for gencodec
type headerMarshaling struct {
Difficulty *hexutil.Big
Number *hexutil.Big
GasLimit hexutil.Uint64
GasUsed hexutil.Uint64
Time *hexutil.Big
Extra hexutil.Bytes
Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON
}
// Hash returns the block hash of the header, which is simply the keccak256 hash of its
// RLP encoding.
func (h *Header) Hash() common.Hash {
return hash.FromRLP(h)
}
// 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 {
// 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.
func (h *Header) Logger(logger *zerolog.Logger) *zerolog.Logger {
nlogger := logger.
With().
Str("blockHash", h.Hash().Hex()).
Uint32("blockShard", h.ShardID()).
Uint64("blockEpoch", h.Epoch().Uint64()).
Uint64("blockNumber", h.Number().Uint64()).
Logger()
return &nlogger
}
// GetShardState returns the deserialized shard state object.
func (h *Header) GetShardState() (shard.State, error) {
shardState := shard.State{}
err := rlp.DecodeBytes(h.ShardState(), &shardState)
if err != nil {
return nil, err
}
return shardState, nil
}
// Copy returns a copy of the given header.
func (h *Header) Copy() blockif.Header {
cpy := *h
return &cpy
}

@ -0,0 +1,117 @@
// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
package v1
import (
"encoding/json"
"errors"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
ethtypes "github.com/ethereum/go-ethereum/core/types"
)
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"`
Root common.Hash `json:"stateRoot" gencodec:"required"`
TxHash common.Hash `json:"transactionsRoot" gencodec:"required"`
ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"`
Bloom ethtypes.Bloom `json:"logsBloom" 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"`
Hash common.Hash `json:"hash"`
}
var enc Header
enc.ParentHash = h.ParentHash()
enc.Coinbase = h.Coinbase()
enc.Root = h.Root()
enc.TxHash = h.TxHash()
enc.ReceiptHash = h.ReceiptHash()
enc.Bloom = h.Bloom()
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.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"`
Root *common.Hash `json:"stateRoot" gencodec:"required"`
TxHash *common.Hash `json:"transactionsRoot" gencodec:"required"`
ReceiptHash *common.Hash `json:"receiptsRoot" gencodec:"required"`
Bloom *ethtypes.Bloom `json:"logsBloom" 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"`
}
var dec Header
if err := json.Unmarshal(input, &dec); err != nil {
return err
}
if dec.ParentHash == nil {
return errors.New("missing required field 'parentHash' for Header")
}
h.SetParentHash(*dec.ParentHash)
if dec.Coinbase == nil {
return errors.New("missing required field 'miner' for Header")
}
h.SetCoinbase(*dec.Coinbase)
if dec.Root == nil {
return errors.New("missing required field 'stateRoot' for Header")
}
h.SetRoot(*dec.Root)
if dec.TxHash == nil {
return errors.New("missing required field 'transactionsRoot' for Header")
}
h.SetTxHash(*dec.TxHash)
if dec.ReceiptHash == nil {
return errors.New("missing required field 'receiptsRoot' for Header")
}
h.SetReceiptHash(*dec.ReceiptHash)
if dec.Bloom == nil {
return errors.New("missing required field 'logsBloom' for Header")
}
h.SetBloom(*dec.Bloom)
h.SetNumber((*big.Int)(dec.Number))
if dec.GasLimit == nil {
return errors.New("missing required field 'gasLimit' for Header")
}
h.SetGasLimit(uint64(*dec.GasLimit))
if dec.GasUsed == nil {
return errors.New("missing required field 'gasUsed' for Header")
}
h.SetGasUsed(uint64(*dec.GasUsed))
if dec.Time == nil {
return errors.New("missing required field 'timestamp' for Header")
}
h.SetTime((*big.Int)(dec.Time))
if dec.Extra == nil {
return errors.New("missing required field 'extraData' for Header")
}
h.SetExtra(*dec.Extra)
if dec.MixDigest == nil {
return errors.New("missing required field 'mixHash' for Header")
}
h.SetMixDigest(*dec.MixDigest)
return nil
}

@ -0,0 +1,417 @@
package v1
import (
"io"
"math/big"
"unsafe"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
"github.com/rs/zerolog"
blockif "github.com/harmony-one/harmony/block/interface"
"github.com/harmony-one/harmony/crypto/hash"
"github.com/harmony-one/harmony/shard"
)
// Header is the V1 block header.
type Header struct {
fields headerFields
}
// EncodeRLP encodes the header fields into RLP format.
func (h *Header) EncodeRLP(w io.Writer) error {
return rlp.Encode(w, &h.fields)
}
// DecodeRLP decodes the given RLP decode stream into the header fields.
func (h *Header) DecodeRLP(s *rlp.Stream) error {
return s.Decode(&h.fields)
}
// NewHeader creates a new header object.
func NewHeader() *Header {
return &Header{headerFields{
Number: new(big.Int),
Time: new(big.Int),
ViewID: new(big.Int),
Epoch: new(big.Int),
}}
}
type headerFields struct {
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
Coinbase common.Address `json:"miner" gencodec:"required"`
Root common.Hash `json:"stateRoot" gencodec:"required"`
TxHash common.Hash `json:"transactionsRoot" gencodec:"required"`
ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"`
OutgoingReceiptHash common.Hash `json:"outgoingReceiptsRoot" gencodec:"required"`
IncomingReceiptHash common.Hash `json:"incomingReceiptsRoot" gencodec:"required"`
Bloom ethtypes.Bloom `json:"logsBloom" 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"`
// Additional Fields
ViewID *big.Int `json:"viewID" gencodec:"required"`
Epoch *big.Int `json:"epoch" gencodec:"required"`
ShardID uint32 `json:"shardID" gencodec:"required"`
LastCommitSignature [96]byte `json:"lastCommitSignature" gencodec:"required"`
LastCommitBitmap []byte `json:"lastCommitBitmap" gencodec:"required"` // Contains which validator signed
ShardStateHash common.Hash `json:"shardStateRoot"`
Vrf []byte `json:"vrf"`
Vdf []byte `json:"vdf"`
ShardState []byte `json:"shardState"`
CrossLinks []byte `json:"crossLink"`
}
// ParentHash is the header hash of the parent block. For the genesis block
// which has no parent by definition, this field is zeroed out.
func (h *Header) ParentHash() common.Hash {
return h.fields.ParentHash
}
// SetParentHash sets the parent hash field.
func (h *Header) SetParentHash(newParentHash common.Hash) {
h.fields.ParentHash = newParentHash
}
// Coinbase is the address of the node that proposed this block and all
// transactions in it.
func (h *Header) Coinbase() common.Address {
return h.fields.Coinbase
}
// SetCoinbase sets the coinbase address field.
func (h *Header) SetCoinbase(newCoinbase common.Address) {
h.fields.Coinbase = newCoinbase
}
// Root is the state (account) trie root hash.
func (h *Header) Root() common.Hash {
return h.fields.Root
}
// SetRoot sets the state trie root hash field.
func (h *Header) SetRoot(newRoot common.Hash) {
h.fields.Root = newRoot
}
// TxHash is the transaction trie root hash.
func (h *Header) TxHash() common.Hash {
return h.fields.TxHash
}
// SetTxHash sets the transaction trie root hash field.
func (h *Header) SetTxHash(newTxHash common.Hash) {
h.fields.TxHash = newTxHash
}
// ReceiptHash is the same-shard transaction receipt trie hash.
func (h *Header) ReceiptHash() common.Hash {
return h.fields.ReceiptHash
}
// SetReceiptHash sets the same-shard transaction receipt trie hash.
func (h *Header) SetReceiptHash(newReceiptHash common.Hash) {
h.fields.ReceiptHash = newReceiptHash
}
// OutgoingReceiptHash is the egress transaction receipt trie hash.
func (h *Header) OutgoingReceiptHash() common.Hash {
return h.fields.OutgoingReceiptHash
}
// SetOutgoingReceiptHash sets the egress transaction receipt trie hash.
func (h *Header) SetOutgoingReceiptHash(newOutgoingReceiptHash common.Hash) {
h.fields.OutgoingReceiptHash = newOutgoingReceiptHash
}
// IncomingReceiptHash is the ingress transaction receipt trie hash.
func (h *Header) IncomingReceiptHash() common.Hash {
return h.fields.IncomingReceiptHash
}
// SetIncomingReceiptHash sets the ingress transaction receipt trie hash.
func (h *Header) SetIncomingReceiptHash(newIncomingReceiptHash common.Hash) {
h.fields.IncomingReceiptHash = newIncomingReceiptHash
}
// Bloom is the Bloom filter that indexes accounts and topics logged by smart
// contract transactions (executions) in this block.
func (h *Header) Bloom() ethtypes.Bloom {
return h.fields.Bloom
}
// SetBloom sets the smart contract log Bloom filter for this block.
func (h *Header) SetBloom(newBloom ethtypes.Bloom) {
h.fields.Bloom = newBloom
}
// Number is the block number.
//
// The returned instance is a copy; the caller may do anything with it.
func (h *Header) Number() *big.Int {
return new(big.Int).Set(h.fields.Number)
}
// SetNumber sets the block number.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetNumber(newNumber *big.Int) {
h.fields.Number = new(big.Int).Set(newNumber)
}
// GasLimit is the gas limit for transactions in this block.
func (h *Header) GasLimit() uint64 {
return h.fields.GasLimit
}
// SetGasLimit sets the gas limit for transactions in this block.
func (h *Header) SetGasLimit(newGasLimit uint64) {
h.fields.GasLimit = newGasLimit
}
// GasUsed is the amount of gas used by transactions in this block.
func (h *Header) GasUsed() uint64 {
return h.fields.GasUsed
}
// SetGasUsed sets the amount of gas used by transactions in this block.
func (h *Header) SetGasUsed(newGasUsed uint64) {
h.fields.GasUsed = newGasUsed
}
// Time is the UNIX timestamp of this block.
//
// The returned instance is a copy; the caller may do anything with it.
func (h *Header) Time() *big.Int {
return new(big.Int).Set(h.fields.Time)
}
// SetTime sets the UNIX timestamp of this block.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetTime(newTime *big.Int) {
h.fields.Time = new(big.Int).Set(newTime)
}
// Extra is the extra data field of this block.
//
// The returned slice is a copy; the caller may do anything with it.
func (h *Header) Extra() []byte {
return append(h.fields.Extra[:0:0], h.fields.Extra...)
}
// SetExtra sets the extra data field of this block.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetExtra(newExtra []byte) {
h.fields.Extra = append(newExtra[:0:0], newExtra...)
}
// MixDigest is the mixhash.
//
// This field is a remnant from Ethereum, and Harmony does not use it and always
// zeroes it out.
func (h *Header) MixDigest() common.Hash {
return h.fields.MixDigest
}
// SetMixDigest sets the mixhash of this block.
func (h *Header) SetMixDigest(newMixDigest common.Hash) {
h.fields.MixDigest = newMixDigest
}
// ViewID is the ID of the view in which this block was originally proposed.
//
// It normally increases by one for each subsequent block, or by more than one
// if one or more PBFT/FBFT view changes have occurred.
//
// The returned instance is a copy; the caller may do anything with it.
func (h *Header) ViewID() *big.Int {
return new(big.Int).Set(h.fields.ViewID)
}
// SetViewID sets the view ID in which the block was originally proposed.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetViewID(newViewID *big.Int) {
h.fields.ViewID = new(big.Int).Set(newViewID)
}
// Epoch is the epoch number of this block.
//
// The returned instance is a copy; the caller may do anything with it.
func (h *Header) Epoch() *big.Int {
return new(big.Int).Set(h.fields.Epoch)
}
// SetEpoch sets the epoch number of this block.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetEpoch(newEpoch *big.Int) {
h.fields.Epoch = new(big.Int).Set(newEpoch)
}
// ShardID is the shard ID to which this block belongs.
func (h *Header) ShardID() uint32 {
return h.fields.ShardID
}
// SetShardID sets the shard ID to which this block belongs.
func (h *Header) SetShardID(newShardID uint32) {
h.fields.ShardID = newShardID
}
// LastCommitSignature is the FBFT commit group signature for the last block.
func (h *Header) LastCommitSignature() [96]byte {
return h.fields.LastCommitSignature
}
// SetLastCommitSignature sets the FBFT commit group signature for the last
// block.
func (h *Header) SetLastCommitSignature(newLastCommitSignature [96]byte) {
h.fields.LastCommitSignature = newLastCommitSignature
}
// LastCommitBitmap is the signatory bitmap of the previous block. Bit
// positions index into committee member array.
//
// The returned slice is a copy; the caller may do anything with it.
func (h *Header) LastCommitBitmap() []byte {
return append(h.fields.LastCommitBitmap[:0:0], h.fields.LastCommitBitmap...)
}
// SetLastCommitBitmap sets the signatory bitmap of the previous block.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetLastCommitBitmap(newLastCommitBitmap []byte) {
h.fields.LastCommitBitmap = append(newLastCommitBitmap[:0:0], newLastCommitBitmap...)
}
// ShardStateHash is the shard state hash.
func (h *Header) ShardStateHash() common.Hash {
return h.fields.ShardStateHash
}
// SetShardStateHash sets the shard state hash.
func (h *Header) SetShardStateHash(newShardStateHash common.Hash) {
h.fields.ShardStateHash = newShardStateHash
}
// Vrf is the output of the VRF for the epoch.
//
// The returned slice is a copy; the caller may do anything with it.
func (h *Header) Vrf() []byte {
return append(h.fields.Vrf[:0:0], h.fields.Vrf...)
}
// SetVrf sets the output of the VRF for the epoch.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetVrf(newVrf []byte) {
h.fields.Vrf = append(newVrf[:0:0], newVrf...)
}
// Vdf is the output of the VDF for the epoch.
//
// The returned slice is a copy; the caller may do anything with it.
func (h *Header) Vdf() []byte {
return append(h.fields.Vdf[:0:0], h.fields.Vdf...)
}
// SetVdf sets the output of the VDF for the epoch.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetVdf(newVdf []byte) {
h.fields.Vdf = append(newVdf[:0:0], newVdf...)
}
// ShardState is the RLP-encoded form of shard state (list of committees) for
// the next epoch.
//
// The returned slice is a copy; the caller may do anything with it.
func (h *Header) ShardState() []byte {
return append(h.fields.ShardState[:0:0], h.fields.ShardState...)
}
// SetShardState sets the RLP-encoded form of shard state
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetShardState(newShardState []byte) {
h.fields.ShardState = append(newShardState[:0:0], newShardState...)
}
// CrossLinks is the RLP-encoded form of non-beacon block headers chosen to be
// canonical by the beacon committee. This field is present only on beacon
// chain block headers.
//
// The returned slice is a copy; the caller may do anything with it.
func (h *Header) CrossLinks() []byte {
return append(h.fields.CrossLinks[:0:0], h.fields.CrossLinks...)
}
// SetCrossLinks sets the RLP-encoded form of non-beacon block headers chosen to
// be canonical by the beacon committee.
//
// It stores a copy; the caller may freely modify the original.
func (h *Header) SetCrossLinks(newCrossLinks []byte) {
h.fields.CrossLinks = append(newCrossLinks[:0:0], newCrossLinks...)
}
// field type overrides for gencodec
type headerMarshaling struct {
Difficulty *hexutil.Big
Number *hexutil.Big
GasLimit hexutil.Uint64
GasUsed hexutil.Uint64
Time *hexutil.Big
Extra hexutil.Bytes
Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON
}
// Hash returns the block hash of the header, which is simply the keccak256 hash of its
// RLP encoding.
func (h *Header) Hash() common.Hash {
return hash.FromRLP(h)
}
// 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 {
// 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.
func (h *Header) Logger(logger *zerolog.Logger) *zerolog.Logger {
nlogger := logger.
With().
Str("blockHash", h.Hash().Hex()).
Uint32("blockShard", h.ShardID()).
Uint64("blockEpoch", h.Epoch().Uint64()).
Uint64("blockNumber", h.Number().Uint64()).
Logger()
return &nlogger
}
// GetShardState returns the deserialized shard state object.
func (h *Header) GetShardState() (shard.State, error) {
shardState := shard.State{}
err := rlp.DecodeBytes(h.ShardState(), &shardState)
if err != nil {
return nil, err
}
return shardState, nil
}
// Copy returns a copy of the given header.
func (h *Header) Copy() blockif.Header {
cpy := *h
return &cpy
}

@ -183,9 +183,9 @@ func (consensus *Consensus) onAnnounce(msg *msg_pb.Message) {
}
// verify validity of block header object
blockHeader := recvMsg.Payload
headerObj := block.NewHeader()
err = rlp.DecodeBytes(blockHeader, headerObj)
encodedHeader := recvMsg.Payload
header := new(block.Header)
err = rlp.DecodeBytes(encodedHeader, header)
if err != nil {
consensus.getLogger().Warn().
Err(err).
@ -194,36 +194,36 @@ func (consensus *Consensus) onAnnounce(msg *msg_pb.Message) {
return
}
if recvMsg.BlockNum < consensus.blockNum || recvMsg.BlockNum != headerObj.Number().Uint64() {
if recvMsg.BlockNum < consensus.blockNum || recvMsg.BlockNum != header.Number().Uint64() {
consensus.getLogger().Debug().
Uint64("MsgBlockNum", recvMsg.BlockNum).
Uint64("blockNum", consensus.blockNum).
Uint64("hdrBlockNum", headerObj.Number().Uint64()).
Uint64("hdrBlockNum", header.Number().Uint64()).
Msg("[OnAnnounce] BlockNum does not match")
return
}
if consensus.mode.Mode() == Normal {
if err = chain.Engine.VerifyHeader(consensus.ChainReader, headerObj, true); err != nil {
if err = chain.Engine.VerifyHeader(consensus.ChainReader, header, true); err != nil {
consensus.getLogger().Warn().
Err(err).
Str("inChain", consensus.ChainReader.CurrentHeader().Number().String()).
Str("MsgBlockNum", headerObj.Number().String()).
Str("MsgBlockNum", header.Number().String()).
Msg("[OnAnnounce] Block content is not verified successfully")
return
}
//VRF/VDF is only generated in the beach chain
if consensus.NeedsRandomNumberGeneration(headerObj.Epoch()) {
if consensus.NeedsRandomNumberGeneration(header.Epoch()) {
//validate the VRF with proof if a non zero VRF is found in header
if len(headerObj.Vrf()) > 0 {
if !consensus.ValidateVrfAndProof(headerObj) {
if len(header.Vrf()) > 0 {
if !consensus.ValidateVrfAndProof(header) {
return
}
}
//validate the VDF with proof if a non zero VDF is found in header
if len(headerObj.Vdf()) > 0 {
if !consensus.ValidateVdfAndProof(headerObj) {
if len(header.Vdf()) > 0 {
if !consensus.ValidateVdfAndProof(header) {
return
}
}

@ -22,6 +22,8 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethdb"
blockfactory "github.com/harmony-one/harmony/block/factory"
"github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/block"
@ -38,6 +40,7 @@ type BlockGen struct {
i int
parent *types.Block
chain []*types.Block
factory blockfactory.Factory
header *block.Header
statedb *state.DB
@ -167,11 +170,12 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
if config == nil {
config = params.TestChainConfig
}
factory := blockfactory.NewFactory(config)
blocks, receipts := make(types.Blocks, n), make([]types.Receipts, n)
chainreader := &fakeChainReader{config: config}
genblock := func(i int, parent *types.Block, statedb *state.DB) (*types.Block, types.Receipts) {
b := &BlockGen{i: i, chain: blocks, parent: parent, statedb: statedb, config: config, engine: engine}
b.header = makeHeader(chainreader, parent, statedb, b.engine)
b := &BlockGen{i: i, chain: blocks, parent: parent, statedb: statedb, config: config, factory: factory, engine: engine}
b.header = makeHeader(chainreader, parent, statedb, b.engine, factory)
//if config.DAOForkSupport && config.DAOForkBlock != nil && config.DAOForkBlock.Cmp(b.header.Number) == 0 {
// misc.ApplyDAOHardFork(statedb)
@ -212,7 +216,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
return blocks, receipts
}
func makeHeader(chain consensus_engine.ChainReader, parent *types.Block, state *state.DB, engine consensus_engine.Engine) *block.Header {
func makeHeader(chain consensus_engine.ChainReader, parent *types.Block, state *state.DB, engine consensus_engine.Engine, factory blockfactory.Factory) *block.Header {
var time *big.Int
if parent.Time() == nil {
time = big.NewInt(10)
@ -220,13 +224,12 @@ func makeHeader(chain consensus_engine.ChainReader, parent *types.Block, state *
time = new(big.Int).Add(parent.Time(), big.NewInt(10)) // block time is fixed at 10 seconds
}
return block.NewHeaderWith().
return factory.NewHeader(parent.Epoch()).With().
Root(state.IntermediateRoot(chain.Config().IsS3(parent.Epoch()))).
ParentHash(parent.Hash()).
Coinbase(parent.Coinbase()).
GasLimit(CalcGasLimit(parent, parent.GasLimit(), parent.GasLimit())).
Number(new(big.Int).Add(parent.Number(), common.Big1)).
Epoch(parent.Epoch()).
Time(time).
Header()
}

@ -4,19 +4,19 @@ import (
"math/big"
"testing"
"github.com/harmony-one/harmony/block"
blockfactory "github.com/harmony-one/harmony/block/factory"
"github.com/harmony-one/harmony/core/types"
shardingconfig "github.com/harmony-one/harmony/internal/configs/sharding"
)
func TestIsEpochBlock(t *testing.T) {
block1 := types.NewBlock(block.NewHeaderWith().Number(big.NewInt(10)).Header(), nil, nil, nil, nil)
block2 := types.NewBlock(block.NewHeaderWith().Number(big.NewInt(0)).Header(), nil, nil, nil, nil)
block3 := types.NewBlock(block.NewHeaderWith().Number(big.NewInt(344064)).Header(), nil, nil, nil, nil)
block4 := types.NewBlock(block.NewHeaderWith().Number(big.NewInt(77)).Header(), nil, nil, nil, nil)
block5 := types.NewBlock(block.NewHeaderWith().Number(big.NewInt(78)).Header(), nil, nil, nil, nil)
block6 := types.NewBlock(block.NewHeaderWith().Number(big.NewInt(188)).Header(), nil, nil, nil, nil)
block7 := types.NewBlock(block.NewHeaderWith().Number(big.NewInt(189)).Header(), nil, nil, nil, nil)
block1 := types.NewBlock(blockfactory.NewTestHeader().With().Number(big.NewInt(10)).Header(), nil, nil, nil, nil)
block2 := types.NewBlock(blockfactory.NewTestHeader().With().Number(big.NewInt(0)).Header(), nil, nil, nil, nil)
block3 := types.NewBlock(blockfactory.NewTestHeader().With().Number(big.NewInt(344064)).Header(), nil, nil, nil, nil)
block4 := types.NewBlock(blockfactory.NewTestHeader().With().Number(big.NewInt(77)).Header(), nil, nil, nil, nil)
block5 := types.NewBlock(blockfactory.NewTestHeader().With().Number(big.NewInt(78)).Header(), nil, nil, nil, nil)
block6 := types.NewBlock(blockfactory.NewTestHeader().With().Number(big.NewInt(188)).Header(), nil, nil, nil, nil)
block7 := types.NewBlock(blockfactory.NewTestHeader().With().Number(big.NewInt(189)).Header(), nil, nil, nil, nil)
tests := []struct {
schedule shardingconfig.Schedule
block *types.Block

@ -30,9 +30,10 @@ import (
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/rlp"
blockfactory "github.com/harmony-one/harmony/block/factory"
"github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/block"
"github.com/harmony-one/harmony/core/rawdb"
"github.com/harmony-one/harmony/core/state"
"github.com/harmony-one/harmony/core/types"
@ -48,17 +49,18 @@ var errGenesisNoConfig = errors.New("genesis has no chain configuration")
// Genesis specifies the header fields, state of a genesis block. It also defines hard
// fork switch-over blocks through the chain configuration.
type Genesis struct {
Config *params.ChainConfig `json:"config"`
Nonce uint64 `json:"nonce"`
ShardID uint32 `json:"shardID"`
Timestamp uint64 `json:"timestamp"`
ExtraData []byte `json:"extraData"`
GasLimit uint64 `json:"gasLimit" gencodec:"required"`
Mixhash common.Hash `json:"mixHash"`
Coinbase common.Address `json:"coinbase"`
Alloc GenesisAlloc `json:"alloc" gencodec:"required"`
ShardStateHash common.Hash `json:"shardStateHash" gencodec:"required"`
ShardState shard.State `json:"shardState" gencodec:"required"`
Config *params.ChainConfig `json:"config"`
Factory blockfactory.Factory `json:"-"`
Nonce uint64 `json:"nonce"`
ShardID uint32 `json:"shardID"`
Timestamp uint64 `json:"timestamp"`
ExtraData []byte `json:"extraData"`
GasLimit uint64 `json:"gasLimit" gencodec:"required"`
Mixhash common.Hash `json:"mixHash"`
Coinbase common.Address `json:"coinbase"`
Alloc GenesisAlloc `json:"alloc" gencodec:"required"`
ShardStateHash common.Hash `json:"shardStateHash" gencodec:"required"`
ShardState shard.State `json:"shardState" gencodec:"required"`
// These fields are used for consensus tests. Please don't use them
// in actual genesis blocks.
@ -247,9 +249,8 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
utils.Logger().Error().Msg("failed to rlp-serialize genesis shard state")
os.Exit(1)
}
head := block.NewHeaderWith().
head := g.Factory.NewHeader(common.Big0).With().
Number(new(big.Int).SetUint64(g.Number)).
Epoch(big.NewInt(0)).
ShardID(g.ShardID).
Time(new(big.Int).SetUint64(g.Timestamp)).
ParentHash(g.ParentHash).
@ -316,6 +317,7 @@ func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big
func DefaultGenesisBlock() *Genesis {
return &Genesis{
Config: params.MainnetChainConfig,
Factory: blockfactory.ForMainnet,
Nonce: 66,
ExtraData: hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"),
GasLimit: 5000,

@ -31,6 +31,7 @@ import (
"golang.org/x/crypto/sha3"
"github.com/harmony-one/harmony/block"
blockfactory "github.com/harmony-one/harmony/block/factory"
mock "github.com/harmony-one/harmony/core/rawdb/mock"
"github.com/harmony-one/harmony/core/types"
)
@ -40,7 +41,7 @@ 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 := block.NewHeaderWith().Number(big.NewInt(42)).Extra([]byte("test header")).Header()
header := blockfactory.NewTestHeader().With().Number(big.NewInt(42)).Extra([]byte("test header")).Header()
if entry := ReadHeader(db, header.Hash(), header.Number().Uint64()); entry != nil {
t.Fatalf("Non existent header returned: %v", entry)
}
@ -73,7 +74,7 @@ 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: []*block.Header{block.NewHeaderWith().Extra([]byte("test header")).Header()}}
body := &types.Body{Uncles: []*block.Header{blockfactory.NewTestHeader().With().Extra([]byte("test header")).Header()}}
hasher := sha3.NewLegacyKeccak256()
rlp.Encode(hasher, body)
@ -111,11 +112,10 @@ 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(block.NewHeaderWith().
block := types.NewBlockWithHeader(blockfactory.NewTestHeader().With().
Extra([]byte("test block")).
TxHash(types.EmptyRootHash).
ReceiptHash(types.EmptyRootHash).
Epoch(big.NewInt(0)).
Number(big.NewInt(0)).
ShardState([]byte("dummy data")).
Header())
@ -171,7 +171,7 @@ func TestBlockStorage(t *testing.T) {
// Tests that partial block contents don't get reassembled into full blocks.
func TestPartialBlockStorage(t *testing.T) {
db := ethdb.NewMemDatabase()
block := types.NewBlockWithHeader(block.NewHeaderWith().
block := types.NewBlockWithHeader(blockfactory.NewTestHeader().With().
Extra([]byte("test block")).
TxHash(types.EmptyRootHash).
ReceiptHash(types.EmptyRootHash).
@ -251,9 +251,9 @@ func TestCanonicalMappingStorage(t *testing.T) {
func TestHeadStorage(t *testing.T) {
db := ethdb.NewMemDatabase()
blockHead := types.NewBlockWithHeader(block.NewHeaderWith().Extra([]byte("test block header")).Header())
blockFull := types.NewBlockWithHeader(block.NewHeaderWith().Extra([]byte("test block full")).Header())
blockFast := types.NewBlockWithHeader(block.NewHeaderWith().Extra([]byte("test block fast")).Header())
blockHead := types.NewBlockWithHeader(blockfactory.NewTestHeader().With().Extra([]byte("test block header")).Header())
blockFull := types.NewBlockWithHeader(blockfactory.NewTestHeader().With().Extra([]byte("test block full")).Header())
blockFast := types.NewBlockWithHeader(blockfactory.NewTestHeader().With().Extra([]byte("test block fast")).Header())
// Check that no head entries are in a pristine database
if entry := ReadHeadHeaderHash(db); entry != (common.Hash{}) {

@ -23,7 +23,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethdb"
block2 "github.com/harmony-one/harmony/block"
blockfactory "github.com/harmony-one/harmony/block/factory"
"github.com/harmony-one/harmony/core/types"
)
@ -36,7 +36,7 @@ func TestLookupStorage(t *testing.T) {
tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), 0, big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33})
txs := []*types.Transaction{tx1, tx2, tx3}
block := types.NewBlock(block2.NewHeaderWith().Number(big.NewInt(314)).Header(), txs, nil, nil, nil)
block := types.NewBlock(blockfactory.NewTestHeader().With().Number(big.NewInt(314)).Header(), txs, nil, nil, nil)
// Check that no transactions entries are in a pristine database
for i, tx := range txs {

@ -31,7 +31,7 @@ import (
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/harmony-one/harmony/block"
blockfactory "github.com/harmony-one/harmony/block/factory"
"github.com/harmony-one/harmony/common/denominations"
"github.com/harmony-one/harmony/core/state"
"github.com/harmony-one/harmony/core/types"
@ -54,7 +54,7 @@ type testBlockChain struct {
}
func (bc *testBlockChain) CurrentBlock() *types.Block {
return types.NewBlock(block.NewHeaderWith().
return types.NewBlock(blockfactory.NewTestHeader().With().
GasLimit(bc.gasLimit).
Header(), nil, nil, nil, nil)
}

@ -195,11 +195,7 @@ func NewBlockWithHeader(header *block.Header) *Block {
// TODO ek – no longer necessary
func CopyHeader(h *block.Header) *block.Header {
cpy := *h
// A field value object that lives outside of a header struct is never
// exposed to the outside for external modification, as its getter and
// setter always make a copy. Therefore, we do not have to clone such
// fields, and multiple header structs can safely share the same field value
// objects.
cpy.Header = cpy.Header.Copy()
return &cpy
}

@ -21,7 +21,7 @@ import (
"bytes"
"testing"
"github.com/harmony-one/harmony/block"
blockfactory "github.com/harmony-one/harmony/block/factory"
)
var (
@ -96,7 +96,7 @@ func TestBlock_SetLastCommitSig(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
b := &Block{header: block.NewHeader()}
b := &Block{header: blockfactory.NewTestHeader()}
b.SetLastCommitSig(tt.sig, tt.signers)
sig := b.header.LastCommitSignature()
if !bytes.Equal(tt.sig, sig[:]) {

@ -8,7 +8,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/bls/ffi/go/bls"
block2 "github.com/harmony-one/harmony/block"
blockfactory "github.com/harmony-one/harmony/block/factory"
bls2 "github.com/harmony-one/harmony/crypto/bls"
msg_pb "github.com/harmony-one/harmony/api/proto/message"
@ -128,7 +128,7 @@ func TestVrf(test *testing.T) {
tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), 0, big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11})
txs := []*types.Transaction{tx1}
block := types.NewBlock(block2.NewHeaderWith().Number(big.NewInt(314)).Header(), txs, nil, nil, nil)
block := types.NewBlock(blockfactory.NewTestHeader().With().Number(big.NewInt(314)).Header(), txs, nil, nil, nil)
blockHash := block.Hash()
dRand.vrf(blockHash)

@ -23,6 +23,7 @@ require (
github.com/gorilla/mux v1.7.2
github.com/harmony-ek/gencodec v0.0.0-20190215044613-e6740dbdd846
github.com/harmony-one/bls v0.0.5
github.com/harmony-one/taggedrlp v0.1.2
github.com/harmony-one/vdf v1.0.0
github.com/hashicorp/golang-lru v0.5.1
github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365
@ -61,7 +62,7 @@ require (
golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443
golang.org/x/lint v0.0.0-20190409202823-959b441ac422
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3 // indirect
golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd
golang.org/x/tools v0.0.0-20190827205025-b29f5f60c37a
google.golang.org/appengine v1.4.0 // indirect
google.golang.org/grpc v1.21.1
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127

@ -12,6 +12,7 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
blockfactory "github.com/harmony-one/harmony/block/factory"
"github.com/harmony-one/harmony/common/denominations"
"github.com/harmony-one/harmony/core"
common2 "github.com/harmony-one/harmony/internal/common"
@ -90,6 +91,7 @@ func (node *Node) SetupGenesisBlock(db ethdb.Database, shardID uint32, myShardSt
gspec := core.Genesis{
Config: &chainConfig,
Factory: blockfactory.NewFactory(&chainConfig),
Alloc: genesisAlloc,
ShardID: shardID,
GasLimit: params.GenesisGasLimit,

@ -5,11 +5,13 @@ import (
"math/big"
"time"
blockfactory "github.com/harmony-one/harmony/block/factory"
"github.com/harmony-one/harmony/shard"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/block"
@ -40,6 +42,7 @@ type environment struct {
// and gathering the sealing result.
type Worker struct {
config *params.ChainConfig
factory blockfactory.Factory
chain *core.BlockChain
current *environment // An environment for current running cycle.
@ -234,12 +237,11 @@ func (w *Worker) UpdateCurrent(coinbase common.Address) error {
// ... except if parent has a resharding assignment it increases by 1.
epoch = epoch.Add(epoch, common.Big1)
}
header := block.NewHeaderWith().
header := w.factory.NewHeader(epoch).With().
ParentHash(parent.Hash()).
Number(num.Add(num, common.Big1)).
GasLimit(core.CalcGasLimit(parent, w.gasFloor, w.gasCeil)).
Time(big.NewInt(timestamp)).
Epoch(epoch).
ShardID(w.chain.ShardID()).
Coinbase(coinbase).
Header()
@ -341,9 +343,10 @@ func (w *Worker) FinalizeNewBlock(sig []byte, signers []byte, viewID uint64, coi
// New create a new worker object.
func New(config *params.ChainConfig, chain *core.BlockChain, engine consensus_engine.Engine, shardID uint32) *Worker {
worker := &Worker{
config: config,
chain: chain,
engine: engine,
config: config,
factory: blockfactory.NewFactory(config),
chain: chain,
engine: engine,
}
worker.gasFloor = 500000000000000000
worker.gasCeil = 1000000000000000000
@ -360,12 +363,11 @@ func New(config *params.ChainConfig, chain *core.BlockChain, engine consensus_en
// ... except if parent has a resharding assignment it increases by 1.
epoch = epoch.Add(epoch, common.Big1)
}
header := block.NewHeaderWith().
header := worker.factory.NewHeader(epoch).With().
ParentHash(parent.Hash()).
Number(num.Add(num, common.Big1)).
GasLimit(core.CalcGasLimit(parent, worker.gasFloor, worker.gasCeil)).
Time(big.NewInt(timestamp)).
Epoch(epoch).
ShardID(worker.chain.ShardID()).
Header()
worker.makeCurrent(parent, header)

@ -5,6 +5,7 @@ import (
"math/rand"
"testing"
blockfactory "github.com/harmony-one/harmony/block/factory"
chain2 "github.com/harmony-one/harmony/internal/chain"
"github.com/ethereum/go-ethereum/crypto"
@ -22,7 +23,8 @@ var (
testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey)
testBankFunds = big.NewInt(8000000000000000000)
chainConfig = params.TestChainConfig
chainConfig = params.TestChainConfig
blockFactory = blockfactory.ForTest
)
func TestNewWorker(t *testing.T) {
@ -31,6 +33,7 @@ func TestNewWorker(t *testing.T) {
database = ethdb.NewMemDatabase()
gspec = core.Genesis{
Config: chainConfig,
Factory: blockFactory,
Alloc: core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}},
ShardID: 10,
}
@ -54,6 +57,7 @@ func TestCommitTransactions(t *testing.T) {
database = ethdb.NewMemDatabase()
gspec = core.Genesis{
Config: chainConfig,
Factory: blockFactory,
Alloc: core.GenesisAlloc{testBankAddress: {Balance: testBankFunds}},
ShardID: 0,
}

@ -9,6 +9,7 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/common"
blockfactory "github.com/harmony-one/harmony/block/factory"
"github.com/harmony-one/harmony/crypto/hash"
"github.com/ethereum/go-ethereum/ethdb"
@ -38,7 +39,8 @@ var (
testUserKey, _ = crypto.GenerateKey()
testUserAddress = crypto.PubkeyToAddress(testUserKey.PublicKey)
chainConfig = params.TestChainConfig
chainConfig = params.TestChainConfig
blockFactory = blockfactory.ForTest
//StakingPriKey is the keys for the deposit contract.
StakingPriKey, _ = crypto.GenerateKey()
@ -52,6 +54,7 @@ var (
database = ethdb.NewMemDatabase()
gspec = core.Genesis{
Config: chainConfig,
Factory: blockFactory,
Alloc: core.GenesisAlloc{FaucetAddress: {Balance: FaucetInitFunds}},
ShardID: 0,
}

Loading…
Cancel
Save