- Anurag Patil
- Pratik Kamble
- Bitcoins are the most popular crypto-currency in common use.
- At their heart, bitcoins use the hardness of cryptographic hashing to ensure a limited “supply” of coins.
- In particular, the key component in a bit-coin is an input that, when “hashed” produces an output smaller than a target value.
- In practice, the comparison values have leading 0’s, thus the bitcoin is required to have a given number of leading 0’s
- The goal of this first project is to use Erlang and the Actor Model to build a good solution to this problem that runs well on multi-core machines.
- Input: The input provided will be, the required number of 0’s of the bitcoin.
- Output: Print, on independent entry lines, the input string, and the correspondingSHA256 hash separated by a TAB, for each of the bitcoins you find. Obviously, your SHA256 hash must have the required number of leading 0s. An extra requirement, to ensure every group finds different coins, is to have the input string prefixed by the gator link ID of one of the team members.
- Clone this repository and install erlang.
- This project has 3 implementations :
- Serialized Computation
- Distributed Implementation
- Client-Server-Actor-Model
-
Serialized Computation:
-
This implementation performs the bitcoin mining serially without any parallelism. The machine mine bitcoin on a specified range using single core.
-
This directory has only one file mining.erl
-
To run this code use the following commands:
- cd Serialized Computation
- erl
- c(mining).
- mining:start().
- Enter the number of zeroes desired.
- 4
- To stop the program, press Ctrl + C.
-
-
Distributed Implementation [static number of actors]:
-
This implementation performs bitcoin mining by mentioning a static number of actors and distributing range of strings to get the corresponding SHA. The server is spawned, and it creates 5 actors statically. These actors mine the bitcoin for giver string on a pre specified range.
-
This directory has 2 files client.erl and server.erl
-
To run this code use the following commands:
- cd Distributed Implementation
- erl
- c(server).
- c(client).
- server:main().
- Enter the number of zeroes desired.
- 4
- To stop the program, press Ctrl + C.
-
-
Actor Model Client Server Implementation [Dynamic number of actors]: This implementation generates a dynamic number of actors chosen from a Gaussian distribution of a 10,000 numbers. The program starts with the executor of the program submitting the required number of zeros to be present in the address of the mined coin. Later, the selected number of actors are spawned by the server. These actors request a uniform distribution of numbers from the server to append to the GatorID string. This string is hashed using the SHA-256 algorithm and checked for the required amount of leading zeroes. If an actor finds a hash (address) that meets the requirement, it sends the address of the Bitcoin block to the server and continues its execution. This process of message transfer between the server and the corresponding actors is completely asynchronous. If an actor runs out of the numbers assigned to it by the server, then the same actor requests the server for a different range of numbers. Thus, this program DOES NOT terminate on its own. It needs to be stopped forcefully using a keyboard interrupt.
The required steps to execute the program are mentioned below.
-
Change the directory to 'Client-Server-Actor-Model'. This directory has 2 files client.erl and server.erl
-
To run this code use the following commands:
- cd Client-Server-Actor-Model
- erl
- c(server).
- c(client).
- Enter the number of zeroes as a parameter to the main function
- server:main(4).
- To stop the program, press Ctrl + C.
-
-
Size of Work Unit :
- The Size of work unit was 1000000000 strings that each actors compute.
- When a client is free, it requests server for work. Server assigns a block of 1000000000 strings to the client.
- We determined the size of work unit on basis of following reasons:
- The Activity Monitor below that 7 Threads were used during the Actor Model Implementation:

