Skip to content
This repository has been archived by the owner on May 22, 2023. It is now read-only.

Add signer publication delay #616

Merged
merged 7 commits into from
Nov 23, 2020
Merged
5 changes: 5 additions & 0 deletions pkg/extensions/tbtc/tbtc.go
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,11 @@ func (t *tbtc) getSignerActionDelay(
return 0, err
}

// just in case this function is not invoked in the right context
if signerIndex < 0 {
return 0, fmt.Errorf("signer index is less than zero")
}

return time.Duration(signerIndex) * t.signerActionDelayStep, nil
}

Expand Down
83 changes: 70 additions & 13 deletions pkg/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,20 @@ import (

var logger = log.Logger("keep-ecdsa")

const monitorKeepPublicKeySubmissionTimeout = 30 * time.Minute
const retryDelay = 1 * time.Second
const blockConfirmations = uint64(12)
const (
// Determines the delay which should be preserved before retrying
// actions within the key generation and signing process.
retryDelay = 1 * time.Second

// Number of blocks which should elapse before confirming
// the given chain state expectations.
blockConfirmations = uint64(12)

// Used to calculate the publication delay factor for the given signer index
// to avoid all signers publishing the same signature for given keep at the
// same time.
signaturePublicationDelayStep = 5 * time.Minute
)

// Node holds interfaces to interact with the blockchain and network messages
// transport layer.
Expand Down Expand Up @@ -309,6 +320,8 @@ func (n *Node) publishSignature(
digest [32]byte,
signature *ecdsa.Signature,
) error {
n.waitSignaturePublicationDelay(keepAddress)

attemptCounter := 0
for {
attemptCounter++
Expand Down Expand Up @@ -359,11 +372,6 @@ func (n *Node) publishSignature(
// and there are enough confirmations from the chain.
// We are fine, leaving.
if !isAwaitingSignature && n.confirmSignature(keepAddress, digest) {
logger.Infof(
"signature for keep [%s] already submitted: [%+x]",
keepAddress.String(),
digest,
)
return nil
}

Expand Down Expand Up @@ -391,11 +399,6 @@ func (n *Node) publishSignature(
// confirmations from the chain before making a decision about
// leaving the submission process.
if !isAwaitingSignature && n.confirmSignature(keepAddress, digest) {
logger.Infof(
"signature for keep [%s] already submitted: [%+x]",
keepAddress.String(),
digest,
)
return nil
}

Expand All @@ -420,6 +423,60 @@ func (n *Node) publishSignature(
}
}

// waitSignaturePublicationDelay waits a certain amount of time appropriately
// for the given signer index to avoid all signers publishing the same signature
// for given keep at the same time.
func (n *Node) waitSignaturePublicationDelay(
keepAddress common.Address,
) {
signerIndex, err := n.getSignerIndex(keepAddress)
if err != nil {
logger.Errorf(
"could not determine signature publication delay for keep [%s]: "+
"[%v]; the signature publication will not be delayed",
keepAddress.String(),
err,
)
return
}

// just in case this function is not invoked in the right context
if signerIndex < 0 {
logger.Errorf(
"could not determine signature publication delay for keep [%s], "+
"signer index is less than zero; the signature publication "+
"will not be delayed",
keepAddress.String(),
)
return
}

delay := time.Duration(signerIndex) * signaturePublicationDelayStep

logger.Infof(
"waiting [%v] before publishing signature for keep [%s]",
delay,
keepAddress.String(),
)

time.Sleep(delay)
}

func (n *Node) getSignerIndex(keepAddress common.Address) (int, error) {
members, err := n.ethereumChain.GetMembers(keepAddress)
if err != nil {
return -1, err
}

for index, member := range members {
if member == n.ethereumChain.Address() {
return index, nil
}
}

return -1, nil
}

func (n *Node) waitForSignature(
keepAddress common.Address,
digest [32]byte,
Expand Down