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

Add Transaction Permissioning Hook to PermissioningService Interface #7952

Draft
wants to merge 28 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
1724426
commit
vaidikcode Nov 27, 2024
858c8ee
addressing comments
vaidikcode Nov 28, 2024
dd498e7
updating api hash
vaidikcode Nov 28, 2024
aae1526
fixing the issue of implementing the permission service class in pr w…
vaidikcode Nov 28, 2024
2509d7d
add tests
vaidikcode Nov 28, 2024
6c7b463
change log
vaidikcode Nov 28, 2024
4a0c5dd
fix
vaidikcode Nov 28, 2024
2d51ec2
fix
vaidikcode Nov 28, 2024
7851707
Merge remote-tracking branch 'origin/#7835' into #7835
vaidikcode Nov 28, 2024
da2c3de
fix
vaidikcode Nov 28, 2024
dd44cca
fix
vaidikcode Nov 28, 2024
549db1f
fix
vaidikcode Dec 3, 2024
7f75593
Merge branch 'hyperledger:main' into #7835
vaidikcode Dec 3, 2024
d77f294
refactor
vaidikcode Dec 3, 2024
245e8ef
Merge remote-tracking branch 'origin/#7835' into #7835
vaidikcode Dec 3, 2024
b51669b
Merge branch 'main' into #7835
vaidikcode Dec 4, 2024
94620ed
fix
vaidikcode Dec 9, 2024
531ff5d
Merge remote-tracking branch 'origin/#7835' into #7835
vaidikcode Dec 9, 2024
ae8f3c8
Merge branch 'main' into #7835
vaidikcode Dec 9, 2024
5d815c2
spotless
vaidikcode Dec 10, 2024
9cfc510
Merge remote-tracking branch 'origin/#7835' into #7835
vaidikcode Dec 10, 2024
80c832c
compile error fix
vaidikcode Dec 11, 2024
b74a3e1
Merge branch 'main' into #7835
macfarla Dec 11, 2024
0b23b89
minor fix
vaidikcode Dec 11, 2024
de4ee35
Merge remote-tracking branch 'origin/#7835' into #7835
vaidikcode Dec 11, 2024
040857a
minor fix
vaidikcode Dec 11, 2024
a037c07
final
macfarla Dec 11, 2024
028c103
Merge branch '#7835' of github.com:vaidikcode/besu into #7835
macfarla Dec 11, 2024
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
- Fast Sync

