@@ -15,7 +15,9 @@ import (
1515 "github.com/ethereum/go-ethereum/common"
1616 "github.com/ethereum/go-ethereum/core/types"
1717 servicemanager "github.com/yetanotherco/aligned_layer/contracts/bindings/AlignedLayerServiceManager"
18+ retry "github.com/yetanotherco/aligned_layer/core"
1819 "github.com/yetanotherco/aligned_layer/core/config"
20+ "github.com/yetanotherco/aligned_layer/core/utils"
1921)
2022
2123type AvsWriter struct {
@@ -70,7 +72,10 @@ func NewAvsWriterFromConfig(baseConfig *config.BaseConfig, ecdsaConfig *config.E
7072 }, nil
7173}
7274
73- func (w * AvsWriter ) SendAggregatedResponse (batchIdentifierHash [32 ]byte , batchMerkleRoot [32 ]byte , senderAddress [20 ]byte , nonSignerStakesAndSignature servicemanager.IBLSSignatureCheckerNonSignerStakesAndSignature ) (* common.Hash , error ) {
75+ // Sends AggregatedResponse and waits for the receipt for three blocks, if not received
76+ // it will try again bumping the last tx gas price based on `CalculateGasPriceBump`
77+ // This process happens indefinitely until the transaction is included.
78+ func (w * AvsWriter ) SendAggregatedResponse (batchIdentifierHash [32 ]byte , batchMerkleRoot [32 ]byte , senderAddress [20 ]byte , nonSignerStakesAndSignature servicemanager.IBLSSignatureCheckerNonSignerStakesAndSignature , gasBumpPercentage uint , gasBumpIncrementalPercentage uint , timeToWaitBeforeBump time.Duration , onGasPriceBumped func (* big.Int )) (* types.Receipt , error ) {
7479 txOpts := * w .Signer .GetTxOpts ()
7580 txOpts .NoSend = true // simulate the transaction
7681 tx , err := w .RespondToTaskV2Retryable (& txOpts , batchMerkleRoot , senderAddress , nonSignerStakesAndSignature )
@@ -83,17 +88,61 @@ func (w *AvsWriter) SendAggregatedResponse(batchIdentifierHash [32]byte, batchMe
8388 return nil , err
8489 }
8590
86- // Send the transaction
91+ // Set the nonce, as we might have to replace the transaction with a higher gas price
92+ txNonce := big .NewInt (int64 (tx .Nonce ()))
93+ txOpts .Nonce = txNonce
94+ txOpts .GasPrice = tx .GasPrice ()
8795 txOpts .NoSend = false
88- txOpts .GasLimit = tx .Gas () * 110 / 100 // Add 10% to the gas limit
89- tx , err = w .RespondToTaskV2Retryable (& txOpts , batchMerkleRoot , senderAddress , nonSignerStakesAndSignature )
90- if err != nil {
91- return nil , err
96+ i := 0
97+
98+ respondToTaskV2Func := func () (* types.Receipt , error ) {
99+ gasPrice , err := utils .GetGasPriceRetryable (w .Client , w .ClientFallback )
100+ if err != nil {
101+ return nil , err
102+ }
103+
104+ bumpedGasPrice := utils .CalculateGasPriceBumpBasedOnRetry (gasPrice , gasBumpPercentage , gasBumpIncrementalPercentage , i )
105+ // new bumped gas price must be higher than the last one (this should hardly ever happen though)
106+ if bumpedGasPrice .Cmp (txOpts .GasPrice ) > 0 {
107+ txOpts .GasPrice = bumpedGasPrice
108+ } else {
109+ // bump the last tx gas price a little by `gasBumpIncrementalPercentage` to replace it.
110+ txOpts .GasPrice = utils .CalculateGasPriceBumpBasedOnRetry (txOpts .GasPrice , gasBumpIncrementalPercentage , 0 , 0 )
111+ }
112+
113+ if i > 0 {
114+ onGasPriceBumped (txOpts .GasPrice )
115+ }
116+
117+ err = w .checkRespondToTaskFeeLimit (tx , txOpts , batchIdentifierHash , senderAddress )
118+ if err != nil {
119+ return nil , retry.PermanentError {Inner : err }
120+ }
121+
122+ w .logger .Infof ("Sending RespondToTask transaction with a gas price of %v" , txOpts .GasPrice )
123+
124+ tx , err = w .RespondToTaskV2Retryable (& txOpts , batchMerkleRoot , senderAddress , nonSignerStakesAndSignature )
125+ if err != nil {
126+ return nil , err
127+ }
128+
129+ receipt , err := utils .WaitForTransactionReceiptRetryable (w .Client , w .ClientFallback , tx .Hash (), timeToWaitBeforeBump )
130+ if receipt != nil {
131+ return receipt , nil
132+ }
133+
134+ // if we are here, it means we have reached the receipt waiting timeout
135+ // we increment the i here to add an incremental percentage to increase the odds of being included in the next blocks
136+ i ++
137+
138+ w .logger .Infof ("RespondToTask receipt waiting timeout has passed, will try again..." )
139+ if err != nil {
140+ return nil , err
141+ }
142+ return nil , fmt .Errorf ("transaction failed" )
92143 }
93144
94- txHash := tx .Hash ()
95-
96- return & txHash , nil
145+ return retry .RetryWithData (respondToTaskV2Func , retry .MinDelay , retry .RetryFactor , 0 , retry .MaxInterval , 0 )
97146}
98147
99148func (w * AvsWriter ) checkRespondToTaskFeeLimit (tx * types.Transaction , txOpts bind.TransactOpts , batchIdentifierHash [32 ]byte , senderAddress [20 ]byte ) error {
0 commit comments