Skip to content

Commit

Permalink
Refactor to improve testability and isolation
Browse files Browse the repository at this point in the history
- Enhance functional core by module splits (focus on data transformation) and simplier and much more tests
- Leverage contexts for a better single responsability principle
- Use field projection to improve database queries and data loading during the startup to fill memory tables
- Improve ETS tables for faster queries in memory
- Define Governance Pools
- Use Docker for Code Proposal Integration to bring isolation and security
  • Loading branch information
Samuel Manzanera committed Nov 5, 2020
1 parent 7289242 commit c156aa0
Show file tree
Hide file tree
Showing 375 changed files with 22,210 additions and 14,951 deletions.
5 changes: 4 additions & 1 deletion .credo.exs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@
{Credo.Check.Readability.TrailingWhiteSpace, []},
{Credo.Check.Readability.UnnecessaryAliasExpansion, []},
{Credo.Check.Readability.VariableNames, []},
{Credo.Check.Refactor.MapInto, false},
{Credo.Check.Readability.BlockPipe, []},
{Credo.Check.Readability.ImplTrue, []},
{Credo.Check.Readability.SeparateAliasRequire, []},

# Refactoring Opportunities
{Credo.Check.Refactor.CondStatements, []},
Expand All @@ -62,6 +64,7 @@
{Credo.Check.Refactor.Nesting, []},
{Credo.Check.Refactor.UnlessWithElse, []},
{Credo.Check.Refactor.WithClauses, []},
{Credo.Check.Refactor.MapInto, false},

# Warnings
{Credo.Check.Warning.BoolOperationOnSameValues, []},
Expand Down
24 changes: 22 additions & 2 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,31 @@ erl_crash.dump
**/doc
.

/rel/artifacts

.DS_Store