### Additions and Improvements
- Add support for transaction permissioning rules in Plugin API [#7952](https://github.com/hyperledger/besu/pull/7952)
Copy link
Contributor

Choose a reason for hiding this comment

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

needs to move to "Unreleased" section

- Fine tune already seen txs tracker when a tx is removed from the pool [#7755](https://github.com/hyperledger/besu/pull/7755)
- Support for enabling and configuring TLS/mTLS in WebSocket service. [#7854](https://github.com/hyperledger/besu/pull/7854)
- Create and publish Besu BOM (Bill of Materials) [#7615](https://github.com/hyperledger/besu/pull/7615)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@ public void beforeExternalServices() {
}
return true;
});

service.registerTransactionPermissioningProvider(
transaction -> {
long configuredGasLimitThreshold = 12000L;
long gasLimit = transaction.getGasLimit();
LOG.info(
"Transaction gas limit: {} | Configured threshold: {} ",
gasLimit,
configuredGasLimitThreshold);
return gasLimit > configuredGasLimitThreshold;
});
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
*/
package org.hyperledger.besu.tests.acceptance.plugins;

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

import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.account.Account;
Expand All @@ -34,6 +36,8 @@ public class PermissioningPluginTest extends AcceptanceTestBase {
private BesuNode bobNode;
private BesuNode charlieNode;

private static final long GAS_LIMIT_THRESHOLD = 12000L;

@BeforeEach
public void setUp() throws Exception {
minerNode = besu.create(createNodeBuilder().name("miner").build());
Expand Down Expand Up @@ -96,4 +100,20 @@ public void transactionsAreNotSendToBlockPendingTransactionsNode() {
charlieNode.verify(txPoolConditions.notInTransactionPool(txHash));
minerNode.verify(txPoolConditions.inTransactionPool(txHash));
}

@Test
public void testGasLimitLogic() {
final long transactionGasLimit = 10000L;
boolean isTransactionPermitted = checkTransactionGasLimit(transactionGasLimit);

assertThat(isTransactionPermitted).isTrue();
}

private boolean checkTransactionGasLimit(final long gasLimit) {
if (gasLimit > GAS_LIMIT_THRESHOLD) {
return true;
} else {
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,28 @@
*/
package org.hyperledger.besu.services;

import org.hyperledger.besu.datatypes.Transaction;
import org.hyperledger.besu.plugin.services.PermissioningService;
import org.hyperledger.besu.plugin.services.permissioning.NodeConnectionPermissioningProvider;
import org.hyperledger.besu.plugin.services.permissioning.NodeMessagePermissioningProvider;
import org.hyperledger.besu.plugin.services.permissioning.TransactionPermissioningProvider;

import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;

import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** The Permissioning service implementation. */
public class PermissioningServiceImpl implements PermissioningService {
private static final Logger LOG = LoggerFactory.getLogger(PermissioningServiceImpl.class);

private final List<NodeConnectionPermissioningProvider> connectionPermissioningProviders =
Lists.newArrayList();
private final List<TransactionPermissioningProvider> transactionPermissioningProviders =
new ArrayList<>();

/** Default Constructor. */
@Inject
Expand All @@ -39,6 +47,13 @@ public void registerNodePermissioningProvider(
connectionPermissioningProviders.add(provider);
}

@Override
public void registerTransactionPermissioningProvider(
final TransactionPermissioningProvider provider) {
transactionPermissioningProviders.add(provider);
LOG.info("Registered new transaction permissioning provider.");
}

/**
* Gets connection permissioning providers.
*
Expand All @@ -65,4 +80,20 @@ public void registerNodeMessagePermissioningProvider(
public List<NodeMessagePermissioningProvider> getMessagePermissioningProviders() {
return messagePermissioningProviders;
}

/**
* Gets transaction rules.
*
* @return whether the transaction is permitted
*/
public boolean isTransactionPermitted(final Transaction transaction) {
for (TransactionPermissioningProvider provider : transactionPermissioningProviders) {
if (!provider.isPermitted(transaction)) {
LOG.debug("Transaction {} not permitted by one of the providers.", transaction.getHash());
return false;
}
}
LOG.debug("Transaction {} permitted.", transaction.getHash());
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@

import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.datatypes.Transaction;
import org.hyperledger.besu.ethereum.permissioning.AllowlistPersistor.ALLOWLIST_TYPE;
import org.hyperledger.besu.ethereum.permissioning.account.TransactionPermissioningProvider;
import org.hyperledger.besu.metrics.BesuMetricCategory;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import org.hyperledger.besu.plugin.services.metrics.Counter;
import org.hyperledger.besu.plugin.services.permissioning.TransactionPermissioningProvider;

import java.io.IOException;
import java.util.ArrayList;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,17 @@

import org.hyperledger.besu.crypto.Hash;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.permissioning.account.TransactionPermissioningProvider;
import org.hyperledger.besu.datatypes.Quantity;
import org.hyperledger.besu.datatypes.Transaction;
import org.hyperledger.besu.ethereum.transaction.CallParameter;
import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
import org.hyperledger.besu.ethereum.transaction.TransactionSimulatorResult;
import org.hyperledger.besu.metrics.BesuMetricCategory;
import org.hyperledger.besu.plugin.services.MetricsSystem;
import org.hyperledger.besu.plugin.services.metrics.Counter;
import org.hyperledger.besu.plugin.services.permissioning.TransactionPermissioningProvider;

import java.math.BigInteger;
import java.util.Optional;

import org.apache.tuweni.bytes.Bytes;
Expand Down Expand Up @@ -195,9 +197,13 @@ public static Bytes createPayload(final Bytes signature, final Transaction trans
private static Bytes encodeTransaction(final Transaction transaction) {
return Bytes.concatenate(
encodeAddress(transaction.getSender()),
encodeAddress(transaction.getTo()),
transaction.getValue(),
transaction.getGasPrice().map(BaseUInt256Value::toBytes).orElse(Bytes32.ZERO),
encodeAddress(transaction.getTo().map(Address.class::cast)),
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't love this line - surely there is a cleaner way todo this

convertQuantityToBytes(transaction.getValue()),
transaction
.getGasPrice()
.map(price -> (BaseUInt256Value<?>) price)
.map(BaseUInt256Value::toBytes)
.orElse(Bytes32.ZERO),
encodeLong(transaction.getGasLimit()),
encodeBytes(transaction.getPayload()));
}
Expand Down Expand Up @@ -231,4 +237,16 @@ private static Bytes encodeBytes(final Bytes value) {
final Bytes padding = Bytes.wrap(new byte[(32 - (value.size() % 32))]);
return Bytes.concatenate(dynamicParameterOffset, length, value, padding);
}

// Convert the Quantity value to Bytes
private static Bytes convertQuantityToBytes(final Quantity quantity) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
private static Bytes convertQuantityToBytes(final Quantity quantity) {
private static Bytes encodeQuantity(final Quantity quantity) {

if (quantity == null) {
return Bytes32.ZERO;
}
if (quantity instanceof BaseUInt256Value) {
return ((BaseUInt256Value) quantity).toBytes();
}
BigInteger value = quantity.getAsBigInteger();
return Bytes.wrap(value.toByteArray());
}
}
2 changes: 1 addition & 1 deletion plugin-api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ Calculated : ${currentHash}
tasks.register('checkAPIChanges', FileStateChecker) {
description = "Checks that the API for the Plugin-API project does not change without deliberate thought"
files = sourceSets.main.allJava.files
knownHash = 'TPCo4SZ61OrJxRAa2SIcAIOAOjVTdRw+UOeHMuiJP84='
knownHash = 'ILrmIl1hU61dFKgFPIvxIJYVLAbIOfX62SotTY2pWnA='
}
check.dependsOn('checkAPIChanges')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import org.hyperledger.besu.plugin.services.permissioning.NodeConnectionPermissioningProvider;
import org.hyperledger.besu.plugin.services.permissioning.NodeMessagePermissioningProvider;
import org.hyperledger.besu.plugin.services.permissioning.TransactionPermissioningProvider;

/**
* This service allows plugins to decide who you should connect to and what you should send them.
Expand All @@ -38,6 +39,13 @@ public interface PermissioningService extends BesuService {
*/
void registerNodePermissioningProvider(NodeConnectionPermissioningProvider provider);

/**
* Registers a callback for transaction permission.
*
* @param provider The provider to register
*/
void registerTransactionPermissioningProvider(final TransactionPermissioningProvider provider);

/**
* Registers a callback to allow the interception of a devp2p message sending request
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright ConsenSys AG.
* Copyright contributors to Besu.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
Expand All @@ -12,9 +12,9 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.permissioning.account;
package org.hyperledger.besu.plugin.services.permissioning;

import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.datatypes.Transaction;

@FunctionalInterface
public interface TransactionPermissioningProvider {
Expand Down