Giter VIP home page Giter VIP logo

elixir-node's Introduction

Travis Build

CURRENTLY NOT COMPATIBLE TO THE AETERNITY NETWORK

This implementation aims to be a aims to be a full node that complies with the aeternity specification, in the current state this is not ready yet and should never be used to join the aeternity network.

Aeternity Elixir Full Node

This is an elixir full node implementation of the aeternity specification.

Compatibility to the erlang aeternity implementation is documented in docs/aeternity-erlang-compatibility.md.

Getting started

Required packages

Elixir 1.6 with Erlang/OTP20 is the basis of the project

Rust is needed for persistent storage dependency

libsodium 1.0.16 is needed for elliptic curve support

sudo apt-get install autoconf autogen libtool libgmp3-dev lsof
wget -O libsodium-src.tar.gz https://github.com/jedisct1/libsodium/releases/download/1.0.16/libsodium-1.0.16.tar.gz
mkdir libsodium-src && tar -zxf libsodium-src.tar.gz -C libsodium-src --strip-components=1
cd libsodium-src && ./configure && make && make check && sudo make install && cd ..

Fetching dependencies

mix deps.get

Starting the application

Start the application in interactive Elixir

  • Development config: make iex-0
  • Production config: MIX_ENV=prod make iex-0

The default sync port is 3015, this can be adjusted using SYNC_PORT=some_port iex -S mix phx.server. The node will run an http api at localhost:4000, this can be adjusted using PORT=some_port iex -S mix phx.server.

Usage

Elixir interactive api-calls

  • Miner.resume() to start the miner

  • Miner.suspend() to stop the miner

  • Miner.mine_sync_block_to_chain() mine the next block

  • Chain.top_block() to get the top block of the current chain

  • Chain.top_block_chain_state() to get the top block chainstate

  • Chain.chain_state(block_hash) to get the chainstate of certain block

  • Pool.get_pool() to get all transactions from the pool

  • Peers.all_peers() to get all connected peers

  • Peers.try_connect(%{host: host, port: port, pubkey: pubkey}) to manually connect a new peer

  • Peers.get_info_try_connect(uri) to connect to another elixir node, providing a get connection info interface

Running the tests

Run the testsuite with mix test

Logging

Debug, error, warning and info logs is found in apps/aecore/logs

Docker Container

A Dockerfile and docker-compose.yml are found in the base directory, prebuilt images are not yet published.

  • Build container docker build . -t elixir-node

  • Run node in container docker run --name elixir-node -it -p 4000:4000 -p 3015:3015 elixir-node

  • Run multiple nodes network with docker compose docker-compose up runs 3 connected nodes, with 2 mining

Detailed Usage

docs/detailed-usage.md

Developer Documentation

docs/developer-docs.md

elixir-node's People

Contributors

0legiv avatar andonov avatar artur64 avatar cheezus1 avatar cytadela8 avatar d-velev avatar danielaivanova avatar gorbak25 avatar gspasov avatar hristohr avatar meivantodorov avatar nedelcho-delchev-tues avatar nikolaidimitrov avatar rdimitrovbg avatar thepiwo avatar tony612 avatar untra avatar velzevur avatar willhol avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

elixir-node's Issues

Validate single Transaction

validate signature of the transaction data (valid signature for data considering the public address of the sending account)

Build Transactionpool

  • build transaction pool worker
  • add new transaction to pool
  • don't add transactions with existing hash in blockchain or pool
  • check new transactions validity when adding
  • when mining take all transaction out of pool into block
  • when adding a block from external source to the chain, remove transactions from the pool

the pool in running application state could be a hashmap maybe

Blocks

General description

This component will be responsible for all blocks operations like : create new block, validate a block and so on.

Headers

General description

This component will be responsible for all header operations like : create new header, set nonce and so on.

