diff --git a/api/proto/node/node.go b/api/proto/node/node.go index 7e9bf8161..dc198bd23 100644 --- a/api/proto/node/node.go +++ b/api/proto/node/node.go @@ -11,8 +11,10 @@ import ( peer "github.com/libp2p/go-libp2p-peer" "github.com/harmony-one/harmony/api/proto" + "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/internal/utils" + "github.com/harmony-one/harmony/shard" ) // MessageType is to indicate the specific type of message under Node category @@ -147,7 +149,7 @@ func ConstructBlocksSyncMessage(blocks []*types.Block) []byte { } // ConstructCrossLinkHeadersMessage constructs cross link header message to send to beacon chain -func ConstructCrossLinkHeadersMessage(headers []*types.Header) []byte { +func ConstructCrossLinkHeadersMessage(headers []*block.Header) []byte { byteBuffer := bytes.NewBuffer([]byte{byte(proto.Node)}) byteBuffer.WriteByte(byte(Block)) byteBuffer.WriteByte(byte(Header)) @@ -158,7 +160,7 @@ func ConstructCrossLinkHeadersMessage(headers []*types.Header) []byte { } // ConstructEpochShardStateMessage contructs epoch shard state message -func ConstructEpochShardStateMessage(epochShardState types.EpochShardState) []byte { +func ConstructEpochShardStateMessage(epochShardState shard.EpochShardState) []byte { byteBuffer := bytes.NewBuffer([]byte{byte(proto.Node)}) byteBuffer.WriteByte(byte(ShardState)) @@ -172,8 +174,8 @@ func ConstructEpochShardStateMessage(epochShardState types.EpochShardState) []by } // DeserializeEpochShardStateFromMessage deserializes the shard state Message from bytes payload -func DeserializeEpochShardStateFromMessage(payload []byte) (*types.EpochShardState, error) { - epochShardState := new(types.EpochShardState) +func DeserializeEpochShardStateFromMessage(payload []byte) (*shard.EpochShardState, error) { + epochShardState := new(shard.EpochShardState) r := bytes.NewBuffer(payload) decoder := gob.NewDecoder(r) diff --git a/api/proto/node/node_test.go b/api/proto/node/node_test.go index 623b980ce..b042d1aa4 100644 --- a/api/proto/node/node_test.go +++ b/api/proto/node/node_test.go @@ -1,18 +1,19 @@ package node import ( + "math/big" + "reflect" "strings" + "testing" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" + + "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/core/state" "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/internal/params" - - "math/big" - "reflect" - "testing" ) var ( @@ -59,7 +60,7 @@ func TestConstructBlocksSyncMessage(t *testing.T) { statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) root := statedb.IntermediateRoot(false) - head := &types.Header{ + head := &block.Header{ Number: new(big.Int).SetUint64(uint64(10000)), Epoch: big.NewInt(0), ShardID: 0, diff --git a/api/service/explorer/service.go b/api/service/explorer/service.go index ed6248ac4..2ee07bf0c 100644 --- a/api/service/explorer/service.go +++ b/api/service/explorer/service.go @@ -17,6 +17,7 @@ import ( libp2p_peer "github.com/libp2p/go-libp2p-peer" "github.com/harmony-one/bls/ffi/go/bls" + msg_pb "github.com/harmony-one/harmony/api/proto/message" "github.com/harmony-one/harmony/core/types" bls2 "github.com/harmony-one/harmony/crypto/bls" @@ -25,6 +26,7 @@ import ( "github.com/harmony-one/harmony/internal/ctxerror" "github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/p2p" + "github.com/harmony-one/harmony/shard" ) // Constants for explorer service. @@ -207,7 +209,7 @@ func (s *Service) GetExplorerBlocks(w http.ResponseWriter, r *http.Request) { accountBlocks := s.ReadBlocksFromDB(fromInt, toInt) curEpoch := int64(-1) - committee := &types.Committee{} + committee := &shard.Committee{} for id, accountBlock := range accountBlocks { if id == 0 || id == len(accountBlocks)-1 || accountBlock == nil { continue @@ -215,7 +217,7 @@ func (s *Service) GetExplorerBlocks(w http.ResponseWriter, r *http.Request) { block := NewBlock(accountBlock, id+fromInt-1) if int64(block.Epoch) > curEpoch { if bytes, err := db.Get([]byte(GetCommitteeKey(uint32(s.ShardID), block.Epoch))); err == nil { - committee = &types.Committee{} + committee = &shard.Committee{} if err = rlp.DecodeBytes(bytes, committee); err != nil { utils.Logger().Warn().Err(err).Msg("cannot read committee for new epoch") } @@ -377,7 +379,7 @@ func (s *Service) GetExplorerCommittee(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) return } - committee := &types.Committee{} + committee := &shard.Committee{} if err := rlp.DecodeBytes(bytes, committee); err != nil { utils.Logger().Warn().Err(err).Msg("cannot decode committee data from DB") w.WriteHeader(500) diff --git a/api/service/explorer/storage.go b/api/service/explorer/storage.go index f95e3da9d..179678d93 100644 --- a/api/service/explorer/storage.go +++ b/api/service/explorer/storage.go @@ -12,6 +12,7 @@ import ( "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/internal/ctxerror" "github.com/harmony-one/harmony/internal/utils" + "github.com/harmony-one/harmony/shard" ) // Constants for storage. @@ -126,7 +127,7 @@ func (storage *Storage) Dump(block *types.Block, height uint64) { } // DumpCommittee commits validators for shardNum and epoch. -func (storage *Storage) DumpCommittee(shardID uint32, epoch uint64, committee types.Committee) error { +func (storage *Storage) DumpCommittee(shardID uint32, epoch uint64, committee shard.Committee) error { batch := storage.db.NewBatch() // Store committees. committeeData, err := rlp.EncodeToBytes(committee) diff --git a/api/service/explorer/storage_test.go b/api/service/explorer/storage_test.go index c6a5dd0fd..78fe378d5 100644 --- a/api/service/explorer/storage_test.go +++ b/api/service/explorer/storage_test.go @@ -9,7 +9,11 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/rlp" "github.com/harmony-one/bls/ffi/go/bls" + + block2 "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/core/types" + "github.com/harmony-one/harmony/shard" + "github.com/stretchr/testify/assert" ) @@ -54,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(&types.Header{Number: big.NewInt(314)}, txs, nil, nil, nil) + block := types.NewBlock(&block2.Header{Number: big.NewInt(314)}, txs, nil, nil, nil) ins := GetStorageInstance("1.1.1.1", "3333", true) ins.Dump(block, uint64(1)) db := ins.GetDB() @@ -82,14 +86,14 @@ func TestDumpCommittee(t *testing.T) { assert.Nil(t, err, "should be nil") err = blsPubKey2.DeserializeHexStr("02c8ff0b88f313717bc3a627d2f8bb172ba3ad3bb9ba3ecb8eed4b7c878653d3d4faf769876c528b73f343967f74a917") assert.Nil(t, err, "should be nil") - BlsPublicKey1 := new(types.BlsPublicKey) - BlsPublicKey2 := new(types.BlsPublicKey) + BlsPublicKey1 := new(shard.BlsPublicKey) + BlsPublicKey2 := new(shard.BlsPublicKey) BlsPublicKey1.FromLibBLSPublicKey(blsPubKey1) BlsPublicKey2.FromLibBLSPublicKey(blsPubKey2) - nodeID1 := types.NodeID{EcdsaAddress: common.HexToAddress("52789f18a342da8023cc401e5d2b14a6b710fba9"), BlsPublicKey: *BlsPublicKey1} - nodeID2 := types.NodeID{EcdsaAddress: common.HexToAddress("7c41e0668b551f4f902cfaec05b5bdca68b124ce"), BlsPublicKey: *BlsPublicKey2} - nodeIDList := []types.NodeID{nodeID1, nodeID2} - committee := types.Committee{ShardID: uint32(0), NodeList: nodeIDList} + nodeID1 := shard.NodeID{EcdsaAddress: common.HexToAddress("52789f18a342da8023cc401e5d2b14a6b710fba9"), BlsPublicKey: *BlsPublicKey1} + nodeID2 := shard.NodeID{EcdsaAddress: common.HexToAddress("7c41e0668b551f4f902cfaec05b5bdca68b124ce"), BlsPublicKey: *BlsPublicKey2} + nodeIDList := []shard.NodeID{nodeID1, nodeID2} + committee := shard.Committee{ShardID: uint32(0), NodeList: nodeIDList} shardID := uint32(0) epoch := uint64(0) ins := GetStorageInstance("1.1.1.1", "3333", true) @@ -112,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(&types.Header{Number: big.NewInt(314)}, txs, nil, nil, nil) + block := types.NewBlock(&block2.Header{Number: big.NewInt(314)}, txs, nil, nil, nil) ins := GetStorageInstance("1.1.1.1", "3333", true) ins.Dump(block, uint64(1)) db := ins.GetDB() diff --git a/api/service/explorer/structs_test.go b/api/service/explorer/structs_test.go index b3f611695..1174efcc5 100644 --- a/api/service/explorer/structs_test.go +++ b/api/service/explorer/structs_test.go @@ -8,6 +8,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/ethereum/go-ethereum/common" + + block2 "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/core/types" common2 "github.com/harmony-one/harmony/internal/common" ) @@ -19,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(&types.Header{Number: big.NewInt(314)}, txs, nil, nil, nil) + block := types.NewBlock(&block2.Header{Number: big.NewInt(314)}, txs, nil, nil, nil) tx := GetTransaction(tx1, block) assert.Equal(t, tx.ID, tx1.Hash().Hex(), "should be equal tx1.Hash()") diff --git a/core/types/gen_header_json.go b/block/gen_header_json.go similarity index 99% rename from core/types/gen_header_json.go rename to block/gen_header_json.go index e38506662..cd05af881 100644 --- a/core/types/gen_header_json.go +++ b/block/gen_header_json.go @@ -1,6 +1,6 @@ // Code generated by github.com/fjl/gencodec. DO NOT EDIT. -package types +package block import ( "encoding/json" diff --git a/block/header.go b/block/header.go new file mode 100644 index 000000000..6ae3f25ca --- /dev/null +++ b/block/header.go @@ -0,0 +1,90 @@ +package block + +import ( + "math/big" + "unsafe" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" + "github.com/rs/zerolog" + + "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 { + 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"` +} + +// 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 +} diff --git a/consensus/consensus.go b/consensus/consensus.go index d41235d4c..68f40bf56 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -20,6 +20,7 @@ import ( "github.com/harmony-one/harmony/internal/memprofiling" "github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/p2p" + "github.com/harmony-one/harmony/shard" ) const ( @@ -304,7 +305,7 @@ func New(host p2p.Host, ShardID uint32, leader p2p.Peer, blsPriKey *bls.SecretKe // genesis accounts. // When used for block reward, it rewards only foundational nodes. type GenesisStakeInfoFinder struct { - byNodeKey map[types.BlsPublicKey][]*structs.StakeInfo + byNodeKey map[shard.BlsPublicKey][]*structs.StakeInfo byAccount map[common.Address][]*structs.StakeInfo } @@ -314,7 +315,7 @@ type GenesisStakeInfoFinder struct { func (f *GenesisStakeInfoFinder) FindStakeInfoByNodeKey( key *bls.PublicKey, ) []*structs.StakeInfo { - var pk types.BlsPublicKey + var pk shard.BlsPublicKey if err := pk.FromLibBLSPublicKey(key); err != nil { utils.Logger().Warn().Err(err).Msg("cannot convert BLS public key") return nil @@ -337,13 +338,13 @@ func (f *GenesisStakeInfoFinder) FindStakeInfoByAccount( // genesis nodes. func NewGenesisStakeInfoFinder() (*GenesisStakeInfoFinder, error) { f := &GenesisStakeInfoFinder{ - byNodeKey: make(map[types.BlsPublicKey][]*structs.StakeInfo), + byNodeKey: make(map[shard.BlsPublicKey][]*structs.StakeInfo), byAccount: make(map[common.Address][]*structs.StakeInfo), } for idx, account := range genesis.HarmonyAccounts { pub := &bls.PublicKey{} pub.DeserializeHexStr(account.BlsPublicKey) - var blsPublicKey types.BlsPublicKey + var blsPublicKey shard.BlsPublicKey if err := blsPublicKey.FromLibBLSPublicKey(pub); err != nil { return nil, ctxerror.New("cannot convert BLS public key", "accountIndex", idx, diff --git a/consensus/consensus_service.go b/consensus/consensus_service.go index 5bbb28b79..d255f6f9c 100644 --- a/consensus/consensus_service.go +++ b/consensus/consensus_service.go @@ -9,6 +9,7 @@ import ( "github.com/ethereum/go-ethereum/common" + "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/crypto/hash" @@ -456,7 +457,7 @@ func (consensus *Consensus) getLogger() *zerolog.Logger { } // retrieve corresponding blsPublicKey from Coinbase Address -func (consensus *Consensus) getLeaderPubKeyFromCoinbase(header *types.Header) (*bls.PublicKey, error) { +func (consensus *Consensus) getLeaderPubKeyFromCoinbase(header *block.Header) (*bls.PublicKey, error) { shardState, err := consensus.ChainReader.ReadShardState(header.Epoch) if err != nil { return nil, ctxerror.New("cannot read shard state", diff --git a/consensus/consensus_v2.go b/consensus/consensus_v2.go index a4f74f478..0e196a0ac 100644 --- a/consensus/consensus_v2.go +++ b/consensus/consensus_v2.go @@ -10,8 +10,11 @@ import ( "github.com/ethereum/go-ethereum/rlp" protobuf "github.com/golang/protobuf/proto" "github.com/harmony-one/bls/ffi/go/bls" + "github.com/harmony-one/vdf/src/vdf_go" + "github.com/harmony-one/harmony/api/proto" msg_pb "github.com/harmony-one/harmony/api/proto/message" + "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core/types" vrf_bls "github.com/harmony-one/harmony/crypto/vrf/bls" @@ -20,7 +23,6 @@ import ( "github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/p2p" "github.com/harmony-one/harmony/p2p/host" - "github.com/harmony-one/vdf/src/vdf_go" ) // handleMessageUpdate will update the consensus state according to received message @@ -182,7 +184,7 @@ func (consensus *Consensus) onAnnounce(msg *msg_pb.Message) { // verify validity of block header object blockHeader := recvMsg.Payload - var headerObj types.Header + var headerObj block.Header err = rlp.DecodeBytes(blockHeader, &headerObj) if err != nil { consensus.getLogger().Warn(). @@ -1203,7 +1205,7 @@ func (consensus *Consensus) GenerateVrfAndProof(newBlock *types.Block, vrfBlockN } // ValidateVrfAndProof validates a VRF/Proof from hash of previous block -func (consensus *Consensus) ValidateVrfAndProof(headerObj types.Header) bool { +func (consensus *Consensus) ValidateVrfAndProof(headerObj block.Header) bool { vrfPk := vrf_bls.NewVRFVerifier(consensus.LeaderPubKey) var blockHash [32]byte @@ -1275,7 +1277,7 @@ func (consensus *Consensus) GenerateVdfAndProof(newBlock *types.Block, vrfBlockN } // ValidateVdfAndProof validates the VDF/proof in the current epoch -func (consensus *Consensus) ValidateVdfAndProof(headerObj types.Header) bool { +func (consensus *Consensus) ValidateVdfAndProof(headerObj block.Header) bool { vrfBlockNumbers, err := consensus.ChainReader.ReadEpochVrfBlockNums(headerObj.Epoch) if err != nil { consensus.getLogger().Error().Err(err). diff --git a/consensus/engine/consensus_engine.go b/consensus/engine/consensus_engine.go index b6274fcb1..5f0d32751 100644 --- a/consensus/engine/consensus_engine.go +++ b/consensus/engine/consensus_engine.go @@ -6,8 +6,10 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/harmony-one/harmony/internal/params" + "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/core/state" "github.com/harmony-one/harmony/core/types" + "github.com/harmony-one/harmony/shard" ) // ChainReader defines a small collection of methods needed to access the local @@ -18,22 +20,22 @@ type ChainReader interface { Config() *params.ChainConfig // CurrentHeader retrieves the current header from the local chain. - CurrentHeader() *types.Header + CurrentHeader() *block.Header // GetHeader retrieves a block header from the database by hash and number. - GetHeader(hash common.Hash, number uint64) *types.Header + GetHeader(hash common.Hash, number uint64) *block.Header // GetHeaderByNumber retrieves a block header from the database by number. - GetHeaderByNumber(number uint64) *types.Header + GetHeaderByNumber(number uint64) *block.Header // GetHeaderByHash retrieves a block header from the database by its hash. - GetHeaderByHash(hash common.Hash) *types.Header + GetHeaderByHash(hash common.Hash) *block.Header // GetBlock retrieves a block from the database by hash and number. GetBlock(hash common.Hash, number uint64) *types.Block // ReadShardState retrieves sharding state given the epoch number. - ReadShardState(epoch *big.Int) (types.ShardState, error) + ReadShardState(epoch *big.Int) (shard.State, error) } // Engine is an algorithm agnostic consensus engine. @@ -41,32 +43,32 @@ type ChainReader interface { type Engine interface { // Author retrieves the Harmony address of the account that validated the given // block. - Author(header *types.Header) (common.Address, error) + Author(header *block.Header) (common.Address, error) // VerifyHeader checks whether a header conforms to the consensus rules of a // given engine. Verifying the seal may be done optionally here, or explicitly // via the VerifySeal method. - VerifyHeader(chain ChainReader, header *types.Header, seal bool) error + VerifyHeader(chain ChainReader, header *block.Header, seal bool) error // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers // concurrently. The method returns a quit channel to abort the operations and // a results channel to retrieve the async verifications (the order is that of // the input slice). - VerifyHeaders(chain ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) + VerifyHeaders(chain ChainReader, headers []*block.Header, seals []bool) (chan<- struct{}, <-chan error) // VerifySeal checks whether the crypto seal on a header is valid according to // the consensus rules of the given engine. - VerifySeal(chain ChainReader, header *types.Header) error + VerifySeal(chain ChainReader, header *block.Header) error // Prepare initializes the consensus fields of a block header according to the // rules of a particular engine. The changes are executed inline. - Prepare(chain ChainReader, header *types.Header) error + Prepare(chain ChainReader, header *block.Header) error // Finalize runs any post-transaction state modifications (e.g. block rewards) // and assembles the final block. // Note: The block header and state database might be updated to reflect any // consensus rules that happen at finalization (e.g. block rewards). - Finalize(chain ChainReader, header *types.Header, state *state.DB, txs []*types.Transaction, + Finalize(chain ChainReader, header *block.Header, state *state.DB, txs []*types.Transaction, receipts []*types.Receipt, outcxs []*types.CXReceipt, incxs []*types.CXReceiptsProof) (*types.Block, error) // Seal generates a new sealing request for the given input block and pushes @@ -77,5 +79,5 @@ type Engine interface { Seal(chain ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error // SealHash returns the hash of a block prior to it being sealed. - SealHash(header *types.Header) common.Hash + SealHash(header *block.Header) common.Hash } diff --git a/contracts/structs/structs.go b/contracts/structs/structs.go index 2aba89620..5a2641b24 100644 --- a/contracts/structs/structs.go +++ b/contracts/structs/structs.go @@ -3,7 +3,7 @@ package structs import ( "math/big" - "github.com/harmony-one/harmony/core/types" + "github.com/harmony-one/harmony/shard" "github.com/ethereum/go-ethereum/common" ) @@ -22,7 +22,7 @@ type StakeInfoReturnValue struct { // StakeInfo stores the staking information for a staker. type StakeInfo struct { Account common.Address - BlsPublicKey types.BlsPublicKey + BlsPublicKey shard.BlsPublicKey BlockNum *big.Int LockPeriodCount *big.Int // The number of locking period the token will be locked. Amount *big.Int diff --git a/core/blockchain.go b/core/blockchain.go index 226f30c82..fbe3fb508 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -38,6 +38,7 @@ import ( "github.com/harmony-one/harmony/internal/params" lru "github.com/hashicorp/golang-lru" + "github.com/harmony-one/harmony/block" consensus_engine "github.com/harmony-one/harmony/consensus/engine" "github.com/harmony-one/harmony/contracts/structs" "github.com/harmony-one/harmony/core/rawdb" @@ -46,6 +47,7 @@ import ( "github.com/harmony-one/harmony/core/vm" "github.com/harmony-one/harmony/internal/ctxerror" "github.com/harmony-one/harmony/internal/utils" + "github.com/harmony-one/harmony/shard" ) var ( @@ -248,7 +250,7 @@ func IsEpochLastBlock(block *types.Block) bool { // IsEpochLastBlockByHeader returns whether this block is the last block of an epoch // given block header -func IsEpochLastBlockByHeader(header *types.Header) bool { +func IsEpochLastBlockByHeader(header *block.Header) bool { return ShardingSchedule.IsLastBlock(header.Number.Uint64()) } @@ -725,11 +727,11 @@ func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*type // GetUnclesInChain retrieves all the uncles from a given block backwards until // a specific distance is reached. -func (bc *BlockChain) GetUnclesInChain(block *types.Block, length int) []*types.Header { - uncles := []*types.Header{} - for i := 0; block != nil && i < length; i++ { - uncles = append(uncles, block.Uncles()...) - block = bc.GetBlock(block.ParentHash(), block.NumberU64()-1) +func (bc *BlockChain) GetUnclesInChain(b *types.Block, length int) []*block.Header { + uncles := []*block.Header{} + for i := 0; b != nil && i < length; i++ { + uncles = append(uncles, b.Uncles()...) + b = bc.GetBlock(b.ParentHash(), b.NumberU64()-1) } return uncles } @@ -1207,7 +1209,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty coalescedLogs []*types.Log ) // Start the parallel header verifier - headers := make([]*types.Header, len(chain)) + headers := make([]*block.Header, len(chain)) seals := make([]bool, len(chain)) for i, block := range chain { @@ -1669,7 +1671,7 @@ Error: %v // should be done or not. The reason behind the optional check is because some // of the header retrieval mechanisms already need to verify nonces, as well as // because nonces can be verified sparsely, not needing to check each. -func (bc *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) { +func (bc *BlockChain) InsertHeaderChain(chain []*block.Header, checkFreq int) (int, error) { start := time.Now() if i, err := bc.hc.ValidateHeaderChain(chain, checkFreq); err != nil { return i, err @@ -1682,7 +1684,7 @@ func (bc *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (i bc.wg.Add(1) defer bc.wg.Done() - whFunc := func(header *types.Header) error { + whFunc := func(header *block.Header) error { bc.mu.Lock() defer bc.mu.Unlock() @@ -1702,7 +1704,7 @@ func (bc *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (i // without the real blocks. Hence, writing headers directly should only be done // in two scenarios: pure-header mode of operation (light clients), or properly // separated header/block phases (non-archive clients). -func (bc *BlockChain) writeHeader(header *types.Header) error { +func (bc *BlockChain) writeHeader(header *block.Header) error { bc.wg.Add(1) defer bc.wg.Done() @@ -1715,7 +1717,7 @@ func (bc *BlockChain) writeHeader(header *types.Header) error { // CurrentHeader retrieves the current head header of the canonical chain. The // header is retrieved from the HeaderChain's internal cache. -func (bc *BlockChain) CurrentHeader() *types.Header { +func (bc *BlockChain) CurrentHeader() *block.Header { return bc.hc.CurrentHeader() } @@ -1733,13 +1735,13 @@ func (bc *BlockChain) GetTdByHash(hash common.Hash) *big.Int { // GetHeader retrieves a block header from the database by hash and number, // caching it if found. -func (bc *BlockChain) GetHeader(hash common.Hash, number uint64) *types.Header { +func (bc *BlockChain) GetHeader(hash common.Hash, number uint64) *block.Header { return bc.hc.GetHeader(hash, number) } // GetHeaderByHash retrieves a block header from the database by hash, caching it if // found. -func (bc *BlockChain) GetHeaderByHash(hash common.Hash) *types.Header { +func (bc *BlockChain) GetHeaderByHash(hash common.Hash) *block.Header { return bc.hc.GetHeaderByHash(hash) } @@ -1769,7 +1771,7 @@ func (bc *BlockChain) GetAncestor(hash common.Hash, number, ancestor uint64, max // GetHeaderByNumber retrieves a block header from the database by number, // caching it (associated with its hash) if found. -func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header { +func (bc *BlockChain) GetHeaderByNumber(number uint64) *block.Header { return bc.hc.GetHeaderByNumber(number) } @@ -1805,10 +1807,10 @@ func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscript } // ReadShardState retrieves sharding state given the epoch number. -func (bc *BlockChain) ReadShardState(epoch *big.Int) (types.ShardState, error) { +func (bc *BlockChain) ReadShardState(epoch *big.Int) (shard.State, error) { cacheKey := string(epoch.Bytes()) if cached, ok := bc.shardStateCache.Get(cacheKey); ok { - shardState := cached.(types.ShardState) + shardState := cached.(shard.State) return shardState, nil } shardState, err := rawdb.ReadShardState(bc.db, epoch) @@ -1821,7 +1823,7 @@ func (bc *BlockChain) ReadShardState(epoch *big.Int) (types.ShardState, error) { // WriteShardState saves the given sharding state under the given epoch number. func (bc *BlockChain) WriteShardState( - epoch *big.Int, shardState types.ShardState, + epoch *big.Int, shardState shard.State, ) error { shardState = shardState.DeepCopy() err := rawdb.WriteShardState(bc.db, epoch, shardState) @@ -1837,7 +1839,7 @@ func (bc *BlockChain) WriteShardState( func (bc *BlockChain) WriteShardStateBytes( epoch *big.Int, shardState []byte, ) error { - decodeShardState := types.ShardState{} + decodeShardState := shard.State{} if err := rlp.DecodeBytes(shardState, &decodeShardState); err != nil { return err } @@ -1897,7 +1899,7 @@ func (bc *BlockChain) GetVrfByNumber(number uint64) []byte { func (bc *BlockChain) GetShardState( epoch *big.Int, stakeInfo *map[common.Address]*structs.StakeInfo, -) (types.ShardState, error) { +) (shard.State, error) { shardState, err := bc.ReadShardState(epoch) if err == nil { // TODO ek – distinguish ErrNotFound return shardState, err diff --git a/core/chain_indexer.go b/core/chain_indexer.go index ca5435df7..038e13e5d 100644 --- a/core/chain_indexer.go +++ b/core/chain_indexer.go @@ -29,8 +29,8 @@ import ( "github.com/ethereum/go-ethereum/event" "github.com/rs/zerolog" + "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/core/rawdb" - "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/internal/utils" ) @@ -44,7 +44,7 @@ type ChainIndexerBackend interface { // Process crunches through the next header in the chain segment. The caller // will ensure a sequential order of headers. - Process(ctx context.Context, header *types.Header) error + Process(ctx context.Context, header *block.Header) error // Commit finalizes the section metadata and stores it into the database. Commit() error @@ -53,7 +53,7 @@ type ChainIndexerBackend interface { // ChainIndexerChain interface is used for connecting the indexer to a blockchain type ChainIndexerChain interface { // CurrentHeader retrieves the latest locally known header. - CurrentHeader() *types.Header + CurrentHeader() *block.Header // SubscribeChainHeadEvent subscribes to new head header notifications. SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription @@ -193,7 +193,7 @@ func (c *ChainIndexer) Close() error { // eventLoop is a secondary - optional - event loop of the indexer which is only // started for the outermost indexer to push chain head events into a processing // queue. -func (c *ChainIndexer) eventLoop(currentHeader *types.Header, events chan ChainHeadEvent, sub event.Subscription) { +func (c *ChainIndexer) eventLoop(currentHeader *block.Header, events chan ChainHeadEvent, sub event.Subscription) { // Mark the chain indexer as active, requiring an additional teardown atomic.StoreUint32(&c.active, 1) diff --git a/core/chain_makers.go b/core/chain_makers.go index ea9e04677..77df0be3f 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -24,10 +24,12 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/harmony-one/harmony/internal/params" + "github.com/harmony-one/harmony/block" consensus_engine "github.com/harmony-one/harmony/consensus/engine" "github.com/harmony-one/harmony/core/state" "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/vm" + "github.com/harmony-one/harmony/shard" ) // BlockGen creates blocks for testing. @@ -36,13 +38,13 @@ type BlockGen struct { i int parent *types.Block chain []*types.Block - header *types.Header + header *block.Header statedb *state.DB gasPool *GasPool txs []*types.Transaction receipts []*types.Receipt - uncles []*types.Header + uncles []*block.Header config *params.ChainConfig engine consensus_engine.Engine @@ -128,7 +130,7 @@ func (b *BlockGen) TxNonce(addr common.Address) uint64 { } // AddUncle adds an uncle header to the generated block. -func (b *BlockGen) AddUncle(h *types.Header) { +func (b *BlockGen) AddUncle(h *block.Header) { b.uncles = append(b.uncles, h) } @@ -206,7 +208,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) *types.Header { +func makeHeader(chain consensus_engine.ChainReader, parent *types.Block, state *state.DB, engine consensus_engine.Engine) *block.Header { var time *big.Int if parent.Time() == nil { time = big.NewInt(10) @@ -214,7 +216,7 @@ 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 &types.Header{ + return &block.Header{ Root: state.IntermediateRoot(chain.Config().IsEIP158(parent.Number())), ParentHash: parent.Hash(), Coinbase: parent.Coinbase(), @@ -231,9 +233,9 @@ func makeHeader(chain consensus_engine.ChainReader, parent *types.Block, state * } // makeHeaderChain creates a deterministic chain of headers rooted at parent. -func makeHeaderChain(parent *types.Header, n int, engine consensus_engine.Engine, db ethdb.Database, seed int) []*types.Header { +func makeHeaderChain(parent *block.Header, n int, engine consensus_engine.Engine, db ethdb.Database, seed int) []*block.Header { blocks := makeBlockChain(types.NewBlockWithHeader(parent), n, engine, db, seed) - headers := make([]*types.Header, len(blocks)) + headers := make([]*block.Header, len(blocks)) for i, block := range blocks { headers[i] = block.Header() } @@ -258,9 +260,9 @@ func (cr *fakeChainReader) Config() *params.ChainConfig { return cr.config } -func (cr *fakeChainReader) CurrentHeader() *types.Header { return nil } -func (cr *fakeChainReader) GetHeaderByNumber(number uint64) *types.Header { return nil } -func (cr *fakeChainReader) GetHeaderByHash(hash common.Hash) *types.Header { return nil } -func (cr *fakeChainReader) GetHeader(hash common.Hash, number uint64) *types.Header { return nil } +func (cr *fakeChainReader) CurrentHeader() *block.Header { return nil } +func (cr *fakeChainReader) GetHeaderByNumber(number uint64) *block.Header { return nil } +func (cr *fakeChainReader) GetHeaderByHash(hash common.Hash) *block.Header { return nil } +func (cr *fakeChainReader) GetHeader(hash common.Hash, number uint64) *block.Header { return nil } func (cr *fakeChainReader) GetBlock(hash common.Hash, number uint64) *types.Block { return nil } -func (cr *fakeChainReader) ReadShardState(epoch *big.Int) (types.ShardState, error) { return nil, nil } +func (cr *fakeChainReader) ReadShardState(epoch *big.Int) (shard.State, error) { return nil, nil } diff --git a/core/core_test.go b/core/core_test.go index 15934f74d..9870b6f06 100644 --- a/core/core_test.go +++ b/core/core_test.go @@ -4,18 +4,19 @@ import ( "math/big" "testing" + "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/core/types" shardingconfig "github.com/harmony-one/harmony/internal/configs/sharding" ) func TestIsEpochBlock(t *testing.T) { - block1 := types.NewBlock(&types.Header{Number: big.NewInt(10)}, nil, nil, nil, nil) - block2 := types.NewBlock(&types.Header{Number: big.NewInt(0)}, nil, nil, nil, nil) - block3 := types.NewBlock(&types.Header{Number: big.NewInt(344064)}, nil, nil, nil, nil) - block4 := types.NewBlock(&types.Header{Number: big.NewInt(77)}, nil, nil, nil, nil) - block5 := types.NewBlock(&types.Header{Number: big.NewInt(78)}, nil, nil, nil, nil) - block6 := types.NewBlock(&types.Header{Number: big.NewInt(188)}, nil, nil, nil, nil) - block7 := types.NewBlock(&types.Header{Number: big.NewInt(189)}, nil, nil, nil, nil) + block1 := types.NewBlock(&block.Header{Number: big.NewInt(10)}, nil, nil, nil, nil) + block2 := types.NewBlock(&block.Header{Number: big.NewInt(0)}, nil, nil, nil, nil) + block3 := types.NewBlock(&block.Header{Number: big.NewInt(344064)}, nil, nil, nil, nil) + block4 := types.NewBlock(&block.Header{Number: big.NewInt(77)}, nil, nil, nil, nil) + block5 := types.NewBlock(&block.Header{Number: big.NewInt(78)}, nil, nil, nil, nil) + block6 := types.NewBlock(&block.Header{Number: big.NewInt(188)}, nil, nil, nil, nil) + block7 := types.NewBlock(&block.Header{Number: big.NewInt(189)}, nil, nil, nil, nil) tests := []struct { schedule shardingconfig.Schedule block *types.Block diff --git a/core/evm.go b/core/evm.go index 8731f5b12..4f5118b15 100644 --- a/core/evm.go +++ b/core/evm.go @@ -20,6 +20,8 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" + + "github.com/harmony-one/harmony/block" consensus_engine "github.com/harmony-one/harmony/consensus/engine" "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/vm" @@ -32,11 +34,11 @@ type ChainContext interface { Engine() consensus_engine.Engine // GetHeader returns the hash corresponding to their hash. - GetHeader(common.Hash, uint64) *types.Header + GetHeader(common.Hash, uint64) *block.Header } // NewEVMContext creates a new context for use in the EVM. -func NewEVMContext(msg Message, header *types.Header, chain ChainContext, author *common.Address) vm.Context { +func NewEVMContext(msg Message, header *block.Header, chain ChainContext, author *common.Address) vm.Context { // If we don't have an explicit author (i.e. not mining), extract from the header var beneficiary common.Address if author == nil { @@ -59,7 +61,7 @@ func NewEVMContext(msg Message, header *types.Header, chain ChainContext, author } // GetHashFn returns a GetHashFunc which retrieves header hashes by number -func GetHashFn(ref *types.Header, chain ChainContext) func(n uint64) common.Hash { +func GetHashFn(ref *block.Header, chain ChainContext) func(n uint64) common.Hash { var cache map[uint64]common.Hash return func(n uint64) common.Hash { diff --git a/core/genesis.go b/core/genesis.go index 665e18932..16c5ef3e6 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -32,10 +32,12 @@ import ( "github.com/ethereum/go-ethereum/rlp" "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" "github.com/harmony-one/harmony/internal/utils" + "github.com/harmony-one/harmony/shard" ) // no go:generate gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go @@ -56,7 +58,7 @@ type Genesis struct { Coinbase common.Address `json:"coinbase"` Alloc GenesisAlloc `json:"alloc" gencodec:"required"` ShardStateHash common.Hash `json:"shardStateHash" gencodec:"required"` - ShardState types.ShardState `json:"shardState" 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. @@ -243,7 +245,7 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block { utils.Logger().Error().Msg("failed to rlp-serialize genesis shard state") os.Exit(1) } - head := &types.Header{ + head := &block.Header{ Number: new(big.Int).SetUint64(g.Number), Epoch: big.NewInt(0), ShardID: g.ShardID, diff --git a/core/headerchain.go b/core/headerchain.go index 01604b2cb..17dcd4c42 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -31,6 +31,7 @@ import ( "github.com/harmony-one/harmony/internal/params" lru "github.com/hashicorp/golang-lru" + "github.com/harmony-one/harmony/block" consensus_engine "github.com/harmony-one/harmony/consensus/engine" "github.com/harmony-one/harmony/core/rawdb" "github.com/harmony-one/harmony/core/types" @@ -52,7 +53,7 @@ type HeaderChain struct { config *params.ChainConfig chainDb ethdb.Database - genesisHeader *types.Header + genesisHeader *block.Header currentHeader atomic.Value // Current head of the header chain (may be above the block chain!) currentHeaderHash common.Hash // Hash of the current head of the header chain (prevent recomputing all the time) @@ -132,7 +133,7 @@ func (hc *HeaderChain) GetBlockNumber(hash common.Hash) *uint64 { // without the real blocks. Hence, writing headers directly should only be done // in two scenarios: pure-header mode of operation (light clients), or properly // separated header/block phases (non-archive clients). -func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, err error) { +func (hc *HeaderChain) WriteHeader(header *block.Header) (status WriteStatus, err error) { // Cache some values to prevent constant recalculation var ( hash = header.Hash() @@ -199,10 +200,10 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er // processed and light chain events sent, while in a BlockChain this is not // necessary since chain events are sent after inserting blocks. Second, the // header writes should be protected by the parent chain mutex individually. -type WhCallback func(*types.Header) error +type WhCallback func(*block.Header) error // ValidateHeaderChain validates header chain. -func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header, checkFreq int) (int, error) { +func (hc *HeaderChain) ValidateHeaderChain(chain []*block.Header, checkFreq int) (int, error) { // Do a sanity check that the provided chain is actually ordered and linked for i := 1; i < len(chain); i++ { if chain[i].Number.Uint64() != chain[i-1].Number.Uint64()+1 || chain[i].ParentHash != chain[i-1].Hash() { @@ -259,7 +260,7 @@ func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header, checkFreq int) // should be done or not. The reason behind the optional check is because some // of the header retrieval mechanisms already need to verfy nonces, as well as // because nonces can be verified sparsely, not needing to check each. -func (hc *HeaderChain) InsertHeaderChain(chain []*types.Header, writeHeader WhCallback, start time.Time) (int, error) { +func (hc *HeaderChain) InsertHeaderChain(chain []*block.Header, writeHeader WhCallback, start time.Time) (int, error) { // Collect some import statistics to report on stats := struct{ processed, ignored int }{} // All headers passed verification, import them into the database @@ -395,10 +396,10 @@ func (hc *HeaderChain) WriteTd(hash common.Hash, number uint64, td *big.Int) err // GetHeader retrieves a block header from the database by hash and number, // caching it if found. -func (hc *HeaderChain) GetHeader(hash common.Hash, number uint64) *types.Header { +func (hc *HeaderChain) GetHeader(hash common.Hash, number uint64) *block.Header { // Short circuit if the header's already in the cache, retrieve otherwise if header, ok := hc.headerCache.Get(hash); ok { - return header.(*types.Header) + return header.(*block.Header) } header := rawdb.ReadHeader(hc.chainDb, hash, number) if header == nil { @@ -411,7 +412,7 @@ func (hc *HeaderChain) GetHeader(hash common.Hash, number uint64) *types.Header // GetHeaderByHash retrieves a block header from the database by hash, caching it if // found. -func (hc *HeaderChain) GetHeaderByHash(hash common.Hash) *types.Header { +func (hc *HeaderChain) GetHeaderByHash(hash common.Hash) *block.Header { number := hc.GetBlockNumber(hash) if number == nil { return nil @@ -429,7 +430,7 @@ func (hc *HeaderChain) HasHeader(hash common.Hash, number uint64) bool { // GetHeaderByNumber retrieves a block header from the database by number, // caching it (associated with its hash) if found. -func (hc *HeaderChain) GetHeaderByNumber(number uint64) *types.Header { +func (hc *HeaderChain) GetHeaderByNumber(number uint64) *block.Header { hash := rawdb.ReadCanonicalHash(hc.chainDb, number) if hash == (common.Hash{}) { return nil @@ -439,12 +440,12 @@ func (hc *HeaderChain) GetHeaderByNumber(number uint64) *types.Header { // CurrentHeader retrieves the current head header of the canonical chain. The // header is retrieved from the HeaderChain's internal cache. -func (hc *HeaderChain) CurrentHeader() *types.Header { - return hc.currentHeader.Load().(*types.Header) +func (hc *HeaderChain) CurrentHeader() *block.Header { + return hc.currentHeader.Load().(*block.Header) } // SetCurrentHeader sets the current head header of the canonical chain. -func (hc *HeaderChain) SetCurrentHeader(head *types.Header) { +func (hc *HeaderChain) SetCurrentHeader(head *block.Header) { rawdb.WriteHeadHeaderHash(hc.chainDb, head.Hash()) hc.currentHeader.Store(head) @@ -495,7 +496,7 @@ func (hc *HeaderChain) SetHead(head uint64, delFn DeleteCallback) { } // SetGenesis sets a new genesis block header for the chain -func (hc *HeaderChain) SetGenesis(head *types.Header) { +func (hc *HeaderChain) SetGenesis(head *block.Header) { hc.genesisHeader = head } diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index 48100283f..b05c5c044 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -24,9 +24,11 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/rlp" + "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/internal/ctxerror" "github.com/harmony-one/harmony/internal/utils" + "github.com/harmony-one/harmony/shard" ) // Indicate whether the receipts corresponding to a blockHash is spent or not @@ -150,12 +152,12 @@ func HasHeader(db DatabaseReader, hash common.Hash, number uint64) bool { } // ReadHeader retrieves the block header corresponding to the hash. -func ReadHeader(db DatabaseReader, hash common.Hash, number uint64) *types.Header { +func ReadHeader(db DatabaseReader, hash common.Hash, number uint64) *block.Header { data := ReadHeaderRLP(db, hash, number) if len(data) == 0 { return nil } - header := new(types.Header) + header := new(block.Header) if err := rlp.Decode(bytes.NewReader(data), header); err != nil { utils.Logger().Error().Err(err).Str("hash", hash.Hex()).Msg("Invalid block header RLP") return nil @@ -165,7 +167,7 @@ func ReadHeader(db DatabaseReader, hash common.Hash, number uint64) *types.Heade // WriteHeader stores a block header into the database and also stores the hash- // to-number mapping. -func WriteHeader(db DatabaseWriter, header *types.Header) { +func WriteHeader(db DatabaseWriter, header *block.Header) { // Write the hash -> number mapping var ( hash = header.Hash() @@ -383,7 +385,7 @@ func DeleteBlock(db DatabaseDeleter, hash common.Hash, number uint64) { } // FindCommonAncestor returns the last common ancestor of two block headers -func FindCommonAncestor(db DatabaseReader, a, b *types.Header) *types.Header { +func FindCommonAncestor(db DatabaseReader, a, b *block.Header) *block.Header { for bn := b.Number.Uint64(); a.Number.Uint64() > bn; { a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1) if a == nil { @@ -412,7 +414,7 @@ func FindCommonAncestor(db DatabaseReader, a, b *types.Header) *types.Header { // ReadShardState retrieves sharding state. func ReadShardState( db DatabaseReader, epoch *big.Int, -) (shardState types.ShardState, err error) { +) (shardState shard.State, err error) { var data []byte data, err = db.Get(shardStateKey(epoch)) if err != nil { @@ -430,7 +432,7 @@ func ReadShardState( // WriteShardState stores sharding state into database. func WriteShardState( - db DatabaseWriter, epoch *big.Int, shardState types.ShardState, + db DatabaseWriter, epoch *big.Int, shardState shard.State, ) (err error) { data, err := rlp.EncodeToBytes(shardState) if err != nil { diff --git a/core/rawdb/accessors_chain_test.go b/core/rawdb/accessors_chain_test.go index 3378ee132..e8729ab6b 100644 --- a/core/rawdb/accessors_chain_test.go +++ b/core/rawdb/accessors_chain_test.go @@ -27,10 +27,12 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/rlp" "github.com/golang/mock/gomock" - mock "github.com/harmony-one/harmony/core/rawdb/mock" - "github.com/harmony-one/harmony/core/types" "github.com/syndtr/goleveldb/leveldb" "golang.org/x/crypto/sha3" + + "github.com/harmony-one/harmony/block" + mock "github.com/harmony-one/harmony/core/rawdb/mock" + "github.com/harmony-one/harmony/core/types" ) // Tests block header storage and retrieval operations. @@ -38,7 +40,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 := &types.Header{Number: big.NewInt(42), Extra: []byte("test header")} + header := &block.Header{Number: big.NewInt(42), Extra: []byte("test header")} if entry := ReadHeader(db, header.Hash(), header.Number.Uint64()); entry != nil { t.Fatalf("Non existent header returned: %v", entry) } @@ -71,7 +73,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: []*types.Header{{Extra: []byte("test header")}}} + body := &types.Body{Uncles: []*block.Header{{Extra: []byte("test header")}}} hasher := sha3.NewLegacyKeccak256() rlp.Encode(hasher, body) @@ -109,7 +111,7 @@ func TestBlockStorage(t *testing.T) { db := ethdb.NewMemDatabase() // Create a test block to move around the database and make sure it's really new - block := types.NewBlockWithHeader(&types.Header{ + block := types.NewBlockWithHeader(&block.Header{ Extra: []byte("test block"), TxHash: types.EmptyRootHash, ReceiptHash: types.EmptyRootHash, @@ -169,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(&types.Header{ + block := types.NewBlockWithHeader(&block.Header{ Extra: []byte("test block"), TxHash: types.EmptyRootHash, ReceiptHash: types.EmptyRootHash, @@ -249,9 +251,9 @@ func TestCanonicalMappingStorage(t *testing.T) { func TestHeadStorage(t *testing.T) { db := ethdb.NewMemDatabase() - blockHead := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block header")}) - blockFull := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block full")}) - blockFast := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block fast")}) + blockHead := types.NewBlockWithHeader(&block.Header{Extra: []byte("test block header")}) + blockFull := types.NewBlockWithHeader(&block.Header{Extra: []byte("test block full")}) + blockFast := types.NewBlockWithHeader(&block.Header{Extra: []byte("test block fast")}) // Check that no head entries are in a pristine database if entry := ReadHeadHeaderHash(db); entry != (common.Hash{}) { diff --git a/core/rawdb/accessors_indexes_test.go b/core/rawdb/accessors_indexes_test.go index 29fa24ee8..7c1acb529 100644 --- a/core/rawdb/accessors_indexes_test.go +++ b/core/rawdb/accessors_indexes_test.go @@ -22,6 +22,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethdb" + + block2 "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/core/types" ) @@ -34,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(&types.Header{Number: big.NewInt(314)}, txs, nil, nil, nil) + block := types.NewBlock(&block2.Header{Number: big.NewInt(314)}, txs, nil, nil, nil) // Check that no transactions entries are in a pristine database for i, tx := range txs { diff --git a/core/resharding.go b/core/resharding.go index f90088abb..e039f7f8b 100644 --- a/core/resharding.go +++ b/core/resharding.go @@ -12,11 +12,11 @@ import ( "github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/harmony/contracts/structs" - "github.com/harmony-one/harmony/core/types" common2 "github.com/harmony-one/harmony/internal/common" shardingconfig "github.com/harmony-one/harmony/internal/configs/sharding" "github.com/harmony-one/harmony/internal/ctxerror" "github.com/harmony-one/harmony/internal/utils" + "github.com/harmony-one/harmony/shard" ) const ( @@ -31,7 +31,7 @@ type ShardingState struct { epoch uint64 // current epoch rnd uint64 // random seed for resharding numShards int // TODO ek – equal to len(shardState); remove this - shardState types.ShardState + shardState shard.State } // sortedCommitteeBySize will sort shards by size @@ -46,7 +46,7 @@ func (ss *ShardingState) sortCommitteeBySize() { } // assignNewNodes add new nodes into the N/2 active committees evenly -func (ss *ShardingState) assignNewNodes(newNodeList []types.NodeID) { +func (ss *ShardingState) assignNewNodes(newNodeList []shard.NodeID) { ss.sortCommitteeBySize() numActiveShards := ss.numShards / 2 Shuffle(newNodeList) @@ -66,7 +66,7 @@ func (ss *ShardingState) assignNewNodes(newNodeList []types.NodeID) { // cuckooResharding uses cuckoo rule to reshard X% of active committee(shards) into inactive committee(shards) func (ss *ShardingState) cuckooResharding(percent float64) { numActiveShards := ss.numShards / 2 - kickedNodes := []types.NodeID{} + kickedNodes := []shard.NodeID{} for i := range ss.shardState { if i >= numActiveShards { break @@ -96,12 +96,12 @@ func (ss *ShardingState) cuckooResharding(percent float64) { } // Reshard will first add new nodes into shards, then use cuckoo rule to reshard to get new shard state -func (ss *ShardingState) Reshard(newNodeList []types.NodeID, percent float64) { +func (ss *ShardingState) Reshard(newNodeList []shard.NodeID, percent float64) { rand.Seed(int64(ss.rnd)) ss.sortCommitteeBySize() // Take out and preserve leaders - leaders := []types.NodeID{} + leaders := []shard.NodeID{} for i := 0; i < ss.numShards; i++ { if len(ss.shardState[i].NodeList) > 0 { leaders = append(leaders, ss.shardState[i].NodeList[0]) @@ -119,15 +119,15 @@ func (ss *ShardingState) Reshard(newNodeList []types.NodeID, percent float64) { utils.Logger().Error().Msg("Not enough leaders to assign to shards") } for i := 0; i < ss.numShards; i++ { - ss.shardState[i].NodeList = append([]types.NodeID{leaders[i]}, ss.shardState[i].NodeList...) + ss.shardState[i].NodeList = append([]shard.NodeID{leaders[i]}, ss.shardState[i].NodeList...) } } // Shuffle will shuffle the list with result uniquely determined by seed, assuming there is no repeat items in the list -func Shuffle(list []types.NodeID) { +func Shuffle(list []shard.NodeID) { // Sort to make sure everyone will generate the same with the same rand seed. sort.Slice(list, func(i, j int) bool { - return types.CompareNodeIDByBLSKey(list[i], list[j]) == -1 + return shard.CompareNodeIDByBLSKey(list[i], list[j]) == -1 }) rand.Shuffle(len(list), func(i, j int) { list[i], list[j] = list[j], list[i] @@ -175,7 +175,7 @@ func GetShardingStateFromBlockChain(bc *BlockChain, epoch *big.Int) (*ShardingSt func CalculateNewShardState( bc *BlockChain, epoch *big.Int, stakeInfo *map[common.Address]*structs.StakeInfo, -) (types.ShardState, error) { +) (shard.State, error) { if epoch.Cmp(big.NewInt(GenesisEpoch)) == 0 { return GetInitShardState(), nil } @@ -192,8 +192,8 @@ func CalculateNewShardState( } // UpdateShardingState remove the unstaked nodes and returns the newly staked node Ids. -func (ss *ShardingState) UpdateShardingState(stakeInfo *map[common.Address]*structs.StakeInfo) []types.NodeID { - oldBlsPublicKeys := make(map[types.BlsPublicKey]bool) // map of bls public keys +func (ss *ShardingState) UpdateShardingState(stakeInfo *map[common.Address]*structs.StakeInfo) []shard.NodeID { + oldBlsPublicKeys := make(map[shard.BlsPublicKey]bool) // map of bls public keys for _, shard := range ss.shardState { newNodeList := shard.NodeList for _, nodeID := range shard.NodeList { @@ -208,11 +208,11 @@ func (ss *ShardingState) UpdateShardingState(stakeInfo *map[common.Address]*stru shard.NodeList = newNodeList } - newAddresses := []types.NodeID{} + newAddresses := []shard.NodeID{} for addr, info := range *stakeInfo { _, ok := oldBlsPublicKeys[info.BlsPublicKey] if !ok { - newAddresses = append(newAddresses, types.NodeID{ + newAddresses = append(newAddresses, shard.NodeID{ EcdsaAddress: addr, BlsPublicKey: info.BlsPublicKey, }) @@ -230,12 +230,12 @@ func (ss *ShardingState) UpdateShardingState(stakeInfo *map[common.Address]*stru var ShardingSchedule shardingconfig.Schedule = shardingconfig.MainnetSchedule // GetInitShardState returns the initial shard state at genesis. -func GetInitShardState() types.ShardState { +func GetInitShardState() shard.State { return GetShardState(big.NewInt(GenesisEpoch)) } // GetShardState returns the shard state based on epoch number -func GetShardState(epoch *big.Int) types.ShardState { +func GetShardState(epoch *big.Int) shard.State { utils.Logger().Info().Int64("epoch", epoch.Int64()).Msg("Get Shard State of Epoch.") shardingConfig := ShardingSchedule.InstanceForEpoch(epoch) shardNum := int(shardingConfig.NumShards()) @@ -244,18 +244,18 @@ func GetShardState(epoch *big.Int) types.ShardState { hmyAccounts := shardingConfig.HmyAccounts() fnAccounts := shardingConfig.FnAccounts() - shardState := types.ShardState{} + shardState := shard.State{} for i := 0; i < shardNum; i++ { - com := types.Committee{ShardID: uint32(i)} + com := shard.Committee{ShardID: uint32(i)} for j := 0; j < shardHarmonyNodes; j++ { index := i + j*shardNum // The initial account to use for genesis nodes pub := &bls.PublicKey{} pub.DeserializeHexStr(hmyAccounts[index].BlsPublicKey) - pubKey := types.BlsPublicKey{} + pubKey := shard.BlsPublicKey{} pubKey.FromLibBLSPublicKey(pub) // TODO: directly read address for bls too - curNodeID := types.NodeID{ + curNodeID := shard.NodeID{ EcdsaAddress: common2.ParseAddr(hmyAccounts[index].Address), BlsPublicKey: pubKey, } @@ -269,10 +269,10 @@ func GetShardState(epoch *big.Int) types.ShardState { pub := &bls.PublicKey{} pub.DeserializeHexStr(fnAccounts[index].BlsPublicKey) - pubKey := types.BlsPublicKey{} + pubKey := shard.BlsPublicKey{} pubKey.FromLibBLSPublicKey(pub) // TODO: directly read address for bls too - curNodeID := types.NodeID{ + curNodeID := shard.NodeID{ EcdsaAddress: common2.ParseAddr(fnAccounts[index].Address), BlsPublicKey: pubKey, } diff --git a/core/resharding_test.go b/core/resharding_test.go index 3d5a96cf9..dd59cc5ed 100644 --- a/core/resharding_test.go +++ b/core/resharding_test.go @@ -8,7 +8,8 @@ import ( "github.com/ethereum/go-ethereum/common" - "github.com/harmony-one/harmony/core/types" + "github.com/harmony-one/harmony/shard" + "github.com/stretchr/testify/assert" ) @@ -38,17 +39,17 @@ func init() { copy(blsPubKey10[:], []byte("random key 10")) } -func fakeGetInitShardState(numberOfShards, numOfNodes int) types.ShardState { +func fakeGetInitShardState(numberOfShards, numOfNodes int) shard.State { rand.Seed(int64(42)) - shardState := types.ShardState{} + shardState := shard.State{} for i := 0; i < numberOfShards; i++ { sid := uint32(i) - com := types.Committee{ShardID: sid} + com := shard.Committee{ShardID: sid} for j := 0; j < numOfNodes; j++ { nid := strconv.Itoa(int(rand.Int63())) blsPubKey := [48]byte{} copy(blsPubKey1[:], []byte(nid)) - com.NodeList = append(com.NodeList, types.NodeID{ + com.NodeList = append(com.NodeList, shard.NodeID{ EcdsaAddress: common.BytesToAddress([]byte(nid)), BlsPublicKey: blsPubKey, }) @@ -58,15 +59,15 @@ func fakeGetInitShardState(numberOfShards, numOfNodes int) types.ShardState { return shardState } -func fakeNewNodeList(seed int64) []types.NodeID { +func fakeNewNodeList(seed int64) []shard.NodeID { rand.Seed(seed) numNewNodes := rand.Intn(10) - nodeList := []types.NodeID{} + nodeList := []shard.NodeID{} for i := 0; i < numNewNodes; i++ { nid := strconv.Itoa(int(rand.Int63())) blsPubKey := [48]byte{} copy(blsPubKey1[:], []byte(nid)) - nodeList = append(nodeList, types.NodeID{ + nodeList = append(nodeList, shard.NodeID{ EcdsaAddress: common.BytesToAddress([]byte(nid)), BlsPublicKey: blsPubKey, }) @@ -80,7 +81,7 @@ func TestFakeNewNodeList(t *testing.T) { } func TestShuffle(t *testing.T) { - nodeList := []types.NodeID{ + nodeList := []shard.NodeID{ {EcdsaAddress: common.Address{0x12}, BlsPublicKey: blsPubKey1}, {EcdsaAddress: common.Address{0x22}, BlsPublicKey: blsPubKey2}, {EcdsaAddress: common.Address{0x32}, BlsPublicKey: blsPubKey3}, @@ -93,7 +94,7 @@ func TestShuffle(t *testing.T) { {EcdsaAddress: common.Address{0x02}, BlsPublicKey: blsPubKey10}, } - cpList := []types.NodeID{} + cpList := []shard.NodeID{} cpList = append(cpList, nodeList...) Shuffle(nodeList) cnt := 0 @@ -120,7 +121,7 @@ func TestSortCommitteeBySize(t *testing.T) { func TestUpdateShardState(t *testing.T) { shardState := fakeGetInitShardState(6, 10) ss := &ShardingState{epoch: 1, rnd: 42, shardState: shardState, numShards: len(shardState)} - newNodeList := []types.NodeID{ + newNodeList := []shard.NodeID{ {EcdsaAddress: common.Address{0x12}, BlsPublicKey: blsPubKey1}, {EcdsaAddress: common.Address{0x22}, BlsPublicKey: blsPubKey2}, {EcdsaAddress: common.Address{0x32}, BlsPublicKey: blsPubKey3}, @@ -136,7 +137,7 @@ func TestUpdateShardState(t *testing.T) { func TestAssignNewNodes(t *testing.T) { shardState := fakeGetInitShardState(2, 2) ss := &ShardingState{epoch: 1, rnd: 42, shardState: shardState, numShards: len(shardState)} - newNodes := []types.NodeID{ + newNodes := []shard.NodeID{ {EcdsaAddress: common.Address{0x12}, BlsPublicKey: blsPubKey1}, {EcdsaAddress: common.Address{0x22}, BlsPublicKey: blsPubKey2}, {EcdsaAddress: common.Address{0x32}, BlsPublicKey: blsPubKey3}, diff --git a/core/state_processor.go b/core/state_processor.go index 895811df7..927902857 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -21,6 +21,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" + + "github.com/harmony-one/harmony/block" consensus_engine "github.com/harmony-one/harmony/consensus/engine" "github.com/harmony-one/harmony/core/state" "github.com/harmony-one/harmony/core/types" @@ -101,7 +103,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.DB, cfg vm.C } // return true if it is valid -func getTransactionType(header *types.Header, tx *types.Transaction) types.TransactionType { +func getTransactionType(header *block.Header, tx *types.Transaction) types.TransactionType { if tx.ShardID() == tx.ToShardID() && header.ShardID == tx.ShardID() { return types.SameShardTx } @@ -117,7 +119,7 @@ func getTransactionType(header *types.Header, tx *types.Transaction) types.Trans // and uses the input parameters for its environment. It returns the receipt // for the transaction, gas used and an error if the transaction failed, // indicating the block was invalid. -func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.DB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, *types.CXReceipt, uint64, error) { +func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.DB, header *block.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, *types.CXReceipt, uint64, error) { txType := getTransactionType(header, tx) if txType == types.InvalidTx { return nil, nil, 0, fmt.Errorf("Invalid Transaction Type") @@ -172,7 +174,7 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo } // ApplyIncomingReceipt will add amount into ToAddress in the receipt -func ApplyIncomingReceipt(config *params.ChainConfig, db *state.DB, header *types.Header, cxp *types.CXReceiptsProof) error { +func ApplyIncomingReceipt(config *params.ChainConfig, db *state.DB, header *block.Header, cxp *types.CXReceiptsProof) error { if cxp == nil { return nil } diff --git a/core/tx_pool.go b/core/tx_pool.go index 95ed4c3a2..e7713f4fd 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -32,6 +32,7 @@ import ( "github.com/ethereum/go-ethereum/metrics" "github.com/harmony-one/harmony/internal/params" + "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/core/state" "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/internal/utils" @@ -360,7 +361,7 @@ func (pool *TxPool) loop() { // lockedReset is a wrapper around reset to allow calling it in a thread safe // manner. This method is only ever used in the tester! -func (pool *TxPool) lockedReset(oldHead, newHead *types.Header) { +func (pool *TxPool) lockedReset(oldHead, newHead *block.Header) { pool.mu.Lock() defer pool.mu.Unlock() @@ -369,7 +370,7 @@ func (pool *TxPool) lockedReset(oldHead, newHead *types.Header) { // reset retrieves the current state of the blockchain and ensures the content // of the transaction pool is valid with regard to the chain state. -func (pool *TxPool) reset(oldHead, newHead *types.Header) { +func (pool *TxPool) reset(oldHead, newHead *block.Header) { // If we're reorging an old state, reinject all dropped transactions var reinject types.Transactions diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go index fbd4f1644..f0ae49b58 100644 --- a/core/tx_pool_test.go +++ b/core/tx_pool_test.go @@ -30,6 +30,8 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" + + "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/common/denominations" "github.com/harmony-one/harmony/core/state" "github.com/harmony-one/harmony/core/types" @@ -52,7 +54,7 @@ type testBlockChain struct { } func (bc *testBlockChain) CurrentBlock() *types.Block { - return types.NewBlock(&types.Header{ + return types.NewBlock(&block.Header{ GasLimit: bc.gasLimit, }, nil, nil, nil, nil) } diff --git a/core/types/block.go b/core/types/block.go index a4ab795ec..e3e484d0d 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -24,16 +24,17 @@ import ( "sort" "sync/atomic" "time" - "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" - "golang.org/x/crypto/sha3" + "github.com/harmony-one/harmony/block" + "github.com/harmony-one/harmony/crypto/hash" "github.com/harmony-one/harmony/internal/utils" + "github.com/harmony-one/harmony/shard" ) // Constants for block. @@ -69,100 +70,18 @@ func (n *BlockNonce) UnmarshalText(input []byte) error { return hexutil.UnmarshalFixedText("BlockNonce", input, n[:]) } -// Header represents a block header in the Harmony blockchain. -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"` - 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"` -} - -// 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 rlpHash(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() (ShardState, error) { - shardState := ShardState{} - err := rlp.DecodeBytes(h.ShardState, &shardState) - if err != nil { - return nil, err - } - return shardState, nil -} - -func rlpHash(x interface{}) (h common.Hash) { - hw := sha3.NewLegacyKeccak256() - rlp.Encode(hw, x) - hw.Sum(h[:0]) - return h -} - // Body is a simple (mutable, non-safe) data container for storing and moving // a block's data contents (transactions and uncles) together. type Body struct { Transactions []*Transaction - Uncles []*Header + Uncles []*block.Header IncomingReceipts CXReceiptsProofs } // Block represents an entire block in the Ethereum blockchain. type Block struct { - header *Header - uncles []*Header + header *block.Header + uncles []*block.Header transactions Transactions incomingReceipts CXReceiptsProofs @@ -208,18 +127,18 @@ type StorageBlock Block // "external" block encoding. used for eth protocol, etc. type extblock struct { - Header *Header + Header *block.Header Txs []*Transaction - Uncles []*Header + Uncles []*block.Header IncomingReceipts CXReceiptsProofs } // [deprecated by eth/63] // "storage" block encoding. used for database. type storageblock struct { - Header *Header + Header *block.Header Txs []*Transaction - Uncles []*Header + Uncles []*block.Header TD *big.Int } @@ -230,7 +149,7 @@ type storageblock struct { // The values of TxHash, UncleHash, ReceiptHash and Bloom in header // are ignored and set to values derived from the given txs, // and receipts. -func NewBlock(header *Header, txs []*Transaction, receipts []*Receipt, outcxs []*CXReceipt, incxs []*CXReceiptsProof) *Block { +func NewBlock(header *block.Header, txs []*Transaction, receipts []*Receipt, outcxs []*CXReceipt, incxs []*CXReceiptsProof) *Block { b := &Block{header: CopyHeader(header)} // TODO: panic if len(txs) != len(receipts) @@ -265,13 +184,13 @@ func NewBlock(header *Header, txs []*Transaction, receipts []*Receipt, outcxs [] // NewBlockWithHeader creates a block with the given header data. The // header data is copied, changes to header and to the field values // will not affect the block. -func NewBlockWithHeader(header *Header) *Block { +func NewBlockWithHeader(header *block.Header) *Block { return &Block{header: CopyHeader(header)} } // CopyHeader creates a deep copy of a block header to prevent side effects from // modifying a header variable. -func CopyHeader(h *Header) *Header { +func CopyHeader(h *block.Header) *block.Header { // TODO: update with new fields cpy := *h if cpy.Time = new(big.Int); h.Time != nil { @@ -347,7 +266,7 @@ func (b *StorageBlock) DecodeRLP(s *rlp.Stream) error { } // Uncles return uncles. -func (b *Block) Uncles() []*Header { +func (b *Block) Uncles() []*block.Header { return b.uncles } @@ -420,7 +339,7 @@ func (b *Block) OutgoingReceiptHash() common.Hash { return b.header.OutgoingRece func (b *Block) Extra() []byte { return common.CopyBytes(b.header.Extra) } // Header returns a copy of Header. -func (b *Block) Header() *Header { return CopyHeader(b.header) } +func (b *Block) Header() *block.Header { return CopyHeader(b.header) } // Body returns the non-header content of the block. func (b *Block) Body() *Body { return &Body{b.transactions, b.uncles, b.incomingReceipts} } @@ -451,13 +370,13 @@ func (c *writeCounter) Write(b []byte) (int, error) { } // CalcUncleHash returns rlp hash of uncles. -func CalcUncleHash(uncles []*Header) common.Hash { - return rlpHash(uncles) +func CalcUncleHash(uncles []*block.Header) common.Hash { + return hash.FromRLP(uncles) } // WithSeal returns a new block with the data from b but the header replaced with // the sealed one. -func (b *Block) WithSeal(header *Header) *Block { +func (b *Block) WithSeal(header *block.Header) *Block { cpy := *header return &Block{ @@ -468,11 +387,11 @@ func (b *Block) WithSeal(header *Header) *Block { } // WithBody returns a new block with the given transaction and uncle contents. -func (b *Block) WithBody(transactions []*Transaction, uncles []*Header, incomingReceipts CXReceiptsProofs) *Block { +func (b *Block) WithBody(transactions []*Transaction, uncles []*block.Header, incomingReceipts CXReceiptsProofs) *Block { block := &Block{ header: CopyHeader(b.header), transactions: make([]*Transaction, len(transactions)), - uncles: make([]*Header, len(uncles)), + uncles: make([]*block.Header, len(uncles)), incomingReceipts: make([]*CXReceiptsProof, len(incomingReceipts)), } copy(block.transactions, transactions) @@ -546,8 +465,8 @@ func (b *Block) AddVdf(vdf []byte) { } // AddShardState add shardState into block header -func (b *Block) AddShardState(shardState ShardState) error { - // Make a copy because ShardState.Hash() internally sorts entries. +func (b *Block) AddShardState(shardState shard.State) error { + // Make a copy because State.Hash() internally sorts entries. // Store the sorted copy. shardState = append(shardState[:0:0], shardState...) b.header.ShardStateHash = shardState.Hash() diff --git a/core/types/block_test.go b/core/types/block_test.go index 4c4d358aa..6683664b6 100644 --- a/core/types/block_test.go +++ b/core/types/block_test.go @@ -20,6 +20,8 @@ package types import ( "bytes" "testing" + + "github.com/harmony-one/harmony/block" ) var ( @@ -94,7 +96,7 @@ func TestBlock_SetLastCommitSig(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - b := &Block{header: &Header{}} + b := &Block{header: &block.Header{}} b.SetLastCommitSig(tt.sig, tt.signers) if !bytes.Equal(tt.sig, b.header.LastCommitSignature[:]) { t.Errorf("signature mismatch: expected %+v, actual %+v", diff --git a/core/types/crosslink.go b/core/types/crosslink.go index 8540f2511..a298c3fc9 100644 --- a/core/types/crosslink.go +++ b/core/types/crosslink.go @@ -7,20 +7,22 @@ import ( "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/common" + + "github.com/harmony-one/harmony/block" ) // CrossLink is only used on beacon chain to store the hash links from other shards type CrossLink struct { - ChainHeader *Header + ChainHeader *block.Header } // NewCrossLink returns a new cross link object -func NewCrossLink(header *Header) CrossLink { +func NewCrossLink(header *block.Header) CrossLink { return CrossLink{header} } // Header returns header -func (cl CrossLink) Header() *Header { +func (cl CrossLink) Header() *block.Header { return cl.ChainHeader } diff --git a/core/types/transaction.go b/core/types/transaction.go index 757bf8a4a..4fc954f80 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -28,6 +28,8 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/rlp" + + "github.com/harmony-one/harmony/crypto/hash" common2 "github.com/harmony-one/harmony/internal/common" ) @@ -292,7 +294,7 @@ func (tx *Transaction) Hash() common.Hash { if hash := tx.hash.Load(); hash != nil { return hash.(common.Hash) } - v := rlpHash(tx) + v := hash.FromRLP(tx) tx.hash.Store(v) return v } diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index 5610eb31a..fbde4d676 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -24,6 +24,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" + + "github.com/harmony-one/harmony/crypto/hash" "github.com/harmony-one/harmony/internal/params" ) @@ -157,7 +159,7 @@ func (s EIP155Signer) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big // Hash returns the hash to be signed by the sender. // It does not uniquely identify the transaction. func (s EIP155Signer) Hash(tx *Transaction) common.Hash { - return rlpHash([]interface{}{ + return hash.FromRLP([]interface{}{ tx.data.AccountNonce, tx.data.Price, tx.data.GasLimit, @@ -215,7 +217,7 @@ func (fs FrontierSigner) SignatureValues(tx *Transaction, sig []byte) (r, s, v * // Hash returns the hash to be signed by the sender. // It does not uniquely identify the transaction. func (fs FrontierSigner) Hash(tx *Transaction) common.Hash { - return rlpHash([]interface{}{ + return hash.FromRLP([]interface{}{ tx.data.AccountNonce, tx.data.Price, tx.data.GasLimit, diff --git a/crypto/hash/rlp.go b/crypto/hash/rlp.go new file mode 100644 index 000000000..d0ba7052f --- /dev/null +++ b/crypto/hash/rlp.go @@ -0,0 +1,15 @@ +package hash + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rlp" + "golang.org/x/crypto/sha3" +) + +// FromRLP hashes the RLP representation of the given object. +func FromRLP(x interface{}) (h common.Hash) { + hw := sha3.NewLegacyKeccak256() + rlp.Encode(hw, x) + hw.Sum(h[:0]) + return h +} diff --git a/drand/drand_test.go b/drand/drand_test.go index e7b73492c..fd42c8320 100644 --- a/drand/drand_test.go +++ b/drand/drand_test.go @@ -7,6 +7,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/harmony-one/bls/ffi/go/bls" + + block2 "github.com/harmony-one/harmony/block" bls2 "github.com/harmony-one/harmony/crypto/bls" msg_pb "github.com/harmony-one/harmony/api/proto/message" @@ -126,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(&types.Header{Number: big.NewInt(314)}, txs, nil, nil, nil) + block := types.NewBlock(&block2.Header{Number: big.NewInt(314)}, txs, nil, nil, nil) blockHash := block.Hash() dRand.vrf(blockHash) diff --git a/hmy/api_backend.go b/hmy/api_backend.go index c1a960ffc..0ed8bd52a 100644 --- a/hmy/api_backend.go +++ b/hmy/api_backend.go @@ -12,8 +12,10 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/rpc" + "github.com/harmony-one/harmony/accounts" "github.com/harmony-one/harmony/api/proto" + "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core/state" "github.com/harmony-one/harmony/core/types" @@ -55,7 +57,7 @@ func (b *APIBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) } // StateAndHeaderByNumber ... -func (b *APIBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.DB, *types.Header, error) { +func (b *APIBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.DB, *block.Header, error) { // Pending state is only known by the miner if blockNr == rpc.PendingBlockNumber { return nil, nil, errors.New("not implemented") @@ -70,7 +72,7 @@ func (b *APIBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.Blo } // HeaderByNumber ... -func (b *APIBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) { +func (b *APIBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*block.Header, error) { // Pending block is only known by the miner if blockNr == rpc.PendingBlockNumber { return nil, errors.New("not implemented") @@ -139,7 +141,7 @@ func (b *APIBackend) GetLogs(ctx context.Context, blockHash common.Hash) ([][]*t } // HeaderByHash ... -func (b *APIBackend) HeaderByHash(ctx context.Context, blockHash common.Hash) (*types.Header, error) { +func (b *APIBackend) HeaderByHash(ctx context.Context, blockHash common.Hash) (*block.Header, error) { // TODO(ricl): implement return nil, nil } @@ -211,7 +213,7 @@ func (b *APIBackend) NetVersion() uint64 { } // GetEVM returns a new EVM entity -func (b *APIBackend) GetEVM(ctx context.Context, msg core.Message, state *state.DB, header *types.Header) (*vm.EVM, func() error, error) { +func (b *APIBackend) GetEVM(ctx context.Context, msg core.Message, state *state.DB, header *block.Header) (*vm.EVM, func() error, error) { // TODO(ricl): The code is borrowed from [go-ethereum](https://github.com/ethereum/go-ethereum/blob/40cdcf8c47ff094775aca08fd5d94051f9cf1dbb/les/api_backend.go#L114) // [question](https://ethereum.stackexchange.com/q/72977/54923) // Might need to reconsider the SetBalance behavior diff --git a/hmy/bloombits.go b/hmy/bloombits.go index adb23adb2..6e8729517 100644 --- a/hmy/bloombits.go +++ b/hmy/bloombits.go @@ -25,6 +25,8 @@ import ( "github.com/ethereum/go-ethereum/core/bloombits" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/ethdb" + + "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core/types" ) @@ -117,7 +119,7 @@ func (b *BloomIndexer) Reset(ctx context.Context, section uint64, lastSectionHea // Process implements core.ChainIndexerBackend, adding a new header's bloom into // the index. -func (b *BloomIndexer) Process(ctx context.Context, header *types.Header) error { +func (b *BloomIndexer) Process(ctx context.Context, header *block.Header) error { b.gen.AddBloom(uint(header.Number.Uint64()-b.section*b.size), header.Bloom) b.head = header.Hash() return nil diff --git a/hmyclient/hmyclient.go b/hmyclient/hmyclient.go index 7e000a8f4..9d75caaa4 100644 --- a/hmyclient/hmyclient.go +++ b/hmyclient/hmyclient.go @@ -6,10 +6,12 @@ import ( "fmt" "math/big" - ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/rpc" + + "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/core/types" ) @@ -96,7 +98,7 @@ func (c *Client) getBlock(ctx context.Context, method string, args ...interface{ return nil, ethereum.NotFound } // Decode header and transactions. - var head *types.Header + var head *block.Header var body rpcBlock if err := json.Unmarshal(raw, &head); err != nil { return nil, err @@ -119,7 +121,7 @@ func (c *Client) getBlock(ctx context.Context, method string, args ...interface{ } txs[i] = tx.tx } - return types.NewBlockWithHeader(head).WithBody(txs, []*types.Header{}, nil), nil + return types.NewBlockWithHeader(head).WithBody(txs, []*block.Header{}, nil), nil } func toBlockNumArg(number *big.Int) string { diff --git a/internal/chain/engine.go b/internal/chain/engine.go index 5c073a58d..3d877814d 100644 --- a/internal/chain/engine.go +++ b/internal/chain/engine.go @@ -9,6 +9,7 @@ import ( "github.com/pkg/errors" "golang.org/x/crypto/sha3" + "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/consensus/engine" "github.com/harmony-one/harmony/core/state" "github.com/harmony-one/harmony/core/types" @@ -22,7 +23,7 @@ type engineImpl struct{} var Engine = &engineImpl{} // SealHash returns the hash of a block prior to it being sealed. -func (e *engineImpl) SealHash(header *types.Header) (hash common.Hash) { +func (e *engineImpl) SealHash(header *block.Header) (hash common.Hash) { hasher := sha3.NewLegacyKeccak256() // TODO: update with new fields if err := rlp.Encode(hasher, []interface{}{ @@ -51,20 +52,20 @@ func (e *engineImpl) Seal(chain engine.ChainReader, block *types.Block, results } // Author returns the author of the block header. -func (e *engineImpl) Author(header *types.Header) (common.Address, error) { +func (e *engineImpl) Author(header *block.Header) (common.Address, error) { // TODO: implement this return common.Address{}, nil } // Prepare is to prepare ... // TODO(RJ): fix it. -func (e *engineImpl) Prepare(chain engine.ChainReader, header *types.Header) error { +func (e *engineImpl) Prepare(chain engine.ChainReader, header *block.Header) error { // TODO: implement prepare method return nil } // VerifyHeader checks whether a header conforms to the consensus rules of the bft engine. -func (e *engineImpl) VerifyHeader(chain engine.ChainReader, header *types.Header, seal bool) error { +func (e *engineImpl) VerifyHeader(chain engine.ChainReader, header *block.Header, seal bool) error { parentHeader := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) if parentHeader == nil { return engine.ErrUnknownAncestor @@ -80,7 +81,7 @@ func (e *engineImpl) VerifyHeader(chain engine.ChainReader, header *types.Header // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers // concurrently. The method returns a quit channel to abort the operations and // a results channel to retrieve the async verifications. -func (e *engineImpl) VerifyHeaders(chain engine.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) { +func (e *engineImpl) VerifyHeaders(chain engine.ChainReader, headers []*block.Header, seals []bool) (chan<- struct{}, <-chan error) { abort, results := make(chan struct{}), make(chan error, len(headers)) for i := 0; i < len(headers); i++ { results <- nil @@ -89,7 +90,7 @@ func (e *engineImpl) VerifyHeaders(chain engine.ChainReader, headers []*types.He } // retrievePublicKeysFromLastBlock finds the public keys of last block's committee -func retrievePublicKeysFromLastBlock(bc engine.ChainReader, header *types.Header) ([]*bls.PublicKey, error) { +func retrievePublicKeysFromLastBlock(bc engine.ChainReader, header *block.Header) ([]*bls.PublicKey, error) { parentHeader := bc.GetHeaderByHash(header.ParentHash) if parentHeader == nil { return nil, ctxerror.New("cannot find parent block header in DB", @@ -123,7 +124,7 @@ func retrievePublicKeysFromLastBlock(bc engine.ChainReader, header *types.Header // VerifySeal implements Engine, checking whether the given block satisfies // the PoS difficulty requirements, i.e. >= 2f+1 valid signatures from the committee -func (e *engineImpl) VerifySeal(chain engine.ChainReader, header *types.Header) error { +func (e *engineImpl) VerifySeal(chain engine.ChainReader, header *block.Header) error { if chain.CurrentHeader().Number.Uint64() <= uint64(1) { return nil } @@ -159,7 +160,7 @@ func (e *engineImpl) VerifySeal(chain engine.ChainReader, header *types.Header) // Finalize implements Engine, accumulating the block rewards, // setting the final state and assembling the block. -func (e *engineImpl) Finalize(chain engine.ChainReader, header *types.Header, state *state.DB, txs []*types.Transaction, receipts []*types.Receipt, outcxs []*types.CXReceipt, incxs []*types.CXReceiptsProof) (*types.Block, error) { +func (e *engineImpl) Finalize(chain engine.ChainReader, header *block.Header, state *state.DB, txs []*types.Transaction, receipts []*types.Receipt, outcxs []*types.CXReceipt, incxs []*types.CXReceiptsProof) (*types.Block, error) { // Accumulate any block and uncle rewards and commit the final state root // Header seems complete, assemble into a block and return if err := AccumulateRewards(chain, state, header); err != nil { @@ -171,7 +172,7 @@ func (e *engineImpl) Finalize(chain engine.ChainReader, header *types.Header, st // QuorumForBlock returns the quorum for the given block header. func QuorumForBlock( - chain engine.ChainReader, h *types.Header, + chain engine.ChainReader, h *block.Header, ) (quorum int, err error) { ss, err := chain.ReadShardState(h.Epoch) if err != nil { diff --git a/internal/chain/reward.go b/internal/chain/reward.go index 284727d42..d21179f75 100644 --- a/internal/chain/reward.go +++ b/internal/chain/reward.go @@ -6,10 +6,10 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/harmony-one/bls/ffi/go/bls" + "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/common/denominations" "github.com/harmony-one/harmony/consensus/engine" "github.com/harmony-one/harmony/core/state" - "github.com/harmony-one/harmony/core/types" bls2 "github.com/harmony-one/harmony/crypto/bls" common2 "github.com/harmony-one/harmony/internal/common" "github.com/harmony-one/harmony/internal/ctxerror" @@ -23,7 +23,7 @@ var BlockReward = new(big.Int).Mul(big.NewInt(24), big.NewInt(denominations.One) // reward. The total reward consists of the static block reward and rewards for // included uncles. The coinbase of each uncle block is also rewarded. func AccumulateRewards( - bc engine.ChainReader, state *state.DB, header *types.Header, + bc engine.ChainReader, state *state.DB, header *block.Header, ) error { blockNum := header.Number.Uint64() if blockNum == 0 { diff --git a/internal/hmyapi/backend.go b/internal/hmyapi/backend.go index f14ba8233..dad963882 100644 --- a/internal/hmyapi/backend.go +++ b/internal/hmyapi/backend.go @@ -9,7 +9,9 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/rpc" + "github.com/harmony-one/harmony/accounts" + "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core/state" "github.com/harmony-one/harmony/core/types" @@ -36,13 +38,13 @@ type Backend interface { // BlockChain API // SetHead(number uint64) - HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) + HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*block.Header, error) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error) - StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.DB, *types.Header, error) + StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.DB, *block.Header, error) GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error) GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error) // GetTd(blockHash common.Hash) *big.Int - GetEVM(ctx context.Context, msg core.Message, state *state.DB, header *types.Header) (*vm.EVM, func() error, error) + GetEVM(ctx context.Context, msg core.Message, state *state.DB, header *block.Header) (*vm.EVM, func() error, error) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription diff --git a/internal/hmyapi/filters/api.go b/internal/hmyapi/filters/api.go index 7ffec68d2..73becc174 100644 --- a/internal/hmyapi/filters/api.go +++ b/internal/hmyapi/filters/api.go @@ -6,11 +6,13 @@ import ( "sync" "time" - ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/rpc" + + "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/core/types" ) @@ -154,7 +156,7 @@ func (api *PublicFilterAPI) NewPendingTransactions(ctx context.Context) (*rpc.Su // https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_newblockfilter func (api *PublicFilterAPI) NewBlockFilter() rpc.ID { var ( - headers = make(chan *types.Header) + headers = make(chan *block.Header) headerSub = api.events.SubscribeNewHeads(headers) ) @@ -193,7 +195,7 @@ func (api *PublicFilterAPI) NewHeads(ctx context.Context) (*rpc.Subscription, er rpcSub := notifier.CreateSubscription() go func() { - headers := make(chan *types.Header) + headers := make(chan *block.Header) headersSub := api.events.SubscribeNewHeads(headers) for { diff --git a/internal/hmyapi/filters/filter.go b/internal/hmyapi/filters/filter.go index ee36badd9..2fd577607 100644 --- a/internal/hmyapi/filters/filter.go +++ b/internal/hmyapi/filters/filter.go @@ -27,6 +27,8 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/rpc" + + "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core/types" ) @@ -35,8 +37,8 @@ import ( type Backend interface { ChainDb() ethdb.Database EventMux() *event.TypeMux - HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) - HeaderByHash(ctx context.Context, blockHash common.Hash) (*types.Header, error) + HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*block.Header, error) + HeaderByHash(ctx context.Context, blockHash common.Hash) (*block.Header, error) GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error) GetLogs(ctx context.Context, blockHash common.Hash) ([][]*types.Log, error) @@ -232,7 +234,7 @@ func (f *Filter) unindexedLogs(ctx context.Context, end uint64) ([]*types.Log, e } // blockLogs returns the logs matching the filter criteria within a single block. -func (f *Filter) blockLogs(ctx context.Context, header *types.Header) (logs []*types.Log, err error) { +func (f *Filter) blockLogs(ctx context.Context, header *block.Header) (logs []*types.Log, err error) { if bloomFilter(header.Bloom, f.addresses, f.topics) { found, err := f.checkMatches(ctx, header) if err != nil { @@ -245,7 +247,7 @@ func (f *Filter) blockLogs(ctx context.Context, header *types.Header) (logs []*t // checkMatches checks if the receipts belonging to the given header contain any log events that // match the filter criteria. This function is called when the bloom filter signals a potential match. -func (f *Filter) checkMatches(ctx context.Context, header *types.Header) (logs []*types.Log, err error) { +func (f *Filter) checkMatches(ctx context.Context, header *block.Header) (logs []*types.Log, err error) { // Get the logs of the block logsList, err := f.backend.GetLogs(ctx, header.Hash()) if err != nil { diff --git a/internal/hmyapi/filters/filter_system.go b/internal/hmyapi/filters/filter_system.go index 470378e9e..44051cb79 100644 --- a/internal/hmyapi/filters/filter_system.go +++ b/internal/hmyapi/filters/filter_system.go @@ -24,11 +24,13 @@ import ( "sync" "time" - ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rpc" + + "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core/rawdb" "github.com/harmony-one/harmony/core/types" @@ -76,7 +78,7 @@ type subscription struct { logsCrit ethereum.FilterQuery logs chan []*types.Log hashes chan []common.Hash - headers chan *types.Header + headers chan *block.Header installed chan struct{} // closed when the filter is installed err chan error // closed when the filter is uninstalled } @@ -87,7 +89,7 @@ type EventSystem struct { mux *event.TypeMux backend Backend lightMode bool - lastHead *types.Header + lastHead *block.Header // Subscriptions txsSub event.Subscription // Subscription for new transaction event @@ -236,7 +238,7 @@ func (es *EventSystem) subscribeMinedPendingLogs(crit ethereum.FilterQuery, logs created: time.Now(), logs: logs, hashes: make(chan []common.Hash), - headers: make(chan *types.Header), + headers: make(chan *block.Header), installed: make(chan struct{}), err: make(chan error), } @@ -253,7 +255,7 @@ func (es *EventSystem) subscribeLogs(crit ethereum.FilterQuery, logs chan []*typ created: time.Now(), logs: logs, hashes: make(chan []common.Hash), - headers: make(chan *types.Header), + headers: make(chan *block.Header), installed: make(chan struct{}), err: make(chan error), } @@ -270,7 +272,7 @@ func (es *EventSystem) subscribePendingLogs(crit ethereum.FilterQuery, logs chan created: time.Now(), logs: logs, hashes: make(chan []common.Hash), - headers: make(chan *types.Header), + headers: make(chan *block.Header), installed: make(chan struct{}), err: make(chan error), } @@ -279,7 +281,7 @@ func (es *EventSystem) subscribePendingLogs(crit ethereum.FilterQuery, logs chan // SubscribeNewHeads creates a subscription that writes the header of a block that is // imported in the chain. -func (es *EventSystem) SubscribeNewHeads(headers chan *types.Header) *Subscription { +func (es *EventSystem) SubscribeNewHeads(headers chan *block.Header) *Subscription { sub := &subscription{ id: rpc.NewID(), typ: BlocksSubscription, @@ -302,7 +304,7 @@ func (es *EventSystem) SubscribePendingTxs(hashes chan []common.Hash) *Subscript created: time.Now(), logs: make(chan []*types.Log), hashes: hashes, - headers: make(chan *types.Header), + headers: make(chan *block.Header), installed: make(chan struct{}), err: make(chan error), } @@ -355,7 +357,7 @@ func (es *EventSystem) broadcast(filters filterIndex, ev interface{}) { f.headers <- e.Block.Header() } if es.lightMode && len(filters[LogsSubscription]) > 0 { - es.lightFilterNewHead(e.Block.Header(), func(header *types.Header, remove bool) { + es.lightFilterNewHead(e.Block.Header(), func(header *block.Header, remove bool) { for _, f := range filters[LogsSubscription] { if matchedLogs := es.lightFilterLogs(header, f.logsCrit.Addresses, f.logsCrit.Topics, remove); len(matchedLogs) > 0 { f.logs <- matchedLogs @@ -366,7 +368,7 @@ func (es *EventSystem) broadcast(filters filterIndex, ev interface{}) { } } -func (es *EventSystem) lightFilterNewHead(newHeader *types.Header, callBack func(*types.Header, bool)) { +func (es *EventSystem) lightFilterNewHead(newHeader *block.Header, callBack func(*block.Header, bool)) { oldh := es.lastHead es.lastHead = newHeader if oldh == nil { @@ -374,7 +376,7 @@ func (es *EventSystem) lightFilterNewHead(newHeader *types.Header, callBack func } newh := newHeader // find common ancestor, create list of rolled back and new block hashes - var oldHeaders, newHeaders []*types.Header + var oldHeaders, newHeaders []*block.Header for oldh.Hash() != newh.Hash() { if oldh.Number.Uint64() >= newh.Number.Uint64() { oldHeaders = append(oldHeaders, oldh) @@ -400,7 +402,7 @@ func (es *EventSystem) lightFilterNewHead(newHeader *types.Header, callBack func } // filter logs of a single header in light client mode -func (es *EventSystem) lightFilterLogs(header *types.Header, addresses []common.Address, topics [][]common.Hash, remove bool) []*types.Log { +func (es *EventSystem) lightFilterLogs(header *block.Header, addresses []common.Address, topics [][]common.Hash, remove bool) []*types.Log { if bloomFilter(header.Bloom, addresses, topics) { // Get the logs of the block ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) diff --git a/node/node.go b/node/node.go index ad6e90f5d..70ffc77a2 100644 --- a/node/node.go +++ b/node/node.go @@ -18,6 +18,7 @@ import ( "github.com/harmony-one/harmony/api/service" "github.com/harmony-one/harmony/api/service/syncing" "github.com/harmony-one/harmony/api/service/syncing/downloader" + "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/consensus" "github.com/harmony-one/harmony/contracts" "github.com/harmony-one/harmony/contracts/structs" @@ -32,6 +33,7 @@ import ( "github.com/harmony-one/harmony/node/worker" "github.com/harmony-one/harmony/p2p" p2p_host "github.com/harmony-one/harmony/p2p/host" + "github.com/harmony-one/harmony/shard" ) // State is a state of a node. @@ -95,7 +97,7 @@ type Node struct { ConfirmedBlockChannel chan *types.Block // The channel to send confirmed blocks BeaconBlockChannel chan *types.Block // The channel to send beacon blocks for non-beaconchain nodes DRand *drand.DRand // The instance for distributed randomness protocol - pendingCrossLinks []*types.Header + pendingCrossLinks []*block.Header pendingClMutex sync.Mutex pendingCXReceipts []*types.CXReceiptsProof // All the receipts received but not yet processed for Consensus @@ -201,7 +203,7 @@ type Node struct { // Next shard state nextShardState struct { // The received master shard state - master *types.EpochShardState + master *shard.EpochShardState // When for a leader to propose the next shard state, // or for a validator to wait for a proposal before view change. diff --git a/node/node_cross_shard.go b/node/node_cross_shard.go index 313487028..35c64ab57 100644 --- a/node/node_cross_shard.go +++ b/node/node_cross_shard.go @@ -9,6 +9,8 @@ import ( "github.com/ethereum/go-ethereum/rlp" "github.com/harmony-one/bls/ffi/go/bls" + + "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core/types" bls_cosi "github.com/harmony-one/harmony/crypto/bls" @@ -20,7 +22,7 @@ import ( func (node *Node) ProcessHeaderMessage(msgPayload []byte) { if node.NodeConfig.ShardID == 0 { - var headers []*types.Header + var headers []*block.Header err := rlp.DecodeBytes(msgPayload, &headers) if err != nil { utils.Logger().Error(). @@ -32,7 +34,7 @@ func (node *Node) ProcessHeaderMessage(msgPayload []byte) { // Try to reprocess all the pending cross links node.pendingClMutex.Lock() crossLinkHeadersToProcess := node.pendingCrossLinks - node.pendingCrossLinks = []*types.Header{} + node.pendingCrossLinks = []*block.Header{} node.pendingClMutex.Unlock() firstCrossLinkBlock := core.ShardingSchedule.FirstCrossLinkBlock() @@ -46,7 +48,7 @@ func (node *Node) ProcessHeaderMessage(msgPayload []byte) { utils.Logger().Debug(). Msgf("[ProcessingHeader] number of crosslink headers to propose %d, firstCrossLinkBlock %d", len(crossLinkHeadersToProcess), firstCrossLinkBlock) - headersToQuque := []*types.Header{} + headersToQuque := []*block.Header{} for _, header := range crossLinkHeadersToProcess { if len(headersToQuque) > crossLinkBatchSize { @@ -156,7 +158,7 @@ func (node *Node) compareCrosslinkWithReceipts(cxp *types.CXReceiptsProof) error } // VerifyCrosslinkHeader verifies the header is valid against the prevHeader. -func (node *Node) VerifyCrosslinkHeader(prevHeader, header *types.Header) error { +func (node *Node) VerifyCrosslinkHeader(prevHeader, header *block.Header) error { // TODO: add fork choice rule if prevHeader.Hash() != header.ParentHash { diff --git a/node/node_genesis.go b/node/node_genesis.go index f327b71ae..f197dcd93 100644 --- a/node/node_genesis.go +++ b/node/node_genesis.go @@ -9,17 +9,17 @@ import ( "github.com/ethereum/go-ethereum/common" - nodeconfig "github.com/harmony-one/harmony/internal/configs/node" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" + "github.com/harmony-one/harmony/common/denominations" "github.com/harmony-one/harmony/core" - "github.com/harmony-one/harmony/core/types" common2 "github.com/harmony-one/harmony/internal/common" + nodeconfig "github.com/harmony-one/harmony/internal/configs/node" "github.com/harmony-one/harmony/internal/genesis" "github.com/harmony-one/harmony/internal/params" "github.com/harmony-one/harmony/internal/utils" + "github.com/harmony-one/harmony/shard" ) const ( @@ -47,14 +47,14 @@ func (gi *genesisInitializer) InitChainDB(db ethdb.Database, shardID uint32) err if c == nil { return errors.New("cannot find local shard in genesis") } - shardState = types.ShardState{*c} + shardState = shard.State{*c} } gi.node.SetupGenesisBlock(db, shardID, shardState) return nil } // SetupGenesisBlock sets up a genesis blockchain. -func (node *Node) SetupGenesisBlock(db ethdb.Database, shardID uint32, myShardState types.ShardState) { +func (node *Node) SetupGenesisBlock(db ethdb.Database, shardID uint32, myShardState shard.State) { utils.Logger().Info().Interface("shardID", shardID).Msg("setting up a brand new chain database") if shardID == node.NodeConfig.ShardID { node.isFirstTime = true diff --git a/node/node_handler.go b/node/node_handler.go index f73740e9b..7a35bef71 100644 --- a/node/node_handler.go +++ b/node/node_handler.go @@ -25,6 +25,7 @@ import ( proto_discovery "github.com/harmony-one/harmony/api/proto/discovery" "github.com/harmony-one/harmony/api/proto/message" proto_node "github.com/harmony-one/harmony/api/proto/node" + "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/contracts/structs" "github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core/types" @@ -33,6 +34,7 @@ import ( "github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/p2p" "github.com/harmony-one/harmony/p2p/host" + "github.com/harmony-one/harmony/shard" ) const ( @@ -264,7 +266,7 @@ func (node *Node) BroadcastNewBlock(newBlock *types.Block) { // BroadcastCrossLinkHeader is called by consensus leader to send the new header as cross link to beacon chain. func (node *Node) BroadcastCrossLinkHeader(newBlock *types.Block) { utils.Logger().Info().Msgf("Broadcasting new header to beacon chain groupID %s", node.NodeConfig.GetBeaconGroupID()) - headers := []*types.Header{} + headers := []*block.Header{} lastLink, err := node.Beaconchain().ReadShardLastCrossLink(newBlock.ShardID()) var latestBlockNum uint64 @@ -472,7 +474,7 @@ func (node *Node) validateNewShardState(block *types.Block, stakeInfo *map[commo // We aren't expecting to reshard, so proceed to sign return nil } - shardState := &types.ShardState{} + shardState := &shard.State{} err := rlp.DecodeBytes(header.ShardState, shardState) if err != nil { return err @@ -491,7 +493,7 @@ func (node *Node) validateNewShardState(block *types.Block, stakeInfo *map[commo return ctxerror.New("cannot calculate expected shard state"). WithCause(err) } - if types.CompareShardState(expected, proposed) != 0 { + if shard.CompareShardState(expected, proposed) != 0 { // TODO ek – log state proposal differences // TODO ek – this error should trigger view change err := errors.New("shard state proposal is different from expected") @@ -538,7 +540,7 @@ func (node *Node) validateNewShardState(block *types.Block, stakeInfo *map[commo "leader proposed to continue against beacon decision") } // Did beaconchain say the same proposal? - if types.CompareCommittee(expected, &proposed) != 0 { + if shard.CompareCommittee(expected, &proposed) != 0 { // TODO ek – log differences // TODO ek – invoke view change return errors.New("proposal differs from one in beacon chain") @@ -647,7 +649,7 @@ func (node *Node) broadcastEpochShardState(newBlock *types.Block) error { return err } epochShardStateMessage := proto_node.ConstructEpochShardStateMessage( - types.EpochShardState{ + shard.EpochShardState{ Epoch: newBlock.Header().Epoch.Uint64() + 1, ShardState: shardState, }, @@ -679,13 +681,13 @@ func (node *Node) AddNewBlock(newBlock *types.Block) error { type genesisNode struct { ShardID uint32 MemberIndex int - NodeID types.NodeID + NodeID shard.NodeID } var ( genesisCatalogOnce sync.Once genesisNodeByStakingAddress = make(map[common.Address]*genesisNode) - genesisNodeByConsensusKey = make(map[types.BlsPublicKey]*genesisNode) + genesisNodeByConsensusKey = make(map[shard.BlsPublicKey]*genesisNode) ) func initGenesisCatalog() { @@ -708,7 +710,7 @@ func getGenesisNodeByStakingAddress(address common.Address) *genesisNode { return genesisNodeByStakingAddress[address] } -func getGenesisNodeByConsensusKey(key types.BlsPublicKey) *genesisNode { +func getGenesisNodeByConsensusKey(key shard.BlsPublicKey) *genesisNode { genesisCatalogOnce.Do(initGenesisCatalog) return genesisNodeByConsensusKey[key] } @@ -832,7 +834,7 @@ func (node *Node) epochShardStateMessageHandler(msgPayload []byte) error { } /* -func (node *Node) transitionIntoNextEpoch(shardState types.ShardState) { +func (node *Node) transitionIntoNextEpoch(shardState types.State) { logger = logger.New( "blsPubKey", hex.EncodeToString(node.Consensus.PubKey.Serialize()), "curShard", node.Blockchain().ShardID(), @@ -884,7 +886,7 @@ func (node *Node) transitionIntoNextEpoch(shardState types.ShardState) { */ func findRoleInShardState( - key *bls.PublicKey, state types.ShardState, + key *bls.PublicKey, state shard.State, ) (shardID uint32, isLeader bool) { keyBytes := key.Serialize() for idx, shard := range state { diff --git a/node/node_newblock.go b/node/node_newblock.go index 53a7193f5..e880e43a4 100644 --- a/node/node_newblock.go +++ b/node/node_newblock.go @@ -8,10 +8,12 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/rlp" + "github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/internal/ctxerror" "github.com/harmony-one/harmony/internal/utils" + "github.com/harmony-one/harmony/shard" ) // Constants of lower bound limit of a new block. @@ -193,7 +195,7 @@ func (node *Node) proposeLocalShardState(block *types.Block) { return } masterShardState := node.nextShardState.master.ShardState - var localShardState types.ShardState + var localShardState shard.State committee := masterShardState.FindCommitteeByID(block.ShardID()) if committee != nil { logger.Info().Msg("found local shard info; proposing it") diff --git a/node/staking.go b/node/staking.go index 4d43297c9..0252b7e7f 100644 --- a/node/staking.go +++ b/node/staking.go @@ -4,13 +4,14 @@ import ( "encoding/hex" "math/big" - "github.com/harmony-one/harmony/core/types" + "github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/contracts/structs" "github.com/harmony-one/harmony/core" "github.com/ethereum/go-ethereum/common" + "github.com/harmony-one/harmony/internal/utils" "github.com/ethereum/go-ethereum/common/hexutil" @@ -45,7 +46,7 @@ func (node *Node) UpdateStakingList(stakeInfoReturnValue *structs.StakeInfoRetur } // True if the token is still staked within the locking period. if curEpoch-startEpoch <= lockPeriodCount.Uint64()*lockPeriodInEpochs { - blsPubKey := types.BlsPublicKey{} + blsPubKey := shard.BlsPublicKey{} copy(blsPubKey[:32], stakeInfoReturnValue.BlsPubicKeys1[i][:]) copy(blsPubKey[32:48], stakeInfoReturnValue.BlsPubicKeys2[i][:16]) node.CurrentStakes[addr] = &structs.StakeInfo{ diff --git a/node/worker/worker.go b/node/worker/worker.go index 261c6ee91..3d9a39611 100644 --- a/node/worker/worker.go +++ b/node/worker/worker.go @@ -8,6 +8,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/harmony-one/harmony/internal/params" + "github.com/harmony-one/harmony/block" consensus_engine "github.com/harmony-one/harmony/consensus/engine" "github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core/state" @@ -24,7 +25,7 @@ type environment struct { state *state.DB // apply state changes here gasPool *core.GasPool // available gas used to pack transactions - header *types.Header + header *block.Header txs []*types.Transaction receipts []*types.Receipt outcxs []*types.CXReceipt // cross shard transaction receipts (source shard) @@ -211,7 +212,7 @@ 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 := &types.Header{ + header := &block.Header{ ParentHash: parent.Hash(), Number: num.Add(num, common.Big1), GasLimit: core.CalcGasLimit(parent, w.gasFloor, w.gasCeil), @@ -224,7 +225,7 @@ func (w *Worker) UpdateCurrent(coinbase common.Address) error { } // makeCurrent creates a new environment for the current cycle. -func (w *Worker) makeCurrent(parent *types.Block, header *types.Header) error { +func (w *Worker) makeCurrent(parent *types.Block, header *block.Header) error { state, err := w.chain.StateAt(parent.Root()) if err != nil { return err @@ -306,7 +307,7 @@ 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 := &types.Header{ + header := &block.Header{ ParentHash: parent.Hash(), Number: num.Add(num, common.Big1), GasLimit: core.CalcGasLimit(parent, worker.gasFloor, worker.gasCeil), diff --git a/core/types/shard_state.go b/shard/shard_state.go similarity index 91% rename from core/types/shard_state.go rename to shard/shard_state.go index e484cfa00..09846dc4d 100644 --- a/core/types/shard_state.go +++ b/shard/shard_state.go @@ -1,4 +1,4 @@ -package types +package shard import ( "bytes" @@ -16,15 +16,15 @@ import ( // EpochShardState is the shard state of an epoch type EpochShardState struct { Epoch uint64 - ShardState ShardState + ShardState State } -// ShardState is the collection of all committees -type ShardState []Committee +// State is the collection of all committees +type State []Committee // FindCommitteeByID returns the committee configuration for the given shard, // or nil if the given shard is not found. -func (ss ShardState) FindCommitteeByID(shardID uint32) *Committee { +func (ss State) FindCommitteeByID(shardID uint32) *Committee { for _, committee := range ss { if committee.ShardID == shardID { return &committee @@ -34,16 +34,16 @@ func (ss ShardState) FindCommitteeByID(shardID uint32) *Committee { } // DeepCopy returns a deep copy of the receiver. -func (ss ShardState) DeepCopy() ShardState { - var r ShardState +func (ss State) DeepCopy() State { + var r State for _, c := range ss { r = append(r, c.DeepCopy()) } return r } -// CompareShardState compares two ShardState instances. -func CompareShardState(s1, s2 ShardState) int { +// CompareShardState compares two State instances. +func CompareShardState(s1, s2 State) int { commonLen := len(s1) if commonLen > len(s2) { commonLen = len(s2) @@ -180,8 +180,8 @@ func GetHashFromNodeList(nodeList []NodeID) []byte { return d.Sum(nil) } -// Hash is the root hash of ShardState -func (ss ShardState) Hash() (h common.Hash) { +// Hash is the root hash of State +func (ss State) Hash() (h common.Hash) { // TODO ek – this sorting really doesn't belong here; it should instead // be made an explicit invariant to be maintained and, if needed, checked. copy := ss.DeepCopy() diff --git a/core/types/shard_state_test.go b/shard/shard_state_test.go similarity index 95% rename from core/types/shard_state_test.go rename to shard/shard_state_test.go index 1d29ddd38..707b1a335 100644 --- a/core/types/shard_state_test.go +++ b/shard/shard_state_test.go @@ -1,4 +1,4 @@ -package types +package shard import ( "bytes" @@ -65,7 +65,7 @@ func TestHash(t *testing.T) { {common.Address{0x66}, blsPubKey6}, }, } - shardState1 := ShardState{com1, com2} + shardState1 := State{com1, com2} h1 := shardState1.Hash() com3 := Committee{ @@ -85,7 +85,7 @@ func TestHash(t *testing.T) { }, } - shardState2 := ShardState{com3, com4} + shardState2 := State{com3, com4} h2 := shardState2.Hash() if bytes.Compare(h1[:], h2[:]) != 0 {