Skip to content

Commit

Permalink
Merge branch 'master' into fmacleal/addition_transient_storage_opcodes
Browse files Browse the repository at this point in the history
  • Loading branch information
fmacleal committed Oct 14, 2024
2 parents fa2eb47 + d64a6bc commit 8892bf3
Show file tree
Hide file tree
Showing 180 changed files with 9,626 additions and 1,095 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ jobs:
GH_REF: ${{ github.ref }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: |
if [ "$GH_EVENT" = pull_request ]; then
if [ "$GH_EVENT" = pull_request ] && [ "${{ github.event.pull_request.head.repo.fork }}" != "true" ]; then
./gradlew -Dorg.gradle.jvmargs=-Xmx5g sonarqube --no-daemon -x build -x test \
-Dsonar.pullrequest.base="$GH_PR_BASE_REF" \
-Dsonar.pullrequest.branch="$GH_PR_HEAD_REF" \
Expand Down
10 changes: 9 additions & 1 deletion .github/workflows/rit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ jobs:
github_event_pull_request_number: ${{ github.event.pull_request.number }}
github_head_ref: ${{ github.head_ref }}
github_ref_name: ${{ github.ref_name }}
github_event_pull_request_head_repo_owner_login: ${{ github.event.pull_request.head.repo.owner.login }}
github_repository_owner: ${{ github.repository_owner }}
run: |
PR_DESCRIPTION=pr-description.txt
Expand Down Expand Up @@ -96,6 +98,11 @@ jobs:
exit 1
fi
# Set the Repo Owner
REPO_OWNER="${github_event_pull_request_head_repo_owner_login:-$github_repository_owner}"
echo "REPO_OWNER=$REPO_OWNER" >> $GITHUB_ENV
echo "RSKJ_BRANCH=$RSKJ_BRANCH" >> $GITHUB_ENV
echo "RIT_BRANCH=$RIT_BRANCH" >> $GITHUB_ENV
echo "POWPEG_BRANCH=$POWPEG_BRANCH" >> $GITHUB_ENV
Expand All @@ -116,11 +123,12 @@ jobs:
echo "SAFE_BRANCH_NAME=$SAFE_BRANCH_NAME" >> $GITHUB_ENV
- name: Run Rootstock Integration Tests
uses: rsksmart/rootstock-integration-tests@497172fd38dcfaf48c77f9bb1eeb6617eef5eed6 #v1
uses: rsksmart/rootstock-integration-tests@e86332474179a63f027d0fe969687d3d24f34c29 #v1
with:
rskj-branch: ${{ env.RSKJ_BRANCH }}
powpeg-node-branch: ${{ env.POWPEG_BRANCH }}
rit-branch: ${{ env.RIT_BRANCH }}
repo-owner: ${{ env.REPO_OWNER }}

- name: Send Slack Notification on Success
if: success() && github.event.pull_request.head.repo.owner.login == 'rsksmart'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,31 @@ public class OkHttpClientTestFixture {
" \"jsonrpc\": \"2.0\"\n" +
"}]";

public static final String ETH_GET_BLOCK_BY_NUMBER =
"{\n" +
" \"method\": \"eth_getBlockByNumber\",\n" +
" \"params\": [\n" +
" \"<BLOCK_NUM_OR_TAG>\",\n" +
" true\n" +
" ],\n" +
" \"id\": 1,\n" +
" \"jsonrpc\": \"2.0\"\n" +
"}";

public static final String ETH_SEND_TRANSACTION =
"{\n" +
" \"jsonrpc\": \"2.0\",\n" +
" \"method\": \"eth_sendTransaction\",\n" +
" \"id\": 1,\n" +
" \"params\": [{\n" +
" \"from\": \"<ADDRESS_FROM>\",\n" +
" \"to\": \"<ADDRESS_TO>\",\n" +
" \"gas\": \"<GAS>\",\n" +
" \"gasPrice\": \"<GAS_PRICE>\",\n" +
" \"value\": \"<VALUE>\"\n" +
" }]\n" +
"}";

private OkHttpClientTestFixture() {
}

Expand Down Expand Up @@ -101,4 +126,9 @@ public static JsonNode getJsonResponseForGetBestBlockMessage(int port) throws IO
Response response = sendJsonRpcGetBestBlockMessage(port);
return new ObjectMapper().readTree(response.body().string());
}

public static String getEnvelopedMethodCalls(String... methodCall) {
return "[\n" + String.join(",\n", methodCall) + "]";
}

}
244 changes: 244 additions & 0 deletions rskj-core/src/integrationTest/java/pte/PteIntegrationTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
/*
* This file is part of RskJ
* Copyright (C) 2024 RSK Labs Ltd.
* (derived from ethereumJ library, Copyright (c) 2016 <ether.camp>)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package pte;

import co.rsk.util.OkHttpClientTestFixture;
import co.rsk.util.cli.CommandLineFixture;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.squareup.okhttp.Response;
import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Stream;

import static co.rsk.util.OkHttpClientTestFixture.*;

public class PteIntegrationTest {

/*
When running this test locally, don't forget to build the .jar for the code you're trying to
test ('./gradlew clean' and './gradlew assemble' should be sufficient for most cases).
*/

