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

Tweak blob gas pricing and improve debug wallet timeout #2119

Merged
merged 6 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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