Merge branch 'master' into dynamic-loading

This commit is contained in:
sofusmortensen 2016-04-09 01:01:36 +02:00
commit d05e6bb6a4
106 changed files with 370 additions and 1029 deletions

View File

@ -24,6 +24,16 @@ Things you need to know:
* There will be a mailing list for discussion, brainstorming etc called [r3dlg-awg](https://groups.google.com/forum/#!forum/r3dlg-awg).
# License
This code is not yet released under a traditional open source license. Until it is, the following license applies:
_Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
set forth therein. Distributed as Non-Project IP to R3 LRC Members pursuant to their respective Member
and Services Agreements and subject to the Non-Project IP license terms. set forth therein. All other rights reserved._
# Instructions for installing prerequisite software
## JDK for Java 8
@ -52,6 +62,7 @@ The code should build, the unit tests should show as all green.
You can catch up with the latest code by selecting "VCS -> Update Project" in the menu.
## IntelliJ Troubleshooting
If on attempting to open the project, IntelliJ refuses because SDK was not selected, do the following:
Configure -> Project Defaults -> Project Structure
@ -66,6 +77,17 @@ click on New… next to the red <No SDK> symbol, and select JDK. It should then
Also select Project language level: as 8. Click OK. Open should now work.
## Other troubleshooting
If you get an error about a missing Quasar agent, then your JVM is being invoked without a needed command line argument.
Make sure an argument like `-javaagent:lib/quasar.jar` is being passed to the invocation.
You may need/want to edit your default JUnit run config in IntelliJ to ensure that parameter is being set, along with
`-Dco.paralleluniverse.fibers.verifyInstrumentation` which is useful to catch mistakes. To do that, click the dropdown
in the toolbar and select "Edit configurations", then expand the defaults tree, then select JUnit and add the two
arguments to the VM options edit.
## Accessing Source Without an IDE
If you don't want to explore or modify the code in a local IDE, you can also just use the command line and a text editor:

View File

@ -160,6 +160,8 @@ task getIRSDemo(type: CreateStartScripts) {
// that have @Suspendable sub implementations. These tend to cause NPEs and are not caught by the verifier
// NOTE: need to make sure the output isn't on the classpath or every other run it generates empty results, so
// we explicitly delete to avoid that happening. We also need to turn off what seems to be a spurious warning in the IDE
//
// TODO: Make this task incremental, as it can be quite slow.
//noinspection GroovyAssignabilityCheck
task quasarScan(dependsOn: ['classes', 'core:classes', 'contracts:classes']) << {

View File

@ -1,11 +1,12 @@
import com.google.common.io.ByteStreams
import java.nio.file.Files
import java.nio.file.Paths
import java.nio.file.StandardCopyOption
import java.nio.file.attribute.FileTime
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
import java.util.zip.ZipFile
import java.util.zip.ZipOutputStream
buildscript {
repositories {
@ -37,7 +38,7 @@ class CanonicalizerPlugin implements Plugin<Project> {
output.setMethod(ZipOutputStream.DEFLATED)
entries.each {
def newEntry = new ZipEntry( it.name )
def newEntry = new ZipEntry(it.name)
newEntry.setLastModifiedTime(zeroTime)
newEntry.setCreationTime(zeroTime)

View File

@ -1,10 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package contracts;
import core.*;
@ -19,7 +12,10 @@ import java.time.*;
*/
public interface ICommercialPaperState extends ContractState {
ICommercialPaperState withOwner(PublicKey newOwner);
ICommercialPaperState withIssuance(PartyReference newIssuance);
ICommercialPaperState withFaceValue(Amount newFaceValue);
ICommercialPaperState withMaturityDate(Instant newMaturityDate);
}

View File

@ -1,35 +1,22 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package contracts;
import core.*;
import core.TransactionForVerification.InOutGroup;
import core.crypto.NullPublicKey;
import core.crypto.SecureHash;
import core.TransactionForVerification.*;
import core.crypto.*;
import core.node.services.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.security.PublicKey;
import java.time.Instant;
import java.util.List;
import static core.ContractsDSLKt.requireSingleCommand;
import static kotlin.collections.CollectionsKt.single;
import org.jetbrains.annotations.*;
import java.security.*;
import java.time.*;
import java.util.*;
import static core.ContractsDSLKt.*;
import static kotlin.collections.CollectionsKt.*;
/**
* This is a Java version of the CommercialPaper contract (chosen because it's simple). This demonstrates how the
* use of Kotlin for implementation of the framework does not impose the same language choice on contract developers.
*
*/
public class JavaCommercialPaper implements Contract {
//public static SecureHash JCP_PROGRAM_ID = SecureHash.sha256("java commercial paper (this should be a bytecode hash)");
@ -41,7 +28,8 @@ public class JavaCommercialPaper implements Contract {
private Amount faceValue;
private Instant maturityDate;
public State() {} // For serialization
public State() {
} // For serialization
public State(PartyReference issuance, PublicKey owner, Amount faceValue, Instant maturityDate) {
this.issuance = issuance;
@ -135,6 +123,7 @@ public class JavaCommercialPaper implements Contract {
return obj instanceof Redeem;
}
}
public static class Issue extends Commands {
@Override
public boolean equals(Object obj) {
@ -175,16 +164,16 @@ public class JavaCommercialPaper implements Contract {
Instant time = timestampCommand.getBefore();
if (! time.isBefore(output.maturityDate)) {
if (!time.isBefore(output.maturityDate)) {
throw new IllegalStateException("Failed Requirement: the maturity date is not in the past");
}
if (!cmd.getSigners().contains(output.issuance.getParty().getOwningKey())) {
throw new IllegalStateException("Failed Requirement: the issuance is signed by the claimed issuer of the paper");
}
}
else { // Everything else (Move, Redeem) requires inputs (they are not first to be actioned)
// There should be only a single input due to aggregation above
} else {
// Everything else (Move, Redeem) requires inputs (they are not first to be actioned)
// There should be only a single input due to aggregation above
State input = single(inputs);
if (!cmd.getSigners().contains(input.getOwner()))
@ -198,9 +187,7 @@ public class JavaCommercialPaper implements Contract {
!output.getIssuance().equals(input.getIssuance()) ||
!output.getMaturityDate().equals(input.getMaturityDate()))
throw new IllegalStateException("Failed requirement: the output state is the same as the input state except for owner");
}
else if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Redeem)
{
} else if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Redeem) {
TimestampCommand timestampCommand = tx.getTimestampBy(DummyTimestampingAuthority.INSTANCE.getIdentity());
if (timestampCommand == null)
throw new IllegalArgumentException("Failed Requirement: must be timestamped");
@ -208,7 +195,7 @@ public class JavaCommercialPaper implements Contract {
Amount received = CashKt.sumCashBy(tx.getOutStates(), input.getOwner());
if (! received.equals(input.getFaceValue()))
if (!received.equals(input.getFaceValue()))
throw new IllegalStateException("Failed Requirement: received amount equals the face value");
if (time.isBefore(input.getMaturityDate()))
throw new IllegalStateException("Failed requirement: the paper must have matured");
@ -229,14 +216,14 @@ public class JavaCommercialPaper implements Contract {
}
public TransactionBuilder generateIssue(@NotNull PartyReference issuance, @NotNull Amount faceValue, @Nullable Instant maturityDate) {
State state = new State(issuance,issuance.getParty().getOwningKey(), faceValue, maturityDate);
return new TransactionBuilder().withItems(state, new Command( new Commands.Issue(), issuance.getParty().getOwningKey()));
State state = new State(issuance, issuance.getParty().getOwningKey(), faceValue, maturityDate);
return new TransactionBuilder().withItems(state, new Command(new Commands.Issue(), issuance.getParty().getOwningKey()));
}
public void generateRedeem(TransactionBuilder tx, StateAndRef<State> paper, List<StateAndRef<Cash.State>> wallet) throws InsufficientBalanceException {
new Cash().generateSpend(tx, paper.getState().getFaceValue(), paper.getState().getOwner(), wallet, null);
tx.addInputState(paper.getRef());
tx.addCommand(new Command( new Commands.Redeem(), paper.getState().getOwner()));
tx.addCommand(new Command(new Commands.Redeem(), paper.getState().getOwner()));
}
public void generateMove(TransactionBuilder tx, StateAndRef<State> paper, PublicKey newOwner) {

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package contracts
import core.*
@ -144,7 +136,7 @@ class Cash : Contract {
// Now check the digital signatures on the move command. Every input has an owning public key, and we must
// see a signature from each of those keys. The actual signatures have been verified against the transaction
// data by the platform before execution.
val owningPubKeys = inputs.map { it.owner }.toSet()
val owningPubKeys = inputs.map { it.owner }.toSet()
val keysThatSigned = tx.commands.requireSingleCommand<Commands.Move>().signers.toSet()
requireThat {
"the owning keys are the same as the signing keys" by keysThatSigned.containsAll(owningPubKeys)
@ -246,10 +238,13 @@ class Cash : Contract {
/** Sums the cash states in the list that are owned by the given key, throwing an exception if there are none. */
fun Iterable<ContractState>.sumCashBy(owner: PublicKey) = filterIsInstance<Cash.State>().filter { it.owner == owner }.map { it.amount }.sumOrThrow()
/** Sums the cash states in the list, throwing an exception if there are none. */
fun Iterable<ContractState>.sumCash() = filterIsInstance<Cash.State>().map { it.amount }.sumOrThrow()
/** Sums the cash states in the list, returning null if there are none. */
fun Iterable<ContractState>.sumCashOrNull() = filterIsInstance<Cash.State>().map { it.amount }.sumOrNull()
/** Sums the cash states in the list, returning zero of the given currency if there are none. */
fun Iterable<ContractState>.sumCashOrZero(currency: Currency) = filterIsInstance<Cash.State>().map { it.amount }.sumOrZero(currency)

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package contracts
import core.*
@ -59,6 +51,7 @@ class CommercialPaper : Contract {
// Although kotlin is smart enough not to need these, as we are using the ICommercialPaperState, we need to declare them explicitly for use later,
override fun withOwner(newOwner: PublicKey): ICommercialPaperState = copy(owner = newOwner)
override fun withIssuance(newIssuance: PartyReference): ICommercialPaperState = copy(issuance = newIssuance)
override fun withFaceValue(newFaceValue: Amount): ICommercialPaperState = copy(faceValue = newFaceValue)
override fun withMaturityDate(newMaturityDate: Instant): ICommercialPaperState = copy(maturityDate = newMaturityDate)

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package contracts
import core.*
@ -63,8 +55,8 @@ class CrowdFund : Contract {
}
data class Pledge(
val owner: PublicKey,
val amount: Amount
val owner: PublicKey,
val amount: Amount
)

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package contracts
import core.*

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package contracts
import core.*
@ -465,7 +457,8 @@ class InterestRateSwap() : Contract {
override val parties: Array<Party>
get() = arrayOf(fixedLeg.fixedRatePayer, floatingLeg.floatingRatePayer)
override fun withPublicKey(before: Party, after: PublicKey): State {
// TODO: This changing of the public key violates the assumption that Party is a fixed identity key.
override fun withPublicKey(before: Party, after: PublicKey): DealState {
val newParty = Party(before.name, after)
if (before == fixedLeg.fixedRatePayer) {
val deal = copy()

View File

@ -1,15 +1,7 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package contracts
fun InterestRateSwap.State.exportIRSToCSV() : String =
"Fixed Leg\n" + FixedRatePaymentEvent.CSVHeader + "\n" +
this.calculation.fixedLegPaymentSchedule.toSortedMap().values.map{ it.asCSV() }.joinToString("\n") + "\n" +
"Floating Leg\n" + FloatingRatePaymentEvent.CSVHeader + "\n" +
this.calculation.floatingLegPaymentSchedule.toSortedMap().values.map{ it.asCSV() }.joinToString("\n") + "\n"
fun InterestRateSwap.State.exportIRSToCSV(): String =
"Fixed Leg\n" + FixedRatePaymentEvent.CSVHeader + "\n" +
this.calculation.fixedLegPaymentSchedule.toSortedMap().values.map { it.asCSV() }.joinToString("\n") + "\n" +
"Floating Leg\n" + FloatingRatePaymentEvent.CSVHeader + "\n" +
this.calculation.floatingLegPaymentSchedule.toSortedMap().values.map { it.asCSV() }.joinToString("\n") + "\n"

View File

@ -13,7 +13,7 @@ import java.security.PublicKey
open class RatioUnit(value: BigDecimal) { // TODO: Discuss this type
val value = value
override fun equals(other: Any?): Boolean{
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other?.javaClass != javaClass) return false
@ -24,7 +24,7 @@ open class RatioUnit(value: BigDecimal) { // TODO: Discuss this type
return true
}
override fun hashCode(): Int{
override fun hashCode(): Int {
return value.hashCode()
}
@ -34,7 +34,7 @@ open class RatioUnit(value: BigDecimal) { // TODO: Discuss this type
* A class to reprecent a percentage in an unambiguous way.
*/
open class PercentageRatioUnit(percentageAsString: String) : RatioUnit(BigDecimal(percentageAsString).divide(BigDecimal("100"))) {
override fun toString(): String = value.times(BigDecimal(100)).toString()+"%"
override fun toString(): String = value.times(BigDecimal(100)).toString() + "%"
}
/**
@ -45,8 +45,8 @@ open class PercentageRatioUnit(percentageAsString: String) : RatioUnit(BigDecima
val String.percent: PercentageRatioUnit get() = PercentageRatioUnit(this)
/**
* Interface representing an agreement that exposes various attributes that are common and allow
* implementation of general protocols that manipulate many agreement types
* Interface representing an agreement that exposes various attributes that are common. Implementing it simplifies
* implementation of general protocols that manipulate many agreement types.
*/
interface DealState : LinearState {
@ -56,7 +56,7 @@ interface DealState : LinearState {
/** Exposes the Parties involved in a generic way */
val parties: Array<Party>
/** Allow swapping in of potentially transaction specific public keys prior to signing */
// TODO: This works by editing the keys used by a Party which is invalid.
fun withPublicKey(before: Party, after: PublicKey): DealState
/**
@ -95,8 +95,7 @@ interface FixableDealState : DealState {
* Parent of the Rate family. Used to denote fixed rates, floating rates, reference rates etc
*/
open class Rate(val ratioUnit: RatioUnit? = null) {
override fun equals(other: Any?): Boolean{
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other?.javaClass != javaClass) return false
@ -112,7 +111,7 @@ open class Rate(val ratioUnit: RatioUnit? = null) {
* that have not yet happened. Yet-to-be fixed floating rates need to be equal such that schedules can be tested
* for equality.
*/
override fun hashCode(): Int{
override fun hashCode(): Int {
return ratioUnit?.hashCode() ?: 0
}
}
@ -127,7 +126,7 @@ class FixedRate(ratioUnit: RatioUnit) : Rate(ratioUnit) {
/**
* The parent class of the Floating rate classes
*/
open class FloatingRate: Rate(null)
open class FloatingRate : Rate(null)
/**
* So a reference rate is a rate that takes its value from a source at a given date

View File

@ -1,17 +1,10 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.crypto;
public class AddressFormatException extends IllegalArgumentException {
public AddressFormatException() {
super();
}
public AddressFormatException(String message) {
super(message);
}

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.crypto;
import java.math.*;
@ -19,7 +11,7 @@ import java.util.*;
* Satoshi explains: why base-58 instead of standard base-64 encoding?
* <ul>
* <li>Don't want 0OIl characters that look the same in some fonts and
* could be used to create visually identical looking account numbers.</li>
* could be used to create visually identical looking account numbers.</li>
* <li>A string with non-alphanumeric characters is not as easily accepted as an account number.</li>
* <li>E-mail usually won't line-break if there's no punctuation to break at.</li>
* <li>Doubleclicking selects the whole number as one word if it's all alphanumeric.</li>
@ -31,7 +23,7 @@ import java.util.*;
* base-256 digits, convert the number to be represented using base-58 digits, preserve the exact
* number of leading zeros (which are otherwise lost during the mathematical operations on the
* numbers), and finally represent the resulting base-58 digits as alphanumeric ASCII characters.
*
* <p>
* NB: This class originally comes from the Apache licensed bitcoinj library. The original author of this code is the
* same as the original author of the R3 repository.
*/
@ -39,6 +31,7 @@ public class Base58 {
public static final char[] ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".toCharArray();
private static final char ENCODED_ZERO = ALPHABET[0];
private static final int[] INDEXES = new int[128];
static {
Arrays.fill(INDEXES, -1);
for (int i = 0; i < ALPHABET.length; i++) {
@ -55,7 +48,7 @@ public class Base58 {
public static String encode(byte[] input) {
if (input.length == 0) {
return "";
}
}
// Count leading zeros.
int zeros = 0;
while (zeros < input.length && input[zeros] == 0) {
@ -124,7 +117,7 @@ public class Base58 {
// Return decoded data (including original number of leading zeros).
return Arrays.copyOfRange(decoded, outputStart - zeros, decoded.length);
}
public static BigInteger decodeToBigInteger(String input) throws AddressFormatException {
return new BigInteger(1, decode(input));
}
@ -138,7 +131,7 @@ public class Base58 {
* @throws AddressFormatException if the input is not base 58 or the checksum does not validate.
*/
public static byte[] decodeChecked(String input) throws AddressFormatException {
byte[] decoded = decode(input);
byte[] decoded = decode(input);
if (decoded.length < 4)
throw new AddressFormatException("Input too short");
byte[] data = Arrays.copyOfRange(decoded, 0, decoded.length - 4);
@ -154,11 +147,11 @@ public class Base58 {
* in the specified base, by the given divisor. The given number is modified in-place
* to contain the quotient, and the return value is the remainder.
*
* @param number the number to divide
* @param number the number to divide
* @param firstDigit the index within the array of the first non-zero digit
* (this is used for optimization by skipping the leading zeros)
* @param base the base in which the number's digits are represented (up to 256)
* @param divisor the number to divide by (up to 256)
* (this is used for optimization by skipping the leading zeros)
* @param base the base in which the number's digits are represented (up to 256)
* @param divisor the number to divide by (up to 256)
* @return the remainder of the division operation
*/
private static byte divmod(byte[] number, int firstDigit, int base, int divisor) {

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core
import java.security.PublicKey
@ -43,6 +35,7 @@ class Requirements {
if (!expr) throw IllegalArgumentException("Failed requirement: $this")
}
}
val R = Requirements()
inline fun <R> requireThat(body: Requirements.() -> R) = R.body()

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core
import com.fasterxml.jackson.core.JsonGenerator
@ -46,7 +38,7 @@ data class Amount(val pennies: Long, val currency: Currency) : Comparable<Amount
require(pennies >= 0) { "Negative amounts are not allowed: $pennies" }
}
constructor(amount:BigDecimal, currency: Currency) : this(amount.toLong(), currency)
constructor(amount: BigDecimal, currency: Currency) : this(amount.toLong(), currency)
operator fun plus(other: Amount): Amount {
checkCurrency(other)
@ -87,6 +79,7 @@ fun Iterable<Amount>.sumOrZero(currency: Currency) = if (iterator().hasNext()) s
/** A [FixOf] identifies the question side of a fix: what day, tenor and type of fix ("LIBOR", "EURIBOR" etc) */
data class FixOf(val name: String, val forDay: LocalDate, val ofTenor: Tenor)
/** A [Fix] represents a named interest rate, on a given day, for a given duration. It can be embedded in a tx. */
data class Fix(val of: FixOf, val value: BigDecimal) : CommandData
@ -98,13 +91,13 @@ data class Fix(val of: FixOf, val value: BigDecimal) : CommandData
@JsonSerialize(using = ExpressionSerializer::class)
data class Expression(val expr: String)
object ExpressionSerializer: JsonSerializer<Expression>() {
object ExpressionSerializer : JsonSerializer<Expression>() {
override fun serialize(expr: Expression, generator: JsonGenerator, provider: SerializerProvider) {
generator.writeString(expr.expr)
}
}
object ExpressionDeserializer: JsonDeserializer<Expression>() {
object ExpressionDeserializer : JsonDeserializer<Expression>() {
override fun deserialize(parser: JsonParser, context: DeserializationContext): Expression {
return Expression(parser.text)
}
@ -112,13 +105,14 @@ object ExpressionDeserializer: JsonDeserializer<Expression>() {
/**
* Placeholder class for the Tenor datatype - which is a standardised duration of time until maturity */
data class Tenor(val name:String) {
data class Tenor(val name: String) {
init {
val verifier = Regex("([0-9])+([DMYW])") // Only doing Overnight, Day, Week, Month, Year for now.
if (!(name == "ON" || verifier.containsMatchIn(name))) {
throw IllegalArgumentException("Unrecognized tenor : $name")
}
}
override fun toString(): String = "$name"
}
@ -126,7 +120,7 @@ data class Tenor(val name:String) {
* We don't actually do anything with this yet though, so it's ignored for now.
*/
enum class AccrualAdjustment {
Adjusted,Unadjusted
Adjusted, Unadjusted
}
/** This is utilised in the [DateRollConvention] class to determine which way we should initially step when
@ -184,7 +178,9 @@ enum class DateRollConvention {
* in the toString lest some people get confused. */
enum class DayCountBasisDay {
// We have to prefix 30 etc with a letter due to enum naming constraints.
D30, D30N, D30P, D30E, D30G, DActual, DActualJ, D30Z, D30F, DBus_SaoPaulo;
D30,
D30N, D30P, D30E, D30G, DActual, DActualJ, D30Z, D30F, DBus_SaoPaulo;
override fun toString(): String {
return super.toString().drop(1)
}
@ -193,7 +189,9 @@ enum class DayCountBasisDay {
/** This forms the year part of the "Day Count Basis" used for interest calculation. */
enum class DayCountBasisYear {
// Ditto above comment for years.
Y360, Y365F, Y365L, Y365Q, Y366, YActual, YActualA, Y365B, Y365, YISMA, YICMA, Y252;
Y360,
Y365F, Y365L, Y365Q, Y366, YActual, YActualA, Y365B, Y365, YISMA, YICMA, Y252;
override fun toString(): String {
return super.toString().drop(1)
}
@ -210,7 +208,8 @@ enum class PaymentRule {
*/
enum class DateOffset {
// TODO: Definitely shouldn't be an enum, but let's leave it for now at T-2 is a convention.
ZERO, TWODAYS,
ZERO,
TWODAYS,
}
@ -237,6 +236,7 @@ enum class Frequency(val annualCompoundCount: Int) {
BiWeekly(26) {
override fun offset(d: LocalDate) = d.plusWeeks(2)
};
abstract fun offset(d: LocalDate): LocalDate
// Daily() // Let's not worry about this for now.
}
@ -252,10 +252,10 @@ fun LocalDate.isWorkingDay(accordingToCalendar: BusinessCalendar): Boolean = acc
* no staff are around to handle problems.
*/
open class BusinessCalendar private constructor(val calendars: Array<out String>, val holidayDates: List<LocalDate>) {
class UnknownCalendar(name: String): Exception("$name not found")
class UnknownCalendar(name: String) : Exception("$name not found")
companion object {
val calendars = listOf("London","NewYork")
val calendars = listOf("London", "NewYork")
val TEST_CALENDAR_DATA = calendars.map {
it to BusinessCalendar::class.java.getResourceAsStream("${it}HolidayCalendar.txt").bufferedReader().readText()
@ -268,7 +268,7 @@ open class BusinessCalendar private constructor(val calendars: Array<out String>
fun getInstance(vararg calname: String) = BusinessCalendar(calname,
calname.flatMap { (TEST_CALENDAR_DATA[it] ?: throw UnknownCalendar(it)).split(",") }.
toSet().
map{ parseDateFromString(it) }.
map { parseDateFromString(it) }.
toList().sorted()
)

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core
import core.crypto.SecureHash
@ -18,7 +10,6 @@ import java.io.OutputStream
import java.security.PublicKey
import java.time.Duration
import java.time.Instant
import java.time.LocalDate
import java.util.jar.JarInputStream
/** Implemented by anything that can be named by a secure hash value (e.g. transactions, attachments). */
@ -51,7 +42,7 @@ interface OwnableState : ContractState {
*
* This simplifies the job of tracking the current version of certain types of state in e.g. a wallet
*/
interface LinearState: ContractState {
interface LinearState : ContractState {
/** Unique thread id within the wallets of all parties */
val thread: SecureHash
@ -73,8 +64,13 @@ data class StateRef(val txhash: SecureHash, val index: Int) {
/** A StateAndRef is simply a (state, ref) pair. For instance, a wallet (which holds available assets) contains these. */
data class StateAndRef<out T : ContractState>(val state: T, val ref: StateRef)
/** Filters a list of [StateAndRef] objects according to the type of the states */
inline fun <reified T : ContractState> List<StateAndRef<ContractState>>.filterStatesOfType(): List<StateAndRef<T>> {
return mapNotNull { if (it.state is T) StateAndRef(it.state, it.ref) else null }
}
/** A [Party] is well known (name, pubkey) pair. In a real system this would probably be an X.509 certificate. */
data class Party(val name: String, val owningKey: PublicKey) {
data class Party(val name: String, val owningKey: PublicKey) {
override fun toString() = name
fun ref(bytes: OpaqueBytes) = PartyReference(this, bytes)
@ -103,6 +99,7 @@ data class Command(val data: CommandData, val pubkeys: List<PublicKey>) {
init {
require(pubkeys.isNotEmpty())
}
constructor(data: CommandData, key: PublicKey) : this(data, listOf(key))
private fun commandDataToString() = data.toString().let { if (it.contains("@")) it.replace('$', '.').split("@")[0] else it }
@ -111,10 +108,10 @@ data class Command(val data: CommandData, val pubkeys: List<PublicKey>) {
/** Wraps an object that was signed by a public key, which may be a well known/recognised institutional key. */
data class AuthenticatedObject<out T : Any>(
val signers: List<PublicKey>,
/** If any public keys were recognised, the looked up institutions are available here */
val signingParties: List<Party>,
val value: T
val signers: List<PublicKey>,
/** If any public keys were recognised, the looked up institutions are available here */
val signingParties: List<Party>,
val value: T
)
/**

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core
import core.crypto.SecureHash
@ -25,7 +17,7 @@ import java.util.concurrent.Callable
class TransactionGraphSearch(val transactions: Map<SecureHash, SignedTransaction>,
val startPoints: List<WireTransaction>) : Callable<List<WireTransaction>> {
class Query(
val withCommandOfType: Class<out CommandData>? = null
val withCommandOfType: Class<out CommandData>? = null
)
var query: Query = Query()

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core
import core.crypto.SecureHash

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core
import co.paralleluniverse.fibers.Suspendable
@ -106,7 +98,9 @@ data class WireTransaction(val inputs: List<StateRef>,
/** Container for a [WireTransaction] and attached signatures. */
data class SignedTransaction(val txBits: SerializedBytes<WireTransaction>,
val sigs: List<DigitalSignature.WithKey>) : NamedByHash {
init { check(sigs.isNotEmpty()) }
init {
check(sigs.isNotEmpty())
}
/** Lazily calculated access to the deserialised/hashed transaction data. */
val tx: WireTransaction by lazy { WireTransaction.deserialize(txBits) }
@ -300,6 +294,7 @@ class TransactionBuilder(private val inputs: MutableList<StateRef> = arrayListOf
// Accessors that yield immutable snapshots.
fun inputStates(): List<StateRef> = ArrayList(inputs)
fun outputStates(): List<ContractState> = ArrayList(outputs)
fun commands(): List<Command> = ArrayList(commands)
fun attachments(): List<SecureHash> = ArrayList(attachments)

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core
import com.google.common.io.ByteStreams
@ -46,13 +38,24 @@ fun random63BitValue(): Long = Math.abs(SecureRandom.getInstanceStrong().nextLon
// Some utilities for working with Guava listenable futures.
fun <T> ListenableFuture<T>.then(executor: Executor, body: () -> Unit) = addListener(Runnable(body), executor)
fun <T> ListenableFuture<T>.success(executor: Executor, body: (T) -> Unit) = then(executor) {
val r = try { get() } catch(e: Throwable) { return@then }
val r = try {
get()
} catch(e: Throwable) {
return@then
}
body(r)
}
fun <T> ListenableFuture<T>.failure(executor: Executor, body: (Throwable) -> Unit) = then(executor) {
try { get() } catch(e: Throwable) { body(e) }
try {
get()
} catch(e: Throwable) {
body(e)
}
}
infix fun <T> ListenableFuture<T>.then(body: () -> Unit): ListenableFuture<T> = apply { then(RunOnCallerThread, body) }
infix fun <T> ListenableFuture<T>.success(body: (T) -> Unit): ListenableFuture<T> = apply { success(RunOnCallerThread, body) }
infix fun <T> ListenableFuture<T>.failure(body: (Throwable) -> Unit): ListenableFuture<T> = apply { failure(RunOnCallerThread, body) }

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.crypto
import com.google.common.io.BaseEncoding
@ -18,7 +10,10 @@ import java.security.interfaces.ECPublicKey
// "sealed" here means there can't be any subclasses other than the ones defined here.
sealed class SecureHash private constructor(bits: ByteArray) : OpaqueBytes(bits) {
class SHA256(bits: ByteArray) : SecureHash(bits) {
init { require(bits.size == 32) }
init {
require(bits.size == 32)
}
override val signatureAlgorithmName: String get() = "SHA256withECDSA"
}
@ -97,6 +92,7 @@ fun PrivateKey.signWithECDSA(bits: ByteArray): DigitalSignature {
fun PrivateKey.signWithECDSA(bitsToSign: ByteArray, publicKey: PublicKey): DigitalSignature.WithKey {
return DigitalSignature.WithKey(publicKey, signWithECDSA(bitsToSign).bits)
}
fun KeyPair.signWithECDSA(bitsToSign: ByteArray) = private.signWithECDSA(bitsToSign, public)
fun KeyPair.signWithECDSA(bitsToSign: OpaqueBytes) = private.signWithECDSA(bitsToSign.bits, public)
fun KeyPair.signWithECDSA(bitsToSign: OpaqueBytes, party: Party) = signWithECDSA(bitsToSign.bits, party)
@ -124,6 +120,7 @@ fun PublicKey.toStringShort(): String {
// Allow Kotlin destructuring: val (private, public) = keypair
operator fun KeyPair.component1() = this.private
operator fun KeyPair.component2() = this.public
/** A simple wrapper that will make it easier to swap out the EC algorithm we use in future */

View File

@ -43,7 +43,7 @@ class CubicSplineInterpolator(private val xs: DoubleArray, private val ys: Doubl
val z = DoubleArray(n)
for (i in 1..n - 1) {
val l = 2 * (xs[i + 1] - xs[i - 1]) - h[i - 1] * m[i - 1]
m[i] = h[i]/l
m[i] = h[i] / l
z[i] = (g[i] - h[i - 1] * z[i - 1]) / l
}
for (j in n - 1 downTo 0) {

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.node.services
import core.Party

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.node.services
import co.paralleluniverse.fibers.Suspendable

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.serialization
import com.google.common.io.BaseEncoding
@ -17,13 +9,15 @@ import java.util.*
* functionality to Java, but it won't arrive for a few years yet!
*/
open class OpaqueBytes(val bits: ByteArray) {
init { check(bits.isNotEmpty()) }
init {
check(bits.isNotEmpty())
}
companion object {
fun of(vararg b: Byte) = OpaqueBytes(byteArrayOf(*b))
}
override fun equals(other: Any?): Boolean{
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is OpaqueBytes) return false
return Arrays.equals(bits, other.bits)

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.serialization
import co.paralleluniverse.fibers.Fiber
@ -81,12 +73,15 @@ inline fun <reified T : Any> ByteArray.deserialize(kryo: Kryo = THREAD_LOCAL_KRY
else
return kryo.readObject(Input(this), T::class.java)
}
inline fun <reified T : Any> OpaqueBytes.deserialize(kryo: Kryo = THREAD_LOCAL_KRYO.get(), includeClassName: Boolean = false): T {
return this.bits.deserialize(kryo, includeClassName)
}
// The more specific deserialize version results in the bytes being cached, which is faster.
@JvmName("SerializedBytesWireTransaction")
fun SerializedBytes<WireTransaction>.deserialize(kryo: Kryo = THREAD_LOCAL_KRYO.get()): WireTransaction = WireTransaction.deserialize(this, kryo)
inline fun <reified T : Any> SerializedBytes<T>.deserialize(kryo: Kryo = THREAD_LOCAL_KRYO.get(), includeClassName: Boolean = false): T = bits.deserialize(kryo, includeClassName)
/**
@ -175,7 +170,11 @@ class ImmutableClassSerializer<T : Any>(val klass: KClass<T>) : Serializer<T>()
}
}
// If the constructor throws an exception, pass it through instead of wrapping it.
return try { constructor.call(*args) } catch (e: InvocationTargetException) { throw e.cause!! }
return try {
constructor.call(*args)
} catch (e: InvocationTargetException) {
throw e.cause!!
}
}
}
@ -198,7 +197,7 @@ fun createKryo(k: Kryo = Kryo()): Kryo {
// no-arg constructor available.
instantiatorStrategy = Kryo.DefaultInstantiatorStrategy(StdInstantiatorStrategy())
register(Arrays.asList( "" ).javaClass, ArraysAsListSerializer());
register(Arrays.asList("").javaClass, ArraysAsListSerializer());
// Because we like to stick a Kryo object in a ThreadLocal to speed things up a bit, we can end up trying to
// serialise the Kryo object itself when suspending a fiber. That's dumb, useless AND can cause crashes, so
@ -252,8 +251,8 @@ fun createKryo(k: Kryo = Kryo()): Kryo {
// Some classes have to be handled with the ImmutableClassSerializer because they need to have their
// constructors be invoked (typically for lazy members).
val immutables = listOf(
SignedTransaction::class,
SerializedBytes::class
SignedTransaction::class,
SerializedBytes::class
)
immutables.forEach {

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.utilities
/**

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.utilities
import core.TransientProperty
@ -45,9 +37,11 @@ class ProgressTracker(vararg steps: Step) {
class Position(val tracker: ProgressTracker, val newStep: Step) : Change() {
override fun toString() = newStep.label
}
class Rendering(val tracker: ProgressTracker, val ofStep: Step) : Change() {
override fun toString() = ofStep.label
}
class Structural(val tracker: ProgressTracker, val parent: Step) : Change() {
override fun toString() = "Structural step change in child of ${parent.label}"
}
@ -75,6 +69,7 @@ class ProgressTracker(vararg steps: Step) {
object UNSTARTED : Step("Unstarted") {
override fun equals(other: Any?) = other is UNSTARTED
}
object DONE : Step("Done") {
override fun equals(other: Any?) = other is DONE
}

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core
import org.junit.Test
@ -25,7 +17,7 @@ class FinanceTypesTest {
@Test
fun `valid tenor tests`() {
val exampleTenors = ("ON,1D,2D,3D,4D,5D,6D,7D,1W,2W,3W,1M,3M,6M,1Y,2Y,3Y,5Y,10Y,12Y,20Y").split(",")
exampleTenors.all { Tenor(it).name.length > 0 } // Slightly obtuse way of ensuring no exception thrown in construction.
exampleTenors.all { Tenor(it).name.length > 0 } // Slightly obtuse way of ensuring no exception thrown in construction.
}
@Test
@ -40,7 +32,7 @@ class FinanceTypesTest {
fun `schedule generator 1`() {
var ret = BusinessCalendar.createGenericSchedule(startDate = LocalDate.of(2014, 11, 25), period = Frequency.Monthly, noOfAdditionalPeriods = 3)
// We know that Jan 25th 2015 is on the weekend -> It should not be in this list returned.
assert(! (LocalDate.of(2015,1,25) in ret))
assert(!(LocalDate.of(2015, 1, 25) in ret))
println(ret)
}
@ -48,61 +40,61 @@ class FinanceTypesTest {
fun `schedule generator 2`() {
var ret = BusinessCalendar.createGenericSchedule(startDate = LocalDate.of(2015, 11, 25), period = Frequency.Monthly, noOfAdditionalPeriods = 3, calendar = BusinessCalendar.getInstance("London"), dateRollConvention = DateRollConvention.Following)
// Xmas should not be in the list!
assert(! (LocalDate.of(2015,12,25) in ret))
assert(!(LocalDate.of(2015, 12, 25) in ret))
println(ret)
}
@Test
fun `create a UK calendar` () {
fun `create a UK calendar`() {
val cal = BusinessCalendar.getInstance("London")
val holdates = cal.holidayDates
println(holdates)
assert(LocalDate.of(2016,12,27) in holdates) // Christmas this year is at the weekend...
assert(LocalDate.of(2016, 12, 27) in holdates) // Christmas this year is at the weekend...
}
@Test
fun `create a US UK calendar`() {
val cal = BusinessCalendar.getInstance("London","NewYork")
assert(LocalDate.of(2016,7,4) in cal.holidayDates) // The most American of holidays
assert(LocalDate.of(2016,8,29) in cal.holidayDates) // August Bank Holiday for brits only
val cal = BusinessCalendar.getInstance("London", "NewYork")
assert(LocalDate.of(2016, 7, 4) in cal.holidayDates) // The most American of holidays
assert(LocalDate.of(2016, 8, 29) in cal.holidayDates) // August Bank Holiday for brits only
println("Calendar contains both US and UK holidays")
}
@Test
fun `calendar test of modified following` () {
fun `calendar test of modified following`() {
val ldn = BusinessCalendar.getInstance("London")
val result = ldn.applyRollConvention(LocalDate.of(2016,12,25),DateRollConvention.ModifiedFollowing)
assert(result == LocalDate.of(2016,12,28))
val result = ldn.applyRollConvention(LocalDate.of(2016, 12, 25), DateRollConvention.ModifiedFollowing)
assert(result == LocalDate.of(2016, 12, 28))
}
@Test
fun `calendar test of modified following pt 2` () {
fun `calendar test of modified following pt 2`() {
val ldn = BusinessCalendar.getInstance("London")
val result = ldn.applyRollConvention(LocalDate.of(2016,12,31),DateRollConvention.ModifiedFollowing)
assert(result == LocalDate.of(2016,12,30))
val result = ldn.applyRollConvention(LocalDate.of(2016, 12, 31), DateRollConvention.ModifiedFollowing)
assert(result == LocalDate.of(2016, 12, 30))
}
@Test
fun `calendar test of modified previous` () {
fun `calendar test of modified previous`() {
val ldn = BusinessCalendar.getInstance("London")
val result = ldn.applyRollConvention(LocalDate.of(2016,1,1),DateRollConvention.ModifiedPrevious)
assert(result == LocalDate.of(2016,1,4))
val result = ldn.applyRollConvention(LocalDate.of(2016, 1, 1), DateRollConvention.ModifiedPrevious)
assert(result == LocalDate.of(2016, 1, 4))
}
@Test
fun `calendar test of previous` () {
fun `calendar test of previous`() {
val ldn = BusinessCalendar.getInstance("London")
val result = ldn.applyRollConvention(LocalDate.of(2016,12,25),DateRollConvention.Previous)
assert(result == LocalDate.of(2016,12,23))
val result = ldn.applyRollConvention(LocalDate.of(2016, 12, 25), DateRollConvention.Previous)
assert(result == LocalDate.of(2016, 12, 23))
}
@Test
fun `calendar test of following` () {
fun `calendar test of following`() {
val ldn = BusinessCalendar.getInstance("London")
val result = ldn.applyRollConvention(LocalDate.of(2016,12,25),DateRollConvention.Following)
assert(result == LocalDate.of(2016,12,28))
val result = ldn.applyRollConvention(LocalDate.of(2016, 12, 25), DateRollConvention.Following)
assert(result == LocalDate.of(2016, 12, 28))
}
@Test
@ -147,5 +139,4 @@ class FinanceTypesTest {
}
}

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.utilities
import org.apache.commons.jexl3.JexlBuilder

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.utilities
import org.junit.Before

View File

@ -1,11 +1,3 @@
/*
* Copyright 2016 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package api
import core.ContractState

View File

@ -2,10 +2,14 @@ package api
import com.google.common.util.concurrent.ListenableFuture
import contracts.DealState
import core.*
import core.ContractState
import core.SignedTransaction
import core.StateRef
import core.WireTransaction
import core.crypto.DigitalSignature
import core.crypto.SecureHash
import core.node.AbstractNode
import core.node.services.linearHeadsOfType
import core.protocols.ProtocolLogic
import core.serialization.SerializedBytes
import core.utilities.ANSIProgressRenderer
@ -14,7 +18,7 @@ import java.util.*
import kotlin.reflect.KParameter
import kotlin.reflect.jvm.javaType
class APIServerImpl(val node: AbstractNode): APIServer {
class APIServerImpl(val node: AbstractNode) : APIServer {
override fun serverTime(): LocalDateTime = LocalDateTime.now(node.services.clock)
@ -26,10 +30,9 @@ class APIServerImpl(val node: AbstractNode): APIServer {
if (query.criteria is StatesQuery.Criteria.AllDeals) {
val states = node.services.walletService.linearHeads
return states.values.map { it.ref }
}
else if (query.criteria is StatesQuery.Criteria.Deal) {
val states = node.services.walletService.linearHeadsInstanceOf(DealState::class.java) {
it.ref == query.criteria.ref
} else if (query.criteria is StatesQuery.Criteria.Deal) {
val states = node.services.walletService.linearHeadsOfType<DealState>().filterValues {
it.state.ref == query.criteria.ref
}
return states.values.map { it.ref }
}
@ -62,9 +65,9 @@ class APIServerImpl(val node: AbstractNode): APIServer {
}
private fun invokeProtocolAsync(type: ProtocolRef, args: Map<String, Any?>): ListenableFuture<out Any?> {
if(type is ProtocolClassRef) {
if (type is ProtocolClassRef) {
val clazz = Class.forName(type.className)
if(ProtocolLogic::class.java.isAssignableFrom(clazz)) {
if (ProtocolLogic::class.java.isAssignableFrom(clazz)) {
// TODO for security, check annotated as exposed on API? Or have PublicProtocolLogic... etc
nextConstructor@ for (constructor in clazz.kotlin.constructors) {
val params = HashMap<KParameter, Any?>()
@ -91,7 +94,7 @@ class APIServerImpl(val node: AbstractNode): APIServer {
// If we get here then we matched every parameter
val protocol = constructor.callBy(params) as ProtocolLogic<*>
ANSIProgressRenderer.progressTracker = protocol.progressTracker
val future = node.smm.add("api-call",protocol)
val future = node.smm.add("api-call", protocol)
return future
}
}

View File

@ -11,7 +11,7 @@ import javax.ws.rs.ext.Provider
* and to organise serializers / deserializers for java.time.* classes as necessary
*/
@Provider
class Config(val services: ServiceHub): ContextResolver<ObjectMapper> {
class Config(val services: ServiceHub) : ContextResolver<ObjectMapper> {
val defaultObjectMapper = JsonSupport.createDefaultMapper(services.identityService)
override fun getContext(type: java.lang.Class<*>) = defaultObjectMapper
}

View File

@ -36,13 +36,13 @@ class InterestRateSwapAPI(val api: APIServer) {
private val logger = loggerFor<InterestRateSwapAPI>()
private fun generateDealLink(deal: InterestRateSwap.State) = "/api/irs/deals/"+deal.common.tradeID
private fun generateDealLink(deal: InterestRateSwap.State) = "/api/irs/deals/" + deal.common.tradeID
private fun getDealByRef(ref: String): InterestRateSwap.State? {
val states = api.queryStates(StatesQuery.selectDeal(ref))
return if (states.isEmpty()) null else {
val deals = api.fetchStates(states).values.map { it as InterestRateSwap.State}.filterNotNull()
return if(deals.isEmpty()) null else deals[0]
val deals = api.fetchStates(states).values.map { it as InterestRateSwap.State }.filterNotNull()
return if (deals.isEmpty()) null else deals[0]
}
}
@ -83,7 +83,7 @@ class InterestRateSwapAPI(val api: APIServer) {
fun storeDemoDate(newDemoDate: LocalDate): Response {
val priorDemoDate = api.serverTime().toLocalDate()
// Can only move date forwards
if(newDemoDate.isAfter(priorDemoDate)) {
if (newDemoDate.isAfter(priorDemoDate)) {
api.invokeProtocolSync(ProtocolClassRef(UpdateBusinessDayProtocol.Broadcast::class.java.name!!), mapOf("date" to newDemoDate))
return Response.ok().build()
}

View File

@ -1,18 +1,9 @@
/*
* Copyright 2016 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package api
/**
* Extremely rudimentary query language which should most likely be replaced with a product
*/
interface StatesQuery {
companion object {
fun select(criteria: Criteria): Selection {
return Selection(criteria)
@ -29,13 +20,11 @@ interface StatesQuery {
}
// TODO make constructors private
data class Selection(val criteria: Criteria): StatesQuery
data class Selection(val criteria: Criteria) : StatesQuery
interface Criteria {
object AllDeals : Criteria
object AllDeals: Criteria
data class Deal(val ref: String): Criteria
data class Deal(val ref: String) : Criteria
}
}

View File

@ -9,7 +9,7 @@ import javax.ws.rs.ext.Provider
* This adds headers needed for cross site scripting on API clients
*/
@Provider
class ResponseFilter: ContainerResponseFilter {
class ResponseFilter : ContainerResponseFilter {
override fun filter(requestContext: ContainerRequestContext, responseContext: ContainerResponseContext) {
val headers = responseContext.headers
@ -21,9 +21,9 @@ class ResponseFilter: ContainerResponseFilter {
* access control and authentication at a network and software level
*
*/
headers.add("Access-Control-Allow-Origin","*")
headers.add("Access-Control-Allow-Origin", "*")
if(requestContext.method == "OPTIONS") {
if (requestContext.method == "OPTIONS") {
headers.add("Access-Control-Allow-Headers", "Content-Type,Accept,Origin")
headers.add("Access-Control-Allow-Methods", "POST,PUT,GET,OPTIONS")
}

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core
import core.node.services.AttachmentStorage

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.messaging
import com.google.common.util.concurrent.ListenableFuture
@ -128,9 +120,12 @@ object TopicStringValidator {
/** The interface for a group of message recipients (which may contain only one recipient) */
interface MessageRecipients
/** A base class for the case of point-to-point messages */
interface SingleMessageRecipient : MessageRecipients
/** A base class for a set of recipients specifically identified by the sender. */
interface MessageRecipientGroup : MessageRecipients
/** A special base class for the set of all possible recipients, without having to identify who they all are. */
interface AllPossibleRecipients : MessageRecipients

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.messaging
import co.paralleluniverse.fibers.Fiber
@ -68,22 +60,15 @@ class StateMachineManager(val serviceHub: ServiceHub, val runInThread: Executor)
// Monitoring support.
private val metrics = serviceHub.monitoringService.metrics
init { metrics.register("Protocols.InFlight", Gauge<kotlin.Int> { _stateMachines.size }) }
init {
metrics.register("Protocols.InFlight", Gauge<kotlin.Int> { _stateMachines.size })
}
private val checkpointingMeter = metrics.meter("Protocols.Checkpointing Rate")
private val totalStartedProtocols = metrics.counter("Protocols.Started")
private val totalFinishedProtocols = metrics.counter("Protocols.Finished")
// This is a workaround for something Gradle does to us during unit tests. It replaces stderr with its own
// class that inserts itself into a ThreadLocal. That then gets caught in fiber serialisation, which we don't
// want because it can't get recreated properly. It turns out there's no good workaround for this! All the obvious
// approaches fail. Pending resolution of https://github.com/puniverse/quasar/issues/153 we just disable
// checkpointing when unit tests are run inside Gradle. The right fix is probably to stop Quasar's
// bit-too-clever-for-its-own-good ThreadLocal serialisation trick. It already wasted far more time than it can
// ever recover.
//
// TODO: Remove this now that TLS serialisation is fixed.
val checkpointing: Boolean get() = !System.err.javaClass.name.contains("LinePerThreadBufferingOutputStream")
/** Returns a list of all state machines executing the given protocol logic at the top level (subprotocols do not count) */
fun <T> findStateMachines(klass: Class<out ProtocolLogic<T>>): List<Pair<ProtocolLogic<T>, ListenableFuture<T>>> {
synchronized(_stateMachines) {
@ -101,19 +86,17 @@ class StateMachineManager(val serviceHub: ServiceHub, val runInThread: Executor)
// This class will be serialised, so everything it points to transitively must also be serialisable (with Kryo).
private class Checkpoint(
val serialisedFiber: ByteArray,
val loggerName: String,
val awaitingTopic: String,
val awaitingObjectOfType: String // java class name
val serialisedFiber: ByteArray,
val loggerName: String,
val awaitingTopic: String,
val awaitingObjectOfType: String // java class name
)
init {
// Blank out the default uncaught exception handler because we always catch things ourselves, and the default
// just redundantly prints stack traces to the logs.
Fiber.setDefaultUncaughtExceptionHandler { fiber, throwable -> }
if (checkpointing)
restoreCheckpoints()
Fiber.setDefaultUncaughtExceptionHandler { fiber, throwable -> }
restoreCheckpoints()
}
/** Reads the database map and resurrects any serialised state machines. */
@ -235,8 +218,7 @@ class StateMachineManager(val serviceHub: ServiceHub, val runInThread: Executor)
serialisedFiber: ByteArray) {
val checkpoint = Checkpoint(serialisedFiber, logger.name, topic, responseType.name)
val curPersistedBytes = checkpoint.serialize().bits
if (checkpointing)
persistCheckpoint(prevCheckpointKey, curPersistedBytes)
persistCheckpoint(prevCheckpointKey, curPersistedBytes)
val newCheckpointKey = curPersistedBytes.sha256()
net.runOnNextMessage(topic, runInThread) { netMsg ->
val obj: Any = THREAD_LOCAL_KRYO.get().readObject(Input(netMsg.data), responseType)

View File

@ -1,19 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.node
import api.APIServer

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.node
import java.io.InputStream

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.node
import api.Config

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.node
import com.typesafe.config.Config

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.node.services
import com.google.common.net.HostAndPort
@ -82,11 +74,13 @@ class ArtemisMessagingService(val directory: Path, val myHostPort: HostAndPort)
var running = false
val sendClients = HashMap<Address, ClientProducer>()
}
private val mutex = ThreadBox(InnerState())
/** A registration to handle messages of different types */
inner class Handler(val executor: Executor?, val topic: String,
val callback: (Message, MessageHandlerRegistration) -> Unit) : MessageHandlerRegistration
private val handlers = CopyOnWriteArrayList<Handler>()
private fun getSendClient(addr: Address): ClientProducer {

View File

@ -1,16 +1,5 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.node.services
import protocols.FetchAttachmentsProtocol
import protocols.FetchTransactionsProtocol
import core.node.services.StorageService
import core.crypto.SecureHash
import core.messaging.Message
import core.messaging.MessagingService
@ -18,6 +7,8 @@ import core.messaging.SingleMessageRecipient
import core.messaging.send
import core.serialization.deserialize
import core.utilities.loggerFor
import protocols.FetchAttachmentsProtocol
import protocols.FetchTransactionsProtocol
import java.io.InputStream
import javax.annotation.concurrent.ThreadSafe

View File

@ -1,14 +1,5 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.node.services
import core.node.services.KeyManagementService
import core.ThreadBox
import core.crypto.generateKeyPair
import java.security.KeyPair
@ -33,6 +24,7 @@ class E2ETestKeyManagementService : KeyManagementService {
private class InnerState {
val keys = HashMap<PublicKey, PrivateKey>()
}
private val mutex = ThreadBox(InnerState())
// Accessing this map clones it.

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.node.services
import core.Party

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.node.services
import core.Party
@ -27,7 +19,7 @@ data class NodeInfo(val address: SingleMessageRecipient, val identity: Party,
* then be cached by every node and thus a network map can be retrieved given only a single successful peer connection.
*
* This interface assumes fast, synchronous access to an in-memory map.
*/
*/
interface NetworkMapCache {
val timestampingNodes: List<NodeInfo>
val ratesOracleNodes: List<NodeInfo>
@ -39,7 +31,7 @@ interface NetworkMapCache {
// TODO: Move this to the test tree once a real network map is implemented and this scaffolding is no longer needed.
class MockNetworkMapCache : NetworkMapCache {
data class MockAddress(val id: String): SingleMessageRecipient
data class MockAddress(val id: String) : SingleMessageRecipient
override val timestampingNodes = Collections.synchronizedList(ArrayList<NodeInfo>())
override val ratesOracleNodes = Collections.synchronizedList(ArrayList<NodeInfo>())

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.node.services
import com.codahale.metrics.MetricRegistry
@ -98,6 +90,7 @@ class NodeAttachmentService(val storePath: Path, val metrics: MetricRegistry) :
stream = HashCheckingStream(id, path, stream)
return stream
}
override fun equals(other: Any?) = other is Attachment && other.id == id
override fun hashCode(): Int = id.hashCode()
}

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.node.services
import core.*
@ -51,8 +43,8 @@ object NodeInterestRates {
}
/** Parses lines containing fixes */
fun parseFile(s: String): Map<FixOf, TreeMap<LocalDate,Fix>> {
val results = HashMap<FixOf, TreeMap<LocalDate,Fix>>()
fun parseFile(s: String): Map<FixOf, TreeMap<LocalDate, Fix>> {
val results = HashMap<FixOf, TreeMap<LocalDate, Fix>>()
for (line in s.lines()) {
val (fixOf, fix) = parseOneRate(line)
val genericKey = FixOf(fixOf.name, LocalDate.MIN, fixOf.ofTenor)
@ -96,7 +88,7 @@ object NodeInterestRates {
override val acceptableFileExtensions = listOf(".rates", ".txt")
override fun upload(data: InputStream): String {
val fixes: Map<FixOf, TreeMap<LocalDate,Fix>> = parseFile(data.
val fixes: Map<FixOf, TreeMap<LocalDate, Fix>> = parseFile(data.
bufferedReader().
readLines().
map { it.trim() }.
@ -133,7 +125,7 @@ object NodeInterestRates {
* to a sorted map of LocalDate to Fix, allowing for approximate date finding so that we do not need
* to populate the file with a rate for every day.
*/
@Volatile var knownFixes = emptyMap<FixOf, TreeMap<LocalDate,Fix>>()
@Volatile var knownFixes = emptyMap<FixOf, TreeMap<LocalDate, Fix>>()
set(value) {
require(value.isNotEmpty())
field = value
@ -154,7 +146,7 @@ object NodeInterestRates {
val rates = knownFixes[FixOf(fixOf.name, LocalDate.MIN, fixOf.ofTenor)]
// Greatest key less than or equal to the date we're looking for
val floor = rates?.floorEntry(fixOf.forDay)?.value
return if (floor!=null) {
return if (floor != null) {
Fix(fixOf, floor.value)
} else {
null

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.node.services
import co.paralleluniverse.common.util.VisibleForTesting

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.node.services
import com.codahale.metrics.Gauge
@ -33,6 +25,7 @@ class NodeWalletService(private val services: ServiceHub) : WalletService {
private class InnerState {
var wallet: Wallet = Wallet(emptyList<StateAndRef<OwnableState>>())
}
private val mutex = ThreadBox(InnerState())
override val currentWallet: Wallet get() = mutex.locked { wallet }
@ -48,7 +41,7 @@ class NodeWalletService(private val services: ServiceHub) : WalletService {
*/
override val linearHeads: Map<SecureHash, StateAndRef<LinearState>>
get() = mutex.locked { wallet }.let { wallet ->
wallet.states.filter { it.state is LinearState }.associateBy { (it.state as LinearState).thread }.mapValues { it.value as StateAndRef<LinearState> }
wallet.states.filterStatesOfType<LinearState>().associateBy { it.state.thread }.mapValues { it.value }
}
override fun notifyAll(txns: Iterable<WireTransaction>): Wallet {
@ -78,9 +71,9 @@ class NodeWalletService(private val services: ServiceHub) : WalletService {
}
private fun isRelevant(state: ContractState, ourKeys: Set<PublicKey>): Boolean {
return if(state is OwnableState) {
return if (state is OwnableState) {
state.owner in ourKeys
} else if(state is LinearState) {
} else if (state is LinearState) {
// It's potentially of interest to the wallet
state.isRelevant(ourKeys)
} else {

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.node.services
import com.codahale.metrics.MetricRegistry
@ -40,12 +32,12 @@ data class Wallet(val states: List<StateAndRef<ContractState>>) {
* which we have no cash evaluate to null (not present in map), not 0.
*/
val cashBalances: Map<Currency, Amount> get() = states.
// Select the states we own which are cash, ignore the rest, take the amounts.
mapNotNull { (it.state as? Cash.State)?.amount }.
// Turn into a Map<Currency, List<Amount>> like { GBP -> (£100, £500, etc), USD -> ($2000, $50) }
groupBy { it.currency }.
// Collapse to Map<Currency, Amount> by summing all the amounts of the same currency together.
mapValues { it.value.sumOrThrow() }
// Select the states we own which are cash, ignore the rest, take the amounts.
mapNotNull { (it.state as? Cash.State)?.amount }.
// Turn into a Map<Currency, List<Amount>> like { GBP -> (£100, £500, etc), USD -> ($2000, $50) }
groupBy { it.currency }.
// Collapse to Map<Currency, Amount> by summing all the amounts of the same currency together.
mapValues { it.value.sumOrThrow() }
}
/**
@ -72,13 +64,17 @@ interface WalletService {
*/
val linearHeads: Map<SecureHash, StateAndRef<LinearState>>
fun <T : LinearState> linearHeadsInstanceOf(clazz: Class<T>, predicate: (T) -> Boolean = { true } ): Map<SecureHash, StateAndRef<T>> {
return linearHeads.filterValues { clazz.isInstance(it.state) }.filterValues { predicate(it.state as T) }.mapValues { StateAndRef(it.value.state as T, it.value.ref) }
// TODO: When KT-10399 is fixed, rename this and remove the inline version below.
/** Returns the [linearHeads] only when the type of the state would be considered an 'instanceof' the given type. */
@Suppress("UNCHECKED_CAST")
fun <T : LinearState> linearHeadsOfType_(stateType: Class<T>): Map<SecureHash, StateAndRef<T>> {
return linearHeads.filterValues { stateType.isInstance(it.state) }.mapValues { StateAndRef(it.value.state as T, it.value.ref) }
}
fun statesForRefs(refs: List<StateRef>): Map<StateRef, ContractState?> {
val refsToStates = currentWallet.states.associateBy { it.ref }
return refs.associateBy( { it }, { refsToStates[it]?.state } )
return refs.associateBy({ it }, { refsToStates[it]?.state })
}
/**
@ -95,17 +91,7 @@ interface WalletService {
fun notify(tx: WireTransaction): Wallet = notifyAll(listOf(tx))
}
// TODO: Document this
@Suppress("UNCHECKED_CAST")
inline fun <reified T : LinearState> WalletService.linearHeadsOfType(): Map<SecureHash, StateAndRef<T>> {
return linearHeads.mapNotNull {
val s = it.value.state
if (s is T)
Pair(it.key, it.value as StateAndRef<T>)
else
null
}.toMap()
}
inline fun <reified T : LinearState> WalletService.linearHeadsOfType() = linearHeadsOfType_(T::class.java)
/**
* The KMS is responsible for storing and using private keys to sign things. An implementation of this may, for example,

View File

@ -14,12 +14,13 @@ open class StorageServiceImpl(attachments: AttachmentStorage,
// This parameter is for unit tests that want to observe operation details.
val recordingAs: (String) -> String = { tableName -> "" })
: StorageService {
protected val tables = HashMap<String, MutableMap<Any, Any>>()
protected val tables = HashMap<String, MutableMap<*, *>>()
private fun <K, V> getMapOriginal(tableName: String): MutableMap<K, V> {
synchronized(tables) {
@Suppress("UNCHECKED_CAST")
return tables.getOrPut(tableName) {
recorderWrap(Collections.synchronizedMap(HashMap<Any, Any>()), tableName);
recorderWrap(Collections.synchronizedMap(HashMap<K, V>()), tableName)
} as MutableMap<K, V>
}
}

View File

@ -1,15 +1,7 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.node.servlets
import core.node.services.StorageService
import core.crypto.SecureHash
import core.node.services.StorageService
import core.utilities.loggerFor
import java.io.FileNotFoundException
import javax.servlet.http.HttpServlet

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.node.servlets
import core.node.AcceptsFileUpload
@ -26,7 +18,7 @@ class DataUploadServlet : HttpServlet() {
override fun doPost(req: HttpServletRequest, resp: HttpServletResponse) {
val node = servletContext.getAttribute("node") as Node
@Suppress("DEPRECATION") // Bogus warning due to superclass static method being deprecated.
@Suppress("DEPRECATION") // Bogus warning due to superclass static method being deprecated.
val isMultipart = ServletFileUpload.isMultipartContent(req)
if (!isMultipart) {

View File

@ -1,16 +1,8 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.protocols
import co.paralleluniverse.fibers.Suspendable
import core.node.services.ServiceHub
import core.messaging.MessageRecipients
import core.node.services.ServiceHub
import core.utilities.ProgressTracker
import core.utilities.UntrustworthyData
import org.slf4j.Logger
@ -47,12 +39,15 @@ abstract class ProtocolLogic<T> {
sessionIDForReceive: Long, obj: Any): UntrustworthyData<T> {
return psm.sendAndReceive(topic, destination, sessionIDForSend, sessionIDForReceive, obj, T::class.java)
}
inline fun <reified T : Any> receive(topic: String, sessionIDForReceive: Long): UntrustworthyData<T> {
return receive(topic, sessionIDForReceive, T::class.java)
}
@Suspendable fun <T : Any> receive(topic: String, sessionIDForReceive: Long, clazz: Class<T>): UntrustworthyData<T> {
return psm.receive(topic, sessionIDForReceive, clazz)
}
@Suspendable fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any) {
psm.send(topic, destination, sessionID, obj)
}

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.protocols
import co.paralleluniverse.fibers.Fiber
@ -14,9 +6,9 @@ import co.paralleluniverse.io.serialization.kryo.KryoSerializer
import com.esotericsoftware.kryo.io.Output
import com.google.common.util.concurrent.ListenableFuture
import com.google.common.util.concurrent.SettableFuture
import core.node.services.ServiceHub
import core.messaging.MessageRecipients
import core.messaging.StateMachineManager
import core.node.services.ServiceHub
import core.serialization.createKryo
import core.utilities.UntrustworthyData
import org.slf4j.Logger

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.testing
import com.fasterxml.jackson.module.kotlin.readValue

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.testing
import com.google.common.util.concurrent.Futures
@ -59,7 +51,7 @@ class InMemoryMessagingNetwork {
*/
@Synchronized
fun createNode(manuallyPumped: Boolean): Pair<Handle, MessagingServiceBuilder<InMemoryMessaging>> {
check(counter >= 0) { "In memory network stopped: please recreate."}
check(counter >= 0) { "In memory network stopped: please recreate." }
val builder = createNodeWithID(manuallyPumped, counter) as Builder
counter++
val id = builder.id
@ -89,15 +81,15 @@ class InMemoryMessagingNetwork {
if (calc != null && recipients is SingleMessageRecipient) {
// Inject some artificial latency.
timer.schedule(calc.between(from.myAddress, recipients).toMillis()) {
msgSendInternal(from, message, recipients)
msgSendInternal(message, recipients)
}
} else {
msgSendInternal(from, message, recipients)
msgSendInternal(message, recipients)
}
_allMessages.onNext(Triple(from.myAddress, message, recipients))
}
private fun msgSendInternal(from: InMemoryMessaging, message: Message, recipients: MessageRecipients) {
private fun msgSendInternal(message: Message, recipients: MessageRecipients) {
when (recipients) {
is Handle -> getQueueForHandle(recipients).add(message)
@ -170,15 +162,18 @@ class InMemoryMessagingNetwork {
* An instance can be obtained by creating a builder and then using the start method.
*/
@ThreadSafe
inner class InMemoryMessaging(private val manuallyPumped: Boolean, private val handle: Handle): MessagingService {
inner class InMemoryMessaging(private val manuallyPumped: Boolean, private val handle: Handle) : MessagingService {
inner class Handler(val executor: Executor?, val topic: String,
val callback: (Message, MessageHandlerRegistration) -> Unit) : MessageHandlerRegistration
@Volatile
protected var running = true
protected inner class InnerState {
val handlers: MutableList<Handler> = ArrayList()
val pendingRedelivery = LinkedList<Message>()
}
protected val state = ThreadBox(InnerState())
override val myAddress: SingleMessageRecipient = handle

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.testing
import com.google.common.jimfs.Jimfs
@ -124,7 +116,8 @@ class MockNetwork(private val threadPerNode: Boolean = false,
fun runNetwork(rounds: Int = -1) {
fun pumpAll() = messagingNetwork.endpoints.map { it.pump(false) }
if (rounds == -1)
while (pumpAll().any { it }) {}
while (pumpAll().any { it }) {
}
else
repeat(rounds) { pumpAll() }
}

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.testing
import com.google.common.util.concurrent.ListenableFuture
@ -30,7 +22,7 @@ import java.util.*
* in a few cities around the world.
*/
abstract class Simulation(val runAsync: Boolean,
val latencyInjector: InMemoryMessagingNetwork.LatencyCalculator?) {
val latencyInjector: InMemoryMessagingNetwork.LatencyCalculator?) {
init {
if (!runAsync && latencyInjector != null)
throw IllegalArgumentException("The latency injector is only useful when using manual pumping.")
@ -41,7 +33,7 @@ abstract class Simulation(val runAsync: Boolean,
// This puts together a mock network of SimulatedNodes.
open class SimulatedNode(dir: Path, config: NodeConfiguration, mockNet: MockNetwork,
withTimestamper: NodeInfo?) : MockNetwork.MockNode(dir, config, mockNet, withTimestamper) {
withTimestamper: NodeInfo?) : MockNetwork.MockNode(dir, config, mockNet, withTimestamper) {
override fun findMyLocation(): PhysicalLocation? = CityDatabase[configuration.nearestCity]
}
@ -190,7 +182,8 @@ abstract class Simulation(val runAsync: Boolean,
}
}
open fun start() {}
open fun start() {
}
fun stop() {
network.nodes.forEach { it.stop() }

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.testing
import com.google.common.util.concurrent.Futures

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.utilities
import org.fusesource.jansi.Ansi

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.utilities
import com.fasterxml.jackson.core.JsonGenerator
@ -59,15 +51,15 @@ object JsonSupport {
return mapper
}
class ServiceHubObjectMapper(val identities: IdentityService): ObjectMapper()
class ServiceHubObjectMapper(val identities: IdentityService) : ObjectMapper()
object ToStringSerializer: JsonSerializer<Any>() {
object ToStringSerializer : JsonSerializer<Any>() {
override fun serialize(obj: Any, generator: JsonGenerator, provider: SerializerProvider) {
generator.writeString(obj.toString())
}
}
object LocalDateDeserializer: JsonDeserializer<LocalDate>() {
object LocalDateDeserializer : JsonDeserializer<LocalDate>() {
override fun deserialize(parser: JsonParser, context: DeserializationContext): LocalDate {
return try {
LocalDate.parse(parser.text)
@ -77,22 +69,22 @@ object JsonSupport {
}
}
object LocalDateKeyDeserializer: KeyDeserializer() {
object LocalDateKeyDeserializer : KeyDeserializer() {
override fun deserializeKey(text: String, p1: DeserializationContext): Any? {
return LocalDate.parse(text)
}
}
object PartySerializer: JsonSerializer<Party>() {
object PartySerializer : JsonSerializer<Party>() {
override fun serialize(obj: Party, generator: JsonGenerator, provider: SerializerProvider) {
generator.writeString(obj.name)
}
}
object PartyDeserializer: JsonDeserializer<Party>() {
object PartyDeserializer : JsonDeserializer<Party>() {
override fun deserialize(parser: JsonParser, context: DeserializationContext): Party {
if(parser.currentToken == JsonToken.FIELD_NAME) {
if (parser.currentToken == JsonToken.FIELD_NAME) {
parser.nextToken()
}
val mapper = parser.codec as ServiceHubObjectMapper
@ -101,7 +93,7 @@ object JsonSupport {
}
}
object SecureHashSerializer: JsonSerializer<SecureHash>() {
object SecureHashSerializer : JsonSerializer<SecureHash>() {
override fun serialize(obj: SecureHash, generator: JsonGenerator, provider: SerializerProvider) {
generator.writeString(obj.toString())
}
@ -110,9 +102,9 @@ object JsonSupport {
/**
* Implemented as a class so that we can instantiate for T
*/
class SecureHashDeserializer<T : SecureHash>: JsonDeserializer<T>() {
class SecureHashDeserializer<T : SecureHash> : JsonDeserializer<T>() {
override fun deserialize(parser: JsonParser, context: DeserializationContext): T {
if(parser.currentToken == JsonToken.FIELD_NAME) {
if (parser.currentToken == JsonToken.FIELD_NAME) {
parser.nextToken()
}
try {
@ -124,7 +116,7 @@ object JsonSupport {
}
}
object CalendarDeserializer: JsonDeserializer<BusinessCalendar>() {
object CalendarDeserializer : JsonDeserializer<BusinessCalendar>() {
override fun deserialize(parser: JsonParser, context: DeserializationContext): BusinessCalendar {
return try {
val array = StringArrayDeserializer.instance.deserialize(parser, context)

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.utilities
import org.slf4j.LoggerFactory
@ -23,6 +15,7 @@ import kotlin.reflect.KClass
// Kotlin's string interpolation efficiently: the message is never calculated/concatenated together unless
// logging at that level is enabled.
inline fun <reified T : Any> loggerFor(): org.slf4j.Logger = LoggerFactory.getLogger(T::class.java)
inline fun org.slf4j.Logger.trace(msg: () -> String) {
if (isTraceEnabled) trace(msg())
}

View File

@ -1,14 +1,5 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.utilities
import core.utilities.loggerFor
import org.slf4j.Logger
import java.util.*
import javax.annotation.concurrent.ThreadSafe
@ -24,6 +15,7 @@ class RecordingMap<K, V>(private val wrappedMap: MutableMap<K, V>,
private val logger: Logger = loggerFor<RecordingMap<K, V>>()) : MutableMap<K, V> by wrappedMap {
// If/when Kotlin supports data classes inside sealed classes, that would be preferable to this.
interface Record
data class Get<K>(val key: K) : Record
data class Put<K, V>(val key: K, val value: V) : Record

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.utilities
/**

View File

@ -11,9 +11,9 @@ class DemoClock(private var delegateClock: Clock = Clock.systemUTC()) : Clock()
@Synchronized fun updateDate(date: LocalDate): Boolean {
val currentDate = LocalDate.now(this)
if(currentDate.isBefore(date)) {
if (currentDate.isBefore(date)) {
// It's ok to increment
delegateClock = Clock.offset(delegateClock, Duration.between(currentDate.atStartOfDay(),date.atStartOfDay()))
delegateClock = Clock.offset(delegateClock, Duration.between(currentDate.atStartOfDay(), date.atStartOfDay()))
return true
}
return false

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package demos
import com.google.common.net.HostAndPort
@ -16,14 +8,14 @@ import core.node.Node
import core.node.NodeConfiguration
import core.node.NodeConfigurationFromConfig
import core.node.services.ArtemisMessagingService
import core.node.services.NodeInfo
import core.node.services.MockNetworkMapCache
import core.node.services.NodeInfo
import core.serialization.deserialize
import core.utilities.BriefLogFormatter
import joptsimple.OptionParser
import demos.protocols.AutoOfferProtocol
import demos.protocols.ExitServerProtocol
import demos.protocols.UpdateBusinessDayProtocol
import joptsimple.OptionParser
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
@ -75,7 +67,7 @@ fun main(args: Array<String>) {
val myNetAddr = HostAndPort.fromString(options.valueOf(networkAddressArg)).withDefaultPort(Node.DEFAULT_PORT)
// The timestamping node runs in the same process as the one that passes null to Node constructor.
val timestamperId = if(options.valueOf(timestamperNetAddr).equals(options.valueOf(networkAddressArg))) {
val timestamperId = if (options.valueOf(timestamperNetAddr).equals(options.valueOf(networkAddressArg))) {
null
} else {
try {
@ -86,7 +78,7 @@ fun main(args: Array<String>) {
}
// The timestamping node runs in the same process as the one that passes null to Node constructor.
val rateOracleId = if(options.valueOf(rateOracleNetAddr).equals(options.valueOf(networkAddressArg))) {
val rateOracleId = if (options.valueOf(rateOracleNetAddr).equals(options.valueOf(networkAddressArg))) {
null
} else {
try {
@ -106,10 +98,10 @@ fun main(args: Array<String>) {
val hostAndPortStrings = options.valuesOf(fakeTradeWithAddr)
val identityFiles = options.valuesOf(fakeTradeWithIdentityFile)
if(hostAndPortStrings.size != identityFiles.size) {
if (hostAndPortStrings.size != identityFiles.size) {
throw IllegalArgumentException("Different number of peer addresses (${hostAndPortStrings.size}) and identities (${identityFiles.size})")
}
for ((hostAndPortString,identityFile) in hostAndPortStrings.zip(identityFiles)) {
for ((hostAndPortString, identityFile) in hostAndPortStrings.zip(identityFiles)) {
try {
val peerId = nodeInfo(hostAndPortString, identityFile)
(node.services.networkMapCache as MockNetworkMapCache).partyNodes.add(peerId)
@ -122,8 +114,10 @@ fun main(args: Array<String>) {
UpdateBusinessDayProtocol.Handler.register(node)
ExitServerProtocol.Handler.register(node)
while(true) {
Thread.sleep(1000L)
try {
while (true) Thread.sleep(Long.MAX_VALUE)
} catch(e: InterruptedException) {
node.stop()
}
exitProcess(0)
}

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package demos
import contracts.Cash

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package demos
import co.paralleluniverse.fibers.Suspendable
@ -20,8 +12,8 @@ import core.node.Node
import core.node.NodeConfiguration
import core.node.NodeConfigurationFromConfig
import core.node.services.ArtemisMessagingService
import core.node.services.NodeInfo
import core.node.services.NodeAttachmentService
import core.node.services.NodeInfo
import core.node.services.NodeWalletService
import core.protocols.ProtocolLogic
import core.serialization.deserialize
@ -242,7 +234,7 @@ class TraderDemoProtocolSeller(val myAddress: HostAndPort,
val party = Party("Bank of London", keyPair.public)
val issuance = run {
val tx = CommercialPaper().generateIssue(party.ref(1,2,3), 1100.DOLLARS, Instant.now() + 10.days)
val tx = CommercialPaper().generateIssue(party.ref(1, 2, 3), 1100.DOLLARS, Instant.now() + 10.days)
// TODO: Consider moving these two steps below into generateIssue.

View File

@ -107,8 +107,8 @@ object AutoOfferProtocol {
}
fun notUs(vararg parties: Party): List<Party> {
val notUsParties : MutableList<Party> = arrayListOf()
for(party in parties) {
val notUsParties: MutableList<Party> = arrayListOf()
for (party in parties) {
if (serviceHub.storageService.myLegalIdentity != party) {
notUsParties.add(party)
}

View File

@ -3,8 +3,8 @@ package demos.protocols
import co.paralleluniverse.fibers.Suspendable
import co.paralleluniverse.strands.Strand
import core.node.Node
import core.node.services.NodeInfo
import core.node.services.MockNetworkMapCache
import core.node.services.NodeInfo
import core.protocols.ProtocolLogic
import core.serialization.deserialize
import java.util.concurrent.TimeUnit
@ -24,7 +24,7 @@ object ExitServerProtocol {
fun register(node: Node) {
node.net.addMessageHandler("${TOPIC}.0") { msg, registration ->
// Just to validate we got the message
if(enabled) {
if (enabled) {
val message = msg.data.deserialize<ExitMessage>()
System.exit(message.exitCode)
}
@ -37,11 +37,11 @@ object ExitServerProtocol {
* This takes a Java Integer rather than Kotlin Int as that is what we end up with in the calling map and currently
* we do not support coercing numeric types in the reflective search for matching constructors
*/
class Broadcast(val exitCode: Integer) : ProtocolLogic<Boolean>() {
class Broadcast(@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") val exitCode: Integer) : ProtocolLogic<Boolean>() {
@Suspendable
override fun call(): Boolean {
if(enabled) {
if (enabled) {
val rc = exitCode.toInt()
val message = ExitMessage(rc)
@ -57,7 +57,7 @@ object ExitServerProtocol {
@Suspendable
private fun doNextRecipient(recipient: NodeInfo, message: ExitMessage) {
if(recipient.address is MockNetworkMapCache.MockAddress) {
if (recipient.address is MockNetworkMapCache.MockAddress) {
// Ignore
} else {
// TODO: messaging ourselves seems to trigger a bug for the time being and we continuously receive messages

View File

@ -6,8 +6,9 @@ import contracts.DealState
import contracts.InterestRateSwap
import core.StateAndRef
import core.node.Node
import core.node.services.NodeInfo
import core.node.services.MockNetworkMapCache
import core.node.services.NodeInfo
import core.node.services.linearHeadsOfType
import core.protocols.ProtocolLogic
import core.random63BitValue
import core.serialization.deserialize
@ -41,14 +42,14 @@ object UpdateBusinessDayProtocol {
override fun call(): Boolean {
// Get deals
progressTracker.currentStep = FETCHING
val dealStateRefs = serviceHub.walletService.linearHeadsInstanceOf(DealState::class.java)
val dealStateRefs = serviceHub.walletService.linearHeadsOfType<DealState>()
val otherPartyToDeals = dealStateRefs.values.groupBy { otherParty(it.state) }
// TODO we need to process these in parallel to stop there being an ordering problem across more than two nodes
val sortedParties = otherPartyToDeals.keys.sortedBy { it.identity.name }
for (party in sortedParties) {
val sortedDeals = otherPartyToDeals[party]!!.sortedBy { it.state.ref }
for(deal in sortedDeals) {
for (deal in sortedDeals) {
progressTracker.currentStep = ITERATING_DEALS
processDeal(party, deal, date, sessionID)
}
@ -65,8 +66,9 @@ object UpdateBusinessDayProtocol {
// TODO we should make this more object oriented when we can ask a state for it's contract
@Suspendable
fun processDeal(party: NodeInfo, deal: StateAndRef<DealState>, date: LocalDate, sessionID: Long) {
when(deal.state) {
is InterestRateSwap.State -> processInterestRateSwap(party, StateAndRef(deal.state as InterestRateSwap.State, deal.ref), date, sessionID)
val s = deal.state
when (s) {
is InterestRateSwap.State -> processInterestRateSwap(party, StateAndRef(s, deal.ref), date, sessionID)
}
}
@ -160,7 +162,7 @@ object UpdateBusinessDayProtocol {
@Suspendable
private fun doNextRecipient(recipient: NodeInfo, message: UpdateBusinessDayMessage) {
if(recipient.address is MockNetworkMapCache.MockAddress) {
if (recipient.address is MockNetworkMapCache.MockAddress) {
// Ignore
} else {
// TODO: messaging ourselves seems to trigger a bug for the time being and we continuously receive messages

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package protocols
import core.Attachment

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package protocols
import co.paralleluniverse.fibers.Suspendable

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package protocols
import core.SignedTransaction

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package protocols
import co.paralleluniverse.fibers.Suspendable

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package protocols
import co.paralleluniverse.fibers.Suspendable

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package protocols
import co.paralleluniverse.fibers.Suspendable
@ -51,7 +43,6 @@ class TimestampingProtocol(private val node: NodeInfo,
}
@Suspendable
override fun call(): DigitalSignature.LegallyIdentifiable {
progressTracker.currentStep = REQUESTING

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package protocols
import co.paralleluniverse.fibers.Suspendable
@ -239,7 +231,7 @@ object TwoPartyDealProtocol {
private fun receiveAndValidateHandshake(): Handshake<U> {
progressTracker.currentStep = RECEIVING
// Wait for a trade request to come in on our pre-provided session ID.
val handshake = receive(DEAL_TOPIC, sessionID, Handshake::class.java)
val handshake = receive<Handshake<U>>(DEAL_TOPIC, sessionID)
progressTracker.currentStep = VERIFYING
handshake.validate {
@ -267,7 +259,7 @@ object TwoPartyDealProtocol {
return ptx.toSignedTransaction(checkSufficientSignatures = false)
}
@Suspendable protected abstract fun validateHandshake(handshake: Handshake<*>): Handshake<U>
@Suspendable protected abstract fun validateHandshake(handshake: Handshake<U>): Handshake<U>
@Suspendable protected abstract fun assembleSharedTX(handshake: Handshake<U>): Pair<TransactionBuilder, List<PublicKey>>
}
@ -291,10 +283,10 @@ object TwoPartyDealProtocol {
override val progressTracker: ProgressTracker = Secondary.tracker()) : Secondary<T>(otherSide, timestampingAuthority, sessionID) {
@Suspendable
override fun validateHandshake(handshake: Handshake<*>): Handshake<T> {
with(handshake as Handshake<T>) {
override fun validateHandshake(handshake: Handshake<T>): Handshake<T> {
with(handshake) {
// What is the seller trying to sell us?
val deal = handshake.payload
val deal: T = handshake.payload
val otherKey = handshake.publicKey
logger.trace { "Got deal request for: ${handshake.payload}" }
@ -308,7 +300,10 @@ object TwoPartyDealProtocol {
val myOldParty = deal.parties.single { it.name == myName }
val theirOldParty = deal.parties.single { it.name != myName }
val newDeal = deal.withPublicKey(myOldParty, serviceHub.keyManagementService.freshKey().public).withPublicKey(theirOldParty, otherKey) as T
@Suppress("UNCHECKED_CAST")
val newDeal = deal.
withPublicKey(myOldParty, serviceHub.keyManagementService.freshKey().public).
withPublicKey(theirOldParty, otherKey) as T
return handshake.copy(payload = newDeal)
}
@ -341,8 +336,8 @@ object TwoPartyDealProtocol {
override val progressTracker: ProgressTracker = Secondary.tracker()) : Secondary<StateRef>(otherSide, timestampingAuthority, sessionID) {
@Suspendable
override fun validateHandshake(handshake: Handshake<*>): Handshake<StateRef> {
with(handshake as Handshake<StateRef>) {
override fun validateHandshake(handshake: Handshake<StateRef>): Handshake<StateRef> {
with(handshake) {
logger.trace { "Got fixing request for: ${dealToFix.state}" }
// Check the start message for acceptability.
@ -363,11 +358,12 @@ object TwoPartyDealProtocol {
// TODO Do we need/want to substitute in new public keys for the Parties?
val myName = serviceHub.storageService.myLegalIdentity.name
val deal = dealToFix.state
val deal: T = dealToFix.state
val myOldParty = deal.parties.single { it.name == myName }
val theirOldParty = deal.parties.single { it.name != myName }
val myNewKey = serviceHub.keyManagementService.freshKey().public
@Suppress("UNCHECKED_CAST")
val newDeal = deal.withPublicKey(myOldParty, myNewKey).withPublicKey(theirOldParty, handshake.publicKey) as T
val oldRef = dealToFix.ref

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package protocols
import co.paralleluniverse.fibers.Suspendable

View File

@ -1,13 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
~ pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
~ set forth therein.
~
~ All other rights reserved.
-->
<restrict>
<http>
<method>post</method>

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.crypto;
import org.junit.*;
@ -13,11 +5,11 @@ import org.junit.*;
import java.math.*;
import java.util.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assert.*;
/** From the bitcoinj library */
/**
* From the bitcoinj library
*/
public class Base58Test {
@Test
public void testEncode() throws Exception {

View File

@ -37,7 +37,7 @@ class CashTests {
this `fails requirement` "the amounts balance"
tweak {
output { outState.copy(amount = 2000.DOLLARS )}
output { outState.copy(amount = 2000.DOLLARS) }
this `fails requirement` "the amounts balance"
}
tweak {
@ -86,9 +86,9 @@ class CashTests {
transaction {
output {
Cash.State(
amount = 1000.DOLLARS,
owner = DUMMY_PUBKEY_1,
deposit = MINI_CORP.ref(12, 34)
amount = 1000.DOLLARS,
owner = DUMMY_PUBKEY_1,
deposit = MINI_CORP.ref(12, 34)
)
}
tweak {
@ -100,7 +100,7 @@ class CashTests {
}
val ptx = TransactionBuilder()
Cash().generateIssue(ptx, 100.DOLLARS, MINI_CORP.ref(12,34), owner = DUMMY_PUBKEY_1)
Cash().generateIssue(ptx, 100.DOLLARS, MINI_CORP.ref(12, 34), owner = DUMMY_PUBKEY_1)
assertTrue(ptx.inputStates().isEmpty())
val s = ptx.outputStates()[0] as Cash.State
assertEquals(100.DOLLARS, s.amount)
@ -173,8 +173,8 @@ class CashTests {
input { inState }
input {
inState.copy(
amount = 150.POUNDS,
owner = DUMMY_PUBKEY_2
amount = 150.POUNDS,
owner = DUMMY_PUBKEY_2
)
}
output { outState.copy(amount = 1150.DOLLARS) }

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package contracts
import core.*
@ -43,12 +35,13 @@ class JavaCommercialPaperTest() : ICommercialPaperTestTemplate {
}
class KotlinCommercialPaperTest() : ICommercialPaperTestTemplate {
override fun getPaper() : ICommercialPaperState = CommercialPaper.State(
override fun getPaper(): ICommercialPaperState = CommercialPaper.State(
issuance = MEGA_CORP.ref(123),
owner = MEGA_CORP_PUBKEY,
faceValue = 1000.DOLLARS,
maturityDate = TEST_TX_TIME + 7.days
)
override fun getIssueCommand(): CommandData = CommercialPaper.Commands.Issue()
override fun getRedeemCommand(): CommandData = CommercialPaper.Commands.Redeem()
override fun getMoveCommand(): CommandData = CommercialPaper.Commands.Move()

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package contracts
import core.*
@ -21,10 +13,10 @@ import kotlin.test.assertTrue
class CrowdFundTests {
val CF_1 = CrowdFund.State(
campaign = CrowdFund.Campaign(
owner = MINI_CORP_PUBKEY,
name = "kickstart me",
target = 1000.DOLLARS,
closingTime = TEST_TX_TIME + 7.days
owner = MINI_CORP_PUBKEY,
name = "kickstart me",
target = 1000.DOLLARS,
closingTime = TEST_TX_TIME + 7.days
),
closed = false,
pledges = ArrayList<CrowdFund.Pledge>()
@ -146,7 +138,7 @@ class CrowdFundTests {
400.DOLLARS.CASH `owned by` MINI_CORP_PUBKEY
)
// MiniCorp closes their campaign.
fun makeFundedTX(time: Instant): LedgerTransaction {
fun makeFundedTX(time: Instant): LedgerTransaction {
val ptx = TransactionBuilder()
ptx.setTime(time, DUMMY_TIMESTAMPER.identity, 30.seconds)
CrowdFund().generateClose(ptx, pledgeTX.outRef(0), miniCorpWallet)

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package contracts
import core.*
@ -16,7 +8,7 @@ import java.time.LocalDate
import java.util.*
fun createDummyIRS(irsSelect: Int): InterestRateSwap.State {
return when(irsSelect) {
return when (irsSelect) {
1 -> {
val fixedLeg = InterestRateSwap.FixedLeg(
@ -326,19 +318,9 @@ class IRSTests {
assert(100 * r1 == 5)
}
@Test
fun `more rate tests`() {
val r1 = FixedRate(PercentageRatioUnit("10"))
val r2 = FixedRate(PercentageRatioUnit("10"))
// TODO: r1+r2 ? Do we want to allow these.
// TODO: r1*r2 ?
}
@Test
fun `expression calculation testing`() {
val dummyIRS = singleIRS()
val v = FixedRate(PercentageRatioUnit("4.5"))
val stuffToPrint: ArrayList<String> = arrayListOf(
"fixedLeg.notional.pennies",
"fixedLeg.fixedRate.ratioUnit",

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core
import com.codahale.metrics.MetricRegistry

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core
import contracts.Cash

View File

@ -1,19 +1,11 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.messaging
import core.Attachment
import core.crypto.SecureHash
import core.crypto.sha256
import core.node.NodeConfiguration
import core.node.services.NodeInfo
import core.node.services.NodeAttachmentService
import core.node.services.NodeInfo
import core.serialization.OpaqueBytes
import core.testing.MockNetwork
import core.testutils.rootCauseExceptions

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
@file:Suppress("UNUSED_VARIABLE")
package core.messaging
@ -54,7 +46,8 @@ open class TestWithInMemoryNetwork {
}
fun runNetwork() {
while (pumpAll(false).any { it }) {}
while (pumpAll(false).any { it }) {
}
}
}

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.messaging
import contracts.Cash
@ -112,11 +104,6 @@ class TwoPartyTradeProtocolTests : TestWithInMemoryNetwork() {
insertFakeTransactions(alicesFakePaper, aliceNode.services, aliceNode.storage.myLegalIdentityKey)
// Horrible Gradle/Kryo/Quasar FUBAR workaround: just skip these tests when run under Gradle for now.
// TODO: Fix this once Quasar issue 153 is resolved.
if (!bobNode.smm.checkpointing)
return
val buyerSessionID = random63BitValue()
val aliceFuture = TwoPartyTradeProtocol.runSeller(
@ -140,6 +127,7 @@ class TwoPartyTradeProtocolTests : TestWithInMemoryNetwork() {
// Everything is on this thread so we can now step through the protocol one step at a time.
// Seller Alice already sent a message to Buyer Bob. Pump once:
fun pumpAlice() = (aliceNode.net as InMemoryMessagingNetwork.InMemoryMessaging).pump(false)
fun pumpBob() = (bobNode.net as InMemoryMessagingNetwork.InMemoryMessaging).pump(false)
pumpBob()

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.node
import com.codahale.metrics.MetricRegistry
@ -42,7 +34,7 @@ class NodeAttachmentStorageTest {
val expectedHash = SecureHash.sha256(Files.readAllBytes(testJar))
val storage = NodeAttachmentService(fs.getPath("/"), MetricRegistry())
val id = testJar.use { storage.importAttachment(it) }
val id = testJar.use { storage.importAttachment(it) }
assertEquals(expectedHash, id)
assertNull(storage.openAttachment(SecureHash.randomSHA256()))

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.node
import contracts.Cash

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.node
import co.paralleluniverse.fibers.Suspendable

View File

@ -1,11 +1,3 @@
/*
* Copyright 2015 Distributed Ledger Group LLC. Distributed as Licensed Company IP to DLG Group Members
* pursuant to the August 7, 2015 Advisory Services Agreement and subject to the Company IP License terms
* set forth therein.
*
* All other rights reserved.
*/
package core.node.services
import contracts.Cash

Some files were not shown because too many files have changed in this diff Show More