Privacy payload plugin (#2377)

* Hook up an empty plugin for future unrestricted privacy encryption

Skeleton implementation for PrivacyPayloadEncryptionProvider
Wire up unencrypted serialization for private transactions

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* wire up simple privacy plugin in acceptance tests

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* Pass the marker transaction through to plugin

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* Move getters/setters into consistent place

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* Rename plugin methods and config to be more generic

- remove protections around transaction.restriction
- the plugin is responsible for this
- make plugin more generic so could be used for restricted/unrestricted

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* Provide more meaningful error message

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* Fix up test naming to match impl naming

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* Rename UNRESTRICTED_PRIVACY to PLUGIN_PRIVACY

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* fix typo in PrivacyParmeters::toString

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* Fix exception messages to be PrivacyPlugin

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>

* Remove blockNumber from getPrivateTransactionFromPayload

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>
This commit is contained in:
Antony Denyer
2021-07-12 08:02:04 +01:00
committed by GitHub
parent 1c1470bcaa
commit ffc22522f8
55 changed files with 835 additions and 396 deletions

View File

@@ -2,6 +2,8 @@
dependencies {
implementation project(':plugin-api')
implementation project(':besu')
implementation project(':ethereum:core')
implementation project(':ethereum:rlp')
implementation 'com.google.auto.service:auto-service'
implementation 'info.picocli:picocli'
implementation 'org.apache.logging.log4j:log4j-api'

View File

@@ -18,10 +18,12 @@ package org.hyperledger.besu.plugins;
import org.hyperledger.besu.plugin.BesuContext;
import org.hyperledger.besu.plugin.BesuPlugin;
import org.hyperledger.besu.plugin.services.PermissioningService;
import org.hyperledger.besu.plugin.services.PicoCLIOptions;
import com.google.auto.service.AutoService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import picocli.CommandLine.Option;
@AutoService(BesuPlugin.class)
public class TestPermissioningPlugin implements BesuPlugin {
@@ -36,46 +38,54 @@ public class TestPermissioningPlugin implements BesuPlugin {
private final String charlieNode =
"ce7edc292d7b747fab2f23584bbafaffde5c8ff17cf689969614441e0527b90015ea9fee96aed6d9c0fc2fbe0bd1883dee223b3200246ff1e21976bdbc9a0fc8";
PermissioningService service;
@Override
public void register(final BesuContext context) {
PermissioningService service = context.getService(PermissioningService.class).get();
context.getService(PicoCLIOptions.class).get().addPicoCLIOptions("permissioning", this);
service = context.getService(PermissioningService.class).get();
}
service.registerNodePermissioningProvider(
(sourceEnode, destinationEnode) -> {
if (sourceEnode.toString().contains(bobNode)
|| destinationEnode.toString().contains(bobNode)) {
@Override
public void start() {
if (enabled) {
service.registerNodePermissioningProvider(
(sourceEnode, destinationEnode) -> {
if (sourceEnode.toString().contains(bobNode)
|| destinationEnode.toString().contains(bobNode)) {
boolean isBobTalkingToAlice =
sourceEnode.toString().contains(aliceNode)
|| destinationEnode.toString().contains(aliceNode);
if (isBobTalkingToAlice) {
LOG.info("BLOCK CONNECTION from {}, to {}", sourceEnode, destinationEnode);
} else {
LOG.info("ALLOW CONNECTION from {}, to {}", sourceEnode, destinationEnode);
boolean isBobTalkingToAlice =
sourceEnode.toString().contains(aliceNode)
|| destinationEnode.toString().contains(aliceNode);
if (isBobTalkingToAlice) {
LOG.info("BLOCK CONNECTION from {}, to {}", sourceEnode, destinationEnode);
} else {
LOG.info("ALLOW CONNECTION from {}, to {}", sourceEnode, destinationEnode);
}
return !isBobTalkingToAlice;
}
return true;
});
return !isBobTalkingToAlice;
}
return true;
});
service.registerNodeMessagePermissioningProvider(
(destinationEnode, code) -> {
if (destinationEnode.toString().contains(charlieNode) && transactionMessage(code)) {
LOG.info("BLOCK MESSAGE to {} code {}", destinationEnode, code);
return false;
}
return true;
});
service.registerNodeMessagePermissioningProvider(
(destinationEnode, code) -> {
if (destinationEnode.toString().contains(charlieNode) && transactionMessage(code)) {
LOG.info("BLOCK MESSAGE to {} code {}", destinationEnode, code);
return false;
}
return true;
});
}
}
private boolean transactionMessage(final int code) {
return code == 0x02 || code == 0x08 || code == 0x09 || code == 0x0a;
}
@Override
public void start() {}
@Override
public void stop() {}
@Option(names = "--plugin-permissioning-enabled")
boolean enabled = false;
}

View File

@@ -0,0 +1,84 @@
/*
* 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.plugins;
import static org.hyperledger.besu.ethereum.privacy.PrivateTransaction.readFrom;
import static org.hyperledger.besu.ethereum.privacy.PrivateTransaction.serialize;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput;
import org.hyperledger.besu.plugin.BesuContext;
import org.hyperledger.besu.plugin.BesuPlugin;
import org.hyperledger.besu.plugin.data.PrivateTransaction;
import org.hyperledger.besu.plugin.data.Transaction;
import org.hyperledger.besu.plugin.services.PicoCLIOptions;
import org.hyperledger.besu.plugin.services.PrivacyPluginService;
import org.hyperledger.besu.plugin.services.privacy.PrivacyPluginPayloadProvider;
import java.util.Optional;
import com.google.auto.service.AutoService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.tuweni.bytes.Bytes;
import picocli.CommandLine.Option;
@AutoService(BesuPlugin.class)
public class TestPrivacyServicePlugin implements BesuPlugin {
private static final Logger LOG = LogManager.getLogger();
private PrivacyPluginService service;
@Override
public void register(final BesuContext context) {
context.getService(PicoCLIOptions.class).get().addPicoCLIOptions("privacy-service", this);
service = context.getService(PrivacyPluginService.class).get();
service.setPayloadProvider(
new PrivacyPluginPayloadProvider() {
@Override
public Bytes generateMarkerPayload(
final PrivateTransaction privateTransaction, final String privacyUserId) {
return Bytes.wrap(Bytes.fromHexString(prefix), serialize(privateTransaction).encoded());
}
@Override
public Optional<PrivateTransaction> getPrivateTransactionFromPayload(
final Transaction transaction) {
final Bytes prefixBytes = Bytes.fromHexString(prefix);
if (transaction.getPayload().slice(0, prefixBytes.size()).equals(prefixBytes)) {
LOG.info("processing payload for" + prefix);
final BytesValueRLPInput bytesValueRLPInput =
new BytesValueRLPInput(
transaction.getPayload().slice(prefixBytes.size()).copy(), false);
return Optional.of(readFrom(bytesValueRLPInput));
} else {
LOG.info("Can not process payload for" + prefix);
return Optional.empty();
}
}
});
}
@Override
public void start() {}
@Override
public void stop() {}
@Option(names = "--plugin-privacy-service-encryption-prefix")
String prefix;
}