Skip to content

Commit

Permalink
dot/state: update BlockState finalized block methods to accept setID (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
noot authored Aug 12, 2020
1 parent 0eb72fb commit 202ed5f
Show file tree
Hide file tree
Showing 20 changed files with 76 additions and 62 deletions.
12 changes: 6 additions & 6 deletions dot/core/digest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func TestDigestHandler_BABEScheduledChange(t *testing.T) {

headers := addTestBlocksToState(t, 2, handler.blockState)
for _, h := range headers {
handler.blockState.SetFinalizedHash(h.Hash(), 0)
handler.blockState.SetFinalizedHash(h.Hash(), 0, 0)
}

auths := handler.babe.Authorities()
Expand All @@ -97,7 +97,7 @@ func TestDigestHandler_BABEScheduledChange(t *testing.T) {
// authorities should change on start of block 3 from start
headers = addTestBlocksToState(t, 1, handler.blockState)
for _, h := range headers {
handler.blockState.SetFinalizedHash(h.Hash(), 0)
handler.blockState.SetFinalizedHash(h.Hash(), 0, 0)
}

time.Sleep(time.Millisecond * 100)
Expand Down Expand Up @@ -222,7 +222,7 @@ func TestDigestHandler_BABEPauseAndResume(t *testing.T) {

headers := addTestBlocksToState(t, 3, handler.blockState)
for _, h := range headers {
handler.blockState.SetFinalizedHash(h.Hash(), 0)
handler.blockState.SetFinalizedHash(h.Hash(), 0, 0)
}

time.Sleep(time.Millisecond * 100)
Expand Down Expand Up @@ -279,7 +279,7 @@ func TestDigestHandler_GrandpaScheduledChange(t *testing.T) {

headers := addTestBlocksToState(t, 2, handler.blockState)
for _, h := range headers {
handler.blockState.SetFinalizedHash(h.Hash(), 0)
handler.blockState.SetFinalizedHash(h.Hash(), 0, 0)
}

auths := handler.grandpa.Authorities()
Expand All @@ -288,7 +288,7 @@ func TestDigestHandler_GrandpaScheduledChange(t *testing.T) {
// authorities should change on start of block 3 from start
headers = addTestBlocksToState(t, 1, handler.blockState)
for _, h := range headers {
handler.blockState.SetFinalizedHash(h.Hash(), 0)
handler.blockState.SetFinalizedHash(h.Hash(), 0, 0)
}

time.Sleep(time.Millisecond * 100)
Expand Down Expand Up @@ -413,7 +413,7 @@ func TestDigestHandler_GrandpaPauseAndResume(t *testing.T) {

headers := addTestBlocksToState(t, 3, handler.blockState)
for _, h := range headers {
handler.blockState.SetFinalizedHash(h.Hash(), 0)
handler.blockState.SetFinalizedHash(h.Hash(), 0, 0)
}

time.Sleep(time.Millisecond * 100)
Expand Down
6 changes: 3 additions & 3 deletions dot/core/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ type BlockState interface {
GetSlotForBlock(common.Hash) (uint64, error)
HighestBlockHash() common.Hash
HighestBlockNumber() *big.Int
GetFinalizedHeader(uint64) (*types.Header, error)
GetFinalizedHash(uint64) (common.Hash, error)
SetFinalizedHash(common.Hash, uint64) error
GetFinalizedHeader(uint64, uint64) (*types.Header, error)
GetFinalizedHash(uint64, uint64) (common.Hash, error)
SetFinalizedHash(common.Hash, uint64, uint64) error
RegisterImportedChannel(ch chan<- *types.Block) (byte, error)
UnregisterImportedChannel(id byte)
RegisterFinalizedChannel(ch chan<- *types.Header) (byte, error)
Expand Down
2 changes: 1 addition & 1 deletion dot/rpc/modules/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type BlockAPI interface {
BestBlockHash() common.Hash
GetBlockByHash(hash common.Hash) (*types.Block, error)
GetBlockHash(blockNumber *big.Int) (*common.Hash, error)
GetFinalizedHash(uint64) (common.Hash, error)
GetFinalizedHash(uint64, uint64) (common.Hash, error)
RegisterImportedChannel(ch chan<- *types.Block) (byte, error)
UnregisterImportedChannel(id byte)
}
Expand Down
10 changes: 6 additions & 4 deletions dot/rpc/modules/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func (cm *ChainModule) GetHead(r *http.Request, req *ChainBlockNumberRequest, re

// GetFinalizedHead returns the most recently finalized block hash
func (cm *ChainModule) GetFinalizedHead(r *http.Request, req *EmptyRequest, res *ChainHashResponse) error {
h, err := cm.blockAPI.GetFinalizedHash(0)
h, err := cm.blockAPI.GetFinalizedHash(0, 0)
if err != nil {
return err
}
Expand All @@ -139,9 +139,11 @@ func (cm *ChainModule) GetFinalizedHead(r *http.Request, req *EmptyRequest, res
return nil
}

// GetFinalizedHeadByRound returns the hash of the block finalized at the given round
func (cm *ChainModule) GetFinalizedHeadByRound(r *http.Request, req *ChainIntRequest, res *ChainHashResponse) error {
h, err := cm.blockAPI.GetFinalizedHash(uint64(*req))
// GetFinalizedHeadByRound returns the hash of the block finalized at the given round and setID
func (cm *ChainModule) GetFinalizedHeadByRound(r *http.Request, req *[]ChainIntRequest, res *ChainHashResponse) error {
round := (uint64)((*req)[0])
setID := (uint64)((*req)[1])
h, err := cm.blockAPI.GetFinalizedHash(round, setID)
if err != nil {
return err
}
Expand Down
6 changes: 3 additions & 3 deletions dot/rpc/modules/chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,17 +233,17 @@ func TestChainGetFinalizedHeadByRound(t *testing.T) {
svc := NewChainModule(chain.Block)

var res ChainHashResponse
req := ChainIntRequest(0)
req := []ChainIntRequest{0, 0}
err := svc.GetFinalizedHeadByRound(nil, &req, &res)
require.NoError(t, err)
expected := genesisHeader.Hash()
require.Equal(t, common.BytesToHex(expected[:]), res)

testhash := common.Hash{1, 2, 3, 4}
err = chain.Block.SetFinalizedHash(testhash, 77)
err = chain.Block.SetFinalizedHash(testhash, 77, 1)
require.NoError(t, err)

req = ChainIntRequest(77)
req = []ChainIntRequest{77, 1}
err = svc.GetFinalizedHeadByRound(nil, &req, &res)
require.NoError(t, err)
require.Equal(t, common.BytesToHex(testhash[:]), res)
Expand Down
2 changes: 1 addition & 1 deletion dot/rpc/websocket_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func (m *MockBlockAPI) GetBlockByHash(hash common.Hash) (*types.Block, error) {
func (m *MockBlockAPI) GetBlockHash(blockNumber *big.Int) (*common.Hash, error) {
return nil, nil
}
func (m *MockBlockAPI) GetFinalizedHash(uint64) (common.Hash, error) {
func (m *MockBlockAPI) GetFinalizedHash(uint64, uint64) (common.Hash, error) {
return common.Hash{}, nil
}
func (m *MockBlockAPI) RegisterImportedChannel(ch chan<- *types.Block) (byte, error) {
Expand Down
1 change: 1 addition & 0 deletions dot/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ func createGRANDPAService(cfg *Config, rt *runtime.Runtime, st *state.Service, d
LogLvl: lvl,
BlockState: st.Block,
DigestHandler: dh,
SetID: 1,
Voters: voters,
Keypair: keys[0].(*ed25519.Keypair),
}
Expand Down
23 changes: 13 additions & 10 deletions dot/state/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ func NewBlockStateFromGenesis(db chaindb.Database, header *types.Header) (*Block
bs.genesisHash = header.Hash()

// set the latest finalized head to the genesis header
err = bs.SetFinalizedHash(bs.genesisHash, 0)
err = bs.SetFinalizedHash(bs.genesisHash, 0, 0)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -194,11 +194,13 @@ func arrivalTimeKey(hash common.Hash) []byte {
return append(arrivalTimePrefix, hash.ToBytes()...)
}

// finalizedHashKey = hashkey + round (LE encoded)
func finalizedHashKey(round uint64) []byte {
// finalizedHashKey = hashkey + round + setID (LE encoded)
func finalizedHashKey(round, setID uint64) []byte {
buf := make([]byte, 8)
binary.LittleEndian.PutUint64(buf, round)
return append(common.FinalizedBlockHashKey, buf...)
key := append(common.FinalizedBlockHashKey, buf...)
binary.LittleEndian.PutUint64(buf, setID)
return append(key, buf...)
}

// GenesisHash returns the hash of the genesis block
Expand Down Expand Up @@ -397,8 +399,8 @@ func (bs *BlockState) SetBlockBody(hash common.Hash, body *types.Body) error {
}

// GetFinalizedHeader returns the latest finalized block header
func (bs *BlockState) GetFinalizedHeader(round uint64) (*types.Header, error) {
h, err := bs.GetFinalizedHash(round)
func (bs *BlockState) GetFinalizedHeader(round, setID uint64) (*types.Header, error) {
h, err := bs.GetFinalizedHash(round, setID)
if err != nil {
return nil, err
}
Expand All @@ -412,7 +414,8 @@ func (bs *BlockState) GetFinalizedHeader(round uint64) (*types.Header, error) {
}

// GetFinalizedHash gets the latest finalized block header
func (bs *BlockState) GetFinalizedHash(round uint64) (common.Hash, error) {
func (bs *BlockState) GetFinalizedHash(round, setID uint64) (common.Hash, error) {
// get current round
r, err := bs.GetRound()
if err != nil {
return common.Hash{}, err
Expand All @@ -423,7 +426,7 @@ func (bs *BlockState) GetFinalizedHash(round uint64) (common.Hash, error) {
return common.Hash{}, fmt.Errorf("round not yet finalized")
}

h, err := bs.db.Get(finalizedHashKey(round))
h, err := bs.db.Get(finalizedHashKey(round, setID))
if err != nil {
return common.Hash{}, err
}
Expand All @@ -432,7 +435,7 @@ func (bs *BlockState) GetFinalizedHash(round uint64) (common.Hash, error) {
}

// SetFinalizedHash sets the latest finalized block header
func (bs *BlockState) SetFinalizedHash(hash common.Hash, round uint64) error {
func (bs *BlockState) SetFinalizedHash(hash common.Hash, round, setID uint64) error {
go bs.notifyFinalized(hash)
if round > 0 {
err := bs.SetRound(round)
Expand All @@ -449,7 +452,7 @@ func (bs *BlockState) SetFinalizedHash(hash common.Hash, round uint64) error {
}
}

return bs.db.Put(finalizedHashKey(round), hash[:])
return bs.db.Put(finalizedHashKey(round, setID), hash[:])
}

// SetRound sets the latest finalized GRANDPA round in the db
Expand Down
4 changes: 2 additions & 2 deletions dot/state/block_notify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func TestFinalizedChannel(t *testing.T) {
chain, _ := AddBlocksToState(t, bs, 3)

for _, b := range chain {
bs.SetFinalizedHash(b.Hash(), 0)
bs.SetFinalizedHash(b.Hash(), 0, 0)
}

for i := 0; i < 1; i++ {
Expand Down Expand Up @@ -128,7 +128,7 @@ func TestFinalizedChannel_Multi(t *testing.T) {
}

chain, _ := AddBlocksToState(t, bs, 1)
bs.SetFinalizedHash(chain[0].Hash(), 0)
bs.SetFinalizedHash(chain[0].Hash(), 0, 0)

var wg sync.WaitGroup
wg.Add(num)
Expand Down
8 changes: 4 additions & 4 deletions dot/state/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,15 +270,15 @@ func TestAddBlock_BlockNumberToHash(t *testing.T) {

func TestFinalizedHash(t *testing.T) {
bs := newTestBlockState(t, testGenesisHeader)
h, err := bs.GetFinalizedHash(0)
h, err := bs.GetFinalizedHash(0, 0)
require.NoError(t, err)
require.Equal(t, testGenesisHeader.Hash(), h)

testhash := common.Hash{1, 2, 3, 4}
err = bs.SetFinalizedHash(testhash, 1)
err = bs.SetFinalizedHash(testhash, 1, 1)
require.NoError(t, err)

h, err = bs.GetFinalizedHash(1)
h, err = bs.GetFinalizedHash(1, 1)
require.NoError(t, err)
require.Equal(t, testhash, h)
}
Expand All @@ -304,7 +304,7 @@ func TestFinalization_DeleteBlock(t *testing.T) {

// pick block to finalize
fin := leaves[len(leaves)-1]
err := bs.SetFinalizedHash(fin, 1)
err := bs.SetFinalizedHash(fin, 1, 1)
require.NoError(t, err)

// assert that every block except finalized has been deleted
Expand Down
2 changes: 1 addition & 1 deletion lib/babe/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ func (b *Service) buildBlockInherents(slot Slot) error {
}

// add finalnum
fin, err := b.blockState.GetFinalizedHeader(0)
fin, err := b.blockState.GetFinalizedHeader(0, 0)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion lib/babe/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type BlockState interface {
GetSlotForBlock(common.Hash) (uint64, error)
HighestBlockHash() common.Hash
HighestBlockNumber() *big.Int
GetFinalizedHeader(uint64) (*types.Header, error)
GetFinalizedHeader(uint64, uint64) (*types.Header, error)
IsDescendantOf(parent, child common.Hash) (bool, error)
}

Expand Down
8 changes: 4 additions & 4 deletions lib/grandpa/grandpa.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func NewService(cfg *Config) (*Service, error) {
logger.Info("creating service", "key", cfg.Keypair.Public().Hex(), "voter set", Voters(cfg.Voters))

// get latest finalized header
head, err := cfg.BlockState.GetFinalizedHeader(0)
head, err := cfg.BlockState.GetFinalizedHeader(0, 0)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -436,7 +436,7 @@ func (s *Service) attemptToFinalize() error {
}

// if we haven't received a finalization message for this block yet, broadcast a finalization message
s.logger.Debug("finalized block!!!", "round", s.state.round, "hash", s.head.Hash())
s.logger.Debug("finalized block!!!", "setID", s.state.setID, "round", s.state.round, "hash", s.head.Hash())
msg := s.newFinalizationMessage(s.head, s.state.round)

// TODO: safety
Expand Down Expand Up @@ -595,13 +595,13 @@ func (s *Service) finalize() error {
}

// set finalized head for round in db
err = s.blockState.SetFinalizedHash(bfc.hash, s.state.round)
err = s.blockState.SetFinalizedHash(bfc.hash, s.state.round, s.state.setID)
if err != nil {
return err
}

// set latest finalized head in db
return s.blockState.SetFinalizedHash(bfc.hash, 0)
return s.blockState.SetFinalizedHash(bfc.hash, 0, 0)
}

// derivePrimary returns the primary for the current round
Expand Down
14 changes: 8 additions & 6 deletions lib/grandpa/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,12 @@ type catchUpResponse struct {
}

func (s *Service) newCatchUpResponse(round, setID uint64) (*catchUpResponse, error) {
// TODO: update blockState.GetFinalizedHeader to accept setID, use that instead, since mapping only stores from current setID
b := s.bestFinalCandidate[round]
header, err := s.blockState.GetFinalizedHeader(round, setID)
if err != nil {
return nil, err
}

has, err := s.blockState.HasJustification(b.hash)
has, err := s.blockState.HasJustification(header.Hash())
if err != nil {
return nil, err
}
Expand All @@ -148,7 +150,7 @@ func (s *Service) newCatchUpResponse(round, setID uint64) (*catchUpResponse, err
return nil, ErrNoJustification
}

just, err := s.blockState.GetJustification(b.hash)
just, err := s.blockState.GetJustification(header.Hash())
if err != nil {
return nil, err
}
Expand All @@ -174,7 +176,7 @@ func (s *Service) newCatchUpResponse(round, setID uint64) (*catchUpResponse, err
SetID: setID,
PreVoteJustification: pvj,
PreCommitJustification: pcj,
Hash: b.hash,
Number: b.number,
Hash: header.Hash(),
Number: header.Number.Uint64(),
}, nil
}
4 changes: 2 additions & 2 deletions lib/grandpa/message_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ func (h *MessageHandler) HandleMessage(msg *ConsensusMessage) error {
fm, ok := m.(*FinalizationMessage)
if ok {
// set finalized head for round in db
err = h.blockState.SetFinalizedHash(fm.Vote.hash, fm.Round)
err = h.blockState.SetFinalizedHash(fm.Vote.hash, fm.Round, h.grandpa.state.setID)
if err != nil {
return err
}

// set latest finalized head in db
err = h.blockState.SetFinalizedHash(fm.Vote.hash, 0)
err = h.blockState.SetFinalizedHash(fm.Vote.hash, 0, 0)
if err != nil {
return err
}
Expand Down
6 changes: 3 additions & 3 deletions lib/grandpa/message_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,15 +154,15 @@ func TestMessageHandler_FinalizationMessage(t *testing.T) {
cm, err := fm.ToConsensusMessage()
require.NoError(t, err)

h := NewMessageHandler(nil, st.Block)
h := NewMessageHandler(gs, st.Block)
err = h.HandleMessage(cm)
require.NoError(t, err)

hash, err := st.Block.GetFinalizedHash(0)
hash, err := st.Block.GetFinalizedHash(0, 0)
require.NoError(t, err)
require.Equal(t, fm.Vote.hash, hash)

hash, err = st.Block.GetFinalizedHash(fm.Round)
hash, err = st.Block.GetFinalizedHash(fm.Round, gs.state.setID)
require.NoError(t, err)
require.Equal(t, fm.Vote.hash, hash)
}
Loading

0 comments on commit 202ed5f

Please sign in to comment.