synapsecns / sanguine

Synapse Monorepo
MIT License
35 stars 25 forks source link

[submit smaller txes when over cap] #2758

Open trajan0x opened 2 weeks ago

trajan0x commented 2 weeks ago

parse error and resubmit smaller attempt if over configured cap

image
greptile-apps[bot] commented 2 weeks ago

To handle the issue of submitting smaller transactions when over the configured cap, follow these steps:

  1. Update Configuration: Add a new configuration option for the maximum transaction size in config.go.
// Config contains configuration for the submitter.
type Config struct {
    // ... existing fields
    MaxTxSize int `yaml:"max_tx_size"`
}

// GetMaxTxSize returns the maximum transaction size.
func (c *Config) GetMaxTxSize(chainID int) int {
    chainConfig, ok := c.Chains[chainID]
    if ok && chainConfig.MaxTxSize != 0 {
        return chainConfig.MaxTxSize
    }
    return c.MaxTxSize
}
  1. Check Transaction Size: Modify the SubmitTransaction method in submitter.go to check the transaction size before submission.
func (t *txSubmitterImpl) SubmitTransaction(parentCtx context.Context, chainID *big.Int, call ContractCallType) (nonce uint64, err error) {
    // ... existing code

    tx, err := call(transactor)
    if err != nil {
        return 0, fmt.Errorf("could not call contract: %w", err)
    }

    maxTxSize := t.config.GetMaxTxSize(int(chainID.Uint64()))
    if len(tx.Data()) > maxTxSize {
        return 0, fmt.Errorf("transaction size %d exceeds max size %d", len(tx.Data()), maxTxSize)
    }

    // ... existing code
}
  1. Handle Resubmission: Implement logic to parse the error and resubmit smaller transactions if the size exceeds the cap.
if len(tx.Data()) > maxTxSize {
    // Logic to split the transaction into smaller parts and resubmit
    // This will depend on the specific contract and transaction type
}

These changes will ensure that transactions are checked for size before submission and resubmitted in smaller parts if they exceed the configured cap.

References

/ethergo/submitter/submitter.go /ethergo/submitter/config/config.go /ethergo/submitter /ethergo/submitter/config /ethergo/submitter/db

Ask Greptile

greptile-apps[bot] commented 2 weeks ago

To address the issue of submitting smaller transactions when over the configured cap, follow these steps:

  1. Modify SubmitTransaction Method in submitter.go:
    • Locate the SubmitTransaction method in ethergo/submitter/submitter.go.
    • Add logic to catch parse errors and check if the transaction size exceeds the configured cap.
    • If the transaction size is over the cap, split the transaction into smaller parts and resubmit.
func (t *txSubmitterImpl) SubmitTransaction(parentCtx context.Context, chainID *big.Int, call ContractCallType) (nonce uint64, err error) {
    ctx, span := t.metrics.Tracer().Start(parentCtx, "submitter.SubmitTransaction", trace.WithAttributes(
        attribute.Stringer("chainID", chainID),
        attribute.String("caller", runtime.FuncForPC(reflect.ValueOf(call).Pointer()).Name()),
    ))

    defer func() {
        metrics.EndSpanWithErr(span, err)
    }()

    // Existing code...

    tx, err := call(transactor)
    if err != nil {
        // Check if the error is due to transaction size exceeding the cap
        if isTxSizeOverCapError(err) {
            // Logic to split the transaction into smaller parts and resubmit
            smallerTxs, splitErr := splitTransaction(tx)
            if splitErr != nil {
                return 0, fmt.Errorf("could not split transaction: %w", splitErr)
            }
            for _, smallerTx := range smallerTxs {
                _, submitErr := t.SubmitTransaction(ctx, chainID, func(opts *bind.TransactOpts) (*types.Transaction, error) {
                    return smallerTx, nil
                })
                if submitErr != nil {
                    return 0, fmt.Errorf("could not resubmit smaller transaction: %w", submitErr)
                }
            }
            return 0, nil
        }
        return 0, fmt.Errorf("could not call contract: %w", err)
    }

    // Existing code...
}

func isTxSizeOverCapError(err error) bool {
    // Implement logic to check if the error is due to transaction size exceeding the cap
    return false // Placeholder
}

func splitTransaction(tx *types.Transaction) ([]*types.Transaction, error) {
    // Implement logic to split the transaction into smaller parts
    return nil, nil // Placeholder
}
  1. Update Configuration in config.go:
    • Ensure the configuration file (ethergo/submitter/config/config.go) has parameters for the transaction size cap.
// Add a new field in ChainConfig struct
MaxTxSize int `yaml:"max_tx_size"`

// Add a getter method for MaxTxSize
func (c *Config) GetMaxTxSize(chainID int) int {
    chainConfig, ok := c.Chains[chainID]
    if ok && chainConfig.MaxTxSize != 0 {
        return chainConfig.MaxTxSize
    }
    return c.MaxTxSize
}
  1. Handle Configuration in submitter.go:
    • Use the new configuration parameter to determine the transaction size cap.
func (t *txSubmitterImpl) SubmitTransaction(parentCtx context.Context, chainID *big.Int, call ContractCallType) (nonce uint64, err error) {
    // Existing code...

    maxTxSize := t.config.GetMaxTxSize(int(chainID.Uint64()))

    // Existing code...

    tx, err := call(transactor)
    if err != nil {
        // Check if the error is due to transaction size exceeding the cap
        if isTxSizeOverCapError(err) || tx.Size() > maxTxSize {
            // Logic to split the transaction into smaller parts and resubmit
            smallerTxs, splitErr := splitTransaction(tx)
            if splitErr != nil {
                return 0, fmt.Errorf("could not split transaction: %w", splitErr)
            }
            for _, smallerTx := range smallerTxs {
                _, submitErr := t.SubmitTransaction(ctx, chainID, func(opts *bind.TransactOpts) (*types.Transaction, error) {
                    return smallerTx, nil
                })
                if submitErr != nil {
                    return 0, fmt.Errorf("could not resubmit smaller transaction: %w", submitErr)
                }
            }
            return 0, nil
        }
        return 0, fmt.Errorf("could not call contract: %w", err)
    }

    // Existing code...
}

References

/ethergo/submitter/submitter.go /ethergo/submitter/config/config.go /ethergo/submitter

Ask Greptile