Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ private BesuNode createCliqueNodeWithExtraCliOptionsAndRpcApis(
"LineaEstimateGasEndpointPlugin",
"LineaSetExtraDataEndpointPlugin",
"LineaTransactionPoolValidatorPlugin",
"LineaTransactionSelectorPlugin"));
"LineaTransactionSelectorPlugin",
"LineaSendBundleEndpointPlugin"));

return besu.create(nodeConfBuilder.build());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public void lineaEstimateGasPriorityFeeMinGasPriceLowerBound() {
final Account sender = accounts.getSecondaryBenefactor();

final CallParams callParams =
new CallParams(null, sender.getAddress(), null, "", "", "0", null, null, null);
new CallParams(null, sender.getAddress(), null, null, "", "", "0", null, null, null);

final var reqLinea = new LineaEstimateGasRequest(callParams);
final var respLinea = reqLinea.execute(minerNode.nodeRequests()).getResult();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public void estimateGasFailsForExceedingModuleLineCountTest() throws Exception {
new EstimateGasTest.CallParams(
null,
sender.getAddress(),
null,
simpleStorage.getContractAddress(),
null,
payload.toHexString(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ public void lineaEstimateGasMatchesEthEstimateGas() {
new CallParams(
null,
sender.getAddress(),
null,
sender.getAddress(),
null,
Bytes.EMPTY.toHexString(),
Expand All @@ -123,6 +124,7 @@ public void passingGasPriceFieldWorks() {
new CallParams(
null,
sender.getAddress(),
null,
sender.getAddress(),
null,
Bytes.EMPTY.toHexString(),
Expand All @@ -146,6 +148,7 @@ public void passingChainIdFieldWorks() {
new CallParams(
"0x539",
sender.getAddress(),
null,
sender.getAddress(),
null,
Bytes.EMPTY.toHexString(),
Expand All @@ -169,6 +172,7 @@ public void passingEIP1559FieldsWorks() {
new CallParams(
null,
sender.getAddress(),
null,
sender.getAddress(),
null,
Bytes.EMPTY.toHexString(),
Expand All @@ -192,6 +196,7 @@ public void passingChainIdAndEIP1559FieldsWorks() {
new CallParams(
"0x539",
sender.getAddress(),
null,
sender.getAddress(),
null,
Bytes.EMPTY.toHexString(),
Expand Down Expand Up @@ -219,6 +224,7 @@ public void passingStateOverridesWorks() {
new CallParams(
"0x539",
sender.getAddress(),
null,
sender.getAddress(),
"1",
Bytes.EMPTY.toHexString(),
Expand All @@ -239,6 +245,49 @@ public void passingStateOverridesWorks() {
"transaction up-front cost 0x208cbab601 exceeds transaction sender account balance 0x0");
}

@Test
public void passingNonceWorks() {

final Account sender = accounts.getSecondaryBenefactor();

final CallParams callParams =
new CallParams(
null,
sender.getAddress(),
"0",
sender.getAddress(),
null,
Bytes.EMPTY.toHexString(),
"0",
null,
"0x1234",
null);

final var reqLinea = new LineaEstimateGasRequest(callParams);
final var respLinea = reqLinea.execute(minerNode.nodeRequests());
assertThat(respLinea.hasError()).isFalse();
assertThat(respLinea.getResult()).isNotNull();

// try with a future nonce
final CallParams callParamsFuture =
new CallParams(
null,
sender.getAddress(),
"10",
sender.getAddress(),
null,
Bytes.EMPTY.toHexString(),
"0",
null,
"0x1234",
null);

final var reqLineaFuture = new LineaEstimateGasRequest(callParamsFuture);
final var respLineaFuture = reqLineaFuture.execute(minerNode.nodeRequests());
assertThat(respLineaFuture.hasError()).isFalse();
assertThat(respLineaFuture.getResult()).isNotNull();
}

@Test
public void lineaEstimateGasIsProfitable() {

Expand All @@ -259,6 +308,7 @@ public void lineaEstimateGasIsProfitable() {
new CallParams(
null,
sender.getAddress(),
null,
sender.getAddress(),
null,
payload.toHexString(),
Expand Down Expand Up @@ -320,6 +370,7 @@ public void invalidParametersLineaEstimateGasRequestReturnErrorResponse() {
null,
sender.getAddress(),
null,
null,
"",
"",
String.valueOf(Integer.MAX_VALUE),
Expand All @@ -341,6 +392,7 @@ public void revertedTransactionReturnErrorResponse() throws Exception {
new CallParams(
null,
sender.getAddress(),
null,
simpleStorage.getContractAddress(),
"",
"",
Expand All @@ -363,6 +415,7 @@ public void failedTransactionReturnErrorResponse() {
null,
sender.getAddress(),
null,
null,
"",
Accounts.GENESIS_ACCOUNT_TWO_PRIVATE_KEY,
"0",
Expand Down Expand Up @@ -492,6 +545,7 @@ static class RawEstimateGasResponse extends org.web3j.protocol.core.Response<Str
record CallParams(
String chainId,
String from,
String nonce,
String to,
String value,
String data,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package linea.plugin.acc.test.rpc.linea;

import static org.assertj.core.api.Assertions.assertThat;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import linea.plugin.acc.test.LineaPluginTestBase;
import linea.plugin.acc.test.TestCommandLineOptionsBuilder;
import lombok.RequiredArgsConstructor;
import org.hyperledger.besu.tests.acceptance.dsl.account.Account;
import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests;
import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction;
import org.hyperledger.besu.tests.acceptance.dsl.transaction.account.TransferTransaction;
import org.junit.jupiter.api.Test;
import org.web3j.protocol.core.Request;

public class SendBundleTest extends LineaPluginTestBase {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯


@Override
public List<String> getTestCliOptions() {
return new TestCommandLineOptionsBuilder().build();
}

@Test
public void singleTxBundleIsAcceptedAndMined() {
final Account sender = accounts.getSecondaryBenefactor();
final Account recipient = accounts.getPrimaryBenefactor();

final TransferTransaction tx = accountTransactions.createTransfer(sender, recipient, 1);

final String rawTx = tx.signedTransactionData();

final var sendBundleRequest =
new SendBundleRequest(new BundleParams(new String[] {rawTx}, Integer.toHexString(1)));
final var sendBundleResponse = sendBundleRequest.execute(minerNode.nodeRequests());

assertThat(sendBundleResponse.hasError()).isFalse();
assertThat(sendBundleResponse.getResult().bundleHash()).isNotBlank();

minerNode.verify(eth.expectSuccessfulTransactionReceipt(tx.transactionHash()));
}

@Test
public void bundleIsAcceptedAndMined() {
final Account sender = accounts.getSecondaryBenefactor();
final Account recipient = accounts.getPrimaryBenefactor();

final TransferTransaction tx1 = accountTransactions.createTransfer(sender, recipient, 1);
final TransferTransaction tx2 = accountTransactions.createTransfer(recipient, sender, 1);

final String[] rawTxs = new String[] {tx1.signedTransactionData(), tx2.signedTransactionData()};

final var sendBundleRequest =
new SendBundleRequest(new BundleParams(rawTxs, Integer.toHexString(1)));
final var sendBundleResponse = sendBundleRequest.execute(minerNode.nodeRequests());

assertThat(sendBundleResponse.hasError()).isFalse();
assertThat(sendBundleResponse.getResult().bundleHash()).isNotBlank();

minerNode.verify(eth.expectSuccessfulTransactionReceipt(tx1.transactionHash()));
minerNode.verify(eth.expectSuccessfulTransactionReceipt(tx2.transactionHash()));
}

@RequiredArgsConstructor
static class SendBundleRequest implements Transaction<SendBundleRequest.SendBundleResponse> {
private final BundleParams bundleParams;

@Override
public SendBundleResponse execute(final NodeRequests nodeRequests) {
try {
return new Request<>(
"linea_sendBundle",
Arrays.asList(bundleParams),
nodeRequests.getWeb3jService(),
SendBundleResponse.class)
.send();
} catch (IOException e) {
throw new RuntimeException(e);
}
}

static class SendBundleResponse extends org.web3j.protocol.core.Response<Response> {}

record Response(String bundleHash) {}
}

record BundleParams(String[] txs, String blockNumber) {}
}
14 changes: 0 additions & 14 deletions acceptance-tests/src/test/resources/logback.xml

This file was deleted.

2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
releaseVersion=1.2.0-rc3.2
besuVersion=25.1-delivery45
besuVersion=25.2-bundles
arithmetizationVersion=beta-v1.2.0-rc3
besuArtifactGroup=io.consensys.linea-besu
distributionIdentifier=linea-sequencer
Expand Down
5 changes: 3 additions & 2 deletions sequencer/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@ dependencies {
implementation "${besuArtifactGroup}.internal:algorithms"
implementation "${besuArtifactGroup}.internal:api"
implementation "${besuArtifactGroup}.internal:core"
implementation "${besuArtifactGroup}.internal:eth"
implementation "${besuArtifactGroup}.internal:rlp"

implementation 'com.google.code.gson:gson'
implementation 'com.github.ben-manes.caffeine:caffeine:3.1.8'
implementation 'com.github.ben-manes.caffeine:caffeine'

implementation 'com.google.code.gson:gson'

implementation 'io.tmio:tuweni-bytes'
implementation 'io.tmio:tuweni-units'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@
import net.consensys.linea.rpc.services.BundlePoolService;
import net.consensys.linea.rpc.services.LineaLimitedBundlePool;
import org.hyperledger.besu.plugin.ServiceManager;
import org.hyperledger.besu.plugin.services.BesuConfiguration;
import org.hyperledger.besu.plugin.services.BesuEvents;
import org.hyperledger.besu.plugin.services.BlockchainService;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import org.hyperledger.besu.plugin.services.RpcEndpointService;
import org.hyperledger.besu.plugin.services.metrics.MetricCategoryRegistry;

/**
Expand All @@ -59,11 +61,13 @@
@Slf4j
public abstract class AbstractLineaSharedPrivateOptionsPlugin
extends AbstractLineaSharedOptionsPlugin {
protected static BesuConfiguration besuConfiguration;
protected static BlockchainService blockchainService;
protected static MetricsSystem metricsSystem;
protected static BesuEvents besuEvents;
protected static BundlePoolService bundlePoolService;
protected static MetricCategoryRegistry metricCategoryRegistry;
protected static RpcEndpointService rpcEndpointService;

private static final AtomicBoolean sharedRegisterTasksDone = new AtomicBoolean(false);
private static final AtomicBoolean sharedStartTasksDone = new AtomicBoolean(false);
Expand Down Expand Up @@ -140,6 +144,13 @@ public synchronized void register(final ServiceManager serviceManager) {
}

protected static void performSharedRegisterTasksOnce(final ServiceManager serviceManager) {
besuConfiguration =
serviceManager
.getService(BesuConfiguration.class)
.orElseThrow(
() ->
new RuntimeException(
"Failed to obtain BesuConfiguration from the ServiceManager."));
blockchainService =
serviceManager
.getService(BlockchainService.class)
Expand All @@ -155,6 +166,14 @@ protected static void performSharedRegisterTasksOnce(final ServiceManager servic
() ->
new RuntimeException(
"Failed to obtain MetricCategoryRegistry from the ServiceManager."));

rpcEndpointService =
serviceManager
.getService(RpcEndpointService.class)
.orElseThrow(
() ->
new RuntimeException(
"Failed to obtain RpcEndpointService from the ServiceManager."));
}

@Override
Expand Down Expand Up @@ -196,7 +215,6 @@ private void performSharedStartTasksOnce(final ServiceManager serviceManager) {
bundlePoolService =
new LineaLimitedBundlePool(
transactionSelectorConfiguration().maxBundlePoolSizeBytes(), besuEvents);
serviceManager.addService(BundlePoolService.class, bundlePoolService);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,16 @@
import org.hyperledger.besu.plugin.data.AddedBlockContext;
import org.hyperledger.besu.plugin.services.BesuEvents;
import org.hyperledger.besu.plugin.services.BesuEvents.InitialSyncCompletionListener;
import org.hyperledger.besu.plugin.services.RpcEndpointService;

/** This plugin registers handlers that are activated when new blocks are imported */
@Slf4j
@AutoService(BesuPlugin.class)
public class LineaExtraDataPlugin extends AbstractLineaRequiredPlugin {
private ServiceManager serviceManager;
private RpcEndpointService rpcEndpointService;

@Override
public void doRegister(final ServiceManager context) {
serviceManager = context;
rpcEndpointService =
context
.getService(RpcEndpointService.class)
.orElseThrow(
() ->
new RuntimeException(
"Failed to obtain RpcEndpointService from the ServiceManager."));

metricCategoryRegistry.addMetricCategory(PRICING_CONF);
}
Expand Down
Loading