From d3ec5a97d4c9cc792e3adbc040fbdc411a99a166 Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Mon, 8 Apr 2024 13:06:05 +0200 Subject: [PATCH] Returned number of active members count when signing --- pkg/tbtc/heartbeat.go | 8 ++++++-- pkg/tbtc/heartbeat_test.go | 12 +++++++----- pkg/tbtc/signing.go | 27 +++++++++++++++------------ pkg/tbtc/signing_loop.go | 7 ++++++- pkg/tbtc/signing_loop_test.go | 8 ++++++++ pkg/tbtc/signing_test.go | 6 +++--- 6 files changed, 45 insertions(+), 23 deletions(-) diff --git a/pkg/tbtc/heartbeat.go b/pkg/tbtc/heartbeat.go index d00faa7cc0..f4e3dc3c8c 100644 --- a/pkg/tbtc/heartbeat.go +++ b/pkg/tbtc/heartbeat.go @@ -45,7 +45,7 @@ type heartbeatSigningExecutor interface { ctx context.Context, message *big.Int, startBlock uint64, - ) (*tecdsa.Signature, uint64, error) + ) (*tecdsa.Signature, uint32, uint64, error) } // heartbeatAction is a walletAction implementation handling heartbeat requests @@ -123,7 +123,11 @@ func (ha *heartbeatAction) execute() error { ) defer cancelHeartbeatCtx() - signature, _, err := ha.signingExecutor.sign(heartbeatCtx, messageToSign, ha.startBlock) + signature, _, _, err := ha.signingExecutor.sign( + heartbeatCtx, + messageToSign, + ha.startBlock, + ) if err != nil { return fmt.Errorf("cannot sign heartbeat message: [%v]", err) } diff --git a/pkg/tbtc/heartbeat_test.go b/pkg/tbtc/heartbeat_test.go index 32941e9b59..d42cc0796f 100644 --- a/pkg/tbtc/heartbeat_test.go +++ b/pkg/tbtc/heartbeat_test.go @@ -4,10 +4,11 @@ import ( "context" "encoding/hex" "fmt" - "github.com/keep-network/keep-core/internal/testutils" - "github.com/keep-network/keep-core/pkg/tecdsa" "math/big" "testing" + + "github.com/keep-network/keep-core/internal/testutils" + "github.com/keep-network/keep-core/pkg/tecdsa" ) func TestHeartbeatAction_HappyPath(t *testing.T) { @@ -136,13 +137,14 @@ func (mhse *mockHeartbeatSigningExecutor) sign( ctx context.Context, message *big.Int, startBlock uint64, -) (*tecdsa.Signature, uint64, error) { +) (*tecdsa.Signature, uint32, uint64, error) { mhse.requestedMessage = message mhse.requestedStartBlock = startBlock if mhse.shouldFail { - return nil, 0, fmt.Errorf("oofta") + return nil, 0, 0, fmt.Errorf("oofta") } - return &tecdsa.Signature{}, startBlock + 1, nil + // TODO: Return the active members count and use it in unit tests. + return &tecdsa.Signature{}, 0, startBlock + 1, nil } diff --git a/pkg/tbtc/signing.go b/pkg/tbtc/signing.go index 532a03942d..b4ab2b069e 100644 --- a/pkg/tbtc/signing.go +++ b/pkg/tbtc/signing.go @@ -145,7 +145,7 @@ func (se *signingExecutor) signBatch( signingStartBlock = endBlocks[i-1] + signingBatchInterludeBlocks } - signature, endBlock, err := se.sign(ctx, message, signingStartBlock) + signature, _, endBlock, err := se.sign(ctx, message, signingStartBlock) if err != nil { return nil, err } @@ -167,15 +167,16 @@ func (se *signingExecutor) signBatch( // triggered according to the given start block. If the message cannot be signed // within a limited time window, an error is returned. If the message was // signed successfully, this function returns the signature along with the -// block at which the signature was calculated. This end block is common for -// all wallet signers so can be used as a synchronization point. +// number of active members that participated in signing, the block at which the +// signature was calculated. The end block is common for all wallet signers so +// can be used as a synchronization point. func (se *signingExecutor) sign( ctx context.Context, message *big.Int, startBlock uint64, -) (*tecdsa.Signature, uint64, error) { +) (*tecdsa.Signature, uint32, uint64, error) { if lockAcquired := se.lock.TryAcquire(1); !lockAcquired { - return nil, 0, errSigningExecutorBusy + return nil, 0, 0, errSigningExecutorBusy } defer se.lock.Release(1) @@ -183,7 +184,7 @@ func (se *signingExecutor) sign( walletPublicKeyBytes, err := marshalPublicKey(wallet.publicKey) if err != nil { - return nil, 0, fmt.Errorf("cannot marshal wallet public key: [%v]", err) + return nil, 0, 0, fmt.Errorf("cannot marshal wallet public key: [%v]", err) } loopTimeoutBlock := startBlock + @@ -197,8 +198,9 @@ func (se *signingExecutor) sign( ) type signingOutcome struct { - signature *tecdsa.Signature - endBlock uint64 + signature *tecdsa.Signature + activeMembersCount uint32 + endBlock uint64 } wg := sync.WaitGroup{} @@ -365,8 +367,9 @@ func (se *signingExecutor) sign( ) signingOutcomeChan <- &signingOutcome{ - signature: loopResult.result.Signature, - endBlock: loopResult.latestEndBlock, + signature: loopResult.result.Signature, + activeMembersCount: loopResult.activeMembersCount, + endBlock: loopResult.latestEndBlock, } }(currentSigner) } @@ -383,9 +386,9 @@ func (se *signingExecutor) sign( // signer, that means all signers failed and have not produced a signature. select { case outcome := <-signingOutcomeChan: - return outcome.signature, outcome.endBlock, nil + return outcome.signature, outcome.activeMembersCount, outcome.endBlock, nil default: - return nil, 0, fmt.Errorf("all signers failed") + return nil, 0, 0, fmt.Errorf("all signers failed") } } diff --git a/pkg/tbtc/signing_loop.go b/pkg/tbtc/signing_loop.go index f67a585fe7..48f881df03 100644 --- a/pkg/tbtc/signing_loop.go +++ b/pkg/tbtc/signing_loop.go @@ -5,11 +5,12 @@ import ( "crypto/sha256" "encoding/binary" "fmt" - "github.com/keep-network/keep-core/pkg/protocol/announcer" "math/big" "math/rand" "sort" + "github.com/keep-network/keep-core/pkg/protocol/announcer" + "github.com/ipfs/go-log/v2" "github.com/keep-network/keep-core/pkg/chain" "github.com/keep-network/keep-core/pkg/protocol/group" @@ -143,6 +144,9 @@ type signingAttemptFn func(*signingAttemptParams) (*signing.Result, uint64, erro type signingRetryLoopResult struct { // result is the outcome of the signing process. result *signing.Result + // activeMembersCount is the number of members that participated in the + // signing process. + activeMembersCount uint32 // latestEndBlock is the block at which the slowest signer of the successful // signing attempt completed signature computation. This block is also // the common end block accepted by all other members of the signing group. @@ -407,6 +411,7 @@ func (srl *signingRetryLoop) start( return &signingRetryLoopResult{ result: result, + activeMembersCount: uint32(len(readyMembersIndexes)), latestEndBlock: latestEndBlock, attemptTimeoutBlock: timeoutBlock, }, nil diff --git a/pkg/tbtc/signing_loop_test.go b/pkg/tbtc/signing_loop_test.go index fbdba89552..cf3b02e716 100644 --- a/pkg/tbtc/signing_loop_test.go +++ b/pkg/tbtc/signing_loop_test.go @@ -101,6 +101,7 @@ func TestSigningRetryLoop(t *testing.T) { expectedErr: nil, expectedResult: &signingRetryLoopResult{ result: testResult, + activeMembersCount: 10, latestEndBlock: 215, // the end block resolved by the done check phase attemptTimeoutBlock: 236, // start block of the first attempt + 30 }, @@ -151,6 +152,7 @@ func TestSigningRetryLoop(t *testing.T) { expectedErr: nil, expectedResult: &signingRetryLoopResult{ result: testResult, + activeMembersCount: 6, latestEndBlock: 215, // the end block resolved by the done check phase attemptTimeoutBlock: 236, // start block of the first attempt + 30 }, @@ -205,6 +207,7 @@ func TestSigningRetryLoop(t *testing.T) { expectedErr: nil, expectedResult: &signingRetryLoopResult{ result: testResult, + activeMembersCount: 10, latestEndBlock: 260, // the end block resolved by the done check phase attemptTimeoutBlock: 277, // start block of the second attempt + 30 }, @@ -261,6 +264,7 @@ func TestSigningRetryLoop(t *testing.T) { expectedErr: nil, expectedResult: &signingRetryLoopResult{ result: testResult, + activeMembersCount: 10, latestEndBlock: 260, // the end block resolved by the done check phase attemptTimeoutBlock: 277, // start block of the second attempt + 30 }, @@ -317,6 +321,7 @@ func TestSigningRetryLoop(t *testing.T) { expectedErr: nil, expectedResult: &signingRetryLoopResult{ result: testResult, + activeMembersCount: 10, latestEndBlock: 260, // the end block resolved by the done check phase attemptTimeoutBlock: 277, // start block of the second attempt + 30 }, @@ -365,6 +370,7 @@ func TestSigningRetryLoop(t *testing.T) { expectedErr: nil, expectedResult: &signingRetryLoopResult{ result: testResult, + activeMembersCount: 10, latestEndBlock: 260, // the end block resolved by the done check phase attemptTimeoutBlock: 277, // start block of the second attempt + 30 }, @@ -436,6 +442,7 @@ func TestSigningRetryLoop(t *testing.T) { expectedErr: nil, expectedResult: &signingRetryLoopResult{ result: testResult, + activeMembersCount: 10, latestEndBlock: 260, // the end block resolved by the done check phase attemptTimeoutBlock: 277, // start block of the second attempt + 30 }, @@ -541,6 +548,7 @@ func TestSigningRetryLoop(t *testing.T) { expectedErr: nil, expectedResult: &signingRetryLoopResult{ result: testResult, + activeMembersCount: 10, latestEndBlock: 260, // the end block resolved by the done check phase attemptTimeoutBlock: 277, // start block of the second attempt + 30 }, diff --git a/pkg/tbtc/signing_test.go b/pkg/tbtc/signing_test.go index 1ace228c72..9bcd42ef6c 100644 --- a/pkg/tbtc/signing_test.go +++ b/pkg/tbtc/signing_test.go @@ -27,7 +27,7 @@ func TestSigningExecutor_Sign(t *testing.T) { message := big.NewInt(100) startBlock := uint64(0) - signature, endBlock, err := executor.sign(ctx, message, startBlock) + signature, _, endBlock, err := executor.sign(ctx, message, startBlock) if err != nil { t.Fatal(err) } @@ -59,13 +59,13 @@ func TestSigningExecutor_Sign_Busy(t *testing.T) { errChan := make(chan error, 1) go func() { - _, _, err := executor.sign(ctx, message, startBlock) + _, _, _, err := executor.sign(ctx, message, startBlock) errChan <- err }() time.Sleep(100 * time.Millisecond) - _, _, err := executor.sign(ctx, message, startBlock) + _, _, _, err := executor.sign(ctx, message, startBlock) testutils.AssertErrorsSame(t, errSigningExecutorBusy, err) err = <-errChan