From 9b09a990bdd0997269e0e76a9cd16d3fc7eb8acd Mon Sep 17 00:00:00 2001 From: mpetrun5 Date: Fri, 12 Jul 2024 11:47:22 +0200 Subject: [PATCH 01/11] Set session ID to txHash to prevent mismatched messages --- chains/btc/executor/executor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chains/btc/executor/executor.go b/chains/btc/executor/executor.go index 7a72a852..c262f003 100644 --- a/chains/btc/executor/executor.go +++ b/chains/btc/executor/executor.go @@ -164,7 +164,7 @@ func (e *Executor) executeResourceProps(props []*BtcTransferProposal, resource c i, msg, resource.Tweak, - fmt.Sprintf("%s-%d", sessionID, i), + fmt.Sprintf("%s-%s", sessionID, hex.EncodeToString(txHash)), e.host, e.comm, e.fetcher) From 3f60f4a9a05e6d2e1d66cf69dbecb48c4dce7c86 Mon Sep 17 00:00:00 2001 From: mpetrun5 Date: Fri, 12 Jul 2024 11:47:33 +0200 Subject: [PATCH 02/11] Fix duplicate ready peers --- tss/coordinator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tss/coordinator.go b/tss/coordinator.go index 49852127..84b7d384 100644 --- a/tss/coordinator.go +++ b/tss/coordinator.go @@ -244,7 +244,7 @@ func (c *Coordinator) initiate(ctx context.Context, tssProcess TssProcess, resul case wMsg := <-readyChan: { log.Debug().Str("SessionID", tssProcess.SessionID()).Msgf("received ready message from %s", wMsg.From) - if !slices.Contains(excludedPeers, wMsg.From) { + if !slices.Contains(excludedPeers, wMsg.From) && !slices.Contains(readyPeers, wMsg.From) { readyPeers = append(readyPeers, wMsg.From) } ready, err := tssProcess.Ready(readyPeers, excludedPeers) From 6a1774c64cd7b7e134dc8c5b37a58170c3998fb2 Mon Sep 17 00:00:00 2001 From: mpetrun5 Date: Fri, 12 Jul 2024 11:47:45 +0200 Subject: [PATCH 03/11] Fix stopping tss process log --- tss/ecdsa/resharing/resharing.go | 4 ++-- tss/ecdsa/signing/signing.go | 2 +- tss/frost/resharing/resharing.go | 2 +- tss/frost/signing/signing.go | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tss/ecdsa/resharing/resharing.go b/tss/ecdsa/resharing/resharing.go index 3540fa15..f84b7dd2 100644 --- a/tss/ecdsa/resharing/resharing.go +++ b/tss/ecdsa/resharing/resharing.go @@ -136,7 +136,7 @@ func (r *Resharing) Run( // Stop ends all subscriptions created when starting the tss process and unlocks keyshare. func (r *Resharing) Stop() { - log.Info().Str("sessionID", r.SessionID()).Msgf("Stopping tss process.") + r.Log.Info().Msgf("Stopping tss process.") r.Communication.UnSubscribe(r.subscriptionID) r.storer.UnlockKeyshare() r.Cancel() @@ -165,7 +165,7 @@ func (r *Resharing) ValidCoordinators() []peer.ID { // StartParams returns threshold and peer subset from the old key to share with new parties. func (r *Resharing) StartParams(readyPeers []peer.ID) []byte { - oldSubset := common.PeersIntersection(r.key.Peers, r.Host.Peerstore().Peers()) + oldSubset := common.PeersIntersection(r.key.Peers, r.Host.Peerstore().Peers()) startParams := &startParams{ OldThreshold: r.key.Threshold, OldSubset: oldSubset, diff --git a/tss/ecdsa/signing/signing.go b/tss/ecdsa/signing/signing.go index c4a1c49b..97f9ab59 100644 --- a/tss/ecdsa/signing/signing.go +++ b/tss/ecdsa/signing/signing.go @@ -138,7 +138,7 @@ func (s *Signing) Run( // Stop ends all subscriptions created when starting the tss process. func (s *Signing) Stop() { - log.Info().Str("sessionID", s.SessionID()).Msgf("Stopping tss process.") + s.Log.Info().Msgf("Stopping tss process.") s.Communication.UnSubscribe(s.subscriptionID) s.Cancel() } diff --git a/tss/frost/resharing/resharing.go b/tss/frost/resharing/resharing.go index f5dd9b3e..42e7fe88 100644 --- a/tss/frost/resharing/resharing.go +++ b/tss/frost/resharing/resharing.go @@ -110,7 +110,7 @@ func (r *Resharing) Run( // Stop ends all subscriptions created when starting the tss process and unlocks keyshare. func (r *Resharing) Stop() { - log.Info().Str("sessionID", r.SessionID()).Msgf("Stopping tss process.") + r.Log.Info().Msgf("Stopping tss process.") r.Communication.UnSubscribe(r.subscriptionID) r.storer.UnlockKeyshare() r.Cancel() diff --git a/tss/frost/signing/signing.go b/tss/frost/signing/signing.go index 4d3ee992..f1ceed3a 100644 --- a/tss/frost/signing/signing.go +++ b/tss/frost/signing/signing.go @@ -141,7 +141,7 @@ func (s *Signing) Run( // Stop ends all subscriptions created when starting the tss process. func (s *Signing) Stop() { - log.Info().Str("sessionID", s.SessionID()).Msgf("Stopping tss process.") + s.Log.Info().Msgf("Stopping tss process.") s.Communication.UnSubscribe(s.subscriptionID) s.Cancel() } From 2afd08a7c1485cb691e826dc1d4b881a049fd4f7 Mon Sep 17 00:00:00 2001 From: mpetrun5 Date: Fri, 12 Jul 2024 12:00:29 +0200 Subject: [PATCH 04/11] Round down fee to smooth out responses --- chains/btc/executor/executor.go | 30 ++++++++++++++------------ chains/btc/executor/message-handler.go | 4 ++-- chains/btc/mempool/mempool.go | 10 ++++----- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/chains/btc/executor/executor.go b/chains/btc/executor/executor.go index c262f003..9ca3ace0 100644 --- a/chains/btc/executor/executor.go +++ b/chains/btc/executor/executor.go @@ -31,8 +31,9 @@ import ( var ( signingTimeout = 30 * time.Minute - INPUT_SIZE = 180 - OUTPUT_SIZE = 34 + INPUT_SIZE uint64 = 180 + OUTPUT_SIZE uint64 = 34 + FEE_ROUNDING_FACTOR uint64 = 5 ) type MempoolAPI interface { @@ -225,7 +226,7 @@ func (e *Executor) rawTx(proposals []*BtcTransferProposal, resource config.Resou if err != nil { return nil, nil, err } - feeEstimate, err := e.fee(int64(len(proposals)), int64(len(proposals))) + feeEstimate, err := e.fee(uint64(len(proposals)), uint64(len(proposals))) if err != nil { return nil, nil, err } @@ -236,26 +237,26 @@ func (e *Executor) rawTx(proposals []*BtcTransferProposal, resource config.Resou if inputAmount < outputAmount { return nil, nil, fmt.Errorf("utxo input amount %d less than output amount %d", inputAmount, outputAmount) } - fee, err := e.fee(int64(len(utxos)), int64(len(proposals))+1) + fee, err := e.fee(uint64(len(utxos)), uint64(len(proposals))+1) if err != nil { return nil, nil, err } - returnAmount := int64(inputAmount) - fee - outputAmount + returnAmount := inputAmount - fee - outputAmount if returnAmount > 0 { // return extra funds returnScript, err := txscript.PayToAddrScript(resource.Address) if err != nil { return nil, nil, err } - txOut := wire.NewTxOut(returnAmount, returnScript) + txOut := wire.NewTxOut(int64(returnAmount), returnScript) tx.AddTxOut(txOut) } return tx, utxos, err } -func (e *Executor) outputs(tx *wire.MsgTx, proposals []*BtcTransferProposal) (int64, error) { - outputAmount := int64(0) +func (e *Executor) outputs(tx *wire.MsgTx, proposals []*BtcTransferProposal) (uint64, error) { + outputAmount := uint64(0) for _, prop := range proposals { addr, err := btcutil.DecodeAddress(prop.Data.Recipient, &e.chainCfg) if err != nil { @@ -265,16 +266,16 @@ func (e *Executor) outputs(tx *wire.MsgTx, proposals []*BtcTransferProposal) (in if err != nil { return 0, err } - txOut := wire.NewTxOut(prop.Data.Amount, destinationAddrByte) + txOut := wire.NewTxOut(int64(prop.Data.Amount), destinationAddrByte) tx.AddTxOut(txOut) outputAmount += prop.Data.Amount } return outputAmount, nil } -func (e *Executor) inputs(tx *wire.MsgTx, address btcutil.Address, outputAmount int64) (int64, []mempool.Utxo, error) { +func (e *Executor) inputs(tx *wire.MsgTx, address btcutil.Address, outputAmount uint64) (uint64, []mempool.Utxo, error) { usedUtxos := make([]mempool.Utxo, 0) - inputAmount := int64(0) + inputAmount := uint64(0) utxos, err := e.mempool.Utxos(address.String()) if err != nil { return 0, nil, err @@ -289,7 +290,7 @@ func (e *Executor) inputs(tx *wire.MsgTx, address btcutil.Address, outputAmount tx.AddTxIn(txIn) usedUtxos = append(usedUtxos, utxo) - inputAmount += int64(utxo.Value) + inputAmount += uint64(utxo.Value) if inputAmount > outputAmount { break } @@ -297,12 +298,13 @@ func (e *Executor) inputs(tx *wire.MsgTx, address btcutil.Address, outputAmount return inputAmount, usedUtxos, nil } -func (e *Executor) fee(numOfInputs, numOfOutputs int64) (int64, error) { +func (e *Executor) fee(numOfInputs, numOfOutputs uint64) (uint64, error) { recommendedFee, err := e.mempool.RecommendedFee() if err != nil { return 0, err } - return (numOfInputs*int64(INPUT_SIZE) + numOfOutputs*int64(OUTPUT_SIZE)) * recommendedFee.EconomyFee, nil + + return (numOfInputs*INPUT_SIZE + numOfOutputs*OUTPUT_SIZE) * ((recommendedFee.EconomyFee / FEE_ROUNDING_FACTOR) * FEE_ROUNDING_FACTOR), nil } func (e *Executor) sendTx(tx *wire.MsgTx, signatures []taproot.Signature) (*chainhash.Hash, error) { diff --git a/chains/btc/executor/message-handler.go b/chains/btc/executor/message-handler.go index 87620878..1c37813c 100644 --- a/chains/btc/executor/message-handler.go +++ b/chains/btc/executor/message-handler.go @@ -14,7 +14,7 @@ import ( ) type BtcTransferProposalData struct { - Amount int64 + Amount uint64 Recipient string DepositNonce uint64 ResourceId [32]byte @@ -64,7 +64,7 @@ func ERC20MessageHandler(msg *transfer.TransferMessage) (*proposal.Proposal, err bigAmount.Div(bigAmount, divisor) return proposal.NewProposal(msg.Source, msg.Destination, BtcTransferProposalData{ - Amount: bigAmount.Int64(), + Amount: bigAmount.Uint64(), Recipient: string(recipient), DepositNonce: msg.Data.DepositNonce, ResourceId: msg.Data.ResourceId, diff --git a/chains/btc/mempool/mempool.go b/chains/btc/mempool/mempool.go index 445b9c75..0a882a9c 100644 --- a/chains/btc/mempool/mempool.go +++ b/chains/btc/mempool/mempool.go @@ -23,11 +23,11 @@ type Utxo struct { } type Fee struct { - FastestFee int64 - HalfHourFee int64 - MinimumFee int64 - EconomyFee int64 - HourFee int64 + FastestFee uint64 + HalfHourFee uint64 + MinimumFee uint64 + EconomyFee uint64 + HourFee uint64 } type MempoolAPI struct { From c1522c2def8bcb6da731f0accbf69f1a4618860c Mon Sep 17 00:00:00 2001 From: mpetrun5 Date: Fri, 12 Jul 2024 14:17:39 +0200 Subject: [PATCH 05/11] Fix proposals hash calculation --- chains/proposal.go | 5 +++-- chains/proposal_test.go | 10 ++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/chains/proposal.go b/chains/proposal.go index 6652d7c7..0a8a72eb 100644 --- a/chains/proposal.go +++ b/chains/proposal.go @@ -5,6 +5,7 @@ package chains import ( "fmt" + "math/big" "github.com/ChainSafe/sygma-relayer/relayer/transfer" "github.com/ethereum/go-ethereum/common/hexutil" @@ -17,8 +18,8 @@ func ProposalsHash(proposals []*transfer.TransferProposal, chainID int64, verifC formattedProps := make([]interface{}, len(proposals)) for i, prop := range proposals { formattedProps[i] = map[string]interface{}{ - "originDomainID": math.NewHexOrDecimal256(int64(prop.Source)), - "depositNonce": math.NewHexOrDecimal256(int64(prop.Data.DepositNonce)), + "originDomainID": big.NewInt(int64(prop.Source)), + "depositNonce": new(big.Int).SetUint64(prop.Data.DepositNonce), "resourceID": hexutil.Encode(prop.Data.ResourceId[:]), "data": prop.Data.Data, } diff --git a/chains/proposal_test.go b/chains/proposal_test.go index afa8921c..9b685686 100644 --- a/chains/proposal_test.go +++ b/chains/proposal_test.go @@ -4,6 +4,8 @@ package chains import ( + "testing" + "github.com/ChainSafe/sygma-relayer/relayer/transfer" "github.com/stretchr/testify/suite" ) @@ -15,6 +17,10 @@ type ProposalTestSuite struct { suite.Suite } +func TestRunProposalTestSuite(t *testing.T) { + suite.Run(t, new(ProposalTestSuite)) +} + func (s *ProposalTestSuite) Test_ProposalsHash() { data := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 243, 16, 122, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 1, 1, 0, 212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125} @@ -22,13 +28,13 @@ func (s *ProposalTestSuite) Test_ProposalsHash() { Source: 1, Destination: 2, Data: transfer.TransferProposalData{ - DepositNonce: 3, + DepositNonce: 15078986465725403975, ResourceId: [32]byte{3}, Metadata: nil, Data: data, }, }} - correctRes := []byte{253, 216, 81, 25, 46, 239, 181, 138, 51, 225, 165, 111, 156, 95, 27, 239, 160, 87, 89, 84, 50, 22, 97, 185, 132, 200, 201, 210, 204, 99, 94, 131} + correctRes := []byte{0xde, 0x7b, 0x5c, 0x9e, 0x8, 0x7a, 0xb4, 0xf5, 0xfb, 0xe, 0x9f, 0x73, 0xa7, 0xe5, 0xbd, 0xb, 0xdf, 0x9e, 0xeb, 0x4, 0xaa, 0xbb, 0xd0, 0xe8, 0xf8, 0xde, 0x58, 0xa2, 0x4, 0xa3, 0x3e, 0x55} res, err := ProposalsHash(prop, 5, verifyingContract, bridgeVersion) s.Nil(err) From 7e0c36bfa8a5cd8c0e36b7e3578e62910cdc8463 Mon Sep 17 00:00:00 2001 From: mpetrun5 Date: Mon, 15 Jul 2024 13:43:47 +0200 Subject: [PATCH 06/11] Avoid fee floor being 0 --- chains/btc/executor/executor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chains/btc/executor/executor.go b/chains/btc/executor/executor.go index 9ca3ace0..e8fa0e8c 100644 --- a/chains/btc/executor/executor.go +++ b/chains/btc/executor/executor.go @@ -304,7 +304,7 @@ func (e *Executor) fee(numOfInputs, numOfOutputs uint64) (uint64, error) { return 0, err } - return (numOfInputs*INPUT_SIZE + numOfOutputs*OUTPUT_SIZE) * ((recommendedFee.EconomyFee / FEE_ROUNDING_FACTOR) * FEE_ROUNDING_FACTOR), nil + return (numOfInputs*INPUT_SIZE + numOfOutputs*OUTPUT_SIZE) * ((recommendedFee.EconomyFee/FEE_ROUNDING_FACTOR)*FEE_ROUNDING_FACTOR + FEE_ROUNDING_FACTOR), nil } func (e *Executor) sendTx(tx *wire.MsgTx, signatures []taproot.Signature) (*chainhash.Hash, error) { From 888d28813e2e64f594cfac5321e7f940fed9cbe0 Mon Sep 17 00:00:00 2001 From: mpetrun5 Date: Tue, 16 Jul 2024 13:12:08 +0200 Subject: [PATCH 07/11] Improve message trackinglogs across networks --- chains/btc/executor/executor.go | 45 +++++++++++++++++--------- chains/btc/listener/deposit-handler.go | 3 +- chains/evm/executor/executor.go | 18 ++++++++--- chains/substrate/executor/executor.go | 7 ++-- tss/ecdsa/signing/signing.go | 3 +- tss/frost/signing/signing.go | 3 +- 6 files changed, 53 insertions(+), 26 deletions(-) diff --git a/chains/btc/executor/executor.go b/chains/btc/executor/executor.go index e8fa0e8c..aa2eb659 100644 --- a/chains/btc/executor/executor.go +++ b/chains/btc/executor/executor.go @@ -94,8 +94,8 @@ func (e *Executor) Execute(proposals []*proposal.Proposal) error { e.exitLock.RLock() defer e.exitLock.RUnlock() - sessionID := proposals[0].MessageID - props, err := e.proposalsForExecution(proposals) + messageID := proposals[0].MessageID + props, err := e.proposalsForExecution(proposals, messageID) if err != nil { return err } @@ -119,15 +119,14 @@ func (e *Executor) Execute(proposals []*proposal.Proposal) error { return fmt.Errorf("no resource for ID %s", hex.EncodeToString(resourceID[:])) } - sessionID := fmt.Sprintf("%s-%s", sessionID, hex.EncodeToString(resourceID[:])) - return e.executeResourceProps(props, resource, sessionID) + return e.executeResourceProps(props, resource, messageID) }) } return p.Wait() } -func (e *Executor) executeResourceProps(props []*BtcTransferProposal, resource config.Resource, sessionID string) error { - log.Info().Str("SessionID", sessionID).Msgf("Executing proposals for resource %s", hex.EncodeToString(resource.ResourceID[:])) +func (e *Executor) executeResourceProps(props []*BtcTransferProposal, resource config.Resource, messageID string) error { + log.Info().Str("messageID", messageID).Msgf("Executing proposals %+v for resource %s", props, hex.EncodeToString(resource.ResourceID[:])) tx, utxos, err := e.rawTx(props, resource) if err != nil { @@ -138,8 +137,11 @@ func (e *Executor) executeResourceProps(props []*BtcTransferProposal, resource c p := pool.New().WithErrors() executionContext, cancelExecution := context.WithCancel(context.Background()) watchContext, cancelWatch := context.WithCancel(context.Background()) + sessionID := fmt.Sprintf("%s-%s", messageID, hex.EncodeToString(resource.ResourceID[:])) defer cancelWatch() - p.Go(func() error { return e.watchExecution(watchContext, cancelExecution, tx, props, sigChn, sessionID) }) + p.Go(func() error { + return e.watchExecution(watchContext, cancelExecution, tx, props, sigChn, sessionID, messageID) + }) prevOuts := make(map[wire.OutPoint]*wire.TxOut) for _, utxo := range utxos { txOut := wire.NewTxOut(int64(utxo.Value), resource.Script) @@ -152,6 +154,11 @@ func (e *Executor) executeResourceProps(props []*BtcTransferProposal, resource c prevOutputFetcher := txscript.NewMultiPrevOutFetcher(prevOuts) sigHashes := txscript.NewTxSigHashes(tx, prevOutputFetcher) + var buf buffer.Buffer + _ = tx.Serialize(&buf) + bytes := buf.Bytes() + log.Info().Str("messageID", messageID).Msgf("Assembled raw unsigned transaction %s", hex.EncodeToString(bytes)) + // we need to sign each input individually for i := range tx.TxIn { txHash, err := txscript.CalcTaprootSignatureHash(sigHashes, txscript.SigHashDefault, tx, i, prevOutputFetcher) @@ -165,7 +172,8 @@ func (e *Executor) executeResourceProps(props []*BtcTransferProposal, resource c i, msg, resource.Tweak, - fmt.Sprintf("%s-%s", sessionID, hex.EncodeToString(txHash)), + messageID, + fmt.Sprintf("%s-%d", sessionID, i), e.host, e.comm, e.fetcher) @@ -178,7 +186,14 @@ func (e *Executor) executeResourceProps(props []*BtcTransferProposal, resource c return p.Wait() } -func (e *Executor) watchExecution(ctx context.Context, cancelExecution context.CancelFunc, tx *wire.MsgTx, proposals []*BtcTransferProposal, sigChn chan interface{}, sessionID string) error { +func (e *Executor) watchExecution( + ctx context.Context, + cancelExecution context.CancelFunc, + tx *wire.MsgTx, + proposals []*BtcTransferProposal, + sigChn chan interface{}, + sessionID string, + messageID string) error { timeout := time.NewTicker(signingTimeout) defer timeout.Stop() defer cancelExecution() @@ -198,7 +213,7 @@ func (e *Executor) watchExecution(ctx context.Context, cancelExecution context.C } cancelExecution() - hash, err := e.sendTx(tx, signatures) + hash, err := e.sendTx(tx, signatures, messageID) if err != nil { _ = e.comm.Broadcast(e.host.Peerstore().Peers(), []byte{}, comm.TssFailMsg, sessionID) e.storeProposalsStatus(proposals, store.FailedProp) @@ -206,7 +221,7 @@ func (e *Executor) watchExecution(ctx context.Context, cancelExecution context.C } e.storeProposalsStatus(proposals, store.ExecutedProp) - log.Info().Str("SessionID", sessionID).Msgf("Sent proposals execution with hash: %s", hash) + log.Info().Str("messageID", messageID).Msgf("Sent proposals execution with hash: %s", hash) } case <-timeout.C: { @@ -307,7 +322,7 @@ func (e *Executor) fee(numOfInputs, numOfOutputs uint64) (uint64, error) { return (numOfInputs*INPUT_SIZE + numOfOutputs*OUTPUT_SIZE) * ((recommendedFee.EconomyFee/FEE_ROUNDING_FACTOR)*FEE_ROUNDING_FACTOR + FEE_ROUNDING_FACTOR), nil } -func (e *Executor) sendTx(tx *wire.MsgTx, signatures []taproot.Signature) (*chainhash.Hash, error) { +func (e *Executor) sendTx(tx *wire.MsgTx, signatures []taproot.Signature, messageID string) (*chainhash.Hash, error) { for i, sig := range signatures { tx.TxIn[i].Witness = wire.TxWitness{sig} } @@ -318,7 +333,7 @@ func (e *Executor) sendTx(tx *wire.MsgTx, signatures []taproot.Signature) (*chai return nil, err } bytes := buf.Bytes() - log.Debug().Msgf("Assembled raw transaction %s", hex.EncodeToString(bytes)) + log.Debug().Str("messageID", messageID).Msgf("Assembled raw transaction %s", hex.EncodeToString(bytes)) return e.conn.SendRawTransaction(tx, true) } @@ -332,7 +347,7 @@ func (e *Executor) signaturesFilled(signatures []taproot.Signature) bool { return true } -func (e *Executor) proposalsForExecution(proposals []*proposal.Proposal) ([]*BtcTransferProposal, error) { +func (e *Executor) proposalsForExecution(proposals []*proposal.Proposal, messageID string) ([]*BtcTransferProposal, error) { e.propMutex.Lock() props := make([]*BtcTransferProposal, 0) for _, prop := range proposals { @@ -342,7 +357,7 @@ func (e *Executor) proposalsForExecution(proposals []*proposal.Proposal) ([]*Btc } if executed { - log.Info().Msgf("Proposal %s already executed", fmt.Sprintf("%d-%d-%d", prop.Source, prop.Destination, prop.Data.(BtcTransferProposalData).DepositNonce)) + log.Warn().Str("messageID", messageID).Msgf("Proposal %s already executed", fmt.Sprintf("%d-%d-%d", prop.Source, prop.Destination, prop.Data.(BtcTransferProposalData).DepositNonce)) continue } diff --git a/chains/btc/listener/deposit-handler.go b/chains/btc/listener/deposit-handler.go index 278ceacf..df36e252 100644 --- a/chains/btc/listener/deposit-handler.go +++ b/chains/btc/listener/deposit-handler.go @@ -22,7 +22,8 @@ func NewBtcDepositHandler() *BtcDepositHandler { return &BtcDepositHandler{} } -func (e *BtcDepositHandler) HandleDeposit(sourceID uint8, +func (e *BtcDepositHandler) HandleDeposit( + sourceID uint8, depositNonce uint64, resourceID [32]byte, amount *big.Int, diff --git a/chains/evm/executor/executor.go b/chains/evm/executor/executor.go index 348ada6a..4494a84b 100644 --- a/chains/evm/executor/executor.go +++ b/chains/evm/executor/executor.go @@ -87,6 +87,7 @@ func (e *Executor) Execute(proposals []*proposal.Proposal) error { if len(batch.proposals) == 0 { continue } + messageID := batch.proposals[0].MessageID b := batch p.Go(func() error { @@ -95,13 +96,14 @@ func (e *Executor) Execute(proposals []*proposal.Proposal) error { return err } - sessionID := fmt.Sprintf("%s-%d", batch.proposals[0].MessageID, i) + sessionID := fmt.Sprintf("%s-%d", messageID, i) log.Info().Str("messageID", batch.proposals[0].MessageID).Msgf("Starting session with ID: %s", sessionID) msg := big.NewInt(0) msg.SetBytes(propHash) signing, err := signing.NewSigning( msg, + messageID, sessionID, e.host, e.comm, @@ -122,14 +124,20 @@ func (e *Executor) Execute(proposals []*proposal.Proposal) error { return err }) - ep.Go(func() error { return e.watchExecution(watchContext, cancelExecution, b, sigChn, sessionID) }) + ep.Go(func() error { return e.watchExecution(watchContext, cancelExecution, b, sigChn, sessionID, messageID) }) return ep.Wait() }) } return p.Wait() } -func (e *Executor) watchExecution(ctx context.Context, cancelExecution context.CancelFunc, batch *Batch, sigChn chan interface{}, sessionID string) error { +func (e *Executor) watchExecution( + ctx context.Context, + cancelExecution context.CancelFunc, + batch *Batch, + sigChn chan interface{}, + sessionID string, + messageID string) error { ticker := time.NewTicker(executionCheckPeriod) timeout := time.NewTicker(signingTimeout) defer ticker.Stop() @@ -152,7 +160,7 @@ func (e *Executor) watchExecution(ctx context.Context, cancelExecution context.C return err } - log.Info().Str("messageID", sessionID).Msgf("Sent proposals execution with hash: %s", hash) + log.Info().Str("messageID", messageID).Msgf("Sent proposals execution with hash: %s", hash) } case <-ticker.C: { @@ -160,7 +168,7 @@ func (e *Executor) watchExecution(ctx context.Context, cancelExecution context.C continue } - log.Info().Str("messageID", sessionID).Msgf("Successfully executed proposals") + log.Info().Str("messageID", messageID).Msgf("Successfully executed proposals") return nil } case <-timeout.C: diff --git a/chains/substrate/executor/executor.go b/chains/substrate/executor/executor.go index d3f8252f..bd09fe6d 100644 --- a/chains/substrate/executor/executor.go +++ b/chains/substrate/executor/executor.go @@ -105,12 +105,13 @@ func (e *Executor) Execute(proposals []*proposal.Proposal) error { return err } - sessionID := transferProposals[0].MessageID + messageID := transferProposals[0].MessageID msg := big.NewInt(0) msg.SetBytes(propHash) signing, err := signing.NewSigning( msg, - sessionID, + messageID, + messageID, e.host, e.comm, e.fetcher) @@ -132,7 +133,7 @@ func (e *Executor) Execute(proposals []*proposal.Proposal) error { return err }) pool.Go(func() error { - return e.watchExecution(watchContext, cancelExecution, transferProposals, sigChn, sessionID) + return e.watchExecution(watchContext, cancelExecution, transferProposals, sigChn, messageID) }) return pool.Wait() } diff --git a/tss/ecdsa/signing/signing.go b/tss/ecdsa/signing/signing.go index 97f9ab59..1afbce9c 100644 --- a/tss/ecdsa/signing/signing.go +++ b/tss/ecdsa/signing/signing.go @@ -44,6 +44,7 @@ type Signing struct { func NewSigning( msg *big.Int, + messageID string, sessionID string, host host.Host, comm comm.Communication, @@ -64,7 +65,7 @@ func NewSigning( Communication: comm, Peers: key.Peers, SID: sessionID, - Log: log.With().Str("SessionID", sessionID).Str("Process", "signing").Logger(), + Log: log.With().Str("SessionID", sessionID).Str("messageID", messageID).Str("Process", "signing").Logger(), Cancel: func() {}, }, key: key, diff --git a/tss/frost/signing/signing.go b/tss/frost/signing/signing.go index f1ceed3a..92fc7338 100644 --- a/tss/frost/signing/signing.go +++ b/tss/frost/signing/signing.go @@ -52,6 +52,7 @@ func NewSigning( id int, msg *big.Int, tweak string, + messageID string, sessionID string, host host.Host, comm comm.Communication, @@ -85,7 +86,7 @@ func NewSigning( Communication: comm, Peers: key.Peers, SID: sessionID, - Log: log.With().Str("SessionID", sessionID).Str("Process", "signing").Logger(), + Log: log.With().Str("SessionID", sessionID).Str("messageID", messageID).Str("Process", "signing").Logger(), Cancel: func() {}, Done: make(chan bool), }, From 2f3a5cdfc1d3e821565c9a4a52f726114aa3e6fa Mon Sep 17 00:00:00 2001 From: mpetrun5 Date: Tue, 16 Jul 2024 13:23:27 +0200 Subject: [PATCH 08/11] Add signing message hex --- tss/ecdsa/signing/signing.go | 2 +- tss/frost/signing/signing.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tss/ecdsa/signing/signing.go b/tss/ecdsa/signing/signing.go index 1afbce9c..1241d334 100644 --- a/tss/ecdsa/signing/signing.go +++ b/tss/ecdsa/signing/signing.go @@ -127,7 +127,7 @@ func (s *Signing) Run( p.Go(func(ctx context.Context) error { return s.processEndMessage(ctx, sigChn) }) p.Go(func(ctx context.Context) error { return s.monitorSigning(ctx) }) - s.Log.Info().Msgf("Started signing process") + s.Log.Info().Msgf("Started signing process for message %s", s.msg.Text(16)) tssError := s.Party.Start() if tssError != nil { diff --git a/tss/frost/signing/signing.go b/tss/frost/signing/signing.go index 92fc7338..c4f07f46 100644 --- a/tss/frost/signing/signing.go +++ b/tss/frost/signing/signing.go @@ -136,7 +136,7 @@ func (s *Signing) Run( p.Go(func(ctx context.Context) error { return s.processEndMessage(ctx) }) p.Go(func(ctx context.Context) error { return s.ProcessOutboundMessages(ctx, outChn, comm.TssKeySignMsg) }) - s.Log.Info().Msgf("Started signing process") + s.Log.Info().Msgf("Started signing process for message %s", s.msg.Text(16)) return p.Wait() } From 5a64060d626c6de783b57b69eaed3c63a024fd46 Mon Sep 17 00:00:00 2001 From: mpetrun5 Date: Tue, 16 Jul 2024 13:28:47 +0200 Subject: [PATCH 09/11] Fix linter --- tss/ecdsa/signing/signing_test.go | 4 ++-- tss/frost/signing/signing_test.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tss/ecdsa/signing/signing_test.go b/tss/ecdsa/signing/signing_test.go index 1ebc6e70..47d5b434 100644 --- a/tss/ecdsa/signing/signing_test.go +++ b/tss/ecdsa/signing/signing_test.go @@ -46,7 +46,7 @@ func (s *SigningTestSuite) Test_ValidSigningProcess() { msgBytes := []byte("Message") msg := big.NewInt(0) msg.SetBytes(msgBytes) - signing, err := signing.NewSigning(msg, "signing1", host, &communication, fetcher) + signing, err := signing.NewSigning(msg, "signing1", "signing1", host, &communication, fetcher) if err != nil { panic(err) } @@ -96,7 +96,7 @@ func (s *SigningTestSuite) Test_SigningTimeout() { msgBytes := []byte("Message") msg := big.NewInt(0) msg.SetBytes(msgBytes) - signing, err := signing.NewSigning(msg, "signing2", host, &communication, fetcher) + signing, err := signing.NewSigning(msg, "signing2", "signing2", host, &communication, fetcher) if err != nil { panic(err) } diff --git a/tss/frost/signing/signing_test.go b/tss/frost/signing/signing_test.go index b7feb435..1199315f 100644 --- a/tss/frost/signing/signing_test.go +++ b/tss/frost/signing/signing_test.go @@ -60,7 +60,7 @@ func (s *SigningTestSuite) Test_ValidSigningProcess() { communicationMap[host.ID()] = &communication fetcher := keyshare.NewFrostKeyshareStore(fmt.Sprintf("../../test/keyshares/%d-frost.keyshare", i)) - signing, err := signing.NewSigning(1, msg, tweak, "signing1", host, &communication, fetcher) + signing, err := signing.NewSigning(1, msg, tweak, "signing1", "signing1", host, &communication, fetcher) if err != nil { panic(err) } @@ -115,7 +115,7 @@ func (s *SigningTestSuite) Test_ProcessTimeout() { communicationMap[host.ID()] = &communication fetcher := keyshare.NewFrostKeyshareStore(fmt.Sprintf("../../test/keyshares/%d-frost.keyshare", i)) - signing, err := signing.NewSigning(1, msg, tweak, "signing1", host, &communication, fetcher) + signing, err := signing.NewSigning(1, msg, tweak, "signing1", "signing1", host, &communication, fetcher) if err != nil { panic(err) } From e8c2705caf46881697791517c0cc041b59daa4c7 Mon Sep 17 00:00:00 2001 From: mpetrun5 Date: Tue, 16 Jul 2024 16:48:31 +0200 Subject: [PATCH 10/11] Fix multiple input btc signing race condition --- chains/btc/executor/executor.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chains/btc/executor/executor.go b/chains/btc/executor/executor.go index aa2eb659..63edd3e6 100644 --- a/chains/btc/executor/executor.go +++ b/chains/btc/executor/executor.go @@ -161,6 +161,7 @@ func (e *Executor) executeResourceProps(props []*BtcTransferProposal, resource c // we need to sign each input individually for i := range tx.TxIn { + sessionID := fmt.Sprintf("%s-%d", sessionID, i) txHash, err := txscript.CalcTaprootSignatureHash(sigHashes, txscript.SigHashDefault, tx, i, prevOutputFetcher) if err != nil { return err @@ -173,7 +174,7 @@ func (e *Executor) executeResourceProps(props []*BtcTransferProposal, resource c msg, resource.Tweak, messageID, - fmt.Sprintf("%s-%d", sessionID, i), + sessionID, e.host, e.comm, e.fetcher) From 27edd380b11d7f8d6e48b442fb0f149f0d45322e Mon Sep 17 00:00:00 2001 From: mpetrun5 Date: Tue, 16 Jul 2024 17:33:24 +0200 Subject: [PATCH 11/11] Fix same age inputs being ordered differently --- chains/btc/mempool/mempool.go | 6 +++++- chains/btc/mempool/mempool_test.go | 11 +++++++++++ chains/btc/mempool/test-data/successful-utxo.json | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/chains/btc/mempool/mempool.go b/chains/btc/mempool/mempool.go index 0a882a9c..814bfeb0 100644 --- a/chains/btc/mempool/mempool.go +++ b/chains/btc/mempool/mempool.go @@ -77,7 +77,11 @@ func (a *MempoolAPI) Utxos(address string) ([]Utxo, error) { return nil, err } sort.Slice(utxos, func(i int, j int) bool { - return utxos[i].Status.BlockTime < utxos[j].Status.BlockTime + if utxos[i].Status.BlockTime == utxos[j].Status.BlockTime { + return utxos[i].TxID < utxos[j].TxID + } else { + return utxos[i].Status.BlockTime < utxos[j].Status.BlockTime + } }) return utxos, nil diff --git a/chains/btc/mempool/mempool_test.go b/chains/btc/mempool/mempool_test.go index cc507edc..20c068b1 100644 --- a/chains/btc/mempool/mempool_test.go +++ b/chains/btc/mempool/mempool_test.go @@ -60,6 +60,17 @@ func (s *MempoolTestSuite) Test_Utxo_SuccessfulFetch() { BlockTime: 1715083122, }, }, + { + TxID: "28154e2008912d27978225c096c22ffe2ea65e1d55bf440ee41c21f9489c7fe2", + Vout: 0, + Value: 11197, + Status: mempool.Status{ + Confirmed: true, + BlockHeight: 2812826, + BlockHash: "000000000000001a01d4058773384f2c23aed5a7e5ede252f99e290fa58324a3", + BlockTime: 1715083122, + }, + }, { TxID: "28154e2008912d27978225c096c22ffe2ea65e1d55bf440ee41c21f9489c7fe9", Vout: 0, diff --git a/chains/btc/mempool/test-data/successful-utxo.json b/chains/btc/mempool/test-data/successful-utxo.json index 0435b6c9..d47aceb3 100644 --- a/chains/btc/mempool/test-data/successful-utxo.json +++ b/chains/btc/mempool/test-data/successful-utxo.json @@ -1,4 +1,5 @@ [ {"txid":"28154e2008912d27978225c096c22ffe2ea65e1d55bf440ee41c21f9489c7fe9","vout":0,"status":{"confirmed":true,"block_height":2812827,"block_hash":"000000000000001a01d4058773384f2c23aed5a7e5ede252f99e290fa58324a5","block_time":1715083123},"value":11198}, + {"txid":"28154e2008912d27978225c096c22ffe2ea65e1d55bf440ee41c21f9489c7fe2","vout":0,"status":{"confirmed":true,"block_height":2812826,"block_hash":"000000000000001a01d4058773384f2c23aed5a7e5ede252f99e290fa58324a3","block_time":1715083122},"value":11197}, {"txid":"28154e2008912d27978225c096c22ffe2ea65e1d55bf440ee41c21f9489c7fe1","vout":0,"status":{"confirmed":true,"block_height":2812826,"block_hash":"000000000000001a01d4058773384f2c23aed5a7e5ede252f99e290fa58324a3","block_time":1715083122},"value":11197} ] \ No newline at end of file