/priv/crypto/c_dist
/priv/crypto/storage_nonce
/priv/storage
/priv/last_sync
/priv/p2p/last_sync
/priv/p2p/last_sync/*
/priv/p2p/test_seeds
/priv/proposal_logs/

# Since we are building assets from assets/,
# we ignore priv/static. You may want to comment
# this depending on your deployment strategy.
/priv/static/*

/assets/node_modules/*
# Self signed cert are used for local and dev purposes
/priv/cert


/assets/node_modules

log_*

/.idea/
uniris-node.iml
projectFilesBackup
12 changes: 9 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ erl_crash.dump
/priv/crypto/c_dist
/priv/crypto/storage_nonce
/priv/storage
/priv/p2p/last_sync
/priv/p2p/last_sync/*
/priv/p2p/last_sync*
/priv/p2p/test_seeds
/priv/proposal_logs/
/priv/uniris_node.zip

# Since we are building assets from assets/,
# we ignore priv/static. You may want to comment
Expand All @@ -30,6 +31,11 @@ erl_crash.dump
# Self signed cert are used for local and dev purposes
/priv/cert


/assets/node_modules

log_*
log_*

/.idea/
uniris-node.iml
projectFilesBackup
15 changes: 15 additions & 0 deletions .iex.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
IEx.configure(inspect: [limit: :infinity])

alias Uniris.Crypto
alias Uniris.DB
alias Uniris.P2P
alias Uniris.P2P.Node
alias Uniris.SharedSecrets
alias Uniris.Account
alias Uniris.Election
alias Uniris.Governance
alias Uniris.Contracts
alias Uniris.TransactionChain
alias Uniris.TransactionChain.Transaction
alias Uniris.TransactionChain.TransactionData
alias Uniris.BeaconChain
42 changes: 35 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,17 +1,45 @@
FROM bitwalker/alpine-elixir:latest

RUN apk add --no-cache --update openssl wget build-base git npm python3
# Install system requirements
RUN apk add --no-cache --update
openssl \
build-base \
gcc \
git \
npm \
python3 \
wget

# Install Libsodium
RUN wget https://download.libsodium.org/libsodium/releases/LATEST.tar.gz && \
mkdir /opt/libsodium && tar zxvf LATEST.tar.gz -C /opt/libsodium && \
cd /opt/libsodium/libsodium-stable && ./configure && \
make && make install
mkdir /opt/libsodium && \
tar zxvf LATEST.tar.gz -C /opt/libsodium && \
cd /opt/libsodium/libsodium-stable && \
./configure && \
make && \
make install

WORKDIR /opt/app

ENV MIX_ENV prod

COPY . .

# Will install the application at /opt/build
RUN ./release.sh
# Install dependencies
# Cache Elixir deps
RUN mix deps.get --only prod
RUN mix deps.compile

WORKDIR /opt/app/assets

# Cache Node deps
RUN npm install

# Compile JavaScript
RUN npm run deploy

WORKDIR /opt/app

CMD ["/bin/bash"]
# Prepare the image
RUN mix compile
RUN mix phx.digest
21 changes: 11 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ Welcome to the Uniris Node source repository ! This software enables you to buil

Uniris features:
- Fast transaction processing (> 1M tps)
- Lower energy consomption than other blockchain
- Lower energy consumption than other blockchain
- Designed with a high level of security (ARCH consensus supporting 90% of maliciousness)
- Adapative cryptographic algorithms (quantum resistant)
- Adaptive cryptographic algorithms (quantum resistant)
- Decentralized Identity and Self Sovereign Identity
- Smart contract platform powered by a built-in interpreter
- Strong scalability with geo secured sharding
Expand All @@ -17,17 +17,17 @@ Uniris features:
Our codebase aims to reach the guidelines of Elixir projects.
We are focusing on the best quality.

The source code can be brough to change to respect the best quality of reading and regarding best practices.
The source code can change to respect the best quality of reading and regarding best practices.

Current implemented features:
- Adapative cryptography: different elliptic curves and software implementation
- TransactionChain: basic struct and transaction generation
- Smart Contract: interpreter coded with Elixir DSL through Metaprogramming and AST
- Node election: heurisitic validation and storage node selection
- Adaptive cryptography: different elliptic curves and software implementation
- TransactionChain: Transaction structure and transaction generation
- Smart Contract: interpreter coded with Elixir DSL through Meta-programming and AST
- Node election: heuristic validation and storage node selection
- P2P: Inter-node communication, supervised connection to detect the P2P view of nodes in almost real-time
- Transaction mining: ARCH consensus
- Node bootstraping
- Beacon chain: Track new transactions and node readyness
- Node bootstrapping
- Beacon chain: Track new transactions and node readiness
- Self-Repair: Self-healing mechanism allowing to resynchronize missing transactions
- Node shared secrets renewal: Integration of authorized validation nodes using heuristic constraints
- P2P transfers and genesis pools allocation
Expand All @@ -45,7 +45,8 @@ Current implemented features:

Requirements:
- Libsodium: for the ed25519 encryption and decryption.
- OTP 23: generation of ed25519 keypair
- OpenSSL 1.11
- OTP 23: generation of ed25519 key pairs

Platforms supported:
- Linux
Expand Down
10 changes: 9 additions & 1 deletion assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ Hooks.Diff = {
}
}

Hooks.Logs = {
mounted() {
this.el.scrollTop = this.el.scrollHeight;
}
}

let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content");
let liveSocket = new LiveSocket("/live", Socket, {hooks: Hooks, params: {_csrf_token: csrfToken}});

Expand Down Expand Up @@ -133,4 +139,6 @@ window.sendApprovalTransaction = function()  {
closeApprovalConfirmation()
})
.catch(console.error)
}
}


46 changes: 25 additions & 21 deletions config/config.exs
Original file line number Diff line number Diff line change
@@ -1,18 +1,5 @@
use Mix.Config

# Configures Elixir's Logger
config :logger, :console,
format: "$date $time $metadata[$level] $message\n",
metadata: [:request_id, :proposal_address]

config :logger,
utc_log: true,
handle_otp_reports: true,
handle_sasl_reports: false

# Use Jason for JSON parsing in Phoenix
config :phoenix, :json_library, Jason

config :git_hooks,
auto_install: true,
verbose: true,
Expand All @@ -28,6 +15,19 @@ config :git_hooks,
]
]

# Configures Elixir's Logger
config :logger, :console,
format: "$date $time $metadata[$level] $message\n",
metadata: [:request_id, :proposal_address, :transaction, :beacon_subset, :node]

config :logger,
utc_log: true,
handle_otp_reports: true,
handle_sasl_reports: false

# Use Jason for JSON parsing in Phoenix
config :phoenix, :json_library, Jason

config :uniris, :src_dir, File.cwd!()

config :uniris, Uniris.Crypto,
Expand All @@ -44,16 +44,20 @@ config :uniris, Uniris.Crypto,
:blake2b
],
default_curve: :ed25519,
default_hash: :sha256
default_hash: :sha256,
storage_nonce_file: "priv/crypto/storage_nonce"

config :uniris, Uniris.Crypto.SoftwareKeystore, seed: System.fetch_env!("UNIRIS_CRYPTO_SEED")
config :uniris, Uniris.Bootstrap.NetworkInit,
genesis_seed:
<<226, 4, 212, 129, 254, 162, 178, 168, 206, 139, 176, 91, 179, 29, 83, 20, 50, 98, 0, 25,
133, 242, 197, 73, 199, 53, 46, 127, 7, 223, 45, 246>>

config :uniris, Uniris.P2P.Endpoint,
port: System.get_env("UNIRIS_P2P_PORT", "3002") |> String.to_integer()

config :uniris, Uniris.P2P, node_client: Uniris.P2P.TCPClient
config :uniris, Uniris.P2P.BootstrappingSeeds, file: "priv/p2p/seeds"

config :uniris, Uniris.P2P.BootstrapingSeeds, file: "priv/p2p/seeds"
config :uniris, Uniris.P2P.Endpoint,
port: System.get_env("UNIRIS_P2P_PORT", "3002") |> String.to_integer(),
nb_acceptors: 10,
transport: :tcp

# Configure the endpoint
config :uniris, UnirisWeb.Endpoint,
Expand All @@ -65,6 +69,6 @@ config :uniris, UnirisWeb.Endpoint,
layout: {UnirisWeb.LayoutView, "live.html"}
]

# Import environment specific config. This must remain at the bottmo
# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.
import_config "#{Mix.env()}.exs"
56 changes: 33 additions & 23 deletions config/dev.exs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use Mix.Config

config :logger,
backends: [:console, {LoggerFileBackend, :file_log}]

config :logger, :file_log, path: "log_#{System.get_env("UNIRIS_CRYPTO_SEED")}"
# config :logger, handle_sasl_reports: true

# Set a higher stacktrace during development. Avoid configuring such
# in production as building large stacktraces may be expensive.
Expand All @@ -12,16 +9,15 @@ config :phoenix, :stacktrace_depth, 20
# Initialize plugs at runtime for faster development compilation
config :phoenix, :plug_init_mode, :runtime

config :uniris, Uniris.Crypto.Keystore, impl: Uniris.Crypto.SoftwareKeystore

config :uniris, Uniris.Storage.Backend, impl: Uniris.Storage.CassandraBackend

config :uniris, Uniris.Storage.KeyValueBackend,
root_dir: "priv/storage/#{System.get_env("UNIRIS_CRYPTO_SEED", "node1")}"
config :uniris, Uniris.BeaconChain.SlotTimer,
interval: "0 * * * * * *",
# Trigger it 5 seconds before
trigger_offset: 5

config :uniris, Uniris.Bootstrap, ip_lookup_provider: Uniris.Bootstrap.IPLookup.EnvImpl
config :uniris, Uniris.Bootstrap.Sync, out_of_sync_date_threshold: 60

config :uniris, Uniris.P2P.BootstrapingSeeds,
config :uniris, Uniris.P2P.BootstrappingSeeds,
# First node crypto seed is "node1"
seeds:
System.get_env(
Expand Down Expand Up @@ -61,24 +57,33 @@ config :uniris, Uniris.Bootstrap.NetworkInit,
]
]

config :uniris, Uniris.BeaconSlotTimer,
interval: "* * * * * *",
# Trigger it 5 seconds before
trigger_offset: 5
config :uniris, Uniris.Crypto.Keystore, impl: Uniris.Crypto.SoftwareKeystore

config :uniris, Uniris.SharedSecretsRenewal,
interval: "* * * * * *",
# Trigger it 20 seconds before
trigger_offset: 20
config :uniris, Uniris.Crypto.SoftwareKeystore,
seed: System.get_env("UNIRIS_CRYPTO_SEED", "node1")

config :uniris, Uniris.DB, impl: Uniris.DB.KeyValueImpl

config :uniris, Uniris.DB.KeyValueImpl,
root_dir: "priv/storage/#{System.get_env("UNIRIS_CRYPTO_SEED", "node1")}"

config :uniris, Uniris.Governance.Pools,
initial_members: [
technical_council: [{"00682FF302BFA84702A00D81D5F97610E02573C0487FBCD6D00A66CCBC0E0656E8", 1}],
ethical_council: ["00682FF302BFA84702A00D81D5F97610E02573C0487FBCD6D00A66CCBC0E0656E8"],
foundation: ["00682FF302BFA84702A00D81D5F97610E02573C0487FBCD6D00A66CCBC0E0656E8"],
uniris: ["00682FF302BFA84702A00D81D5F97610E02573C0487FBCD6D00A66CCBC0E0656E8"]
]

config :uniris, Uniris.SelfRepair.Scheduler, interval: "0 * * * * * *"

config :uniris, Uniris.SelfRepair,
last_sync_file: "priv/p2p/last_sync/#{System.get_env("UNIRIS_CRYPTO_SEED")}",
interval: "* * * * * *",
config :uniris, Uniris.SelfRepair.Sync,
last_sync_file: "priv/p2p/last_sync_#{System.get_env("UNIRIS_CRYPTO_SEED")}",
network_startup_date: %DateTime{
year: DateTime.utc_now().year,
month: DateTime.utc_now().month,
day: DateTime.utc_now().day,
hour: DateTime.utc_now().hour - 1,
hour: DateTime.add(DateTime.utc_now(), -3600).hour,
minute: 0,
second: 0,
microsecond: {0, 0},
Expand All @@ -88,6 +93,11 @@ config :uniris, Uniris.SelfRepair,
zone_abbr: "UTC"
}

config :uniris, Uniris.SharedSecrets.NodeRenewalScheduler,
interval: "0 * * * * * *",
# Trigger it 20 seconds before
trigger_offset: 20

# For development, we disable any cache and enable
# debugging and code reloading.
#
Expand Down
Loading

0 comments on commit c156aa0

Please sign in to comment.