diff --git a/pkg/rpc/tx_blob.go b/pkg/rpc/tx_blob.go index e9c5b0af7..d00fda8e0 100644 --- a/pkg/rpc/tx_blob.go +++ b/pkg/rpc/tx_blob.go @@ -7,19 +7,25 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/holiman/uint256" ) -func (c *EthClient) TransactBlobTx(opts *bind.TransactOpts, data []byte) (*types.Transaction, error) { +// TransactBlobTx create, sign and send blob tx. +func (c *EthClient) TransactBlobTx( + opts *bind.TransactOpts, + contract *common.Address, + input, blobData []byte, +) (*types.Transaction, error) { // Sign the transaction and schedule it for execution if opts.Signer == nil { return nil, errors.New("no signer to authorize the transaction with") } // Create blob tx. - rawTx, err := c.createBlobTx(opts, data) + rawTx, err := c.createBlobTx(opts, contract, input, blobData) if err != nil { return nil, err } @@ -36,7 +42,12 @@ func (c *EthClient) TransactBlobTx(opts *bind.TransactOpts, data []byte) (*types return signedTx, nil } -func (c *EthClient) createBlobTx(opts *bind.TransactOpts, data []byte) (*types.Transaction, error) { +func (c *EthClient) createBlobTx( + opts *bind.TransactOpts, + contract *common.Address, + input, + blobData []byte, +) (*types.Transaction, error) { header, err := c.HeaderByNumber(opts.Context, nil) if err != nil { return nil, err @@ -67,43 +78,68 @@ func (c *EthClient) createBlobTx(opts *bind.TransactOpts, data []byte) (*types.T var err error gasLimit, err = c.EstimateGas(opts.Context, ethereum.CallMsg{ From: opts.From, - To: nil, + To: contract, GasPrice: nil, GasTipCap: gasTipCap, GasFeeCap: gasFeeCap, Value: nil, - Data: nil, + Data: input, }) if err != nil { return nil, err } } - // create the transaction - nonce, err := c.getNonce(opts) - if err != nil { - return nil, err + + // Get nonce. + var nonce uint64 + if opts.Nonce == nil { + nonce, err = c.getNonce(opts) + if err != nil { + return nil, err + } + } else { + nonce = opts.Nonce.Uint64() } + + // Get chainID. chainID, err := c.ChainID(opts.Context) if err != nil { return nil, err } - sidecar, err := makeSidecarWithSingleBlob(data) + // Make sidecar. + sidecar, err := MakeSidecarWithSingleBlob(blobData) if err != nil { return nil, err } + sidecar.BlobHashes() + // Calculate blob fee cap. var blobFeeCap uint64 = 100066 if header.ExcessBlobGas != nil { blobFeeCap = *header.ExcessBlobGas } - baseTx := &types.BlobTx{ + // Normalize value + var value = uint256.NewInt(0) + if opts.Value != nil { + value.SetFromBig(opts.Value) + } + + var addr common.Address + if contract != nil { + addr = *contract + } + + var baseTx = &types.BlobTx{ ChainID: uint256.NewInt(chainID.Uint64()), Nonce: nonce, - GasTipCap: uint256.NewInt(gasTipCap.Uint64()), - GasFeeCap: uint256.NewInt(gasFeeCap.Uint64()), + GasTipCap: uint256.MustFromBig(gasTipCap), + GasFeeCap: uint256.MustFromBig(gasFeeCap), Gas: gasLimit, + To: addr, + Value: value, + Data: input, BlobFeeCap: uint256.MustFromBig(eip4844.CalcBlobFee(blobFeeCap)), BlobHashes: sidecar.BlobHashes(), Sidecar: sidecar, @@ -118,7 +154,8 @@ func (c *EthClient) getNonce(opts *bind.TransactOpts) (uint64, error) { return opts.Nonce.Uint64(), nil } -func makeSidecarWithSingleBlob(data []byte) (*types.BlobTxSidecar, error) { +// MakeSidecarWithSingleBlob make a sidecar that just include one blob. +func MakeSidecarWithSingleBlob(data []byte) (*types.BlobTxSidecar, error) { if len(data) > BlobBytes { return nil, fmt.Errorf("data is bigger than 128k") } diff --git a/pkg/rpc/tx_blob_test.go b/pkg/rpc/tx_blob_test.go index 2240b5046..fcd749901 100644 --- a/pkg/rpc/tx_blob_test.go +++ b/pkg/rpc/tx_blob_test.go @@ -37,7 +37,7 @@ func TestBlockTx(t *testing.T) { assert.NoError(t, err) t.Logf("address: %s, balance: %s", opts.From.String(), balance.String()) - tx, err := l1Client.TransactBlobTx(opts, []byte("s")) + tx, err := l1Client.TransactBlobTx(opts, nil, nil, []byte("s")) assert.NoError(t, err) receipt, err := bind.WaitMined(ctx, l1Client, tx) diff --git a/proposer/proposer.go b/proposer/proposer.go index c08c5e869..9950b725d 100644 --- a/proposer/proposer.go +++ b/proposer/proposer.go @@ -307,23 +307,9 @@ func (p *Proposer) ProposeOp(ctx context.Context) error { return nil } -func (p *Proposer) sendTxListByBlobTx(ctx context.Context, txListBytes []byte) (*types.Transaction, error) { - blobOpts, err := getTxOpts(ctx, p.rpc.L1, p.L1ProposerPrivKey, p.rpc.L1ChainID, nil) - if err != nil { - return nil, err - } - tx, err := p.rpc.L1.TransactBlobTx(blobOpts, txListBytes) - if err != nil { - return nil, err - } - - return tx, nil -} - func (p *Proposer) sendProposeBlockTxWithBlobHash( ctx context.Context, - blobHash common.Hash, - txListSize *big.Int, + txListBytes []byte, nonce *uint64, assignment *encoding.ProverAssignment, assignedProver common.Address, @@ -383,12 +369,17 @@ func (p *Proposer) sendProposeBlockTxWithBlobHash( Data: hookInputData, }) + // Make sidecar in order to get blob hash. + sideCar, err := rpc.MakeSidecarWithSingleBlob(txListBytes) + if err != nil { + return nil, err + } encodedParams, err := encoding.EncodeBlockParams(&encoding.BlockParams{ AssignedProver: assignedProver, ExtraData: rpc.StringToBytes32(p.ExtraData), TxListByteOffset: common.Big0, - TxListByteSize: txListSize, - BlobHash: blobHash, + TxListByteSize: big.NewInt(int64(len(txListBytes))), + BlobHash: sideCar.BlobHashes()[0], CacheBlobForReuse: false, ParentMetaHash: parentMetaHash, HookCalls: hookCalls, @@ -397,16 +388,23 @@ func (p *Proposer) sendProposeBlockTxWithBlobHash( return nil, err } - proposeTx, err := p.rpc.TaikoL1.ProposeBlock( + opts.NoSend = true + rawTx, err := p.rpc.TaikoL1.ProposeBlock( opts, encodedParams, nil, ) - if err != nil { return nil, encoding.TryParsingCustomError(err) } + // Create blob tx and send it. + opts.NoSend = false + proposeTx, err := p.rpc.L1.TransactBlobTx(opts, &p.TaikoL1Address, rawTx.Data(), txListBytes) + if err != nil { + return nil, err + } + return proposeTx, nil } @@ -519,7 +517,6 @@ func (p *Proposer) ProposeTxList( var ( isReplacement bool tx *types.Transaction - blobTx *types.Transaction ) if err = backoff.Retry( func() error { @@ -529,16 +526,9 @@ func (p *Proposer) ProposeTxList( // Send tx list by blob tx. if p.BlobAllowed { - if blobTx == nil { - blobTx, err = p.sendTxListByBlobTx(ctx, txListBytes) - if err != nil { - return err - } - } tx, err = p.sendProposeBlockTxWithBlobHash( ctx, - blobTx.BlobHashes()[0], - big.NewInt(int64(len(txListBytes))), + txListBytes, nonce, assignment, proverAddress, @@ -587,11 +577,6 @@ func (p *Proposer) ProposeTxList( ctxWithTimeout, cancel := context.WithTimeout(ctx, p.WaitReceiptTimeout) defer cancel() - if blobTx != nil { - if _, err = bind.WaitMined(ctxWithTimeout, p.rpc.L1, blobTx); err != nil { - return err - } - } if tx != nil { if _, err = rpc.WaitReceipt(ctxWithTimeout, p.rpc.L1, tx); err != nil { return err diff --git a/proposer/proposer_test.go b/proposer/proposer_test.go index e3b3da671..9f6169392 100644 --- a/proposer/proposer_test.go +++ b/proposer/proposer_test.go @@ -198,12 +198,9 @@ func (s *ProposerTestSuite) TestSendProposeBlockTx() { newTx *types.Transaction ) if s.p.BlobAllowed { - blobTx, blobErr := s.p.sendTxListByBlobTx(ctx, encoded) - s.Nil(blobErr) newTx, err = s.p.sendProposeBlockTxWithBlobHash( ctx, - blobTx.BlobHashes()[0], - big.NewInt(int64(len(encoded))), + encoded, &nonce, signedAssignment, proverAddress,