private static final int RPC_PORT = 9999;
private static final int MAX_BLOCKS_TO_GET = 20;

private final ObjectMapper objectMapper = new ObjectMapper();

private String buildLibsPath;
private String jarName;
private String strBaseArgs;
private String baseJavaCmd;

@TempDir
private Path tempDir;

@BeforeEach
public void setup() throws IOException {
String projectPath = System.getProperty("user.dir");
buildLibsPath = String.format("%s/build/libs", projectPath);
String integrationTestResourcesPath = String.format("%s/src/integrationTest/resources", projectPath);
String logbackXmlFile = String.format("%s/logback.xml", integrationTestResourcesPath);
String rskConfFile = String.format("%s/pte-integration-test-rskj.conf", integrationTestResourcesPath);
Stream<Path> pathsStream = Files.list(Paths.get(buildLibsPath));
jarName = pathsStream.filter(p -> !p.toFile().isDirectory())
.map(p -> p.getFileName().toString())
.filter(fn -> fn.endsWith("-all.jar"))
.findFirst()
.orElse("");

Path databaseDirPath = tempDir.resolve("database");
String databaseDir = databaseDirPath.toString();
String[] baseArgs = new String[]{
String.format("-Xdatabase.dir=%s", databaseDir),
"--regtest",
String.format("-Xrpc.providers.web.http.port=%s", RPC_PORT)
};
strBaseArgs = String.join(" ", baseArgs);
baseJavaCmd = String.format("java %s %s", String.format("-Dlogback.configurationFile=%s", logbackXmlFile), String.format("-Drsk.conf.file=%s", rskConfFile));
}

@Test
void whenParallelizableTransactionsAreSent_someAreExecutedInParallel() throws Exception {

// Given

// Pre-funded Test Accounts on Regtest
List<String> accounts = Arrays.asList(
"0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826",
"0x7986b3df570230288501eea3d890bd66948c9b79",
"0x0a3aa774752ec2042c46548456c094a76c7f3a79",
"0xcf7cdbbb5f7ba79d3ffe74a0bba13fc0295f6036",
"0x39b12c05e8503356e3a7df0b7b33efa4c054c409",
"0xc354d97642faa06781b76ffb6786f72cd7746c97",
"0xdebe71e1de41fc77c44df4b6db940026e31b0e71",
"0x7857288e171c6159c5576d1bd9ac40c0c48a771c",
"0xa4dea4d5c954f5fd9e87f0e9752911e83a3d18b3",
"0x09a1eda29f664ac8f68106f6567276df0c65d859",
"0xec4ddeb4380ad69b3e509baad9f158cdf4e4681d"
);

Map<String, Response> txResponseMap = new HashMap<>();
Map<String, Map<Integer, String>> blocksResponseMap = new HashMap<>();

String cmd = String.format(
"%s -cp %s/%s co.rsk.Start --reset %s",
baseJavaCmd,
buildLibsPath,
jarName,
strBaseArgs);

// When

CommandLineFixture.runCommand(
cmd,
1,
TimeUnit.MINUTES,
proc -> {
try {

// Send bulk transactions

Response txResponse = sendBulkTransactions(
accounts.get(0), accounts.get(1), accounts.get(2), accounts.get(3),
accounts.get(4), accounts.get(5), accounts.get(6), accounts.get(7));

txResponseMap.put("bulkTransactionsResponse", txResponse);

// Await for n blocks to be mined and return them

Future<Map<Integer, String>> future = getBlocksAsync();

try {

blocksResponseMap.put("asyncBlocksResult", future.get());

} catch (ExecutionException | InterruptedException e) {
Assertions.fail(e);
}

} catch (IOException e) {
Assertions.fail(e);
}
}
);

// Then

Assertions.assertEquals(200, txResponseMap.get("bulkTransactionsResponse").code());

Map<Integer, String> blocksResult = blocksResponseMap.get("asyncBlocksResult");
Assertions.assertEquals(MAX_BLOCKS_TO_GET, blocksResult.size());

boolean pteFound = false;
int i = blocksResult.size(); // Start from the last element (optimization)
while (!pteFound && i >= 0) {
i -= 1;

JsonNode blockResponse = objectMapper.readTree(blocksResult.get(i));
JsonNode result = blockResponse.get(0).get("result");

if (!result.isNull()) {
JsonNode pteEdges = result.get("rskPteEdges");
if (pteEdges.isArray() && pteEdges.size() > 0) {
Assertions.assertTrue(result.get("transactions").isArray());
Assertions.assertTrue(result.get("transactions").size() > 1);
pteFound = true;
}
}
}

Assertions.assertTrue(pteFound);

}

