From 1f617e07d491f36efcbdba9a800e0e4478a9e063 Mon Sep 17 00:00:00 2001 From: Nedelcho Delchev Date: Thu, 19 Oct 2017 17:51:46 +0300 Subject: [PATCH 1/2] [GH-#60] Miner now goes through cycles --- apps/aecore/lib/aecore/miner/worker.ex | 32 ++++++++++++++--------- apps/aecore/lib/aecore/pow/hashcash.ex | 18 ++++++++----- apps/aecore/test/aecore_hashcash_test.exs | 3 ++- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/apps/aecore/lib/aecore/miner/worker.ex b/apps/aecore/lib/aecore/miner/worker.ex index 36bb5203..b29a20e3 100644 --- a/apps/aecore/lib/aecore/miner/worker.ex +++ b/apps/aecore/lib/aecore/miner/worker.ex @@ -16,6 +16,8 @@ defmodule Aecore.Miner.Worker do alias Aecore.Txs.Pool.Worker, as: Pool @coinbase_transaction_value 100 + @number_of_cycles 10 + @nonce_per_cycle 100000 def start_link() do GenStateMachine.start_link(__MODULE__, %{}, name: __MODULE__) @@ -42,7 +44,7 @@ defmodule Aecore.Miner.Worker do def idle({:call, from}, :start, data) do IO.puts("Mining resuming by user") GenStateMachine.cast(__MODULE__, :mine) - {:next_state, :running, data, [{:reply, from, :ok}]} + {:next_state, :running, 0, [{:reply, from, :ok}]} end def idle({:call, from}, :suspend, data) do @@ -62,10 +64,10 @@ defmodule Aecore.Miner.Worker do end ## Running ## - def running(:cast, :mine, data) do - mine_next_block() + def running(:cast, :mine, start_nonce) do + {_, next_nonce} = mine_next_block(start_nonce) GenStateMachine.cast(__MODULE__, :mine) - {:next_state, :running, data} + {:next_state, :running, next_nonce} end def running({:call, from}, :get_state, _data) do @@ -103,8 +105,8 @@ defmodule Aecore.Miner.Worker do def coinbase_transaction_value, do: @coinbase_transaction_value ## Internal - @spec mine_next_block() :: :ok | :error - defp mine_next_block() do + @spec mine_next_block(integer()) :: :ok | :error + defp mine_next_block(start_nonce) do chain_state = Chain.chain_state() txs_list = Map.values(Pool.get_and_empty_pool()) @@ -139,13 +141,17 @@ defmodule Aecore.Miner.Worker do Block.current_block_version() ) - {:ok, mined_header} = Hashcash.generate(unmined_header) + {status, mined_header} = Hashcash.generate(unmined_header, start_nonce + @nonce_per_cycle) block = %Block{header: mined_header, txs: valid_txs} - - Logger.info(fn -> - "Mined block ##{block.header.height}, difficulty target #{block.header.difficulty_target}, nonce #{block.header.nonce}" - end) - - Chain.add_block(block) + if(status == :ok) do + Chain.add_block(block) + + Logger.info(fn -> + "Mined block ##{block.header.height}, difficulty target #{block.header.difficulty_target}, nonce #{block.header.nonce}" + end) + {:block_found, 0} + else + {:no_block_found, start_nonce + @nonce_per_cycle} + end end end diff --git a/apps/aecore/lib/aecore/pow/hashcash.ex b/apps/aecore/lib/aecore/pow/hashcash.ex index 1006ac4b..c4e26eab 100644 --- a/apps/aecore/lib/aecore/pow/hashcash.ex +++ b/apps/aecore/lib/aecore/pow/hashcash.ex @@ -27,13 +27,17 @@ defmodule Aecore.Pow.Hashcash do @doc """ Find a nonce """ - @spec generate(map()) :: {:ok, %Aecore.Structures.Header{}} | {:error, term()} - def generate(%Aecore.Structures.Header{nonce: nonce} = block_header) do + @spec generate(map(), integer()) :: {:ok, %Aecore.Structures.Header{}} | {:error, term()} + def generate(%Aecore.Structures.Header{nonce: nonce} = block_header, start_nonce) do block_header_hash = BlockValidation.block_header_hash(block_header) - - case verify(block_header_hash, block_header.difficulty_target) do - true -> {:ok, block_header} - false -> generate(%{block_header | nonce: nonce + 1}) - end + case verify(block_header_hash, block_header.difficulty_target) do + true -> {:ok, block_header} + false -> + if(nonce <= start_nonce) do + generate(%{block_header | nonce: nonce + 1}, start_nonce) + else + {:error, :no_solution_found} + end + end end end diff --git a/apps/aecore/test/aecore_hashcash_test.exs b/apps/aecore/test/aecore_hashcash_test.exs index 709bb6bc..6200cdab 100644 --- a/apps/aecore/test/aecore_hashcash_test.exs +++ b/apps/aecore/test/aecore_hashcash_test.exs @@ -7,7 +7,8 @@ defmodule HashcashTest do @tag timeout: 10000000 test "successfull test" do - assert {:ok, mined_header} = Hashcash.generate(Block.genesis_block.header) + start_nonce = 0 + assert {:ok, mined_header} = Hashcash.generate(Block.genesis_block.header, start_nonce) assert :true = Hashcash.verify(mined_header) end end From 0e0292e2bc001e26136cb0e17b07a3fd56bee511 Mon Sep 17 00:00:00 2001 From: Nedelcho Delchev Date: Thu, 19 Oct 2017 18:35:40 +0300 Subject: [PATCH 2/2] [GH-#60] Refactoring the code --- apps/aecore/lib/aecore/miner/worker.ex | 25 ++++++++++++------------- apps/aecore/lib/aecore/pow/hashcash.ex | 2 +- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/apps/aecore/lib/aecore/miner/worker.ex b/apps/aecore/lib/aecore/miner/worker.ex index b29a20e3..ae066e06 100644 --- a/apps/aecore/lib/aecore/miner/worker.ex +++ b/apps/aecore/lib/aecore/miner/worker.ex @@ -16,7 +16,6 @@ defmodule Aecore.Miner.Worker do alias Aecore.Txs.Pool.Worker, as: Pool @coinbase_transaction_value 100 - @number_of_cycles 10 @nonce_per_cycle 100000 def start_link() do @@ -41,7 +40,7 @@ defmodule Aecore.Miner.Worker do end ## Idle ## - def idle({:call, from}, :start, data) do + def idle({:call, from}, :start, _data) do IO.puts("Mining resuming by user") GenStateMachine.cast(__MODULE__, :mine) {:next_state, :running, 0, [{:reply, from, :ok}]} @@ -141,17 +140,17 @@ defmodule Aecore.Miner.Worker do Block.current_block_version() ) - {status, mined_header} = Hashcash.generate(unmined_header, start_nonce + @nonce_per_cycle) - block = %Block{header: mined_header, txs: valid_txs} - if(status == :ok) do - Chain.add_block(block) - - Logger.info(fn -> - "Mined block ##{block.header.height}, difficulty target #{block.header.difficulty_target}, nonce #{block.header.nonce}" - end) - {:block_found, 0} - else - {:no_block_found, start_nonce + @nonce_per_cycle} + case Hashcash.generate(unmined_header, start_nonce + @nonce_per_cycle) do + {:ok, mined_header} -> + block = %Block{header: mined_header, txs: valid_txs} + Chain.add_block(block) + Logger.info(fn -> + "Mined block ##{block.header.height}, difficulty target #{block.header.difficulty_target}, nonce #{block.header.nonce}" + end) + {:block_found, 0} + + {:error, _message} -> + {:no_block_found, start_nonce + @nonce_per_cycle} end end end diff --git a/apps/aecore/lib/aecore/pow/hashcash.ex b/apps/aecore/lib/aecore/pow/hashcash.ex index c4e26eab..2f439b8a 100644 --- a/apps/aecore/lib/aecore/pow/hashcash.ex +++ b/apps/aecore/lib/aecore/pow/hashcash.ex @@ -36,7 +36,7 @@ defmodule Aecore.Pow.Hashcash do if(nonce <= start_nonce) do generate(%{block_header | nonce: nonce + 1}, start_nonce) else - {:error, :no_solution_found} + {:error, "no solution found"} end end end