- We ran the program on 2 machines. One Macbook Air, M1 Processor with 8 core CPU and One Lenovo Legion with intel i7 processor with 8 cores. Checking the Activity monitor of both the machines, on various work unit sizes, helped us move to a decision.
- Running more than 7 threads on 8 core machines, each thread had 142857142 strings to compute.
- Running the implementations as mentioned above, we got a clear idea of the load on single core and the affect of adding actors and running them parallelly.
- The Activity Monitor below that 7 Threads were used during the Actor Model Implementation:
-
The result of running your program for input 4
> server:main(4).
ok
Actor ID: <0.95.0> Output: "a.patil:2007383" "0000a12895ccd9feefb8639c5b4e834380395f907c9f3d12927ee4c538b02f54"
Actor ID: <0.98.0> Output: "a.patil:8011357" "000004e29805e12006c1f82c290101ad17ff37347aa2b700efc08191d194a9da"
Actor ID: <0.97.0> Output: "a.patil:6014388" "00009495e7696c5a5ad48e407eeda57565e42b7a5967fcbe3391831d60266b8e"
Actor ID: <0.95.0> Output: "a.patil:2037416" "00005d75694934ffa3a44f36d60066f5cd1155554fd91584334312e8c90a23f9"
Actor ID: <0.94.0> Output: "a.patil:46211" "00009ec91fc74c0fdc949b50778ea79314cface6495d0fb158e02c712c5d31fc"
Actor ID: <0.99.0> Output: "a.patil:10046835" "0000a921c1efdbbf85402e186b2d91b70afeb055742708ff26114be1266a35dd"
Actor ID: <0.99.0> Output: "a.patil:10052754" "0000f45b00ab05f995d7c1d6d21b95034379029a2e9ac22611e25fa427d79bdc"
Actor ID: <0.97.0> Output: "a.patil:6065694" "0000e28568389a145d02a9ffd5eac9914f3b825516ab015994a4780289b73b72"
Actor ID: <0.96.0> Output: "a.patil:4073180" "0000dd779fe65ef3a2217f71c8c10cb4c443631199fa9b4276e31d676eb8fd64"
Actor ID: <0.99.0> Output: "a.patil:10079524" "000069a10eb3cad15b33eccc89b46033c9f2d64373782ef7a7b63dd1d778f259"
Actor ID: <0.97.0> Output: "a.patil:6078994" "000091cc9625b2b9f2bd2b18c3d5fe550dee09caffd6ae37c3dbcb9f53edeeeb"
Actor ID: <0.99.0> Output: "a.patil:10092022" "00009b7043678c40413f72e974ec242d90e88e3f432aa321c2e12a560511718c"
Actor ID: <0.95.0> Output: "a.patil:2113496" "000019f987deba44690b414d80e9b15ed348ea68bf6de2c5fcc14412c1618357"
Actor ID: <0.95.0> Output: "a.patil:2124212" "0000ca6a5d315addbd445f7228ae26be91b8dad5a414a234ce2b84fae05ae137"
Actor ID: <0.98.0> Output: "a.patil:8133489" "000048b5116735535c765473b8d6670388b74730f432ae049b0e3d458dd772d9"
Actor ID: <0.98.0> Output: "a.patil:8134402" "0000ffc94db2b447591b036ba065d052f5ed5bbc7b26541fd39cfc8c3a1719b0"
Actor ID: <0.96.0> Output: "a.patil:4176024" "0000dfe70aa3a49a31aa2dfee73d175b5e7ae1a4da7224b6e5bcf17522e4a624"
Actor ID: <0.98.0> Output: "a.patil:8239919" "00004071215c4a5bea9e7ff10999564ad24bdb098772e8ce7e86354bf1bd4cea"
Actor ID: <0.94.0> Output: "a.patil:250848" "0000d8754e9130379be1d94b5e1bcdbedd33443dec7b99ae3f2448eb6a090fb7"
Actor ID: <0.94.0> Output: "a.patil:315024" "0000cb7f023b784c2896f68740c5cd803ef68ec632976a3b0ecc330dc0256420"
Actor ID: <0.97.0> Output: "a.patil:6339940" "0000c340fef3fa30fa7e406339b72902e2ce9f49e92a990cc968717b669571c5"
Actor ID: <0.98.0> Output: "a.patil:8344244" "000072ee9f6bced14efce9c972e1836924aeb37dd34e6b40985394ca25fe7ba3"
Actor ID: <0.97.0> Output: "a.patil:6362612" "000084ee38577334950c542fe0427f7f481fa0a255b98a33aa21117578469aee"
Actor ID: <0.97.0> Output: "a.patil:6378070" "000052f746ba53f6500945ece25c9997ae3dc1600004f09951bcc67b58315d11"
Actor ID: <0.98.0> Output: "a.patil:8380510" "0000c09666e09c71c54dcfa0c0c82650d8bd53ba2786aa2d5ecfb8fc9a171aeb"
Actor ID: <0.96.0> Output: "a.patil:4399275" "0000bbb0845bd7da19b4654167cb34dc94226623307a11dbf373587289797435"
Actor ID: <0.99.0> Output: "a.patil:10384535" "0000c9ef2e524c665e59141dc96a7d03ff1e33a0fbaf2ab69032d58f06a21f6b"
Actor ID: <0.95.0> Output: "a.patil:2422529" "000034f3d4907e5069b3cf112f1ca50568517f6ef436f786641b3381e35ebae3"
Actor ID: <0.94.0> Output: "a.patil:420397" "00005d5b28db0138e3652697a88b53b348603d1821f995592e43fe03bdeb9686"
Actor ID: <0.96.0> Output: "a.patil:4440468" "0000e28eedb2c24f10994002d3159ac96574836620cbd49071269ad520c6c3ff"
Actor ID: <0.97.0> Output: "a.patil:6433940" "0000e77071d42385dddad1a13f4c45c972b9ae0886461400d299ad9e419a3578"
Actor ID: <0.99.0> Output: "a.patil:10429404" "000097691c7759bf5b403bfa8fc73709fb45053472b7bb78805dd96c1b061f7b"
Actor ID: <0.96.0> Output: "a.patil:4455669" "0000f423927506f1d9f7297c60525ed4ba13df7549953c5deb41fa4b3c7da7bd"
Actor ID: <0.95.0> Output: "a.patil:2469313" "0000f5e630151504af293138b4c0d5216a5742518b73d93b137be77369f08bd4"
Actor ID: <0.95.0> Output: "a.patil:2479914" "000089a34a0df63593aee0f58c661590fb230f3c395f34c1f3fd926a120e0108"
Actor ID: <0.97.0> Output: "a.patil:6467315" "00006c6d49cc1e40652a7b00d2abda40cc4c9031bdb1420b7b8c95059bb814fd"
Actor ID: <0.94.0> Output: "a.patil:463840" "0000345b334b3c1b81d35423ae05773ab80092e7d70931355e5f3cfed2a31d1d"
Actor ID: <0.94.0> Output: "a.patil:481211" "0000648a95b35f7e69c9c674b692167b0219dc283bc7eadaa2e5840c1ac88688"
Actor ID: <0.94.0> Output: "a.patil:493076" "000085f8d0519ceb3d0bbdb881ae8f9359e985a1de6844927a2699d0ffa8a452"
Actor ID: <0.95.0> Output: "a.patil:2512867" "0000fee2dc588d14a7d9f7143a3a01892f977958af70696c4a03ca5c0dd028ac"
Actor ID: <0.97.0> Output: "a.patil:6503056" "0000c9d6d84576df7b0d13218d10670431df27e4e66f41948ea97a541d3c9c9c"
Actor ID: <0.94.0> Output: "a.patil:503689" "0000ea14f22d85e4a9e5039c41d8622ef17a168d2f3032bf1ea6ff5f77142fe4"
Actor ID: <0.96.0> Output: "a.patil:4546256" "0000d5a90a4743ad61cf402f6fdbc960e4039cc222f1c21be6f003ff050acc6b"
-
We ran the hash miner for 5 leading zeroes and recorded the time for serialized and actor model implementation. Please refer to the following screenshots:
- Time for Serial Implementation : 4ms

- Time for Actor Model Implementation for 350 actors working asynchronously: ~1ms
- Time for Serial Implementation : 4ms
-
The ratio of CPU time to REAL TIME tells you how many cores were effectively used in the computation.
- CPU time [Single-Core Serialized Model]= 4ms
- Real time [Multicore Actor Model]= = ~1ms = 1ms
- Absolute Ratio = CPU Time / Real Time = 4/1 = 4
-
The Multicore distributed asynchronous model was executed on 2 machines, where one machine acted as a server, while the other acted as a client.



