mirror of
https://github.com/corda/corda.git
synced 2025-02-06 11:09:18 +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).
|
* 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
|
# Instructions for installing prerequisite software
|
||||||
|
|
||||||
## JDK for Java 8
|
## 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.
|
You can catch up with the latest code by selecting "VCS -> Update Project" in the menu.
|
||||||
|
|
||||||
## IntelliJ Troubleshooting
|
## IntelliJ Troubleshooting
|
||||||
|
|
||||||
If on attempting to open the project, IntelliJ refuses because SDK was not selected, do the following:
|
If on attempting to open the project, IntelliJ refuses because SDK was not selected, do the following:
|
||||||
|
|
||||||
Configure -> Project Defaults -> Project Structure
|
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.
|
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
|
## 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:
|
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
|
// 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
|
// 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
|
// 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
|
//noinspection GroovyAssignabilityCheck
|
||||||
task quasarScan(dependsOn: ['classes', 'core:classes', 'contracts:classes']) << {
|
task quasarScan(dependsOn: ['classes', 'core:classes', 'contracts:classes']) << {
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import com.google.common.io.ByteStreams
|
import com.google.common.io.ByteStreams
|
||||||
|
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import java.nio.file.StandardCopyOption
|
import java.nio.file.StandardCopyOption
|
||||||
import java.nio.file.attribute.FileTime
|
import java.nio.file.attribute.FileTime
|
||||||
import java.util.zip.ZipEntry
|
import java.util.zip.ZipEntry
|
||||||
import java.util.zip.ZipOutputStream
|
|
||||||
import java.util.zip.ZipFile
|
import java.util.zip.ZipFile
|
||||||
|
import java.util.zip.ZipOutputStream
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
@ -37,7 +38,7 @@ class CanonicalizerPlugin implements Plugin<Project> {
|
|||||||
output.setMethod(ZipOutputStream.DEFLATED)
|
output.setMethod(ZipOutputStream.DEFLATED)
|
||||||
|
|
||||||
entries.each {
|
entries.each {
|
||||||
def newEntry = new ZipEntry( it.name )
|
def newEntry = new ZipEntry(it.name)
|
||||||
|
|
||||||
newEntry.setLastModifiedTime(zeroTime)
|
newEntry.setLastModifiedTime(zeroTime)
|
||||||
newEntry.setCreationTime(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;
|
package contracts;
|
||||||
|
|
||||||
import core.*;
|
import core.*;
|
||||||
@ -19,7 +12,10 @@ import java.time.*;
|
|||||||
*/
|
*/
|
||||||
public interface ICommercialPaperState extends ContractState {
|
public interface ICommercialPaperState extends ContractState {
|
||||||
ICommercialPaperState withOwner(PublicKey newOwner);
|
ICommercialPaperState withOwner(PublicKey newOwner);
|
||||||
|
|
||||||
ICommercialPaperState withIssuance(PartyReference newIssuance);
|
ICommercialPaperState withIssuance(PartyReference newIssuance);
|
||||||
|
|
||||||
ICommercialPaperState withFaceValue(Amount newFaceValue);
|
ICommercialPaperState withFaceValue(Amount newFaceValue);
|
||||||
|
|
||||||
ICommercialPaperState withMaturityDate(Instant newMaturityDate);
|
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;
|
package contracts;
|
||||||
|
|
||||||
import core.*;
|
import core.*;
|
||||||
import core.TransactionForVerification.InOutGroup;
|
import core.TransactionForVerification.*;
|
||||||
import core.crypto.NullPublicKey;
|
import core.crypto.*;
|
||||||
import core.crypto.SecureHash;
|
|
||||||
import core.node.services.*;
|
import core.node.services.*;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.*;
|
||||||
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 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
|
* 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.
|
* use of Kotlin for implementation of the framework does not impose the same language choice on contract developers.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class JavaCommercialPaper implements Contract {
|
public class JavaCommercialPaper implements Contract {
|
||||||
//public static SecureHash JCP_PROGRAM_ID = SecureHash.sha256("java commercial paper (this should be a bytecode hash)");
|
//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 Amount faceValue;
|
||||||
private Instant maturityDate;
|
private Instant maturityDate;
|
||||||
|
|
||||||
public State() {} // For serialization
|
public State() {
|
||||||
|
} // For serialization
|
||||||
|
|
||||||
public State(PartyReference issuance, PublicKey owner, Amount faceValue, Instant maturityDate) {
|
public State(PartyReference issuance, PublicKey owner, Amount faceValue, Instant maturityDate) {
|
||||||
this.issuance = issuance;
|
this.issuance = issuance;
|
||||||
@ -135,6 +123,7 @@ public class JavaCommercialPaper implements Contract {
|
|||||||
return obj instanceof Redeem;
|
return obj instanceof Redeem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Issue extends Commands {
|
public static class Issue extends Commands {
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
@ -175,15 +164,15 @@ public class JavaCommercialPaper implements Contract {
|
|||||||
|
|
||||||
Instant time = timestampCommand.getBefore();
|
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");
|
throw new IllegalStateException("Failed Requirement: the maturity date is not in the past");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cmd.getSigners().contains(output.issuance.getParty().getOwningKey())) {
|
if (!cmd.getSigners().contains(output.issuance.getParty().getOwningKey())) {
|
||||||
throw new IllegalStateException("Failed Requirement: the issuance is signed by the claimed issuer of the paper");
|
throw new IllegalStateException("Failed Requirement: the issuance is signed by the claimed issuer of the paper");
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else { // Everything else (Move, Redeem) requires inputs (they are not first to be actioned)
|
// Everything else (Move, Redeem) requires inputs (they are not first to be actioned)
|
||||||
// There should be only a single input due to aggregation above
|
// There should be only a single input due to aggregation above
|
||||||
State input = single(inputs);
|
State input = single(inputs);
|
||||||
|
|
||||||
@ -198,9 +187,7 @@ public class JavaCommercialPaper implements Contract {
|
|||||||
!output.getIssuance().equals(input.getIssuance()) ||
|
!output.getIssuance().equals(input.getIssuance()) ||
|
||||||
!output.getMaturityDate().equals(input.getMaturityDate()))
|
!output.getMaturityDate().equals(input.getMaturityDate()))
|
||||||
throw new IllegalStateException("Failed requirement: the output state is the same as the input state except for owner");
|
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());
|
TimestampCommand timestampCommand = tx.getTimestampBy(DummyTimestampingAuthority.INSTANCE.getIdentity());
|
||||||
if (timestampCommand == null)
|
if (timestampCommand == null)
|
||||||
throw new IllegalArgumentException("Failed Requirement: must be timestamped");
|
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());
|
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");
|
throw new IllegalStateException("Failed Requirement: received amount equals the face value");
|
||||||
if (time.isBefore(input.getMaturityDate()))
|
if (time.isBefore(input.getMaturityDate()))
|
||||||
throw new IllegalStateException("Failed requirement: the paper must have matured");
|
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) {
|
public TransactionBuilder generateIssue(@NotNull PartyReference issuance, @NotNull Amount faceValue, @Nullable Instant maturityDate) {
|
||||||
State state = new State(issuance,issuance.getParty().getOwningKey(), faceValue, maturityDate);
|
State state = new State(issuance, issuance.getParty().getOwningKey(), faceValue, maturityDate);
|
||||||
return new TransactionBuilder().withItems(state, new Command( new Commands.Issue(), issuance.getParty().getOwningKey()));
|
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 {
|
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);
|
new Cash().generateSpend(tx, paper.getState().getFaceValue(), paper.getState().getOwner(), wallet, null);
|
||||||
tx.addInputState(paper.getRef());
|
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) {
|
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
|
package contracts
|
||||||
|
|
||||||
import core.*
|
import core.*
|
||||||
@ -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. */
|
/** 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()
|
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. */
|
/** 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()
|
fun Iterable<ContractState>.sumCash() = filterIsInstance<Cash.State>().map { it.amount }.sumOrThrow()
|
||||||
|
|
||||||
/** Sums the cash states in the list, returning null if there are none. */
|
/** Sums the cash states in the list, returning null if there are none. */
|
||||||
fun Iterable<ContractState>.sumCashOrNull() = filterIsInstance<Cash.State>().map { it.amount }.sumOrNull()
|
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. */
|
/** 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)
|
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
|
package contracts
|
||||||
|
|
||||||
import core.*
|
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,
|
// 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 withOwner(newOwner: PublicKey): ICommercialPaperState = copy(owner = newOwner)
|
||||||
|
|
||||||
override fun withIssuance(newIssuance: PartyReference): ICommercialPaperState = copy(issuance = newIssuance)
|
override fun withIssuance(newIssuance: PartyReference): ICommercialPaperState = copy(issuance = newIssuance)
|
||||||
override fun withFaceValue(newFaceValue: Amount): ICommercialPaperState = copy(faceValue = newFaceValue)
|
override fun withFaceValue(newFaceValue: Amount): ICommercialPaperState = copy(faceValue = newFaceValue)
|
||||||
override fun withMaturityDate(newMaturityDate: Instant): ICommercialPaperState = copy(maturityDate = newMaturityDate)
|
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
|
package contracts
|
||||||
|
|
||||||
import core.*
|
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
|
package contracts
|
||||||
|
|
||||||
import core.*
|
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
|
package contracts
|
||||||
|
|
||||||
import core.*
|
import core.*
|
||||||
@ -465,7 +457,8 @@ class InterestRateSwap() : Contract {
|
|||||||
override val parties: Array<Party>
|
override val parties: Array<Party>
|
||||||
get() = arrayOf(fixedLeg.fixedRatePayer, floatingLeg.floatingRatePayer)
|
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)
|
val newParty = Party(before.name, after)
|
||||||
if (before == fixedLeg.fixedRatePayer) {
|
if (before == fixedLeg.fixedRatePayer) {
|
||||||
val deal = copy()
|
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
|
package contracts
|
||||||
|
|
||||||
fun InterestRateSwap.State.exportIRSToCSV() : String =
|
fun InterestRateSwap.State.exportIRSToCSV(): String =
|
||||||
"Fixed Leg\n" + FixedRatePaymentEvent.CSVHeader + "\n" +
|
"Fixed Leg\n" + FixedRatePaymentEvent.CSVHeader + "\n" +
|
||||||
this.calculation.fixedLegPaymentSchedule.toSortedMap().values.map{ it.asCSV() }.joinToString("\n") + "\n" +
|
this.calculation.fixedLegPaymentSchedule.toSortedMap().values.map { it.asCSV() }.joinToString("\n") + "\n" +
|
||||||
"Floating Leg\n" + FloatingRatePaymentEvent.CSVHeader + "\n" +
|
"Floating Leg\n" + FloatingRatePaymentEvent.CSVHeader + "\n" +
|
||||||
this.calculation.floatingLegPaymentSchedule.toSortedMap().values.map{ it.asCSV() }.joinToString("\n") + "\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
|
open class RatioUnit(value: BigDecimal) { // TODO: Discuss this type
|
||||||
val value = value
|
val value = value
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean{
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
if (other?.javaClass != javaClass) return false
|
if (other?.javaClass != javaClass) return false
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ open class RatioUnit(value: BigDecimal) { // TODO: Discuss this type
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int{
|
override fun hashCode(): Int {
|
||||||
return value.hashCode()
|
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.
|
* A class to reprecent a percentage in an unambiguous way.
|
||||||
*/
|
*/
|
||||||
open class PercentageRatioUnit(percentageAsString: String) : RatioUnit(BigDecimal(percentageAsString).divide(BigDecimal("100"))) {
|
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)
|
val String.percent: PercentageRatioUnit get() = PercentageRatioUnit(this)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface representing an agreement that exposes various attributes that are common and allow
|
* Interface representing an agreement that exposes various attributes that are common. Implementing it simplifies
|
||||||
* implementation of general protocols that manipulate many agreement types
|
* implementation of general protocols that manipulate many agreement types.
|
||||||
*/
|
*/
|
||||||
interface DealState : LinearState {
|
interface DealState : LinearState {
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ interface DealState : LinearState {
|
|||||||
/** Exposes the Parties involved in a generic way */
|
/** Exposes the Parties involved in a generic way */
|
||||||
val parties: Array<Party>
|
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
|
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
|
* Parent of the Rate family. Used to denote fixed rates, floating rates, reference rates etc
|
||||||
*/
|
*/
|
||||||
open class Rate(val ratioUnit: RatioUnit? = null) {
|
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 (this === other) return true
|
||||||
if (other?.javaClass != javaClass) return false
|
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
|
* that have not yet happened. Yet-to-be fixed floating rates need to be equal such that schedules can be tested
|
||||||
* for equality.
|
* for equality.
|
||||||
*/
|
*/
|
||||||
override fun hashCode(): Int{
|
override fun hashCode(): Int {
|
||||||
return ratioUnit?.hashCode() ?: 0
|
return ratioUnit?.hashCode() ?: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,7 +126,7 @@ class FixedRate(ratioUnit: RatioUnit) : Rate(ratioUnit) {
|
|||||||
/**
|
/**
|
||||||
* The parent class of the Floating rate classes
|
* 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
|
* 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;
|
package core.crypto;
|
||||||
|
|
||||||
public class AddressFormatException extends IllegalArgumentException {
|
public class AddressFormatException extends IllegalArgumentException {
|
||||||
public AddressFormatException() {
|
public AddressFormatException() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public AddressFormatException(String message) {
|
public AddressFormatException(String message) {
|
||||||
super(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;
|
package core.crypto;
|
||||||
|
|
||||||
import java.math.*;
|
import java.math.*;
|
||||||
@ -31,7 +23,7 @@ import java.util.*;
|
|||||||
* base-256 digits, convert the number to be represented using base-58 digits, preserve the exact
|
* 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
|
* 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.
|
* 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
|
* 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.
|
* same as the original author of the R3 repository.
|
||||||
*/
|
*/
|
||||||
@ -39,6 +31,7 @@ public class Base58 {
|
|||||||
public static final char[] ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".toCharArray();
|
public static final char[] ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".toCharArray();
|
||||||
private static final char ENCODED_ZERO = ALPHABET[0];
|
private static final char ENCODED_ZERO = ALPHABET[0];
|
||||||
private static final int[] INDEXES = new int[128];
|
private static final int[] INDEXES = new int[128];
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Arrays.fill(INDEXES, -1);
|
Arrays.fill(INDEXES, -1);
|
||||||
for (int i = 0; i < ALPHABET.length; i++) {
|
for (int i = 0; i < ALPHABET.length; i++) {
|
||||||
|
@ -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
|
package core
|
||||||
|
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
@ -43,6 +35,7 @@ class Requirements {
|
|||||||
if (!expr) throw IllegalArgumentException("Failed requirement: $this")
|
if (!expr) throw IllegalArgumentException("Failed requirement: $this")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val R = Requirements()
|
val R = Requirements()
|
||||||
inline fun <R> requireThat(body: Requirements.() -> R) = R.body()
|
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
|
package core
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonGenerator
|
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" }
|
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 {
|
operator fun plus(other: Amount): Amount {
|
||||||
checkCurrency(other)
|
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) */
|
/** 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)
|
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. */
|
/** 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
|
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)
|
@JsonSerialize(using = ExpressionSerializer::class)
|
||||||
data class Expression(val expr: String)
|
data class Expression(val expr: String)
|
||||||
|
|
||||||
object ExpressionSerializer: JsonSerializer<Expression>() {
|
object ExpressionSerializer : JsonSerializer<Expression>() {
|
||||||
override fun serialize(expr: Expression, generator: JsonGenerator, provider: SerializerProvider) {
|
override fun serialize(expr: Expression, generator: JsonGenerator, provider: SerializerProvider) {
|
||||||
generator.writeString(expr.expr)
|
generator.writeString(expr.expr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object ExpressionDeserializer: JsonDeserializer<Expression>() {
|
object ExpressionDeserializer : JsonDeserializer<Expression>() {
|
||||||
override fun deserialize(parser: JsonParser, context: DeserializationContext): Expression {
|
override fun deserialize(parser: JsonParser, context: DeserializationContext): Expression {
|
||||||
return Expression(parser.text)
|
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 */
|
* 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 {
|
init {
|
||||||
val verifier = Regex("([0-9])+([DMYW])") // Only doing Overnight, Day, Week, Month, Year for now.
|
val verifier = Regex("([0-9])+([DMYW])") // Only doing Overnight, Day, Week, Month, Year for now.
|
||||||
if (!(name == "ON" || verifier.containsMatchIn(name))) {
|
if (!(name == "ON" || verifier.containsMatchIn(name))) {
|
||||||
throw IllegalArgumentException("Unrecognized tenor : $name")
|
throw IllegalArgumentException("Unrecognized tenor : $name")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String = "$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.
|
* We don't actually do anything with this yet though, so it's ignored for now.
|
||||||
*/
|
*/
|
||||||
enum class AccrualAdjustment {
|
enum class AccrualAdjustment {
|
||||||
Adjusted,Unadjusted
|
Adjusted, Unadjusted
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This is utilised in the [DateRollConvention] class to determine which way we should initially step when
|
/** 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. */
|
* in the toString lest some people get confused. */
|
||||||
enum class DayCountBasisDay {
|
enum class DayCountBasisDay {
|
||||||
// We have to prefix 30 etc with a letter due to enum naming constraints.
|
// 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 {
|
override fun toString(): String {
|
||||||
return super.toString().drop(1)
|
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. */
|
/** This forms the year part of the "Day Count Basis" used for interest calculation. */
|
||||||
enum class DayCountBasisYear {
|
enum class DayCountBasisYear {
|
||||||
// Ditto above comment for years.
|
// 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 {
|
override fun toString(): String {
|
||||||
return super.toString().drop(1)
|
return super.toString().drop(1)
|
||||||
}
|
}
|
||||||
@ -210,7 +208,8 @@ enum class PaymentRule {
|
|||||||
*/
|
*/
|
||||||
enum class DateOffset {
|
enum class DateOffset {
|
||||||
// TODO: Definitely shouldn't be an enum, but let's leave it for now at T-2 is a convention.
|
// 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) {
|
BiWeekly(26) {
|
||||||
override fun offset(d: LocalDate) = d.plusWeeks(2)
|
override fun offset(d: LocalDate) = d.plusWeeks(2)
|
||||||
};
|
};
|
||||||
|
|
||||||
abstract fun offset(d: LocalDate): LocalDate
|
abstract fun offset(d: LocalDate): LocalDate
|
||||||
// Daily() // Let's not worry about this for now.
|
// 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.
|
* no staff are around to handle problems.
|
||||||
*/
|
*/
|
||||||
open class BusinessCalendar private constructor(val calendars: Array<out String>, val holidayDates: List<LocalDate>) {
|
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 {
|
companion object {
|
||||||
val calendars = listOf("London","NewYork")
|
val calendars = listOf("London", "NewYork")
|
||||||
|
|
||||||
val TEST_CALENDAR_DATA = calendars.map {
|
val TEST_CALENDAR_DATA = calendars.map {
|
||||||
it to BusinessCalendar::class.java.getResourceAsStream("${it}HolidayCalendar.txt").bufferedReader().readText()
|
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,
|
fun getInstance(vararg calname: String) = BusinessCalendar(calname,
|
||||||
calname.flatMap { (TEST_CALENDAR_DATA[it] ?: throw UnknownCalendar(it)).split(",") }.
|
calname.flatMap { (TEST_CALENDAR_DATA[it] ?: throw UnknownCalendar(it)).split(",") }.
|
||||||
toSet().
|
toSet().
|
||||||
map{ parseDateFromString(it) }.
|
map { parseDateFromString(it) }.
|
||||||
toList().sorted()
|
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
|
package core
|
||||||
|
|
||||||
import core.crypto.SecureHash
|
import core.crypto.SecureHash
|
||||||
@ -18,7 +10,6 @@ import java.io.OutputStream
|
|||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.time.LocalDate
|
|
||||||
import java.util.jar.JarInputStream
|
import java.util.jar.JarInputStream
|
||||||
|
|
||||||
/** Implemented by anything that can be named by a secure hash value (e.g. transactions, attachments). */
|
/** 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
|
* 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 */
|
/** Unique thread id within the wallets of all parties */
|
||||||
val thread: SecureHash
|
val thread: SecureHash
|
||||||
|
|
||||||
@ -73,6 +64,11 @@ 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. */
|
/** 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)
|
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. */
|
/** 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
|
override fun toString() = name
|
||||||
@ -103,6 +99,7 @@ data class Command(val data: CommandData, val pubkeys: List<PublicKey>) {
|
|||||||
init {
|
init {
|
||||||
require(pubkeys.isNotEmpty())
|
require(pubkeys.isNotEmpty())
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(data: CommandData, key: PublicKey) : this(data, listOf(key))
|
constructor(data: CommandData, key: PublicKey) : this(data, listOf(key))
|
||||||
|
|
||||||
private fun commandDataToString() = data.toString().let { if (it.contains("@")) it.replace('$', '.').split("@")[0] else it }
|
private fun commandDataToString() = data.toString().let { if (it.contains("@")) it.replace('$', '.').split("@")[0] else 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
|
package core
|
||||||
|
|
||||||
import core.crypto.SecureHash
|
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
|
package core
|
||||||
|
|
||||||
import core.crypto.SecureHash
|
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
|
package core
|
||||||
|
|
||||||
import co.paralleluniverse.fibers.Suspendable
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
@ -106,7 +98,9 @@ data class WireTransaction(val inputs: List<StateRef>,
|
|||||||
/** Container for a [WireTransaction] and attached signatures. */
|
/** Container for a [WireTransaction] and attached signatures. */
|
||||||
data class SignedTransaction(val txBits: SerializedBytes<WireTransaction>,
|
data class SignedTransaction(val txBits: SerializedBytes<WireTransaction>,
|
||||||
val sigs: List<DigitalSignature.WithKey>) : NamedByHash {
|
val sigs: List<DigitalSignature.WithKey>) : NamedByHash {
|
||||||
init { check(sigs.isNotEmpty()) }
|
init {
|
||||||
|
check(sigs.isNotEmpty())
|
||||||
|
}
|
||||||
|
|
||||||
/** Lazily calculated access to the deserialised/hashed transaction data. */
|
/** Lazily calculated access to the deserialised/hashed transaction data. */
|
||||||
val tx: WireTransaction by lazy { WireTransaction.deserialize(txBits) }
|
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.
|
// Accessors that yield immutable snapshots.
|
||||||
fun inputStates(): List<StateRef> = ArrayList(inputs)
|
fun inputStates(): List<StateRef> = ArrayList(inputs)
|
||||||
|
|
||||||
fun outputStates(): List<ContractState> = ArrayList(outputs)
|
fun outputStates(): List<ContractState> = ArrayList(outputs)
|
||||||
fun commands(): List<Command> = ArrayList(commands)
|
fun commands(): List<Command> = ArrayList(commands)
|
||||||
fun attachments(): List<SecureHash> = ArrayList(attachments)
|
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
|
package core
|
||||||
|
|
||||||
import com.google.common.io.ByteStreams
|
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.
|
// 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>.then(executor: Executor, body: () -> Unit) = addListener(Runnable(body), executor)
|
||||||
|
|
||||||
fun <T> ListenableFuture<T>.success(executor: Executor, body: (T) -> Unit) = then(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)
|
body(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> ListenableFuture<T>.failure(executor: Executor, body: (Throwable) -> Unit) = then(executor) {
|
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>.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>.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) }
|
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
|
package core.crypto
|
||||||
|
|
||||||
import com.google.common.io.BaseEncoding
|
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" here means there can't be any subclasses other than the ones defined here.
|
||||||
sealed class SecureHash private constructor(bits: ByteArray) : OpaqueBytes(bits) {
|
sealed class SecureHash private constructor(bits: ByteArray) : OpaqueBytes(bits) {
|
||||||
class SHA256(bits: ByteArray) : SecureHash(bits) {
|
class SHA256(bits: ByteArray) : SecureHash(bits) {
|
||||||
init { require(bits.size == 32) }
|
init {
|
||||||
|
require(bits.size == 32)
|
||||||
|
}
|
||||||
|
|
||||||
override val signatureAlgorithmName: String get() = "SHA256withECDSA"
|
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 {
|
fun PrivateKey.signWithECDSA(bitsToSign: ByteArray, publicKey: PublicKey): DigitalSignature.WithKey {
|
||||||
return DigitalSignature.WithKey(publicKey, signWithECDSA(bitsToSign).bits)
|
return DigitalSignature.WithKey(publicKey, signWithECDSA(bitsToSign).bits)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun KeyPair.signWithECDSA(bitsToSign: ByteArray) = private.signWithECDSA(bitsToSign, public)
|
fun KeyPair.signWithECDSA(bitsToSign: ByteArray) = private.signWithECDSA(bitsToSign, public)
|
||||||
fun KeyPair.signWithECDSA(bitsToSign: OpaqueBytes) = private.signWithECDSA(bitsToSign.bits, public)
|
fun KeyPair.signWithECDSA(bitsToSign: OpaqueBytes) = private.signWithECDSA(bitsToSign.bits, public)
|
||||||
fun KeyPair.signWithECDSA(bitsToSign: OpaqueBytes, party: Party) = signWithECDSA(bitsToSign.bits, party)
|
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
|
// Allow Kotlin destructuring: val (private, public) = keypair
|
||||||
operator fun KeyPair.component1() = this.private
|
operator fun KeyPair.component1() = this.private
|
||||||
|
|
||||||
operator fun KeyPair.component2() = this.public
|
operator fun KeyPair.component2() = this.public
|
||||||
|
|
||||||
/** A simple wrapper that will make it easier to swap out the EC algorithm we use in future */
|
/** 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)
|
val z = DoubleArray(n)
|
||||||
for (i in 1..n - 1) {
|
for (i in 1..n - 1) {
|
||||||
val l = 2 * (xs[i + 1] - xs[i - 1]) - h[i - 1] * m[i - 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
|
z[i] = (g[i] - h[i - 1] * z[i - 1]) / l
|
||||||
}
|
}
|
||||||
for (j in n - 1 downTo 0) {
|
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
|
package core.node.services
|
||||||
|
|
||||||
import core.Party
|
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
|
package core.node.services
|
||||||
|
|
||||||
import co.paralleluniverse.fibers.Suspendable
|
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
|
package core.serialization
|
||||||
|
|
||||||
import com.google.common.io.BaseEncoding
|
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!
|
* functionality to Java, but it won't arrive for a few years yet!
|
||||||
*/
|
*/
|
||||||
open class OpaqueBytes(val bits: ByteArray) {
|
open class OpaqueBytes(val bits: ByteArray) {
|
||||||
init { check(bits.isNotEmpty()) }
|
init {
|
||||||
|
check(bits.isNotEmpty())
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun of(vararg b: Byte) = OpaqueBytes(byteArrayOf(*b))
|
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 (this === other) return true
|
||||||
if (other !is OpaqueBytes) return false
|
if (other !is OpaqueBytes) return false
|
||||||
return Arrays.equals(bits, other.bits)
|
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
|
package core.serialization
|
||||||
|
|
||||||
import co.paralleluniverse.fibers.Fiber
|
import co.paralleluniverse.fibers.Fiber
|
||||||
@ -81,12 +73,15 @@ inline fun <reified T : Any> ByteArray.deserialize(kryo: Kryo = THREAD_LOCAL_KRY
|
|||||||
else
|
else
|
||||||
return kryo.readObject(Input(this), T::class.java)
|
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 {
|
inline fun <reified T : Any> OpaqueBytes.deserialize(kryo: Kryo = THREAD_LOCAL_KRYO.get(), includeClassName: Boolean = false): T {
|
||||||
return this.bits.deserialize(kryo, includeClassName)
|
return this.bits.deserialize(kryo, includeClassName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The more specific deserialize version results in the bytes being cached, which is faster.
|
// The more specific deserialize version results in the bytes being cached, which is faster.
|
||||||
@JvmName("SerializedBytesWireTransaction")
|
@JvmName("SerializedBytesWireTransaction")
|
||||||
fun SerializedBytes<WireTransaction>.deserialize(kryo: Kryo = THREAD_LOCAL_KRYO.get()): WireTransaction = WireTransaction.deserialize(this, kryo)
|
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)
|
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.
|
// 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.
|
// no-arg constructor available.
|
||||||
instantiatorStrategy = Kryo.DefaultInstantiatorStrategy(StdInstantiatorStrategy())
|
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
|
// 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
|
// serialise the Kryo object itself when suspending a fiber. That's dumb, useless AND can cause crashes, so
|
||||||
|
@ -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
|
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
|
package core.utilities
|
||||||
|
|
||||||
import core.TransientProperty
|
import core.TransientProperty
|
||||||
@ -45,9 +37,11 @@ class ProgressTracker(vararg steps: Step) {
|
|||||||
class Position(val tracker: ProgressTracker, val newStep: Step) : Change() {
|
class Position(val tracker: ProgressTracker, val newStep: Step) : Change() {
|
||||||
override fun toString() = newStep.label
|
override fun toString() = newStep.label
|
||||||
}
|
}
|
||||||
|
|
||||||
class Rendering(val tracker: ProgressTracker, val ofStep: Step) : Change() {
|
class Rendering(val tracker: ProgressTracker, val ofStep: Step) : Change() {
|
||||||
override fun toString() = ofStep.label
|
override fun toString() = ofStep.label
|
||||||
}
|
}
|
||||||
|
|
||||||
class Structural(val tracker: ProgressTracker, val parent: Step) : Change() {
|
class Structural(val tracker: ProgressTracker, val parent: Step) : Change() {
|
||||||
override fun toString() = "Structural step change in child of ${parent.label}"
|
override fun toString() = "Structural step change in child of ${parent.label}"
|
||||||
}
|
}
|
||||||
@ -75,6 +69,7 @@ class ProgressTracker(vararg steps: Step) {
|
|||||||
object UNSTARTED : Step("Unstarted") {
|
object UNSTARTED : Step("Unstarted") {
|
||||||
override fun equals(other: Any?) = other is UNSTARTED
|
override fun equals(other: Any?) = other is UNSTARTED
|
||||||
}
|
}
|
||||||
|
|
||||||
object DONE : Step("Done") {
|
object DONE : Step("Done") {
|
||||||
override fun equals(other: Any?) = other is 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
|
package core
|
||||||
|
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@ -40,7 +32,7 @@ class FinanceTypesTest {
|
|||||||
fun `schedule generator 1`() {
|
fun `schedule generator 1`() {
|
||||||
var ret = BusinessCalendar.createGenericSchedule(startDate = LocalDate.of(2014, 11, 25), period = Frequency.Monthly, noOfAdditionalPeriods = 3)
|
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.
|
// 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)
|
println(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,61 +40,61 @@ class FinanceTypesTest {
|
|||||||
fun `schedule generator 2`() {
|
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)
|
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!
|
// 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)
|
println(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `create a UK calendar` () {
|
fun `create a UK calendar`() {
|
||||||
val cal = BusinessCalendar.getInstance("London")
|
val cal = BusinessCalendar.getInstance("London")
|
||||||
val holdates = cal.holidayDates
|
val holdates = cal.holidayDates
|
||||||
println(holdates)
|
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
|
@Test
|
||||||
fun `create a US UK calendar`() {
|
fun `create a US UK calendar`() {
|
||||||
val cal = BusinessCalendar.getInstance("London","NewYork")
|
val cal = BusinessCalendar.getInstance("London", "NewYork")
|
||||||
assert(LocalDate.of(2016,7,4) in cal.holidayDates) // The most American of holidays
|
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
|
assert(LocalDate.of(2016, 8, 29) in cal.holidayDates) // August Bank Holiday for brits only
|
||||||
println("Calendar contains both US and UK holidays")
|
println("Calendar contains both US and UK holidays")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `calendar test of modified following` () {
|
fun `calendar test of modified following`() {
|
||||||
val ldn = BusinessCalendar.getInstance("London")
|
val ldn = BusinessCalendar.getInstance("London")
|
||||||
val result = ldn.applyRollConvention(LocalDate.of(2016,12,25),DateRollConvention.ModifiedFollowing)
|
val result = ldn.applyRollConvention(LocalDate.of(2016, 12, 25), DateRollConvention.ModifiedFollowing)
|
||||||
assert(result == LocalDate.of(2016,12,28))
|
assert(result == LocalDate.of(2016, 12, 28))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `calendar test of modified following pt 2` () {
|
fun `calendar test of modified following pt 2`() {
|
||||||
val ldn = BusinessCalendar.getInstance("London")
|
val ldn = BusinessCalendar.getInstance("London")
|
||||||
val result = ldn.applyRollConvention(LocalDate.of(2016,12,31),DateRollConvention.ModifiedFollowing)
|
val result = ldn.applyRollConvention(LocalDate.of(2016, 12, 31), DateRollConvention.ModifiedFollowing)
|
||||||
assert(result == LocalDate.of(2016,12,30))
|
assert(result == LocalDate.of(2016, 12, 30))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `calendar test of modified previous` () {
|
fun `calendar test of modified previous`() {
|
||||||
val ldn = BusinessCalendar.getInstance("London")
|
val ldn = BusinessCalendar.getInstance("London")
|
||||||
val result = ldn.applyRollConvention(LocalDate.of(2016,1,1),DateRollConvention.ModifiedPrevious)
|
val result = ldn.applyRollConvention(LocalDate.of(2016, 1, 1), DateRollConvention.ModifiedPrevious)
|
||||||
assert(result == LocalDate.of(2016,1,4))
|
assert(result == LocalDate.of(2016, 1, 4))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `calendar test of previous` () {
|
fun `calendar test of previous`() {
|
||||||
val ldn = BusinessCalendar.getInstance("London")
|
val ldn = BusinessCalendar.getInstance("London")
|
||||||
val result = ldn.applyRollConvention(LocalDate.of(2016,12,25),DateRollConvention.Previous)
|
val result = ldn.applyRollConvention(LocalDate.of(2016, 12, 25), DateRollConvention.Previous)
|
||||||
assert(result == LocalDate.of(2016,12,23))
|
assert(result == LocalDate.of(2016, 12, 23))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `calendar test of following` () {
|
fun `calendar test of following`() {
|
||||||
val ldn = BusinessCalendar.getInstance("London")
|
val ldn = BusinessCalendar.getInstance("London")
|
||||||
val result = ldn.applyRollConvention(LocalDate.of(2016,12,25),DateRollConvention.Following)
|
val result = ldn.applyRollConvention(LocalDate.of(2016, 12, 25), DateRollConvention.Following)
|
||||||
assert(result == LocalDate.of(2016,12,28))
|
assert(result == LocalDate.of(2016, 12, 28))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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
|
package core.utilities
|
||||||
|
|
||||||
import org.apache.commons.jexl3.JexlBuilder
|
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
|
package core.utilities
|
||||||
|
|
||||||
import org.junit.Before
|
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
|
package api
|
||||||
|
|
||||||
import core.ContractState
|
import core.ContractState
|
||||||
|
@ -2,10 +2,14 @@ package api
|
|||||||
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture
|
import com.google.common.util.concurrent.ListenableFuture
|
||||||
import contracts.DealState
|
import contracts.DealState
|
||||||
import core.*
|
import core.ContractState
|
||||||
|
import core.SignedTransaction
|
||||||
|
import core.StateRef
|
||||||
|
import core.WireTransaction
|
||||||
import core.crypto.DigitalSignature
|
import core.crypto.DigitalSignature
|
||||||
import core.crypto.SecureHash
|
import core.crypto.SecureHash
|
||||||
import core.node.AbstractNode
|
import core.node.AbstractNode
|
||||||
|
import core.node.services.linearHeadsOfType
|
||||||
import core.protocols.ProtocolLogic
|
import core.protocols.ProtocolLogic
|
||||||
import core.serialization.SerializedBytes
|
import core.serialization.SerializedBytes
|
||||||
import core.utilities.ANSIProgressRenderer
|
import core.utilities.ANSIProgressRenderer
|
||||||
@ -14,7 +18,7 @@ import java.util.*
|
|||||||
import kotlin.reflect.KParameter
|
import kotlin.reflect.KParameter
|
||||||
import kotlin.reflect.jvm.javaType
|
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)
|
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) {
|
if (query.criteria is StatesQuery.Criteria.AllDeals) {
|
||||||
val states = node.services.walletService.linearHeads
|
val states = node.services.walletService.linearHeads
|
||||||
return states.values.map { it.ref }
|
return states.values.map { it.ref }
|
||||||
}
|
} else if (query.criteria is StatesQuery.Criteria.Deal) {
|
||||||
else if (query.criteria is StatesQuery.Criteria.Deal) {
|
val states = node.services.walletService.linearHeadsOfType<DealState>().filterValues {
|
||||||
val states = node.services.walletService.linearHeadsInstanceOf(DealState::class.java) {
|
it.state.ref == query.criteria.ref
|
||||||
it.ref == query.criteria.ref
|
|
||||||
}
|
}
|
||||||
return states.values.map { it.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?> {
|
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)
|
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
|
// TODO for security, check annotated as exposed on API? Or have PublicProtocolLogic... etc
|
||||||
nextConstructor@ for (constructor in clazz.kotlin.constructors) {
|
nextConstructor@ for (constructor in clazz.kotlin.constructors) {
|
||||||
val params = HashMap<KParameter, Any?>()
|
val params = HashMap<KParameter, Any?>()
|
||||||
@ -91,7 +94,7 @@ class APIServerImpl(val node: AbstractNode): APIServer {
|
|||||||
// If we get here then we matched every parameter
|
// If we get here then we matched every parameter
|
||||||
val protocol = constructor.callBy(params) as ProtocolLogic<*>
|
val protocol = constructor.callBy(params) as ProtocolLogic<*>
|
||||||
ANSIProgressRenderer.progressTracker = protocol.progressTracker
|
ANSIProgressRenderer.progressTracker = protocol.progressTracker
|
||||||
val future = node.smm.add("api-call",protocol)
|
val future = node.smm.add("api-call", protocol)
|
||||||
return future
|
return future
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import javax.ws.rs.ext.Provider
|
|||||||
* and to organise serializers / deserializers for java.time.* classes as necessary
|
* and to organise serializers / deserializers for java.time.* classes as necessary
|
||||||
*/
|
*/
|
||||||
@Provider
|
@Provider
|
||||||
class Config(val services: ServiceHub): ContextResolver<ObjectMapper> {
|
class Config(val services: ServiceHub) : ContextResolver<ObjectMapper> {
|
||||||
val defaultObjectMapper = JsonSupport.createDefaultMapper(services.identityService)
|
val defaultObjectMapper = JsonSupport.createDefaultMapper(services.identityService)
|
||||||
override fun getContext(type: java.lang.Class<*>) = defaultObjectMapper
|
override fun getContext(type: java.lang.Class<*>) = defaultObjectMapper
|
||||||
}
|
}
|
@ -36,13 +36,13 @@ class InterestRateSwapAPI(val api: APIServer) {
|
|||||||
|
|
||||||
private val logger = loggerFor<InterestRateSwapAPI>()
|
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? {
|
private fun getDealByRef(ref: String): InterestRateSwap.State? {
|
||||||
val states = api.queryStates(StatesQuery.selectDeal(ref))
|
val states = api.queryStates(StatesQuery.selectDeal(ref))
|
||||||
return if (states.isEmpty()) null else {
|
return if (states.isEmpty()) null else {
|
||||||
val deals = api.fetchStates(states).values.map { it as InterestRateSwap.State}.filterNotNull()
|
val deals = api.fetchStates(states).values.map { it as InterestRateSwap.State }.filterNotNull()
|
||||||
return if(deals.isEmpty()) null else deals[0]
|
return if (deals.isEmpty()) null else deals[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ class InterestRateSwapAPI(val api: APIServer) {
|
|||||||
fun storeDemoDate(newDemoDate: LocalDate): Response {
|
fun storeDemoDate(newDemoDate: LocalDate): Response {
|
||||||
val priorDemoDate = api.serverTime().toLocalDate()
|
val priorDemoDate = api.serverTime().toLocalDate()
|
||||||
// Can only move date forwards
|
// 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))
|
api.invokeProtocolSync(ProtocolClassRef(UpdateBusinessDayProtocol.Broadcast::class.java.name!!), mapOf("date" to newDemoDate))
|
||||||
return Response.ok().build()
|
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
|
package api
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extremely rudimentary query language which should most likely be replaced with a product
|
* Extremely rudimentary query language which should most likely be replaced with a product
|
||||||
*/
|
*/
|
||||||
interface StatesQuery {
|
interface StatesQuery {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun select(criteria: Criteria): Selection {
|
fun select(criteria: Criteria): Selection {
|
||||||
return Selection(criteria)
|
return Selection(criteria)
|
||||||
@ -29,13 +20,11 @@ interface StatesQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO make constructors private
|
// TODO make constructors private
|
||||||
data class Selection(val criteria: Criteria): StatesQuery
|
data class Selection(val criteria: Criteria) : StatesQuery
|
||||||
|
|
||||||
interface Criteria {
|
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
|
* This adds headers needed for cross site scripting on API clients
|
||||||
*/
|
*/
|
||||||
@Provider
|
@Provider
|
||||||
class ResponseFilter: ContainerResponseFilter {
|
class ResponseFilter : ContainerResponseFilter {
|
||||||
override fun filter(requestContext: ContainerRequestContext, responseContext: ContainerResponseContext) {
|
override fun filter(requestContext: ContainerRequestContext, responseContext: ContainerResponseContext) {
|
||||||
val headers = responseContext.headers
|
val headers = responseContext.headers
|
||||||
|
|
||||||
@ -21,9 +21,9 @@ class ResponseFilter: ContainerResponseFilter {
|
|||||||
* access control and authentication at a network and software level
|
* 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-Headers", "Content-Type,Accept,Origin")
|
||||||
headers.add("Access-Control-Allow-Methods", "POST,PUT,GET,OPTIONS")
|
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
|
package core
|
||||||
|
|
||||||
import core.node.services.AttachmentStorage
|
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
|
package core.messaging
|
||||||
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture
|
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) */
|
/** The interface for a group of message recipients (which may contain only one recipient) */
|
||||||
interface MessageRecipients
|
interface MessageRecipients
|
||||||
|
|
||||||
/** A base class for the case of point-to-point messages */
|
/** A base class for the case of point-to-point messages */
|
||||||
interface SingleMessageRecipient : MessageRecipients
|
interface SingleMessageRecipient : MessageRecipients
|
||||||
|
|
||||||
/** A base class for a set of recipients specifically identified by the sender. */
|
/** A base class for a set of recipients specifically identified by the sender. */
|
||||||
interface MessageRecipientGroup : MessageRecipients
|
interface MessageRecipientGroup : MessageRecipients
|
||||||
|
|
||||||
/** A special base class for the set of all possible recipients, without having to identify who they all are. */
|
/** A special base class for the set of all possible recipients, without having to identify who they all are. */
|
||||||
interface AllPossibleRecipients : MessageRecipients
|
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
|
package core.messaging
|
||||||
|
|
||||||
import co.paralleluniverse.fibers.Fiber
|
import co.paralleluniverse.fibers.Fiber
|
||||||
@ -68,22 +60,15 @@ class StateMachineManager(val serviceHub: ServiceHub, val runInThread: Executor)
|
|||||||
|
|
||||||
// Monitoring support.
|
// Monitoring support.
|
||||||
private val metrics = serviceHub.monitoringService.metrics
|
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 checkpointingMeter = metrics.meter("Protocols.Checkpointing Rate")
|
||||||
private val totalStartedProtocols = metrics.counter("Protocols.Started")
|
private val totalStartedProtocols = metrics.counter("Protocols.Started")
|
||||||
private val totalFinishedProtocols = metrics.counter("Protocols.Finished")
|
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) */
|
/** 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>>> {
|
fun <T> findStateMachines(klass: Class<out ProtocolLogic<T>>): List<Pair<ProtocolLogic<T>, ListenableFuture<T>>> {
|
||||||
synchronized(_stateMachines) {
|
synchronized(_stateMachines) {
|
||||||
@ -111,8 +96,6 @@ class StateMachineManager(val serviceHub: ServiceHub, val runInThread: Executor)
|
|||||||
// Blank out the default uncaught exception handler because we always catch things ourselves, and the default
|
// Blank out the default uncaught exception handler because we always catch things ourselves, and the default
|
||||||
// just redundantly prints stack traces to the logs.
|
// just redundantly prints stack traces to the logs.
|
||||||
Fiber.setDefaultUncaughtExceptionHandler { fiber, throwable -> }
|
Fiber.setDefaultUncaughtExceptionHandler { fiber, throwable -> }
|
||||||
|
|
||||||
if (checkpointing)
|
|
||||||
restoreCheckpoints()
|
restoreCheckpoints()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,7 +218,6 @@ class StateMachineManager(val serviceHub: ServiceHub, val runInThread: Executor)
|
|||||||
serialisedFiber: ByteArray) {
|
serialisedFiber: ByteArray) {
|
||||||
val checkpoint = Checkpoint(serialisedFiber, logger.name, topic, responseType.name)
|
val checkpoint = Checkpoint(serialisedFiber, logger.name, topic, responseType.name)
|
||||||
val curPersistedBytes = checkpoint.serialize().bits
|
val curPersistedBytes = checkpoint.serialize().bits
|
||||||
if (checkpointing)
|
|
||||||
persistCheckpoint(prevCheckpointKey, curPersistedBytes)
|
persistCheckpoint(prevCheckpointKey, curPersistedBytes)
|
||||||
val newCheckpointKey = curPersistedBytes.sha256()
|
val newCheckpointKey = curPersistedBytes.sha256()
|
||||||
net.runOnNextMessage(topic, runInThread) { netMsg ->
|
net.runOnNextMessage(topic, runInThread) { netMsg ->
|
||||||
|
@ -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
|
package core.node
|
||||||
|
|
||||||
import api.APIServer
|
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
|
package core.node
|
||||||
|
|
||||||
import java.io.InputStream
|
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
|
package core.node
|
||||||
|
|
||||||
import api.Config
|
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
|
package core.node
|
||||||
|
|
||||||
import com.typesafe.config.Config
|
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
|
package core.node.services
|
||||||
|
|
||||||
import com.google.common.net.HostAndPort
|
import com.google.common.net.HostAndPort
|
||||||
@ -82,11 +74,13 @@ class ArtemisMessagingService(val directory: Path, val myHostPort: HostAndPort)
|
|||||||
var running = false
|
var running = false
|
||||||
val sendClients = HashMap<Address, ClientProducer>()
|
val sendClients = HashMap<Address, ClientProducer>()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val mutex = ThreadBox(InnerState())
|
private val mutex = ThreadBox(InnerState())
|
||||||
|
|
||||||
/** A registration to handle messages of different types */
|
/** A registration to handle messages of different types */
|
||||||
inner class Handler(val executor: Executor?, val topic: String,
|
inner class Handler(val executor: Executor?, val topic: String,
|
||||||
val callback: (Message, MessageHandlerRegistration) -> Unit) : MessageHandlerRegistration
|
val callback: (Message, MessageHandlerRegistration) -> Unit) : MessageHandlerRegistration
|
||||||
|
|
||||||
private val handlers = CopyOnWriteArrayList<Handler>()
|
private val handlers = CopyOnWriteArrayList<Handler>()
|
||||||
|
|
||||||
private fun getSendClient(addr: Address): ClientProducer {
|
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
|
package core.node.services
|
||||||
|
|
||||||
import protocols.FetchAttachmentsProtocol
|
|
||||||
import protocols.FetchTransactionsProtocol
|
|
||||||
import core.node.services.StorageService
|
|
||||||
import core.crypto.SecureHash
|
import core.crypto.SecureHash
|
||||||
import core.messaging.Message
|
import core.messaging.Message
|
||||||
import core.messaging.MessagingService
|
import core.messaging.MessagingService
|
||||||
@ -18,6 +7,8 @@ import core.messaging.SingleMessageRecipient
|
|||||||
import core.messaging.send
|
import core.messaging.send
|
||||||
import core.serialization.deserialize
|
import core.serialization.deserialize
|
||||||
import core.utilities.loggerFor
|
import core.utilities.loggerFor
|
||||||
|
import protocols.FetchAttachmentsProtocol
|
||||||
|
import protocols.FetchTransactionsProtocol
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import javax.annotation.concurrent.ThreadSafe
|
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
|
package core.node.services
|
||||||
|
|
||||||
import core.node.services.KeyManagementService
|
|
||||||
import core.ThreadBox
|
import core.ThreadBox
|
||||||
import core.crypto.generateKeyPair
|
import core.crypto.generateKeyPair
|
||||||
import java.security.KeyPair
|
import java.security.KeyPair
|
||||||
@ -33,6 +24,7 @@ class E2ETestKeyManagementService : KeyManagementService {
|
|||||||
private class InnerState {
|
private class InnerState {
|
||||||
val keys = HashMap<PublicKey, PrivateKey>()
|
val keys = HashMap<PublicKey, PrivateKey>()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val mutex = ThreadBox(InnerState())
|
private val mutex = ThreadBox(InnerState())
|
||||||
|
|
||||||
// Accessing this map clones it.
|
// 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
|
package core.node.services
|
||||||
|
|
||||||
import core.Party
|
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
|
package core.node.services
|
||||||
|
|
||||||
import core.Party
|
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.
|
* 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.
|
* This interface assumes fast, synchronous access to an in-memory map.
|
||||||
*/
|
*/
|
||||||
interface NetworkMapCache {
|
interface NetworkMapCache {
|
||||||
val timestampingNodes: List<NodeInfo>
|
val timestampingNodes: List<NodeInfo>
|
||||||
val ratesOracleNodes: 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.
|
// TODO: Move this to the test tree once a real network map is implemented and this scaffolding is no longer needed.
|
||||||
class MockNetworkMapCache : NetworkMapCache {
|
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 timestampingNodes = Collections.synchronizedList(ArrayList<NodeInfo>())
|
||||||
override val ratesOracleNodes = 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
|
package core.node.services
|
||||||
|
|
||||||
import com.codahale.metrics.MetricRegistry
|
import com.codahale.metrics.MetricRegistry
|
||||||
@ -98,6 +90,7 @@ class NodeAttachmentService(val storePath: Path, val metrics: MetricRegistry) :
|
|||||||
stream = HashCheckingStream(id, path, stream)
|
stream = HashCheckingStream(id, path, stream)
|
||||||
return stream
|
return stream
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun equals(other: Any?) = other is Attachment && other.id == id
|
override fun equals(other: Any?) = other is Attachment && other.id == id
|
||||||
override fun hashCode(): Int = id.hashCode()
|
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
|
package core.node.services
|
||||||
|
|
||||||
import core.*
|
import core.*
|
||||||
@ -51,8 +43,8 @@ object NodeInterestRates {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Parses lines containing fixes */
|
/** Parses lines containing fixes */
|
||||||
fun parseFile(s: String): Map<FixOf, TreeMap<LocalDate,Fix>> {
|
fun parseFile(s: String): Map<FixOf, TreeMap<LocalDate, Fix>> {
|
||||||
val results = HashMap<FixOf, TreeMap<LocalDate,Fix>>()
|
val results = HashMap<FixOf, TreeMap<LocalDate, Fix>>()
|
||||||
for (line in s.lines()) {
|
for (line in s.lines()) {
|
||||||
val (fixOf, fix) = parseOneRate(line)
|
val (fixOf, fix) = parseOneRate(line)
|
||||||
val genericKey = FixOf(fixOf.name, LocalDate.MIN, fixOf.ofTenor)
|
val genericKey = FixOf(fixOf.name, LocalDate.MIN, fixOf.ofTenor)
|
||||||
@ -96,7 +88,7 @@ object NodeInterestRates {
|
|||||||
override val acceptableFileExtensions = listOf(".rates", ".txt")
|
override val acceptableFileExtensions = listOf(".rates", ".txt")
|
||||||
|
|
||||||
override fun upload(data: InputStream): String {
|
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().
|
bufferedReader().
|
||||||
readLines().
|
readLines().
|
||||||
map { it.trim() }.
|
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 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.
|
* 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) {
|
set(value) {
|
||||||
require(value.isNotEmpty())
|
require(value.isNotEmpty())
|
||||||
field = value
|
field = value
|
||||||
@ -154,7 +146,7 @@ object NodeInterestRates {
|
|||||||
val rates = knownFixes[FixOf(fixOf.name, LocalDate.MIN, fixOf.ofTenor)]
|
val rates = knownFixes[FixOf(fixOf.name, LocalDate.MIN, fixOf.ofTenor)]
|
||||||
// Greatest key less than or equal to the date we're looking for
|
// Greatest key less than or equal to the date we're looking for
|
||||||
val floor = rates?.floorEntry(fixOf.forDay)?.value
|
val floor = rates?.floorEntry(fixOf.forDay)?.value
|
||||||
return if (floor!=null) {
|
return if (floor != null) {
|
||||||
Fix(fixOf, floor.value)
|
Fix(fixOf, floor.value)
|
||||||
} else {
|
} else {
|
||||||
null
|
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
|
package core.node.services
|
||||||
|
|
||||||
import co.paralleluniverse.common.util.VisibleForTesting
|
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
|
package core.node.services
|
||||||
|
|
||||||
import com.codahale.metrics.Gauge
|
import com.codahale.metrics.Gauge
|
||||||
@ -33,6 +25,7 @@ class NodeWalletService(private val services: ServiceHub) : WalletService {
|
|||||||
private class InnerState {
|
private class InnerState {
|
||||||
var wallet: Wallet = Wallet(emptyList<StateAndRef<OwnableState>>())
|
var wallet: Wallet = Wallet(emptyList<StateAndRef<OwnableState>>())
|
||||||
}
|
}
|
||||||
|
|
||||||
private val mutex = ThreadBox(InnerState())
|
private val mutex = ThreadBox(InnerState())
|
||||||
|
|
||||||
override val currentWallet: Wallet get() = mutex.locked { wallet }
|
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>>
|
override val linearHeads: Map<SecureHash, StateAndRef<LinearState>>
|
||||||
get() = mutex.locked { wallet }.let { wallet ->
|
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 {
|
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 {
|
private fun isRelevant(state: ContractState, ourKeys: Set<PublicKey>): Boolean {
|
||||||
return if(state is OwnableState) {
|
return if (state is OwnableState) {
|
||||||
state.owner in ourKeys
|
state.owner in ourKeys
|
||||||
} else if(state is LinearState) {
|
} else if (state is LinearState) {
|
||||||
// It's potentially of interest to the wallet
|
// It's potentially of interest to the wallet
|
||||||
state.isRelevant(ourKeys)
|
state.isRelevant(ourKeys)
|
||||||
} else {
|
} 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
|
package core.node.services
|
||||||
|
|
||||||
import com.codahale.metrics.MetricRegistry
|
import com.codahale.metrics.MetricRegistry
|
||||||
@ -72,13 +64,17 @@ interface WalletService {
|
|||||||
*/
|
*/
|
||||||
val linearHeads: Map<SecureHash, StateAndRef<LinearState>>
|
val linearHeads: Map<SecureHash, StateAndRef<LinearState>>
|
||||||
|
|
||||||
fun <T : LinearState> linearHeadsInstanceOf(clazz: Class<T>, predicate: (T) -> Boolean = { true } ): Map<SecureHash, StateAndRef<T>> {
|
// TODO: When KT-10399 is fixed, rename this and remove the inline version below.
|
||||||
return linearHeads.filterValues { clazz.isInstance(it.state) }.filterValues { predicate(it.state as T) }.mapValues { StateAndRef(it.value.state as T, it.value.ref) }
|
|
||||||
|
/** 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?> {
|
fun statesForRefs(refs: List<StateRef>): Map<StateRef, ContractState?> {
|
||||||
val refsToStates = currentWallet.states.associateBy { it.ref }
|
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))
|
fun notify(tx: WireTransaction): Wallet = notifyAll(listOf(tx))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Document this
|
inline fun <reified T : LinearState> WalletService.linearHeadsOfType() = linearHeadsOfType_(T::class.java)
|
||||||
@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()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The KMS is responsible for storing and using private keys to sign things. An implementation of this may, for example,
|
* 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.
|
// This parameter is for unit tests that want to observe operation details.
|
||||||
val recordingAs: (String) -> String = { tableName -> "" })
|
val recordingAs: (String) -> String = { tableName -> "" })
|
||||||
: StorageService {
|
: 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> {
|
private fun <K, V> getMapOriginal(tableName: String): MutableMap<K, V> {
|
||||||
synchronized(tables) {
|
synchronized(tables) {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
return tables.getOrPut(tableName) {
|
return tables.getOrPut(tableName) {
|
||||||
recorderWrap(Collections.synchronizedMap(HashMap<Any, Any>()), tableName);
|
recorderWrap(Collections.synchronizedMap(HashMap<K, V>()), tableName)
|
||||||
} as MutableMap<K, V>
|
} 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
|
package core.node.servlets
|
||||||
|
|
||||||
import core.node.services.StorageService
|
|
||||||
import core.crypto.SecureHash
|
import core.crypto.SecureHash
|
||||||
|
import core.node.services.StorageService
|
||||||
import core.utilities.loggerFor
|
import core.utilities.loggerFor
|
||||||
import java.io.FileNotFoundException
|
import java.io.FileNotFoundException
|
||||||
import javax.servlet.http.HttpServlet
|
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
|
package core.node.servlets
|
||||||
|
|
||||||
import core.node.AcceptsFileUpload
|
import core.node.AcceptsFileUpload
|
||||||
|
@ -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
|
package core.protocols
|
||||||
|
|
||||||
import co.paralleluniverse.fibers.Suspendable
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
import core.node.services.ServiceHub
|
|
||||||
import core.messaging.MessageRecipients
|
import core.messaging.MessageRecipients
|
||||||
|
import core.node.services.ServiceHub
|
||||||
import core.utilities.ProgressTracker
|
import core.utilities.ProgressTracker
|
||||||
import core.utilities.UntrustworthyData
|
import core.utilities.UntrustworthyData
|
||||||
import org.slf4j.Logger
|
import org.slf4j.Logger
|
||||||
@ -47,12 +39,15 @@ abstract class ProtocolLogic<T> {
|
|||||||
sessionIDForReceive: Long, obj: Any): UntrustworthyData<T> {
|
sessionIDForReceive: Long, obj: Any): UntrustworthyData<T> {
|
||||||
return psm.sendAndReceive(topic, destination, sessionIDForSend, sessionIDForReceive, obj, T::class.java)
|
return psm.sendAndReceive(topic, destination, sessionIDForSend, sessionIDForReceive, obj, T::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified T : Any> receive(topic: String, sessionIDForReceive: Long): UntrustworthyData<T> {
|
inline fun <reified T : Any> receive(topic: String, sessionIDForReceive: Long): UntrustworthyData<T> {
|
||||||
return receive(topic, sessionIDForReceive, T::class.java)
|
return receive(topic, sessionIDForReceive, T::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suspendable fun <T : Any> receive(topic: String, sessionIDForReceive: Long, clazz: Class<T>): UntrustworthyData<T> {
|
@Suspendable fun <T : Any> receive(topic: String, sessionIDForReceive: Long, clazz: Class<T>): UntrustworthyData<T> {
|
||||||
return psm.receive(topic, sessionIDForReceive, clazz)
|
return psm.receive(topic, sessionIDForReceive, clazz)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suspendable fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any) {
|
@Suspendable fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any) {
|
||||||
psm.send(topic, destination, sessionID, obj)
|
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
|
package core.protocols
|
||||||
|
|
||||||
import co.paralleluniverse.fibers.Fiber
|
import co.paralleluniverse.fibers.Fiber
|
||||||
@ -14,9 +6,9 @@ import co.paralleluniverse.io.serialization.kryo.KryoSerializer
|
|||||||
import com.esotericsoftware.kryo.io.Output
|
import com.esotericsoftware.kryo.io.Output
|
||||||
import com.google.common.util.concurrent.ListenableFuture
|
import com.google.common.util.concurrent.ListenableFuture
|
||||||
import com.google.common.util.concurrent.SettableFuture
|
import com.google.common.util.concurrent.SettableFuture
|
||||||
import core.node.services.ServiceHub
|
|
||||||
import core.messaging.MessageRecipients
|
import core.messaging.MessageRecipients
|
||||||
import core.messaging.StateMachineManager
|
import core.messaging.StateMachineManager
|
||||||
|
import core.node.services.ServiceHub
|
||||||
import core.serialization.createKryo
|
import core.serialization.createKryo
|
||||||
import core.utilities.UntrustworthyData
|
import core.utilities.UntrustworthyData
|
||||||
import org.slf4j.Logger
|
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
|
package core.testing
|
||||||
|
|
||||||
import com.fasterxml.jackson.module.kotlin.readValue
|
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
|
package core.testing
|
||||||
|
|
||||||
import com.google.common.util.concurrent.Futures
|
import com.google.common.util.concurrent.Futures
|
||||||
@ -59,7 +51,7 @@ class InMemoryMessagingNetwork {
|
|||||||
*/
|
*/
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun createNode(manuallyPumped: Boolean): Pair<Handle, MessagingServiceBuilder<InMemoryMessaging>> {
|
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
|
val builder = createNodeWithID(manuallyPumped, counter) as Builder
|
||||||
counter++
|
counter++
|
||||||
val id = builder.id
|
val id = builder.id
|
||||||
@ -89,15 +81,15 @@ class InMemoryMessagingNetwork {
|
|||||||
if (calc != null && recipients is SingleMessageRecipient) {
|
if (calc != null && recipients is SingleMessageRecipient) {
|
||||||
// Inject some artificial latency.
|
// Inject some artificial latency.
|
||||||
timer.schedule(calc.between(from.myAddress, recipients).toMillis()) {
|
timer.schedule(calc.between(from.myAddress, recipients).toMillis()) {
|
||||||
msgSendInternal(from, message, recipients)
|
msgSendInternal(message, recipients)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
msgSendInternal(from, message, recipients)
|
msgSendInternal(message, recipients)
|
||||||
}
|
}
|
||||||
_allMessages.onNext(Triple(from.myAddress, 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) {
|
when (recipients) {
|
||||||
is Handle -> getQueueForHandle(recipients).add(message)
|
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.
|
* An instance can be obtained by creating a builder and then using the start method.
|
||||||
*/
|
*/
|
||||||
@ThreadSafe
|
@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,
|
inner class Handler(val executor: Executor?, val topic: String,
|
||||||
val callback: (Message, MessageHandlerRegistration) -> Unit) : MessageHandlerRegistration
|
val callback: (Message, MessageHandlerRegistration) -> Unit) : MessageHandlerRegistration
|
||||||
|
|
||||||
@Volatile
|
@Volatile
|
||||||
protected var running = true
|
protected var running = true
|
||||||
|
|
||||||
protected inner class InnerState {
|
protected inner class InnerState {
|
||||||
val handlers: MutableList<Handler> = ArrayList()
|
val handlers: MutableList<Handler> = ArrayList()
|
||||||
val pendingRedelivery = LinkedList<Message>()
|
val pendingRedelivery = LinkedList<Message>()
|
||||||
}
|
}
|
||||||
|
|
||||||
protected val state = ThreadBox(InnerState())
|
protected val state = ThreadBox(InnerState())
|
||||||
|
|
||||||
override val myAddress: SingleMessageRecipient = handle
|
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
|
package core.testing
|
||||||
|
|
||||||
import com.google.common.jimfs.Jimfs
|
import com.google.common.jimfs.Jimfs
|
||||||
@ -124,7 +116,8 @@ class MockNetwork(private val threadPerNode: Boolean = false,
|
|||||||
fun runNetwork(rounds: Int = -1) {
|
fun runNetwork(rounds: Int = -1) {
|
||||||
fun pumpAll() = messagingNetwork.endpoints.map { it.pump(false) }
|
fun pumpAll() = messagingNetwork.endpoints.map { it.pump(false) }
|
||||||
if (rounds == -1)
|
if (rounds == -1)
|
||||||
while (pumpAll().any { it }) {}
|
while (pumpAll().any { it }) {
|
||||||
|
}
|
||||||
else
|
else
|
||||||
repeat(rounds) { pumpAll() }
|
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
|
package core.testing
|
||||||
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture
|
import com.google.common.util.concurrent.ListenableFuture
|
||||||
@ -190,7 +182,8 @@ abstract class Simulation(val runAsync: Boolean,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun start() {}
|
open fun start() {
|
||||||
|
}
|
||||||
|
|
||||||
fun stop() {
|
fun stop() {
|
||||||
network.nodes.forEach { it.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
|
package core.testing
|
||||||
|
|
||||||
import com.google.common.util.concurrent.Futures
|
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
|
package core.utilities
|
||||||
|
|
||||||
import org.fusesource.jansi.Ansi
|
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
|
package core.utilities
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonGenerator
|
import com.fasterxml.jackson.core.JsonGenerator
|
||||||
@ -59,15 +51,15 @@ object JsonSupport {
|
|||||||
return mapper
|
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) {
|
override fun serialize(obj: Any, generator: JsonGenerator, provider: SerializerProvider) {
|
||||||
generator.writeString(obj.toString())
|
generator.writeString(obj.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object LocalDateDeserializer: JsonDeserializer<LocalDate>() {
|
object LocalDateDeserializer : JsonDeserializer<LocalDate>() {
|
||||||
override fun deserialize(parser: JsonParser, context: DeserializationContext): LocalDate {
|
override fun deserialize(parser: JsonParser, context: DeserializationContext): LocalDate {
|
||||||
return try {
|
return try {
|
||||||
LocalDate.parse(parser.text)
|
LocalDate.parse(parser.text)
|
||||||
@ -77,22 +69,22 @@ object JsonSupport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object LocalDateKeyDeserializer: KeyDeserializer() {
|
object LocalDateKeyDeserializer : KeyDeserializer() {
|
||||||
override fun deserializeKey(text: String, p1: DeserializationContext): Any? {
|
override fun deserializeKey(text: String, p1: DeserializationContext): Any? {
|
||||||
return LocalDate.parse(text)
|
return LocalDate.parse(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object PartySerializer: JsonSerializer<Party>() {
|
object PartySerializer : JsonSerializer<Party>() {
|
||||||
override fun serialize(obj: Party, generator: JsonGenerator, provider: SerializerProvider) {
|
override fun serialize(obj: Party, generator: JsonGenerator, provider: SerializerProvider) {
|
||||||
generator.writeString(obj.name)
|
generator.writeString(obj.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object PartyDeserializer: JsonDeserializer<Party>() {
|
object PartyDeserializer : JsonDeserializer<Party>() {
|
||||||
override fun deserialize(parser: JsonParser, context: DeserializationContext): Party {
|
override fun deserialize(parser: JsonParser, context: DeserializationContext): Party {
|
||||||
if(parser.currentToken == JsonToken.FIELD_NAME) {
|
if (parser.currentToken == JsonToken.FIELD_NAME) {
|
||||||
parser.nextToken()
|
parser.nextToken()
|
||||||
}
|
}
|
||||||
val mapper = parser.codec as ServiceHubObjectMapper
|
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) {
|
override fun serialize(obj: SecureHash, generator: JsonGenerator, provider: SerializerProvider) {
|
||||||
generator.writeString(obj.toString())
|
generator.writeString(obj.toString())
|
||||||
}
|
}
|
||||||
@ -110,9 +102,9 @@ object JsonSupport {
|
|||||||
/**
|
/**
|
||||||
* Implemented as a class so that we can instantiate for T
|
* 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 {
|
override fun deserialize(parser: JsonParser, context: DeserializationContext): T {
|
||||||
if(parser.currentToken == JsonToken.FIELD_NAME) {
|
if (parser.currentToken == JsonToken.FIELD_NAME) {
|
||||||
parser.nextToken()
|
parser.nextToken()
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@ -124,7 +116,7 @@ object JsonSupport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object CalendarDeserializer: JsonDeserializer<BusinessCalendar>() {
|
object CalendarDeserializer : JsonDeserializer<BusinessCalendar>() {
|
||||||
override fun deserialize(parser: JsonParser, context: DeserializationContext): BusinessCalendar {
|
override fun deserialize(parser: JsonParser, context: DeserializationContext): BusinessCalendar {
|
||||||
return try {
|
return try {
|
||||||
val array = StringArrayDeserializer.instance.deserialize(parser, context)
|
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
|
package core.utilities
|
||||||
|
|
||||||
import org.slf4j.LoggerFactory
|
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
|
// Kotlin's string interpolation efficiently: the message is never calculated/concatenated together unless
|
||||||
// logging at that level is enabled.
|
// logging at that level is enabled.
|
||||||
inline fun <reified T : Any> loggerFor(): org.slf4j.Logger = LoggerFactory.getLogger(T::class.java)
|
inline fun <reified T : Any> loggerFor(): org.slf4j.Logger = LoggerFactory.getLogger(T::class.java)
|
||||||
|
|
||||||
inline fun org.slf4j.Logger.trace(msg: () -> String) {
|
inline fun org.slf4j.Logger.trace(msg: () -> String) {
|
||||||
if (isTraceEnabled) trace(msg())
|
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
|
package core.utilities
|
||||||
|
|
||||||
import core.utilities.loggerFor
|
|
||||||
import org.slf4j.Logger
|
import org.slf4j.Logger
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.annotation.concurrent.ThreadSafe
|
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 {
|
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.
|
// If/when Kotlin supports data classes inside sealed classes, that would be preferable to this.
|
||||||
interface Record
|
interface Record
|
||||||
|
|
||||||
data class Get<K>(val key: K) : Record
|
data class Get<K>(val key: K) : Record
|
||||||
data class Put<K, V>(val key: K, val value: V) : 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
|
package core.utilities
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,9 +11,9 @@ class DemoClock(private var delegateClock: Clock = Clock.systemUTC()) : Clock()
|
|||||||
|
|
||||||
@Synchronized fun updateDate(date: LocalDate): Boolean {
|
@Synchronized fun updateDate(date: LocalDate): Boolean {
|
||||||
val currentDate = LocalDate.now(this)
|
val currentDate = LocalDate.now(this)
|
||||||
if(currentDate.isBefore(date)) {
|
if (currentDate.isBefore(date)) {
|
||||||
// It's ok to increment
|
// 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 true
|
||||||
}
|
}
|
||||||
return false
|
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
|
package demos
|
||||||
|
|
||||||
import com.google.common.net.HostAndPort
|
import com.google.common.net.HostAndPort
|
||||||
@ -16,14 +8,14 @@ import core.node.Node
|
|||||||
import core.node.NodeConfiguration
|
import core.node.NodeConfiguration
|
||||||
import core.node.NodeConfigurationFromConfig
|
import core.node.NodeConfigurationFromConfig
|
||||||
import core.node.services.ArtemisMessagingService
|
import core.node.services.ArtemisMessagingService
|
||||||
import core.node.services.NodeInfo
|
|
||||||
import core.node.services.MockNetworkMapCache
|
import core.node.services.MockNetworkMapCache
|
||||||
|
import core.node.services.NodeInfo
|
||||||
import core.serialization.deserialize
|
import core.serialization.deserialize
|
||||||
import core.utilities.BriefLogFormatter
|
import core.utilities.BriefLogFormatter
|
||||||
import joptsimple.OptionParser
|
|
||||||
import demos.protocols.AutoOfferProtocol
|
import demos.protocols.AutoOfferProtocol
|
||||||
import demos.protocols.ExitServerProtocol
|
import demos.protocols.ExitServerProtocol
|
||||||
import demos.protocols.UpdateBusinessDayProtocol
|
import demos.protocols.UpdateBusinessDayProtocol
|
||||||
|
import joptsimple.OptionParser
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.Paths
|
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)
|
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.
|
// 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
|
null
|
||||||
} else {
|
} else {
|
||||||
try {
|
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.
|
// 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
|
null
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
@ -106,10 +98,10 @@ fun main(args: Array<String>) {
|
|||||||
|
|
||||||
val hostAndPortStrings = options.valuesOf(fakeTradeWithAddr)
|
val hostAndPortStrings = options.valuesOf(fakeTradeWithAddr)
|
||||||
val identityFiles = options.valuesOf(fakeTradeWithIdentityFile)
|
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})")
|
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 {
|
try {
|
||||||
val peerId = nodeInfo(hostAndPortString, identityFile)
|
val peerId = nodeInfo(hostAndPortString, identityFile)
|
||||||
(node.services.networkMapCache as MockNetworkMapCache).partyNodes.add(peerId)
|
(node.services.networkMapCache as MockNetworkMapCache).partyNodes.add(peerId)
|
||||||
@ -122,8 +114,10 @@ fun main(args: Array<String>) {
|
|||||||
UpdateBusinessDayProtocol.Handler.register(node)
|
UpdateBusinessDayProtocol.Handler.register(node)
|
||||||
ExitServerProtocol.Handler.register(node)
|
ExitServerProtocol.Handler.register(node)
|
||||||
|
|
||||||
while(true) {
|
try {
|
||||||
Thread.sleep(1000L)
|
while (true) Thread.sleep(Long.MAX_VALUE)
|
||||||
|
} catch(e: InterruptedException) {
|
||||||
|
node.stop()
|
||||||
}
|
}
|
||||||
exitProcess(0)
|
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
|
package demos
|
||||||
|
|
||||||
import contracts.Cash
|
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
|
package demos
|
||||||
|
|
||||||
import co.paralleluniverse.fibers.Suspendable
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
@ -20,8 +12,8 @@ import core.node.Node
|
|||||||
import core.node.NodeConfiguration
|
import core.node.NodeConfiguration
|
||||||
import core.node.NodeConfigurationFromConfig
|
import core.node.NodeConfigurationFromConfig
|
||||||
import core.node.services.ArtemisMessagingService
|
import core.node.services.ArtemisMessagingService
|
||||||
import core.node.services.NodeInfo
|
|
||||||
import core.node.services.NodeAttachmentService
|
import core.node.services.NodeAttachmentService
|
||||||
|
import core.node.services.NodeInfo
|
||||||
import core.node.services.NodeWalletService
|
import core.node.services.NodeWalletService
|
||||||
import core.protocols.ProtocolLogic
|
import core.protocols.ProtocolLogic
|
||||||
import core.serialization.deserialize
|
import core.serialization.deserialize
|
||||||
@ -242,7 +234,7 @@ class TraderDemoProtocolSeller(val myAddress: HostAndPort,
|
|||||||
val party = Party("Bank of London", keyPair.public)
|
val party = Party("Bank of London", keyPair.public)
|
||||||
|
|
||||||
val issuance = run {
|
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.
|
// TODO: Consider moving these two steps below into generateIssue.
|
||||||
|
|
||||||
|
@ -107,8 +107,8 @@ object AutoOfferProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun notUs(vararg parties: Party): List<Party> {
|
fun notUs(vararg parties: Party): List<Party> {
|
||||||
val notUsParties : MutableList<Party> = arrayListOf()
|
val notUsParties: MutableList<Party> = arrayListOf()
|
||||||
for(party in parties) {
|
for (party in parties) {
|
||||||
if (serviceHub.storageService.myLegalIdentity != party) {
|
if (serviceHub.storageService.myLegalIdentity != party) {
|
||||||
notUsParties.add(party)
|
notUsParties.add(party)
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@ package demos.protocols
|
|||||||
import co.paralleluniverse.fibers.Suspendable
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
import co.paralleluniverse.strands.Strand
|
import co.paralleluniverse.strands.Strand
|
||||||
import core.node.Node
|
import core.node.Node
|
||||||
import core.node.services.NodeInfo
|
|
||||||
import core.node.services.MockNetworkMapCache
|
import core.node.services.MockNetworkMapCache
|
||||||
|
import core.node.services.NodeInfo
|
||||||
import core.protocols.ProtocolLogic
|
import core.protocols.ProtocolLogic
|
||||||
import core.serialization.deserialize
|
import core.serialization.deserialize
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
@ -24,7 +24,7 @@ object ExitServerProtocol {
|
|||||||
fun register(node: Node) {
|
fun register(node: Node) {
|
||||||
node.net.addMessageHandler("${TOPIC}.0") { msg, registration ->
|
node.net.addMessageHandler("${TOPIC}.0") { msg, registration ->
|
||||||
// Just to validate we got the message
|
// Just to validate we got the message
|
||||||
if(enabled) {
|
if (enabled) {
|
||||||
val message = msg.data.deserialize<ExitMessage>()
|
val message = msg.data.deserialize<ExitMessage>()
|
||||||
System.exit(message.exitCode)
|
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
|
* 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
|
* 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
|
@Suspendable
|
||||||
override fun call(): Boolean {
|
override fun call(): Boolean {
|
||||||
if(enabled) {
|
if (enabled) {
|
||||||
val rc = exitCode.toInt()
|
val rc = exitCode.toInt()
|
||||||
val message = ExitMessage(rc)
|
val message = ExitMessage(rc)
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ object ExitServerProtocol {
|
|||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
private fun doNextRecipient(recipient: NodeInfo, message: ExitMessage) {
|
private fun doNextRecipient(recipient: NodeInfo, message: ExitMessage) {
|
||||||
if(recipient.address is MockNetworkMapCache.MockAddress) {
|
if (recipient.address is MockNetworkMapCache.MockAddress) {
|
||||||
// Ignore
|
// Ignore
|
||||||
} else {
|
} else {
|
||||||
// TODO: messaging ourselves seems to trigger a bug for the time being and we continuously receive messages
|
// 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 contracts.InterestRateSwap
|
||||||
import core.StateAndRef
|
import core.StateAndRef
|
||||||
import core.node.Node
|
import core.node.Node
|
||||||
import core.node.services.NodeInfo
|
|
||||||
import core.node.services.MockNetworkMapCache
|
import core.node.services.MockNetworkMapCache
|
||||||
|
import core.node.services.NodeInfo
|
||||||
|
import core.node.services.linearHeadsOfType
|
||||||
import core.protocols.ProtocolLogic
|
import core.protocols.ProtocolLogic
|
||||||
import core.random63BitValue
|
import core.random63BitValue
|
||||||
import core.serialization.deserialize
|
import core.serialization.deserialize
|
||||||
@ -41,14 +42,14 @@ object UpdateBusinessDayProtocol {
|
|||||||
override fun call(): Boolean {
|
override fun call(): Boolean {
|
||||||
// Get deals
|
// Get deals
|
||||||
progressTracker.currentStep = FETCHING
|
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) }
|
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
|
// 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 }
|
val sortedParties = otherPartyToDeals.keys.sortedBy { it.identity.name }
|
||||||
for (party in sortedParties) {
|
for (party in sortedParties) {
|
||||||
val sortedDeals = otherPartyToDeals[party]!!.sortedBy { it.state.ref }
|
val sortedDeals = otherPartyToDeals[party]!!.sortedBy { it.state.ref }
|
||||||
for(deal in sortedDeals) {
|
for (deal in sortedDeals) {
|
||||||
progressTracker.currentStep = ITERATING_DEALS
|
progressTracker.currentStep = ITERATING_DEALS
|
||||||
processDeal(party, deal, date, sessionID)
|
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
|
// TODO we should make this more object oriented when we can ask a state for it's contract
|
||||||
@Suspendable
|
@Suspendable
|
||||||
fun processDeal(party: NodeInfo, deal: StateAndRef<DealState>, date: LocalDate, sessionID: Long) {
|
fun processDeal(party: NodeInfo, deal: StateAndRef<DealState>, date: LocalDate, sessionID: Long) {
|
||||||
when(deal.state) {
|
val s = deal.state
|
||||||
is InterestRateSwap.State -> processInterestRateSwap(party, StateAndRef(deal.state as InterestRateSwap.State, deal.ref), date, sessionID)
|
when (s) {
|
||||||
|
is InterestRateSwap.State -> processInterestRateSwap(party, StateAndRef(s, deal.ref), date, sessionID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +162,7 @@ object UpdateBusinessDayProtocol {
|
|||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
private fun doNextRecipient(recipient: NodeInfo, message: UpdateBusinessDayMessage) {
|
private fun doNextRecipient(recipient: NodeInfo, message: UpdateBusinessDayMessage) {
|
||||||
if(recipient.address is MockNetworkMapCache.MockAddress) {
|
if (recipient.address is MockNetworkMapCache.MockAddress) {
|
||||||
// Ignore
|
// Ignore
|
||||||
} else {
|
} else {
|
||||||
// TODO: messaging ourselves seems to trigger a bug for the time being and we continuously receive messages
|
// 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
|
package protocols
|
||||||
|
|
||||||
import core.Attachment
|
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
|
package protocols
|
||||||
|
|
||||||
import co.paralleluniverse.fibers.Suspendable
|
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
|
package protocols
|
||||||
|
|
||||||
import core.SignedTransaction
|
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
|
package protocols
|
||||||
|
|
||||||
import co.paralleluniverse.fibers.Suspendable
|
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
|
package protocols
|
||||||
|
|
||||||
import co.paralleluniverse.fibers.Suspendable
|
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
|
package protocols
|
||||||
|
|
||||||
import co.paralleluniverse.fibers.Suspendable
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
@ -51,7 +43,6 @@ class TimestampingProtocol(private val node: NodeInfo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun call(): DigitalSignature.LegallyIdentifiable {
|
override fun call(): DigitalSignature.LegallyIdentifiable {
|
||||||
progressTracker.currentStep = REQUESTING
|
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
|
package protocols
|
||||||
|
|
||||||
import co.paralleluniverse.fibers.Suspendable
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
@ -239,7 +231,7 @@ object TwoPartyDealProtocol {
|
|||||||
private fun receiveAndValidateHandshake(): Handshake<U> {
|
private fun receiveAndValidateHandshake(): Handshake<U> {
|
||||||
progressTracker.currentStep = RECEIVING
|
progressTracker.currentStep = RECEIVING
|
||||||
// Wait for a trade request to come in on our pre-provided session ID.
|
// 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
|
progressTracker.currentStep = VERIFYING
|
||||||
handshake.validate {
|
handshake.validate {
|
||||||
@ -267,7 +259,7 @@ object TwoPartyDealProtocol {
|
|||||||
return ptx.toSignedTransaction(checkSufficientSignatures = false)
|
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>>
|
@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) {
|
override val progressTracker: ProgressTracker = Secondary.tracker()) : Secondary<T>(otherSide, timestampingAuthority, sessionID) {
|
||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun validateHandshake(handshake: Handshake<*>): Handshake<T> {
|
override fun validateHandshake(handshake: Handshake<T>): Handshake<T> {
|
||||||
with(handshake as Handshake<T>) {
|
with(handshake) {
|
||||||
// What is the seller trying to sell us?
|
// What is the seller trying to sell us?
|
||||||
val deal = handshake.payload
|
val deal: T = handshake.payload
|
||||||
val otherKey = handshake.publicKey
|
val otherKey = handshake.publicKey
|
||||||
logger.trace { "Got deal request for: ${handshake.payload}" }
|
logger.trace { "Got deal request for: ${handshake.payload}" }
|
||||||
|
|
||||||
@ -308,7 +300,10 @@ object TwoPartyDealProtocol {
|
|||||||
val myOldParty = deal.parties.single { it.name == myName }
|
val myOldParty = deal.parties.single { it.name == myName }
|
||||||
val theirOldParty = 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)
|
return handshake.copy(payload = newDeal)
|
||||||
}
|
}
|
||||||
@ -341,8 +336,8 @@ object TwoPartyDealProtocol {
|
|||||||
override val progressTracker: ProgressTracker = Secondary.tracker()) : Secondary<StateRef>(otherSide, timestampingAuthority, sessionID) {
|
override val progressTracker: ProgressTracker = Secondary.tracker()) : Secondary<StateRef>(otherSide, timestampingAuthority, sessionID) {
|
||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
override fun validateHandshake(handshake: Handshake<*>): Handshake<StateRef> {
|
override fun validateHandshake(handshake: Handshake<StateRef>): Handshake<StateRef> {
|
||||||
with(handshake as Handshake<StateRef>) {
|
with(handshake) {
|
||||||
logger.trace { "Got fixing request for: ${dealToFix.state}" }
|
logger.trace { "Got fixing request for: ${dealToFix.state}" }
|
||||||
|
|
||||||
// Check the start message for acceptability.
|
// 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?
|
// TODO Do we need/want to substitute in new public keys for the Parties?
|
||||||
val myName = serviceHub.storageService.myLegalIdentity.name
|
val myName = serviceHub.storageService.myLegalIdentity.name
|
||||||
val deal = dealToFix.state
|
val deal: T = dealToFix.state
|
||||||
val myOldParty = deal.parties.single { it.name == myName }
|
val myOldParty = deal.parties.single { it.name == myName }
|
||||||
val theirOldParty = deal.parties.single { it.name != myName }
|
val theirOldParty = deal.parties.single { it.name != myName }
|
||||||
val myNewKey = serviceHub.keyManagementService.freshKey().public
|
val myNewKey = serviceHub.keyManagementService.freshKey().public
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
val newDeal = deal.withPublicKey(myOldParty, myNewKey).withPublicKey(theirOldParty, handshake.publicKey) as T
|
val newDeal = deal.withPublicKey(myOldParty, myNewKey).withPublicKey(theirOldParty, handshake.publicKey) as T
|
||||||
val oldRef = dealToFix.ref
|
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
|
package protocols
|
||||||
|
|
||||||
import co.paralleluniverse.fibers.Suspendable
|
import co.paralleluniverse.fibers.Suspendable
|
||||||
|
@ -1,13 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?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>
|
<restrict>
|
||||||
<http>
|
<http>
|
||||||
<method>post</method>
|
<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;
|
package core.crypto;
|
||||||
|
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
@ -13,11 +5,11 @@ import org.junit.*;
|
|||||||
import java.math.*;
|
import java.math.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.*;
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
|
|
||||||
/** From the bitcoinj library */
|
/**
|
||||||
|
* From the bitcoinj library
|
||||||
|
*/
|
||||||
public class Base58Test {
|
public class Base58Test {
|
||||||
@Test
|
@Test
|
||||||
public void testEncode() throws Exception {
|
public void testEncode() throws Exception {
|
||||||
|
@ -37,7 +37,7 @@ class CashTests {
|
|||||||
this `fails requirement` "the amounts balance"
|
this `fails requirement` "the amounts balance"
|
||||||
|
|
||||||
tweak {
|
tweak {
|
||||||
output { outState.copy(amount = 2000.DOLLARS )}
|
output { outState.copy(amount = 2000.DOLLARS) }
|
||||||
this `fails requirement` "the amounts balance"
|
this `fails requirement` "the amounts balance"
|
||||||
}
|
}
|
||||||
tweak {
|
tweak {
|
||||||
@ -100,7 +100,7 @@ class CashTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val ptx = TransactionBuilder()
|
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())
|
assertTrue(ptx.inputStates().isEmpty())
|
||||||
val s = ptx.outputStates()[0] as Cash.State
|
val s = ptx.outputStates()[0] as Cash.State
|
||||||
assertEquals(100.DOLLARS, s.amount)
|
assertEquals(100.DOLLARS, s.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
|
package contracts
|
||||||
|
|
||||||
import core.*
|
import core.*
|
||||||
@ -43,12 +35,13 @@ class JavaCommercialPaperTest() : ICommercialPaperTestTemplate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class KotlinCommercialPaperTest() : ICommercialPaperTestTemplate {
|
class KotlinCommercialPaperTest() : ICommercialPaperTestTemplate {
|
||||||
override fun getPaper() : ICommercialPaperState = CommercialPaper.State(
|
override fun getPaper(): ICommercialPaperState = CommercialPaper.State(
|
||||||
issuance = MEGA_CORP.ref(123),
|
issuance = MEGA_CORP.ref(123),
|
||||||
owner = MEGA_CORP_PUBKEY,
|
owner = MEGA_CORP_PUBKEY,
|
||||||
faceValue = 1000.DOLLARS,
|
faceValue = 1000.DOLLARS,
|
||||||
maturityDate = TEST_TX_TIME + 7.days
|
maturityDate = TEST_TX_TIME + 7.days
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun getIssueCommand(): CommandData = CommercialPaper.Commands.Issue()
|
override fun getIssueCommand(): CommandData = CommercialPaper.Commands.Issue()
|
||||||
override fun getRedeemCommand(): CommandData = CommercialPaper.Commands.Redeem()
|
override fun getRedeemCommand(): CommandData = CommercialPaper.Commands.Redeem()
|
||||||
override fun getMoveCommand(): CommandData = CommercialPaper.Commands.Move()
|
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
|
package contracts
|
||||||
|
|
||||||
import core.*
|
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
|
package contracts
|
||||||
|
|
||||||
import core.*
|
import core.*
|
||||||
@ -16,7 +8,7 @@ import java.time.LocalDate
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
fun createDummyIRS(irsSelect: Int): InterestRateSwap.State {
|
fun createDummyIRS(irsSelect: Int): InterestRateSwap.State {
|
||||||
return when(irsSelect) {
|
return when (irsSelect) {
|
||||||
1 -> {
|
1 -> {
|
||||||
|
|
||||||
val fixedLeg = InterestRateSwap.FixedLeg(
|
val fixedLeg = InterestRateSwap.FixedLeg(
|
||||||
@ -326,19 +318,9 @@ class IRSTests {
|
|||||||
assert(100 * r1 == 5)
|
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
|
@Test
|
||||||
fun `expression calculation testing`() {
|
fun `expression calculation testing`() {
|
||||||
val dummyIRS = singleIRS()
|
val dummyIRS = singleIRS()
|
||||||
val v = FixedRate(PercentageRatioUnit("4.5"))
|
|
||||||
val stuffToPrint: ArrayList<String> = arrayListOf(
|
val stuffToPrint: ArrayList<String> = arrayListOf(
|
||||||
"fixedLeg.notional.pennies",
|
"fixedLeg.notional.pennies",
|
||||||
"fixedLeg.fixedRate.ratioUnit",
|
"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
|
package core
|
||||||
|
|
||||||
import com.codahale.metrics.MetricRegistry
|
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
|
package core
|
||||||
|
|
||||||
import contracts.Cash
|
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
|
package core.messaging
|
||||||
|
|
||||||
import core.Attachment
|
import core.Attachment
|
||||||
import core.crypto.SecureHash
|
import core.crypto.SecureHash
|
||||||
import core.crypto.sha256
|
import core.crypto.sha256
|
||||||
import core.node.NodeConfiguration
|
import core.node.NodeConfiguration
|
||||||
import core.node.services.NodeInfo
|
|
||||||
import core.node.services.NodeAttachmentService
|
import core.node.services.NodeAttachmentService
|
||||||
|
import core.node.services.NodeInfo
|
||||||
import core.serialization.OpaqueBytes
|
import core.serialization.OpaqueBytes
|
||||||
import core.testing.MockNetwork
|
import core.testing.MockNetwork
|
||||||
import core.testutils.rootCauseExceptions
|
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")
|
@file:Suppress("UNUSED_VARIABLE")
|
||||||
|
|
||||||
package core.messaging
|
package core.messaging
|
||||||
@ -54,7 +46,8 @@ open class TestWithInMemoryNetwork {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun runNetwork() {
|
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
|
package core.messaging
|
||||||
|
|
||||||
import contracts.Cash
|
import contracts.Cash
|
||||||
@ -112,11 +104,6 @@ class TwoPartyTradeProtocolTests : TestWithInMemoryNetwork() {
|
|||||||
|
|
||||||
insertFakeTransactions(alicesFakePaper, aliceNode.services, aliceNode.storage.myLegalIdentityKey)
|
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 buyerSessionID = random63BitValue()
|
||||||
|
|
||||||
val aliceFuture = TwoPartyTradeProtocol.runSeller(
|
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.
|
// 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:
|
// Seller Alice already sent a message to Buyer Bob. Pump once:
|
||||||
fun pumpAlice() = (aliceNode.net as InMemoryMessagingNetwork.InMemoryMessaging).pump(false)
|
fun pumpAlice() = (aliceNode.net as InMemoryMessagingNetwork.InMemoryMessaging).pump(false)
|
||||||
|
|
||||||
fun pumpBob() = (bobNode.net as InMemoryMessagingNetwork.InMemoryMessaging).pump(false)
|
fun pumpBob() = (bobNode.net as InMemoryMessagingNetwork.InMemoryMessaging).pump(false)
|
||||||
|
|
||||||
pumpBob()
|
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
|
package core.node
|
||||||
|
|
||||||
import com.codahale.metrics.MetricRegistry
|
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.node
|
package core.node
|
||||||
|
|
||||||
import contracts.Cash
|
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
|
package core.node
|
||||||
|
|
||||||
import co.paralleluniverse.fibers.Suspendable
|
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
|
package core.node.services
|
||||||
|
|
||||||
import contracts.Cash
|
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