private Response getBlockByNumber(String number) throws IOException {
String content = getEnvelopedMethodCalls(
ETH_GET_BLOCK_BY_NUMBER.replace(
"<BLOCK_NUM_OR_TAG>",
number)
);

System.out.println(content);

return OkHttpClientTestFixture.sendJsonRpcMessage(content, RPC_PORT);
}

private Response sendBulkTransactions(
String addressFrom1, String addressTo1,
String addressFrom2, String addressTo2,
String addressFrom3, String addressTo3,
String addressFrom4, String addressTo4) throws IOException {

String gas = "0x9C40";
String gasPrice = "0x10";
String value = "0x500";

String[] placeholders = new String[]{
"<ADDRESS_FROM>", "<ADDRESS_TO>", "<GAS>",
"<GAS_PRICE>", "<VALUE>"
};

String content = getEnvelopedMethodCalls(
StringUtils.replaceEach(ETH_SEND_TRANSACTION, placeholders,
new String[]{addressFrom1, addressTo1, gas, gasPrice, value}),
StringUtils.replaceEach(ETH_SEND_TRANSACTION, placeholders,
new String[]{addressFrom2, addressTo2, gas, gasPrice, value}),
StringUtils.replaceEach(ETH_SEND_TRANSACTION, placeholders,
new String[]{addressFrom3, addressTo3, gas, gasPrice, value}),
StringUtils.replaceEach(ETH_SEND_TRANSACTION, placeholders,
new String[]{addressFrom4, addressTo4, gas, gasPrice, value})
);

System.out.println(content);

return OkHttpClientTestFixture.sendJsonRpcMessage(content, RPC_PORT);
}

private Future<Map<Integer, String>> getBlocksAsync() {
CompletableFuture<Map<Integer, String>> completableFuture = new CompletableFuture<>();

Executors.newCachedThreadPool().submit(() -> {
Map<Integer, String> results = new HashMap<>();

for (int i = 0; i < MAX_BLOCKS_TO_GET; i++) {
String response = getBlockByNumber("0x" + String.format("%02x", i)).body().string();

results.put(i, response);
Thread.sleep(500);
}

completableFuture.complete(results);
return null;
});

return completableFuture;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
miner {

server {
enabled = true
updateWorkOnNewTransaction = true
}

client {
enabled = true
automine = false
delayBetweenBlocks = 5 seconds
delayBetweenRefreshes = 1 second
}

}

peer {

discovery = {

# if peer discovery is off
# the peer window will show
# only what retrieved by active
# peer [true/false]
enabled = false

# List of the peers to start
# the search of the online peers
# values: [ip:port]
ip.list = []

}

}
9 changes: 5 additions & 4 deletions rskj-core/src/main/java/co/rsk/RskContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -481,9 +481,9 @@ public synchronized BlockExecutor getBlockExecutor() {

if (blockExecutor == null) {
blockExecutor = new BlockExecutor(
getRskSystemProperties().getActivationConfig(),
getRepositoryLocator(),
getTransactionExecutorFactory()
getTransactionExecutorFactory(),
getRskSystemProperties()
);
}

Expand Down Expand Up @@ -1093,7 +1093,7 @@ public synchronized BlockValidationRule getBlockValidationRule() {
rskSystemProperties.getActivationConfig(),
rskSystemProperties.getNetworkConstants()
);
blockValidationRule = new BlockValidatorRule(
blockValidationRule = new BlockCompositeRule(
new TxsMinGasPriceRule(),
new BlockTxsMaxGasPriceRule(rskSystemProperties.getActivationConfig()),
new BlockUnclesValidationRule(
Expand All @@ -1120,7 +1120,8 @@ public synchronized BlockValidationRule getBlockValidationRule() {
blockTimeStampValidationRule,
new GasLimitRule(commonConstants.getMinGasLimit()),
new ExtraDataRule(commonConstants.getMaximumExtraDataSize()),
getForkDetectionDataRule()
getForkDetectionDataRule(),
new ValidTxExecutionSublistsEdgesRule(getRskSystemProperties().getActivationConfig())
);
}

Expand Down
Loading

0 comments on commit 8892bf3

Please sign in to comment.