Run auto-formatter over the code.

This commit is contained in:
Mike Hearn 2016-04-07 20:16:28 +02:00
parent 931ce4a749
commit caf48b65c9
65 changed files with 286 additions and 217 deletions

View File

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

View File

@ -19,7 +19,10 @@ import java.time.*;
*/
public interface ICommercialPaperState extends ContractState {
ICommercialPaperState withOwner(PublicKey newOwner);
ICommercialPaperState withIssuance(PartyReference newIssuance);
ICommercialPaperState withFaceValue(Amount newFaceValue);
ICommercialPaperState withMaturityDate(Instant newMaturityDate);
}

View File

@ -9,27 +9,22 @@
package contracts;
import core.*;
import core.TransactionForVerification.InOutGroup;
import core.crypto.NullPublicKey;
import core.crypto.SecureHash;
import core.TransactionForVerification.*;
import core.crypto.*;
import core.node.services.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.security.PublicKey;
import java.time.Instant;
import java.util.List;
import static core.ContractsDSLKt.requireSingleCommand;
import static kotlin.collections.CollectionsKt.single;
import org.jetbrains.annotations.*;
import java.security.*;
import java.time.*;
import java.util.*;
import static core.ContractsDSLKt.*;
import static kotlin.collections.CollectionsKt.*;
/**
* This is a Java version of the CommercialPaper contract (chosen because it's simple). This demonstrates how the
* use of Kotlin for implementation of the framework does not impose the same language choice on contract developers.
*
*/
public class JavaCommercialPaper implements Contract {
public static SecureHash JCP_PROGRAM_ID = SecureHash.sha256("java commercial paper (this should be a bytecode hash)");
@ -40,7 +35,8 @@ public class JavaCommercialPaper implements Contract {
private Amount faceValue;
private Instant maturityDate;
public State() {} // For serialization
public State() {
} // For serialization
public State(PartyReference issuance, PublicKey owner, Amount faceValue, Instant maturityDate) {
this.issuance = issuance;
@ -133,6 +129,7 @@ public class JavaCommercialPaper implements Contract {
return obj instanceof Redeem;
}
}
public static class Issue extends Commands {
@Override
public boolean equals(Object obj) {
@ -173,16 +170,16 @@ public class JavaCommercialPaper implements Contract {
Instant time = timestampCommand.getBefore();
if (! time.isBefore(output.maturityDate)) {
if (!time.isBefore(output.maturityDate)) {
throw new IllegalStateException("Failed Requirement: the maturity date is not in the past");
}
if (!cmd.getSigners().contains(output.issuance.getParty().getOwningKey())) {
throw new IllegalStateException("Failed Requirement: the issuance is signed by the claimed issuer of the paper");
}
}
else { // Everything else (Move, Redeem) requires inputs (they are not first to be actioned)
// There should be only a single input due to aggregation above
} else {
// Everything else (Move, Redeem) requires inputs (they are not first to be actioned)
// There should be only a single input due to aggregation above
State input = single(inputs);
if (!cmd.getSigners().contains(input.getOwner()))
@ -196,9 +193,7 @@ public class JavaCommercialPaper implements Contract {
!output.getIssuance().equals(input.getIssuance()) ||
!output.getMaturityDate().equals(input.getMaturityDate()))
throw new IllegalStateException("Failed requirement: the output state is the same as the input state except for owner");
}
else if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Redeem)
{
} else if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Redeem) {
TimestampCommand timestampCommand = tx.getTimestampBy(DummyTimestampingAuthority.INSTANCE.getIdentity());
if (timestampCommand == null)
throw new IllegalArgumentException("Failed Requirement: must be timestamped");
@ -206,7 +201,7 @@ public class JavaCommercialPaper implements Contract {
Amount received = CashKt.sumCashBy(tx.getOutStates(), input.getOwner());
if (! received.equals(input.getFaceValue()))
if (!received.equals(input.getFaceValue()))
throw new IllegalStateException("Failed Requirement: received amount equals the face value");
if (time.isBefore(input.getMaturityDate()))
throw new IllegalStateException("Failed requirement: the paper must have matured");
@ -227,14 +222,14 @@ public class JavaCommercialPaper implements Contract {
}
public TransactionBuilder generateIssue(@NotNull PartyReference issuance, @NotNull Amount faceValue, @Nullable Instant maturityDate) {
State state = new State(issuance,issuance.getParty().getOwningKey(), faceValue, maturityDate);
return new TransactionBuilder().withItems(state, new Command( new Commands.Issue(), issuance.getParty().getOwningKey()));
State state = new State(issuance, issuance.getParty().getOwningKey(), faceValue, maturityDate);
return new TransactionBuilder().withItems(state, new Command(new Commands.Issue(), issuance.getParty().getOwningKey()));
}
public void generateRedeem(TransactionBuilder tx, StateAndRef<State> paper, List<StateAndRef<Cash.State>> wallet) throws InsufficientBalanceException {
new Cash().generateSpend(tx, paper.getState().getFaceValue(), paper.getState().getOwner(), wallet, null);
tx.addInputState(paper.getRef());
tx.addCommand(new Command( new Commands.Redeem(), paper.getState().getOwner()));
tx.addCommand(new Command(new Commands.Redeem(), paper.getState().getOwner()));
}
public void generateMove(TransactionBuilder tx, StateAndRef<State> paper, PublicKey newOwner) {

View File

@ -143,7 +143,7 @@ class Cash : Contract {
// Now check the digital signatures on the move command. Every input has an owning public key, and we must
// see a signature from each of those keys. The actual signatures have been verified against the transaction
// data by the platform before execution.
val owningPubKeys = inputs.map { it.owner }.toSet()
val owningPubKeys = inputs.map { it.owner }.toSet()
val keysThatSigned = tx.commands.requireSingleCommand<Commands.Move>().signers.toSet()
requireThat {
"the owning keys are the same as the signing keys" by keysThatSigned.containsAll(owningPubKeys)
@ -245,10 +245,13 @@ class Cash : Contract {
/** Sums the cash states in the list that are owned by the given key, throwing an exception if there are none. */
fun Iterable<ContractState>.sumCashBy(owner: PublicKey) = filterIsInstance<Cash.State>().filter { it.owner == owner }.map { it.amount }.sumOrThrow()
/** Sums the cash states in the list, throwing an exception if there are none. */
fun Iterable<ContractState>.sumCash() = filterIsInstance<Cash.State>().map { it.amount }.sumOrThrow()
/** Sums the cash states in the list, returning null if there are none. */
fun Iterable<ContractState>.sumCashOrNull() = filterIsInstance<Cash.State>().map { it.amount }.sumOrNull()
/** Sums the cash states in the list, returning zero of the given currency if there are none. */
fun Iterable<ContractState>.sumCashOrZero(currency: Currency) = filterIsInstance<Cash.State>().map { it.amount }.sumOrZero(currency)

View File

@ -59,6 +59,7 @@ class CommercialPaper : Contract {
// Although kotlin is smart enough not to need these, as we are using the ICommercialPaperState, we need to declare them explicitly for use later,
override fun withOwner(newOwner: PublicKey): ICommercialPaperState = copy(owner = newOwner)
override fun withIssuance(newIssuance: PartyReference): ICommercialPaperState = copy(issuance = newIssuance)
override fun withFaceValue(newFaceValue: Amount): ICommercialPaperState = copy(faceValue = newFaceValue)
override fun withMaturityDate(newMaturityDate: Instant): ICommercialPaperState = copy(maturityDate = newMaturityDate)

View File

@ -63,8 +63,8 @@ class CrowdFund : Contract {
}
data class Pledge(
val owner: PublicKey,
val amount: Amount
val owner: PublicKey,
val amount: Amount
)

View File

@ -8,8 +8,8 @@
package contracts
fun InterestRateSwap.State.exportIRSToCSV() : String =
"Fixed Leg\n" + FixedRatePaymentEvent.CSVHeader + "\n" +
this.calculation.fixedLegPaymentSchedule.toSortedMap().values.map{ it.asCSV() }.joinToString("\n") + "\n" +
"Floating Leg\n" + FloatingRatePaymentEvent.CSVHeader + "\n" +
this.calculation.floatingLegPaymentSchedule.toSortedMap().values.map{ it.asCSV() }.joinToString("\n") + "\n"
fun InterestRateSwap.State.exportIRSToCSV(): String =
"Fixed Leg\n" + FixedRatePaymentEvent.CSVHeader + "\n" +
this.calculation.fixedLegPaymentSchedule.toSortedMap().values.map { it.asCSV() }.joinToString("\n") + "\n" +
"Floating Leg\n" + FloatingRatePaymentEvent.CSVHeader + "\n" +
this.calculation.floatingLegPaymentSchedule.toSortedMap().values.map { it.asCSV() }.joinToString("\n") + "\n"

View File

@ -13,7 +13,7 @@ import java.security.PublicKey
open class RatioUnit(value: BigDecimal) { // TODO: Discuss this type
val value = value
override fun equals(other: Any?): Boolean{
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other?.javaClass != javaClass) return false
@ -24,7 +24,7 @@ open class RatioUnit(value: BigDecimal) { // TODO: Discuss this type
return true
}
override fun hashCode(): Int{
override fun hashCode(): Int {
return value.hashCode()
}
@ -34,7 +34,7 @@ open class RatioUnit(value: BigDecimal) { // TODO: Discuss this type
* A class to reprecent a percentage in an unambiguous way.
*/
open class PercentageRatioUnit(percentageAsString: String) : RatioUnit(BigDecimal(percentageAsString).divide(BigDecimal("100"))) {
override fun toString(): String = value.times(BigDecimal(100)).toString()+"%"
override fun toString(): String = value.times(BigDecimal(100)).toString() + "%"
}
/**
@ -95,8 +95,7 @@ interface FixableDealState : DealState {
* Parent of the Rate family. Used to denote fixed rates, floating rates, reference rates etc
*/
open class Rate(val ratioUnit: RatioUnit? = null) {
override fun equals(other: Any?): Boolean{
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other?.javaClass != javaClass) return false
@ -112,7 +111,7 @@ open class Rate(val ratioUnit: RatioUnit? = null) {
* that have not yet happened. Yet-to-be fixed floating rates need to be equal such that schedules can be tested
* for equality.
*/
override fun hashCode(): Int{
override fun hashCode(): Int {
return ratioUnit?.hashCode() ?: 0
}
}
@ -127,7 +126,7 @@ class FixedRate(ratioUnit: RatioUnit) : Rate(ratioUnit) {
/**
* The parent class of the Floating rate classes
*/
open class FloatingRate: Rate(null)
open class FloatingRate : Rate(null)
/**
* So a reference rate is a rate that takes its value from a source at a given date

View File

@ -12,6 +12,7 @@ public class AddressFormatException extends IllegalArgumentException {
public AddressFormatException() {
super();
}
public AddressFormatException(String message) {
super(message);
}

View File

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

View File

@ -43,6 +43,7 @@ class Requirements {
if (!expr) throw IllegalArgumentException("Failed requirement: $this")
}
}
val R = Requirements()
inline fun <R> requireThat(body: Requirements.() -> R) = R.body()

View File

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

View File

@ -52,7 +52,7 @@ interface OwnableState : ContractState {
*
* This simplifies the job of tracking the current version of certain types of state in e.g. a wallet
*/
interface LinearState: ContractState {
interface LinearState : ContractState {
/** Unique thread id within the wallets of all parties */
val thread: SecureHash
@ -80,7 +80,7 @@ inline fun <reified T : ContractState> List<StateAndRef<ContractState>>.filterSt
}
/** A [Party] is well known (name, pubkey) pair. In a real system this would probably be an X.509 certificate. */
data class Party(val name: String, val owningKey: PublicKey) {
data class Party(val name: String, val owningKey: PublicKey) {
override fun toString() = name
fun ref(bytes: OpaqueBytes) = PartyReference(this, bytes)
@ -109,6 +109,7 @@ data class Command(val data: CommandData, val pubkeys: List<PublicKey>) {
init {
require(pubkeys.isNotEmpty())
}
constructor(data: CommandData, key: PublicKey) : this(data, listOf(key))
private fun commandDataToString() = data.toString().let { if (it.contains("@")) it.replace('$', '.').split("@")[0] else it }
@ -117,10 +118,10 @@ data class Command(val data: CommandData, val pubkeys: List<PublicKey>) {
/** Wraps an object that was signed by a public key, which may be a well known/recognised institutional key. */
data class AuthenticatedObject<out T : Any>(
val signers: List<PublicKey>,
/** If any public keys were recognised, the looked up institutions are available here */
val signingParties: List<Party>,
val value: T
val signers: List<PublicKey>,
/** If any public keys were recognised, the looked up institutions are available here */
val signingParties: List<Party>,
val value: T
)
/**

View File

@ -25,7 +25,7 @@ import java.util.concurrent.Callable
class TransactionGraphSearch(val transactions: Map<SecureHash, SignedTransaction>,
val startPoints: List<WireTransaction>) : Callable<List<WireTransaction>> {
class Query(
val withCommandOfType: Class<out CommandData>? = null
val withCommandOfType: Class<out CommandData>? = null
)
var query: Query = Query()

View File

@ -104,7 +104,9 @@ data class WireTransaction(val inputs: List<StateRef>,
/** Container for a [WireTransaction] and attached signatures. */
data class SignedTransaction(val txBits: SerializedBytes<WireTransaction>,
val sigs: List<DigitalSignature.WithKey>) : NamedByHash {
init { check(sigs.isNotEmpty()) }
init {
check(sigs.isNotEmpty())
}
/** Lazily calculated access to the deserialised/hashed transaction data. */
val tx: WireTransaction by lazy { WireTransaction.deserialize(txBits) }
@ -298,6 +300,7 @@ class TransactionBuilder(private val inputs: MutableList<StateRef> = arrayListOf
// Accessors that yield immutable snapshots.
fun inputStates(): List<StateRef> = ArrayList(inputs)
fun outputStates(): List<ContractState> = ArrayList(outputs)
fun commands(): List<Command> = ArrayList(commands)
fun attachments(): List<SecureHash> = ArrayList(attachments)

View File

@ -46,13 +46,24 @@ fun random63BitValue(): Long = Math.abs(SecureRandom.getInstanceStrong().nextLon
// Some utilities for working with Guava listenable futures.
fun <T> ListenableFuture<T>.then(executor: Executor, body: () -> Unit) = addListener(Runnable(body), executor)
fun <T> ListenableFuture<T>.success(executor: Executor, body: (T) -> Unit) = then(executor) {
val r = try { get() } catch(e: Throwable) { return@then }
val r = try {
get()
} catch(e: Throwable) {
return@then
}
body(r)
}
fun <T> ListenableFuture<T>.failure(executor: Executor, body: (Throwable) -> Unit) = then(executor) {
try { get() } catch(e: Throwable) { body(e) }
try {
get()
} catch(e: Throwable) {
body(e)
}
}
infix fun <T> ListenableFuture<T>.then(body: () -> Unit): ListenableFuture<T> = apply { then(RunOnCallerThread, body) }
infix fun <T> ListenableFuture<T>.success(body: (T) -> Unit): ListenableFuture<T> = apply { success(RunOnCallerThread, body) }
infix fun <T> ListenableFuture<T>.failure(body: (Throwable) -> Unit): ListenableFuture<T> = apply { failure(RunOnCallerThread, body) }

View File

@ -18,7 +18,10 @@ import java.security.interfaces.ECPublicKey
// "sealed" here means there can't be any subclasses other than the ones defined here.
sealed class SecureHash private constructor(bits: ByteArray) : OpaqueBytes(bits) {
class SHA256(bits: ByteArray) : SecureHash(bits) {
init { require(bits.size == 32) }
init {
require(bits.size == 32)
}
override val signatureAlgorithmName: String get() = "SHA256withECDSA"
}
@ -97,6 +100,7 @@ fun PrivateKey.signWithECDSA(bits: ByteArray): DigitalSignature {
fun PrivateKey.signWithECDSA(bitsToSign: ByteArray, publicKey: PublicKey): DigitalSignature.WithKey {
return DigitalSignature.WithKey(publicKey, signWithECDSA(bitsToSign).bits)
}
fun KeyPair.signWithECDSA(bitsToSign: ByteArray) = private.signWithECDSA(bitsToSign, public)
fun KeyPair.signWithECDSA(bitsToSign: OpaqueBytes) = private.signWithECDSA(bitsToSign.bits, public)
fun KeyPair.signWithECDSA(bitsToSign: OpaqueBytes, party: Party) = signWithECDSA(bitsToSign.bits, party)
@ -124,6 +128,7 @@ fun PublicKey.toStringShort(): String {
// Allow Kotlin destructuring: val (private, public) = keypair
operator fun KeyPair.component1() = this.private
operator fun KeyPair.component2() = this.public
/** A simple wrapper that will make it easier to swap out the EC algorithm we use in future */

View File

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

View File

@ -17,13 +17,15 @@ import java.util.*
* functionality to Java, but it won't arrive for a few years yet!
*/
open class OpaqueBytes(val bits: ByteArray) {
init { check(bits.isNotEmpty()) }
init {
check(bits.isNotEmpty())
}
companion object {
fun of(vararg b: Byte) = OpaqueBytes(byteArrayOf(*b))
}
override fun equals(other: Any?): Boolean{
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is OpaqueBytes) return false
return Arrays.equals(bits, other.bits)

View File

@ -81,12 +81,15 @@ inline fun <reified T : Any> ByteArray.deserialize(kryo: Kryo = THREAD_LOCAL_KRY
else
return kryo.readObject(Input(this), T::class.java)
}
inline fun <reified T : Any> OpaqueBytes.deserialize(kryo: Kryo = THREAD_LOCAL_KRYO.get(), includeClassName: Boolean = false): T {
return this.bits.deserialize(kryo, includeClassName)
}
// The more specific deserialize version results in the bytes being cached, which is faster.
@JvmName("SerializedBytesWireTransaction")
fun SerializedBytes<WireTransaction>.deserialize(): WireTransaction = WireTransaction.deserialize(this)
inline fun <reified T : Any> SerializedBytes<T>.deserialize(): T = bits.deserialize()
/**
@ -175,7 +178,11 @@ class ImmutableClassSerializer<T : Any>(val klass: KClass<T>) : Serializer<T>()
}
}
// If the constructor throws an exception, pass it through instead of wrapping it.
return try { constructor.call(*args) } catch (e: InvocationTargetException) { throw e.cause!! }
return try {
constructor.call(*args)
} catch (e: InvocationTargetException) {
throw e.cause!!
}
}
}
@ -187,7 +194,7 @@ fun createKryo(k: Kryo = Kryo()): Kryo {
// no-arg constructor available.
instantiatorStrategy = Kryo.DefaultInstantiatorStrategy(StdInstantiatorStrategy())
register(Arrays.asList( "" ).javaClass, ArraysAsListSerializer());
register(Arrays.asList("").javaClass, ArraysAsListSerializer());
// Because we like to stick a Kryo object in a ThreadLocal to speed things up a bit, we can end up trying to
// serialise the Kryo object itself when suspending a fiber. That's dumb, useless AND can cause crashes, so
@ -211,8 +218,8 @@ fun createKryo(k: Kryo = Kryo()): Kryo {
// Some classes have to be handled with the ImmutableClassSerializer because they need to have their
// constructors be invoked (typically for lazy members).
val immutables = listOf(
SignedTransaction::class,
SerializedBytes::class
SignedTransaction::class,
SerializedBytes::class
)
immutables.forEach {

View File

@ -45,9 +45,11 @@ class ProgressTracker(vararg steps: Step) {
class Position(val tracker: ProgressTracker, val newStep: Step) : Change() {
override fun toString() = newStep.label
}
class Rendering(val tracker: ProgressTracker, val ofStep: Step) : Change() {
override fun toString() = ofStep.label
}
class Structural(val tracker: ProgressTracker, val parent: Step) : Change() {
override fun toString() = "Structural step change in child of ${parent.label}"
}
@ -75,6 +77,7 @@ class ProgressTracker(vararg steps: Step) {
object UNSTARTED : Step("Unstarted") {
override fun equals(other: Any?) = other is UNSTARTED
}
object DONE : Step("Done") {
override fun equals(other: Any?) = other is DONE
}

View File

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

View File

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

View File

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

View File

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

View File

@ -12,7 +12,6 @@ package api
* Extremely rudimentary query language which should most likely be replaced with a product
*/
interface StatesQuery {
companion object {
fun select(criteria: Criteria): Selection {
return Selection(criteria)
@ -29,13 +28,11 @@ interface StatesQuery {
}
// TODO make constructors private
data class Selection(val criteria: Criteria): StatesQuery
data class Selection(val criteria: Criteria) : StatesQuery
interface Criteria {
object AllDeals : Criteria
object AllDeals: Criteria
data class Deal(val ref: String): Criteria
data class Deal(val ref: String) : Criteria
}
}

View File

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

View File

@ -128,9 +128,12 @@ object TopicStringValidator {
/** The interface for a group of message recipients (which may contain only one recipient) */
interface MessageRecipients
/** A base class for the case of point-to-point messages */
interface SingleMessageRecipient : MessageRecipients
/** A base class for a set of recipients specifically identified by the sender. */
interface MessageRecipientGroup : MessageRecipients
/** A special base class for the set of all possible recipients, without having to identify who they all are. */
interface AllPossibleRecipients : MessageRecipients

View File

@ -68,7 +68,11 @@ class StateMachineManager(val serviceHub: ServiceHub, val runInThread: Executor)
// Monitoring support.
private val metrics = serviceHub.monitoringService.metrics
init { metrics.register("Protocols.InFlight", Gauge<kotlin.Int> { _stateMachines.size }) }
init {
metrics.register("Protocols.InFlight", Gauge<kotlin.Int> { _stateMachines.size })
}
private val checkpointingMeter = metrics.meter("Protocols.Checkpointing Rate")
private val totalStartedProtocols = metrics.counter("Protocols.Started")
private val totalFinishedProtocols = metrics.counter("Protocols.Finished")
@ -90,16 +94,16 @@ class StateMachineManager(val serviceHub: ServiceHub, val runInThread: Executor)
// This class will be serialised, so everything it points to transitively must also be serialisable (with Kryo).
private class Checkpoint(
val serialisedFiber: ByteArray,
val loggerName: String,
val awaitingTopic: String,
val awaitingObjectOfType: String // java class name
val serialisedFiber: ByteArray,
val loggerName: String,
val awaitingTopic: String,
val awaitingObjectOfType: String // java class name
)
init {
// Blank out the default uncaught exception handler because we always catch things ourselves, and the default
// just redundantly prints stack traces to the logs.
Fiber.setDefaultUncaughtExceptionHandler { fiber, throwable -> }
Fiber.setDefaultUncaughtExceptionHandler { fiber, throwable -> }
restoreCheckpoints()
}

View File

@ -82,11 +82,13 @@ class ArtemisMessagingService(val directory: Path, val myHostPort: HostAndPort)
var running = false
val sendClients = HashMap<Address, ClientProducer>()
}
private val mutex = ThreadBox(InnerState())
/** A registration to handle messages of different types */
inner class Handler(val executor: Executor?, val topic: String,
val callback: (Message, MessageHandlerRegistration) -> Unit) : MessageHandlerRegistration
private val handlers = CopyOnWriteArrayList<Handler>()
private fun getSendClient(addr: Address): ClientProducer {

View File

@ -8,9 +8,6 @@
package core.node.services
import protocols.FetchAttachmentsProtocol
import protocols.FetchTransactionsProtocol
import core.node.services.StorageService
import core.crypto.SecureHash
import core.messaging.Message
import core.messaging.MessagingService
@ -18,6 +15,8 @@ import core.messaging.SingleMessageRecipient
import core.messaging.send
import core.serialization.deserialize
import core.utilities.loggerFor
import protocols.FetchAttachmentsProtocol
import protocols.FetchTransactionsProtocol
import java.io.InputStream
import javax.annotation.concurrent.ThreadSafe

View File

@ -8,7 +8,6 @@
package core.node.services
import core.node.services.KeyManagementService
import core.ThreadBox
import core.crypto.generateKeyPair
import java.security.KeyPair
@ -33,6 +32,7 @@ class E2ETestKeyManagementService : KeyManagementService {
private class InnerState {
val keys = HashMap<PublicKey, PrivateKey>()
}
private val mutex = ThreadBox(InnerState())
// Accessing this map clones it.

View File

@ -27,7 +27,7 @@ data class NodeInfo(val address: SingleMessageRecipient, val identity: Party,
* then be cached by every node and thus a network map can be retrieved given only a single successful peer connection.
*
* This interface assumes fast, synchronous access to an in-memory map.
*/
*/
interface NetworkMapCache {
val timestampingNodes: List<NodeInfo>
val ratesOracleNodes: List<NodeInfo>
@ -39,7 +39,7 @@ interface NetworkMapCache {
// TODO: Move this to the test tree once a real network map is implemented and this scaffolding is no longer needed.
class MockNetworkMapCache : NetworkMapCache {
data class MockAddress(val id: String): SingleMessageRecipient
data class MockAddress(val id: String) : SingleMessageRecipient
override val timestampingNodes = Collections.synchronizedList(ArrayList<NodeInfo>())
override val ratesOracleNodes = Collections.synchronizedList(ArrayList<NodeInfo>())

View File

@ -98,6 +98,7 @@ class NodeAttachmentService(val storePath: Path, val metrics: MetricRegistry) :
stream = HashCheckingStream(id, path, stream)
return stream
}
override fun equals(other: Any?) = other is Attachment && other.id == id
override fun hashCode(): Int = id.hashCode()
}

View File

@ -51,8 +51,8 @@ object NodeInterestRates {
}
/** Parses lines containing fixes */
fun parseFile(s: String): Map<FixOf, TreeMap<LocalDate,Fix>> {
val results = HashMap<FixOf, TreeMap<LocalDate,Fix>>()
fun parseFile(s: String): Map<FixOf, TreeMap<LocalDate, Fix>> {
val results = HashMap<FixOf, TreeMap<LocalDate, Fix>>()
for (line in s.lines()) {
val (fixOf, fix) = parseOneRate(line)
val genericKey = FixOf(fixOf.name, LocalDate.MIN, fixOf.ofTenor)
@ -96,7 +96,7 @@ object NodeInterestRates {
override val acceptableFileExtensions = listOf(".rates", ".txt")
override fun upload(data: InputStream): String {
val fixes: Map<FixOf, TreeMap<LocalDate,Fix>> = parseFile(data.
val fixes: Map<FixOf, TreeMap<LocalDate, Fix>> = parseFile(data.
bufferedReader().
readLines().
map { it.trim() }.
@ -133,7 +133,7 @@ object NodeInterestRates {
* to a sorted map of LocalDate to Fix, allowing for approximate date finding so that we do not need
* to populate the file with a rate for every day.
*/
@Volatile var knownFixes = emptyMap<FixOf, TreeMap<LocalDate,Fix>>()
@Volatile var knownFixes = emptyMap<FixOf, TreeMap<LocalDate, Fix>>()
set(value) {
require(value.isNotEmpty())
field = value
@ -154,7 +154,7 @@ object NodeInterestRates {
val rates = knownFixes[FixOf(fixOf.name, LocalDate.MIN, fixOf.ofTenor)]
// Greatest key less than or equal to the date we're looking for
val floor = rates?.floorEntry(fixOf.forDay)?.value
return if (floor!=null) {
return if (floor != null) {
Fix(fixOf, floor.value)
} else {
null

View File

@ -33,6 +33,7 @@ class NodeWalletService(private val services: ServiceHub) : WalletService {
private class InnerState {
var wallet: Wallet = Wallet(emptyList<StateAndRef<OwnableState>>())
}
private val mutex = ThreadBox(InnerState())
override val currentWallet: Wallet get() = mutex.locked { wallet }
@ -78,9 +79,9 @@ class NodeWalletService(private val services: ServiceHub) : WalletService {
}
private fun isRelevant(state: ContractState, ourKeys: Set<PublicKey>): Boolean {
return if(state is OwnableState) {
return if (state is OwnableState) {
state.owner in ourKeys
} else if(state is LinearState) {
} else if (state is LinearState) {
// It's potentially of interest to the wallet
state.isRelevant(ourKeys)
} else {

View File

@ -40,12 +40,12 @@ data class Wallet(val states: List<StateAndRef<ContractState>>) {
* which we have no cash evaluate to null (not present in map), not 0.
*/
val cashBalances: Map<Currency, Amount> get() = states.
// Select the states we own which are cash, ignore the rest, take the amounts.
mapNotNull { (it.state as? Cash.State)?.amount }.
// Turn into a Map<Currency, List<Amount>> like { GBP -> (£100, £500, etc), USD -> ($2000, $50) }
groupBy { it.currency }.
// Collapse to Map<Currency, Amount> by summing all the amounts of the same currency together.
mapValues { it.value.sumOrThrow() }
// Select the states we own which are cash, ignore the rest, take the amounts.
mapNotNull { (it.state as? Cash.State)?.amount }.
// Turn into a Map<Currency, List<Amount>> like { GBP -> (£100, £500, etc), USD -> ($2000, $50) }
groupBy { it.currency }.
// Collapse to Map<Currency, Amount> by summing all the amounts of the same currency together.
mapValues { it.value.sumOrThrow() }
}
/**
@ -82,7 +82,7 @@ interface WalletService {
fun statesForRefs(refs: List<StateRef>): Map<StateRef, ContractState?> {
val refsToStates = currentWallet.states.associateBy { it.ref }
return refs.associateBy( { it }, { refsToStates[it]?.state } )
return refs.associateBy({ it }, { refsToStates[it]?.state })
}
/**

View File

@ -8,8 +8,8 @@
package core.node.servlets
import core.node.services.StorageService
import core.crypto.SecureHash
import core.node.services.StorageService
import core.utilities.loggerFor
import java.io.FileNotFoundException
import javax.servlet.http.HttpServlet

View File

@ -26,7 +26,7 @@ class DataUploadServlet : HttpServlet() {
override fun doPost(req: HttpServletRequest, resp: HttpServletResponse) {
val node = servletContext.getAttribute("node") as Node
@Suppress("DEPRECATION") // Bogus warning due to superclass static method being deprecated.
@Suppress("DEPRECATION") // Bogus warning due to superclass static method being deprecated.
val isMultipart = ServletFileUpload.isMultipartContent(req)
if (!isMultipart) {

View File

@ -9,8 +9,8 @@
package core.protocols
import co.paralleluniverse.fibers.Suspendable
import core.node.services.ServiceHub
import core.messaging.MessageRecipients
import core.node.services.ServiceHub
import core.utilities.ProgressTracker
import core.utilities.UntrustworthyData
import org.slf4j.Logger
@ -47,12 +47,15 @@ abstract class ProtocolLogic<T> {
sessionIDForReceive: Long, obj: Any): UntrustworthyData<T> {
return psm.sendAndReceive(topic, destination, sessionIDForSend, sessionIDForReceive, obj, T::class.java)
}
inline fun <reified T : Any> receive(topic: String, sessionIDForReceive: Long): UntrustworthyData<T> {
return receive(topic, sessionIDForReceive, T::class.java)
}
@Suspendable fun <T : Any> receive(topic: String, sessionIDForReceive: Long, clazz: Class<T>): UntrustworthyData<T> {
return psm.receive(topic, sessionIDForReceive, clazz)
}
@Suspendable fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any) {
psm.send(topic, destination, sessionID, obj)
}

View File

@ -14,9 +14,9 @@ import co.paralleluniverse.io.serialization.kryo.KryoSerializer
import com.esotericsoftware.kryo.io.Output
import com.google.common.util.concurrent.ListenableFuture
import com.google.common.util.concurrent.SettableFuture
import core.node.services.ServiceHub
import core.messaging.MessageRecipients
import core.messaging.StateMachineManager
import core.node.services.ServiceHub
import core.serialization.createKryo
import core.utilities.UntrustworthyData
import org.slf4j.Logger

View File

@ -59,7 +59,7 @@ class InMemoryMessagingNetwork {
*/
@Synchronized
fun createNode(manuallyPumped: Boolean): Pair<Handle, MessagingServiceBuilder<InMemoryMessaging>> {
check(counter >= 0) { "In memory network stopped: please recreate."}
check(counter >= 0) { "In memory network stopped: please recreate." }
val builder = createNodeWithID(manuallyPumped, counter) as Builder
counter++
val id = builder.id
@ -170,15 +170,18 @@ class InMemoryMessagingNetwork {
* An instance can be obtained by creating a builder and then using the start method.
*/
@ThreadSafe
inner class InMemoryMessaging(private val manuallyPumped: Boolean, private val handle: Handle): MessagingService {
inner class InMemoryMessaging(private val manuallyPumped: Boolean, private val handle: Handle) : MessagingService {
inner class Handler(val executor: Executor?, val topic: String,
val callback: (Message, MessageHandlerRegistration) -> Unit) : MessageHandlerRegistration
@Volatile
protected var running = true
protected inner class InnerState {
val handlers: MutableList<Handler> = ArrayList()
val pendingRedelivery = LinkedList<Message>()
}
protected val state = ThreadBox(InnerState())
override val myAddress: SingleMessageRecipient = handle

View File

@ -124,7 +124,8 @@ class MockNetwork(private val threadPerNode: Boolean = false,
fun runNetwork(rounds: Int = -1) {
fun pumpAll() = messagingNetwork.endpoints.map { it.pump(false) }
if (rounds == -1)
while (pumpAll().any { it }) {}
while (pumpAll().any { it }) {
}
else
repeat(rounds) { pumpAll() }
}

View File

@ -30,7 +30,7 @@ import java.util.*
* in a few cities around the world.
*/
abstract class Simulation(val runAsync: Boolean,
val latencyInjector: InMemoryMessagingNetwork.LatencyCalculator?) {
val latencyInjector: InMemoryMessagingNetwork.LatencyCalculator?) {
init {
if (!runAsync && latencyInjector != null)
throw IllegalArgumentException("The latency injector is only useful when using manual pumping.")
@ -41,7 +41,7 @@ abstract class Simulation(val runAsync: Boolean,
// This puts together a mock network of SimulatedNodes.
open class SimulatedNode(dir: Path, config: NodeConfiguration, mockNet: MockNetwork,
withTimestamper: NodeInfo?) : MockNetwork.MockNode(dir, config, mockNet, withTimestamper) {
withTimestamper: NodeInfo?) : MockNetwork.MockNode(dir, config, mockNet, withTimestamper) {
override fun findMyLocation(): PhysicalLocation? = CityDatabase[configuration.nearestCity]
}
@ -190,7 +190,8 @@ abstract class Simulation(val runAsync: Boolean,
}
}
open fun start() {}
open fun start() {
}
fun stop() {
network.nodes.forEach { it.stop() }

View File

@ -59,15 +59,15 @@ object JsonSupport {
return mapper
}
class ServiceHubObjectMapper(val identities: IdentityService): ObjectMapper()
class ServiceHubObjectMapper(val identities: IdentityService) : ObjectMapper()
object ToStringSerializer: JsonSerializer<Any>() {
object ToStringSerializer : JsonSerializer<Any>() {
override fun serialize(obj: Any, generator: JsonGenerator, provider: SerializerProvider) {
generator.writeString(obj.toString())
}
}
object LocalDateDeserializer: JsonDeserializer<LocalDate>() {
object LocalDateDeserializer : JsonDeserializer<LocalDate>() {
override fun deserialize(parser: JsonParser, context: DeserializationContext): LocalDate {
return try {
LocalDate.parse(parser.text)
@ -77,22 +77,22 @@ object JsonSupport {
}
}
object LocalDateKeyDeserializer: KeyDeserializer() {
object LocalDateKeyDeserializer : KeyDeserializer() {
override fun deserializeKey(text: String, p1: DeserializationContext): Any? {
return LocalDate.parse(text)
}
}
object PartySerializer: JsonSerializer<Party>() {
object PartySerializer : JsonSerializer<Party>() {
override fun serialize(obj: Party, generator: JsonGenerator, provider: SerializerProvider) {
generator.writeString(obj.name)
}
}
object PartyDeserializer: JsonDeserializer<Party>() {
object PartyDeserializer : JsonDeserializer<Party>() {
override fun deserialize(parser: JsonParser, context: DeserializationContext): Party {
if(parser.currentToken == JsonToken.FIELD_NAME) {
if (parser.currentToken == JsonToken.FIELD_NAME) {
parser.nextToken()
}
val mapper = parser.codec as ServiceHubObjectMapper
@ -101,7 +101,7 @@ object JsonSupport {
}
}
object SecureHashSerializer: JsonSerializer<SecureHash>() {
object SecureHashSerializer : JsonSerializer<SecureHash>() {
override fun serialize(obj: SecureHash, generator: JsonGenerator, provider: SerializerProvider) {
generator.writeString(obj.toString())
}
@ -110,9 +110,9 @@ object JsonSupport {
/**
* Implemented as a class so that we can instantiate for T
*/
class SecureHashDeserializer<T : SecureHash>: JsonDeserializer<T>() {
class SecureHashDeserializer<T : SecureHash> : JsonDeserializer<T>() {
override fun deserialize(parser: JsonParser, context: DeserializationContext): T {
if(parser.currentToken == JsonToken.FIELD_NAME) {
if (parser.currentToken == JsonToken.FIELD_NAME) {
parser.nextToken()
}
try {
@ -124,7 +124,7 @@ object JsonSupport {
}
}
object CalendarDeserializer: JsonDeserializer<BusinessCalendar>() {
object CalendarDeserializer : JsonDeserializer<BusinessCalendar>() {
override fun deserialize(parser: JsonParser, context: DeserializationContext): BusinessCalendar {
return try {
val array = StringArrayDeserializer.instance.deserialize(parser, context)

View File

@ -23,6 +23,7 @@ import kotlin.reflect.KClass
// Kotlin's string interpolation efficiently: the message is never calculated/concatenated together unless
// logging at that level is enabled.
inline fun <reified T : Any> loggerFor(): org.slf4j.Logger = LoggerFactory.getLogger(T::class.java)
inline fun org.slf4j.Logger.trace(msg: () -> String) {
if (isTraceEnabled) trace(msg())
}

View File

@ -8,7 +8,6 @@
package core.utilities
import core.utilities.loggerFor
import org.slf4j.Logger
import java.util.*
import javax.annotation.concurrent.ThreadSafe
@ -24,6 +23,7 @@ class RecordingMap<K, V>(private val wrappedMap: MutableMap<K, V>,
private val logger: Logger = loggerFor<RecordingMap<K, V>>()) : MutableMap<K, V> by wrappedMap {
// If/when Kotlin supports data classes inside sealed classes, that would be preferable to this.
interface Record
data class Get<K>(val key: K) : Record
data class Put<K, V>(val key: K, val value: V) : Record

View File

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

View File

@ -75,7 +75,7 @@ fun main(args: Array<String>) {
val myNetAddr = HostAndPort.fromString(options.valueOf(networkAddressArg)).withDefaultPort(Node.DEFAULT_PORT)
// The timestamping node runs in the same process as the one that passes null to Node constructor.
val timestamperId = if(options.valueOf(timestamperNetAddr).equals(options.valueOf(networkAddressArg))) {
val timestamperId = if (options.valueOf(timestamperNetAddr).equals(options.valueOf(networkAddressArg))) {
null
} else {
try {
@ -86,7 +86,7 @@ fun main(args: Array<String>) {
}
// The timestamping node runs in the same process as the one that passes null to Node constructor.
val rateOracleId = if(options.valueOf(rateOracleNetAddr).equals(options.valueOf(networkAddressArg))) {
val rateOracleId = if (options.valueOf(rateOracleNetAddr).equals(options.valueOf(networkAddressArg))) {
null
} else {
try {
@ -106,10 +106,10 @@ fun main(args: Array<String>) {
val hostAndPortStrings = options.valuesOf(fakeTradeWithAddr)
val identityFiles = options.valuesOf(fakeTradeWithIdentityFile)
if(hostAndPortStrings.size != identityFiles.size) {
if (hostAndPortStrings.size != identityFiles.size) {
throw IllegalArgumentException("Different number of peer addresses (${hostAndPortStrings.size}) and identities (${identityFiles.size})")
}
for ((hostAndPortString,identityFile) in hostAndPortStrings.zip(identityFiles)) {
for ((hostAndPortString, identityFile) in hostAndPortStrings.zip(identityFiles)) {
try {
val peerId = nodeInfo(hostAndPortString, identityFile)
(node.services.networkMapCache as MockNetworkMapCache).partyNodes.add(peerId)

View File

@ -20,8 +20,8 @@ import core.node.Node
import core.node.NodeConfiguration
import core.node.NodeConfigurationFromConfig
import core.node.services.ArtemisMessagingService
import core.node.services.NodeInfo
import core.node.services.NodeAttachmentService
import core.node.services.NodeInfo
import core.node.services.NodeWalletService
import core.protocols.ProtocolLogic
import core.serialization.deserialize
@ -242,7 +242,7 @@ class TraderDemoProtocolSeller(val myAddress: HostAndPort,
val party = Party("Bank of London", keyPair.public)
val issuance = run {
val tx = CommercialPaper().generateIssue(party.ref(1,2,3), 1100.DOLLARS, Instant.now() + 10.days)
val tx = CommercialPaper().generateIssue(party.ref(1, 2, 3), 1100.DOLLARS, Instant.now() + 10.days)
// TODO: Consider moving these two steps below into generateIssue.

View File

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

View File

@ -24,7 +24,7 @@ object ExitServerProtocol {
fun register(node: Node) {
node.net.addMessageHandler("${TOPIC}.0") { msg, registration ->
// Just to validate we got the message
if(enabled) {
if (enabled) {
val message = msg.data.deserialize<ExitMessage>()
System.exit(message.exitCode)
}
@ -41,7 +41,7 @@ object ExitServerProtocol {
@Suspendable
override fun call(): Boolean {
if(enabled) {
if (enabled) {
val rc = exitCode.toInt()
val message = ExitMessage(rc)
@ -57,7 +57,7 @@ object ExitServerProtocol {
@Suspendable
private fun doNextRecipient(recipient: NodeInfo, message: ExitMessage) {
if(recipient.address is MockNetworkMapCache.MockAddress) {
if (recipient.address is MockNetworkMapCache.MockAddress) {
// Ignore
} else {
// TODO: messaging ourselves seems to trigger a bug for the time being and we continuously receive messages

View File

@ -49,7 +49,7 @@ object UpdateBusinessDayProtocol {
val sortedParties = otherPartyToDeals.keys.sortedBy { it.identity.name }
for (party in sortedParties) {
val sortedDeals = otherPartyToDeals[party]!!.sortedBy { it.state.ref }
for(deal in sortedDeals) {
for (deal in sortedDeals) {
progressTracker.currentStep = ITERATING_DEALS
processDeal(party, deal, date, sessionID)
}
@ -162,7 +162,7 @@ object UpdateBusinessDayProtocol {
@Suspendable
private fun doNextRecipient(recipient: NodeInfo, message: UpdateBusinessDayMessage) {
if(recipient.address is MockNetworkMapCache.MockAddress) {
if (recipient.address is MockNetworkMapCache.MockAddress) {
// Ignore
} else {
// TODO: messaging ourselves seems to trigger a bug for the time being and we continuously receive messages

View File

@ -51,7 +51,6 @@ class TimestampingProtocol(private val node: NodeInfo,
}
@Suspendable
override fun call(): DigitalSignature.LegallyIdentifiable {
progressTracker.currentStep = REQUESTING

View File

@ -13,11 +13,11 @@ import org.junit.*;
import java.math.*;
import java.util.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assert.*;
/** From the bitcoinj library */
/**
* From the bitcoinj library
*/
public class Base58Test {
@Test
public void testEncode() throws Exception {

View File

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

View File

@ -43,12 +43,13 @@ class JavaCommercialPaperTest() : ICommercialPaperTestTemplate {
}
class KotlinCommercialPaperTest() : ICommercialPaperTestTemplate {
override fun getPaper() : ICommercialPaperState = CommercialPaper.State(
override fun getPaper(): ICommercialPaperState = CommercialPaper.State(
issuance = MEGA_CORP.ref(123),
owner = MEGA_CORP_PUBKEY,
faceValue = 1000.DOLLARS,
maturityDate = TEST_TX_TIME + 7.days
)
override fun getIssueCommand(): CommandData = CommercialPaper.Commands.Issue()
override fun getRedeemCommand(): CommandData = CommercialPaper.Commands.Redeem()
override fun getMoveCommand(): CommandData = CommercialPaper.Commands.Move()

View File

@ -21,10 +21,10 @@ import kotlin.test.assertTrue
class CrowdFundTests {
val CF_1 = CrowdFund.State(
campaign = CrowdFund.Campaign(
owner = MINI_CORP_PUBKEY,
name = "kickstart me",
target = 1000.DOLLARS,
closingTime = TEST_TX_TIME + 7.days
owner = MINI_CORP_PUBKEY,
name = "kickstart me",
target = 1000.DOLLARS,
closingTime = TEST_TX_TIME + 7.days
),
closed = false,
pledges = ArrayList<CrowdFund.Pledge>()
@ -146,7 +146,7 @@ class CrowdFundTests {
400.DOLLARS.CASH `owned by` MINI_CORP_PUBKEY
)
// MiniCorp closes their campaign.
fun makeFundedTX(time: Instant): LedgerTransaction {
fun makeFundedTX(time: Instant): LedgerTransaction {
val ptx = TransactionBuilder()
ptx.setTime(time, DUMMY_TIMESTAMPER.identity, 30.seconds)
CrowdFund().generateClose(ptx, pledgeTX.outRef(0), miniCorpWallet)

View File

@ -16,7 +16,7 @@ import java.time.LocalDate
import java.util.*
fun createDummyIRS(irsSelect: Int): InterestRateSwap.State {
return when(irsSelect) {
return when (irsSelect) {
1 -> {
val fixedLeg = InterestRateSwap.FixedLeg(

View File

@ -12,8 +12,8 @@ import core.Attachment
import core.crypto.SecureHash
import core.crypto.sha256
import core.node.NodeConfiguration
import core.node.services.NodeInfo
import core.node.services.NodeAttachmentService
import core.node.services.NodeInfo
import core.serialization.OpaqueBytes
import core.testing.MockNetwork
import core.testutils.rootCauseExceptions

View File

@ -54,7 +54,8 @@ open class TestWithInMemoryNetwork {
}
fun runNetwork() {
while (pumpAll(false).any { it }) {}
while (pumpAll(false).any { it }) {
}
}
}

View File

@ -135,6 +135,7 @@ class TwoPartyTradeProtocolTests : TestWithInMemoryNetwork() {
// Everything is on this thread so we can now step through the protocol one step at a time.
// Seller Alice already sent a message to Buyer Bob. Pump once:
fun pumpAlice() = (aliceNode.net as InMemoryMessagingNetwork.InMemoryMessaging).pump(false)
fun pumpBob() = (bobNode.net as InMemoryMessagingNetwork.InMemoryMessaging).pump(false)
pumpBob()

View File

@ -42,7 +42,7 @@ class NodeAttachmentStorageTest {
val expectedHash = SecureHash.sha256(Files.readAllBytes(testJar))
val storage = NodeAttachmentService(fs.getPath("/"), MetricRegistry())
val id = testJar.use { storage.importAttachment(it) }
val id = testJar.use { storage.importAttachment(it) }
assertEquals(expectedHash, id)
assertNull(storage.openAttachment(SecureHash.randomSHA256()))

View File

@ -31,7 +31,7 @@ class TransactionSerializationTests {
@Before
fun setup() {
tx = TransactionBuilder().withItems(
fakeStateRef, outputState, changeState, Command(Cash.Commands.Move(), arrayListOf(TestUtils.keypair.public))
fakeStateRef, outputState, changeState, Command(Cash.Commands.Move(), arrayListOf(TestUtils.keypair.public))
)
}

View File

@ -27,7 +27,7 @@ import kotlin.test.assertFailsWith
import kotlin.test.fail
/** If an exception is thrown by the body, rethrows the root cause exception. */
inline fun <R> rootCauseExceptions(body: () -> R) : R {
inline fun <R> rootCauseExceptions(body: () -> R): R {
try {
return body()
} catch(e: Exception) {
@ -40,6 +40,7 @@ object TestUtils {
val keypair2 = generateKeyPair()
val keypair3 = generateKeyPair()
}
// A dummy time at which we will be pretending test transactions are created.
val TEST_TX_TIME = Instant.parse("2015-04-17T12:00:00.00Z")
@ -107,7 +108,7 @@ infix fun CommercialPaper.State.`owned by`(owner: PublicKey) = this.copy(owner =
infix fun ICommercialPaperState.`owned by`(new_owner: PublicKey) = this.withOwner(new_owner)
// Allows you to write 100.DOLLARS.CASH
val Amount.CASH: Cash.State get() = Cash.State(MINI_CORP.ref(1,2,3), this, NullPublicKey)
val Amount.CASH: Cash.State get() = Cash.State(MINI_CORP.ref(1, 2, 3), this, NullPublicKey)
class LabeledOutput(val label: String?, val state: ContractState) {
override fun toString() = state.toString() + (if (label != null) " ($label)" else "")
@ -120,7 +121,7 @@ infix fun ContractState.label(label: String) = LabeledOutput(label, this)
abstract class AbstractTransactionForTest {
protected val attachments = ArrayList<SecureHash>()
protected val outStates = ArrayList<LabeledOutput>()
protected val commands = ArrayList<Command>()
protected val commands = ArrayList<Command>()
open fun output(label: String? = null, s: () -> ContractState) = LabeledOutput(label, s()).apply { outStates.add(this) }
@ -148,7 +149,8 @@ abstract class AbstractTransactionForTest {
// Forbid patterns like: transaction { ... transaction { ... } }
@Deprecated("Cannot nest transactions, use tweak", level = DeprecationLevel.ERROR)
fun transaction(body: TransactionForTest.() -> Unit) {}
fun transaction(body: TransactionForTest.() -> Unit) {
}
}
// Corresponds to the args to Contract.verify
@ -180,6 +182,7 @@ open class TransactionForTest : AbstractTransactionForTest() {
// which is uglier?? :)
infix fun `fails requirement`(msg: String) = rejects(msg)
fun fails_requirement(msg: String) = this.`fails requirement`(msg)
// Use this to create transactions where the output of this transaction is automatically used as an input of
@ -281,10 +284,14 @@ class TransactionGroupDSL<T : ContractState>(private val stateType: Class<T>) {
}
@Deprecated("Does not nest ", level = DeprecationLevel.ERROR)
fun roots(body: Roots.() -> Unit) {}
fun roots(body: Roots.() -> Unit) {
}
@Deprecated("Use the vararg form of transaction inside roots", level = DeprecationLevel.ERROR)
fun transaction(body: WireTransactionDSL.() -> Unit) {}
fun transaction(body: WireTransactionDSL.() -> Unit) {
}
}
fun roots(body: Roots.() -> Unit) = Roots().apply { body() }
val txns = ArrayList<WireTransaction>()
@ -304,7 +311,8 @@ class TransactionGroupDSL<T : ContractState>(private val stateType: Class<T>) {
fun labelForTransaction(tx: LedgerTransaction): String? = txnToLabelMap[tx.hash]
@Deprecated("Does not nest ", level = DeprecationLevel.ERROR)
fun transactionGroup(body: TransactionGroupDSL<T>.() -> Unit) {}
fun transactionGroup(body: TransactionGroupDSL<T>.() -> Unit) {
}
fun toTransactionGroup() = TransactionGroup(
txns.map { it.toLedgerTransaction(MockIdentityService, MockStorageService().attachments) }.toSet(),