mirror of
https://github.com/vacp2p/linea-besu.git
synced 2026-01-09 15:37:54 -05:00
remove tests and associated classes for smart contract permissioning (#8372)
Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com>
This commit is contained in:
@@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.dsl.condition.perm;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.account.Account;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.perm.AccountSmartContractPermissioningTransactions;
|
|
||||||
|
|
||||||
public class AccountSmartContractPermissioningConditions {
|
|
||||||
|
|
||||||
private final AccountSmartContractPermissioningTransactions transactions;
|
|
||||||
|
|
||||||
public AccountSmartContractPermissioningConditions(
|
|
||||||
final AccountSmartContractPermissioningTransactions transactions) {
|
|
||||||
this.transactions = transactions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Condition accountIsAllowed(final String address, final Account account) {
|
|
||||||
return new WaitForTrueResponse(transactions.isAccountAllowed(address, account));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Condition accountIsForbidden(final String address, final Account account) {
|
|
||||||
return new WaitForFalseResponse(transactions.isAccountAllowed(address, account));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.dsl.condition.perm;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.perm.NodeSmartContractPermissioningTransactions;
|
|
||||||
|
|
||||||
public class NodeSmartContractPermissioningConditions {
|
|
||||||
|
|
||||||
private final NodeSmartContractPermissioningTransactions transactions;
|
|
||||||
|
|
||||||
public NodeSmartContractPermissioningConditions(
|
|
||||||
final NodeSmartContractPermissioningTransactions transactions) {
|
|
||||||
this.transactions = transactions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Condition nodeIsAllowed(final String address, final Node node) {
|
|
||||||
return new WaitForTrueResponse(transactions.isNodeAllowed(address, node));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Condition nodeIsForbidden(final String address, final Node node) {
|
|
||||||
return new WaitForFalseResponse(transactions.isNodeAllowed(address, node));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Condition connectionIsAllowed(final String address, final Node source, final Node target) {
|
|
||||||
return new WaitForTrueResponse(transactions.isConnectionAllowed(address, source, target));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Condition connectionIsForbidden(
|
|
||||||
final String address, final Node source, final Node target) {
|
|
||||||
return new WaitForFalseResponse(transactions.isConnectionAllowed(address, source, target));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.dsl.condition.perm;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.plugin.data.EnodeURL;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.perm.NodeSmartContractPermissioningV2Transactions;
|
|
||||||
|
|
||||||
public class NodeSmartContractPermissioningV2Conditions {
|
|
||||||
|
|
||||||
private final NodeSmartContractPermissioningV2Transactions transactions;
|
|
||||||
|
|
||||||
public NodeSmartContractPermissioningV2Conditions(
|
|
||||||
final NodeSmartContractPermissioningV2Transactions transactions) {
|
|
||||||
this.transactions = transactions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Condition connectionIsAllowed(final String address, final Node node) {
|
|
||||||
return new WaitForTrueResponse(transactions.isConnectionAllowed(address, node));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Condition connectionIsAllowed(final String address, final EnodeURL enodeURL) {
|
|
||||||
return new WaitForTrueResponse(transactions.isConnectionAllowed(address, enodeURL));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Condition connectionIsForbidden(final String address, final Node node) {
|
|
||||||
return new WaitForFalseResponse(transactions.isConnectionAllowed(address, node));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Condition connectionIsForbidden(final String address, final EnodeURL enodeURL) {
|
|
||||||
return new WaitForFalseResponse(transactions.isConnectionAllowed(address, enodeURL));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.dsl.transaction.perm;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
import static org.web3j.utils.Numeric.toHexString;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.datatypes.Address;
|
|
||||||
import org.hyperledger.besu.datatypes.Hash;
|
|
||||||
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 java.io.IOException;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
import org.apache.tuweni.bytes.Bytes;
|
|
||||||
import org.web3j.crypto.RawTransaction;
|
|
||||||
import org.web3j.crypto.TransactionEncoder;
|
|
||||||
|
|
||||||
public class AccountSmartContractPermissioningAllowAccountTransaction implements Transaction<Hash> {
|
|
||||||
|
|
||||||
private static final Bytes ADD_ACCOUNT_SIGNATURE =
|
|
||||||
org.hyperledger.besu.crypto.Hash.keccak256(Bytes.of("addAccount(address)".getBytes(UTF_8)))
|
|
||||||
.slice(0, 4);
|
|
||||||
|
|
||||||
private final Account sender;
|
|
||||||
private final Address contractAddress;
|
|
||||||
private final Address account;
|
|
||||||
|
|
||||||
public AccountSmartContractPermissioningAllowAccountTransaction(
|
|
||||||
final Account sender, final Address contractAddress, final Address account) {
|
|
||||||
this.sender = sender;
|
|
||||||
this.contractAddress = contractAddress;
|
|
||||||
this.account = account;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Hash execute(final NodeRequests node) {
|
|
||||||
final String signedTransactionData = signedTransactionData();
|
|
||||||
try {
|
|
||||||
String hash =
|
|
||||||
node.eth().ethSendRawTransaction(signedTransactionData).send().getTransactionHash();
|
|
||||||
return Hash.fromHexString(hash);
|
|
||||||
} catch (final IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String signedTransactionData() {
|
|
||||||
final Bytes payload =
|
|
||||||
Bytes.concatenate(
|
|
||||||
ADD_ACCOUNT_SIGNATURE, Bytes.fromHexString("0x000000000000000000000000"), account);
|
|
||||||
|
|
||||||
final RawTransaction transaction =
|
|
||||||
RawTransaction.createTransaction(
|
|
||||||
sender.getNextNonce(),
|
|
||||||
BigInteger.valueOf(1000),
|
|
||||||
BigInteger.valueOf(100_000),
|
|
||||||
contractAddress.toString(),
|
|
||||||
payload.toString());
|
|
||||||
|
|
||||||
return toHexString(
|
|
||||||
TransactionEncoder.signMessage(transaction, sender.web3jCredentialsOrThrow()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.dsl.transaction.perm;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
import static org.web3j.utils.Numeric.toHexString;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.datatypes.Address;
|
|
||||||
import org.hyperledger.besu.datatypes.Hash;
|
|
||||||
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 java.io.IOException;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
import org.apache.tuweni.bytes.Bytes;
|
|
||||||
import org.web3j.crypto.RawTransaction;
|
|
||||||
import org.web3j.crypto.TransactionEncoder;
|
|
||||||
|
|
||||||
public class AccountSmartContractPermissioningForbidAccountTransaction
|
|
||||||
implements Transaction<Hash> {
|
|
||||||
|
|
||||||
private static final Bytes REMOVE_ACCOUNT_SIGNATURE =
|
|
||||||
org.hyperledger.besu.crypto.Hash.keccak256(Bytes.of("removeAccount(address)".getBytes(UTF_8)))
|
|
||||||
.slice(0, 4);
|
|
||||||
|
|
||||||
private final Account sender;
|
|
||||||
private final Address contractAddress;
|
|
||||||
private final Address account;
|
|
||||||
|
|
||||||
public AccountSmartContractPermissioningForbidAccountTransaction(
|
|
||||||
final Account sender, final Address contractAddress, final Address account) {
|
|
||||||
this.sender = sender;
|
|
||||||
this.contractAddress = contractAddress;
|
|
||||||
this.account = account;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Hash execute(final NodeRequests node) {
|
|
||||||
final String signedTransactionData = signedTransactionData();
|
|
||||||
try {
|
|
||||||
String hash =
|
|
||||||
node.eth().ethSendRawTransaction(signedTransactionData).send().getTransactionHash();
|
|
||||||
return Hash.fromHexString(hash);
|
|
||||||
} catch (final IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String signedTransactionData() {
|
|
||||||
final Bytes payload =
|
|
||||||
Bytes.concatenate(
|
|
||||||
REMOVE_ACCOUNT_SIGNATURE, Bytes.fromHexString("0x000000000000000000000000"), account);
|
|
||||||
|
|
||||||
RawTransaction transaction =
|
|
||||||
RawTransaction.createTransaction(
|
|
||||||
sender.getNextNonce(),
|
|
||||||
BigInteger.valueOf(1000),
|
|
||||||
BigInteger.valueOf(100_000),
|
|
||||||
contractAddress.toString(),
|
|
||||||
payload.toString());
|
|
||||||
|
|
||||||
return toHexString(
|
|
||||||
TransactionEncoder.signMessage(transaction, sender.web3jCredentialsOrThrow()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.dsl.transaction.perm;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.crypto.Hash;
|
|
||||||
import org.hyperledger.besu.datatypes.Address;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.apache.tuweni.bytes.Bytes;
|
|
||||||
import org.web3j.protocol.core.DefaultBlockParameterName;
|
|
||||||
|
|
||||||
public class AccountSmartContractPermissioningIsAllowedTransaction implements Transaction<Boolean> {
|
|
||||||
|
|
||||||
private static final Bytes IS_ACCOUNT_ALLOWED_SIGNATURE =
|
|
||||||
Hash.keccak256(Bytes.of("whitelistContains(address)".getBytes(UTF_8))).slice(0, 4);
|
|
||||||
|
|
||||||
private final Address contractAddress;
|
|
||||||
private final Address account;
|
|
||||||
|
|
||||||
public AccountSmartContractPermissioningIsAllowedTransaction(
|
|
||||||
final Address contractAddress, final Address account) {
|
|
||||||
this.contractAddress = contractAddress;
|
|
||||||
this.account = account;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean execute(final NodeRequests node) {
|
|
||||||
try {
|
|
||||||
final String value =
|
|
||||||
node.eth().ethCall(payload(), DefaultBlockParameterName.LATEST).send().getValue();
|
|
||||||
return checkTransactionResult(Bytes.fromHexString(value));
|
|
||||||
} catch (final IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks the returned bytes from the permissioning contract call to see if it's a value we
|
|
||||||
// understand
|
|
||||||
static Boolean checkTransactionResult(final Bytes result) {
|
|
||||||
// booleans are padded to 32 bytes
|
|
||||||
if (result.size() != 32) {
|
|
||||||
throw new IllegalArgumentException("Unexpected result size");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0 is false
|
|
||||||
if (result.equals(
|
|
||||||
Bytes.fromHexString(
|
|
||||||
"0x0000000000000000000000000000000000000000000000000000000000000000"))) {
|
|
||||||
return false;
|
|
||||||
// 1 filled to 32 bytes is true
|
|
||||||
} else if (result.equals(
|
|
||||||
Bytes.fromHexString(
|
|
||||||
"0x0000000000000000000000000000000000000000000000000000000000000001"))) {
|
|
||||||
return true;
|
|
||||||
// Anything else is wrong
|
|
||||||
} else {
|
|
||||||
throw new IllegalStateException("Unexpected result form");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private org.web3j.protocol.core.methods.request.Transaction payload() {
|
|
||||||
final Bytes payload =
|
|
||||||
Bytes.concatenate(
|
|
||||||
IS_ACCOUNT_ALLOWED_SIGNATURE,
|
|
||||||
Bytes.fromHexString("0x000000000000000000000000"),
|
|
||||||
account);
|
|
||||||
|
|
||||||
return org.web3j.protocol.core.methods.request.Transaction.createFunctionCallTransaction(
|
|
||||||
null, null, null, null, contractAddress.toString(), payload.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.dsl.transaction.perm;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.datatypes.Address;
|
|
||||||
import org.hyperledger.besu.datatypes.Hash;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.account.Account;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.account.Accounts;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction;
|
|
||||||
|
|
||||||
public class AccountSmartContractPermissioningTransactions {
|
|
||||||
|
|
||||||
private final Accounts accounts;
|
|
||||||
|
|
||||||
public AccountSmartContractPermissioningTransactions(final Accounts accounts) {
|
|
||||||
this.accounts = accounts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Transaction<Hash> allowAccount(final String contractAddress, final Account account) {
|
|
||||||
return new AccountSmartContractPermissioningAllowAccountTransaction(
|
|
||||||
accounts.getPrimaryBenefactor(),
|
|
||||||
Address.fromHexString(contractAddress),
|
|
||||||
Address.fromHexString(account.getAddress()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Transaction<Hash> forbidAccount(final String contractAddress, final Account account) {
|
|
||||||
return new AccountSmartContractPermissioningForbidAccountTransaction(
|
|
||||||
accounts.getPrimaryBenefactor(),
|
|
||||||
Address.fromHexString(contractAddress),
|
|
||||||
Address.fromHexString(account.getAddress()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Transaction<Boolean> isAccountAllowed(
|
|
||||||
final String contractAddress, final Account account) {
|
|
||||||
return new AccountSmartContractPermissioningIsAllowedTransaction(
|
|
||||||
Address.fromHexString(contractAddress), Address.fromHexString(account.getAddress()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.dsl.transaction.perm;
|
|
||||||
|
|
||||||
import static org.web3j.utils.Numeric.toHexString;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.datatypes.Address;
|
|
||||||
import org.hyperledger.besu.datatypes.Hash;
|
|
||||||
import org.hyperledger.besu.plugin.data.EnodeURL;
|
|
||||||
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 java.io.IOException;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.tuweni.bytes.Bytes;
|
|
||||||
import org.web3j.abi.FunctionEncoder;
|
|
||||||
import org.web3j.abi.datatypes.Function;
|
|
||||||
import org.web3j.crypto.RawTransaction;
|
|
||||||
import org.web3j.crypto.TransactionEncoder;
|
|
||||||
|
|
||||||
public class NodeSmartContractPermissioningAllowNodeByURLV2Transaction
|
|
||||||
implements Transaction<Hash> {
|
|
||||||
|
|
||||||
private final Account sender;
|
|
||||||
private final Address contractAddress;
|
|
||||||
private final EnodeURL enodeUrl;
|
|
||||||
|
|
||||||
public NodeSmartContractPermissioningAllowNodeByURLV2Transaction(
|
|
||||||
final Account sender, final Address contractAddress, final EnodeURL enodeUrl) {
|
|
||||||
this.sender = sender;
|
|
||||||
this.contractAddress = contractAddress;
|
|
||||||
this.enodeUrl = enodeUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Hash execute(final NodeRequests node) {
|
|
||||||
final String signedTransactionData = signedTransactionData();
|
|
||||||
try {
|
|
||||||
String hash =
|
|
||||||
node.eth().ethSendRawTransaction(signedTransactionData).send().getTransactionHash();
|
|
||||||
return Hash.fromHexString(hash);
|
|
||||||
} catch (final IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String signedTransactionData() {
|
|
||||||
final Bytes payload = createPayload(enodeUrl);
|
|
||||||
|
|
||||||
RawTransaction transaction =
|
|
||||||
RawTransaction.createTransaction(
|
|
||||||
sender.getNextNonce(),
|
|
||||||
BigInteger.valueOf(1_000L),
|
|
||||||
BigInteger.valueOf(3_000_000L),
|
|
||||||
contractAddress.toString(),
|
|
||||||
payload.toString());
|
|
||||||
|
|
||||||
return toHexString(
|
|
||||||
TransactionEncoder.signMessage(transaction, sender.web3jCredentialsOrThrow()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Bytes createPayload(final EnodeURL enodeUrl) {
|
|
||||||
try {
|
|
||||||
final String hexNodeIdString = enodeUrl.getNodeId().toUnprefixedHexString();
|
|
||||||
final String address = enodeUrl.toURI().getHost();
|
|
||||||
final int port = enodeUrl.getListeningPortOrZero();
|
|
||||||
|
|
||||||
final Function addNodeFunction =
|
|
||||||
FunctionEncoder.makeFunction(
|
|
||||||
"addEnode",
|
|
||||||
List.of("string", "string", "uint16"),
|
|
||||||
List.of(hexNodeIdString, address, port),
|
|
||||||
Collections.emptyList());
|
|
||||||
return Bytes.fromHexString(FunctionEncoder.encode(addNodeFunction));
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error adding node to allowlist", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.dsl.transaction.perm;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
import static org.web3j.utils.Numeric.toHexString;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.datatypes.Address;
|
|
||||||
import org.hyperledger.besu.datatypes.Hash;
|
|
||||||
import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl;
|
|
||||||
import org.hyperledger.besu.ethereum.permissioning.NodeSmartContractPermissioningController;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.account.Account;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
import org.apache.tuweni.bytes.Bytes;
|
|
||||||
import org.web3j.crypto.RawTransaction;
|
|
||||||
import org.web3j.crypto.TransactionEncoder;
|
|
||||||
|
|
||||||
public class NodeSmartContractPermissioningAllowNodeTransaction implements Transaction<Hash> {
|
|
||||||
|
|
||||||
private static final Bytes ADD_ENODE_SIGNATURE =
|
|
||||||
org.hyperledger.besu.crypto.Hash.keccak256(
|
|
||||||
Bytes.of("addEnode(bytes32,bytes32,bytes16,uint16)".getBytes(UTF_8)))
|
|
||||||
.slice(0, 4);
|
|
||||||
|
|
||||||
private final Account sender;
|
|
||||||
private final Address contractAddress;
|
|
||||||
private final Node node;
|
|
||||||
|
|
||||||
public NodeSmartContractPermissioningAllowNodeTransaction(
|
|
||||||
final Account sender, final Address contractAddress, final Node node) {
|
|
||||||
this.sender = sender;
|
|
||||||
this.contractAddress = contractAddress;
|
|
||||||
this.node = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Hash execute(final NodeRequests node) {
|
|
||||||
final String signedTransactionData = signedTransactionData();
|
|
||||||
try {
|
|
||||||
String hash =
|
|
||||||
node.eth().ethSendRawTransaction(signedTransactionData).send().getTransactionHash();
|
|
||||||
return Hash.fromHexString(hash);
|
|
||||||
} catch (final IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String signedTransactionData() {
|
|
||||||
final String enodeURL = ((RunnableNode) node).enodeUrl().toASCIIString();
|
|
||||||
final Bytes payload =
|
|
||||||
NodeSmartContractPermissioningController.createPayload(
|
|
||||||
ADD_ENODE_SIGNATURE, EnodeURLImpl.fromString(enodeURL));
|
|
||||||
|
|
||||||
RawTransaction transaction =
|
|
||||||
RawTransaction.createTransaction(
|
|
||||||
sender.getNextNonce(),
|
|
||||||
BigInteger.valueOf(1000),
|
|
||||||
BigInteger.valueOf(100_000),
|
|
||||||
contractAddress.toString(),
|
|
||||||
payload.toString());
|
|
||||||
|
|
||||||
return toHexString(
|
|
||||||
TransactionEncoder.signMessage(transaction, sender.web3jCredentialsOrThrow()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.dsl.transaction.perm;
|
|
||||||
|
|
||||||
import static org.web3j.utils.Numeric.toHexString;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.datatypes.Address;
|
|
||||||
import org.hyperledger.besu.datatypes.Hash;
|
|
||||||
import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl;
|
|
||||||
import org.hyperledger.besu.plugin.data.EnodeURL;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.account.Account;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.tuweni.bytes.Bytes;
|
|
||||||
import org.web3j.abi.FunctionEncoder;
|
|
||||||
import org.web3j.abi.datatypes.Function;
|
|
||||||
import org.web3j.crypto.RawTransaction;
|
|
||||||
import org.web3j.crypto.TransactionEncoder;
|
|
||||||
|
|
||||||
public class NodeSmartContractPermissioningAllowNodeV2Transaction implements Transaction<Hash> {
|
|
||||||
|
|
||||||
private final Account sender;
|
|
||||||
private final Address contractAddress;
|
|
||||||
private final Node node;
|
|
||||||
|
|
||||||
public NodeSmartContractPermissioningAllowNodeV2Transaction(
|
|
||||||
final Account sender, final Address contractAddress, final Node node) {
|
|
||||||
this.sender = sender;
|
|
||||||
this.contractAddress = contractAddress;
|
|
||||||
this.node = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Hash execute(final NodeRequests node) {
|
|
||||||
final String signedTransactionData = signedTransactionData();
|
|
||||||
try {
|
|
||||||
String hash =
|
|
||||||
node.eth().ethSendRawTransaction(signedTransactionData).send().getTransactionHash();
|
|
||||||
return Hash.fromHexString(hash);
|
|
||||||
} catch (final IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String signedTransactionData() {
|
|
||||||
final EnodeURL enodeURL = EnodeURLImpl.fromURI(((RunnableNode) node).enodeUrl());
|
|
||||||
final Bytes payload = createPayload(enodeURL);
|
|
||||||
|
|
||||||
RawTransaction transaction =
|
|
||||||
RawTransaction.createTransaction(
|
|
||||||
sender.getNextNonce(),
|
|
||||||
BigInteger.valueOf(1_000L),
|
|
||||||
BigInteger.valueOf(3_000_000L),
|
|
||||||
contractAddress.toString(),
|
|
||||||
payload.toString());
|
|
||||||
|
|
||||||
return toHexString(
|
|
||||||
TransactionEncoder.signMessage(transaction, sender.web3jCredentialsOrThrow()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Bytes createPayload(final EnodeURL enodeUrl) {
|
|
||||||
try {
|
|
||||||
final String hexNodeIdString = enodeUrl.getNodeId().toUnprefixedHexString();
|
|
||||||
final String address = enodeUrl.getIp().getHostAddress();
|
|
||||||
final int port = enodeUrl.getListeningPortOrZero();
|
|
||||||
|
|
||||||
final Function addNodeFunction =
|
|
||||||
FunctionEncoder.makeFunction(
|
|
||||||
"addEnode",
|
|
||||||
List.of("string", "string", "uint16"),
|
|
||||||
List.of(hexNodeIdString, address, port),
|
|
||||||
Collections.emptyList());
|
|
||||||
return Bytes.fromHexString(FunctionEncoder.encode(addNodeFunction));
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error adding node to allowlist", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.dsl.transaction.perm;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.datatypes.Address;
|
|
||||||
import org.hyperledger.besu.ethereum.permissioning.NodeSmartContractV2PermissioningController;
|
|
||||||
import org.hyperledger.besu.plugin.data.EnodeURL;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.tuweni.bytes.Bytes;
|
|
||||||
import org.web3j.abi.FunctionEncoder;
|
|
||||||
import org.web3j.abi.datatypes.Function;
|
|
||||||
import org.web3j.protocol.core.DefaultBlockParameterName;
|
|
||||||
|
|
||||||
public class NodeSmartContractPermissioningConnectionIsAllowedByURLV2Transaction
|
|
||||||
implements Transaction<Boolean> {
|
|
||||||
|
|
||||||
private final Address contractAddress;
|
|
||||||
private final EnodeURL enodeUrl;
|
|
||||||
|
|
||||||
public NodeSmartContractPermissioningConnectionIsAllowedByURLV2Transaction(
|
|
||||||
final Address contractAddress, final EnodeURL enodeUrl) {
|
|
||||||
this.contractAddress = contractAddress;
|
|
||||||
this.enodeUrl = enodeUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean execute(final NodeRequests node) {
|
|
||||||
try {
|
|
||||||
final String value =
|
|
||||||
node.eth().ethCall(payload(), DefaultBlockParameterName.LATEST).send().getValue();
|
|
||||||
return Bytes.fromHexString(value)
|
|
||||||
.equals(NodeSmartContractV2PermissioningController.TRUE_RESPONSE);
|
|
||||||
} catch (final IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private org.web3j.protocol.core.methods.request.Transaction payload() {
|
|
||||||
final Bytes payload = createPayload(this.enodeUrl);
|
|
||||||
|
|
||||||
return org.web3j.protocol.core.methods.request.Transaction.createFunctionCallTransaction(
|
|
||||||
null, null, null, null, contractAddress.toString(), payload.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private Bytes createPayload(final EnodeURL enodeUrl) {
|
|
||||||
try {
|
|
||||||
final String hexNodeIdString = enodeUrl.getNodeId().toUnprefixedHexString();
|
|
||||||
final String address = enodeUrl.toURI().getHost();
|
|
||||||
final int port = enodeUrl.getListeningPortOrZero();
|
|
||||||
|
|
||||||
final Function connectionAllowedFunction =
|
|
||||||
FunctionEncoder.makeFunction(
|
|
||||||
"connectionAllowed",
|
|
||||||
List.of("string", "string", "uint16"),
|
|
||||||
List.of(hexNodeIdString, address, port),
|
|
||||||
Collections.emptyList());
|
|
||||||
return Bytes.fromHexString(FunctionEncoder.encode(connectionAllowedFunction));
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error calling connectionAllowed", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.dsl.transaction.perm;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
import static org.hyperledger.besu.ethereum.permissioning.NodeSmartContractPermissioningController.checkTransactionResult;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.crypto.Hash;
|
|
||||||
import org.hyperledger.besu.datatypes.Address;
|
|
||||||
import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl;
|
|
||||||
import org.hyperledger.besu.ethereum.permissioning.NodeSmartContractPermissioningController;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.apache.tuweni.bytes.Bytes;
|
|
||||||
import org.web3j.protocol.core.DefaultBlockParameterName;
|
|
||||||
|
|
||||||
public class NodeSmartContractPermissioningConnectionIsAllowedTransaction
|
|
||||||
implements Transaction<Boolean> {
|
|
||||||
|
|
||||||
private static final Bytes IS_CONNECTION_ALLOWED_SIGNATURE =
|
|
||||||
Hash.keccak256(
|
|
||||||
Bytes.of(
|
|
||||||
"connectionAllowed(bytes32,bytes32,bytes16,uint16,bytes32,bytes32,bytes16,uint16)"
|
|
||||||
.getBytes(UTF_8)))
|
|
||||||
.slice(0, 4);
|
|
||||||
|
|
||||||
private final Address contractAddress;
|
|
||||||
private final Node source;
|
|
||||||
private final Node target;
|
|
||||||
|
|
||||||
public NodeSmartContractPermissioningConnectionIsAllowedTransaction(
|
|
||||||
final Address contractAddress, final Node source, final Node target) {
|
|
||||||
this.contractAddress = contractAddress;
|
|
||||||
this.source = source;
|
|
||||||
this.target = target;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean execute(final NodeRequests node) {
|
|
||||||
try {
|
|
||||||
final String value =
|
|
||||||
node.eth().ethCall(payload(), DefaultBlockParameterName.LATEST).send().getValue();
|
|
||||||
return checkTransactionResult(Bytes.fromHexString(value));
|
|
||||||
} catch (final IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private org.web3j.protocol.core.methods.request.Transaction payload() {
|
|
||||||
final String sourceEnodeURL = ((RunnableNode) source).enodeUrl().toASCIIString();
|
|
||||||
final String targetEnodeURL = ((RunnableNode) target).enodeUrl().toASCIIString();
|
|
||||||
final Bytes payload =
|
|
||||||
NodeSmartContractPermissioningController.createPayload(
|
|
||||||
IS_CONNECTION_ALLOWED_SIGNATURE,
|
|
||||||
EnodeURLImpl.fromString(sourceEnodeURL),
|
|
||||||
EnodeURLImpl.fromString(targetEnodeURL));
|
|
||||||
|
|
||||||
return org.web3j.protocol.core.methods.request.Transaction.createFunctionCallTransaction(
|
|
||||||
null, null, null, null, contractAddress.toString(), payload.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.dsl.transaction.perm;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.datatypes.Address;
|
|
||||||
import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl;
|
|
||||||
import org.hyperledger.besu.ethereum.permissioning.NodeSmartContractV2PermissioningController;
|
|
||||||
import org.hyperledger.besu.plugin.data.EnodeURL;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.tuweni.bytes.Bytes;
|
|
||||||
import org.web3j.abi.FunctionEncoder;
|
|
||||||
import org.web3j.abi.datatypes.Function;
|
|
||||||
import org.web3j.protocol.core.DefaultBlockParameterName;
|
|
||||||
|
|
||||||
public class NodeSmartContractPermissioningConnectionIsAllowedV2Transaction
|
|
||||||
implements Transaction<Boolean> {
|
|
||||||
|
|
||||||
private final Address contractAddress;
|
|
||||||
private final Node node;
|
|
||||||
|
|
||||||
public NodeSmartContractPermissioningConnectionIsAllowedV2Transaction(
|
|
||||||
final Address contractAddress, final Node node) {
|
|
||||||
this.contractAddress = contractAddress;
|
|
||||||
this.node = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean execute(final NodeRequests node) {
|
|
||||||
try {
|
|
||||||
final String value =
|
|
||||||
node.eth().ethCall(payload(), DefaultBlockParameterName.LATEST).send().getValue();
|
|
||||||
return Bytes.fromHexString(value)
|
|
||||||
.equals(NodeSmartContractV2PermissioningController.TRUE_RESPONSE);
|
|
||||||
} catch (final IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private org.web3j.protocol.core.methods.request.Transaction payload() {
|
|
||||||
final EnodeURL enodeURL = EnodeURLImpl.fromURI(((RunnableNode) node).enodeUrl());
|
|
||||||
final Bytes payload = createPayload(enodeURL);
|
|
||||||
|
|
||||||
return org.web3j.protocol.core.methods.request.Transaction.createFunctionCallTransaction(
|
|
||||||
null, null, null, null, contractAddress.toString(), payload.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private Bytes createPayload(final EnodeURL enodeUrl) {
|
|
||||||
try {
|
|
||||||
final String hexNodeIdString = enodeUrl.getNodeId().toUnprefixedHexString();
|
|
||||||
final String address = enodeUrl.getIp().getHostAddress();
|
|
||||||
final int port = enodeUrl.getListeningPortOrZero();
|
|
||||||
|
|
||||||
final Function connectionAllowedFunction =
|
|
||||||
FunctionEncoder.makeFunction(
|
|
||||||
"connectionAllowed",
|
|
||||||
List.of("string", "string", "uint16"),
|
|
||||||
List.of(hexNodeIdString, address, port),
|
|
||||||
Collections.emptyList());
|
|
||||||
return Bytes.fromHexString(FunctionEncoder.encode(connectionAllowedFunction));
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error calling connectionAllowed", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.dsl.transaction.perm;
|
|
||||||
|
|
||||||
import static org.web3j.utils.Numeric.toHexString;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.datatypes.Address;
|
|
||||||
import org.hyperledger.besu.datatypes.Hash;
|
|
||||||
import org.hyperledger.besu.plugin.data.EnodeURL;
|
|
||||||
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 java.io.IOException;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.tuweni.bytes.Bytes;
|
|
||||||
import org.web3j.abi.FunctionEncoder;
|
|
||||||
import org.web3j.abi.datatypes.Function;
|
|
||||||
import org.web3j.crypto.RawTransaction;
|
|
||||||
import org.web3j.crypto.TransactionEncoder;
|
|
||||||
|
|
||||||
public class NodeSmartContractPermissioningForbidNodeByURLV2Transaction
|
|
||||||
implements Transaction<Hash> {
|
|
||||||
|
|
||||||
private final Account sender;
|
|
||||||
private final Address contractAddress;
|
|
||||||
private final EnodeURL enodeUrl;
|
|
||||||
|
|
||||||
public NodeSmartContractPermissioningForbidNodeByURLV2Transaction(
|
|
||||||
final Account sender, final Address contractAddress, final EnodeURL enodeUrl) {
|
|
||||||
this.sender = sender;
|
|
||||||
this.contractAddress = contractAddress;
|
|
||||||
this.enodeUrl = enodeUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Hash execute(final NodeRequests node) {
|
|
||||||
final String signedTransactionData = signedTransactionData();
|
|
||||||
try {
|
|
||||||
String hash =
|
|
||||||
node.eth().ethSendRawTransaction(signedTransactionData).send().getTransactionHash();
|
|
||||||
return Hash.fromHexString(hash);
|
|
||||||
} catch (final IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String signedTransactionData() {
|
|
||||||
final Bytes payload = createPayload(this.enodeUrl);
|
|
||||||
|
|
||||||
RawTransaction transaction =
|
|
||||||
RawTransaction.createTransaction(
|
|
||||||
sender.getNextNonce(),
|
|
||||||
BigInteger.valueOf(1000),
|
|
||||||
BigInteger.valueOf(3_000_000L),
|
|
||||||
contractAddress.toString(),
|
|
||||||
payload.toString());
|
|
||||||
|
|
||||||
return toHexString(
|
|
||||||
TransactionEncoder.signMessage(transaction, sender.web3jCredentialsOrThrow()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Bytes createPayload(final EnodeURL enodeUrl) {
|
|
||||||
try {
|
|
||||||
final String hexNodeIdString = enodeUrl.getNodeId().toUnprefixedHexString();
|
|
||||||
final String address = enodeUrl.toURI().getHost();
|
|
||||||
final int port = enodeUrl.getListeningPortOrZero();
|
|
||||||
|
|
||||||
final Function removeNodeFunction =
|
|
||||||
FunctionEncoder.makeFunction(
|
|
||||||
"removeEnode",
|
|
||||||
List.of("string", "string", "uint16"),
|
|
||||||
List.of(hexNodeIdString, address, port),
|
|
||||||
Collections.emptyList());
|
|
||||||
return Bytes.fromHexString(FunctionEncoder.encode(removeNodeFunction));
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error removing node from allowlist", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.dsl.transaction.perm;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
import static org.web3j.utils.Numeric.toHexString;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.datatypes.Address;
|
|
||||||
import org.hyperledger.besu.datatypes.Hash;
|
|
||||||
import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl;
|
|
||||||
import org.hyperledger.besu.ethereum.permissioning.NodeSmartContractPermissioningController;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.account.Account;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
import org.apache.tuweni.bytes.Bytes;
|
|
||||||
import org.web3j.crypto.RawTransaction;
|
|
||||||
import org.web3j.crypto.TransactionEncoder;
|
|
||||||
|
|
||||||
public class NodeSmartContractPermissioningForbidNodeTransaction implements Transaction<Hash> {
|
|
||||||
|
|
||||||
private static final Bytes REMOVE_ENODE_SIGNATURE =
|
|
||||||
org.hyperledger.besu.crypto.Hash.keccak256(
|
|
||||||
Bytes.of("removeEnode(bytes32,bytes32,bytes16,uint16)".getBytes(UTF_8)))
|
|
||||||
.slice(0, 4);
|
|
||||||
|
|
||||||
private final Account sender;
|
|
||||||
private final Address contractAddress;
|
|
||||||
private final Node node;
|
|
||||||
|
|
||||||
public NodeSmartContractPermissioningForbidNodeTransaction(
|
|
||||||
final Account sender, final Address contractAddress, final Node node) {
|
|
||||||
this.sender = sender;
|
|
||||||
this.contractAddress = contractAddress;
|
|
||||||
this.node = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Hash execute(final NodeRequests node) {
|
|
||||||
final String signedTransactionData = signedTransactionData();
|
|
||||||
try {
|
|
||||||
String hash =
|
|
||||||
node.eth().ethSendRawTransaction(signedTransactionData).send().getTransactionHash();
|
|
||||||
return Hash.fromHexString(hash);
|
|
||||||
} catch (final IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String signedTransactionData() {
|
|
||||||
final String enodeURL = ((RunnableNode) node).enodeUrl().toASCIIString();
|
|
||||||
final Bytes payload =
|
|
||||||
NodeSmartContractPermissioningController.createPayload(
|
|
||||||
REMOVE_ENODE_SIGNATURE, EnodeURLImpl.fromString(enodeURL));
|
|
||||||
|
|
||||||
RawTransaction transaction =
|
|
||||||
RawTransaction.createTransaction(
|
|
||||||
sender.getNextNonce(),
|
|
||||||
BigInteger.valueOf(1000),
|
|
||||||
BigInteger.valueOf(100_000),
|
|
||||||
contractAddress.toString(),
|
|
||||||
payload.toString());
|
|
||||||
|
|
||||||
return toHexString(
|
|
||||||
TransactionEncoder.signMessage(transaction, sender.web3jCredentialsOrThrow()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.dsl.transaction.perm;
|
|
||||||
|
|
||||||
import static org.web3j.utils.Numeric.toHexString;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.datatypes.Address;
|
|
||||||
import org.hyperledger.besu.datatypes.Hash;
|
|
||||||
import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl;
|
|
||||||
import org.hyperledger.besu.plugin.data.EnodeURL;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.account.Account;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.tuweni.bytes.Bytes;
|
|
||||||
import org.web3j.abi.FunctionEncoder;
|
|
||||||
import org.web3j.abi.datatypes.Function;
|
|
||||||
import org.web3j.crypto.RawTransaction;
|
|
||||||
import org.web3j.crypto.TransactionEncoder;
|
|
||||||
|
|
||||||
public class NodeSmartContractPermissioningForbidNodeV2Transaction implements Transaction<Hash> {
|
|
||||||
|
|
||||||
private final Account sender;
|
|
||||||
private final Address contractAddress;
|
|
||||||
private final Node node;
|
|
||||||
|
|
||||||
public NodeSmartContractPermissioningForbidNodeV2Transaction(
|
|
||||||
final Account sender, final Address contractAddress, final Node node) {
|
|
||||||
this.sender = sender;
|
|
||||||
this.contractAddress = contractAddress;
|
|
||||||
this.node = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Hash execute(final NodeRequests node) {
|
|
||||||
final String signedTransactionData = signedTransactionData();
|
|
||||||
try {
|
|
||||||
String hash =
|
|
||||||
node.eth().ethSendRawTransaction(signedTransactionData).send().getTransactionHash();
|
|
||||||
return Hash.fromHexString(hash);
|
|
||||||
} catch (final IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String signedTransactionData() {
|
|
||||||
final EnodeURL enodeURL = EnodeURLImpl.fromURI(((RunnableNode) node).enodeUrl());
|
|
||||||
final Bytes payload = createPayload(enodeURL);
|
|
||||||
|
|
||||||
RawTransaction transaction =
|
|
||||||
RawTransaction.createTransaction(
|
|
||||||
sender.getNextNonce(),
|
|
||||||
BigInteger.valueOf(1000),
|
|
||||||
BigInteger.valueOf(3_000_000L),
|
|
||||||
contractAddress.toString(),
|
|
||||||
payload.toString());
|
|
||||||
|
|
||||||
return toHexString(
|
|
||||||
TransactionEncoder.signMessage(transaction, sender.web3jCredentialsOrThrow()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Bytes createPayload(final EnodeURL enodeUrl) {
|
|
||||||
try {
|
|
||||||
final String hexNodeIdString = enodeUrl.getNodeId().toUnprefixedHexString();
|
|
||||||
final String address = enodeUrl.getIp().getHostAddress();
|
|
||||||
final int port = enodeUrl.getListeningPortOrZero();
|
|
||||||
|
|
||||||
final Function removeNodeFunction =
|
|
||||||
FunctionEncoder.makeFunction(
|
|
||||||
"removeEnode",
|
|
||||||
List.of("string", "string", "uint16"),
|
|
||||||
List.of(hexNodeIdString, address, port),
|
|
||||||
Collections.emptyList());
|
|
||||||
return Bytes.fromHexString(FunctionEncoder.encode(removeNodeFunction));
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Error removing node from allowlist", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.dsl.transaction.perm;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.crypto.Hash;
|
|
||||||
import org.hyperledger.besu.datatypes.Address;
|
|
||||||
import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl;
|
|
||||||
import org.hyperledger.besu.ethereum.permissioning.NodeSmartContractPermissioningController;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.NodeRequests;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.apache.tuweni.bytes.Bytes;
|
|
||||||
import org.web3j.protocol.core.DefaultBlockParameterName;
|
|
||||||
|
|
||||||
public class NodeSmartContractPermissioningIsAllowedTransaction implements Transaction<Boolean> {
|
|
||||||
|
|
||||||
private static final Bytes IS_NODE_ALLOWED_SIGNATURE =
|
|
||||||
Hash.keccak256(Bytes.of("enodeAllowed(bytes32,bytes32,bytes16,uint16)".getBytes(UTF_8)))
|
|
||||||
.slice(0, 4);
|
|
||||||
|
|
||||||
private final Address contractAddress;
|
|
||||||
private final Node node;
|
|
||||||
|
|
||||||
public NodeSmartContractPermissioningIsAllowedTransaction(
|
|
||||||
final Address contractAddress, final Node node) {
|
|
||||||
this.contractAddress = contractAddress;
|
|
||||||
this.node = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean execute(final NodeRequests node) {
|
|
||||||
try {
|
|
||||||
final String value =
|
|
||||||
node.eth().ethCall(payload(), DefaultBlockParameterName.LATEST).send().getValue();
|
|
||||||
return checkTransactionResult(Bytes.fromHexString(value));
|
|
||||||
} catch (final IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks the returned bytes from the permissioning contract call to see if it's a value we
|
|
||||||
// understand
|
|
||||||
static Boolean checkTransactionResult(final Bytes result) {
|
|
||||||
// booleans are padded to 32 bytes
|
|
||||||
if (result.size() != 32) {
|
|
||||||
throw new IllegalArgumentException("Unexpected result size");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0 is false
|
|
||||||
if (result.equals(
|
|
||||||
Bytes.fromHexString(
|
|
||||||
"0x0000000000000000000000000000000000000000000000000000000000000000"))) {
|
|
||||||
return false;
|
|
||||||
// 1 filled to 32 bytes is true
|
|
||||||
} else if (result.equals(
|
|
||||||
Bytes.fromHexString(
|
|
||||||
"0x0000000000000000000000000000000000000000000000000000000000000001"))) {
|
|
||||||
return true;
|
|
||||||
// Anything else is wrong
|
|
||||||
} else {
|
|
||||||
throw new IllegalStateException("Unexpected result form");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private org.web3j.protocol.core.methods.request.Transaction payload() {
|
|
||||||
final String sourceEnodeURL = ((RunnableNode) node).enodeUrl().toASCIIString();
|
|
||||||
final Bytes payload =
|
|
||||||
NodeSmartContractPermissioningController.createPayload(
|
|
||||||
IS_NODE_ALLOWED_SIGNATURE, EnodeURLImpl.fromString(sourceEnodeURL));
|
|
||||||
|
|
||||||
return org.web3j.protocol.core.methods.request.Transaction.createFunctionCallTransaction(
|
|
||||||
null, null, null, null, contractAddress.toString(), payload.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.dsl.transaction.perm;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.datatypes.Address;
|
|
||||||
import org.hyperledger.besu.datatypes.Hash;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.account.Accounts;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction;
|
|
||||||
|
|
||||||
public class NodeSmartContractPermissioningTransactions {
|
|
||||||
|
|
||||||
private final Accounts accounts;
|
|
||||||
|
|
||||||
public NodeSmartContractPermissioningTransactions(final Accounts accounts) {
|
|
||||||
this.accounts = accounts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Transaction<Hash> allowNode(final String contractAddress, final Node node) {
|
|
||||||
return new NodeSmartContractPermissioningAllowNodeTransaction(
|
|
||||||
accounts.getPrimaryBenefactor(), Address.fromHexString(contractAddress), node);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Transaction<Hash> forbidNode(final String contractAddress, final Node node) {
|
|
||||||
return new NodeSmartContractPermissioningForbidNodeTransaction(
|
|
||||||
accounts.getPrimaryBenefactor(), Address.fromHexString(contractAddress), node);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Transaction<Boolean> isNodeAllowed(final String contractAddress, final Node node) {
|
|
||||||
return new NodeSmartContractPermissioningIsAllowedTransaction(
|
|
||||||
Address.fromHexString(contractAddress), node);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Transaction<Boolean> isConnectionAllowed(
|
|
||||||
final String contractAddress, final Node source, final Node target) {
|
|
||||||
return new NodeSmartContractPermissioningConnectionIsAllowedTransaction(
|
|
||||||
Address.fromHexString(contractAddress), source, target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.dsl.transaction.perm;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.datatypes.Address;
|
|
||||||
import org.hyperledger.besu.datatypes.Hash;
|
|
||||||
import org.hyperledger.besu.plugin.data.EnodeURL;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.account.Accounts;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction;
|
|
||||||
|
|
||||||
public class NodeSmartContractPermissioningV2Transactions {
|
|
||||||
|
|
||||||
private final Accounts accounts;
|
|
||||||
|
|
||||||
public NodeSmartContractPermissioningV2Transactions(final Accounts accounts) {
|
|
||||||
this.accounts = accounts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Transaction<Hash> allowNode(final String contractAddress, final Node node) {
|
|
||||||
return new NodeSmartContractPermissioningAllowNodeV2Transaction(
|
|
||||||
accounts.getPrimaryBenefactor(), Address.fromHexString(contractAddress), node);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Transaction<Hash> allowNode(final String contractAddress, final EnodeURL enodeURL) {
|
|
||||||
return new NodeSmartContractPermissioningAllowNodeByURLV2Transaction(
|
|
||||||
accounts.getPrimaryBenefactor(), Address.fromHexString(contractAddress), enodeURL);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Transaction<Hash> forbidNode(final String contractAddress, final Node node) {
|
|
||||||
return new NodeSmartContractPermissioningForbidNodeV2Transaction(
|
|
||||||
accounts.getPrimaryBenefactor(), Address.fromHexString(contractAddress), node);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Transaction<Hash> forbidNode(final String contractAddress, final EnodeURL enodeURL) {
|
|
||||||
return new NodeSmartContractPermissioningForbidNodeByURLV2Transaction(
|
|
||||||
accounts.getPrimaryBenefactor(), Address.fromHexString(contractAddress), enodeURL);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Transaction<Boolean> isConnectionAllowed(final String contractAddress, final Node node) {
|
|
||||||
return new NodeSmartContractPermissioningConnectionIsAllowedV2Transaction(
|
|
||||||
Address.fromHexString(contractAddress), node);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Transaction<Boolean> isConnectionAllowed(
|
|
||||||
final String contractAddress, final EnodeURL enodeURL) {
|
|
||||||
return new NodeSmartContractPermissioningConnectionIsAllowedByURLV2Transaction(
|
|
||||||
Address.fromHexString(contractAddress), enodeURL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.permissioning;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.account.Account;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.account.TransferTransaction;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Disabled;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
@Disabled("permissioning tests flaky with timeouts")
|
|
||||||
public class AccountLocalAndOnchainPermissioningAcceptanceTest
|
|
||||||
extends AccountSmartContractPermissioningAcceptanceTestBase {
|
|
||||||
|
|
||||||
private Account senderC;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void setUp() {
|
|
||||||
senderC = accounts.createAccount("Account-C");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAccountCannotSendTxWhenNotOnLocalAllowList() {
|
|
||||||
// Onchain allowlist: Primary, Secondary, C
|
|
||||||
// Local allowlist: Primary, Secondary
|
|
||||||
|
|
||||||
final Node node =
|
|
||||||
permissionedNode(
|
|
||||||
"node1",
|
|
||||||
Arrays.asList(
|
|
||||||
accounts.getPrimaryBenefactor().getAddress(),
|
|
||||||
accounts.getSecondaryBenefactor().getAddress()));
|
|
||||||
permissionedCluster.start(node);
|
|
||||||
|
|
||||||
// ensure SenderC has got some ether available
|
|
||||||
node.execute(accountTransactions.createTransfer(senderC, 10));
|
|
||||||
node.verify(senderC.balanceEquals(10));
|
|
||||||
|
|
||||||
// add accounts to onchain allowlist
|
|
||||||
node.execute(allowAccount(accounts.getPrimaryBenefactor()));
|
|
||||||
node.verify(accountIsAllowed(accounts.getPrimaryBenefactor()));
|
|
||||||
|
|
||||||
node.execute(allowAccount(accounts.getSecondaryBenefactor()));
|
|
||||||
node.verify(accountIsAllowed(accounts.getSecondaryBenefactor()));
|
|
||||||
|
|
||||||
node.execute(allowAccount(senderC));
|
|
||||||
node.verify(accountIsAllowed(senderC));
|
|
||||||
|
|
||||||
// sender C should not be able to send Tx
|
|
||||||
verifyTransferForbidden(node, senderC, accounts.getSecondaryBenefactor());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAccountCannotSendTxWhenNotOnOnchainAllowList() {
|
|
||||||
// Onchain allowlist: Primary, Secondary, Receiver
|
|
||||||
// Local allowlist: Primary, Secondary, C, Receiver
|
|
||||||
|
|
||||||
final Account receiverAccount = accounts.createAccount("Rec-A");
|
|
||||||
|
|
||||||
final Node node =
|
|
||||||
permissionedNode(
|
|
||||||
"node1",
|
|
||||||
Arrays.asList(
|
|
||||||
accounts.getPrimaryBenefactor().getAddress(),
|
|
||||||
accounts.getSecondaryBenefactor().getAddress(),
|
|
||||||
senderC.getAddress(),
|
|
||||||
receiverAccount.getAddress()));
|
|
||||||
permissionedCluster.start(node);
|
|
||||||
|
|
||||||
// ensure SenderC has got some ether available
|
|
||||||
node.execute(accountTransactions.createTransfer(senderC, 10));
|
|
||||||
node.verify(senderC.balanceEquals(10));
|
|
||||||
|
|
||||||
// add accounts to onchain allowlist
|
|
||||||
node.execute(allowAccount(accounts.getPrimaryBenefactor()));
|
|
||||||
node.verify(accountIsAllowed(accounts.getPrimaryBenefactor()));
|
|
||||||
|
|
||||||
node.execute(allowAccount(accounts.getSecondaryBenefactor()));
|
|
||||||
node.verify(accountIsAllowed(accounts.getSecondaryBenefactor()));
|
|
||||||
|
|
||||||
node.execute(allowAccount(receiverAccount));
|
|
||||||
node.verify(accountIsAllowed(receiverAccount));
|
|
||||||
|
|
||||||
// verify senderC is forbidden because it is not on Onchain allowlist
|
|
||||||
node.verify(accountIsForbidden(senderC));
|
|
||||||
|
|
||||||
// sender C should not be able to send Tx
|
|
||||||
verifyTransferForbidden(node, senderC, accounts.getSecondaryBenefactor());
|
|
||||||
|
|
||||||
// final check, other account should be able to send tx
|
|
||||||
node.execute(
|
|
||||||
accountTransactions.createTransfer(accounts.getPrimaryBenefactor(), receiverAccount, 5));
|
|
||||||
node.verify(receiverAccount.balanceEquals(5));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifyTransferForbidden(
|
|
||||||
final Node node, final Account sender, final Account beneficiary) {
|
|
||||||
final BigInteger nonce = node.execute(ethTransactions.getTransactionCount(sender.getAddress()));
|
|
||||||
final TransferTransaction transfer =
|
|
||||||
accountTransactions.createTransfer(sender, beneficiary, 1, nonce);
|
|
||||||
node.verify(
|
|
||||||
eth.expectEthSendRawTransactionException(
|
|
||||||
transfer.signedTransactionData(),
|
|
||||||
"Sender account not authorized to send transactions"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.permissioning;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.account.Account;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.account.TransferTransaction;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
public class AccountSmartContractPermissioningAcceptanceTest
|
|
||||||
extends AccountSmartContractPermissioningAcceptanceTestBase {
|
|
||||||
|
|
||||||
private Node node;
|
|
||||||
private Account allowedSender;
|
|
||||||
private Account otherAccount;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void setUp() {
|
|
||||||
node = permissionedNode("node1", Collections.emptyList());
|
|
||||||
permissionedCluster.start(node);
|
|
||||||
|
|
||||||
allowedSender = accounts.createAccount("authorized-account");
|
|
||||||
otherAccount = accounts.createAccount("other-account");
|
|
||||||
|
|
||||||
// ensure primary benefactor is permitted (account used to permit/forbid other accounts)
|
|
||||||
node.execute(allowAccount(accounts.getPrimaryBenefactor()));
|
|
||||||
node.verify(accountIsAllowed(accounts.getPrimaryBenefactor()));
|
|
||||||
|
|
||||||
// ensure allowedSender has got some ether available
|
|
||||||
node.execute(accountTransactions.createTransfer(allowedSender, 10));
|
|
||||||
node.verify(allowedSender.balanceEquals(10));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void allowedAccountCanTransferValue() {
|
|
||||||
node.execute(allowAccount(allowedSender));
|
|
||||||
node.verify(accountIsAllowed(allowedSender));
|
|
||||||
|
|
||||||
node.execute(accountTransactions.createTransfer(allowedSender, otherAccount, 5));
|
|
||||||
node.verify(otherAccount.balanceEquals(5));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void forbiddenAccountCannotTransferValue() {
|
|
||||||
node.execute(forbidAccount(allowedSender));
|
|
||||||
node.verify(accountIsForbidden(allowedSender));
|
|
||||||
|
|
||||||
verifyTransferForbidden(allowedSender, otherAccount);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifyTransferForbidden(final Account sender, final Account beneficiary) {
|
|
||||||
final BigInteger nonce = node.execute(ethTransactions.getTransactionCount(sender.getAddress()));
|
|
||||||
final TransferTransaction transfer =
|
|
||||||
accountTransactions.createTransfer(sender, beneficiary, 1, nonce);
|
|
||||||
node.verify(
|
|
||||||
eth.expectEthSendRawTransactionException(
|
|
||||||
transfer.signedTransactionData(),
|
|
||||||
"Sender account not authorized to send transactions"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.permissioning;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.datatypes.Hash;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.account.Account;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.condition.perm.AccountSmartContractPermissioningConditions;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.Cluster;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfiguration;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfigurationBuilder;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.permissioning.PermissionedNodeBuilder;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.perm.AccountSmartContractPermissioningTransactions;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
|
||||||
|
|
||||||
class AccountSmartContractPermissioningAcceptanceTestBase extends AcceptanceTestBase {
|
|
||||||
|
|
||||||
private final AccountSmartContractPermissioningTransactions smartContractAccountPermissioning;
|
|
||||||
private final AccountSmartContractPermissioningConditions
|
|
||||||
accountSmartContractPermissioningConditions;
|
|
||||||
|
|
||||||
private static final String CONTRACT_ADDRESS = "0x0000000000000000000000000000000000008888";
|
|
||||||
private static final String GENESIS_FILE = "/permissioning/simple_permissioning_genesis.json";
|
|
||||||
|
|
||||||
protected final Cluster permissionedCluster;
|
|
||||||
|
|
||||||
protected AccountSmartContractPermissioningAcceptanceTestBase() {
|
|
||||||
super();
|
|
||||||
smartContractAccountPermissioning = new AccountSmartContractPermissioningTransactions(accounts);
|
|
||||||
accountSmartContractPermissioningConditions =
|
|
||||||
new AccountSmartContractPermissioningConditions(smartContractAccountPermissioning);
|
|
||||||
this.permissionedCluster = permissionedCluster();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Cluster permissionedCluster() {
|
|
||||||
final ClusterConfiguration clusterConfiguration =
|
|
||||||
new ClusterConfigurationBuilder().awaitPeerDiscovery(false).build();
|
|
||||||
return new Cluster(clusterConfiguration, net);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Node permissionedNode(final String name, final List<String> accountsPermittedInConfig) {
|
|
||||||
PermissionedNodeBuilder permissionedNodeBuilder =
|
|
||||||
this.permissionedNodeBuilder
|
|
||||||
.name(name)
|
|
||||||
.genesisFile(GENESIS_FILE)
|
|
||||||
.accountsContractEnabled(CONTRACT_ADDRESS);
|
|
||||||
|
|
||||||
if (accountsPermittedInConfig != null && !accountsPermittedInConfig.isEmpty()) {
|
|
||||||
permissionedNodeBuilder.accountsPermittedInConfig(accountsPermittedInConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
return permissionedNodeBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Node node(final String name) {
|
|
||||||
try {
|
|
||||||
return besu.createCustomGenesisNode(name, GENESIS_FILE, false);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException("Error creating node", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterEach
|
|
||||||
@Override
|
|
||||||
public void tearDownAcceptanceTestBase() {
|
|
||||||
permissionedCluster.stop();
|
|
||||||
super.tearDownAcceptanceTestBase();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Transaction<Hash> allowAccount(final Account account) {
|
|
||||||
return smartContractAccountPermissioning.allowAccount(CONTRACT_ADDRESS, account);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Transaction<Hash> forbidAccount(final Account account) {
|
|
||||||
return smartContractAccountPermissioning.forbidAccount(CONTRACT_ADDRESS, account);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Condition accountIsAllowed(final Account account) {
|
|
||||||
return accountSmartContractPermissioningConditions.accountIsAllowed(CONTRACT_ADDRESS, account);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Condition accountIsForbidden(final Account account) {
|
|
||||||
return accountSmartContractPermissioningConditions.accountIsForbidden(
|
|
||||||
CONTRACT_ADDRESS, account);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.permissioning;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Disabled;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
@Disabled("permissioning tests flaky with timeouts")
|
|
||||||
public class NodeLocalAndOnchainPermissioningAcceptanceTest
|
|
||||||
extends NodeSmartContractPermissioningAcceptanceTestBase {
|
|
||||||
|
|
||||||
private Node bootnode;
|
|
||||||
private Node permissionedNode;
|
|
||||||
private Node allowedNode;
|
|
||||||
private Node forbiddenNode;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void setUp() {
|
|
||||||
bootnode = bootnode("bootnode");
|
|
||||||
forbiddenNode = node("forbidden-node");
|
|
||||||
allowedNode = node("allowed-node");
|
|
||||||
|
|
||||||
permissionedCluster.start(bootnode, allowedNode, forbiddenNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNodeCannotConnectWhenAllowedOnchainButNotLocally() {
|
|
||||||
|
|
||||||
// add permissioned node after cluster start because we need enode URI for local config
|
|
||||||
permissionedNode = permissionedNode("permissioned-node", bootnode, allowedNode);
|
|
||||||
permissionedCluster.addNode(permissionedNode);
|
|
||||||
|
|
||||||
// update Onchain smart contract with allowed nodes
|
|
||||||
permissionedNode.execute(allowNode(bootnode));
|
|
||||||
permissionedNode.verify(nodeIsAllowed(bootnode));
|
|
||||||
|
|
||||||
permissionedNode.execute(allowNode(allowedNode));
|
|
||||||
permissionedNode.verify(nodeIsAllowed(allowedNode));
|
|
||||||
|
|
||||||
permissionedNode.execute(allowNode(permissionedNode));
|
|
||||||
permissionedNode.verify(nodeIsAllowed(permissionedNode));
|
|
||||||
|
|
||||||
permissionedNode.execute(allowNode(forbiddenNode));
|
|
||||||
permissionedNode.verify(nodeIsAllowed(forbiddenNode));
|
|
||||||
|
|
||||||
permissionedNodeShouldDiscoverOnlyAllowedNodes();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNodeCannotConnectWhenAllowedLocallyButNotOnchain() {
|
|
||||||
// onchain allowlist: A, B
|
|
||||||
// local allowlist: A, B, C
|
|
||||||
|
|
||||||
// add permissioned node after cluster start because we need enode URI for local config
|
|
||||||
permissionedNode = permissionedNode("permissioned-node", bootnode, allowedNode, forbiddenNode);
|
|
||||||
permissionedCluster.addNode(permissionedNode);
|
|
||||||
|
|
||||||
// update Onchain smart contract with allowed nodes
|
|
||||||
permissionedNode.execute(allowNode(bootnode));
|
|
||||||
permissionedNode.verify(nodeIsAllowed(bootnode));
|
|
||||||
|
|
||||||
permissionedNode.execute(allowNode(allowedNode));
|
|
||||||
permissionedNode.verify(nodeIsAllowed(allowedNode));
|
|
||||||
|
|
||||||
permissionedNode.execute(allowNode(permissionedNode));
|
|
||||||
permissionedNode.verify(nodeIsAllowed(permissionedNode));
|
|
||||||
|
|
||||||
permissionedNodeShouldDiscoverOnlyAllowedNodes();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNodesCanConnectWhenAllowedBothOnchainAndLocally() {
|
|
||||||
// add permissioned node after cluster start because we need enode URI for local config
|
|
||||||
permissionedNode = permissionedNode("permissioned-node", bootnode, allowedNode, forbiddenNode);
|
|
||||||
permissionedCluster.addNode(permissionedNode);
|
|
||||||
|
|
||||||
// update Onchain smart contract with allowed nodes
|
|
||||||
permissionedNode.execute(allowNode(bootnode));
|
|
||||||
permissionedNode.verify(nodeIsAllowed(bootnode));
|
|
||||||
|
|
||||||
permissionedNode.execute(allowNode(allowedNode));
|
|
||||||
permissionedNode.verify(nodeIsAllowed(allowedNode));
|
|
||||||
|
|
||||||
permissionedNode.execute(allowNode(permissionedNode));
|
|
||||||
permissionedNode.verify(nodeIsAllowed(permissionedNode));
|
|
||||||
|
|
||||||
permissionedNode.execute(allowNode(forbiddenNode));
|
|
||||||
permissionedNode.verify(nodeIsAllowed(forbiddenNode));
|
|
||||||
|
|
||||||
bootnode.verify(net.awaitPeerCount(3));
|
|
||||||
allowedNode.verify(net.awaitPeerCount(3));
|
|
||||||
forbiddenNode.verify(net.awaitPeerCount(3));
|
|
||||||
permissionedNode.verify(net.awaitPeerCount(3));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void permissionedNodeShouldDiscoverOnlyAllowedNodes() {
|
|
||||||
bootnode.verify(net.awaitPeerCount(3));
|
|
||||||
allowedNode.verify(net.awaitPeerCount(3));
|
|
||||||
forbiddenNode.verify(net.awaitPeerCount(2));
|
|
||||||
permissionedNode.verify(net.awaitPeerCount(2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.permissioning;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Disabled;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
public class NodeSmartContractPermissioningAcceptanceTest
|
|
||||||
extends NodeSmartContractPermissioningAcceptanceTestBase {
|
|
||||||
|
|
||||||
private Node bootnode;
|
|
||||||
private Node permissionedNode;
|
|
||||||
private Node allowedNode;
|
|
||||||
private Node forbiddenNode;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void setUp() {
|
|
||||||
bootnode = bootnode("bootnode");
|
|
||||||
forbiddenNode = node("forbidden-node");
|
|
||||||
allowedNode = node("allowed-node");
|
|
||||||
permissionedNode = permissionedNode("permissioned-node");
|
|
||||||
|
|
||||||
permissionedCluster.start(bootnode, forbiddenNode, allowedNode, permissionedNode);
|
|
||||||
|
|
||||||
// updating permissioning smart contract with allowed nodes
|
|
||||||
permissionedNode.verify(nodeIsForbidden(bootnode));
|
|
||||||
permissionedNode.execute(allowNode(bootnode));
|
|
||||||
permissionedNode.verify(nodeIsAllowed(bootnode));
|
|
||||||
permissionedNode.verify(admin.hasPeer(bootnode));
|
|
||||||
|
|
||||||
permissionedNode.execute(allowNode(allowedNode));
|
|
||||||
permissionedNode.verify(nodeIsAllowed(allowedNode));
|
|
||||||
|
|
||||||
permissionedNode.execute(allowNode(permissionedNode));
|
|
||||||
permissionedNode.verify(nodeIsAllowed(permissionedNode));
|
|
||||||
|
|
||||||
permissionedNode.verify(admin.addPeer(allowedNode));
|
|
||||||
|
|
||||||
allowedNode.verify(eth.syncingStatus(false));
|
|
||||||
bootnode.verify(eth.syncingStatus(false));
|
|
||||||
permissionedNode.verify(eth.syncingStatus(false));
|
|
||||||
forbiddenNode.verify(eth.syncingStatus(false));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Disabled("test is flaky")
|
|
||||||
public void permissionedNodeShouldPeerOnlyWithAllowedNodes() {
|
|
||||||
bootnode.verify(net.awaitPeerCount(3));
|
|
||||||
allowedNode.verify(net.awaitPeerCount(3));
|
|
||||||
forbiddenNode.verify(net.awaitPeerCount(2));
|
|
||||||
permissionedNode.verify(net.awaitPeerCount(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void permissionedNodeShouldDisconnectFromNodeNotPermittedAnymore() {
|
|
||||||
permissionedNode.execute(forbidNode(allowedNode));
|
|
||||||
permissionedNode.verify(connectionIsForbidden(permissionedNode, allowedNode));
|
|
||||||
|
|
||||||
permissionedNode.verify(net.awaitPeerCount(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void permissioningUpdatesPropagateThroughNetwork() {
|
|
||||||
// connection to newly permitted node is allowed
|
|
||||||
allowedNode.execute(allowNode(forbiddenNode));
|
|
||||||
allowedNode.verify(connectionIsAllowed(permissionedNode, forbiddenNode));
|
|
||||||
// permissioning changes in peer should propagate to permissioned node
|
|
||||||
permissionedNode.verify(connectionIsAllowed(permissionedNode, forbiddenNode));
|
|
||||||
|
|
||||||
permissionedNode.verify(admin.addPeer(forbiddenNode));
|
|
||||||
permissionedNode.verify(net.awaitPeerCount(3));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onchainPermissioningAllowlistShouldPersistAcrossRestarts() {
|
|
||||||
permissionedCluster.stop();
|
|
||||||
permissionedCluster.start(bootnode, forbiddenNode, allowedNode, permissionedNode);
|
|
||||||
|
|
||||||
permissionedNode.verify(nodeIsAllowed(allowedNode));
|
|
||||||
permissionedNode.verify(nodeIsAllowed(bootnode));
|
|
||||||
permissionedNode.verify(nodeIsAllowed(permissionedNode));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.permissioning;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.datatypes.Hash;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.condition.perm.NodeSmartContractPermissioningConditions;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.Cluster;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfiguration;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfigurationBuilder;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.permissioning.PermissionedNodeBuilder;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.perm.NodeSmartContractPermissioningTransactions;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
|
||||||
|
|
||||||
class NodeSmartContractPermissioningAcceptanceTestBase extends AcceptanceTestBase {
|
|
||||||
|
|
||||||
private final NodeSmartContractPermissioningTransactions smartContractNodePermissioning;
|
|
||||||
private final NodeSmartContractPermissioningConditions nodeSmartContractPermissioningConditions;
|
|
||||||
|
|
||||||
protected static final String CONTRACT_ADDRESS = "0x0000000000000000000000000000000000009999";
|
|
||||||
protected static final String GENESIS_FILE = "/permissioning/simple_permissioning_genesis.json";
|
|
||||||
|
|
||||||
protected final Cluster permissionedCluster;
|
|
||||||
|
|
||||||
protected NodeSmartContractPermissioningAcceptanceTestBase() {
|
|
||||||
super();
|
|
||||||
smartContractNodePermissioning = new NodeSmartContractPermissioningTransactions(accounts);
|
|
||||||
nodeSmartContractPermissioningConditions =
|
|
||||||
new NodeSmartContractPermissioningConditions(smartContractNodePermissioning);
|
|
||||||
this.permissionedCluster = permissionedCluster();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Cluster permissionedCluster() {
|
|
||||||
final ClusterConfiguration clusterConfiguration =
|
|
||||||
new ClusterConfigurationBuilder().awaitPeerDiscovery(false).build();
|
|
||||||
return new Cluster(clusterConfiguration, net);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Node permissionedNode(final String name, final Node... localConfigAllowedNodes) {
|
|
||||||
return permissionedNode(name, GENESIS_FILE, localConfigAllowedNodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Node permissionedNode(
|
|
||||||
final String name, final String genesisFile, final Node... localConfigAllowedNodes) {
|
|
||||||
PermissionedNodeBuilder permissionedNodeBuilder =
|
|
||||||
this.permissionedNodeBuilder
|
|
||||||
.name(name)
|
|
||||||
.genesisFile(genesisFile)
|
|
||||||
.nodesContractEnabled(CONTRACT_ADDRESS);
|
|
||||||
if (localConfigAllowedNodes != null && localConfigAllowedNodes.length > 0) {
|
|
||||||
permissionedNodeBuilder.nodesPermittedInConfig(localConfigAllowedNodes);
|
|
||||||
}
|
|
||||||
return permissionedNodeBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Node bootnode(final String name) {
|
|
||||||
return bootnode(name, GENESIS_FILE);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Node bootnode(final String name, final String genesisFile) {
|
|
||||||
try {
|
|
||||||
return besu.createCustomGenesisNode(name, genesisFile, true);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException("Error creating node", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Node node(final String name) {
|
|
||||||
try {
|
|
||||||
return besu.createCustomGenesisNode(name, GENESIS_FILE, false);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException("Error creating node", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Node miner(final String name) {
|
|
||||||
try {
|
|
||||||
return besu.createCustomGenesisNode(name, GENESIS_FILE, false, true);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException("Error creating node", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterEach
|
|
||||||
@Override
|
|
||||||
public void tearDownAcceptanceTestBase() {
|
|
||||||
permissionedCluster.stop();
|
|
||||||
super.tearDownAcceptanceTestBase();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Transaction<Hash> allowNode(final Node node) {
|
|
||||||
return smartContractNodePermissioning.allowNode(CONTRACT_ADDRESS, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Condition nodeIsAllowed(final Node node) {
|
|
||||||
return nodeSmartContractPermissioningConditions.nodeIsAllowed(CONTRACT_ADDRESS, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Transaction<Hash> forbidNode(final Node node) {
|
|
||||||
return smartContractNodePermissioning.forbidNode(CONTRACT_ADDRESS, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Condition nodeIsForbidden(final Node node) {
|
|
||||||
return nodeSmartContractPermissioningConditions.nodeIsForbidden(CONTRACT_ADDRESS, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Condition connectionIsAllowed(final Node source, final Node target) {
|
|
||||||
return nodeSmartContractPermissioningConditions.connectionIsAllowed(
|
|
||||||
CONTRACT_ADDRESS, source, target);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Condition connectionIsForbidden(final Node source, final Node target) {
|
|
||||||
return nodeSmartContractPermissioningConditions.connectionIsForbidden(
|
|
||||||
CONTRACT_ADDRESS, source, target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.permissioning;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.datatypes.Address;
|
|
||||||
import org.hyperledger.besu.ethereum.permissioning.PermissioningConfiguration;
|
|
||||||
import org.hyperledger.besu.ethereum.permissioning.SmartContractPermissioningConfiguration;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
public class NodeSmartContractPermissioningIbft2StallAcceptanceTest
|
|
||||||
extends NodeSmartContractPermissioningAcceptanceTestBase {
|
|
||||||
|
|
||||||
private static final String GENESIS_FILE =
|
|
||||||
"/permissioning/simple_permissioning_ibft_genesis.json";
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void restartedIbftClusterShouldNotStall() throws IOException {
|
|
||||||
final BesuNode bootnode = besu.createIbft2NonValidatorBootnode("bootnode", GENESIS_FILE);
|
|
||||||
final BesuNode nodeA = besu.createIbft2Node("nodeA", GENESIS_FILE);
|
|
||||||
final BesuNode nodeB = besu.createIbft2Node("nodeB", GENESIS_FILE);
|
|
||||||
|
|
||||||
permissionedCluster.start(bootnode, nodeA, nodeB);
|
|
||||||
|
|
||||||
// make sure we are producing blocks before sending any transactions
|
|
||||||
waitForBlockHeight(bootnode, 1);
|
|
||||||
|
|
||||||
// allow nodes in onchain smart contract
|
|
||||||
nodeA.execute(allowNode(bootnode));
|
|
||||||
nodeA.execute(allowNode(nodeA));
|
|
||||||
nodeA.execute(allowNode(nodeB));
|
|
||||||
|
|
||||||
// verify the nodes are allowed
|
|
||||||
nodeA.verify(nodeIsAllowed(bootnode));
|
|
||||||
nodeA.verify(nodeIsAllowed(nodeA));
|
|
||||||
nodeA.verify(nodeIsAllowed(nodeB));
|
|
||||||
|
|
||||||
permissionedCluster.stop();
|
|
||||||
|
|
||||||
// Create permissioning config
|
|
||||||
final SmartContractPermissioningConfiguration smartContractPermissioningConfiguration =
|
|
||||||
new SmartContractPermissioningConfiguration();
|
|
||||||
smartContractPermissioningConfiguration.setSmartContractNodeAllowlistEnabled(true);
|
|
||||||
smartContractPermissioningConfiguration.setNodeSmartContractAddress(
|
|
||||||
Address.fromHexString(CONTRACT_ADDRESS));
|
|
||||||
final PermissioningConfiguration permissioningConfiguration =
|
|
||||||
new PermissioningConfiguration(
|
|
||||||
Optional.empty(), Optional.of(smartContractPermissioningConfiguration));
|
|
||||||
|
|
||||||
// Set permissioning configurations on nodes
|
|
||||||
bootnode.setPermissioningConfiguration(permissioningConfiguration);
|
|
||||||
nodeA.setPermissioningConfiguration(permissioningConfiguration);
|
|
||||||
nodeB.setPermissioningConfiguration(permissioningConfiguration);
|
|
||||||
|
|
||||||
permissionedCluster.start(bootnode, nodeA, nodeB);
|
|
||||||
|
|
||||||
// Verify blockchain is progressing
|
|
||||||
permissionedCluster.verify(blockchain.reachesHeight(bootnode, 1, 120));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.permissioning;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Disabled;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
public class NodeSmartContractPermissioningOutOfSyncAcceptanceTest
|
|
||||||
extends NodeSmartContractPermissioningAcceptanceTestBase {
|
|
||||||
private Node bootnode;
|
|
||||||
private Node permissionedNodeA;
|
|
||||||
private Node permissionedNodeB;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void setUp() throws InterruptedException {
|
|
||||||
bootnode = bootnode("bootnode");
|
|
||||||
permissionedNodeA = permissionedNode("permissioned-node-A");
|
|
||||||
permissionedNodeB = permissionedNode("permissioned-node-B");
|
|
||||||
|
|
||||||
permissionedCluster.start(bootnode, permissionedNodeA);
|
|
||||||
|
|
||||||
// update onchain smart contract to allowlist nodes
|
|
||||||
permissionedNodeA.execute(allowNode(bootnode));
|
|
||||||
permissionedNodeA.verify(nodeIsAllowed(bootnode));
|
|
||||||
permissionedNodeA.execute(allowNode(permissionedNodeA));
|
|
||||||
permissionedNodeA.verify(nodeIsAllowed(permissionedNodeA));
|
|
||||||
permissionedNodeA.verify(admin.addPeer(bootnode));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Disabled("test is flaky #7108")
|
|
||||||
public void addNodeToClusterAndVerifyNonBootNodePeerConnectionWorksAfterSync() {
|
|
||||||
final long blockchainHeight = 25L;
|
|
||||||
waitForBlockHeight(permissionedNodeA, blockchainHeight);
|
|
||||||
|
|
||||||
// verify Node A is in sync with bootnode
|
|
||||||
final var minerChainHead = bootnode.execute(ethTransactions.block());
|
|
||||||
permissionedNodeA.verify(blockchain.minimumHeight(minerChainHead.getNumber().longValue()));
|
|
||||||
|
|
||||||
// check that connection is forbidden (before node b is permitted)
|
|
||||||
permissionedCluster.addNode(permissionedNodeB);
|
|
||||||
permissionedNodeB.verify(connectionIsForbidden(permissionedNodeA, permissionedNodeB));
|
|
||||||
|
|
||||||
// Permit Node B
|
|
||||||
permissionedNodeA.execute(allowNode(permissionedNodeB));
|
|
||||||
permissionedNodeA.verify(admin.addPeer(permissionedNodeB));
|
|
||||||
|
|
||||||
// connection should be allowed after node B syncs
|
|
||||||
waitForBlockHeight(permissionedNodeB, blockchainHeight);
|
|
||||||
permissionedNodeB.verify(connectionIsAllowed(permissionedNodeA, permissionedNodeB));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.permissioning;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Disabled;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
public class NodeSmartContractPermissioningV2AcceptanceTest
|
|
||||||
extends NodeSmartContractPermissioningV2AcceptanceTestBase {
|
|
||||||
|
|
||||||
private Node bootnode;
|
|
||||||
private Node permissionedNode;
|
|
||||||
private Node allowedNode;
|
|
||||||
private Node forbiddenNode;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void setUp() {
|
|
||||||
bootnode = bootnode("bootnode");
|
|
||||||
forbiddenNode = node("forbidden-node");
|
|
||||||
allowedNode = node("allowed-node");
|
|
||||||
permissionedNode = permissionedNode("permissioned-node");
|
|
||||||
|
|
||||||
permissionedCluster.start(bootnode, forbiddenNode, allowedNode, permissionedNode);
|
|
||||||
|
|
||||||
verifyAllNodesAreInSyncWithMiner();
|
|
||||||
|
|
||||||
// updating permissioning smart contract with allowed nodes
|
|
||||||
|
|
||||||
permissionedNode.execute(allowNode(bootnode));
|
|
||||||
permissionedNode.verify(connectionIsAllowed(bootnode));
|
|
||||||
|
|
||||||
permissionedNode.execute(allowNode(allowedNode));
|
|
||||||
permissionedNode.verify(connectionIsAllowed(allowedNode));
|
|
||||||
|
|
||||||
permissionedNode.execute(allowNode(permissionedNode));
|
|
||||||
permissionedNode.verify(connectionIsAllowed(permissionedNode));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Disabled("test is flaky")
|
|
||||||
public void permissionedNodeShouldPeerOnlyWithAllowedNodes() {
|
|
||||||
bootnode.verify(net.awaitPeerCount(3));
|
|
||||||
allowedNode.verify(net.awaitPeerCount(3));
|
|
||||||
forbiddenNode.verify(net.awaitPeerCount(2));
|
|
||||||
permissionedNode.verify(net.awaitPeerCount(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void permissionedNodeShouldDisconnectFromNodeNotPermittedAnymore() {
|
|
||||||
permissionedNode.verify(admin.hasPeer(bootnode));
|
|
||||||
permissionedNode.verify(admin.addPeer(allowedNode));
|
|
||||||
permissionedNode.verify(net.awaitPeerCount(2));
|
|
||||||
|
|
||||||
permissionedNode.execute(forbidNode(allowedNode));
|
|
||||||
permissionedNode.verify(connectionIsForbidden(allowedNode));
|
|
||||||
|
|
||||||
permissionedNode.verify(net.awaitPeerCount(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void permissionedNodeShouldConnectToNewlyPermittedNode() {
|
|
||||||
permissionedNode.verify(admin.hasPeer(bootnode));
|
|
||||||
permissionedNode.verify(admin.addPeer(allowedNode));
|
|
||||||
permissionedNode.verify(net.awaitPeerCount(2));
|
|
||||||
|
|
||||||
verifyAllNodesAreInSyncWithMiner();
|
|
||||||
|
|
||||||
permissionedNode.execute(allowNode(forbiddenNode));
|
|
||||||
permissionedNode.verify(connectionIsAllowed(forbiddenNode));
|
|
||||||
permissionedNode.verify(admin.addPeer(forbiddenNode));
|
|
||||||
|
|
||||||
permissionedNode.verify(net.awaitPeerCount(3));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void permissioningUpdatesPropagateThroughNetwork() {
|
|
||||||
permissionedNode.verify(admin.hasPeer(bootnode));
|
|
||||||
permissionedNode.verify(admin.addPeer(allowedNode));
|
|
||||||
permissionedNode.verify(net.awaitPeerCount(2));
|
|
||||||
|
|
||||||
verifyAllNodesAreInSyncWithMiner();
|
|
||||||
|
|
||||||
// permissioning changes in peer should propagate to permissioned node
|
|
||||||
allowedNode.execute(allowNode(forbiddenNode));
|
|
||||||
allowedNode.verify(connectionIsAllowed(forbiddenNode));
|
|
||||||
permissionedNode.verify(connectionIsAllowed(forbiddenNode));
|
|
||||||
|
|
||||||
permissionedNode.verify(admin.addPeer(forbiddenNode));
|
|
||||||
permissionedNode.verify(net.awaitPeerCount(3));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifyAllNodesAreInSyncWithMiner() {
|
|
||||||
// verify the miner (permissionedNode) started producing blocks and other nodes are syncing
|
|
||||||
// from it
|
|
||||||
waitForBlockHeight(permissionedNode, 1);
|
|
||||||
final var minerChainHead = permissionedNode.execute(ethTransactions.block());
|
|
||||||
bootnode.verify(blockchain.minimumHeight(minerChainHead.getNumber().longValue()));
|
|
||||||
allowedNode.verify(blockchain.minimumHeight(minerChainHead.getNumber().longValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onchainPermissioningAllowlistShouldPersistAcrossRestarts() {
|
|
||||||
permissionedCluster.stop();
|
|
||||||
permissionedCluster.start(bootnode, forbiddenNode, allowedNode, permissionedNode);
|
|
||||||
|
|
||||||
verifyAllNodesAreInSyncWithMiner();
|
|
||||||
|
|
||||||
permissionedNode.verify(connectionIsAllowed(allowedNode));
|
|
||||||
permissionedNode.verify(connectionIsAllowed(bootnode));
|
|
||||||
permissionedNode.verify(connectionIsAllowed(permissionedNode));
|
|
||||||
permissionedNode.verify(connectionIsForbidden(forbiddenNode));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.permissioning;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.datatypes.Hash;
|
|
||||||
import org.hyperledger.besu.plugin.data.EnodeURL;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.condition.Condition;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.condition.perm.NodeSmartContractPermissioningV2Conditions;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.Cluster;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfiguration;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfigurationBuilder;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.configuration.permissioning.PermissionedNodeBuilder;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.Transaction;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.transaction.perm.NodeSmartContractPermissioningV2Transactions;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
|
||||||
|
|
||||||
class NodeSmartContractPermissioningV2AcceptanceTestBase extends AcceptanceTestBase {
|
|
||||||
|
|
||||||
private final NodeSmartContractPermissioningV2Transactions smartContractNodePermissioningV2;
|
|
||||||
private final NodeSmartContractPermissioningV2Conditions
|
|
||||||
nodeSmartContractPermissioningConditionsV2;
|
|
||||||
|
|
||||||
protected static final String CONTRACT_ADDRESS = "0x0000000000000000000000000000000000009999";
|
|
||||||
protected static final String GENESIS_FILE =
|
|
||||||
"/permissioning/simple_permissioning_v2_genesis.json";
|
|
||||||
|
|
||||||
protected final Cluster permissionedCluster;
|
|
||||||
|
|
||||||
protected NodeSmartContractPermissioningV2AcceptanceTestBase() {
|
|
||||||
super();
|
|
||||||
smartContractNodePermissioningV2 = new NodeSmartContractPermissioningV2Transactions(accounts);
|
|
||||||
nodeSmartContractPermissioningConditionsV2 =
|
|
||||||
new NodeSmartContractPermissioningV2Conditions(smartContractNodePermissioningV2);
|
|
||||||
|
|
||||||
this.permissionedCluster = permissionedCluster();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Cluster permissionedCluster() {
|
|
||||||
final ClusterConfiguration clusterConfiguration =
|
|
||||||
new ClusterConfigurationBuilder().awaitPeerDiscovery(false).build();
|
|
||||||
return new Cluster(clusterConfiguration, net);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Node permissionedNode(final String name, final Node... localConfigAllowedNodes) {
|
|
||||||
return permissionedNode(name, GENESIS_FILE, localConfigAllowedNodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Node permissionedNode(
|
|
||||||
final String name, final String genesisFile, final Node... localConfigAllowedNodes) {
|
|
||||||
PermissionedNodeBuilder permissionedNodeBuilder =
|
|
||||||
this.permissionedNodeBuilder
|
|
||||||
.name(name)
|
|
||||||
.genesisFile(genesisFile)
|
|
||||||
.nodesContractV2Enabled(CONTRACT_ADDRESS);
|
|
||||||
if (localConfigAllowedNodes != null && localConfigAllowedNodes.length > 0) {
|
|
||||||
permissionedNodeBuilder.nodesPermittedInConfig(localConfigAllowedNodes);
|
|
||||||
}
|
|
||||||
return permissionedNodeBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Node bootnode(final String name) {
|
|
||||||
return bootnode(name, GENESIS_FILE);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Node bootnode(final String name, final String genesisFile) {
|
|
||||||
try {
|
|
||||||
return besu.createCustomGenesisNode(name, genesisFile, true);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException("Error creating node", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Node node(final String name) {
|
|
||||||
try {
|
|
||||||
return besu.createCustomGenesisNode(name, GENESIS_FILE, false);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException("Error creating node", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterEach
|
|
||||||
@Override
|
|
||||||
public void tearDownAcceptanceTestBase() {
|
|
||||||
permissionedCluster.stop();
|
|
||||||
super.tearDownAcceptanceTestBase();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Transaction<Hash> allowNode(final Node node) {
|
|
||||||
return smartContractNodePermissioningV2.allowNode(CONTRACT_ADDRESS, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Transaction<Hash> allowNode(final EnodeURL enodeURL) {
|
|
||||||
return smartContractNodePermissioningV2.allowNode(CONTRACT_ADDRESS, enodeURL);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Transaction<Hash> forbidNode(final Node node) {
|
|
||||||
return smartContractNodePermissioningV2.forbidNode(CONTRACT_ADDRESS, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Transaction<Hash> forbidNode(final EnodeURL enodeURL) {
|
|
||||||
return smartContractNodePermissioningV2.forbidNode(CONTRACT_ADDRESS, enodeURL);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Condition connectionIsForbidden(final Node node) {
|
|
||||||
return nodeSmartContractPermissioningConditionsV2.connectionIsForbidden(CONTRACT_ADDRESS, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Condition connectionIsForbidden(final EnodeURL enodeURL) {
|
|
||||||
return nodeSmartContractPermissioningConditionsV2.connectionIsForbidden(
|
|
||||||
CONTRACT_ADDRESS, enodeURL);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Condition connectionIsAllowed(final Node node) {
|
|
||||||
return nodeSmartContractPermissioningConditionsV2.connectionIsAllowed(CONTRACT_ADDRESS, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Condition connectionIsAllowed(final EnodeURL enodeURL) {
|
|
||||||
return nodeSmartContractPermissioningConditionsV2.connectionIsAllowed(
|
|
||||||
CONTRACT_ADDRESS, enodeURL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.permissioning;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl;
|
|
||||||
import org.hyperledger.besu.ethereum.p2p.peers.ImmutableEnodeDnsConfiguration;
|
|
||||||
import org.hyperledger.besu.plugin.data.EnodeURL;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode;
|
|
||||||
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
|
|
||||||
import org.assertj.core.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Disabled;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
@Disabled("test is flaky #7191")
|
|
||||||
public class NodeSmartContractPermissioningV2DNSAcceptanceTest
|
|
||||||
extends NodeSmartContractPermissioningV2AcceptanceTestBase {
|
|
||||||
|
|
||||||
private Node bootnode;
|
|
||||||
private Node permissionedNode;
|
|
||||||
private Node allowedNode;
|
|
||||||
private Node forbiddenNode;
|
|
||||||
|
|
||||||
final ImmutableEnodeDnsConfiguration enodeDnsConfiguration =
|
|
||||||
ImmutableEnodeDnsConfiguration.builder().dnsEnabled(true).updateEnabled(true).build();
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void setUp() {
|
|
||||||
bootnode = bootnode("bootnode");
|
|
||||||
forbiddenNode = node("forbidden-node");
|
|
||||||
allowedNode = node("allowed-node");
|
|
||||||
permissionedNode = permissionedNode("permissioned-node");
|
|
||||||
|
|
||||||
permissionedCluster.start(bootnode, forbiddenNode, allowedNode, permissionedNode);
|
|
||||||
|
|
||||||
// updating permissioning smart contract with allowed nodes
|
|
||||||
|
|
||||||
permissionedNode.execute(allowNode(bootnode));
|
|
||||||
permissionedNode.verify(connectionIsAllowed(bootnode));
|
|
||||||
|
|
||||||
permissionedNode.execute(allowNode(allowedNode));
|
|
||||||
permissionedNode.verify(connectionIsAllowed(allowedNode));
|
|
||||||
|
|
||||||
permissionedNode.execute(allowNode(permissionedNode));
|
|
||||||
permissionedNode.verify(connectionIsAllowed(permissionedNode));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void permissionedNodeShouldAddDnsRuleAndAllowNode() throws UnknownHostException {
|
|
||||||
final EnodeURL forbiddenEnodeURL = getForbiddenEnodeURL();
|
|
||||||
Assertions.assertThat(forbiddenEnodeURL.toURI().getHost()).isEqualTo("127.0.0.1");
|
|
||||||
final EnodeURL forbiddenDnsEnodeURL = buildDnsEnodeUrl(forbiddenEnodeURL);
|
|
||||||
Assertions.assertThat(forbiddenDnsEnodeURL.toURI().getHost())
|
|
||||||
.isEqualTo(InetAddress.getLocalHost().getHostName());
|
|
||||||
|
|
||||||
permissionedNode.verify(connectionIsForbidden(forbiddenNode));
|
|
||||||
permissionedNode.verify(connectionIsForbidden(forbiddenDnsEnodeURL));
|
|
||||||
permissionedNode.execute(allowNode(forbiddenDnsEnodeURL));
|
|
||||||
permissionedNode.verify(connectionIsAllowed(forbiddenDnsEnodeURL));
|
|
||||||
permissionedNode.execute(forbidNode(forbiddenEnodeURL));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void permissionedNodeShouldAddDNSRuleAndConnectToNewPeer() throws UnknownHostException {
|
|
||||||
final EnodeURL forbiddenEnodeURL = getForbiddenEnodeURL();
|
|
||||||
Assertions.assertThat(forbiddenEnodeURL.toURI().getHost()).isEqualTo("127.0.0.1");
|
|
||||||
final EnodeURL forbiddenDnsEnodeURL = buildDnsEnodeUrl(forbiddenEnodeURL);
|
|
||||||
Assertions.assertThat(forbiddenDnsEnodeURL.toURI().getHost())
|
|
||||||
.isEqualTo(InetAddress.getLocalHost().getHostName());
|
|
||||||
|
|
||||||
permissionedNode.verify(net.awaitPeerCount(2));
|
|
||||||
permissionedNode.verify(connectionIsForbidden(forbiddenNode));
|
|
||||||
permissionedNode.verify(connectionIsForbidden(forbiddenDnsEnodeURL));
|
|
||||||
permissionedNode.execute(allowNode(forbiddenDnsEnodeURL));
|
|
||||||
permissionedNode.verify(connectionIsAllowed(forbiddenDnsEnodeURL));
|
|
||||||
permissionedNode.verify(admin.addPeer(forbiddenNode));
|
|
||||||
permissionedNode.verify(net.awaitPeerCount(3));
|
|
||||||
permissionedNode.execute(forbidNode(forbiddenEnodeURL));
|
|
||||||
}
|
|
||||||
|
|
||||||
private EnodeURL getForbiddenEnodeURL() {
|
|
||||||
return EnodeURLImpl.fromURI(((RunnableNode) forbiddenNode).enodeUrl());
|
|
||||||
}
|
|
||||||
|
|
||||||
private EnodeURL buildDnsEnodeUrl(final EnodeURL forbiddenEnodeURL) {
|
|
||||||
return EnodeURLImpl.builder()
|
|
||||||
.configureFromEnode(forbiddenEnodeURL)
|
|
||||||
.ipAddress("localhost", enodeDnsConfiguration)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.tests.acceptance.permissioning;
|
|
||||||
|
|
||||||
import static java.util.stream.Collectors.toList;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.Node;
|
|
||||||
import org.hyperledger.besu.tests.acceptance.dsl.node.RunnableNode;
|
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Disabled;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
@Disabled("flaky test #7155")
|
|
||||||
public class NodesSmartContractPermissioningStaticNodesAcceptanceTest
|
|
||||||
extends NodeSmartContractPermissioningAcceptanceTestBase {
|
|
||||||
|
|
||||||
private Node miner;
|
|
||||||
private Node permissionedNode;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void setUp() {
|
|
||||||
miner = miner("miner");
|
|
||||||
permissionedCluster.start(miner);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onlyTrustStaticNodesWhileOutOfSync() {
|
|
||||||
// wait for some blocks so the permissioned node has some syncing to do
|
|
||||||
waitForBlockHeight(miner, 25);
|
|
||||||
stopMining(miner);
|
|
||||||
|
|
||||||
// start permissioned node with miner node in the static nodes list
|
|
||||||
permissionedNode = permissionedNodeWithStaticNodes(Arrays.asList(miner));
|
|
||||||
permissionedCluster.addNode(permissionedNode);
|
|
||||||
|
|
||||||
// as soon as we start the node should connect to static nodes
|
|
||||||
permissionedNode.verify(net.awaitPeerCount(1));
|
|
||||||
waitForBlockHeight(permissionedNode, 25);
|
|
||||||
|
|
||||||
// after syncing up with the network the node won't trust static nodes anymore
|
|
||||||
permissionedNode.verify(net.awaitPeerCount(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void stopMining(final Node node) {
|
|
||||||
node.execute(minerTransactions.minerStop());
|
|
||||||
node.verify(eth.miningStatus(false));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Node permissionedNodeWithStaticNodes(final List<Node> staticNodes) {
|
|
||||||
return permissionedNodeBuilder
|
|
||||||
.name("node-with-static-nodes")
|
|
||||||
.genesisFile(GENESIS_FILE)
|
|
||||||
.nodesContractEnabled(CONTRACT_ADDRESS)
|
|
||||||
.staticNodes(mapNodesToEnodeURLs(staticNodes))
|
|
||||||
.disableMining()
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
private List<String> mapNodesToEnodeURLs(final List<Node> staticNodes) {
|
|
||||||
return staticNodes.stream()
|
|
||||||
.map(node -> (RunnableNode) node)
|
|
||||||
.map(RunnableNode::enodeUrl)
|
|
||||||
.map(URI::toASCIIString)
|
|
||||||
.collect(toList());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,286 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.ethereum.permissioning;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|
||||||
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryBlockchain;
|
|
||||||
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive;
|
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.config.GenesisConfig;
|
|
||||||
import org.hyperledger.besu.config.JsonUtil;
|
|
||||||
import org.hyperledger.besu.datatypes.Address;
|
|
||||||
import org.hyperledger.besu.ethereum.chain.GenesisState;
|
|
||||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
|
||||||
import org.hyperledger.besu.ethereum.core.MiningConfiguration;
|
|
||||||
import org.hyperledger.besu.ethereum.core.ProtocolScheduleFixture;
|
|
||||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
|
||||||
import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl;
|
|
||||||
import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
|
|
||||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
|
|
||||||
import org.hyperledger.besu.metrics.BesuMetricCategory;
|
|
||||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
|
||||||
import org.hyperledger.besu.plugin.services.metrics.Counter;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
|
||||||
import com.google.common.io.Resources;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
|
||||||
public class NodeSmartContractPermissioningControllerTest {
|
|
||||||
@Mock private MetricsSystem metricsSystem;
|
|
||||||
@Mock private Counter checkCounter;
|
|
||||||
@Mock private Counter checkPermittedCounter;
|
|
||||||
@Mock private Counter checkUnpermittedCounter;
|
|
||||||
|
|
||||||
private NodeSmartContractPermissioningController setupController(
|
|
||||||
final String resourceName, final String contractAddressString) throws IOException {
|
|
||||||
final ProtocolSchedule protocolSchedule = ProtocolScheduleFixture.MAINNET;
|
|
||||||
|
|
||||||
final String emptyContractFile =
|
|
||||||
Resources.toString(this.getClass().getResource(resourceName), UTF_8);
|
|
||||||
|
|
||||||
final ObjectNode jsonData = JsonUtil.objectNodeFromString(emptyContractFile, true);
|
|
||||||
final GenesisState genesisState =
|
|
||||||
GenesisState.fromConfig(GenesisConfig.fromConfig(jsonData), protocolSchedule);
|
|
||||||
|
|
||||||
final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock());
|
|
||||||
final WorldStateArchive worldArchive = createInMemoryWorldStateArchive();
|
|
||||||
|
|
||||||
genesisState.writeStateTo(worldArchive.getWorldState());
|
|
||||||
|
|
||||||
final TransactionSimulator ts =
|
|
||||||
new TransactionSimulator(
|
|
||||||
blockchain, worldArchive, protocolSchedule, MiningConfiguration.newDefault(), 0L);
|
|
||||||
final Address contractAddress = Address.fromHexString(contractAddressString);
|
|
||||||
|
|
||||||
when(metricsSystem.createCounter(
|
|
||||||
BesuMetricCategory.PERMISSIONING,
|
|
||||||
"node_smart_contract_check_count",
|
|
||||||
"Number of times the node smart contract permissioning provider has been checked"))
|
|
||||||
.thenReturn(checkCounter);
|
|
||||||
|
|
||||||
when(metricsSystem.createCounter(
|
|
||||||
BesuMetricCategory.PERMISSIONING,
|
|
||||||
"node_smart_contract_check_count_permitted",
|
|
||||||
"Number of times the node smart contract permissioning provider has been checked and returned permitted"))
|
|
||||||
.thenReturn(checkPermittedCounter);
|
|
||||||
|
|
||||||
when(metricsSystem.createCounter(
|
|
||||||
BesuMetricCategory.PERMISSIONING,
|
|
||||||
"node_smart_contract_check_count_unpermitted",
|
|
||||||
"Number of times the node smart contract permissioning provider has been checked and returned unpermitted"))
|
|
||||||
.thenReturn(checkUnpermittedCounter);
|
|
||||||
|
|
||||||
return new NodeSmartContractPermissioningController(contractAddress, ts, metricsSystem);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifyCountersUntouched() {
|
|
||||||
verify(checkCounter, times(0)).inc();
|
|
||||||
verify(checkPermittedCounter, times(0)).inc();
|
|
||||||
verify(checkUnpermittedCounter, times(0)).inc();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifyCountersPermitted() {
|
|
||||||
verify(checkCounter, times(1)).inc();
|
|
||||||
verify(checkPermittedCounter, times(1)).inc();
|
|
||||||
verify(checkUnpermittedCounter, times(0)).inc();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifyCountersUnpermitted() {
|
|
||||||
verify(checkCounter, times(1)).inc();
|
|
||||||
verify(checkPermittedCounter, times(0)).inc();
|
|
||||||
verify(checkUnpermittedCounter, times(1)).inc();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifyCountersFailedCheck() {
|
|
||||||
verify(checkCounter, times(1)).inc();
|
|
||||||
verify(checkPermittedCounter, times(0)).inc();
|
|
||||||
verify(checkUnpermittedCounter, times(0)).inc();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIpv4Included() throws IOException {
|
|
||||||
final NodeSmartContractPermissioningController controller =
|
|
||||||
setupController(
|
|
||||||
"/NodeSmartContractPermissioningControllerTest/preseededSmartPermissioning.json",
|
|
||||||
"0x0000000000000000000000000000000000001234");
|
|
||||||
|
|
||||||
verifyCountersUntouched();
|
|
||||||
|
|
||||||
assertThat(
|
|
||||||
controller.isConnectionPermitted(
|
|
||||||
EnodeURLImpl.fromString(
|
|
||||||
"enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.1:30303"),
|
|
||||||
EnodeURLImpl.fromString(
|
|
||||||
"enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.1:30304")))
|
|
||||||
.isTrue();
|
|
||||||
|
|
||||||
verifyCountersPermitted();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIpv4DestinationMissing() throws IOException {
|
|
||||||
final NodeSmartContractPermissioningController controller =
|
|
||||||
setupController(
|
|
||||||
"/NodeSmartContractPermissioningControllerTest/preseededSmartPermissioning.json",
|
|
||||||
"0x0000000000000000000000000000000000001234");
|
|
||||||
|
|
||||||
verifyCountersUntouched();
|
|
||||||
|
|
||||||
assertThat(
|
|
||||||
controller.isConnectionPermitted(
|
|
||||||
EnodeURLImpl.fromString(
|
|
||||||
"enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.1:30303"),
|
|
||||||
EnodeURLImpl.fromString(
|
|
||||||
"enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.1:30305")))
|
|
||||||
.isFalse();
|
|
||||||
|
|
||||||
verifyCountersUnpermitted();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIpv4SourceMissing() throws IOException {
|
|
||||||
final NodeSmartContractPermissioningController controller =
|
|
||||||
setupController(
|
|
||||||
"/NodeSmartContractPermissioningControllerTest/preseededSmartPermissioning.json",
|
|
||||||
"0x0000000000000000000000000000000000001234");
|
|
||||||
|
|
||||||
verifyCountersUntouched();
|
|
||||||
|
|
||||||
assertThat(
|
|
||||||
controller.isConnectionPermitted(
|
|
||||||
EnodeURLImpl.fromString(
|
|
||||||
"enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.1:30302"),
|
|
||||||
EnodeURLImpl.fromString(
|
|
||||||
"enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@192.168.0.1:30304")))
|
|
||||||
.isFalse();
|
|
||||||
|
|
||||||
verifyCountersUnpermitted();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIpv6Included() throws IOException {
|
|
||||||
final NodeSmartContractPermissioningController controller =
|
|
||||||
setupController(
|
|
||||||
"/NodeSmartContractPermissioningControllerTest/preseededSmartPermissioning.json",
|
|
||||||
"0x0000000000000000000000000000000000001234");
|
|
||||||
|
|
||||||
verifyCountersUntouched();
|
|
||||||
|
|
||||||
assertThat(
|
|
||||||
controller.isConnectionPermitted(
|
|
||||||
EnodeURLImpl.fromString(
|
|
||||||
"enode://1234000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab61@[1:2:3:4:5:6:7:8]:30303"),
|
|
||||||
EnodeURLImpl.fromString(
|
|
||||||
"enode://1234000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab62@[1:2:3:4:5:6:7:8]:30304")))
|
|
||||||
.isTrue();
|
|
||||||
|
|
||||||
verifyCountersPermitted();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIpv6SourceMissing() throws IOException {
|
|
||||||
final NodeSmartContractPermissioningController controller =
|
|
||||||
setupController(
|
|
||||||
"/NodeSmartContractPermissioningControllerTest/preseededSmartPermissioning.json",
|
|
||||||
"0x0000000000000000000000000000000000001234");
|
|
||||||
|
|
||||||
verifyCountersUntouched();
|
|
||||||
|
|
||||||
assertThat(
|
|
||||||
controller.isConnectionPermitted(
|
|
||||||
EnodeURLImpl.fromString(
|
|
||||||
"enode://1234000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab63@[1:2:3:4:5:6:7:8]:30303"),
|
|
||||||
EnodeURLImpl.fromString(
|
|
||||||
"enode://1234000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab62@[1:2:3:4:5:6:7:8]:30304")))
|
|
||||||
.isFalse();
|
|
||||||
|
|
||||||
verifyCountersUnpermitted();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIpv6DestinationMissing() throws IOException {
|
|
||||||
final NodeSmartContractPermissioningController controller =
|
|
||||||
setupController(
|
|
||||||
"/NodeSmartContractPermissioningControllerTest/preseededSmartPermissioning.json",
|
|
||||||
"0x0000000000000000000000000000000000001234");
|
|
||||||
|
|
||||||
verifyCountersUntouched();
|
|
||||||
|
|
||||||
assertThat(
|
|
||||||
controller.isConnectionPermitted(
|
|
||||||
EnodeURLImpl.fromString(
|
|
||||||
"enode://1234000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab61@[1:2:3:4:5:6:7:8]:30303"),
|
|
||||||
EnodeURLImpl.fromString(
|
|
||||||
"enode://1234000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab63@[1:2:3:4:5:6:7:8]:30304")))
|
|
||||||
.isFalse();
|
|
||||||
|
|
||||||
verifyCountersUnpermitted();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPermissioningContractMissing() throws IOException {
|
|
||||||
final NodeSmartContractPermissioningController controller =
|
|
||||||
setupController(
|
|
||||||
"/NodeSmartContractPermissioningControllerTest/noSmartPermissioning.json",
|
|
||||||
"0x0000000000000000000000000000000000001234");
|
|
||||||
|
|
||||||
verifyCountersUntouched();
|
|
||||||
|
|
||||||
assertThatThrownBy(
|
|
||||||
() ->
|
|
||||||
controller.isConnectionPermitted(
|
|
||||||
EnodeURLImpl.fromString(
|
|
||||||
"enode://1234000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab61@[1:2:3:4:5:6:7:8]:30303"),
|
|
||||||
EnodeURLImpl.fromString(
|
|
||||||
"enode://1234000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab63@[1:2:3:4:5:6:7:8]:30304")))
|
|
||||||
.isInstanceOf(IllegalStateException.class)
|
|
||||||
.hasMessage("Permissioning contract does not exist");
|
|
||||||
|
|
||||||
verifyCountersFailedCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPermissioningContractCorrupt() throws IOException {
|
|
||||||
final NodeSmartContractPermissioningController controller =
|
|
||||||
setupController(
|
|
||||||
"/NodeSmartContractPermissioningControllerTest/corruptSmartPermissioning.json",
|
|
||||||
"0x0000000000000000000000000000000000001234");
|
|
||||||
|
|
||||||
verifyCountersUntouched();
|
|
||||||
|
|
||||||
assertThatThrownBy(
|
|
||||||
() ->
|
|
||||||
controller.isConnectionPermitted(
|
|
||||||
EnodeURLImpl.fromString(
|
|
||||||
"enode://1234000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab61@[1:2:3:4:5:6:7:8]:30303"),
|
|
||||||
EnodeURLImpl.fromString(
|
|
||||||
"enode://1234000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab63@[1:2:3:4:5:6:7:8]:30304")))
|
|
||||||
.isInstanceOf(IllegalStateException.class)
|
|
||||||
.hasMessage("Permissioning transaction failed when processing");
|
|
||||||
|
|
||||||
verifyCountersFailedCheck();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,226 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.ethereum.permissioning;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.datatypes.Address;
|
|
||||||
import org.hyperledger.besu.ethereum.core.BlockDataGenerator;
|
|
||||||
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
|
|
||||||
import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl;
|
|
||||||
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
|
|
||||||
import org.hyperledger.besu.ethereum.transaction.CallParameter;
|
|
||||||
import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason;
|
|
||||||
import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
|
|
||||||
import org.hyperledger.besu.ethereum.transaction.TransactionSimulatorResult;
|
|
||||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem;
|
|
||||||
import org.hyperledger.besu.plugin.data.EnodeURL;
|
|
||||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
|
||||||
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import org.apache.tuweni.bytes.Bytes;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
public class NodeSmartContractV2PermissioningControllerTest {
|
|
||||||
|
|
||||||
/*
|
|
||||||
Payloads created using Remix to call method connectionAllowed(string, string, uint16)
|
|
||||||
*/
|
|
||||||
private static final Bytes SOURCE_ENODE_EXPECTED_PAYLOAD_IP =
|
|
||||||
Bytes.fromHexString(
|
|
||||||
"0x45a59e5b00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000765f0000000000000000000000000000000000000000000000000000000000000080666362653966383332313834383762336330623530383738313933383830653663323563666438363730386330613062663063613931663063653633333734366138393266653234306166613562396138383062386263613438653861323237303465663933376664646132643763633633653464343165643162343137616500000000000000000000000000000000000000000000000000000000000000093132372e302e302e310000000000000000000000000000000000000000000000");
|
|
||||||
private static final Bytes DESTINATION_ENODE_EXPECTED_PAYLOAD_IP =
|
|
||||||
Bytes.fromHexString(
|
|
||||||
"0x45a59e5b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000009dd40000000000000000000000000000000000000000000000000000000000000080333534386338376239393230666631366161346264636630316338356632353131376132396165313537346437353962616434386363393436336438653966376333633164316539666230643238653733383938393531663930653032373134616262373730666436643232653930333731383832613435363538383030653900000000000000000000000000000000000000000000000000000000000000093132372e302e302e310000000000000000000000000000000000000000000000");
|
|
||||||
|
|
||||||
private static final EnodeURL SOURCE_ENODE_IPV4 =
|
|
||||||
EnodeURLImpl.fromString(
|
|
||||||
"enode://fcbe9f83218487b3c0b50878193880e6c25cfd86708c0a0bf0ca91f0ce633746a892fe240afa5b9a880b8bca48e8a22704ef937fdda2d7cc63e4d41ed1b417ae@127.0.0.1:30303");
|
|
||||||
private static final EnodeURL DESTINATION_ENODE_IPV4 =
|
|
||||||
EnodeURLImpl.fromString(
|
|
||||||
"enode://3548c87b9920ff16aa4bdcf01c85f25117a29ae1574d759bad48cc9463d8e9f7c3c1d1e9fb0d28e73898951f90e02714abb770fd6d22e90371882a45658800e9@127.0.0.1:40404");
|
|
||||||
private static final EnodeURL SOURCE_ENODE_IPV6 =
|
|
||||||
EnodeURLImpl.fromString(
|
|
||||||
"enode://fcbe9f83218487b3c0b50878193880e6c25cfd86708c0a0bf0ca91f0ce633746a892fe240afa5b9a880b8bca48e8a22704ef937fdda2d7cc63e4d41ed1b417ae@[::ffff:7f00:0001]:30303");
|
|
||||||
private static final EnodeURL DESTINATION_ENODE_IPV6 =
|
|
||||||
EnodeURLImpl.fromString(
|
|
||||||
"enode://3548c87b9920ff16aa4bdcf01c85f25117a29ae1574d759bad48cc9463d8e9f7c3c1d1e9fb0d28e73898951f90e02714abb770fd6d22e90371882a45658800e9@[::ffff:7f00:0001]:40404");
|
|
||||||
|
|
||||||
private final BlockDataGenerator blockDataGenerator = new BlockDataGenerator();
|
|
||||||
private final Address contractAddress = Address.ZERO;
|
|
||||||
private final TransactionSimulator transactionSimulator = mock(TransactionSimulator.class);
|
|
||||||
private final MetricsSystem metricsSystem = new NoOpMetricsSystem();
|
|
||||||
|
|
||||||
private NodeSmartContractV2PermissioningController permissioningController;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void beforeEach() {
|
|
||||||
permissioningController =
|
|
||||||
new NodeSmartContractV2PermissioningController(
|
|
||||||
contractAddress, transactionSimulator, metricsSystem);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void nonExpectedCallOutputThrowsIllegalState() {
|
|
||||||
final TransactionSimulatorResult txSimulatorResult =
|
|
||||||
transactionSimulatorResult(Bytes.random(10), ValidationResult.valid());
|
|
||||||
|
|
||||||
when(transactionSimulator.processAtHead(eq(callParams(SOURCE_ENODE_EXPECTED_PAYLOAD_IP))))
|
|
||||||
.thenReturn(Optional.of(txSimulatorResult));
|
|
||||||
|
|
||||||
assertThatIllegalStateException()
|
|
||||||
.isThrownBy(
|
|
||||||
() ->
|
|
||||||
permissioningController.checkSmartContractRules(
|
|
||||||
SOURCE_ENODE_IPV4, DESTINATION_ENODE_IPV4));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void falseCallOutputReturnsNotPermitted() {
|
|
||||||
final TransactionSimulatorResult txSimulatorResult =
|
|
||||||
transactionSimulatorResult(
|
|
||||||
NodeSmartContractV2PermissioningController.FALSE_RESPONSE, ValidationResult.valid());
|
|
||||||
|
|
||||||
when(transactionSimulator.processAtHead(eq(callParams(SOURCE_ENODE_EXPECTED_PAYLOAD_IP))))
|
|
||||||
.thenReturn(Optional.of(txSimulatorResult));
|
|
||||||
|
|
||||||
boolean isPermitted =
|
|
||||||
permissioningController.checkSmartContractRules(SOURCE_ENODE_IPV4, DESTINATION_ENODE_IPV4);
|
|
||||||
assertThat(isPermitted).isFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void failedCallOutputReturnsNotPermitted() {
|
|
||||||
final TransactionSimulatorResult txSimulatorResult =
|
|
||||||
transactionSimulatorResult(
|
|
||||||
NodeSmartContractV2PermissioningController.TRUE_RESPONSE,
|
|
||||||
ValidationResult.invalid(TransactionInvalidReason.INTERNAL_ERROR));
|
|
||||||
|
|
||||||
when(transactionSimulator.processAtHead(eq(callParams(SOURCE_ENODE_EXPECTED_PAYLOAD_IP))))
|
|
||||||
.thenReturn(Optional.of(txSimulatorResult));
|
|
||||||
|
|
||||||
boolean isPermitted =
|
|
||||||
permissioningController.checkSmartContractRules(SOURCE_ENODE_IPV4, DESTINATION_ENODE_IPV4);
|
|
||||||
assertThat(isPermitted).isFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void expectedPayloadWhenCheckingPermissioningWithIPV4() {
|
|
||||||
final TransactionSimulatorResult txSimulatorResult =
|
|
||||||
transactionSimulatorResult(
|
|
||||||
NodeSmartContractV2PermissioningController.TRUE_RESPONSE, ValidationResult.valid());
|
|
||||||
|
|
||||||
when(transactionSimulator.processAtHead(eq(callParams(SOURCE_ENODE_EXPECTED_PAYLOAD_IP))))
|
|
||||||
.thenReturn(Optional.of(txSimulatorResult));
|
|
||||||
when(transactionSimulator.processAtHead(eq(callParams(DESTINATION_ENODE_EXPECTED_PAYLOAD_IP))))
|
|
||||||
.thenReturn(Optional.of(txSimulatorResult));
|
|
||||||
|
|
||||||
boolean isPermitted =
|
|
||||||
permissioningController.checkSmartContractRules(SOURCE_ENODE_IPV4, DESTINATION_ENODE_IPV4);
|
|
||||||
assertThat(isPermitted).isTrue();
|
|
||||||
|
|
||||||
verify(transactionSimulator, times(2)).processAtHead(any());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void expectedPayloadWhenCheckingPermissioningWithIPV6() {
|
|
||||||
final TransactionSimulatorResult txSimulatorResult =
|
|
||||||
transactionSimulatorResult(
|
|
||||||
NodeSmartContractV2PermissioningController.TRUE_RESPONSE, ValidationResult.valid());
|
|
||||||
|
|
||||||
when(transactionSimulator.processAtHead(eq(callParams(SOURCE_ENODE_EXPECTED_PAYLOAD_IP))))
|
|
||||||
.thenReturn(Optional.of(txSimulatorResult));
|
|
||||||
when(transactionSimulator.processAtHead(eq(callParams(DESTINATION_ENODE_EXPECTED_PAYLOAD_IP))))
|
|
||||||
.thenReturn(Optional.of(txSimulatorResult));
|
|
||||||
|
|
||||||
boolean isPermitted =
|
|
||||||
permissioningController.checkSmartContractRules(SOURCE_ENODE_IPV6, DESTINATION_ENODE_IPV6);
|
|
||||||
assertThat(isPermitted).isTrue();
|
|
||||||
|
|
||||||
verify(transactionSimulator, times(2)).processAtHead(any());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void expectedPayloadWhenCheckingPermissioningWithAlternateDNS()
|
|
||||||
throws UnknownHostException {
|
|
||||||
final TransactionSimulatorResult txSimulatorResultFalse =
|
|
||||||
transactionSimulatorResult(
|
|
||||||
NodeSmartContractV2PermissioningController.FALSE_RESPONSE, ValidationResult.valid());
|
|
||||||
|
|
||||||
final TransactionSimulatorResult txSimulatorResultTrue =
|
|
||||||
transactionSimulatorResult(
|
|
||||||
NodeSmartContractV2PermissioningController.TRUE_RESPONSE, ValidationResult.valid());
|
|
||||||
|
|
||||||
when(transactionSimulator.processAtHead(eq(callParams(SOURCE_ENODE_EXPECTED_PAYLOAD_IP))))
|
|
||||||
.thenReturn(Optional.of(txSimulatorResultFalse));
|
|
||||||
when(transactionSimulator.processAtHead(eq(callParams(DESTINATION_ENODE_EXPECTED_PAYLOAD_IP))))
|
|
||||||
.thenReturn(Optional.of(txSimulatorResultFalse));
|
|
||||||
|
|
||||||
var sourcePayload = sourceEnodeExpectedPayloadDns();
|
|
||||||
when(transactionSimulator.processAtHead(eq(callParams(Bytes.fromHexString(sourcePayload)))))
|
|
||||||
.thenReturn(Optional.of(txSimulatorResultTrue));
|
|
||||||
var destinationPayload = destinationEnodeExpectedPayloadDns();
|
|
||||||
when(transactionSimulator.processAtHead(
|
|
||||||
eq(callParams(Bytes.fromHexString(destinationPayload)))))
|
|
||||||
.thenReturn(Optional.of(txSimulatorResultTrue));
|
|
||||||
|
|
||||||
boolean isPermitted =
|
|
||||||
permissioningController.checkSmartContractRules(SOURCE_ENODE_IPV4, DESTINATION_ENODE_IPV4);
|
|
||||||
assertThat(isPermitted).isTrue();
|
|
||||||
|
|
||||||
verify(transactionSimulator, times(4)).processAtHead(any());
|
|
||||||
}
|
|
||||||
|
|
||||||
private CallParameter callParams(final Bytes payload) {
|
|
||||||
return new CallParameter(null, contractAddress, -1, null, null, payload);
|
|
||||||
}
|
|
||||||
|
|
||||||
private TransactionSimulatorResult transactionSimulatorResult(
|
|
||||||
final Bytes output, final ValidationResult<TransactionInvalidReason> validationResult) {
|
|
||||||
return new TransactionSimulatorResult(
|
|
||||||
blockDataGenerator.transaction(),
|
|
||||||
TransactionProcessingResult.successful(
|
|
||||||
blockDataGenerator.logs(1, 1), 0L, 0L, output, validationResult));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note - don't use FunctionEncoder.makeFunction here otherwise we're not really testing anything!
|
|
||||||
private String sourceEnodeExpectedPayloadDns() throws UnknownHostException {
|
|
||||||
var hostname = InetAddress.getLocalHost().getHostName();
|
|
||||||
return "0x45a59e5b00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000765f0000000000000000000000000000000000000000000000000000000000000080666362653966383332313834383762336330623530383738313933383830653663323563666438363730386330613062663063613931663063653633333734366138393266653234306166613562396138383062386263613438653861323237303465663933376664646132643763633633653464343165643162343137616500000000000000000000000000000000000000000000000000000000000000"
|
|
||||||
+ Bytes.of(hostname.length()).toUnprefixedHexString()
|
|
||||||
+ Bytes.of(hostname.getBytes(UTF_8)).toUnprefixedHexString()
|
|
||||||
+ "00".repeat(32 - hostname.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
private String destinationEnodeExpectedPayloadDns() throws UnknownHostException {
|
|
||||||
var hostname = InetAddress.getLocalHost().getHostName();
|
|
||||||
return "0x45a59e5b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000009dd40000000000000000000000000000000000000000000000000000000000000080333534386338376239393230666631366161346264636630316338356632353131376132396165313537346437353962616434386363393436336438653966376333633164316539666230643238653733383938393531663930653032373134616262373730666436643232653930333731383832613435363538383030653900000000000000000000000000000000000000000000000000000000000000"
|
|
||||||
+ Bytes.of(hostname.length()).toUnprefixedHexString()
|
|
||||||
+ Bytes.of(hostname.getBytes(UTF_8)).toUnprefixedHexString()
|
|
||||||
+ "00".repeat(32 - hostname.length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,197 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright ConsenSys AG.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
package org.hyperledger.besu.ethereum.permissioning;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|
||||||
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryBlockchain;
|
|
||||||
import static org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider.createInMemoryWorldStateArchive;
|
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import org.hyperledger.besu.config.GenesisConfig;
|
|
||||||
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
|
|
||||||
import org.hyperledger.besu.datatypes.Address;
|
|
||||||
import org.hyperledger.besu.datatypes.TransactionType;
|
|
||||||
import org.hyperledger.besu.datatypes.Wei;
|
|
||||||
import org.hyperledger.besu.ethereum.chain.GenesisState;
|
|
||||||
import org.hyperledger.besu.ethereum.chain.MutableBlockchain;
|
|
||||||
import org.hyperledger.besu.ethereum.core.MiningConfiguration;
|
|
||||||
import org.hyperledger.besu.ethereum.core.ProtocolScheduleFixture;
|
|
||||||
import org.hyperledger.besu.ethereum.core.Transaction;
|
|
||||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
|
|
||||||
import org.hyperledger.besu.ethereum.transaction.TransactionSimulator;
|
|
||||||
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
|
|
||||||
import org.hyperledger.besu.metrics.BesuMetricCategory;
|
|
||||||
import org.hyperledger.besu.plugin.services.MetricsSystem;
|
|
||||||
import org.hyperledger.besu.plugin.services.metrics.Counter;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
import org.apache.tuweni.bytes.Bytes;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
|
||||||
public class TransactionSmartContractPermissioningControllerTest {
|
|
||||||
@Mock private MetricsSystem metricsSystem;
|
|
||||||
@Mock private Counter checkCounter;
|
|
||||||
@Mock private Counter checkPermittedCounter;
|
|
||||||
@Mock private Counter checkUnpermittedCounter;
|
|
||||||
|
|
||||||
private TransactionSmartContractPermissioningController setupController(
|
|
||||||
final String resourceName, final String contractAddressString) {
|
|
||||||
final ProtocolSchedule protocolSchedule = ProtocolScheduleFixture.MAINNET;
|
|
||||||
|
|
||||||
final GenesisState genesisState =
|
|
||||||
GenesisState.fromConfig(
|
|
||||||
GenesisConfig.fromSource(this.getClass().getResource(resourceName)), protocolSchedule);
|
|
||||||
|
|
||||||
final MutableBlockchain blockchain = createInMemoryBlockchain(genesisState.getBlock());
|
|
||||||
final WorldStateArchive worldArchive = createInMemoryWorldStateArchive();
|
|
||||||
|
|
||||||
genesisState.writeStateTo(worldArchive.getWorldState());
|
|
||||||
|
|
||||||
final TransactionSimulator ts =
|
|
||||||
new TransactionSimulator(
|
|
||||||
blockchain, worldArchive, protocolSchedule, MiningConfiguration.newDefault(), 0L);
|
|
||||||
final Address contractAddress = Address.fromHexString(contractAddressString);
|
|
||||||
|
|
||||||
when(metricsSystem.createCounter(
|
|
||||||
BesuMetricCategory.PERMISSIONING,
|
|
||||||
"transaction_smart_contract_check_count",
|
|
||||||
"Number of times the transaction smart contract permissioning provider has been checked"))
|
|
||||||
.thenReturn(checkCounter);
|
|
||||||
|
|
||||||
when(metricsSystem.createCounter(
|
|
||||||
BesuMetricCategory.PERMISSIONING,
|
|
||||||
"transaction_smart_contract_check_count_permitted",
|
|
||||||
"Number of times the transaction smart contract permissioning provider has been checked and returned permitted"))
|
|
||||||
.thenReturn(checkPermittedCounter);
|
|
||||||
|
|
||||||
when(metricsSystem.createCounter(
|
|
||||||
BesuMetricCategory.PERMISSIONING,
|
|
||||||
"transaction_smart_contract_check_count_unpermitted",
|
|
||||||
"Number of times the transaction smart contract permissioning provider has been checked and returned unpermitted"))
|
|
||||||
.thenReturn(checkUnpermittedCounter);
|
|
||||||
|
|
||||||
return new TransactionSmartContractPermissioningController(contractAddress, ts, metricsSystem);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Transaction transactionForAccount(final Address address) {
|
|
||||||
return Transaction.builder()
|
|
||||||
.type(TransactionType.FRONTIER)
|
|
||||||
.sender(address)
|
|
||||||
.value(Wei.ZERO)
|
|
||||||
.gasPrice(Wei.ZERO)
|
|
||||||
.gasLimit(0)
|
|
||||||
.payload(Bytes.fromHexString("0x1234"))
|
|
||||||
.nonce(1)
|
|
||||||
.signature(
|
|
||||||
SignatureAlgorithmFactory.getInstance()
|
|
||||||
.createSignature(BigInteger.ONE, BigInteger.TEN, (byte) 1))
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifyCountersUntouched() {
|
|
||||||
verify(checkCounter, times(0)).inc();
|
|
||||||
verify(checkPermittedCounter, times(0)).inc();
|
|
||||||
verify(checkUnpermittedCounter, times(0)).inc();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifyCountersPermitted() {
|
|
||||||
verify(checkCounter, times(1)).inc();
|
|
||||||
verify(checkPermittedCounter, times(1)).inc();
|
|
||||||
verify(checkUnpermittedCounter, times(0)).inc();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifyCountersUnpermitted() {
|
|
||||||
verify(checkCounter, times(1)).inc();
|
|
||||||
verify(checkPermittedCounter, times(0)).inc();
|
|
||||||
verify(checkUnpermittedCounter, times(1)).inc();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifyCountersFailedCheck() {
|
|
||||||
verify(checkCounter, times(1)).inc();
|
|
||||||
verify(checkPermittedCounter, times(0)).inc();
|
|
||||||
verify(checkUnpermittedCounter, times(0)).inc();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAccountIncluded() throws IOException {
|
|
||||||
final TransactionSmartContractPermissioningController controller =
|
|
||||||
setupController(
|
|
||||||
"/TransactionSmartContractPermissioningControllerTest/preseededSmartPermissioning.json",
|
|
||||||
"0x0000000000000000000000000000000000001234");
|
|
||||||
|
|
||||||
verifyCountersUntouched();
|
|
||||||
|
|
||||||
assertThat(controller.isPermitted(transactionForAccount(Address.fromHexString("0x1"))))
|
|
||||||
.isTrue();
|
|
||||||
|
|
||||||
verifyCountersPermitted();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAccountNotIncluded() throws IOException {
|
|
||||||
final TransactionSmartContractPermissioningController controller =
|
|
||||||
setupController(
|
|
||||||
"/TransactionSmartContractPermissioningControllerTest/preseededSmartPermissioning.json",
|
|
||||||
"0x0000000000000000000000000000000000001234");
|
|
||||||
|
|
||||||
verifyCountersUntouched();
|
|
||||||
|
|
||||||
assertThat(controller.isPermitted(transactionForAccount(Address.fromHexString("0x2"))))
|
|
||||||
.isFalse();
|
|
||||||
|
|
||||||
verifyCountersUnpermitted();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPermissioningContractMissing() throws IOException {
|
|
||||||
final TransactionSmartContractPermissioningController controller =
|
|
||||||
setupController(
|
|
||||||
"/TransactionSmartContractPermissioningControllerTest/noSmartPermissioning.json",
|
|
||||||
"0x0000000000000000000000000000000000001234");
|
|
||||||
|
|
||||||
verifyCountersUntouched();
|
|
||||||
|
|
||||||
assertThat(controller.isPermitted(transactionForAccount(Address.fromHexString("0x1"))))
|
|
||||||
.isTrue();
|
|
||||||
|
|
||||||
verifyCountersPermitted();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPermissioningContractCorrupt() throws IOException {
|
|
||||||
final TransactionSmartContractPermissioningController controller =
|
|
||||||
setupController(
|
|
||||||
"/TransactionSmartContractPermissioningControllerTest/corruptSmartPermissioning.json",
|
|
||||||
"0x0000000000000000000000000000000000001234");
|
|
||||||
|
|
||||||
verifyCountersUntouched();
|
|
||||||
|
|
||||||
assertThatThrownBy(
|
|
||||||
() -> controller.isPermitted(transactionForAccount(Address.fromHexString("0x1"))))
|
|
||||||
.isInstanceOf(IllegalStateException.class)
|
|
||||||
.hasMessage("Transaction permissioning transaction failed when processing");
|
|
||||||
|
|
||||||
verifyCountersFailedCheck();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user