Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Merge pull request #197 from HelixNetwork/dev
Browse files Browse the repository at this point in the history
1.0.1
  • Loading branch information
oracle58 authored Oct 3, 2019
2 parents ca79d90 + 85fe707 commit 27ff9a8
Show file tree
Hide file tree
Showing 16 changed files with 242 additions and 16 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ effective.pom
.project
.settings/
enforcer.pom

out
# db
db
mainnet.log
Expand Down Expand Up @@ -63,4 +63,4 @@ modules/*
*.pem

# os
.DS_Store
.DS_Store
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.0.1
- Added dev instrumentation
- Added hardware specs

## 1.0.0
- Added new implementation of `TransactionTestUtils.buildTransaction()`
- Added test for DAGHelper
Expand Down
28 changes: 25 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,33 @@
# Pendulum

Pendulum is a quorum based [Tangle](https://github.com/iotaledger/iri/) implementation designed towards reliable timekeeping and high-throughput messaging.
- **Latest release:** 1.0.0 release
- **Latest release:** 1.0.1 release
- **License:** GPLv3

Special thanks to all of the [IOTA Contributors](https://github.com/iotaledger/iri/graphs/contributors)!

## Hardware requirements

**Minimal** (~t2.small AWS instance)
- 2GB RAM
- 1 GHz CPU
- 10 GB storage
- 10Mbit/s WAN, static IP

**Optimal** (~t2.medium AWS instance)
- 4GB RAM or more
- 2 or more 2GHz CPU cores (~ t2.medium AWS instance)
- 50GB SSD
- 1Gbit/s WAN, static IP

**Enterprise-grade**
- Four or more instances with Optimal specs
- two or more instances with `--remote` API enabled
- two or more "relayer" instances connected to multiple peers
- For validators: additional dedicated instance with Optimal specification for the validator node
- HA loadbalancer proxing API instances. Can be hardware or software based (e.g. [Nginx cluster sample config](#nginx-cluster-sample-config) below)


## Developers

- Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.
Expand All @@ -36,9 +58,9 @@ Build an executable jar at the `target` directory using maven.

### Launch Validator node
Launching a node as a validator first requires to generate a 64 character hex string, that is used as a seed for key generation. You will find the public key in the last line of the `validator.key` file contained in the resources directory. If you wish to act as a validator, please send a request to [email protected] containing your public key.

java -jar target/pendulum-<VERSION>.jar -p 8085 --validator <pathToValidatorSeed>


### Nginx cluster sample config

Expand Down
74 changes: 74 additions & 0 deletions docker/docker-compose-cluster.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
version: "3.1"

networks:
helix_network:

secrets:
seed:
file: ./backend/seed.txt

services:
relayer:
container_name: relayer_stmpe_ml
image: dzlzv/pendulum:0.6.9
hostname: relayer
restart: on-failure
volumes:
- /docker-volumes/relayer/data:/pendulum/data
- ./relayer/hlx-0.1.0.ini:/pendulum/conf/conf.ini:ro
environment:
- DOCKER_PLM_REMOTE_LIMIT_API="interruptAttachToTangle"
- JAVA_MAX_MEMORY=1500m
- JAVA_MIN_MEMORY=256m
- DOCKER_PLM_LOGGING_LEVEL=debug
ports:
- "6550:6550"
expose:
- "4100"
- "8085"
command: ["-p","8085","-n", "udp://backend:4100 udp://relayer1.helixmain.net:4100 udp://nginx:4100"]
networks:
helix_network:

backend:
container_name: backend_stmpe_ml
image: dzlzv/pendulum:0.6.9
hostname: backend
restart: on-failure
volumes:
- /docker-volumes/backend/data:/pendulum/data
- ./backend/seed.txt:/pendulum/conf/seed.txt:ro
- ./backend/hlx-0.1.0.ini:/pendulum/conf/conf.ini:ro
environment:
- DOCKER_PLM_REMOTE_LIMIT_API="interruptAttachToTangle"
- JAVA_MAX_MEMORY=1024m
- JAVA_MIN_MEMORY=256m
- DOCKER_PLM_LOGGING_LEVEL=debug
ports:
- "6551:6550"
expose:
- "4100"
- "8085"
secrets:
- seed
command: ["-p","8085","-n", "udp://relayer:4100"]
networks:
helix_network:

nginx:
container_name: 'production-nginx'
image: nginx:1.17.3
restart: on-failure
ports:
- "4100:4100/udp"
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./production.conf:/etc/nginx/conf.d/default.conf
- ./dh-param/dhparam-2048.pem:/etc/ssl/certs/dhparam-2048.pem
- /docker-volumes/etc/letsencrypt/live/stmpe.ml/fullchain.pem:/etc/ssl/certs/fullchain.pem
- /docker-volumes/etc/letsencrypt/live/stmpe.ml/privkey.pem:/etc/ssl/certs/privkey.pem
- /docker-volumes/data/letsencrypt:/data/letsencrypt
networks:
helix_network:
19 changes: 19 additions & 0 deletions docker/ssl/nginx-image/nginx-udp.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
events { worker_connections 4096; }

stream {

## uncomment for reverse-proxying to multiple relayers
# upstream pendulum_udp {
# server relayer1:4100;
# server relayer2:4100;
# }

server {
listen 4100 udp;
proxy_pass relayer:4100;
}
}

http {
include /etc/nginx/conf.d/*.conf;
}
77 changes: 77 additions & 0 deletions docker/ssl/nginx-image/pendulum-cluster.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
upstream pendulum {
ip_hash;
server relayer:8085 max_fails=3 fail_timeout=30s;
server backend:8085;
}

server {
listen 80;
server_name ### your.server.name ###;

## Uncomment if let's encrypt free certificate is used
#location ~ /.well-known/acme-challenge {
# allow all;
# root /data/letsencrypt;
#}

location / {
rewrite ^ https://$host$request_uri? permanent;
}
}

server {
listen 443 ssl;
listen [::]:443 ssl;
server_name ### your.server.name ###;

server_tokens off;

## put your ssl certs there
ssl_certificate /etc/ssl/certs/fullchain.pem;
ssl_certificate_key /etc/ssl/certs/privkey.pem;

ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
ssl_prefer_server_ciphers on;

ssl_ecdh_curve secp384r1;
ssl_session_tickets off;

# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8;

ssl_session_cache shared:SSL:10m;
ssl_buffer_size 8k;

# It's recommended to generate dhparam-2048.pem
#ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;

location / {
proxy_hide_header Access-Control-Allow-Origin;
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-HELIX-API-Version,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';

if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-HELIX-API-Version,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}

proxy_redirect off;
proxy_set_header host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-forward-for $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://pendulum;
}
}
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<groupId>net.pendulum</groupId>
<artifactId>pendulum</artifactId>

<version>1.0.0</version>
<version>1.0.1</version>

<name>Pendulum</name>
<description>Pendulum Protocol</description>
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/net/helix/pendulum/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public class Main {

public static final String MAINNET_NAME = "Pendulum";
public static final String TESTNET_NAME = "Pendulum Testnet";
public static final String VERSION = "1.0.0";
public static final String VERSION = "1.0.1";

/**
* The entry point of Pendulum.
Expand Down
1 change: 1 addition & 0 deletions src/main/java/net/helix/pendulum/TransactionValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ public void runValidation(TransactionViewModel transactionViewModel, final int m
transactionViewModel.setMetadata();
transactionViewModel.setAttachmentData();
if(hasInvalidTimestamp(transactionViewModel)) {
log.debug("Invalid timestamp for txHash/addressHash: {} {}", transactionViewModel.getHash().toString(), transactionViewModel.getAddressHash().toString());
throw new StaleTimestampException("Invalid transaction timestamp.");
}
for (int i = VALUE_OFFSET + VALUE_USABLE_SIZE; i < VALUE_OFFSET + VALUE_SIZE; i++) { // todo always false.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
import net.helix.pendulum.service.snapshot.SnapshotProvider;
import net.helix.pendulum.service.snapshot.SnapshotService;
import net.helix.pendulum.service.snapshot.impl.SnapshotStateDiffImpl;
import net.helix.pendulum.service.spentaddresses.impl.SpentAddressesServiceImpl;
import net.helix.pendulum.storage.Tangle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

Expand All @@ -23,6 +26,7 @@
* This class is stateless and does not hold any domain specific models.<br />
*/
public class LedgerServiceImpl implements LedgerService {
private static final Logger log = LoggerFactory.getLogger(LedgerServiceImpl.class);
/**
* Holds the tangle object which acts as a database interface.<br />
*/
Expand Down Expand Up @@ -101,8 +105,8 @@ public boolean applyRoundToLedger(RoundViewModel round) throws LedgerException {
if(generateStateDiff(round)) {
try {
snapshotService.replayMilestones(snapshotProvider.getLatestSnapshot(), round.index());
//System.out.println("Snapshot");
//snapshotProvider.getLatestSnapshot().getBalances().forEach((address, balance) -> System.out.println("Address: " + address.toString() + ", " + balance));
log.debug("Replayed milestones +1");
//snapshotProvider.getLatestSnapshot().getBalances().forEach((address, balance) -> log.debug(("Address: " + address.toString() + ", " + balance)));
} catch (SnapshotException e) {
throw new LedgerException("failed to apply the balance changes to the ledger state", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ public void trackLatestSolidMilestones() throws MilestoneException {
}
}
if (isRoundSolid(nextRound)) {
// TODO: Ask Oliver about these classes?
//syncValidatorTracker();
//syncLatestMilestoneTracker(nextRound.index());
applyRoundToLedger(nextRound);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,18 @@ void monitorThread(MilestoneTracker milestoneTracker) {
snapshotProvider.getLatestSnapshot().getIndex() == milestoneTracker.getCurrentRoundIndex()
? config.getLocalSnapshotsIntervalSynced()
: config.getLocalSnapshotsIntervalUnsynced();

log.debug("monitorThread.localSnapshotInterval = {}", localSnapshotInterval);
log.debug("milestoneTracker.getCurrentRoundIndex() = {}", milestoneTracker.getCurrentRoundIndex());
log.debug("getLatestSnapshot().getIndex() = {}", snapshotProvider.getLatestSnapshot().getIndex());
log.debug("Sync check = {}", milestoneTracker.getCurrentRoundIndex() - snapshotProvider.getLatestSnapshot().getIndex());
int latestSnapshotIndex = snapshotProvider.getLatestSnapshot().getIndex();
int initialSnapshotIndex = snapshotProvider.getInitialSnapshot().getIndex();
log.debug("Taking local snapshot in ... {}",
(config.getLocalSnapshotsDepth() + localSnapshotInterval) - (latestSnapshotIndex - initialSnapshotIndex));

if (latestSnapshotIndex - initialSnapshotIndex > config.getLocalSnapshotsDepth() + localSnapshotInterval) {
try {
log.debug("Taking a local snapshot.");
snapshotService.takeLocalSnapshot(milestoneTracker, transactionPruner);
} catch (SnapshotException e) {
log.error("error while taking local snapshot", e);
Expand All @@ -152,9 +158,8 @@ void monitorThread(MilestoneTracker milestoneTracker) {
}

/**
* A snapshot is taken in an interval.
* A snapshot is taken in an interval.
* This interval changes based on the state of the node.
*
* @param inSync if this node is in sync
* @return the current interval in which we take local snapshots
*/
Expand All @@ -169,10 +174,8 @@ protected int getSnapshotInterval(boolean inSync) {
* A node is defined in sync when the latest snapshot milestone index and the
* latest milestone index are equal. In order to prevent a bounce between in and
* out of sync, a buffer is added when a node became in sync.
*
* This will always return false if we are not done scanning milestone
* candidates during initialization.
*
* @param milestoneTracker tracker we use to determine milestones
* @return <code>true</code> if we are in sync, otherwise <code>false</code>
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import net.helix.pendulum.model.Hash;
import net.helix.pendulum.service.snapshot.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashSet;
import java.util.Map;
Expand All @@ -14,6 +16,9 @@
* Implements the basic contract of the {@link Snapshot} interface.
*/
public class SnapshotImpl implements Snapshot {

private static final Logger log = LoggerFactory.getLogger(SnapshotServiceImpl.class);

/**
* Holds a reference to the state of this snapshot.
*/
Expand Down Expand Up @@ -554,6 +559,7 @@ public void applyStateDiff(SnapshotStateDiff diff) throws SnapshotException {

try {
state.applyStateDiff(diff);
log.debug("Applied the state diff to the current balances to examine consistency +1");
} finally {
unlockWrite();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,12 @@ public Snapshot getLatestSnapshot() {
*/
@Override
public void writeSnapshotToDisk(Snapshot snapshot, String basePath) throws SnapshotException {
// this here might be causing the pid error issues.
// the snapshot gets locked. And then, no one can get from it.
snapshot.lockRead();
try {
log.debug("The snapshot hash = {}", snapshot.getHash().toString());

String fileSeperator = System.getProperty("file.separator");
// state and meta files
String snapshotStateFilePath = String.join(fileSeperator, basePath, "snapshot.state");
Expand Down
Loading

0 comments on commit 27ff9a8

Please sign in to comment.