Return the plugin-apis to this repo (#1900)

* Return plugin-api to the main repo
* Spotless
* Migrate all external plugin-api references to the project in this repo
* Add licence header
* Update repo reference for publish, even if commented
* Use real configuration for publishing plugin-api

This was tested with the
`:plugins:publishMavenJavaPublicationToMavenLocal` task and checking the
local Maven repo to make sure it was using the correct paths

Signed-off-by: Edward Evans <edward.evans@consensys.net>

Signed-off-by: Adrian Sutton <adrian.sutton@consensys.net>
pull/2/head
Edward 5 years ago committed by GitHub
parent c691f488e2
commit 9601f44ac8
  1. 2
      acceptance-tests/build.gradle
  2. 3
      build.gradle
  3. 2
      consensus/common/build.gradle
  4. 2
      crypto/build.gradle
  5. 2
      ethereum/core/build.gradle
  6. 2
      ethereum/mock-p2p/build.gradle
  7. 2
      ethereum/rlp/build.gradle
  8. 2
      gradle/versions.gradle
  9. 3
      metrics/core/build.gradle
  10. 3
      metrics/rocksdb/build.gradle
  11. 2
      pantheon/build.gradle
  12. 78
      plugins/build.gradle
  13. 42
      plugins/src/main/java/tech/pegasys/pantheon/plugin/PantheonContext.java
  14. 53
      plugins/src/main/java/tech/pegasys/pantheon/plugin/PantheonPlugin.java
  15. 28
      plugins/src/main/java/tech/pegasys/pantheon/plugin/Unstable.java
  16. 19
      plugins/src/main/java/tech/pegasys/pantheon/plugin/data/Address.java
  17. 46
      plugins/src/main/java/tech/pegasys/pantheon/plugin/data/BinaryData.java
  18. 156
      plugins/src/main/java/tech/pegasys/pantheon/plugin/data/BlockHeader.java
  19. 23
      plugins/src/main/java/tech/pegasys/pantheon/plugin/data/Hash.java
  20. 43
      plugins/src/main/java/tech/pegasys/pantheon/plugin/data/Log.java
  21. 35
      plugins/src/main/java/tech/pegasys/pantheon/plugin/data/Quantity.java
  22. 130
      plugins/src/main/java/tech/pegasys/pantheon/plugin/data/Transaction.java
  23. 19
      plugins/src/main/java/tech/pegasys/pantheon/plugin/data/UnformattedData.java
  24. 119
      plugins/src/main/java/tech/pegasys/pantheon/plugin/services/MetricsSystem.java
  25. 36
      plugins/src/main/java/tech/pegasys/pantheon/plugin/services/PantheonConfiguration.java
  26. 117
      plugins/src/main/java/tech/pegasys/pantheon/plugin/services/PantheonEvents.java
  27. 37
      plugins/src/main/java/tech/pegasys/pantheon/plugin/services/PicoCLIOptions.java
  28. 38
      plugins/src/main/java/tech/pegasys/pantheon/plugin/services/StorageService.java
  29. 47
      plugins/src/main/java/tech/pegasys/pantheon/plugin/services/exception/StorageException.java
  30. 30
      plugins/src/main/java/tech/pegasys/pantheon/plugin/services/metrics/Counter.java
  31. 31
      plugins/src/main/java/tech/pegasys/pantheon/plugin/services/metrics/LabelledMetric.java
  32. 43
      plugins/src/main/java/tech/pegasys/pantheon/plugin/services/metrics/MetricCategory.java
  33. 29
      plugins/src/main/java/tech/pegasys/pantheon/plugin/services/metrics/MetricCategoryRegistry.java
  34. 43
      plugins/src/main/java/tech/pegasys/pantheon/plugin/services/metrics/OperationTimer.java
  35. 78
      plugins/src/main/java/tech/pegasys/pantheon/plugin/services/storage/KeyValueStorage.java
  36. 57
      plugins/src/main/java/tech/pegasys/pantheon/plugin/services/storage/KeyValueStorageFactory.java
  37. 49
      plugins/src/main/java/tech/pegasys/pantheon/plugin/services/storage/KeyValueStorageTransaction.java
  38. 30
      plugins/src/main/java/tech/pegasys/pantheon/plugin/services/storage/SegmentIdentifier.java
  39. 3
      services/kvstore/build.gradle
  40. 2
      services/pipeline/build.gradle
  41. 3
      services/tasks/build.gradle
  42. 1
      settings.gradle
  43. 2
      util/build.gradle

@ -33,6 +33,7 @@ dependencies {
testImplementation project(':metrics:core')
testImplementation project(':pantheon')
testImplementation project(path: ':pantheon', configuration: 'testArtifacts')
testImplementation project(':plugins')
testImplementation project(':services:kvstore')
testImplementation project(':testutil')
testImplementation project(':util')
@ -55,7 +56,6 @@ dependencies {
testImplementation 'tech.pegasys.ethsigner.internal:core'
testImplementation 'tech.pegasys.ethsigner.internal:file-based'
testImplementation 'tech.pegasys.ethsigner.internal:signing-api'
testImplementation 'tech.pegasys.pantheon:plugin-api'
}
test.enabled = false

@ -272,6 +272,9 @@ allprojects {
task deploy() {}
tasks.register('checkPluginAPIChanges', DefaultTask) { }
checkPluginAPIChanges.dependsOn(':plugins:checkAPIChanges')
check.dependsOn('checkPluginAPIChanges')
subprojects {

@ -26,7 +26,7 @@ jar {
}
dependencies {
api 'tech.pegasys.pantheon:plugin-api'
api project(':plugins')
implementation project(':ethereum:core')
implementation project(':ethereum:jsonrpc')

@ -26,10 +26,10 @@ jar {
}
dependencies {
api project(':plugins')
api project(':util')
api 'org.bouncycastle:bcprov-jdk15on'
api 'tech.pegasys.pantheon:plugin-api'
implementation 'com.google.guava:guava'
implementation 'org.apache.logging.log4j:log4j-api'

@ -32,13 +32,13 @@ dependencies {
implementation project(':ethereum:rlp')
implementation project(':ethereum:trie')
implementation project(':metrics:core')
implementation project(':plugins')
implementation project(':services:kvstore')
implementation 'com.fasterxml.jackson.core:jackson-databind'
implementation 'com.google.guava:guava'
implementation 'io.vertx:vertx-core'
implementation 'org.apache.logging.log4j:log4j-api'
implementation 'tech.pegasys.pantheon:plugin-api'
runtime 'org.apache.logging.log4j:log4j-core'

@ -26,7 +26,7 @@ jar {
}
dependencies {
api 'tech.pegasys.pantheon:plugin-api'
api project(':plugins')
implementation project(':ethereum:p2p')
implementation project(':ethereum:permissioning')

@ -26,8 +26,8 @@ jar {
}
dependencies {
api project(':plugins')
api project(':util')
api 'tech.pegasys.pantheon:plugin-api'
implementation 'com.google.guava:guava'
implementation 'io.vertx:vertx-core'

@ -95,7 +95,5 @@ dependencyManagement {
dependency "tech.pegasys.ethsigner.internal:core:0.3.0"
dependency "tech.pegasys.ethsigner.internal:file-based:0.3.0"
dependency "tech.pegasys.ethsigner.internal:signing-api:0.3.0"
dependency "tech.pegasys.pantheon:plugin-api:1.2.3"
}
}

@ -33,6 +33,8 @@ publishing {
dependencies {
implementation project(':plugins')
implementation 'com.google.guava:guava'
implementation 'io.prometheus:simpleclient'
implementation 'io.prometheus:simpleclient_common'
@ -41,7 +43,6 @@ dependencies {
implementation 'io.vertx:vertx-core'
implementation 'io.vertx:vertx-web'
implementation 'org.apache.logging.log4j:log4j-api'
implementation 'tech.pegasys.pantheon:plugin-api'
runtime 'org.apache.logging.log4j:log4j-core'

@ -27,12 +27,11 @@ jar {
dependencies {
implementation project(':metrics:core')
implementation project(':plugins')
implementation project(':services:util')
implementation 'com.google.guava:guava'
implementation 'io.prometheus:simpleclient'
implementation 'org.apache.logging.log4j:log4j-api'
implementation 'org.rocksdb:rocksdbjni'
implementation 'tech.pegasys.pantheon:plugin-api'
}

@ -44,6 +44,7 @@ dependencies {
implementation project(':ethereum:rlp')
implementation project(':metrics:core')
implementation project(':nat')
implementation project(':plugins')
implementation project(':services:kvstore')
implementation 'com.fasterxml.jackson.core:jackson-databind'
@ -56,7 +57,6 @@ dependencies {
implementation 'net.consensys.cava:cava-toml'
implementation 'org.apache.logging.log4j:log4j-api'
implementation 'org.springframework.security:spring-security-crypto'
implementation 'tech.pegasys.pantheon:plugin-api'
runtime 'org.apache.logging.log4j:log4j-core'
runtime 'org.apache.logging.log4j:log4j-slf4j-impl'

@ -0,0 +1,78 @@
/*
* Copyright 2019 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.
*/
import net.ltgt.gradle.errorprone.CheckSeverity
import java.security.MessageDigest
apply plugin: 'java-library'
jar {
baseName 'plugin-api'
manifest {
attributes(
'Specification-Title': baseName,
'Specification-Version': project.version,
'Implementation-Title': baseName,
'Implementation-Version': calculateVersion()
)
}
}
dependencies {
}
configurations { testArtifacts }
artifacts { testSupportArtifacts testSupportJar }
class FileStateChecker extends DefaultTask {
Set<File> files
String knownHash
@TaskAction
def CheckState() {
def digestor = MessageDigest.getInstance("SHA-256")
this.files.sort().each {
digestor.update(it.readBytes())
}
def currentHash = digestor.digest()encodeBase64().toString()
if (this.knownHash != currentHash) {
throw new GradleException("""For the Plugin APIs the checksum of the project did not match what was expected.
If this is a deliberate change where you have thought through backwards compatibility,
then update "Expected" for "Calculated" in the appropriate build.gradle as the knownHash for this task.
Expected : ${this.knownHash}
Calculated : ${currentHash}
""")
}
}
}
tasks.register('checkAPIChanges', FileStateChecker) {
description = "Checks that the API for the Plugin-API project does not change without deliberate thought"
files = sourceSets.main.allJava.files
knownHash = 'PBo0D4R6/1EYXEn+k0nmWHW4TkklUWQbQGNqgWzslfw='
}
check.dependsOn('checkAPIChanges')
publishing {
publications {
mavenJava(MavenPublication) {
groupId 'tech.pegasys.pantheon.plugin-api'
pom {
name = 'Pantheon Plugins Library'
description = 'Core Plugins Libraries for Pantheon'
}
}
}
}

@ -0,0 +1,42 @@
/*
* Copyright 2019 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.
*/
package tech.pegasys.pantheon.plugin;
import java.util.Optional;
/** Allows plugins to access Pantheon services. */
public interface PantheonContext {
/**
* Get the requested service, if it is available. There are a number of reasons that a service may
* not be available:
*
* <ul>
* <li>The service may not have started yet. Most services are not available before the {@link
* PantheonPlugin#start()} method is called
* <li>The service is not supported by this version of Pantheon
* <li>The service may not be applicable to the current configuration. For example some services
* may only be available when a proof of authority network is in use
* </ul>
*
* <p>Since plugins are automatically loaded, unless the user has specifically requested
* functionality provided by the plugin, no error should be raised if required services are
* unavailable.
*
* @param serviceType the class defining the requested service.
* @param <T> the service type
* @return an optional containing the instance of the requested service, or empty if the service
* is unavailable
*/
<T> Optional<T> getService(Class<T> serviceType);
}

@ -0,0 +1,53 @@
/*
* Copyright 2019 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.
*/
package tech.pegasys.pantheon.plugin;
/**
* Base interface for Pantheon plugins.
*
* <p>Plugins are discovered and loaded using {@link java.util.ServiceLoader} from jar files within
* Pantheon's plugin directory. See the {@link java.util.ServiceLoader} documentation for how to
* register plugins.
*/
public interface PantheonPlugin {
/**
* Called when the plugin is first registered with Pantheon. Plugins are registered very early in
* the Pantheon life-cycle and should use this callback to register any command line options
* required via the PicoCLIOptions service.
*
* <p>The <code>context</code> parameter should be stored in a field in the plugin. This is the
* only time it will be provided to the plugin and is how the plugin will interact with Pantheon.
*
* <p>Typically the plugin will not begin operation until the {@link #start()} method is called.
*
* @param context the context that provides access to Pantheon services.
*/
void register(PantheonContext context);
/**
* Called once Pantheon has loaded configuration and is starting up. The plugin should begin
* operation, including registering any event listener with Pantheon services and starting any
* background threads the plugin requires.
*/
void start();
/**
* Called when the plugin is being stopped. This method will be called as part of Pantheon
* shutting down but may also be called at other times to disable the plugin.
*
* <p>The plugin should remove any registered listeners and stop any background threads it
* started.
*/
void stop();
}

@ -0,0 +1,28 @@
/*
* Copyright 2019 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.
*/
package tech.pegasys.pantheon.plugin;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.CLASS;
import java.lang.annotation.Retention;
/**
* This annotation is an indicator that the interface or method may evolve in a way that it not
* backwards compatible. Such as deleting methods, changing signatures, and adding checked
* exceptions. Authors are advised to exercise caution when using these APIs.
*/
@Retention(CLASS)
@java.lang.annotation.Target({METHOD, TYPE})
public @interface Unstable {}

@ -0,0 +1,19 @@
/*
* Copyright 2019 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.
*/
package tech.pegasys.pantheon.plugin.data;
import tech.pegasys.pantheon.plugin.Unstable;
/** An interface for {@link BinaryData} that also represents an Ethereum account address. */
@Unstable
public interface Address extends UnformattedData {}

@ -0,0 +1,46 @@
/*
* Copyright 2019 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.
*/
package tech.pegasys.pantheon.plugin.data;
import tech.pegasys.pantheon.plugin.Unstable;
/** Super class for all types that are ultimately represented by binary data. */
@Unstable
public interface BinaryData {
/**
* The byte level representation of the binary data. This array should be treated as read only
* constant data as any changes will not be reflected in the source.
*
* @return a read-only array of the bytes of the binary data.
*/
byte[] getByteArray();
/**
* A hex string representation of the data. This hex string will represent the hex of the entire
* binary data and will be "<code>0x</code>" prefixed. APIs that depend on shortend forms will
* need to process the string.
*
* @return A string repsenting the hex encodeing of the data.
*/
String getHexString();
/**
* The size, in bytes, of the contained binary data. Because {@link #getByteArray()} may cause the
* underlying data to be copied using this size method is preferred when such a check would avoid
* a call to {@link #getByteArray()} or {@link #getHexString()}.
*
* @return The length of the binary data in bytes.
*/
int size();
}

@ -0,0 +1,156 @@
/*
* Copyright 2019 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.
*/
package tech.pegasys.pantheon.plugin.data;
import tech.pegasys.pantheon.plugin.Unstable;
/**
* The minimum set of data for a BlockHeader, as defined in the <a href=
* "https://ethereum.github.io/yellowpaper/paper.pdf">Ethereum Yellow Paper</a>.
*/
@Unstable
public interface BlockHeader {
/**
* The Keccak 256-bit hash of the parent blocks header, in its entirety.
*
* @return The Keccak 256-bit hash of the parent blocks header, in its entirety.
*/
Hash getParentHash();
/**
* The Keccak 256-bit hash of the ommers list portion of this block.
*
* @return The Keccak 256-bit hash of the ommers list portion of this block.
*/
Hash getOmmersHash();
/**
* The 160-bit address to which all fees collected from the successful mining of this block be
* transferred.
*
* <p>The name in the yellow paper is beneficiary.
*
* @return The 160-bit address to which all fees collected from the successful mining of this
* block be transferred.
*/
Address getCoinbase();
/**
* The Keccak 256-bit hash of the root node of the state trie, after all transactions are executed
* and finalisations applied.
*
* @return The Keccak 256-bit hash of the root node of the state trie, after all transactions are
* executed and finalisations applied.
*/
Hash getStateRoot();
/**
* The Keccak 256-bit hash of theroot node of the trie structure populated with each transaction
* in the transactions list portion of the block.
*
* @return The Keccak 256-bit hash of theroot node of the trie structure populated with each
* transaction in the transactions list portion of the block.
*/
Hash getTransactionsRoot();
/**
* The Keccak 256-bit hash of the root node of the trie structure populated with the receipts of
* each transaction in the transactions list portion of the block.
*
* @return The Keccak 256-bit hash of the root node of the trie structure populated with the
* receipts of each transaction in the transactions list portion of the block.
*/
Hash getReceiptsRoot();
/**
* The Bloom filter composed from indexable information (logger address and log topics) contained
* in each log entry from the receipt of each transaction in the transactions list.
*
* @return The Bloom filter composed from indexable information (logger address and log topics)
* contained in each log entry from the receipt of each transaction in the transactions list.
*/
UnformattedData getLogsBloom();
/**
* A scalar value corresponding to the difficulty level of this block. This can be calculated from
* the previous blocks difficulty level and the timestamp.
*
* @return A scalar value corresponding to the difficulty level of this block. This can be
* calculated from the previous blocks difficulty level and the timestamp.
*/
Quantity getDifficulty();
/**
* A scalar value equal to the number of ancestor blocks. The genesis block has a number of zero.
*
* @return A scalar value equal to the number of ancestor blocks. The genesis block has a number
* of zero.
*/
long getNumber();
/**
* A scalar value equal to the current limit of gas expenditure per block.
*
* @return A scalar value equal to the current limit of gas expenditure per block.
*/
long getGasLimit();
/**
* A scalar value equal to the total gas used in transactions in this block.
*
* @return A scalar value equal to the total gas used in transactions in this block.
*/
long getGasUsed();
/**
* A scalar value equal to the reasonable output of Unixs time() at this blocks inception.
*
* @return A scalar value equal to the reasonable output of Unixs time() at this blocks
* inception.
*/
long getTimestamp();
/**
* An arbitrary byte array containing data relevant to this block. This must be 32 bytes or fewer.
*
* @return An arbitrary byte array containing data relevant to this block. This must be 32 bytes
* or fewer.
*/
UnformattedData getExtraData();
/**
* A 256-bit hash which, combined with the nonce, proves that a sufficient amount of computation
* has been carried out on this block.
*
* @return A 256-bit hash which, combined with the nonce, proves that a sufficient amount of
* computation has been carried out on this block.
*/
Hash getMixHash();
/**
* A 64-bit value which, combined with the mixhash, proves that a sufficient amount of computation
* has been carried out on this block.
*
* @return A 64-bit value which, combined with the mixhash, proves that a sufficient amount of
* computation has been carried out on this block.
*/
long getNonce();
/**
* The Keccak 256-bit hash of this header.
*
* @return The Keccak 256-bit hash of this header.
*/
Hash getBlockHash();
}

@ -0,0 +1,23 @@
/*
* Copyright 2019 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.
*/
package tech.pegasys.pantheon.plugin.data;
import tech.pegasys.pantheon.plugin.Unstable;
/**
* A marker interface indicating that this {@link UnformattedData} represents a hash of some sort.
* The particular algorithm depends on the source, it may be ripemd, keccak, or some other
* algorithm.
*/
@Unstable
public interface Hash extends UnformattedData {}

@ -0,0 +1,43 @@
/*
* Copyright 2019 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.
*/
package tech.pegasys.pantheon.plugin.data;
import tech.pegasys.pantheon.plugin.Unstable;
import java.util.List;
/** A Log entry from a transaction execution. */
@Unstable
public interface Log {
/**
* The address of the contract writing this log message.
*
* @return The loggers address.
*/
Address getLogger();
/**
* The list of 32 byte log topics, possibly empty.
*
* @return The list, possibly zero length, of log topics.
*/
List<? extends UnformattedData> getTopics();
/**
* The data, of possibly unlimited length, for this log entry.
*
* @return The log data.
*/
UnformattedData getData();
}

@ -0,0 +1,35 @@
/*
* Copyright 2019 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.
*/
package tech.pegasys.pantheon.plugin.data;
import tech.pegasys.pantheon.plugin.Unstable;
/**
* An interface to mark the {@link BinaryData} that also represents a disceete quantity, such as an
* unsigned integer value.
*/
@Unstable
public interface Quantity extends BinaryData {
/**
* Returns the numeric value of the quantity.
*
* <p>The specific class returned may be the boxed Java primitives, however plugin authors should
* not rely on the underlying number always being castable to that primitive in all cases and
* should instead rely on APIs such as {@link Number#longValue()} to cast to primitive values.
* Similarly the underlying object based values may evolve over time.
*
* @return The boxed or object based value of the quantity.
*/
Number getValue();
}

@ -0,0 +1,130 @@
/*
* Copyright 2019 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.
*/
package tech.pegasys.pantheon.plugin.data;
import tech.pegasys.pantheon.plugin.Unstable;
import java.math.BigInteger;
import java.util.Optional;
/**
* A transaction is a single cryptographically-signed instruction constructed by an actor externally
* to the scope of Ethereum. While it is assumed that the ultimate external actor will be human in
* nature, software tools will be used in its construction and dissemination.
*
* <p>There are two types of transactions: those which result in message calls and those which
* result in the creation of new accounts with associated code (known informally as contract
* creation). Message call transactions will have an address present in the {@link #getTo} method
* whereas contract creation transactions will not.
*/
@Unstable
public interface Transaction {
/**
* A scalar value equal to the number of transactions sent by the sender.
*
* @return the number of transactions sent by the sender.
*/
long getNonce();
/**
* A scalar value equal to the number of Wei to be paid per unit of gas for all computation costs
* incurred as a result of the execution of this transaction.
*
* @return the quantity of Wei per gas unit paid.
*/
Quantity getGasPrice();
/**
* A scalar value equal to the maximum amount of gas that should be used in executing this
* transaction. This is paid up-front, before any computation is done and may not be increased
* later.
*
* @return the maximum amount of gas that should be used in executing this * transaction.
*/
long getGasLimit();
/**
* The 160-bit address of the message calls recipient. For a contract creation transaction this
* address will not be present.
*
* @return address of the recipient
*/
Optional<? extends Address> getTo();
/**
* A scalar value equal to the number of Wei to be transferred to the message calls recipient or,
* in the case of contract creation, as an endowment to the newly created account
*
* @return value equal to the number of Wei to be transferred
*/
Quantity getValue();
/**
* Value corresponding to the 'V' component of the signature of the transaction.
*
* @return the 'V' component of the signature
*/
BigInteger getV();
/**
* Value corresponding to the 'V' component of the signature of the transaction.
*
* @return the 'V' component of the signature
*/
BigInteger getR();
/**
* Value corresponding to the 'V' component of the signature of the transaction.
*
* @return the 'V' component of the signature
*/
BigInteger getS();
/**
* The 160-bit address of the account sending the transaction, extracted from the v, r, s
* parameters.
*
* @return The address of the account that sent this transaction.
*/
Address getSender();
/**
* The chainId, computed from the 'V' portion of the signature. Used for replay protection. If
* replay protection is not enabled this value will not be present.
*
* @return The chainId for transaction.
*/
Optional<BigInteger> getChainId();
/**
* An unlimited size byte array specifying the EVM-code for the account // initialisation
* procedure.
*
* <p>Only present if this is a contract creation transaction, which is only true if {@link
* #getTo} is empty.
*
* @return if present, the contract init code.
*/
Optional<? extends UnformattedData> getInit();
/**
* An unlimited size byte array specifying theinput data of the message call.
*
* <p>Only present if this is a message call transaction, which is only true if {@link #getTo} is
* present.
*
* @return if present, the message call data
*/
Optional<? extends UnformattedData> getData();
}

@ -0,0 +1,19 @@
/*
* Copyright 2019 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.
*/
package tech.pegasys.pantheon.plugin.data;
import tech.pegasys.pantheon.plugin.Unstable;
/** An interface to mark BinaryData that is not a scalar {@link Quantity}. */
@Unstable
public interface UnformattedData extends BinaryData {}

@ -0,0 +1,119 @@
/*
* Copyright 2018 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.
*/
package tech.pegasys.pantheon.plugin.services;
import tech.pegasys.pantheon.plugin.services.metrics.Counter;
import tech.pegasys.pantheon.plugin.services.metrics.LabelledMetric;
import tech.pegasys.pantheon.plugin.services.metrics.MetricCategory;
import tech.pegasys.pantheon.plugin.services.metrics.OperationTimer;
import java.util.function.DoubleSupplier;
import java.util.function.IntSupplier;
import java.util.function.LongSupplier;
/** An interface for creating various Metrics components. */
public interface MetricsSystem {
/**
* Creates a Counter.
*
* @param category The {@link MetricCategory} this counter is assigned to.
* @param name A name for this metric.
* @param help A human readable description of the metric.
* @return The created Counter instance.
*/
default Counter createCounter(
final MetricCategory category, final String name, final String help) {
return createLabelledCounter(category, name, help, new String[0]).labels();
}
/**
* Creates a Counter with assigned labels.
*
* @param category The {@link MetricCategory} this counter is assigned to.
* @param name A name for this metric.
* @param help A human readable description of the metric.
* @param labelNames An array of labels to assign to the Counter.
* @return The created LabelledMetric instance.
*/
LabelledMetric<Counter> createLabelledCounter(
MetricCategory category, String name, String help, String... labelNames);
/**
* Creates a Timer.
*
* @param category The {@link MetricCategory} this timer is assigned to.
* @param name A name for this metric.
* @param help A human readable description of the metric.
* @return The created Timer instance.
*/
default OperationTimer createTimer(
final MetricCategory category, final String name, final String help) {
return createLabelledTimer(category, name, help, new String[0]).labels();
}
/**
* Creates a Timer with assigned labels.
*
* @param category The {@link MetricCategory} this timer is assigned to.
* @param name A name for this metric.
* @param help A human readable description of the metric.
* @param labelNames An array of labels to assign to the Timer.
* @return The created LabelledMetric instance.
*/
LabelledMetric<OperationTimer> createLabelledTimer(
MetricCategory category, String name, String help, String... labelNames);
/**
* Creates a gauge for displaying double vales. A gauge is a metric to report the current value.
* The metric value may go up or down.
*
* @param category The {@link MetricCategory} this gauge is assigned to.
* @param name A name for this metric.
* @param help A human readable description of the metric.
* @param valueSupplier A supplier for the double value to be presented.
*/
void createGauge(MetricCategory category, String name, String help, DoubleSupplier valueSupplier);
/**
* Creates a gauge for displaying integer values.
*
* @param category The {@link MetricCategory} this gauge is assigned to.
* @param name A name for this metric.
* @param help A human readable description of the metric.
* @param valueSupplier A supplier for the integer value to be presented.
*/
default void createIntegerGauge(
final MetricCategory category,
final String name,
final String help,
final IntSupplier valueSupplier) {
createGauge(category, name, help, () -> (double) valueSupplier.getAsInt());
}
/**
* Creates a gauge for displaying long values.
*
* @param category The {@link MetricCategory} this gauge is assigned to.
* @param name A name for this metric.
* @param help A human readable description of the metric.
* @param valueSupplier A supplier for the long value to be presented.
*/
default void createLongGauge(
final MetricCategory category,
final String name,
final String help,
final LongSupplier valueSupplier) {
createGauge(category, name, help, () -> (double) valueSupplier.getAsLong());
}
}

@ -0,0 +1,36 @@
/*
* Copyright 2019 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.
*/
package tech.pegasys.pantheon.plugin.services;
import java.net.URI;
import java.nio.file.Path;
import java.util.Optional;
/** Generally useful configuration provided by Pantheon. */
public interface PantheonConfiguration {
/**
* Location of the working directory of the storage in the file system running the client.
*
* @return location of the storage in the file system of the client.
*/
Path getStoragePath();
/**
* Url of the enclave that stores private transaction data.
*
* @return an optional containing the url of the enclave Pantheon is connected to, or empty if
* privacy is not enabled.
*/
Optional<URI> getEnclaveUrl();
}

@ -0,0 +1,117 @@
/*
* Copyright 2019 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.
*/
package tech.pegasys.pantheon.plugin.services;
import tech.pegasys.pantheon.plugin.Unstable;
import tech.pegasys.pantheon.plugin.data.BlockHeader;
import tech.pegasys.pantheon.plugin.data.Transaction;
/**
* This service allows plugins to attach to various events during the normal operation of Pantheon.
*
* <p>Currently supported events
*
* <ul>
* <li><b>newBlockPropagated</b> - Fired when a new block header has been received and validated
* and is about to be sent out to other peers, but before the body of the block has been
* evaluated and validated.
* <li><b>newTransactionAdded</b> - Fired when a new transaction has been added to the node.
* </ul>
*/
@Unstable
public interface PantheonEvents {
/**
* Add a listener watching new blocks propagated.
*
* @param newBlockPropagatedListener The listener that will accept a BlockHeader as the event.
* @return an object to be used as an identifier when de-registering the event.
*/
Object addNewBlockPropagatedListener(NewBlockPropagatedListener newBlockPropagatedListener);
/**
* Remove the blockAdded listener from pantheon notifications.
*
* @param listenerIdentifier The instance that was returned from addBlockAddedListener;
*/
void removeNewBlockPropagatedListener(Object listenerIdentifier);
/**
* Add a listener watching new transactions added to the node.
*
* @param newTransactionAddedListener The listener that will accept the Transaction object as the
* event.
* @return an object to be used as an identifier when de-registering the event.
*/
Object addNewTransactionAddedListener(NewTransactionAddedListener newTransactionAddedListener);
/**
* Remove the blockAdded listener from pantheon notifications.
*
* @param listenerIdentifier The instance that was returned from addNewTransactionAddedListener;
*/
void removeNewTransactionAddedListener(Object listenerIdentifier);
/**
* Add a listener watching dropped transactions.
*
* @param newTransactionDroppedListener The listener that will accept the Transaction object as
* the event.
* @return an object to be used as an identifier when de-registering the event.
*/
Object addNewTransactionDroppedListener(TransactionDroppedListener newTransactionDroppedListener);
/**
* Remove the transactionDropped listener from pantheon notifications.
*
* @param listenerIdentifier The instance that was returned from addTransactionDroppedListener;
*/
void removeTransactionDroppedListener(Object listenerIdentifier);
/** The listener interface for receiving new block propagated events. */
interface NewBlockPropagatedListener {
/**
* Invoked when a new block header has been received and validated and is about to be sent out
* to other peers, but before the body of the block has been evaluated and validated.
*
* <p>The block may not have been imported to the local chain yet and may fail later
* validations.
*
* @param newBlockHeader the new block header.
*/
void newBlockPropagated(BlockHeader newBlockHeader);
}
/** The listener interface for receiving new transaction added events. */
interface NewTransactionAddedListener {
/**
* Invoked when a new transaction has been added to the node.
*
* @param transaction the new transaction.
*/
void newTransactionAdded(Transaction transaction);
}
/** The listener interface for receiving transaction dropped events. */
interface TransactionDroppedListener {
/**
* Invoked when a transaction is dropped from the node.
*
* @param transaction the dropped transaction.
*/
void newTransactionDropped(Transaction transaction);
}
}

@ -0,0 +1,37 @@
/*
* Copyright 2019 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.
*/
package tech.pegasys.pantheon.plugin.services;
/**
* A service that plugins can use to add CLI options and commands to the PantheonCommand. The
* PicoCLI library annotations will be inspected and the object will be passed into a
* picocli.CommandLine.addMixin call.
*
* <p>This service will be available during the registration callbacks.
*
* <p>CLI arguments should conform to the <a
* href="https://github.com/PegaSysEng/pantheon/blob/master/CLI-STYLE-GUIDE.md">CLI-STYLE-GUIDE.md</a>
* conventions.
*/
public interface PicoCLIOptions {
/**
* During the registration callback plugins can register CLI options that should be added to
* Pantheon's CLI startup.
*
* @param namespace A namespace prefix. All registered options must start with this prefix
* @param optionObject The instance of the object to be inspected. PicoCLI will reflect the fields
* of this object to extract the CLI options.
*/
void addPicoCLIOptions(String namespace, Object optionObject);
}

@ -0,0 +1,38 @@
/*
* Copyright 2019 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.
*/
package tech.pegasys.pantheon.plugin.services;
import tech.pegasys.pantheon.plugin.Unstable;
import tech.pegasys.pantheon.plugin.services.storage.KeyValueStorageFactory;
import tech.pegasys.pantheon.plugin.services.storage.SegmentIdentifier;
import java.util.List;
/** This service allows plugins to register as an available storage engine. */
@Unstable
public interface StorageService {
/**
* Registers a factory as available for creating key-value storage instances.
*
* @param factory creates instances providing key-value storage.
*/
void registerKeyValueStorage(KeyValueStorageFactory factory);
/**
* Retrieves the identifiers for the isolation segments that could be requested during operation.
*
* @return full set of possible segments required from the storage service.
*/
List<SegmentIdentifier> getAllSegmentIdentifiers();
}

@ -0,0 +1,47 @@
/*
* Copyright 2019 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.
*/
package tech.pegasys.pantheon.plugin.services.exception;
/** Base exception class for problems encountered in the domain for storage. */
public class StorageException extends RuntimeException {
/**
* Constructs a new storage exception with the specified cause.
*
* @param cause saved for later retrieval by the {@link #getCause()} method). (A {@code null}
* value is permitted, and indicates that the cause is nonexistent or unknown.)
*/
public StorageException(final Throwable cause) {
super(cause);
}
/**
* Constructs a new storage exception with the specified detail message and cause.
*
* @param message the detail that may be retrieved later by Throwable.getMessage().
* @param cause saved for later retrieval by the {@link #getCause()} method). (A {@code null}
* value is permitted, and indicates that the cause is nonexistent or unknown.)
*/
public StorageException(final String message, final Throwable cause) {
super(message, cause);
}
/**
* Constructs a new storage exception with the specified detail message.
*
* @param message the detail that may be retrieved later by Throwable.getMessage().
*/
public StorageException(final String message) {
super(message);
}
}

@ -0,0 +1,30 @@
/*
* Copyright 2018 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.
*/
package tech.pegasys.pantheon.plugin.services.metrics;
/**
* A counter is a metric to track counts of events or running totals etc. The value of the counter
* can only increase.
*/
public interface Counter {
/** Increment the counter by 1. */
void inc();
/**
* Increment the counter by a specified amount.
*
* @param amount The amount to increment the counter by. Must be greater than or equal to 0.
*/
void inc(long amount);
}

@ -0,0 +1,31 @@
/*
* Copyright 2018 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.
*/
package tech.pegasys.pantheon.plugin.services.metrics;
/**
* A metric with labels associated. Values for the associated labels can be provided to access the
* underlying metric.
*
* @param <T> The type of metric the labels are applied to.
*/
public interface LabelledMetric<T> {
/**
* Returns a metric tagged with the specified label values.
*
* @param labels An array of label values in the same order as the labels when creating this
* metric. The number of values provided must match the number of labels.
* @return A metric tagged with the specified labels.
*/
T labels(String... labels);
}

@ -0,0 +1,43 @@
/*
* Copyright 2019 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.
*/
package tech.pegasys.pantheon.plugin.services.metrics;
import java.util.Optional;
/**
* A MetricCategory is used to group related metrics. Every metric belongs to one and only one
* MetricCategory.
*
* <p>Categories must be registered with the {@link MetricCategoryRegistry} during plugin
* initialisation.
*/
public interface MetricCategory {
/**
* Gets the name of this MetricCategory.
*
* @return The name of this MetricCategory.
*/
String getName();
/**
* Gets the application-specific MetricCategory prefix. An empty Optional may be returned if this
* category is not application specific.
*
* <p>The prefix, if present, is prepended to the category name when creating a single combined
* name for metrics.
*
* @return An optional application prefix.
*/
Optional<String> getApplicationPrefix();
}

@ -0,0 +1,29 @@
/*
* Copyright 2019 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.
*/
package tech.pegasys.pantheon.plugin.services.metrics;
/**
* Allow registration of {@link MetricCategory} instances so they are recognised by the metrics
* system and can be enabled.
*
* <p>Categories must be registered during plugin initialisation.
*/
public interface MetricCategoryRegistry {
/**
* Registers a {@link MetricCategory}.
*
* @param newMetricCategory The {@link MetricCategory} that is being registered.
*/
public void addMetricCategory(final MetricCategory newMetricCategory);
}

@ -0,0 +1,43 @@
/*
* Copyright 2018 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.
*/
package tech.pegasys.pantheon.plugin.services.metrics;
import java.io.Closeable;
/** A timer metric that records duration of operations for metrics purposes. */
public interface OperationTimer {
/**
* Starts the timer.
*
* @return The produced TimingContext, which must be stopped or closed when the operation being
* timed has completed.
*/
TimingContext startTimer();
/** An interface for stopping the timer and returning elapsed time. */
interface TimingContext extends Closeable {
/**
* Stops the timer and returns the elapsed time.
*
* @return Elapsed time in seconds.
*/
double stopTimer();
@Override
default void close() {
stopTimer();
}
}
}

@ -0,0 +1,78 @@
/*
* Copyright 2019 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.
*/
package tech.pegasys.pantheon.plugin.services.storage;
import tech.pegasys.pantheon.plugin.Unstable;
import tech.pegasys.pantheon.plugin.services.exception.StorageException;
import java.io.Closeable;
import java.util.Optional;
import java.util.function.Predicate;
/**
* Responsible for storing values against keys.
*
* <p>Behaviour expected with regard to key to value mapping is that of a map, one key maps to one
* value, when a new value is added with an existing key, that key now points at the new value.
*
* <p>All keys and values must be non-null.
*/
@Unstable
public interface KeyValueStorage extends Closeable {
/**
* Deletes all keys and values from the storage.
*
* @throws StorageException problem encountered when attempting to clear storage.
*/
void clear() throws StorageException;
/**
* Whether the key-value storage contains the given key.
*
* @param key a key that might be contained in the key-value storage.
* @return <code>true</code> when the given key is present in keyset, <code>false</code>
* otherwise.
* @throws StorageException problem encountered when interacting with the key set.
*/
boolean containsKey(byte[] key) throws StorageException;
/**
* Retrieves the value associated with a given key.
*
* @param key whose associated value is being retrieved.
* @return an {@link Optional} containing the value associated with the specified key, otherwise
* empty.
* @throws StorageException problem encountered during the retrieval attempt.
*/
Optional<byte[]> get(byte[] key) throws StorageException;
/**
* Performs an evaluation against each key in the store, keeping the entries that pass, removing
* those that fail.
*
* @param retainCondition predicate to evaluate each key against, unless the result is {@code
* null}, both the key and associated value must be removed.
* @return the number of keys removed.
* @throws StorageException problem encountered when removing data.
*/
long removeAllKeysUnless(Predicate<byte[]> retainCondition) throws StorageException;
/**
* Begins a fresh transaction, for sequencing operations for later atomic execution.
*
* @return transaciton to sequence key-value operations.
* @throws StorageException problem encountered when starting a new transaction.
*/
KeyValueStorageTransaction startTransaction() throws StorageException;
}

@ -0,0 +1,57 @@
/*
* Copyright 2019 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.
*/
package tech.pegasys.pantheon.plugin.services.storage;
import tech.pegasys.pantheon.plugin.Unstable;
import tech.pegasys.pantheon.plugin.services.exception.StorageException;
/** Factory for creating key-value storage instances. */
@Unstable
public interface KeyValueStorageFactory {
/**
* Retrieves the identity of the key-value storage factory.
*
* @return the storage identifier, used when selecting the appropriate storage service.
*/
String getName();
/**
* Creates a new key-value storage instance, appropriate for the given segment.
*
* <p>When segment isolation is not supported, the create will still be called with each of the
* required segments, where the same storage instance should be returned.
*
* <p>New segments may be introduced in future releases and should result in a new empty
* key-space. Segments created with the identifier of an existing segment should have the same
* data as that existing segment.
*
* @param segment identity of the isolation segment, an identifier for the data set the storage
* will contain.
* @return the storage instance reserved for the given segment.
* @exception StorageException problem encountered when creating storage for the segment.
*/
KeyValueStorage create(SegmentIdentifier segment) throws StorageException;
/**
* Whether storage segment isolation is supported by the factory created instances.
*
* <p>As supporting segment isolation is similar to a separating keys into distinct namespaces,
* where operations only affect within that segment i.e. the same key from two segments point to
* separate values.
*
* @return <code>true</code> when the created storage instances are isolated from each other,
* <code>false</code> when keys of different segments can collide with each other.
*/
boolean isSegmentIsolationSupported();
}

@ -0,0 +1,49 @@
/*
* Copyright 2019 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.
*/
package tech.pegasys.pantheon.plugin.services.storage;
import tech.pegasys.pantheon.plugin.Unstable;
import tech.pegasys.pantheon.plugin.services.exception.StorageException;
/** A transaction that can atomically commit a sequence of operations to a key-value store. */
@Unstable
public interface KeyValueStorageTransaction {
/**
* Associates the specified value with the specified key.
*
* <p>If a previously value had been store against the given key, the old value is replaced by the
* given value.
*
* @param key the given value is to be associated with.
* @param value associated with the specified key.
*/
void put(byte[] key, byte[] value);
/**
* When the given key is present, the key and mapped value will be removed from storage.
*
* @param key the key and mapped value that will be removed.
*/
void remove(byte[] key);
/**
* Performs an atomic commit of all the operations queued in the transaction.
*
* @throws StorageException problem was encountered preventing the commit
*/
void commit() throws StorageException;
/** Reset the transaction to a state prior to any operations being queued. */
void rollback();
}

@ -0,0 +1,30 @@
/*
* Copyright 2019 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.
*/
package tech.pegasys.pantheon.plugin.services.storage;
import tech.pegasys.pantheon.plugin.Unstable;
/**
* A namespace identifier for the storage instance segment, a grouping of data that should be kept
* isolated from the data of other segments.
*/
@Unstable
public interface SegmentIdentifier {
/**
* Identifier for the segment consistent throughout the lifetime of the segment.
*
* @return unique name of the segment.
*/
String getName();
}

@ -26,10 +26,9 @@ jar {
}
dependencies {
api project(':plugins')
api project(':util')
api 'tech.pegasys.pantheon:plugin-api'
implementation project(':metrics:core')
implementation project(':metrics:rocksdb')
implementation project(':services:util')

@ -28,10 +28,10 @@ jar {
dependencies {
api project(':util')
implementation project(':metrics:core')
implementation project(':plugins')
implementation 'org.apache.logging.log4j:log4j-api'
implementation 'com.google.guava:guava'
implementation 'tech.pegasys.pantheon:plugin-api'
runtime 'org.apache.logging.log4j:log4j-core'

@ -26,10 +26,9 @@ jar {
}
dependencies {
api project(':plugins')
api project(':util')
api 'tech.pegasys.pantheon:plugin-api'
compileOnly 'org.openjdk.jmh:jmh-generator-annprocess'
implementation project(':metrics:core')

@ -37,6 +37,7 @@ include 'metrics:core'
include 'metrics:rocksdb'
include 'nat'
include 'pantheon'
include 'plugins'
include 'services:kvstore'
include 'services:pipeline'
include 'services:tasks'

@ -26,10 +26,10 @@ jar {
}
dependencies {
implementation project(':plugins')
implementation 'com.google.guava:guava'
implementation 'io.vertx:vertx-core'
implementation 'org.apache.logging.log4j:log4j-api'
implementation 'tech.pegasys.pantheon:plugin-api'
runtime 'org.apache.logging.log4j:log4j-core'

Loading…
Cancel
Save