-
Notifications
You must be signed in to change notification settings - Fork 75
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
DKG test loop #3034
DKG test loop #3034
Changes from all commits
af45efd
e895b9b
c310f80
e620aed
762b0d8
3d88e37
b0d2670
66e9c3a
a46353d
a5b67cb
0d940da
002b15a
1900757
b04ec33
0aea172
05cc9ca
e002bfb
1c5a815
c80c1ab
d2e607c
6fd17ee
e49262d
185fe7f
641466e
5ac87df
ed315ca
fbe3062
7c122d5
10e12b9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,8 +3,16 @@ package event | |
import ( | ||
"encoding/hex" | ||
"fmt" | ||
"github.com/keep-network/keep-common/pkg/cache" | ||
"math/big" | ||
"sync" | ||
"time" | ||
) | ||
|
||
const ( | ||
// DKGSeedCachePeriod is the time period the cache maintains | ||
// the DKG seed corresponding to a DKG instance. | ||
DKGSeedCachePeriod = 7 * 24 * time.Hour | ||
) | ||
|
||
// Local chain interface to avoid import cycles. | ||
|
@@ -24,51 +32,45 @@ type chain interface { | |
// should be handled. | ||
// | ||
// Those events are supported: | ||
// - group selection started | ||
// - DKG started | ||
// - relay entry requested | ||
type Deduplicator struct { | ||
chain chain | ||
minGroupCreationDurationBlocks uint64 | ||
chain chain | ||
|
||
groupSelectionMutex sync.Mutex | ||
currentGroupSelectionStartBlock uint64 | ||
dkgSeedCache *cache.TimeCache | ||
|
||
relayEntryMutex sync.Mutex | ||
currentRequestStartBlock uint64 | ||
currentRequestPreviousEntry string | ||
} | ||
|
||
// NewDeduplicator constructs a new Deduplicator instance. | ||
func NewDeduplicator( | ||
chain chain, | ||
minGroupCreationDurationBlocks uint64, | ||
) *Deduplicator { | ||
func NewDeduplicator(chain chain) *Deduplicator { | ||
return &Deduplicator{ | ||
chain: chain, | ||
minGroupCreationDurationBlocks: minGroupCreationDurationBlocks, | ||
chain: chain, | ||
dkgSeedCache: cache.NewTimeCache(DKGSeedCachePeriod), | ||
} | ||
} | ||
|
||
// NotifyGroupSelectionStarted notifies the client wants to start group | ||
// selection upon receiving an event. It returns boolean indicating whether the | ||
// NotifyDKGStarted notifies the client wants to start the distributed key | ||
// generation upon receiving an event. It returns boolean indicating whether the | ||
// client should proceed with the execution or ignore the event as a duplicate. | ||
func (d *Deduplicator) NotifyGroupSelectionStarted( | ||
newGroupSelectionStartBlock uint64, | ||
func (d *Deduplicator) NotifyDKGStarted( | ||
newDKGSeed *big.Int, | ||
) bool { | ||
d.groupSelectionMutex.Lock() | ||
defer d.groupSelectionMutex.Unlock() | ||
|
||
minCurrentGroupCreationEndBlock := d.currentGroupSelectionStartBlock + | ||
d.minGroupCreationDurationBlocks | ||
|
||
shouldUpdate := d.currentGroupSelectionStartBlock == 0 || | ||
newGroupSelectionStartBlock > minCurrentGroupCreationEndBlock | ||
|
||
if shouldUpdate { | ||
d.currentGroupSelectionStartBlock = newGroupSelectionStartBlock | ||
d.dkgSeedCache.Sweep() | ||
|
||
// The cache key is the hexadecimal representation of the seed. | ||
cacheKey := newDKGSeed.Text(16) | ||
// If the key is not in the cache, that means the seed was not handled | ||
// yet and the client should proceed with the execution. | ||
if !d.dkgSeedCache.Has(cacheKey) { | ||
d.dkgSeedCache.Add(cacheKey) | ||
return true | ||
} | ||
|
||
// Otherwise, the DKG seed is a duplicate and the client should not proceed | ||
// with the execution. | ||
return false | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quoting from the PR description:
I am not sure if this is the case. As far as I remember, the deduplicator was mostly handling soft forks. We were receiving the same event twice but with a different block number: Although this is naive, and we could improve it by, for example, waiting for N blocks, then checking the last N blocks if the event is included, I think the current implementation should do the work, even for v2. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Not only soft forks. The event subscription mechanism from contract bindings can replay the event when fetching past events. This happens more often than soft forks and results in an event having the same block.
This is something I'm not sure about. In v2 the minimum time between two There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yeah, that's a good point! The time it takes the DKG protocol to produce the result is 72 blocks ([1], [2]). Subscription monitoring mechanism pulls 100 past blocks by default and although it could make sense for the relay request subscription, it does not make sense for DKG because after the first 6 blocks of inactivity, the game for the given member is over. This solution is not ideal but at the same time, it's the simplest one. I am afraid that dealing with challenges will make this code pretty complicated. I think that this should work:
Does it make sense? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We synced with @lukasz-zimnoch and came up with a better solution:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here it is fbe3062 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And added a TODO about disabling the monitoring loop 7c122d5 |
||
|
@@ -122,7 +124,7 @@ func (d *Deduplicator) NotifyRelayEntryStarted( | |
if newRequestPreviousEntry == | ||
hex.EncodeToString(currentRequestPreviousEntryOnChain[:]) && | ||
newRequestStartBlock == | ||
currentRequestStartBlockOnChain.Uint64() { | ||
currentRequestStartBlockOnChain.Uint64() { | ||
return true, nil | ||
} | ||
} else { | ||
|
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.
#3056 introduces
chain.Address
, I think we could use it here.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.
Just a note for the future implementation with a real
SortitionPool
: fortunately, there is a function allowing to fetch the addresses in one shot.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.
Yep, there is a comment about the deprecation of
StakerAddress
. I can replace it withchain.Address
during the cleanup, I plan to do in thepkg/beacon
package.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.
When we call
SelectGroup
and assign a return value innode.go
we call that vargroupMembers
and IMO that name is clearer because we return an array of members. WDYT about naming itSelectGroupMembers
instead?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.
There will be a follow-up PR that will add a real-world implementation of that function. I'll consider the rename then.