{"id":15407081,"url":"https://github.com/ltfschoen/tendermint-elixir","last_synced_at":"2025-04-18T03:17:59.269Z","repository":{"id":76620374,"uuid":"119010124","full_name":"ltfschoen/tendermint-elixir","owner":"ltfschoen","description":"Tendermint Elixir ABCI Application Boilerplate","archived":false,"fork":false,"pushed_at":"2018-01-31T11:16:18.000Z","size":136,"stargazers_count":12,"open_issues_count":4,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-29T06:21:42.486Z","etag":null,"topics":["abci","blockchain","elixir","erlang-library","multiple-network","shell-script","tendermint","tendermint-applications","testnet"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ltfschoen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-01-26T05:35:29.000Z","updated_at":"2023-09-01T10:47:20.000Z","dependencies_parsed_at":null,"dependency_job_id":"b28a81e5-7f61-4c73-91db-a4e2cb1a7a0f","html_url":"https://github.com/ltfschoen/tendermint-elixir","commit_stats":{"total_commits":24,"total_committers":2,"mean_commits":12.0,"dds":0.04166666666666663,"last_synced_commit":"1f87968b5fa73f612c139ef887d465c499e2b785"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ltfschoen%2Ftendermint-elixir","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ltfschoen%2Ftendermint-elixir/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ltfschoen%2Ftendermint-elixir/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ltfschoen%2Ftendermint-elixir/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ltfschoen","download_url":"https://codeload.github.com/ltfschoen/tendermint-elixir/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249419483,"owners_count":21268644,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["abci","blockchain","elixir","erlang-library","multiple-network","shell-script","tendermint","tendermint-applications","testnet"],"created_at":"2024-10-01T16:27:00.182Z","updated_at":"2025-04-18T03:17:59.251Z","avatar_url":"https://github.com/ltfschoen.png","language":"Elixir","readme":"\n---\nTENDERMINT-ELIXIR\n---\n\n# Table of Contents\n  * [Purpose](#chapter-0)\n  * [Goals](#chapter-1)\n  * [Installation (of Elixir and Tendermint)](#chapter-2)\n  * [Initialise and Configure Tendermint](#chapter-3)\n  * [Install ABCI-CLI (using Go)](#chapter-3.5)\n  * [Setup and Run Elixir ABCI Application and ABCI Server (in IEx REPL)](#chapter-4)\n  * [Run Tendermint (Multiple Testnet Nodes)](#chapter-5)\n  * [Experimentation with cURL Requests to ABCI Server (Erlang)](#chapter-6)\n  * [Experimentation with ABCI-CLI](#chapter-7)\n  * [Experimentation with Tendermint (Single Node)](#chapter-8)\n  * [Experimentation with ABCI Server (Erlang) Library (in IEx REPL)](#chapter-9)\n  * [Experimentation with Merkle Tree Elixir Library (in IEx REPL)](#chapter-10)\n  * [Open Source Contributions and Community Questions](#chapter-11)\n  * [Troubleshooting and FAQ](#chapter-12)\n  * [About Tendermint](#chapter-13)\n  * [References](#chapter-14)\n  * [Unsorted Notes](#chapter-15)\n\n## Purpose \u003ca id=\"chapter-0\"\u003e\u003c/a\u003e\n\n* Write an Elixir Application that uses the Tendermint Core (Blockchain Engine) \n\n## Goals \u003ca id=\"chapter-1\"\u003e\u003c/a\u003e\n\n* [X] Install Tendermint Core (BFT Consensus) in Go `tendermint --help`\n* [X] Install Tendermint ABCI-CLI `abci-cli --help`\n* [X] Create Boilerplate Elixir Tendermint Application\n* [X] Load [Merkle Tree Elixir Library](https://github.com/yosriady/merkle_tree) with [Mix](https://elixirschool.com/en/lessons/basics/mix/) into Elixir Tendermint Application. Merke Tree Erlang Library is used perform Merkle Proof Calculations to verify State-Replication https://github.com/yosriady/merkle_tree#usage\n* [X] Load [Tendermint ABCI Server (Erlang)](https://github.com/KrzysiekJ/abci_server) with Mix into Elixir Tendermint Application \n* [X] Run Elixir Tendermint Application (optionally using Interactive Elixir (IEx))\n  * [X] Start the Tendermint ABCI Server (Erlang)\n  * [X] Stop the Tendermint ABCI Server (Erlang)\n* [X] Create Shell Script to generate Tendermint Testnet with four (4) Nodes `bash launch_testnet_nodes.sh`\n* [ ] Create Elixir ABCI Application and processes ABCI-CLI (Tendermint Client) and cURL requests to say the `broadcast_tx_commit` endpoint of the Tendermint ABCI (Tendermint's server-side Application BlockChain Interface API) that uses the Tendermint Core, which is a Byzantine Fault Tolerance (BFT) Blockchain Engine Middlware that processes a State Transition machine input from any language (i.e. Elixir) and replicates it on many Tendermint Testnet Nodes as output. Successful transactions are included in the Mempool, broadcast to Peers, and eventually committed in a Block with the return value containing `check_tx` and `deliver_tx` properties (each containing `data` and `log` sub-properties) to signify that the transaction was run through the CheckTx and DeliverTx ABCI messages of the TMSP (Simple Messaging Protocol)\n* [ ] Implement the Merkle Tree Elixir Library example code https://github.com/yosriady/merkle_tree#usage \n* [ ] Generate Documentation with [ExDoc](https://github.com/elixir-lang/ex_doc) and published on [HexDocs](https://hexdocs.pm)\n* [ ] Publish on [Hex](https://hex.pm/docs/publish)\n\n# Installation (of Elixir and Tendermint)\u003ca id=\"chapter-2\"\u003e\u003c/a\u003e\n\n## Install Elixir\n\n* Install Elixir - https://elixir-lang.org/install.html\n  ```bash\n  brew install elixir;\n  elixir --version\n  ```\n\n## Install Tendermint \n\n* Tendermint\n  * Install Tendermint v0.15.0 - https://github.com/tendermint/tendermint/wiki/Installation\n    * Click \"Install from Source\" https://tendermint.com/downloads\n    * Redirects to Install Tendermint https://tendermint.readthedocs.io/en/master/install.html\n    * Install Tendermint From Source https://tendermint.readthedocs.io/en/master/install.html#from-source\n    * Install GoLang @ https://golang.org/doc/install\n    * Add GOPATH https://github.com/golang/go/wiki/SettingGOPATH\n    * Add GoLang to $PATH\n    * Note: Attempted to use Docker by encountered `shopt` error, as shown in Dockerfile\n\n  ```bash\n  go get --help\n  go get -u -v github.com/tendermint/tendermint/cmd/tendermint\n  tendermint --help\n  ```\n\n## Install JSON Pretty Print\n\n* Install JSONPP - https://jmhodges.github.io/jsonpp/\n  ```\n  brew install jsonpp\n  ```\n\n# Initialise and Configure Tendermint \u003ca id=\"chapter-3\"\u003e\u003c/a\u003e\n\n## Initialise Tendermint\n\n* Create new Private Key `priv_validator.json`, and Genesis File `genesis.json` containing associated Public Key \n  ```bash\n  tendermint init\n  ```\n\n## Reset Tendermint (if necessary)\n  ```bash\n  cd ~/.tendermint \n  rm -rf data/\n  tendermint unsafe_reset_priv_validator\n  ```\n\n## Configure Tendermint\n\n* View Tendermint Directory Root \n  ```bash\n  $ ls  ~/.tendermint\n\n  config.toml\n  data\n  genesis.json\n  priv_validator.json\n  ```  \n\n* View/Edit TOML Configuration File - https://github.com/tendermint/tendermint/wiki/Configuration\n  ```bash\n  $ cat ~/.tendermint/config.toml\n  # This is a TOML config file.\n  # For more information, see https://github.com/toml-lang/toml\n\n  # ABCI Application Socket Address\n  proxy_app = \"tcp://0.0.0.0:46658\"\n\n  # Node Name\n  moniker = \"\u003cMY_NETWORK_NAME\u003e.local\"\n  fast_sync = true\n  db_backend = \"leveldb\"\n  log_level = \"state:info,*:error\"\n\n  # Allow Tendermint p2p library to make connections to peers with the same IP address\n  # https://tendermint.readthedocs.io/en/master/using-tendermint.html#local-network\n  addrbook_strict = false\n\n  [rpc]\n  # RPC Server Listening Address\n  laddr = \"tcp://0.0.0.0:46657\"\n\n  [p2p]\n  # Peer Listening Address on Tendermint\n  laddr = \"tcp://0.0.0.0:46656\"\n  seeds = \"\"\n  ```\n\n* View New Private Key from initialising Tendermint\n  ```bash\n  $ cat ~/.tendermint/priv_validator.json | python -m json.tool\n  {\n      \"address\": \"E472...\",\n      \"last_height\": 18,\n      \"last_round\": 0,\n      \"last_signature\": {\n          \"type\": \"ed25519\",\n          \"data\": \"B755...\"\n      },\n      \"last_signbytes\": \"7B22...\",\n      \"last_step\": 3,\n      \"priv_key\": {\n          \"type\": \"ed25519\",\n          \"data\": \"D11C...\"\n      },\n      \"pub_key\": {\n          \"type\": \"ed25519\",\n          \"data\": \"8373...\"\n      }\n  }\n  ```\n\n* View Genesis File containing Public Key \n  ```bash\n  $ cat ~/.tendermint/genesis.json | python -m json.tool\n  {\n      \"app_hash\": \"\",\n      \"chain_id\": \"test-chain-gZoesi\",\n      \"genesis_time\": \"0001-01-01T00:00:00Z\",\n      \"validators\": [\n          {\n              \"pub_key\": {\n                  \"type\": \"ed25519\",\n                  \"data\": \"8373...\"\n              },\n              \"power\": 10,\n              \"name\": \"\"\n          }\n      ]\n  }\n  ```\n\n# Install ABCI-CLI (using Go) \u003ca id=\"chapter-3.5\"\u003e\u003c/a\u003e\n\n* Install ABCI-CLI with Go (includes example Dummy and Counter Apps) - https://tendermint.readthedocs.io/en/master/getting-started.html#dummy-a-first-example\n  ```bash\n  go get -u github.com/tendermint/abci/cmd/abci-cli;\n  abci-cli --help\n  ```\n\n# Run Tendermint (Single Tendermint Node) with Example ABCI Applications \u003ca id=\"chapter-4\"\u003e\u003c/a\u003e\n\n## Run Tendermint (Single Tendermint Node) with Example ABCI Applications (i.e. \"Dummy\" (GoLang))\n\n* Start Tendermint Single-Node Blockchain and Compile in-progress ABCI Application written in GoLang (i.e. Dummy App https://github.com/tendermint/abci)\n  ```bash\n  $ tendermint node --proxy_app=dummy\n\n  I[01-22|21:35:03.283] Executed block                               module=state height=1 validTxs=0 invalidTxs=0\n  I[01-22|21:35:03.283] Committed state                              module=state height=1 txs=0 appHash=\n  I[01-22|21:35:04.295] Executed block                               module=state height=2 validTxs=0 invalidTxs=0\n  I[01-22|21:35:04.295] Committed state                              module=state height=2 txs=0 appHash=\n  ```\n\n* Review Example Application built with ABCI Server - https://github.com/KrzysiekJ/abci_counter\n\n# Setup and Run Elixir ABCI Application and ABCI Server (Erlang) (in IEx REPL) \u003ca id=\"chapter-5\"\u003e\u003c/a\u003e\n\n## Update GNU Make\n\n* Upgrade to GNU Make 4 or later (macOS pre-installed with GNU Make 3) https://erlang.mk/guide/installation.html\n  ```bash\n  brew install erlang git;\n  brew install make --with-default-names;\n  ```\n\n## Switch Directory (to the Elixir ABCI Application)\n\n* Change into App Directory.\n  ```bash\n  cd blockchain_tendermint;\n  ```\n\n## Configure Mix Dependencies. Add ABCI Server (Erlang) (to the Elixir ABCI Application)\n\n* Add ABCI Server (Erlang) to mix.exs. [Choose a Release Tag](https://github.com/KrzysiekJ/abci_server/tags) \n  ```elixir\n  defp deps do\n    [\n      # ABCI Server (Erlang) - https://github.com/KrzysiekJ/abci_server\n      # Tendermint List of ABCI Servers - http://tendermint.readthedocs.io/projects/tools/en/master/ecosystem.html?highlight=server#abci-servers\n      {:abci_server, git: \"https://github.com/KrzysiekJ/abci_server.git\", tag: \"v0.4.0\"}\n    ]\n  end\n  ```\n\n## Install Mix Dependencies (for the Elixir ABCI Application)\n\n* Fetch Mix Dependencies defined in mix.exs\n  ```bash\n  mix deps.get\n  ```\n\n## Show Documentation for ABCI Server (Erlang)\n\n* Documentation Generation. Open Documentation in Web Browser\n  ```bash\n  cd deps/abci_server/ \u0026\u0026 make docs \u0026\u0026 open doc/index.html \u0026\u0026 cd ../../\n  ```\n\n## Compile Elixir ABCI Application with Mix\n\n* Compile Mix Project into _build/ Directory\n  ```bash\n  MIX_ENV=dev mix compile\n  ```\n\n## Run Elixir ABCI Application in Interactive Elixir (IEx) REPL to Demonstrate Verification of Transaction Sender/Recipient\n\n* Interactive Elixir (REPL) within context of Elixir App and dependencies injected into IEx runtime\n  ```bash\n  iex -S mix\n  ```\n\n  ```elixir\n  c(\"lib/blockchain_tendermint.ex\")\n  BlockchainTendermint.start_server\n  ```\n\n* Run Tendermint Node \n  ```\n  tendermint node\n  ```\n\n* Send cURL Request to ABCI Server endpoint.\n  ```\n  curl -s 'localhost:46658/broadcast_tx_commit?tx=\"sender=___\u0026receiver=___\u0026data=___\"'\n  ```\n\n* View Logs from ABCI Server in IEx Terminal Window. Shows Outputs of `handle_request` function in Elixir ABCI App\n  ```\n  iex(1)\u003e BlockchainTendermint.start_server\n  {:ok, #PID\u003c0.168.0\u003e}\n  iex(2)\u003e Processing Transaction\n  Received Arguments to handle_request: \"sender=a\u0026receiver=b\u0026data=''\"\n  58c89d709329eb37285837b042ab6ff72c7c8f74de0446b091b6a0131c102cfd\n  Validity of Transaction: true\n\n  20:32:18.499 [error] GenServer #PID\u003c0.176.0\u003e terminating\n  ** (FunctionClauseError) no function clause matching in :abci.e_msg_ResponseInfo/3\n      ...\n  Last message: {:tcp, #Port\u003c0.5191\u003e, \u003c\u003c1, 10, 34, 8, 10, 6, 48, 46, 49, 53, 46, 48, 1, 2, 26, 0\u003e\u003e}\n  State: {:state, #Port\u003c0.5191\u003e, :ranch_tcp, \"\", BlockchainTendermint}\n  \n  20:32:18.502 [error] Ranch listener BlockchainTendermint had connection process started with :abci_server:start_link/4 at #PID\u003c0.176.0\u003e exit with reason: ...\n  ```\n\n* Stop Server\n  ```elixir\n  BlockchainTendermint.stop_server\n  ```\n\n# Run Mix Unit Tests and Doctests \u003ca id=\"chapter-4.5\"\u003e\u003c/a\u003e\n\n* Run Unit Tests and Doctests with Mix\n  ```bash\n  mix test\n  ```\n\n# Run Tendermint (Multiple Testnet Nodes) \u003ca id=\"chapter-5\"\u003e\u003c/a\u003e\n\n* Launch Testnet Nodes (4 OFF) (in separate Terminal Tabs using Shell Script)\n  ```bash\n  $ bash launch_testnet_nodes.sh\n  Tendermint Testnet Location: /Users/Ls/code/blockchain/tendermint-elixir/mytestnet\n  Loading Nodes: mach0, mach1, mach2, mach3\n  Loading Seeds: 0.0.0.0:46656,0.0.0.0:46666,0.0.0.0:46676,0.0.0.0:46686\n  Successfully initialized 4 node directories\n  ```\n  * Troubleshooting: If nothing appears in each of the separate Terminal Tabs then in restart the server in IEx with:\n    ```elixir\n    k = BlockchainTendermint.stop_server\n    {ok, _} = BlockchainTendermint.start_server\n    ```\n\n    * Example output in each separate Terminal Tab\n\n      ```bash\n      E[01-27|23:38:17.914] Stopping abci.socketClient for error: EOF    module=abci-client connection=query\n      E[01-27|23:38:29.069] Stopping abci.socketClient for error: EOF    module=abci-client connection=mempool\n      E[01-27|23:38:29.069] Stopping abci.socketClient for error: EOF    module=abci-client connection=consensus\n\n      E[01-27|23:38:29.068] Stopping abci.socketClient for error: read tcp 127.0.0.1:63711-\u003e127.0.0.1:46658: read: connection reset by peer module=abci-client connection=query\n      E[01-27|23:38:29.068] Stopping abci.socketClient for error: read tcp 127.0.0.1:63713-\u003e127.0.0.1:46658: read: connection reset by peer module=abci-client connection=consensus\n      E[01-27|23:38:29.069] Stopping abci.socketClient for error: read tcp 127.0.0.1:63712-\u003e127.0.0.1:46658: read: connection reset by peer module=abci-client connection=mempool\n      ```\n\n  * **UNRESOLVED**\n\n* Optional Alternative Deployment \n  * Kubernetes - https://github.com/tendermint/tools/tree/master/mintnet-kubernetes\n    * **TODO**\n\n# Experimentation with cURL Requests to ABCI Server (Erlang) \u003ca id=\"chapter-6\"\u003e\u003c/a\u003e\n\n* Show all available API endpoints by going to http://0.0.0.0:46658/\n\n  * **UNRESOLVED**\n\n* Send Request to ABCI Server endpoint. Note: Must use `0.0.0.0` NOT `localhost`\n  ```\n  curl -v '0.0.0.0:46658/status' | jsonpp | grep app_hash\n    *   Trying 0.0.0.0...\n    * TCP_NODELAY set\n    * Connected to 0.0.0.0 (0.0.0.0) port 46658 (#0)\n    \u003e GET /status HTTP/1.1\n    \u003e Host: 0.0.0.0:46658\n    \u003e User-Agent: curl/7.57.0\n    \u003e Accept: */*\n    \u003e \n  ```\n\n  * **UNRESOLVED**\n\n# Experimentation with ABCI-CLI \u003ca id=\"chapter-7\"\u003e\u003c/a\u003e\n\n**UNRESOLVED**\n\n* Experiment with ABCI-CLI (from separate Bash Terminal Tab after starting ABCI Server in IEx)\n  * CheckTx\n    ```bash\n    abci-cli check_tx \"0x00\" --address tcp://0.0.0.0:46658 --abci \"socket\" --log_level \"debug\" --verbose\n    ```\n\n  * Echo\n    ```bash\n    abci-cli echo \"Hello\" --address tcp://0.0.0.0:46658 --abci \"socket\" --log_level \"debug\" --verbose\n    ```\n\n  * DeliverTx\n    ```bash\n    abci-cli deliver_tx \"0x00\" --address tcp://0.0.0.0:46658 --abci \"socket\" --log_level \"debug\" --verbose\n    ```\n\n  * Query\n    ```bash\n    abci-cli query \"0x00\" --address tcp://0.0.0.0:46658 --abci \"socket\" --log_level \"debug\" --verbose\n    ```\n\n# Experimentation with Tendermint (Single Node) \u003ca id=\"chapter-8\"\u003e\u003c/a\u003e\n\n* Run Tendermint Core (blockchain engine) Node\n  ```bash\n  tendermint init;\n  tendermint unsafe_reset_all;\n  tendermint node --help;\n  tendermint node \\\n    --abci \"socket\" \\\n    --consensus.create_empty_blocks true \\\n    --fast_sync true \\\n    --moniker \"LS.local\" \\\n    --p2p.laddr \"tcp://0.0.0.0:46656\" \\\n    --p2p.pex true \\\n    --p2p.seeds \"tcp://127.0.0.1:46656, tcp://127.0.0.1:46666, tcp://127.0.0.1:46676, tcp://127.0.0.1:46686\" \\\n    --p2p.skip_upnp false \\\n    --proxy_app \"tcp://127.0.0.1:46658\" \\\n    --rpc.laddr \"tcp://0.0.0.0:46657\" \\\n    --rpc.unsafe true \\\n    --home \"/Users/Ls/.tendermint\" \\\n    --log_level \"state:info,*:error\" \\\n    --trace true\n  ```\n\n# Experimentation with ABCI Server (Erlang) Library (in IEx REPL) \u003ca id=\"chapter-9\"\u003e\u003c/a\u003e\n\n* Run IEx\n  ```bash\n  iex -S mix\n  ```\n    \n## Experiment with ABCI Server in IEx\n\n* Reference: Loading an Erlang Library into Elixir - https://elixirschool.com/en/lessons/advanced/erlang/\n\n* Important Note: `__info__/1` is an Elixir thing the compiler adds, you probably want `module_info/1` which is the erlang equivalent - https://elixir-lang.slack.com/archives/C03EPRA3B/p1517018221000028\n\n* Show ABCI Server Module Information. Start ABCI Server. Stop ABCI Server\n  ```elixir\n  iex\u003e :abci_server.module_info  \n  [\n    module: :abci_server,\n    exports: [\n      start_link: 4,\n      start_listener: 2,\n      child_spec: 2,\n      stop_listener: 1,\n      init: 1,\n      handle_call: 3,\n      handle_cast: 2,\n      handle_info: 2,\n      terminate: 2,\n      code_change: 3,\n      module_info: 0,\n      module_info: 1\n    ],\n    attributes: [\n      vsn: [86973587470476204871336807197797490126],\n      behaviour: [:gen_server],\n      behaviour: [:ranch_protocol]\n    ],\n    compile: [\n      options: [\n        :debug_info,\n        {:i,\n        '/Users/Ls/code/blockchain/tendermint-elixir/blockchain_tendermint/deps/abci_server/include'},\n        :warn_obsolete_guard,\n        :warn_shadow_vars,\n        :warn_export_vars\n      ],\n      version: '7.1.4',\n      source: '/Users/Ls/code/blockchain/tendermint-elixir/blockchain_tendermint/deps/abci_server/src/abci_server.erl'\n    ],\n    native: false,\n    md5: \u003c\u003c65, 110, ..., 206\u003e\u003e\n  ]\n\n  iex\u003e  defmodule Foo do             \n          def bar() do               \n            IO.puts(\"Hello, World!\") \n          end\n        end\n\n  iex\u003e {ok, _} = :abci_server.start_listener(Foo, 46658)\n  {:ok, #PID\u003c0.181.0\u003e}\n  ```\n\n* Integration Tests run against the ABCI Server (Erlang) (separate Bash Terminal Tab) https://github.com/tendermint/abci#tools\n  ```bash\n  abci-cli test\n  ```\n\n  * View Output (in the Bash Terminal Tab running IEx)\n    ```elixir\n    iex\u003e \n    14:27:53.961 [error] GenServer #PID\u003c0.242.0\u003e terminating\n    ** (UndefinedFunctionError) function Foo.handle_request/1 is undefined (module Foo is not available)\n        Foo.handle_request(\n          { \n            :RequestInitChain, \n            [ \n              { :Validator, \u003c\u003c1, 229, ..., 36\u003e\u003e, 1647107211121726315 }, \n              { :Validator, \u003c\u003c1, 243, ..., 78\u003e\u003e, 8186817011543816184 }, \n              { :Validator, \u003c\u003c1, 102, ..., 16\u003e\u003e, 7982159435569315414 }, \n              { :Validator, \u003c\u003c1, 135, ..., 64\u003e\u003e, 2846252370576207682 }, \n              { :Validator, \u003c\u003c1, 241,..., 159\u003e\u003e, 637770835807807961 }, \n              { :Validator, \u003c\u003c1, 16, ..., 76\u003e\u003e, 4097788002864909056 }, \n              { :Validator, \u003c\u003c1, 152, ..., 70\u003e\u003e, 8116718250853054711 }, \n              { :Validator, \u003c\u003c1, 19, ..., 246\u003e\u003e, 3891949616163017026 }, \n              { :Validator, \u003c\u003c1, 179, ..., 254\u003e\u003e, 7045591847215797995 }, \n              { :Validator, \u003c\u003c1, 189, ..., 80\u003e\u003e, 4226073179895220771 }\n            ]\n          }\n        )\n        (abci_server) src/abci_server.erl:117: :abci_server.handle_requests/2\n        (abci_server) src/abci_server.erl:83: :abci_server.handle_info/2\n        (stdlib) gen_server.erl:616: :gen_server.try_dispatch/4\n        (stdlib) gen_server.erl:686: :gen_server.handle_msg/6\n        (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3\n    Last message: { :tcp, #Port\u003c0.5297\u003e, \u003c\u003c2, 1, ..., 148, ...\u003e\u003e }\n    State:        { :state, #Port\u003c0.5297\u003e, :ranch_tcp, \"\", Foo}\n    \n    14:27:53.965 [error] Ranch listener Foo had connection process started with :abci_server:start_link/4 at #PID\u003c0.242.0\u003e exit with reason: \n    { :undef, \n      [ \n        { \n          Foo, \n          :handle_request, [ \n            RequestInitChain: [ \n              { :Validator, \u003c\u003c1, 229, ..., 36\u003e\u003e, 1647107211121726315 }, \n              { :Validator, \u003c\u003c1, 189, ..., 112, ...\u003e\u003e, 4226073179895220771 }\n            ]\n          ], \n          []\n        }, \n        { \n          :abci_server, \n          :handle_requests, \n          2, \n          [file: 'src/abci_server.erl', line: 117]\n        }, \n        {\n          :abci_server, \n          :handle_info, \n          2, \n          [file: 'src/abci_server.erl', line: 83]\n        }, \n        {\n          :gen_server, \n          :try_dispatch, \n          4,\n          [file: 'gen_server.erl', line: 616]\n        }, \n        {\n          :gen_server, \n          :handle_msg, \n          6, \n          [file: 'gen_server.erl', line: 686]\n        }, \n        {\n          :proc_lib, \n          :init_p_do_apply, \n          3, \n          [file: 'proc_lib.erl', line: 247]\n        }\n      ]\n    }\n    ```\n\n* Update Elixir App to define `handle_request` Handle Request. Re-run the following in a separete Bash Terminal whilst ABCI Server (Erlang) is running and it will return `Passed test: InitChain`. \n  * Reference: Sample ABCI Counter App https://github.com/KrzysiekJ/abci_counter/tree/master/src\n  ```bash\n  abci-cli test\n  ```\n\n# Experimentation with Merkle Tree Elixir Library (in IEx REPL) \u003ca id=\"chapter-10\"\u003e\u003c/a\u003e\n\n* Merkle Tree Library\n  * [MerkleTree Module Example](https://hexdocs.pm/merkle_tree/MerkleTree.html)\n    * Create a Merkle Tree (given a number of string Blocks, and optional Cryptographic Hash Function):\n      * Each non-leaf node is labelled with the hash of the labels or values (for leafs) of its child nodes\n      * Allows efficent and secure verification of the contents of large data structures\n      * Default Hash Function is `:sha256`\n      * API Docs Reference: https://hexdocs.pm/merkle_tree/MerkleTree.html#new/2\n      * Reference: \n        * Merkle Trees in Elixir Blogpost: https://yos.io/2016/05/19/merkle-trees-in-elixir/\n\n    ```elixir\n    iex\u003e MerkleTree.__info__(:functions)\n    [__struct__: 0, __struct__: 1, build: 2, new: 1, new: 2]\n    iex\u003e mt = MerkleTree.new ['a', 'b', 'c', 'd']\n    %MerkleTree{\n      blocks: ['a', 'b', 'c', 'd'], \n      hash_function: \u0026MerkleTree.Crypto.sha256/1,\n      root: \n        %MerkleTree.Node {\n          children: [ \n            %MerkleTree.Node {\n              children: [ \n                %MerkleTree.Node {\n                  children: [],\n                  value: \"ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb\"\n                },\n                %MerkleTree.Node {\n                  children: [], \n                  value: \"3e23e8160039594a33894f6564e1b1348bbd7a0088d42c4acb73eeaed59c009d\"\n                }\n              ],\n              value: \"62af5c3cb8da3e4f25061e829ebeea5c7513c54949115b1acc225930a90154da\"\n            },\n            %MerkleTree.Node {\n              children: [\n                %MerkleTree.Node {\n                  children: [], \n                  value: \"2e7d2c03a9507ae265ecf5b5356885a53393a2029d241394997265a1a25aefc6\"\n                },\n                %MerkleTree.Node {\n                  children: [], \n                  value: \"18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4\"}\n              ],\n              value: \"d3a0f1c792ccf7f1708d5422696263e35755a86917ea76ef9242bd4a8cf4891a\"\n            }\n          ],\n          value: \"58c89d709329eb37285837b042ab6ff72c7c8f74de0446b091b6a0131c102cfd\"\n        }\n    }\n    $ mt.blocks()\n    ['a', 'b', 'c', 'd'] \n    $ mt.hash_function()\n    \u0026MerkleTree.Crypto.sha256/1\n    $ mt.root()\n    ...\n    ```\n\n  * [MerkleTree.Proof Module Example](https://hexdocs.pm/merkle_tree/MerkleTree.Proof.html) (requires merkle_tree \u003e1.2.0)\n    * Generate and Verify Merkle Proofs\n    ```elixir\n    iex\u003e MerkleTree.Proof.__info__(:functions)           \n    [__struct__: 0, __struct__: 1, prove: 2, proven?: 3]\n    iex\u003e proof1 = MerkleTree.Proof.prove(mt, 1)\n    iex\u003e proven1 = MerkleTree.Proof.proven?({\"b\", 1}, \"58c89d709329eb37285837b042ab6ff72c7c8f74de0446b091b6a0131c102cfd\", proof1)\n    true\n\n    iex\u003e proof3 = MerkleTree.Proof.prove(mt, 3)                                              \n    %MerkleTree.Proof{          \n      hash_function: \u0026MerkleTree.Crypto.sha256/1,\n      hashes: [\"62af5c3cb8da3e4f25061e829ebeea5c7513c54949115b1acc225930a90154da\",\n      \"2e7d2c03a9507ae265ecf5b5356885a53393a2029d241394997265a1a25aefc6\"]\n    }\n    iex\u003e proven3 = MerkleTree.Proof.proven?({\"d\", 3}, \"58c89d709329eb37285837b042ab6ff72c7c8f74de0446b091b6a0131c102cfd\", proof3)\n    true\n    ```\n\n  * [MerkleTree.Crypto Module Example](https://hexdocs.pm/merkle_tree/MerkleTree.Crypto.html)\n    ```elixir\n    iex\u003e MerkleTree.Crypto.__info__(:functions) \n    [hash: 2, sha256: 1]\n    iex\u003e MerkleTree.Crypto.hash(\"tendermint\", :sha256) \n  \"f6c3848fc2ab9188dd2c563828019be7cee4e269f5438c19f5173f79898e9ee6\"\n    iex\u003e MerkleTree.Crypto.hash(\"tendermint\", :md5)   \n  \"bc93700bdf1d47ad28654ad93611941f\"\n    iex\u003e MerkleTree.Crypto.sha256(\"tendermint\")    \n  \"f6c3848fc2ab9188dd2c563828019be7cee4e269f5438c19f5173f79898e9ee6\"\n    ```\n\n# Open Source Contributions and Community Questions \u003ca id=\"chapter-11\"\u003e\u003c/a\u003e\n\n* Merkle Tree\n  * Pull Request - https://github.com/yosriady/merkle_tree/pull/8\n  * Issue - https://github.com/yosriady/merkle_tree/issues/9\n\n* ABCI Server\n  * Pull Request - https://github.com/KrzysiekJ/abci_server/pull/3\n  * Issues:\n    * https://github.com/KrzysiekJ/abci_server/issues/4\n    * https://github.com/KrzysiekJ/abci_server/issues/5\n\n  * Questions\n    * Elixir Slack \n      * https://elixir-lang.slack.com/archives/C03EPRA3B/p1517016786000068\n\n# Troubleshooting and FAQ \u003ca id=\"chapter-12\"\u003e\u003c/a\u003e\n\n* Problem: `erlang.mk:26: Please upgrade to GNU Make 4 or later: https://erlang.mk/guide/installation.html`\n  * Solution:\n    * Check Make and GMake installation directories\n      ```\n      $ which -a make;\n      /usr/bin/make\n      $ which -a gmake;\n      /usr/local/bin/gmake\n      ```\n\n    * Add to Bash Profile\n      ```\n      export PATH=\"/usr/local/bin/make:$PATH\"\n      export PATH=\"/usr/local/opt/make/libexec/gnubin:$PATH\"\n      ```\n    * Reset Bash Profile\n      ```\n      source ~/.bash_profile\n      ```\n    * Create Symlink between version of GNU Make 4 in PATH and where it is installed (instead of default macOS GNU Make 3)\n      ```\n      ln -s /usr/local/bin/gmake /usr/local/bin/make\n      ```\n    * Check PATH of Make has changed\n      ```\n      $ which make\n      /usr/local/bin/make\n      ```\n\n* Problem: `** (Mix) Could not start application ranch: could not find application file: ranch.app`\n  * Solved: See Issue raised https://github.com/KrzysiekJ/abci_server/issues/4\n\n* Problem: Unable to communicate with Elixir ABCI App. After running ABCI Server, when I try and connect with `tendermint node`, it gives the following error, which is not listed on the Tendermint how to read logs webpage -\nhttps://tendermint.readthedocs.io/en/master/how-to-read-logs.html\n  ```\n  E[01-27|05:47:23.729] Stopping abci.socketClient for error: EOF    module=abci-client connection=query\n  ```\n  * **UNRESOLVED**\n    * https://matrix.to/#/!vIMgGaMqkLIWPCZvPF:matrix.org/$151705250910696925POLba:matrix.org\n    * https://github.com/tendermint/tendermint/issues/1166\n\n* Problem: Tendermint Testnet Node flags moniker and seed do not overwrite as expected\n  * **UNRESOLVED**\n    * https://github.com/tendermint/tendermint/issues/1167\n\n# About Tendermint \u003ca id=\"chapter-13\"\u003e\u003c/a\u003e\n\n* Tendermint\n\n  * Background - https://blockchainhub.net/blog/blog/scaling-ethereum-2/\n\n  * Diagrams\n    * Tendermint in a (technical) nutshell - https://github.com/devcorn/hackatom/blob/master/tminfo.pdf\n\n  * TendermintCore (BFT \"consensus engine\" Protocol that is mostly Asynchronous that uses a Simple State Machine https://tendermint.readthedocs.io/en/master/introduction.html#consensus-overview, and that communicates with an Application via TSP socket protocol that satisfies the ABCI)\n    * About\n      * Tendermint Core\n        * Definition - a general purpose blockchain data structure (transactions batched in blocks where each block contains a cryptographic hash of the previous block, and the blocks form a chain) to replicate your Application on distributed systems (many machines) to provide fault tolerance\n          * Secure Replication - Byzantine Fault Tolerant (BFT) since it still works when up to 1/3 of machines fail (from causes including hacking and malicious attacks)\n          * Consistent Replication - all non-faulty machines may see same Transaction Log and computes same State\n          * Consensus Engine - sharing Blocks and Transactions between Nodes to ensure recorded on all machines in same immutable order (blockchain)\n          * Hosts Arbitrary States - may be used as plug-and-play replacement for consensus engines of other blockchain software (i.e. run any programming language implementation of Ethereum as an ABCI application using Tendermint consensus, i.e. Ethermint, Cosmos network)\n\n    * Byzantine Fault Tolerant (BFT) Consensus engine\n      * Note: Non Proof-of-Work (PoW) system\n      * Reference: https://github.com/tendermint/tendermint/wiki/Byzantine-Consensus-Algorithm\n        * Summary\n          * Block Data Structure - https://github.com/tendermint/tendermint/wiki/Block-Structure\n            * `Header` - chain info and Last State\n              * `ChainId` (string): name of the Blockchain, e.g. \"tendermint\"\n              * `Height` (int): sequential Block Number starting with 1\n              * `Time` (time): local time of the Proposer of this Block\n              * `LastBlockHash` ([]byte): Block Hash of the Previous Block at `Height - 1`\n              * `LastBlockPartsetHeader` (PartSetHeader): Partset Header of the Previous Block\n              * `StateHash` ([]byte): State Hash of the State after processing this Block\n                * `StateHash` is a hash derived from a encoding the State's Fields (i.e. `BondedValidators`, `UnbondingValidators`, `Accounts`, `ValidatorInfos`, and `NameRegistry`), using a [Simple Tree (Binary Tree)](https://github.com/tendermint/tendermint/wiki/Merkle-Trees#simple-tree-with-dictionaries) to merkelise a dictionary list of KV Pair structs.\n                * `StateHash` is recursively included in the block `Header` and indirectly into the `BlockHash`\n\n            * `Data` - Transactions of the Block that are any sequence of Bytes comprising:\n              * `Txs` ([]`Tx`): list of Transactions. \n              Note: [ABCI Applications](https://github.com/tendermint/abci) (previuosly known as TMSP) may Accept or Reject a Tx\n            * `LastCommit` - Comprises `Precommit` Signatures of the Previous Block \n              * `Precommits` ([]`Vote`): confirms that Consensus Decided for the Last Block was performed by over 2/3 (i.e. +2/3) of valid Voting Participants\n                * `Vote`\n                  * `Height` (int): Block Height being Decided on\n                  * `Round` (int): Consensus Round number (starting with 0)\n                  * `Type` (byte): Vote Type, either:\n                    * `Prevote` or `Precommit` - [Vote Type](https://github.com/tendermint/tendermint/wiki/Block-Structure#vote) to Broadcast\n                      i.e. `\"type\": 2`\n                    * Note: Proof-of-Lock-Change (PoLC) is the Set of +2/3 `Prevote`'s for a Block, or `\u003cnil\u003e` at Node `(H, R)`\n                  * `BlockHash` ([]byte): \n                    * Block Hash of a valid Block, or nil.\n                    * Blockhash is a hash derived from a encoding the Block Header fields using a [Simple Tree (Binary Tree)](https://github.com/tendermint/tendermint/wiki/Merkle-Trees#simple-tree-with-dictionaries) to merkelise a dictionary list of KV Pair structs\n                  * `BlockPartsetHeader` (PartSetHeader):\n                    * PartSet Header, or x0000 if Block Hash is nil\n                    * PartSet (inspired by LibSwift project) is used to propagate a Large File over a Gossip Protocol Network (i.e. multicast a message to all nodes in a network, where each node only sends the message to a few of the nodes)\n                    * PartSet splits a Byteslice of Data (a Part) into a Transmission Parts List. Compute the Merke Root Hash of the Transmission Parts List. Verify that a Part is legitimately a Part of the Data by using the Merkle Root Hash of the Transmission Parts List prior to Forwarding the Part to other Peers (even before other Parts are known)  \n                      i.e. `{ \"hash\": \"XYZ\", \"total\": 123 }`\n                    * Example code: https://github.com/tendermint/tendermint/wiki/Block-Structure#commit\n                  * `Signature` (Signature): `Signature` field of Vote's Transaction\n                    * `sign-bytes`: JSON stringified (ordered) encoding (excluding the `Signature`) of Vote's Transaction\n                      i.e. Example Precommit Vote:\n                      `{ \"chain_id\": \"tendermint\",\"vote\": { ... } }`\n\n          * Consensus Process (State Machine) - https://tendermint.readthedocs.io/en/master/introduction.html#consensus-overview \n            * Deciding Next Block (at each Block Height `H`)\n              * Rounds (Round-based Protocol) - each Round has a State Machine `RoundStep` representation (aka \"Step\") comprising Optimally 3x Steps + 2x Special Steps:\n                * Round (sequence)\n                  * Step 1: `Propose (H, R)` \n                    * Prerequisite, either:\n                      * `CommitTime` + `timeoutCommit` (after `NewHeight` committed) OR\n                      * `timeoutPrecommit`\n                    * Start:\n                      * Proposer (designated) proposes a Block at `(H, R)`\n                    * End: \n                      * After `timeoutProposer` -\u003e Step 2\n                      * After `PoLC Round` receipt of Proposal Block and all Prevotes -\u003e Step 2\n                      * After \"Common Exit Conditions\"\n                        * Question Raised - How does this make sense when all the common exit conditions occur after \"Step 1\"\n                          * https://matrix.to/#/!vIMgGaMqkLIWPCZvPF:matrix.org/$15167017365754249pwRYF:matrix.org\n                  * Step 2: `Prevote (H, R)`\n                    * Start:\n                      * Validators broadcast their Prevote Vote\n                    * Situations:\n                      * Unlocking happens when Validators that have been Locked on a Block since `LastLockRound`\n                      who also have a `PoLC` for something else at `PoLC-Round` where `LastLockRound \u003c PoLC-Round \u003c R`\n                      * Prevote for a Block happens when a Validator is still Locked on a Block\n                      * Prevote for a Proposed Block from `Propose (H, R)` happens when it is Valid\n                      * Prevote of `\u003cnil\u003e` happens for a Proposed Block that is Invalid or received late\n                    * End:\n                      * After +2/3 Prevotes for a specific Block or `\u003cnil\u003e` -\u003e Step 3\n                      * After `timeoutPrevote` after receiving any +2/3 Prevotes -\u003e Step 3\n                      * After \"Common Exit Conditions\"\n                  * Step 3: `Precommit (H, R)` after +2/3 Precommits for Block found\n                    * Start:\n                      * Validators broadcast their Precommit Vote\n                    * Situation:\n                      * Re-Locks / Changes Lock and Precommits Block `B` and Sets `LastLockRound = R` when Validator has PoLC `(H, R)` for specific Block `B`\n                      * Unlocks and Precommits `\u003cnil\u003e` (i.e. obtained +2/3 Prevotes and waited but did not see PoLC for the Round) when Validator has PoLC at `(H, R)` for `\u003cnil\u003e`\n                      * Lock remains and Precommits `\u003cnil\u003e` otherwise\n                    * End:\n                      * After +2/3 Precommits for `\u003cnil\u003e` -\u003e Step 1 `Propose (H, R + 1)`\n                      * After `timeoutPrecommit` after receiving any +2/3 Precommits -\u003e Step 1 `Propose (H, R + 1)`\n                      * After \"Common Exit Conditions\"\n                * Special Step A: `Commit (H)` by:\n                  * Setting `CommitTime = now`\n                  * Waiting to receive Block and then Stage, Save, and Commit the Block -\u003e Step B `NewHeight (H + 1)`\n                * Special Step B: `NewHeight (H)`\n                  * Move `Precommits` to `LastCommit`\n                  * Increment Block Height\n                  * Set `StartTime = CommitTime + timeoutCommit`\n                  * Wait until `StartTime` to receive straggling commits -\u003e Step 1 `Propose (H, 0)`\n                    i.e. `NewHeight -\u003e (Propose -\u003e Prevote -\u003e Precommit) + -\u003e Commit -\u003e NewHeight -\u003e`\n                * Note: See Diagram: https://github.com/tendermint/tendermint/wiki/Byzantine-Consensus-Algorithm\n              * Note: Multiple Rounds may be required to due to:\n                * Problems\n                  * Proposer (designated) was not online\n                  * Proposer (designated) had proposed an Invalid Block\n                  * Proposer (designated) had proposed a Valid Block that did not propogate in time\n                  * Proposer (designated) had proposed a Valid Block but +2/3 of its Prevotes were not received in time (i.e. at least 1x Validator may have voted `\u003cnil\u003e` or performed a malicious votes) so there were Insufficient Validator Nodes when the Precommit step was reached\n                  * Proposer (designated) had proposed a Valid Block and +2/3 of its Prevotes were received for sufficent nodes, but +2/3 of the Precommits for the Proposed Block were not received for sufficient Validator nodes.\n                * Solutions\n                  * Subsequent Round and Proposer (designated)\n                  * Increasing Round parameters (i.e. Timeout) for successive rounds\n\n          * Proposal \n            * Signed \u0026 Published by Proposer (designated) at each Round\n            * Proposal at Node `(H, R)` comprises:\n              * Block\n              * Optional PoLC Round (which is less than `R`), included if Proposer is aware of one, and provides a hint to the network to allow \"unlocking\" of Nodes when safe to ensure \"Proof of Liveness\"\n\n          * Proposer (NOT Validators)\n            * Selected in proportion to their Voting Power (using round robin selection algorithm)\n            * Reference: [Code](https://github.com/tendermint/tendermint/blob/develop/types/validator_set.go#L49)\n\n          * Nodes - optionally connected in the network, are at a given:\n            * Height `H` - Block Height being decided upon\n            * Round `R` - Consensus Round number (starting from 0)\n            * Step `S`\n              * i.e. `(H, R, S)`\n          \n          * Peers - are Nodes that are directly connected to a Node\n\n          * `Channel` (Throttled information)\n            * `Connection` - between 2x Nodes\n\n          * Epidemic Gossip Protocol - implemented by some Channels to update Peers on latest State of Consensus \n            * Nodes use PartSet algorithm (LibSwift inspired) to gossip/broadcast Parts (split Data) across the network for the current Round decision for a Proposed Block by a Proposer\n            * Nodes gossip Prevote/Precommit Votes to enable Other Nodes to progress forward\n              i.e. Node A (ahead of Node B) may send Node B Prevotes/Precommits for Node B's current/future Round\n            * Nodes gossip Prevotes for Proposed Proof-of-Lock-Change (PoLC) Round (i.e. requires Set of +2/3 `Prevote`'s for a Block, or `\u003cnil\u003e` at Node `(H, R)`\n            * Nodes gossip Block Commits for Older Blocks to Other Nodes that are lagging with a lower Blockchain Height\n            * Nodes gossip `HasVote` messages opportunistically to hint to Peers what Votes they have\n            * Nodes broadcast to all Peers their current State\n\n          * Gossip Protocol Participants are \"Validators\"\n            * Validators\n              * Validators take turns as Proposer (delegate) Blocks containing Transactions and Voting on Blocks to be Committed on-chain at Block Height\n              * Validators Vote to move to Next Round after waiting a Timeout interval (the only Synchronous aspect of the Protocol) to receive a complete Proposal Block from the Proposer \n              * Validators only progress after hearing from 2/3+ of the Validator Set\n\n            * Blocks\n              * Failure of a Block Commit causes the Protocol to move to the Next Round with a New Validator as Proposer (delegate) to propose the Next Block Height\n              * Tendermint uses same mechanism for Block Commits as it does for Skipping to Next Round\n              * Tendermint guarantees Safety without Validators ever committing a Block Commit that conflicts at the same Block Height on the assumption that 1/3- of Validators are BFT by using \"Locking\" rules that modulate the paths that may be followed in the Consensus Flow Diagram\n\n            * Block Commit Failure\n              * Causes\n                * Proposer (delegate) may be Offline\n                * Network may be slow\n              * Solutions\n                * Skip a Validator\n            \n            * Voting Stages required for Block Commit\n              * Prevote \n                * Block Committed when 2/3+ of Validators Precommit for the same Block in the same Round.\n                * \"Polka\" occurs when 2/3+ of Validators Prevote for the same Block\n              * Precommit\n                * Precommitted Blocks by a Validator are \"Locked\" on the Block and then must Prevote for the Block it is \"Locked\" on\n                * Validators may only \"Unlock\" and Precommit for a New Block if there is a \"Polka\" for the New Block in a later Round\n                * Precommits must be justified by a \"Polka\" in the same Round\n\n            * Nodes\n              * Non-Active Validators \n                * No Validator Private Key\n                * Relays to Peers any Consensus Process information (i.e. meta-data, Proposals, Blocks, and Votes)\n                * State (Current `H`, `R`, `S`)\n                * Enable other Nodes to progress forward\n              * Active Validator (aka \"Validator-Node\")\n                * Validator Private Keys\n                * Signs Votes\n                * State (Current `H`, `R`, `S`)\n                * Enable other Nodes to progress forward\n\n            * Stake\n              * Validator \"Weight\" varies in the Consensys Protocol of some systems\n                * Voting Power Proportion may not be uniformly distributed across individual Validators \n              * Tendermint allows for creation of Proof-of-Stake systems through definition of a native Currency that denominates Voting Power. Cosmos Network is designed using this PoS mechanism across an array of cryptocurrencies implemented as ABCI Applications\n                * Validators \"bond\" their Voting Power Currency holdings in a security deposit that may be destroyed if found to misbehave in the Consensys Protocol, which quantifies an economic security element whereby the Cost of Violating the assumption that 2/3- of Voting Power is Byzantine \n\n          * Proofs\n\n            * Proof of Safety\n              * Assuming -1/3 (less than 1/3) of Validators voting power are Byzantine\n              * Validators may commit Block `B` at Round `R` after observing +2/3 (over 2/3) of Precommits at Round `R`\n              * Unlikely for 1/3+ (over 1/3) of Honest Nodes Locked at Round `R' \u003e R` to remain so until they observe PoLC at `R' \u003e R`\n              * -2/3 (less than 2/3) are available to Vote for anything other than Block `B`\n              since 1/3+ (over 1/3) are Locked and Honest Nodes\n              * CONFUSING?\n            \n            * Proof of Liveness\n              * Assuming 1/3+ (over 1/3) of Validators are Locked on 2x different Blocks from different Rounds\n              then a Proposer's `PoLC-Round` will Unlock Nodes that were Locked in previous Rounds\n              * Proposer (designated) will become aware of a PoLC in a subsequent Round \n              * `timeoutProposalR` increments with Round `R` whilst Proposal size is capped, so network eventually is able to fully gossip the whole Proposal (both Block and PoLC)\n\n            * TODO\n              * Proof of Fork Accountability - https://github.com/tendermint/tendermint/wiki/Byzantine-Consensus-Algorithm#proof-of-fork-accountability\n              * Alternative Algorithm - https://github.com/tendermint/tendermint/wiki/Byzantine-Consensus-Algorithm#alternative-algorithm\n              * Censorship Attacks - https://github.com/tendermint/tendermint/wiki/Byzantine-Consensus-Algorithm#censorship-attacks\n              * Overcoming Forks and Censorship Attacks - https://github.com/tendermint/tendermint/wiki/Byzantine-Consensus-Algorithm#overcoming-forks-and-censorship-attacks\n\n    * Benefits:\n      * Speed\n        * Tendermint blocks can commit to finality in the order of 1 second\n        * TendermintCore can handle transaction volume at the rate of 10,000 transactions per second for 250 byte transactions.\n      * Security\n        * Tendermint consensus is optimally BFT with accountability since liability may be determined when the blockchain forks\n      * Scalability\n        * Tendermint may be used for Sharding since it allows running parallel blockchains in parallel without the speed or security of each chain diminishing (unlike with PoW)  \n        * Tendermint algorithm can scale to hundreds or thousands of validators (depending on desired block times), and improves over time with advances in bandwidth and CPU capacity.\n\n  * Tendermint Generic Application BlockChain \"Interface\" (ABCI) is an API between Application Process and Consensus Process. ABCI has a Tendermint Socket Protocol (TSP aka Teaspoon) Implementation:\n    * Run in separate Unix processes.\n    * De-coupling (abstracting away) the Application State Details of a particular blockchain Application (using a socket protocol) from the Tendermint Core (consensus engine and P2P layers) to avoid a \"monolithic\" blockchain \"stack\" design so not limited to just using language of the blockchain stack that compile down to say the Turing-complete bytecode of the Ethereum Virtual Machine (EVM) (i.e. Serpent, Solidity)\n    * Allows BFT replication of applications with Transactions processed in any programming language\n    * Security guarantees\n    * ABCI has 3x Primary Message Types (delivered from Tendermint Core to the ABCI, then ABCI replies with response messages)\n      * DeliverTx Message\n        * Transactions on the blockchain are delivered with it\n        * Validation of Transactions received with the DeliverTx message must be validated by the Application against the current State, Application Protocol, and Transaction's Cryptographic Credentials\n        * Valid Transactions update the Application State (i.e binding a value in a KV Store or updating the UTXO DB)\n      * CheckTx Message\n        * Only for Validating Transactions\n        * Validates Transaction using Tendermint Core's Mempool\n        * Only Relays Valid Transactions to Peers\n        * Invalid Transactions may be caused if a Capabilities Based System is used but they have not renewed their capabilities with each Transaction, or CheckTx in an Application may return an error if a sequence number in a Transaction was not incremented\n      * Commit Message\n        * Computes the Cryptographic Commitment to the current Application State to be inserted into Next Block Header\n        * Inconsistencies and errors in updating State appear as Blockchain Forks \n        * Secure Lightweight Client development is simplified since Merkle-Hash Proofs may be Verified against the Block Hash, which is Signed by a Quorum\n    * Applications may have Multiple ABCI Socket Connections (3x created by Tendermint Core), including (see Diagram in https://tendermint.readthedocs.io/en/master/introduction.html#intro-to-abci):\n      * Connection 1: Validates Transactions when broadcasting in the Mempool\n      * Connection 2: Consensus Engine to run Block Proposals\n      * Connection 3: Querying the Application State\n\n    * Application Logic Deterministic\n      * Transaction processing on blockchain must be Deterministic so Consensus is reached among Tendermint Core replica Nodes\n      * Blockchain Developers should avoid Non-Determinism by using Linters and Static Analysers:\n        * Avoid Random Number Generators without Deterministic Seeding\n        * Avoid Race Conditions on threads\n        * Avoid use of System Clock \n        * Avoid Uninitialised Memory (in Unsafe languages like C or C++)\n        * Avoid Floating Point Arithmetic\n        * Avoid Random Language Features \n\n  * Communication between TendermintCore and Tendermint Applications\n    * TMSP (Simple Messaging Protocol)\n\n# References \u003ca id=\"chapter-14\"\u003e\u003c/a\u003e\n\n* Tendermint\n  * TendermintCore Wiki - https://github.com/tendermint/tendermint/wiki/\n  * Application Developers Guide - https://github.com/tendermint/tendermint/wiki/Application-Developers\n  * Byzantine Consensus Algorithm - https://github.com/tendermint/tendermint/wiki/Byzantine-Consensus-Algorithm\n  * Tendermint Documentation - https://tendermint.readthedocs.io/en/master/getting-started.html\n  * Tendermint Documentation Release - https://media.readthedocs.org/pdf/tendermint/master/tendermint.pdf\n  * Tendermine: BFT in the Age of Blockchains - https://allquantor.at/blockchainbib/pdf/buchman2016tendermint.pdf\n  * Cosmos usage of Tendermint\n    * https://cosmos.network/about/whitepaper\n    * https://cosmos.network/about/faq\n  * Merkle Tree Proof Calculation and Checking - https://github.com/yosriady/merkle_tree\n\n* Erlang \n  * Erlang Standard Library - http://erlang.org/doc/apps/stdlib/index.html\n\n# Unsorted Notes \u003ca id=\"chapter-15\"\u003e\u003c/a\u003e\n\n```\ncd $GOPATH/src/github.com/tendermint/tendermint\ngit tag -l\ngit checkout v0.14.0\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fltfschoen%2Ftendermint-elixir","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fltfschoen%2Ftendermint-elixir","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fltfschoen%2Ftendermint-elixir/lists"}