Skip to content

Commit

Permalink
Tweak blob gas pricing and improve debug wallet timeout (#2119)
Browse files Browse the repository at this point in the history
* tweak blob gas pricing and improve timeout on debug wallet
  • Loading branch information
badgersrus authored Oct 31, 2024
1 parent 32f4203 commit 663b13f
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 88 deletions.
8 changes: 6 additions & 2 deletions go/ethadapter/geth_rpc_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,10 +359,14 @@ func (e *gethRPCClient) prepareBlobTxToRetry(ctx context.Context, txData types.T
}
blobFeeCap := calcBlobFeeCap(blobBaseFee, retryNumber)

baseFee := head.BaseFee
gasFeeCap := new(big.Int).Mul(baseFee, big.NewInt(2))
gasFeeCap.Add(gasFeeCap, retryPrice)

return &types.BlobTx{
Nonce: nonce,
GasTipCap: uint256.MustFromBig(retryPrice), // aka maxPriorityFeePerGas
GasFeeCap: uint256.MustFromBig(retryPrice), // aka. maxFeePerGas
GasTipCap: uint256.MustFromBig(retryPrice), // maxPriorityFeePerGas
GasFeeCap: uint256.MustFromBig(gasFeeCap), // maxFeePerGas = (baseFee * 2) + maxPriorityFeePerGas
Gas: gasLimit,
To: *unEstimatedTx.To(),
Value: uint256.MustFromBig(value),
Expand Down
85 changes: 45 additions & 40 deletions go/host/l1/publisher.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,55 +231,60 @@ func (p *Publisher) PublishSecretResponse(secretResponse *common.ProducedSecretR
// ExtractRelevantTenTransactions will extract any transactions from the block that are relevant to TEN
// todo (#2495) we should monitor for relevant L1 events instead of scanning every transaction in the block
func (p *Publisher) ExtractRelevantTenTransactions(block *types.Block, receipts types.Receipts) ([]*common.TxAndReceiptAndBlobs, []*ethadapter.L1RollupTx, []*ethadapter.L1SetImportantContractsTx) {
txWithReceiptsAndBlobs := make([]*common.TxAndReceiptAndBlobs, 0)
rollupTxs := make([]*ethadapter.L1RollupTx, 0)
contractAddressTxs := make([]*ethadapter.L1SetImportantContractsTx, 0)

txs := block.Transactions()
for i, rec := range receipts {
if rec.BlockNumber == nil {
continue // Skip non-relevant transactions
}
// temporarily add this host stopping check to prevent sim test failures until a more robust solution is implemented
for !p.hostStopper.IsStopping() {
txWithReceiptsAndBlobs := make([]*common.TxAndReceiptAndBlobs, 0)
rollupTxs := make([]*ethadapter.L1RollupTx, 0)
contractAddressTxs := make([]*ethadapter.L1SetImportantContractsTx, 0)

txs := block.Transactions()
for i, rec := range receipts {
if rec.BlockNumber == nil {
continue // Skip non-relevant transactions
}

decodedTx := p.mgmtContractLib.DecodeTx(txs[i])
var blobs []*kzg4844.Blob
var err error
decodedTx := p.mgmtContractLib.DecodeTx(txs[i])
var blobs []*kzg4844.Blob
var err error

switch typedTx := decodedTx.(type) {
case *ethadapter.L1SetImportantContractsTx:
contractAddressTxs = append(contractAddressTxs, typedTx)
case *ethadapter.L1RollupHashes:
blobs, err = p.blobResolver.FetchBlobs(p.sendingContext, block.Header(), typedTx.BlobHashes)
if err != nil {
if errors.Is(err, ethereum.NotFound) {
p.logger.Crit("Blobs were not found on beacon chain or archive service", "block", block.Hash(), "error", err)
} else {
p.logger.Crit("could not fetch blobs", log.ErrKey, err)
switch typedTx := decodedTx.(type) {
case *ethadapter.L1SetImportantContractsTx:
contractAddressTxs = append(contractAddressTxs, typedTx)
case *ethadapter.L1RollupHashes:
blobs, err = p.blobResolver.FetchBlobs(p.sendingContext, block.Header(), typedTx.BlobHashes)
// temporarily add this host stopping check to prevent sim test failures until a more robust solution is implemented
if err != nil {
if errors.Is(err, ethereum.NotFound) {
p.logger.Crit("Blobs were not found on beacon chain or archive service", "block", block.Hash(), "error", err)
} else {
p.logger.Crit("could not fetch blobs", log.ErrKey, err)
}
continue
}
continue
}

encodedRlp, err := ethadapter.DecodeBlobs(blobs)
if err != nil {
p.logger.Crit("could not decode blobs.", log.ErrKey, err)
continue
}
encodedRlp, err := ethadapter.DecodeBlobs(blobs)
if err != nil {
p.logger.Crit("could not decode blobs.", log.ErrKey, err)
continue
}

rlp := &ethadapter.L1RollupTx{
Rollup: encodedRlp,
rlp := &ethadapter.L1RollupTx{
Rollup: encodedRlp,
}
rollupTxs = append(rollupTxs, rlp)
}
rollupTxs = append(rollupTxs, rlp)

// compile the tx, receipt and blobs into a single struct for submission to the enclave
txWithReceiptsAndBlobs = append(txWithReceiptsAndBlobs, &common.TxAndReceiptAndBlobs{
Tx: txs[i],
Receipt: rec,
Blobs: blobs,
})
}

// compile the tx, receipt and blobs into a single struct for submission to the enclave
txWithReceiptsAndBlobs = append(txWithReceiptsAndBlobs, &common.TxAndReceiptAndBlobs{
Tx: txs[i],
Receipt: rec,
Blobs: blobs,
})
return txWithReceiptsAndBlobs, rollupTxs, contractAddressTxs
}

return txWithReceiptsAndBlobs, rollupTxs, contractAddressTxs
return nil, nil, nil
}

// FindSecretResponseTx will scan the block for any secret response transactions. This is separate from the above method
Expand Down
11 changes: 6 additions & 5 deletions integration/smartcontract/debug_mgmt_contract_lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,20 @@ func (d *debugMgmtContractLib) AwaitedIssueRollup(rollup common.ExtRollup, clien
}
txData, err := d.CreateBlobRollup(&ethadapter.L1RollupTx{Rollup: encodedRollup})
if err != nil {
return err
return fmt.Errorf("failed to create blob rollup: %w", err)
}

issuedTx, receipt, err := w.AwaitedSignAndSendTransaction(client, txData)
if err != nil {
return err
return fmt.Errorf("failed to send and await transaction: %w", err)
}

if receipt.Status != types.ReceiptStatusSuccessful {
_, err := w.debugTransaction(client, issuedTx)
if err != nil {
return fmt.Errorf("transaction should have succeeded, expected %d got %d - reason: %w", types.ReceiptStatusSuccessful, receipt.Status, err)
debugOutput, debugErr := w.debugTransaction(client, issuedTx)
if debugErr != nil {
return fmt.Errorf("transaction failed with status %d and debug failed: %v", receipt.Status, debugErr)
}
return fmt.Errorf("transaction failed with status %d: %s", receipt.Status, string(debugOutput))
}

// rollup meta data is actually stored
Expand Down
58 changes: 20 additions & 38 deletions integration/smartcontract/debug_wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,79 +2,61 @@ package smartcontract

import (
"context"
"errors"
"fmt"
"time"

"github.com/ethereum/go-ethereum"
"github.com/ten-protocol/go-ten/go/common/retry"

"github.com/ethereum/go-ethereum/core/types"
"github.com/ten-protocol/go-ten/go/ethadapter"
"github.com/ten-protocol/go-ten/go/wallet"
)

var _timeout = 180 * time.Second

// debugWallet is a wrapper around the wallet that simplifies commonly used functions
type debugWallet struct {
wallet.Wallet
receiptTimeout time.Duration
}

// newDebugWallet returns a new debug wrapped wallet
func newDebugWallet(w wallet.Wallet) *debugWallet {
return &debugWallet{w}
func newDebugWallet(w wallet.Wallet, timeout time.Duration) *debugWallet {
return &debugWallet{
Wallet: w,
receiptTimeout: timeout,
}
}

// AwaitedSignAndSendTransaction signs a tx, issues the tx and awaits the tx to be minted into a block
func (w *debugWallet) AwaitedSignAndSendTransaction(client ethadapter.EthClient, txData types.TxData) (*types.Transaction, *types.Receipt, error) {
var err error

txData, err = client.PrepareTransactionToSend(context.Background(), txData, w.Address())
txData, err := client.PrepareTransactionToSend(context.Background(), txData, w.Address())
if err != nil {
w.SetNonce(w.GetNonce() - 1)
return nil, nil, err
}
signedTx, err := w.SignAndSendTransaction(client, txData)
if err != nil {
return nil, nil, err
}
receipt, err := waitTxResult(client, signedTx)
if err != nil {
return nil, nil, err
}
return signedTx, receipt, nil
}

// SignAndSendTransaction signs and sends a tx
func (w *debugWallet) SignAndSendTransaction(client ethadapter.EthClient, txData types.TxData) (*types.Transaction, error) {
signedTx, err := w.SignTransaction(txData)
if err != nil {
return nil, err
return nil, nil, err
}

err = client.SendTransaction(signedTx)
if err != nil {
return nil, err
return nil, nil, err
}

return signedTx, nil
}

// waitTxResult waits for a tx to be minted into a block
func waitTxResult(client ethadapter.EthClient, tx *types.Transaction) (*types.Receipt, error) {
var receipt *types.Receipt
var err error
for start := time.Now(); time.Since(start) < _timeout; time.Sleep(time.Second) {
receipt, err = client.TransactionReceipt(tx.Hash())
err = retry.Do(func() error {
receipt, err = client.TransactionReceipt(signedTx.Hash())
if err != nil {
if errors.Is(err, ethereum.NotFound) {
continue
}
return nil, err
return err
}
if receipt == nil {
return fmt.Errorf("no receipt yet")
}
return nil
}, retry.NewTimeoutStrategy(w.receiptTimeout, time.Second))

return receipt, nil
}
return nil, fmt.Errorf("transaction not minted after timeout")
return signedTx, receipt, err
}

func (w *debugWallet) debugTransaction(client ethadapter.EthClient, tx *types.Transaction) ([]byte, error) {
Expand Down
4 changes: 1 addition & 3 deletions integration/smartcontract/smartcontracts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,13 @@ func runGethNetwork(t *testing.T) *netInfo {
}

func TestManagementContract(t *testing.T) {
t.Skip("Skipping as it's too flaky.")

// run tests on one network
sim := runGethNetwork(t)
defer sim.eth2Network.Stop() //nolint: errcheck

// set up the client and the (debug) wallet
client := sim.ethClients[0]
w := newDebugWallet(sim.wallets[0])
w := newDebugWallet(sim.wallets[0], 30*time.Second)

for name, test := range map[string]func(*testing.T, *debugMgmtContractLib, *debugWallet, ethadapter.EthClient){
"secretCannotBeInitializedTwice": secretCannotBeInitializedTwice,
Expand Down

0 comments on commit 663b13f

Please sign in to comment.