-
Notifications
You must be signed in to change notification settings - Fork 126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore(lib/grandpa): update grandpa message tracker to store messages with map of maps, also store commit messages #1769
Conversation
lib/grandpa/message_tracker_test.go
Outdated
} | ||
|
||
func TestMessageTracker_SendMessage(t *testing.T) { | ||
kr, err := keystore.NewEd25519Keyring() | ||
require.NoError(t, err) | ||
|
||
gs, in, _, _ := setupGrandpa(t, kr.Bob().(*ed25519.Keypair)) | ||
fmt.Println(len(in)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
dot/network/sync.go
Outdated
if goal-int64(start) < int64(blockRequestSize) { | ||
start := best.Int64() + 1 | ||
req := createBlockRequest(start, 0) | ||
req := createBlockRequest(start, uint32(goal)-uint32(start)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uint32(goal - start)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we merge this and the below code and decide on the request size and make the request code common?
var requestSize int32
if goal-int64(start) < int64(blockRequestSize) {
start := best.Int64() + 1
requestSize = int32(goal - start)
} else {
m := start % uint64(blockRequestSize)
start = start - m + 1
requestSize = ...
}
for i := 0; i < numRequests; i++ {
if start > uint64(goal) {
return
}
if requestSize / blockRequestSize == 0 {
currentRequestSize = requestSize
} else {
currentRequestSize = blockRequestSize
}
... // logic
start += uint64(currentRequestSize)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
goal
and start
have different types so they need to both be casted to uint32 before they can be subtracted
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think both of them are int64
. Let me recheck.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arijitAD they aren't :(
../../dot/network/sync.go:457:25: invalid operation: goal - start (mismatched types int64 and uint64)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lib/grandpa/message_handler.go
Outdated
@@ -54,13 +56,18 @@ func (h *MessageHandler) handleMessage(from peer.ID, m GrandpaMessage) (network. | |||
switch m.Type() { | |||
case voteType: | |||
vm, ok := m.(*VoteMessage) | |||
if h.grandpa != nil && ok { | |||
// send vote message to grandpa service | |||
if h.grandpa == nil || !ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a switch case,
func (h *MessageHandler) handleMessage(from peer.ID, m GrandpaMessage) (network.NotificationsMessage, error) {
logger.Trace("handling grandpa message", "msg", m)
switch msg := m.(type) {
case *VoteMessage:
if h.grandpa == nil {
return nil, nil
}
// send vote message to grandpa service
go func() {
h.grandpa.in <- &networkVoteMessage{
from: from,
msg: msg,
}
}()
return nil, nil
case *CommitMessage:
return nil, h.handleCommitMessage(msg)
case *NeighbourMessage:
return nil, h.handleNeighbourMessage(from, msg)
case *catchUpRequest:
return h.handleCatchUpRequest(msg)
case *catchUpResponse:
return nil, h.handleCatchUpResponse(msg)
}
return nil, ErrInvalidMessageType
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
voteMessages map[common.Hash]map[ed25519.PublicKeyBytes]*networkVoteMessage // map of vote block hash -> array of VoteMessages for that hash | ||
commitMessages map[common.Hash]*CommitMessage // map of commit block hash to commit message | ||
mapLock sync.Mutex | ||
in chan *types.Block // receive imported block from BlockState |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This channel is used to receive data
in <-chan *types.Block
We should close the channel at the sender's end.
func (bs *BlockState) UnregisterImportedChannel(id byte) {
bs.importedLock.Lock()
defer bs.importedLock.Unlock()
if ch, ok := bs.imported[id]; !ok {
close(ch)
}
delete(bs.imported, id)
err := bs.importedBytePool.Put(id)
if err != nil {
logger.Error("failed to unregister imported channel", "error", err)
}
}
instead of
func (t *tracker) stop() {
close(t.stopped)
t.blockState.UnregisterImportedChannel(t.chanID)
close(t.in)
}
One general principle of using Go channels is don't close a channel from the receiver side and don't close a channel if the channel has multiple concurrent senders. In other words, we should only close a channel in a sender goroutine if the sender is the only sender of the channel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah I think this relies on Ed's refactor in #1736 so I'd rather not change it here, I agree with you though that the whole notifier code needs to be refactored. I can change it here if you'd like but it overlaps with Ed's PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I commented on this on Ed's PR #1736 (comment)
t.mapLock.Unlock() | ||
defer t.mapLock.Unlock() | ||
|
||
msgs, has := t.voteMessages[v.msg.Message.Hash] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change to
voteMsg, has := t.voteMessages[v.msg.Message.Hash]
if !has {
voteMsg = make(map[ed25519.PublicKeyBytes]*networkVoteMessage)
t.voteMessages[v.msg.Message.Hash] = voteMsg
}
voteMsg[v.msg.Message.AuthorityID] = v
Code to verify
func TestMessageTracker_MapInsideMap(t *testing.T) {
mm := make(map[common.Hash]map[ed25519.PublicKeyBytes]*networkVoteMessage)
hash := common.NewHash([]byte{0})
voteMsg, ok := mm[hash]
require.False(t, ok)
voteMsg = make(map[ed25519.PublicKeyBytes]*networkVoteMessage)
mm[hash] = voteMsg
AuthorityID := ed25519.PublicKeyBytes(common.MustHexToHash("0x34602b88f60513f1c805d87ef52896934baf6a662bc37414dbdbf69356b1a691"))
voteMsg[AuthorityID] = &networkVoteMessage{}
voteMsg, ok = mm[hash]
require.True(t, ok)
_, ok = voteMsg[AuthorityID]
require.True(t, ok)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added a test for the maps in addVote
lib/grandpa/message_tracker.go
Outdated
@@ -82,16 +97,31 @@ func (t *tracker) handleBlocks() { | |||
continue | |||
} | |||
|
|||
t.mapLock.Lock() | |||
func() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better indentation
func (t *tracker) handleBlocks() {
handleBlocks := func(b *types.Block) {
t.mapLock.Lock()
defer t.mapLock.Unlock()
h := b.Header.Hash()
if vms, has := t.voteMessages[h]; has {
for _, v := range vms {
_, err := t.handler.handleMessage(v.from, v.msg)
if err != nil {
logger.Warn("failed to handle vote message", "message", v, "error", err)
}
}
delete(t.voteMessages, h)
}
if cm, has := t.commitMessages[h]; has {
_, err := t.handler.handleMessage("", cm)
if err != nil {
logger.Warn("failed to handle commit message", "message", cm, "error", err)
}
delete(t.commitMessages, h)
}
}
for {
select {
case b := <-t.in:
if b == nil {
continue
}
handleBlocks(b)
case <-t.stopped:
return
}
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or create a function func (t *tracker) handle(b *types.Block)
and call it inside the case:
for {
select {
case b := <-t.in:
if b == nil { continue }
t.handle(b)
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated to have a separate handleBlock
function
@@ -125,6 +132,11 @@ func (h *MessageHandler) handleCommitMessage(msg *CommitMessage) error { | |||
|
|||
// check justification here | |||
if err := h.verifyCommitMessageJustification(msg); err != nil { | |||
if errors.Is(err, blocktree.ErrStartNodeNotFound) { | |||
// TODO: make this synchronous |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue created to this TODO -> #1771
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice, I'm still unsure about this todo, after the sync refactor it hopefully won't be necessary, but we'll see
dot/network/sync.go
Outdated
start = start - m + 1 | ||
reqSize := blockRequestSize | ||
if goal-int64(start) < int64(blockRequestSize) { | ||
start = uint64(best.Int64() + 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
start = uint64(best.Int64() + 1) | |
start = best.Uint64() + 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
lib/grandpa/message_tracker.go
Outdated
t.voteMessages[v.msg.Message.Hash] = make(map[ed25519.PublicKeyBytes]*networkVoteMessage) | ||
msgs = t.voteMessages[v.msg.Message.Hash] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
t.voteMessages[v.msg.Message.Hash] = make(map[ed25519.PublicKeyBytes]*networkVoteMessage) | |
msgs = t.voteMessages[v.msg.Message.Hash] | |
msgs = make(map[ed25519.PublicKeyBytes]*networkVoteMessage) | |
t.voteMessages[v.msg.Message.Hash] = msgs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
Codecov Report
@@ Coverage Diff @@
## development #1769 +/- ##
============================================
Coverage 59.09% 59.09%
============================================
Files 184 184
Lines 19383 19390 +7
============================================
+ Hits 11454 11459 +5
+ Misses 5951 5944 -7
- Partials 1978 1987 +9
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
🎉 This PR is included in version 0.6.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
…with map of maps, also store commit messages (ChainSafe#1769)
Changes
Tests
Issues
Primary Reviewer