mirror of
https://github.com/corda/corda.git
synced 2025-01-29 15:43:55 +00:00
Merge branch 'master' into dynamic-loading
This commit is contained in:
commit
d05e6bb6a4
22
README.md
22
README.md
@ -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:
|
||||
|
@ -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']) << {
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
)
|
||||
|
||||
|
||||
|
@ -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.*
|
||||
|
@ -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()
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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()
|
||||
)
|
||||
|
||||
|
@ -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
|
||||
)
|
||||
|
||||
/**
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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) }
|
||||
|
@ -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 */
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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>())
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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>
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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() }
|
||||
}
|
||||
|
@ -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() }
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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())
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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 {
|
||||
|
@ -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) }
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 }) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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()))
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user