first check in
This commit is contained in:
19
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
19
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
wrapperVersion=3.3.2
|
||||
distributionType=only-script
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
|
||||
85
pom.xml
Normal file
85
pom.xml
Normal file
@@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.4.3</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.hypernode</groupId>
|
||||
<artifactId>ledger</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>ledger</name>
|
||||
<description>Demo project for Spring Boot</description>
|
||||
<url/>
|
||||
<licenses>
|
||||
<license/>
|
||||
</licenses>
|
||||
<developers>
|
||||
<developer/>
|
||||
</developers>
|
||||
<scm>
|
||||
<connection/>
|
||||
<developerConnection/>
|
||||
<tag/>
|
||||
<url/>
|
||||
</scm>
|
||||
<properties>
|
||||
<java.version>21</java.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<scope>runtime</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
32
src/main/java/com/hypernode/ledger/ClientMethods.java
Normal file
32
src/main/java/com/hypernode/ledger/ClientMethods.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package com.hypernode.ledger;
|
||||
|
||||
public class ClientMethods {
|
||||
|
||||
//client functions
|
||||
|
||||
public static String createNewPrivateKey()
|
||||
{
|
||||
return "PrivateKey";
|
||||
}
|
||||
public static String createPublicKey(String _privateKey)
|
||||
{
|
||||
return "publicKey";
|
||||
}
|
||||
public static Payment walletSpendCurrency(Currency _currency,String _privateKey, String _recipient, String _comment)
|
||||
{
|
||||
Payment payment = ClientMethods.createPayment(_currency,_privateKey,_recipient,_comment);
|
||||
return payment;
|
||||
}
|
||||
public static Payment createPayment(Currency _currency, String _privateKey, String _recipient, String _comment)
|
||||
{
|
||||
Payment payment = new Payment();
|
||||
|
||||
payment.publicKeyFrom = _currency.publicKeyFrom;
|
||||
payment.publicKeyTo = _recipient;
|
||||
payment.paymentComment = _comment;
|
||||
payment.amount = _currency.amount;
|
||||
|
||||
payment.signature = WebServiceMethods.encodeMessage(payment.getSignableMessage(), _privateKey);
|
||||
return payment;
|
||||
}
|
||||
}
|
||||
13
src/main/java/com/hypernode/ledger/Currency.java
Normal file
13
src/main/java/com/hypernode/ledger/Currency.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package com.hypernode.ledger;
|
||||
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class Currency {
|
||||
public static final String COLLECTION_NAME = "Currency";
|
||||
|
||||
String publicKeyFrom;//public key
|
||||
//String bankTo;//public key
|
||||
String publicKeyServer;//vote for a specific validator server
|
||||
BigDecimal amount;
|
||||
}
|
||||
27
src/main/java/com/hypernode/ledger/DataContract.java
Normal file
27
src/main/java/com/hypernode/ledger/DataContract.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package com.hypernode.ledger;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
public class DataContract {
|
||||
|
||||
int id;
|
||||
int version;
|
||||
List<ValidatorNode> validatorNodeList;
|
||||
List<Currency> currencyList;
|
||||
List<MessageElement> paymentList;
|
||||
List<Currency> currencyMintProposal;
|
||||
String publicKeySender;
|
||||
String signature;
|
||||
|
||||
Instant received;
|
||||
|
||||
public void mergeDataContract(DataContract _newContract)
|
||||
{
|
||||
//find differences in validatornodelist
|
||||
|
||||
//validate currencyList
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
13
src/main/java/com/hypernode/ledger/LedgerApplication.java
Normal file
13
src/main/java/com/hypernode/ledger/LedgerApplication.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package com.hypernode.ledger;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class LedgerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(LedgerApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
5
src/main/java/com/hypernode/ledger/LedgerParameters.java
Normal file
5
src/main/java/com/hypernode/ledger/LedgerParameters.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package com.hypernode.ledger;
|
||||
|
||||
public class LedgerParameters {
|
||||
//int groupSize;
|
||||
}
|
||||
8
src/main/java/com/hypernode/ledger/MessageElement.java
Normal file
8
src/main/java/com/hypernode/ledger/MessageElement.java
Normal file
@@ -0,0 +1,8 @@
|
||||
package com.hypernode.ledger;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MessageElement {
|
||||
Payment payment;
|
||||
List<ValidationSignature> validationSignatures;
|
||||
}
|
||||
24
src/main/java/com/hypernode/ledger/Payment.java
Normal file
24
src/main/java/com/hypernode/ledger/Payment.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package com.hypernode.ledger;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class Payment {
|
||||
public static final String COLLECTION_NAME = "Payment";
|
||||
|
||||
String publicKeyFrom;//public key
|
||||
String publicKeyTo;//public key
|
||||
String paymentComment;//comment of the transaction
|
||||
BigDecimal amount;//value of the exchanged currency
|
||||
String signature;//digital signature to validate the emission from the PublicKeyFrom
|
||||
|
||||
public String getSignableMessage()
|
||||
{
|
||||
return this.publicKeyFrom
|
||||
+ this.amount + this.publicKeyTo +this.paymentComment;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.hypernode.ledger;
|
||||
|
||||
public class ValidationSignature {
|
||||
}
|
||||
25
src/main/java/com/hypernode/ledger/ValidatorNode.java
Normal file
25
src/main/java/com/hypernode/ledger/ValidatorNode.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package com.hypernode.ledger;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class ValidatorNode {
|
||||
public static final String COLLECTION_NAME = "ValidatorNode";
|
||||
int id;
|
||||
String Name;
|
||||
String address;//ipv6 like address, first 2 numbers determine your layer1, then layer2, and finally your position on layer3
|
||||
String publicKey;
|
||||
String representedBy;
|
||||
|
||||
public static ValidatorNode initialize()
|
||||
{
|
||||
ValidatorNode validatorNode = new ValidatorNode();
|
||||
return validatorNode;
|
||||
}
|
||||
|
||||
}
|
||||
290
src/main/java/com/hypernode/ledger/WebServiceMethods.java
Normal file
290
src/main/java/com/hypernode/ledger/WebServiceMethods.java
Normal file
@@ -0,0 +1,290 @@
|
||||
package com.hypernode.ledger;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
/***
|
||||
* How to use this software
|
||||
*
|
||||
* This program aims to create a distributed ledger to illustrate the Hypernode validation algorithm.
|
||||
* This ledger will keep track of Currency objects, which are the equivalent of digital bank notes.
|
||||
* Either you or your wallet program, by keeping track of the private keys which correspond to
|
||||
* the currency objects under your control, can assign them to its new public key (spend them).
|
||||
* The recipient will be able to spend that same bank note at a later date because by writing
|
||||
* the transaction on the ledger the old public key will be replaced with his own new public key.
|
||||
*
|
||||
*
|
||||
* How to host a node
|
||||
*
|
||||
* This class contains all the logic required to keep the distributed ledger running.
|
||||
* The program works like this:
|
||||
*
|
||||
* 0 - Configurations
|
||||
* 0a - GroupSize
|
||||
* The variable groupSize is used in the code to determine how many connections will be required
|
||||
* to be performed by this server for every group.
|
||||
* It will also determine the maximum number of validators as (groupSize^groupSize)
|
||||
* and the amount required to be staked as totalCurrency / (groupSize^groupSize)
|
||||
*
|
||||
* 1 - Initializing
|
||||
* Whenever you launch this server program
|
||||
* you can connect to one of the nodes you trust
|
||||
* from any compatible ledger,
|
||||
* or you can create your own ledger.
|
||||
* 1.a - Connect to an existing ledger:
|
||||
* Please call ConnectToExistingLedger to connect to the target node
|
||||
* It will require specifying an IP address/web address of the target ledger.
|
||||
* You could instantiate multiple instances of WebServiceMethod and add a ledgerName if you wanted to
|
||||
* 1.b - Create a new ledger:
|
||||
* Call the method CreateNewLedger, specifying the parameters in the origin DataContract.
|
||||
* You will then be able to connect to this server from another instance of this program as described in 1.a
|
||||
* 1.c - Register as a validator
|
||||
* To balance the need of accountability with the need for decentralization and the need for performance
|
||||
* this decentralized ledger uses ProofOfStake in combination with the Hypernode validation algorithm.
|
||||
* Every server who wants to be a validator must stake at least
|
||||
* totalCurrency / ((ledgerparameter.groupSize)^ledgerparameter.groupSize)
|
||||
* which means that the public key of the server must correspond to a public key in the ledger
|
||||
* for currency element worth at least that amount
|
||||
*
|
||||
* 2 - Wallet Operation
|
||||
* Once the network is initialized it is possible to register transactions
|
||||
* 2a - Managing private keys
|
||||
* Every Currency object has a corresponding private key that will allow its spending
|
||||
* Therefore the wallet will need to maintain a reference map between those items (Currencu,PrivateKey)
|
||||
* 2b - Initiating a transaction
|
||||
* To assign a new Public Key to a currency you control, call the method walletSpendCurrency()
|
||||
* This should be done in the wallet, and the result should be communicated to a server
|
||||
* by calling the method notifySpendCurrency().
|
||||
*
|
||||
* 3 - Server operation
|
||||
* 3a - Initialization completed
|
||||
* The context of registering the transactions is divided into blocks.
|
||||
* Every validator will be assigned an ID when they connect to the network.
|
||||
* This id will be an array of integers of size groupSize
|
||||
* It will also get a list of all the IP address of the other servers and their public key.
|
||||
* 3b - Processing transaction
|
||||
* After receiving calls on notifySpendCurrency() your first step will be to verify
|
||||
* the authenticity of the signature on those transactions, and eventually block them
|
||||
* Those who pass the signature verification and that you also see as available to process in the blockchain
|
||||
* get grouped into a transaction list and signed with your own digital signature
|
||||
* At this point the server, starting from his ID, will identify all the servers
|
||||
* whose ID array only differs by one element (i.e. in a 4 groupSize configuration the server id might be x.y.z.t
|
||||
* and it would send messages to [0-4].y.z.t, x.[0-4].z.t, x.y.[0-4].t, x.y.z.[0-4])
|
||||
* and send them his own transaction list.
|
||||
* Once he sent his transaction list, the server will wait for 30 seconds to receive the transactions list from
|
||||
* all the servers he contacted earlier (which will be groupSize^2 connections).
|
||||
* This server will add up every group's transaction, based on their subgroup, and validate plus resend that to
|
||||
* all of the contacted servers. You should now have groupSize lists,
|
||||
* which contain every transaction that originated from a specific subgroup, and they are all different except for
|
||||
* the transactions you submitted.
|
||||
* Now it's time to combine all of those transactions into one unique transactionlist, sign it and send it to
|
||||
* the servers you are in contact with.
|
||||
* You should receive the same list back from your nodes, and that would validate that the frame has been successfully processed
|
||||
* In case it is coherent you can recalculate your id and proceed into the next frame
|
||||
* If it is not coherent you can take the id of the servers which do not match the majority, and use that information
|
||||
* to ping the other servers in that same group ([0-4].y.z.t, x.[0-4].z.t, x.y.[0-4].t, x.y.z.[0-4])
|
||||
* and exchange the full list. If yours and theirs match you just found the imposter. The validators will all spread
|
||||
* the news to their circle, making them lose their staking reward
|
||||
*
|
||||
*
|
||||
* 4 - Special operations
|
||||
* A Special Operations object can signal willingness to change a parameter.
|
||||
* If more than half of the nodes agree then you can change the groupSize to improve efficiency
|
||||
* or emit new currency
|
||||
* 4b - new currency
|
||||
* every service can put out a separate List<Payment>, where the payment_from is null
|
||||
* and specify a public key for the payment_to.
|
||||
*
|
||||
*
|
||||
* 5 - Tips for a better experience
|
||||
* You really need at least 128 validators to call it decentralized
|
||||
* If you have less than 20 validators set the groupSize to 20, so it will be one single big group
|
||||
* This system scales better the more validators you have.
|
||||
* In some cases it might make more sense to set the groupSize to a higher number,
|
||||
* Maybe i should write a function to pick the best groupSize number based on the number of validators
|
||||
*
|
||||
*/
|
||||
public class WebServiceMethods {
|
||||
DataContract lastDataContract;
|
||||
DataContract myCurrentDataContract;
|
||||
List<DataContract> peerDataContracts;
|
||||
List<MessageElement> pendingPayments;
|
||||
ValidatorNode thisValidatorNode;
|
||||
List<WebServiceMethods> peers;
|
||||
String privateKey;
|
||||
int id;
|
||||
int groupSize;
|
||||
int groupInstances;
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
WebServiceMethods thisServer = new WebServiceMethods();
|
||||
thisServer.connectToExistingLedger("","");
|
||||
}
|
||||
|
||||
public void createNewLedger( ValidatorNode _self, String _privateKey, DataContract _startingData)
|
||||
{
|
||||
this.thisValidatorNode = _self;
|
||||
this.lastDataContract = _startingData;
|
||||
this.privateKey = _privateKey;
|
||||
}
|
||||
|
||||
public void connectToExistingLedger(String _ipaddress, String _privateKey)
|
||||
{
|
||||
WebServiceMethods thatServer = new WebServiceMethods();
|
||||
String authenticationString;
|
||||
|
||||
authenticationString = thatServer.authenticationRequest(WebServiceMethods.createPublicKey(_privateKey));
|
||||
this.lastDataContract = thatServer.authenticationResponse(WebServiceMethods.encodeMessage(authenticationString,_privateKey),WebServiceMethods.createPublicKey(_privateKey));
|
||||
//while validatornodelist.next if element.publicKey = this.createpublickey()
|
||||
this.thisValidatorNode = this.lastDataContract.validatorNodeList.getLast();
|
||||
|
||||
this.privateKey = _privateKey;
|
||||
|
||||
//you are now authenticated, at the next frame the Validator list will be updated
|
||||
//and at the next one you will be able to exchange messages
|
||||
//with the other servers.
|
||||
//the first frame you will listen and populate your startingLedger
|
||||
//and from the subsequent you will be able to send your own transactions
|
||||
}
|
||||
|
||||
public boolean meshExchangeData()
|
||||
{
|
||||
DataContract dataContract = new DataContract();
|
||||
WebServiceMethods webServiceMethods = new WebServiceMethods();
|
||||
//implements point 3b
|
||||
|
||||
//process the data sent to you in receiveData//done at receipt
|
||||
|
||||
//call receiveData on the records you need to call
|
||||
//for every datacontract in peerdatacontracts
|
||||
//evaluate if you need to wait at least 30 seconds to get a message
|
||||
if(dataContract.version < this.myCurrentDataContract.version
|
||||
&& Instant.now().minusSeconds(30).isBefore( dataContract.received ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//
|
||||
//foreach webServiceMethods peer in peers
|
||||
webServiceMethods.receiveData(this.thisValidatorNode.publicKey,this.myCurrentDataContract);
|
||||
//once you have exchanged exponent messages with all your peers and all message are good
|
||||
//you know that the frame is valid and everyone signed on it
|
||||
return true;
|
||||
}
|
||||
public static String encodeMessage(String message, String privateKey)
|
||||
{
|
||||
return "encodedMessage";
|
||||
}
|
||||
public static String decodeMessage(String _encryptedMessage, String _publicKey)
|
||||
{
|
||||
return "decodedMessage";
|
||||
}
|
||||
public static String createPublicKey(String _privateKey)
|
||||
{
|
||||
return "publicKey";
|
||||
}
|
||||
public static boolean verifySignature(String _message, String _publicKey, String _signature)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private void setGroupParameters(int id)
|
||||
{
|
||||
Integer exponent = 1;
|
||||
Integer base;
|
||||
Integer groupValue;
|
||||
Integer divisionValue;
|
||||
Integer divisionReminder;
|
||||
while (Math.pow(exponent,exponent) < id )
|
||||
{
|
||||
if(exponent >20)
|
||||
{
|
||||
throw new Error("we got lost");
|
||||
}
|
||||
exponent += 1;
|
||||
}
|
||||
exponent -= 1;
|
||||
base = exponent;
|
||||
while (Math.pow(base,exponent) <id )
|
||||
{
|
||||
base += 1;
|
||||
}
|
||||
base -= 1;
|
||||
if(Math.pow(base,exponent) > Math.pow(exponent+1,exponent+1))
|
||||
{
|
||||
base = exponent + 1;
|
||||
exponent = base;
|
||||
}
|
||||
|
||||
|
||||
this.groupSize = base;
|
||||
this.groupInstances = exponent;
|
||||
divisionValue = id;
|
||||
while(divisionValue > 0)
|
||||
{
|
||||
divisionReminder = divisionValue - (Math.floorDiv(divisionValue,this.groupSize) * this.groupSize);
|
||||
divisionValue = Math.floorDiv(divisionValue,this.groupSize);
|
||||
//pop divisionReminder in the array
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//exposed web service methods
|
||||
public String authenticationRequest(String _publicKey)
|
||||
{
|
||||
//the caller asks for a message to sign and then gives it back signed.
|
||||
//He will need to use a public key of a currency object he controls,
|
||||
// which will then be used for staking
|
||||
return "";
|
||||
}
|
||||
public DataContract authenticationResponse(String _publicKey, String signedMessage)
|
||||
{
|
||||
//to redo, i need to announce the new connection and assign its address
|
||||
ValidatorNode validatorNode = new ValidatorNode();
|
||||
//should probably order the validatornode by id first, and by publickey second
|
||||
//and assign the new id in order, patching up the holes done by servers disconnecting
|
||||
//once you do get this you can start to meshExchangeData
|
||||
this.lastDataContract.validatorNodeList.add(validatorNode);
|
||||
|
||||
return this.lastDataContract;
|
||||
}
|
||||
public void notifySpendCurrency(List<Payment> _requestedPayments)
|
||||
{
|
||||
Payment payment = new Payment();
|
||||
MessageElement messageElement = new MessageElement();
|
||||
//while looping requestedPayments
|
||||
payment = new Payment();
|
||||
//validate single payment
|
||||
if(WebServiceMethods.verifySignature(payment.getSignableMessage(),payment.publicKeyFrom, payment.signature))
|
||||
//if validation fails blacklist a specific ip for 1h(maybe?)
|
||||
{
|
||||
throw new Error("invalid payment");
|
||||
}
|
||||
//if all ok add it to the list of validated transactions to be pushed
|
||||
else
|
||||
{
|
||||
messageElement.payment = payment;
|
||||
}
|
||||
this.pendingPayments.add(messageElement);//find the singleton
|
||||
}
|
||||
public void receiveData(String _sender, DataContract _dataContract)
|
||||
{
|
||||
//listiterator on your pendingdatacontracts
|
||||
ValidatorNode validatorNode = new ValidatorNode();
|
||||
if (validatorNode.address.equals(_sender)) {
|
||||
//someone gave you data, you have to process it and see if it is still good
|
||||
|
||||
this.myCurrentDataContract.mergeDataContract(_dataContract);
|
||||
|
||||
//remove old temporary datacontract and replace it with the newest iteration for that source
|
||||
this.peerDataContracts.remove(1);
|
||||
this.peerDataContracts.add(_dataContract);
|
||||
//return
|
||||
this.meshExchangeData();
|
||||
} else {
|
||||
//you can reduce the spamming maybe?
|
||||
throw new Error("Unauthorized");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
1
src/main/resources/application.properties
Normal file
1
src/main/resources/application.properties
Normal file
@@ -0,0 +1 @@
|
||||
spring.application.name=ledger
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.hypernode.ledger;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class LedgerApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user