Skip to content
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

fix: send aggregated response bump #1440

Open
wants to merge 10 commits into
base: staging
Choose a base branch
from
2 changes: 1 addition & 1 deletion aggregator/pkg/aggregator.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ func (agg *Aggregator) handleBlsAggServiceResponse(blsAggServiceResp blsagg.BlsA
}

agg.logger.Info("Sending aggregated response onchain", "taskIndex", blsAggServiceResp.TaskIndex,
"batchIdentifierHash", "0x"+hex.EncodeToString(batchIdentifierHash[:]))
"batchIdentifierHash", "0x"+hex.EncodeToString(batchIdentifierHash[:]), "merkleRoot", "0x"+hex.EncodeToString(batchData.BatchMerkleRoot[:]))
receipt, err := agg.sendAggregatedResponse(batchIdentifierHash, batchData.BatchMerkleRoot, batchData.SenderAddress, nonSignerStakesAndSignature)
if err == nil {
agg.telemetry.TaskSentToEthereum(batchData.BatchMerkleRoot, receipt.TxHash.String())
Expand Down
39 changes: 28 additions & 11 deletions core/chainio/avs_writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,15 @@ func NewAvsWriterFromConfig(baseConfig *config.BaseConfig, ecdsaConfig *config.E
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) {
txOpts := *w.Signer.GetTxOpts()
txOpts.NoSend = true // simulate the transaction
tx, err := w.RespondToTaskV2Retryable(&txOpts, batchMerkleRoot, senderAddress, nonSignerStakesAndSignature)
sim_tx, err := w.RespondToTaskV2Retryable(&txOpts, batchMerkleRoot, senderAddress, nonSignerStakesAndSignature)
if err != nil {
return nil, err
}

// Set the nonce, as we might have to replace the transaction with a higher gas price
txNonce := big.NewInt(int64(tx.Nonce()))
txNonce := big.NewInt(int64(sim_tx.Nonce()))
txOpts.Nonce = txNonce
txOpts.GasPrice = tx.GasPrice()
txOpts.GasPrice = sim_tx.GasPrice()
txOpts.NoSend = false
i := 0

Expand All @@ -114,29 +114,32 @@ func (w *AvsWriter) SendAggregatedResponse(batchIdentifierHash [32]byte, batchMe

// We compare both Aggregator funds and Batcher balance in Aligned against respondToTaskFeeLimit
// Both are required to have some balance, more details inside the function
err = w.checkAggAndBatcherHaveEnoughBalance(tx, txOpts, batchIdentifierHash, senderAddress)
err = w.checkAggAndBatcherHaveEnoughBalance(sim_tx, txOpts, batchIdentifierHash, senderAddress)
if err != nil {
w.logger.Errorf("Permanent error when checking respond to task fee limit, err %v", err)
return nil, retry.PermanentError{Inner: err}
}

w.logger.Infof("Sending RespondToTask transaction with a gas price of %v", txOpts.GasPrice)

tx, err = w.RespondToTaskV2Retryable(&txOpts, batchMerkleRoot, senderAddress, nonSignerStakesAndSignature)
real_tx, err := w.RespondToTaskV2Retryable(&txOpts, batchMerkleRoot, senderAddress, nonSignerStakesAndSignature)
if err != nil {
w.logger.Errorf("Respond to task transaction err, %v", err)
return nil, err
}

receipt, err := utils.WaitForTransactionReceiptRetryable(w.Client, w.ClientFallback, tx.Hash(), timeToWaitBeforeBump)
w.logger.Infof("Transaction sent, waiting for receipt")
receipt, err := utils.WaitForTransactionReceiptRetryable(w.Client, w.ClientFallback, real_tx.Hash(), timeToWaitBeforeBump)
if receipt != nil {
w.checkIfAggregatorHadToPaidForBatcher(tx, batchIdentifierHash)
w.checkIfAggregatorHadToPaidForBatcher(real_tx, batchIdentifierHash)
return receipt, nil
}

// if we are here, it means we have reached the receipt waiting timeout
// we increment the i here to add an incremental percentage to increase the odds of being included in the next blocks
i++

w.logger.Infof("RespondToTask receipt waiting timeout has passed, will try again...")
w.logger.Infof("RespondToTask receipt waiting timeout has passed, will try again...", "merkle_root", batchMerkleRoot)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -169,9 +172,23 @@ func (w *AvsWriter) checkIfAggregatorHadToPaidForBatcher(tx *types.Transaction,
}

func (w *AvsWriter) checkAggAndBatcherHaveEnoughBalance(tx *types.Transaction, txOpts bind.TransactOpts, batchIdentifierHash [32]byte, senderAddress [20]byte) error {
defer func() {
if r := recover(); r != nil {
w.logger.Error("Recovered from panic", "error", r)
}
// return fmt.Errorf("Recovered from panic") // TODO can't do this
}()

w.logger.Info("Checking if aggregator and batcher have enough balance for the transaction")
aggregatorAddress := txOpts.From
txCost := new(big.Int).Mul(new(big.Int).SetUint64(tx.Gas()), txOpts.GasPrice)
txGasAsBigInt := new(big.Int).SetUint64(tx.Gas())
txGasPrice := txOpts.GasPrice
w.logger.Info("Transaction Gas Cost", "cost", txGasAsBigInt)
w.logger.Info("Transaction Gas Price", "cost", txGasPrice)

txCost := new(big.Int).Mul(txGasAsBigInt, txGasPrice)

// txCost := new(big.Int).Mul(new(big.Int)tx.Gas()), txOpts.GasPrice)
w.logger.Info("Transaction cost", "cost", txCost)

batchState, err := w.BatchesStateRetryable(&bind.CallOpts{}, batchIdentifierHash)
Expand All @@ -183,8 +200,8 @@ func (w *AvsWriter) checkAggAndBatcherHaveEnoughBalance(tx *types.Transaction, t
respondToTaskFeeLimit := batchState.RespondToTaskFeeLimit
w.logger.Info("Checking balance against Batch RespondToTaskFeeLimit", "RespondToTaskFeeLimit", respondToTaskFeeLimit)
// Note: we compare both Aggregator funds and Batcher balance in Aligned against respondToTaskFeeLimit
// Batcher will pay up to respondToTaskFeeLimit, for this he needs that amount of funds in Aligned
// Aggregator will pay any extra cost, for this he needs at least respondToTaskFeeLimit in his balance
// Batcher will pay up to respondToTaskFeeLimit, for this he needs that amount of funds in Aligned
// Aggregator will pay any extra cost, for this he needs at least respondToTaskFeeLimit in his balance
return w.compareBalances(respondToTaskFeeLimit, aggregatorAddress, senderAddress)
}

Expand Down
7 changes: 7 additions & 0 deletions core/chainio/retryable.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,17 @@ func (w *AvsWriter) RespondToTaskV2Retryable(opts *bind.TransactOpts, batchMerkl
respondToTaskV2_func := func() (*types.Transaction, error) {
// Try with main connection
tx, err := w.AvsContractBindings.ServiceManager.RespondToTaskV2(opts, batchMerkleRoot, senderAddress, nonSignerStakesAndSignature)

if err != nil {
println("error probably revert: 1", err.Error())
// If error try with fallback
tx, err = w.AvsContractBindings.ServiceManagerFallback.RespondToTaskV2(opts, batchMerkleRoot, senderAddress, nonSignerStakesAndSignature)
}
// todo quitar retry para ver err mas rapido
if err != nil {
println("error probably revert: 2", err.Error())
}

return tx, err
}
return retry.RetryWithData(respondToTaskV2_func, retry.MinDelayChain, retry.RetryFactor, retry.NumRetries, retry.MaxIntervalChain, retry.MaxElapsedTime)
Expand Down
Loading