Logging

  • Include a logging framework
  • log info for informational use messages such as "block mined"
  • log error for all notable errors that can occur in the code
  • log debug messages with specific informations about some calculations, if needed to check if the blockchain is working as intended
  • set the default logging level to info

broadcast new transactions to all peers

  • when adding a transaction to the pool send it to every peer in peermanager
  • receive a transaction from another peer and add it to the pool if its not included already

broadcast new block to all peers

  • If a block is mined, broadcast it to all peer
  • if a block is received from other peers, validate it and add it to the chain
  • after validation broadcast it further to other clients

Document in wiki: How to build a blockchain

Task for everybody to contribute, document how did we build our blockchain.
Where did we start, what components did we build and how do they work together.
This should include all important details but pseudocode at most. There should be reasoning included in every decision we made, what it is needed for.

Document it in the wiki in Markdown

Build a Block and Block Header Data Structure

  • Block Header data structure: height, version, prev_hash, txs_hash, difficulty_target, nonce, timestamp
  • Block data structure: header and list of transactions contained in the block
  • the Block Header should produce a hash of the serialized data of the header, this is the prev_hash in the following block of the chain and used to make the block header immutable once it's built upon
  • height: the height of the previous block +1 when generating a new one (later mining task #8)
  • version: a version number (can first be constant to 1, no other versions available)
  • prev_hash: hash of the block header of the previous block in the list
  • txs_hash: merkle tree hash of the transactions data in the block structure
  • difficulty_target: number of how many zeros in the binary representation of the block that have to be in the beginning
  • nonce: a incremented number used when mining to generate different hashes for the same data

Build Transaction Data Structure

  • First task is excluding the signature from the transaction
  • Data structure: nonce, from account, to account, value
  • nonce is a random integer generated on initialisation of a transaction, for the hash of a equal transaction, but not the same to be different
  • from account is the public address of one account originating the transaction
  • to account is the public address of the account receiving the transaction
  • value is the amount of transaction

Validation of a Block

  • Check previous block hash correct in our out block list structure
  • Check hash of transactions matching the actual transaction data
  • Check if the difficulty target is matched by the zeros in beginning of the hash
  • Check the validity of every transaction
  • Check the height if it's +1 of the prior block
  • Check timestamp for a defined time period (e.g. 2 hours from previous block, maybe as median of last X blocks) this is only needed for receiving new blocks from the network

Bitcoin Block checking protocol: https://en.bitcoin.it/wiki/Protocol_rules#.22block.22_messages this is just for informational purposes and has not to be implemented fully

Difficulty Target Calculation

  • Calculate a target based upon how fast blocks were generated in past, so a median time between blocks is ensured

Documentation for Bitcoin difficulty: https://en.bitcoin.it/wiki/Difficulty
For our implementation we can choose different parameters, e.g. calculate the difficulty for each block and use a target time of 1min

Test multiple transactions in one block

all transactions should be in the same block

  • account A has 100 tokens, spends 100 to B should succeed
  • account A has 100 tokens, spends 110 to B should be invalid
  • account A has 100 tokens, spends 40 to B, and two times 30 to C should succeed
  • account A has 100 tokens, spends 50 to B, and two times 30 to C, last transaction to C should be invalid, others be included
  • account A has 100 tokens, spends 100 to B, B spends 100 to C should succeed if (still) undefined is correct

Include chainstate validation in block validation

  • this will only work when adding new blocks to the chain, verifying older blocks would result in failure
  • verify if the local calculated chainstate, including the changes by transactions in the new block, will match the chainstate roothash in the block header
  • TODO @thepiwo: add more details on how to match validity

Update Readme

  • describe starting
  • describe mining
  • describe important internal api calls
  • describe logs
  • describe testing

Calculate Chainstate

  • data structure of what account has what money available
  • update the chainstate for every block, traverse the transactions and add or substract amounts
  • add merkle root hash of the current chainstate in block header when mining, including all transactions to be mined in this block
  • the state should only consist of transactions included in mined blocks
  • when adding a block to the chain, check if the merkle root hash of the chainstate, matches the locally calculated chainstate

provide get_info endpoint

  • add endpoint to get the clients info, e.g:
{
    "current_block_version" : 1,
    "current_block_height" : 2,
    "current_block_hash" : xyz,
    "genesis_block_hash" : abc,
    "peer_count" : 8,
    "difficulty_target" : 21,
    "public_key": pubkey
}
  • replace ping/pong with get_info, only add peer if genesis block has is correct

Test multiple transactions in multiple blocks

Every transaction should be in the following block

  • account A has 100 tokens, spends 100 to B should succeed
  • account A has 100 tokens, spends 110 to B should be invalid
  • account A has 100 tokens, spends 40 to B, and two times 30 to C should succeed
  • account A has 100 tokens, spends 50 to B, and two times 30 to C, last transaction to C should be invalid, others be included
  • account A has 100 tokens, spends 100 to B, B spends 100 to C should succeed

Generate a Transaction Signature

  • Extend transaction datastructure with the signature
  • Sign the serialized transaction data with private key of the sending account

provide get_block_by_hash endpoint

  • traverse the chain to get a block by hash
  • provide a endpoint to get blocks from other clients
  • receive the block from other clients and verify it

Create PeerManager and add new Peer

  • Build PeerManager GenServer
  • add_peer function to expect a ip address
  • on adding peer /ping to see if it is alive, if so, add to a list of peers
  • check_peers function to check all peers in list if they are still alive, remove if not

Build a Sequence of Blocks Data Structure

  • List of Blocks
  • Generate a Genesis Block starting the List, the Genesis Block should use a previous block hash of zeroes and have a valid pow nonce (can be generated using later mining task #8 )

Key manager

General description

  • create key pair when node starts.

Include Chainstate in checking Transaction validity

  • check if one account from the chainstate has enough balance available that should be spend in the transaction, if the balance minus the available balance is below 0 the transaction should be considered invalid
  • check validity when mining considering the transactions to be added to the new block, to do so use a temporary clone of the chainstate when checking each transaction and add each transaction there. The issue could be that there are more transactions originating from one account inside a block to be mined that when added up exceed the accounts balance, in this case the first transactions not exceeding the balance are considered valid, the others invalid.

add fee to transaction

  • add fee value to the transaction
  • the fee will should be reduced from from_acc e.g. balance 100 --> from_acc 99 fee 1
  • the miner should be able to collect all fees from transactions in the block in addition to the coinbase

increment transaction nonce for every outgoing transaction

  • start first transaction from one account with nonce 0
  • for every outgoing transaction increment the nonce
  • keep the current nonce in chain_state
  • only allow higher nonces when adding transactions to a block
  • order transactions from same account by nonce when taking them out of the transaction pool

Mining

  • Generate the next Block based on the List of blocks
  • try incrementing nonces until difficulty target (from function)
  • input parameters should be the last block of the chain, transactions to be included, current timestamp of generation
  • check the validity of the prior block
  • check the validity of every transaction
  • append newly generated block to the list of blocks
  • continue mining the following block, based upon the newest one
  • extract mining to seperate module
  • stop the miner if needed
  • use bits representation for difficulty target check in hashcash implementation
  • test chain to mine some blocks

Proof of Work Documentation for Bitcoin: https://en.bitcoin.it/wiki/Proof_of_work

Mining for number of cycles

Only mine e.g. 100.000 nonces in one cycle and then recall the mining function with new timestamp and transactions. This should allow timely suspension if needed

Coinbase Transaction

  • define some hardcoded coinbase transaction value (e.g. 100 tokens)
  • when mining a block add a coinbase transaction to the miners public key, it has no from_acc and no signature
  • check coinbase transaction sum when checking block validity, sum of coinbase transactions values should not exceed the coinbase transaction value
  • a coinbase transaction should never be in the transaction pool

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.