README

GoDoc License Build Status Go Report Card Coverage Statusd Sourcegraph

BDLS Consensus

Introduction

BDLS is an innovative BFT consensus algorithm that features safety and liveness by presenting a mathematically proven secure BFT protocol that is resilient in open networks such as the Internet. With BDLS, we invented a new random beacons to ensure verifiable unpredictability and fairness of validators. More importantly, BDLS overcomes many problems, such as DoS attacks, as well as the deadlock problem caused by unreliable p2p/broadcast channels. These problems are all very relevant to existing realistic open network scenarios, and are the focus of extensive work in improving Internet security, but it is an area largely ignored by most in mainstream BFT protocol design.(Paper: https://eprint.iacr.org/2019/1460.pdf)

For this library, to make the runtime behavior of consensus algorithm predictable as function: y = f(x, t), where 'x' is the message it received, and 't' is the time while being called, then'y' is the deterministic status of consensus after 'x' and 't' applied to 'f', it has been designed in a deterministic scheme, without parallel computing, networking, and the correctness of program implementation can be proven with proper test cases.

For more information on the BDLS consensus, you could view here https://medium.com/sperax/bdls-protocol-best-efficiency-best-security-best-performance-4cc2770608dd

Features

  1. Pure algorithm implementation in deterministic and predictable behavior, easily to be integrated into existing projects, refer to DFA for more.
  2. Well-tested on various platforms with complicated cases.
  3. Auto back-off under heavy payload, guaranteed finalization(worst case gurantee).
  4. Easy integratation into Blockchain & non-Blockchain consensus, like WAL replication in database.
  5. Builtin network emulation for various network latency with comprehensive statistics.

Documentation

For complete documentation, see the associated Godoc.

Performance

DATE: 2020/03/18
OS: Linux 4.19.84-microsoft-standard #1 SMP Wed Nov 13 11:44:37 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
MEM: 64GB
CPU: AMD Ryzen 7 2700X Eight-Core Processor

TERMINOLOGY: 

DECIDE.AVG = Average finalization time for each height.
DECIDE.ROUNDS = The rounds where decides has made.
PEER.NUM = Actual participantion.
PJ.NUM = Participants(Quorum) 
NET.MSGS = Total network number of messages exchanged in all heights.
NET.BYTES = Total network bytes exchanged in all heights.
MSG.AVGSIZE = Average message size.(Tested with 1KB State.)
NET.MSGRATE = Network message rate(messages/second).
PEER.RATE = Peer's average bandwidth.
DELAY.MIN = Actual minimal network latency(network latency is randomized with normal distribution).
DELAY.MAX = Actual maximal network latency.
DELAY.AVG = Actual average latency.
DELAY.EXP = Expected Latency set to consensus algorithm.

COMMANDS:
$ go test -v -cpuprofile=cpu.out -memprofile=mem.out -timeout 2h

TESTING CASES:
=============

Case 1: 20 Fully Connected Participants in 100ms,200ms,300ms,500ms,1s correctly set expected delay
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| DECIDE.AVG | DECIDE.ROUNDS | PEER.NUM | PJ.NUM | NET.MSGS | NET.BYTES | MSG.AVGSIZE | NET.MSGRATE | PEER.RATE | DELAY.MIN | DELAY.MAX | DELAY.AVG | DELAY.EXP |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| 1.47s      | 1;1;1;1;1     | 20       | 20     | 9765     | 16.1M     | 1.7K        | 66.32/s     | 110.1K/s  | 59.61ms   | 135.47ms  | 100.02ms  | 100ms     |
| 2.3s       | 1;1;1;1;1     | 20       | 20     | 9756     | 16.2M     | 1.7K        | 42.31/s     | 70.6K/s   | 121.64ms  | 273.65ms  | 200.12ms  | 200ms     |
| 3.11s      | 1;1;1;1;1     | 20       | 20     | 9758     | 15.9M     | 1.7K        | 31.30/s     | 50.9K/s   | 177.7ms   | 421.95ms  | 300.04ms  | 300ms     |
| 4.76s      | 1;1;1;1;1     | 20       | 20     | 9756     | 15.9M     | 1.7K        | 20.48/s     | 33.4K/s   | 308.55ms  | 674.98ms  | 499.04ms  | 500ms     |
| 8.85s      | 1;1;1;1;1     | 20       | 20     | 9753     | 15.8M     | 1.7K        | 11.02/s     | 17.8K/s   | 638.02ms  | 1.38348s  | 999.99ms  | 1s        |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+

Case 2: 30 Fully Connected Participants in 100ms,200ms,300ms,500ms,1s correctly set expected delay
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| DECIDE.AVG | DECIDE.ROUNDS | PEER.NUM | PJ.NUM | NET.MSGS | NET.BYTES | MSG.AVGSIZE | NET.MSGRATE | PEER.RATE | DELAY.MIN | DELAY.MAX | DELAY.AVG | DELAY.EXP |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| 1.53s      | 1;1;1;1;1     | 30       | 30     | 22152    | 36.2M     | 1.7K        | 96.17/s     | 156.5K/s  | 55.18ms   | 141.39ms  | 100.09ms  | 100ms     |
| 2.33s      | 1;1;1;1;1     | 30       | 30     | 22152    | 36.3M     | 1.7K        | 63.23/s     | 104.2K/s  | 125.74ms  | 275.21ms  | 199.87ms  | 200ms     |
| 3.14s      | 1;1;1;1;1     | 30       | 30     | 22137    | 36.2M     | 1.7K        | 46.90/s     | 76.7K/s   | 176.14ms  | 415.37ms  | 300.16ms  | 300ms     |
| 4.75s      | 1;1;1;1;1     | 30       | 30     | 22136    | 35.9M     | 1.7K        | 31.03/s     | 50.3K/s   | 317.97ms  | 695.47ms  | 499.76ms  | 500ms     |
| 8.9s       | 1;1;1;1;1     | 30       | 30     | 22135    | 36M       | 1.7K        | 16.57/s     | 26.9K/s   | 532.09ms  | 1.34651s  | 1.00002s  | 1s        |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+

Case 3: 50 Fully Connected Participants in 100ms,200ms,300ms,500ms,1s correctly set expected delay
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| DECIDE.AVG | DECIDE.ROUNDS | PEER.NUM | PJ.NUM | NET.MSGS | NET.BYTES | MSG.AVGSIZE | NET.MSGRATE | PEER.RATE | DELAY.MIN | DELAY.MAX | DELAY.AVG | DELAY.EXP |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| 1.82s      | 1;1;1;1;1     | 50       | 50     | 59819    | 104.3M    | 1.8K        | 131.20/s    | 227.1K/s  | 56.7ms    | 137.95ms  | 99.91ms   | 100ms     |
| 2.59s      | 1;1;1;1;1     | 50       | 50     | 61951    | 102.9M    | 1.7K        | 95.61/s     | 155.7K/s  | 115.92ms  | 289.78ms  | 200.05ms  | 200ms     |
| 3.32s      | 1;1;1;1;1     | 50       | 50     | 61916    | 101.8M    | 1.7K        | 74.52/s     | 122.2K/s  | 170.95ms  | 421.28ms  | 300.02ms  | 300ms     |
| 4.9s       | 1;1;1;1;1     | 50       | 50     | 61905    | 101.6M    | 1.7K        | 50.50/s     | 82.8K/s   | 288.33ms  | 731.75ms  | 500.06ms  | 500ms     |
| 8.97s      | 1;1;1;1;1     | 50       | 50     | 61906    | 101.4M    | 1.7K        | 27.60/s     | 45.2K/s   | 570.08ms  | 1.42545s  | 1.00002s  | 1s        |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+

Case 4: 80 Fully Connected Participants in 100ms,200ms,300ms,500ms,1s correctly set expected delay
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| DECIDE.AVG | DECIDE.ROUNDS | PEER.NUM | PJ.NUM | NET.MSGS | NET.BYTES | MSG.AVGSIZE | NET.MSGRATE | PEER.RATE | DELAY.MIN | DELAY.MAX | DELAY.AVG | DELAY.EXP |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| 5.6s       | 2;2;1;2;2     | 80       | 80     | 267894   | 1.8G      | 7.1K        | 119.58/s    | 834.2K/s  | 53.01ms   | 150.23ms  | 99.9ms    | 100ms     |
| 3.13s      | 1;1;1;1;1     | 80       | 80     | 153622   | 278.2M    | 1.9K        | 122.58/s    | 217.2K/s  | 110.94ms  | 285.03ms  | 199.81ms  | 200ms     |
| 3.74s      | 1;1;1;1;1     | 80       | 80     | 156056   | 261.3M    | 1.7K        | 104.26/s    | 171.5K/s  | 164.08ms  | 429.22ms  | 299.94ms  | 300ms     |
| 5.24s      | 1;1;1;1;1     | 80       | 80     | 158652   | 260.2M    | 1.7K        | 75.64/s     | 122.2K/s  | 273.16ms  | 718.12ms  | 500.22ms  | 500ms     |
| 9.38s      | 1;1;1;1;1     | 80       | 80     | 159054   | 261M      | 1.7K        | 42.35/s     | 68.8K/s   | 553.89ms  | 1.44921s  | 1.00012s  | 1s        |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+

Case 5: 100 Fully Connected Participants in 100ms,200ms,300ms,500ms,1s correctly set expected delay
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| DECIDE.AVG | DECIDE.ROUNDS | PEER.NUM | PJ.NUM | NET.MSGS | NET.BYTES | MSG.AVGSIZE | NET.MSGRATE | PEER.RATE | DELAY.MIN | DELAY.MAX | DELAY.AVG | DELAY.EXP |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| 9.5s       | 2;2;3;2;2     | 100      | 100    | 505578   | 3.5G      | 7.3K        | 106.42/s    | 764.4K/s  | 52.3ms    | 145.48ms  | 99.92ms   | 100ms     |
| 7.43s      | 2;2;2;1;1     | 100      | 100    | 361084   | 2.3G      | 6.6K        | 97.18/s     | 626.3K/s  | 100.07ms  | 300.16ms  | 199.57ms  | 200ms     |
| 7.66s      | 1;2;1;2;1     | 100      | 100    | 330107   | 2G        | 6.3K        | 86.08/s     | 527.8K/s  | 167.46ms  | 444.85ms  | 299.79ms  | 300ms     |
| 5.78s      | 1;1;1;1;1     | 100      | 100    | 241856   | 404.4M    | 1.7K        | 83.56/s     | 136.7K/s  | 239.32ms  | 736.61ms  | 499.73ms  | 500ms     |
| 9.54s      | 1;1;1;1;1     | 100      | 100    | 248825   | 409.1M    | 1.7K        | 52.12/s     | 85.2K/s   | 560.41ms  | 1.48048s  | 1.00002s  | 1s        |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------

Case 6: 20 Partially Connected Participants in 100ms,200ms,300ms,500ms,1s correctly set expected delay
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| DECIDE.AVG | DECIDE.ROUNDS | PEER.NUM | PJ.NUM | NET.MSGS | NET.BYTES | MSG.AVGSIZE | NET.MSGRATE | PEER.RATE | DELAY.MIN | DELAY.MAX | DELAY.AVG | DELAY.EXP |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| 2.59s      | 2;1;2;2;1     | 13       | 20     | 5016     | 8.2M      | 1.7K        | 29.79/s     | 49.6K/s   | 58.49ms   | 140.78ms  | 100ms     | 100ms     |
| 9.98s      | 1;2;3;4;2     | 13       | 20     | 6264     | 9.6M      | 1.6K        | 9.65/s      | 15.1K/s   | 118.56ms  | 269.81ms  | 200.2ms   | 200ms     |
| 7.2s       | 1;1;2;3;1     | 13       | 20     | 5016     | 8.2M      | 1.7K        | 10.72/s     | 17.8K/s   | 198.85ms  | 408.56ms  | 300.19ms  | 300ms     |
| 30.95s     | 5;2;1;1;1     | 13       | 20     | 5640     | 8.9M      | 1.6K        | 2.80/s      | 4.5K/s    | 304.56ms  | 663.24ms  | 499.11ms  | 500ms     |
| 23.43s     | 2;2;2;1;2     | 13       | 20     | 5328     | 8.6M      | 1.7K        | 3.50/s      | 5.7K/s    | 621.09ms  | 1.37182s  | 1.00037s  | 1s        |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+

Case 7: 30 Partially Connected Participants in 100ms,200ms,300ms,500ms,1s correctly set expected delay
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| DECIDE.AVG | DECIDE.ROUNDS | PEER.NUM | PJ.NUM | NET.MSGS | NET.BYTES | MSG.AVGSIZE | NET.MSGRATE | PEER.RATE | DELAY.MIN | DELAY.MAX | DELAY.AVG | DELAY.EXP |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| 24.06s     | 1;2;1;7;4     | 20       | 30     | 17381    | 25.7M     | 1.5K        | 7.22/s      | 10.9K/s   | 60.17ms   | 143.24ms  | 99.98ms   | 100ms     |
| 27.88s     | 2;6;2;1;4     | 20       | 30     | 17383    | 25.7M     | 1.5K        | 6.23/s      | 9.4K/s    | 123.31ms  | 269.15ms  | 200.06ms  | 200ms     |
| 15.14s     | 3;1;2;2;4     | 20       | 30     | 15101    | 23.1M     | 1.6K        | 9.97/s      | 15.6K/s   | 186.63ms  | 422.51ms  | 299.87ms  | 300ms     |
| 11.47s     | 3;1;1;2;1     | 20       | 30     | 12060    | 19.7M     | 1.7K        | 10.51/s     | 17.4K/s   | 307.34ms  | 682.54ms  | 499.59ms  | 500ms     |
| 44.77s     | 3;2;4;1;2     | 20       | 30     | 15100    | 23.1M     | 1.6K        | 3.37/s      | 5.3K/s    | 622.36ms  | 1.34913s  | 999.89ms  | 1s        |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+

Case 8: 50 Partially Connected Participants in 100ms,200ms,300ms,500ms,1s correctly set expected delay
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| DECIDE.AVG | DECIDE.ROUNDS | PEER.NUM | PJ.NUM | NET.MSGS | NET.BYTES | MSG.AVGSIZE | NET.MSGRATE | PEER.RATE | DELAY.MIN | DELAY.MAX | DELAY.AVG | DELAY.EXP |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| 6.23s      | 4;3;3;1;1     | 33       | 50     | 41680    | 65M       | 1.6K        | 40.50/s     | 64.2K/s   | 55.59ms   | 139.67ms  | 100.03ms  | 100ms     |
| 10.51s     | 2;1;4;4;1     | 33       | 50     | 41664    | 64.4M     | 1.6K        | 24.02/s     | 37.8K/s   | 117.5ms   | 290.2ms   | 199.97ms  | 200ms     |
| 15.37s     | 2;3;3;1;4     | 33       | 50     | 43776    | 66.8M     | 1.6K        | 17.25/s     | 26.8K/s   | 179.9ms   | 421.71ms  | 299.84ms  | 300ms     |
| 10.91s     | 2;1;2;2;1     | 33       | 50     | 33216    | 54.9M     | 1.7K        | 18.45/s     | 30.9K/s   | 303.06ms  | 713.69ms  | 500.5ms   | 500ms     |
| 38.8s      | 3;3;1;2;3     | 33       | 50     | 41664    | 64.4M     | 1.6K        | 6.51/s      | 10.2K/s   | 609.65ms  | 1.38302s  | 1.00107s  | 1s        |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+

Case 9: 80 Partially Connected Participants in 100ms,200ms,300ms,500ms,1s correctly set expected delay
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| DECIDE.AVG | DECIDE.ROUNDS | PEER.NUM | PJ.NUM | NET.MSGS | NET.BYTES | MSG.AVGSIZE | NET.MSGRATE | PEER.RATE | DELAY.MIN | DELAY.MAX | DELAY.AVG | DELAY.EXP |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| 5.25s      | 2;2;3;2;3     | 53       | 80     | 121369   | 520.3M    | 4.4K        | 87.18/s     | 377.5K/s  | 59.25ms   | 149.4ms   | 99.95ms   | 100ms     |
| 6s         | 1;2;2;2;2     | 53       | 80     | 91790    | 152.8M    | 1.7K        | 57.64/s     | 96.5K/s   | 120.06ms  | 286.27ms  | 199.98ms  | 200ms     |
| 5.87s      | 2;1;2;1;1     | 53       | 80     | 80728    | 138.1M    | 1.8K        | 51.84/s     | 88.6K/s   | 175.44ms  | 423.91ms  | 300.17ms  | 300ms     |
| 11.21s     | 2;1;2;1;2     | 53       | 80     | 86217    | 142.9M    | 1.7K        | 29.02/s     | 48.5K/s   | 291.37ms  | 734.8ms   | 500.38ms  | 500ms     |
| 21.97s     | 1;1;2;2;2     | 53       | 80     | 86216    | 142.9M    | 1.7K        | 14.80/s     | 24.9K/s   | 533.87ms  | 1.43307s  | 1.00042s  | 1s        |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+

Case 10: 100 Partially Connected Participants in 100ms,200ms,300ms,500ms,1s correctly set expected delay
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| DECIDE.AVG | DECIDE.ROUNDS | PEER.NUM | PJ.NUM | NET.MSGS | NET.BYTES | MSG.AVGSIZE | NET.MSGRATE | PEER.RATE | DELAY.MIN | DELAY.MAX | DELAY.AVG | DELAY.EXP |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| 8.92s      | 4;2;3;2;4     | 67       | 100    | 248185   | 1.7G      | 7K          | 82.99/s     | 577.1K/s  | 50.01ms   | 144ms     | 99.98ms   | 100ms     |
| 8.28s      | 2;2;3;2;3     | 67       | 100    | 175047   | 286.4M    | 1.7K        | 63.08/s     | 103.9K/s  | 116.41ms  | 287.7ms   | 199.87ms  | 200ms     |
| 10.21s     | 2;3;1;1;3     | 67       | 100    | 156156   | 279M      | 1.8K        | 45.63/s     | 81.9K/s   | 157.92ms  | 422.21ms  | 300.11ms  | 300ms     |
| 19.24s     | 1;4;1;2;1     | 67       | 100    | 146918   | 239M      | 1.7K        | 22.79/s     | 37.5K/s   | 289.88ms  | 705.65ms  | 500.13ms  | 500ms     |
| 38.13s     | 1;2;4;2;1     | 67       | 100    | 155760   | 248.7M    | 1.6K        | 12.19/s     | 19.8K/s   | 558.98ms  | 1.49546s  | 1.00018s  | 1s        |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+

Case 11: 50 Fully Connected Participants in 100ms,200ms,300ms,500ms,1s incorrectly set expected delay
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| DECIDE.AVG | DECIDE.ROUNDS | PEER.NUM | PJ.NUM | NET.MSGS | NET.BYTES | MSG.AVGSIZE | NET.MSGRATE | PEER.RATE | DELAY.MIN | DELAY.MAX | DELAY.AVG | DELAY.EXP |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| 2.9s       | 2;2;2;2;2     | 50       | 50     | 116591   | 438.1M    | 3.8K        | 160.49/s    | 605.2K/s  | 58.21ms   | 145.52ms  | 99.98ms   | 50ms      |
| 2.81s      | 1;1;2;1;1     | 50       | 50     | 81768    | 250.3M    | 3.1K        | 116.32/s    | 343.2K/s  | 98.55ms   | 281.13ms  | 199.73ms  | 100ms     |
| 3.61s      | 2;1;1;1;1     | 50       | 50     | 82816    | 219.3M    | 2.7K        | 91.68/s     | 239K/s    | 175.29ms  | 441.01ms  | 299.71ms  | 150ms     |
| 4.45s      | 1;1;1;1;1     | 50       | 50     | 73038    | 114.1M    | 1.6K        | 65.56/s     | 101.8K/s  | 287.19ms  | 743.13ms  | 500ms     | 250ms     |
| 7.99s      | 1;1;1;1;1     | 50       | 50     | 73225    | 114.2M    | 1.6K        | 36.62/s     | 56.9K/s   | 606.02ms  | 1.41356s  | 999.36ms  | 500ms     |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+

Case 12: 50 Partially Connected Participants in 100ms,200ms,300ms,500ms,1s incorrectly set expected delay
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| DECIDE.AVG | DECIDE.ROUNDS | PEER.NUM | PJ.NUM | NET.MSGS | NET.BYTES | MSG.AVGSIZE | NET.MSGRATE | PEER.RATE | DELAY.MIN | DELAY.MAX | DELAY.AVG | DELAY.EXP |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+
| 3.45s      | 2;2;3;3;3     | 33       | 50     | 50621    | 80.2M     | 1.6K        | 88.78/s     | 141.4K/s  | 58.45ms   | 141.37ms  | 100.02ms  | 50ms      |
| 8.49s      | 2;3;4;4;2     | 33       | 50     | 55392    | 119M      | 2.2K        | 39.54/s     | 86.3K/s   | 119.07ms  | 279.23ms  | 200.16ms  | 100ms     |
| 4.57s      | 1;1;2;2;2     | 33       | 50     | 42720    | 144.1M    | 3.5K        | 56.65/s     | 192.2K/s  | 174.43ms  | 422.48ms  | 300.09ms  | 150ms     |
| 8.04s      | 2;1;1;3;1     | 33       | 50     | 38497    | 60.9M     | 1.6K        | 28.99/s     | 46.3K/s   | 297.08ms  | 699.25ms  | 499.54ms  | 250ms     |
| 18.06s     | 1;2;3;2;1     | 33       | 50     | 40608    | 63.2M     | 1.6K        | 13.63/s     | 21.4K/s   | 595.42ms  | 1.45499s  | 1.00061s  | 500ms     |
+------------+---------------+----------+--------+----------+-----------+-------------+-------------+-----------+-----------+-----------+-----------+-----------+

See also overload benchmark: PI4-OVERLOAD.TXT

Specification

  1. Consensus messages are specified in message.proto, users of this library can encapsulate this message in a carrier message, like gossip in TCP.
  2. Consensus algorithm is NOT thread-safe, it MUST be protected by some synchronization mechanism, like sync.Mutex or chan + goroutine.

Usage

  1. A testing IPC peer -- ipc_peer.go
  2. A testing TCP node -- TCP based Consensus Emualtor

Status

GA

Expand ▾ Collapse ▴

Documentation

Overview

    Package bdls implements Sperax Byzantine Fault Tolerance in Partially Connected Asynchronous Networks based on https://eprint.iacr.org/2019/1460.pdf.

    To make the runtime behavior of consensus algorithm predictable, as a function: y = f(x, t), where 'x' is the message it received, and 't' is the time while being called, and 'y' is the deterministic status of consensus after 'x' and 't' applied to 'f', this library has been designed in a deterministic scheme, without parallel computing, networking, and current time is a parameter to this library.

    As it's a pure algorithm implementation, it's not thread-safe! Users of this library should take care of their own sychronziation mechanism.

    Index

    Constants

    View Source
    const (
    	// ProtocolVersion is the current BDLS protocol implementation version,
    	// version wil be sent along with messages for protocol upgrading.
    	ProtocolVersion = 1
    	// DefaultConsensusLatency is the default propagation latency setting for
    	// consensus protocol, user can adjust consensus object's latency setting
    	// via Consensus.SetLatency()
    	DefaultConsensusLatency = 300 * time.Millisecond
    
    	// MaxConsensusLatency is the ceiling of latencies
    	MaxConsensusLatency = 10 * time.Second
    )
    View Source
    const (
    	// SizeAxis defines byte size of X-axis or Y-axis in a public key
    	SizeAxis = 32
    	// SignaturePrefix is the prefix for signing a consensus message
    	SignaturePrefix = "BDLS_CONSENSUS_SIGNATURE"
    )
    View Source
    const (
    	// ConfigMinimumParticipants is the minimum number of participant allow in consensus protocol
    	ConfigMinimumParticipants = 4
    )

    Variables

    View Source
    var (
    	// Config Related
    	ErrConfigEpoch              = errors.New("Config.Epoch is nil")
    	ErrConfigStateNil           = errors.New("Config.CurrentState is nil")
    	ErrConfigStateCompare       = errors.New("Config.StateCompare function has not set")
    	ErrConfigStateValidate      = errors.New("Config.StateValidate function has not set")
    	ErrConfigPrivateKey         = errors.New("Config.PrivateKey has not set")
    	ErrConfigParticipants       = errors.New("Config.Participants must contain at least 4 participants")
    	ErrConfigPubKeyToCoordinate = errors.New("Config.must contain at least 4 participants")
    
    	// common errors related to every message
    	ErrMessageVersion            = errors.New("the message has different version")
    	ErrMessageValidator          = errors.New("the message has been rejected by external validator")
    	ErrMessageIsEmpty            = errors.New("the message being verified is empty")
    	ErrMessageUnknownMessageType = errors.New("unrecognized message type")
    	ErrMessageSignature          = errors.New("cannot verify the signature of this message")
    	ErrMessageUnknownParticipant = errors.New("the message is from unknown partcipants")
    
    	// <roundchange> related
    	ErrRoundChangeHeightMismatch  = errors.New("the <roundchange> message has another height than expected")
    	ErrRoundChangeRoundLower      = errors.New("the <roundchange> message has lower round than expected")
    	ErrRoundChangeStateValidation = errors.New("the state data validation failed <roundchange> message")
    
    	// <lock> related
    	ErrLockEmptyState              = errors.New("the state is empty in <lock> message")
    	ErrLockStateValidation         = errors.New("the state data validation failed <lock> message")
    	ErrLockHeightMismatch          = errors.New("the <lock> message has another height than expected")
    	ErrLockRoundLower              = errors.New("the <lock> message has lower round than expected")
    	ErrLockNotSignedByLeader       = errors.New("the <lock> message is not signed by leader")
    	ErrLockProofUnknownParticipant = errors.New("the proofs in <lock> message has unknown participant")
    	ErrLockProofTypeMismatch       = errors.New("the proofs in <lock> message is not <roundchange>")
    	ErrLockProofHeightMismatch     = errors.New("the proofs in <lock> message has mismatched height")
    	ErrLockProofRoundMismatch      = errors.New("the proofs in <lock> message has mismatched round")
    	ErrLockProofStateValidation    = errors.New("the proofs in <lock> message has invalid state data")
    	ErrLockProofInsufficient       = errors.New("the <lock> message has insufficient <roundchange> proofs to the proposed state")
    
    	// <select> related
    	ErrSelectStateValidation         = errors.New("the state data validation failed <select> message")
    	ErrSelectHeightMismatch          = errors.New("the <select> message has another height than expected")
    	ErrSelectRoundLower              = errors.New("the <select> message has lower round than expected")
    	ErrSelectNotSignedByLeader       = errors.New("the <select> message is not signed by leader")
    	ErrSelectStateMismatch           = errors.New("the <select> message has nil state but proof contains non-nil state")
    	ErrSelectProofUnknownParticipant = errors.New("the proofs in <select> message has unknown participant")
    	ErrSelectProofTypeMismatch       = errors.New("the proofs in <select> message is not <roundchange>")
    	ErrSelectProofHeightMismatch     = errors.New("the proofs in <select> message has mismatched height")
    	ErrSelectProofRoundMismatch      = errors.New("the proofs in <select> message has mismatched round")
    	ErrSelectProofStateValidation    = errors.New("the proofs in <select> message has invalid state data")
    	ErrSelectProofNotTheMaximal      = errors.New("the proposed state is not the maximal one in the <select> message")
    	ErrSelectProofInsufficient       = errors.New("the <select> message has insufficient overall proofs")
    	ErrSelectProofExceeded           = errors.New("the <select> message overall state proposals exceeded maximal")
    
    	// <decide> Related
    	ErrDecideHeightLower             = errors.New("the <decide> message has lower height than expected")
    	ErrDecideEmptyState              = errors.New("the state is empty in <decide> message")
    	ErrDecideStateValidation         = errors.New("the state data validation failed <decide> message")
    	ErrDecideNotSignedByLeader       = errors.New("the <decide> message is not signed by leader")
    	ErrDecideProofUnknownParticipant = errors.New("the proofs in <decide> message has unknown participant")
    	ErrDecideProofTypeMismatch       = errors.New("the proofs in <decide> message is not <commit>")
    	ErrDecideProofHeightMismatch     = errors.New("the proofs in <decide> message has mismatched height")
    	ErrDecideProofRoundMismatch      = errors.New("the proofs in <decide> message has mismatched round")
    	ErrDecideProofStateValidation    = errors.New("the proofs in <decide> message has invalid state data")
    	ErrDecideProofInsufficient       = errors.New("the <decide> message has insufficient <commit> proofs to the proposed state")
    
    	// <lock-release> related
    	ErrLockReleaseStatus = errors.New("received <lock-release> message in non LOCK-RELEASE state")
    
    	// <commit> related
    	ErrCommitEmptyState      = errors.New("the state is empty in <commit> message")
    	ErrCommitStateMismatch   = errors.New("the state in <commit> message does not match what leader has locked")
    	ErrCommitStateValidation = errors.New("the state data validation failed <commit> message")
    	ErrCommitStatus          = errors.New("received <commit> message in non COMMIT state")
    	ErrCommitHeightMismatch  = errors.New("the <commit> messge has another height than expected")
    	ErrCommitRoundMismatch   = errors.New("the <commit> message is from another round")
    
    	// <decide> verification
    	ErrMismatchedTargetState = errors.New("the state in <decide> message does not match the provided target state")
    )
    View Source
    var (
    	ErrInvalidLengthMessage        = fmt.Errorf("proto: negative length found during unmarshaling")
    	ErrIntOverflowMessage          = fmt.Errorf("proto: integer overflow")
    	ErrUnexpectedEndOfGroupMessage = fmt.Errorf("proto: unexpected end of group")
    )
    View Source
    var ErrPubKey = errors.New("incorrect pubkey format")

      ErrPubKey will be returned if error found while decoding message's public key

      View Source
      var MessageType_name = map[int32]string{
      	0: "Nop",
      	1: "RoundChange",
      	2: "Lock",
      	3: "Select",
      	4: "Commit",
      	5: "LockRelease",
      	6: "Decide",
      	7: "Resync",
      }
      View Source
      var MessageType_value = map[string]int32{
      	"Nop":         0,
      	"RoundChange": 1,
      	"Lock":        2,
      	"Select":      3,
      	"Commit":      4,
      	"LockRelease": 5,
      	"Decide":      6,
      	"Resync":      7,
      }
      View Source
      var S256Curve elliptic.Curve = btcec.S256()

        secp256k1 elliptic curve

        Functions

        func VerifyConfig

        func VerifyConfig(c *Config) error

          VerifyConfig verifies the integrity of this config when creating new consensus object

          Types

          type Config

          type Config struct {
          	// the starting time point for consensus
          	Epoch time.Time
          	// CurrentHeight
          	CurrentHeight uint64
          	// PrivateKey
          	PrivateKey *ecdsa.PrivateKey
          	// Consensus Group
          	Participants []Identity
          	// EnableCommitUnicast sets to true to enable <commit> message to be delivered via unicast
          	// if not(by default), <commit> message will be broadcasted
          	EnableCommitUnicast bool
          
          	// StateCompare is a function from user to compare states,
          	// The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
          	// Usually this will lead to block header comparsion in blockchain, or replication log in database,
          	// users should check fields in block header to make comparison.
          	StateCompare func(a State, b State) int
          
          	// StateValidate is a function from user to validate the integrity of
          	// state data.
          	StateValidate func(State) bool
          
          	// MessageValidator is an external validator to be called when a message inputs into ReceiveMessage
          	MessageValidator func(c *Consensus, m *Message, signed *SignedProto) bool
          
          	// MessageOutCallback will be called if not nil before a message send out
          	MessageOutCallback func(m *Message, signed *SignedProto)
          
          	// Identity derviation from ecdsa.PublicKey
          	// (optional). Default to DefaultPubKeyToIdentity
          	PubKeyToIdentity func(pubkey *ecdsa.PublicKey) (ret Identity)
          }

            Config is to config the parameters of BDLS consensus protocol

            type Consensus

            type Consensus struct {
            	// contains filtered or unexported fields
            }

              Consensus implements a deterministic BDLS consensus protocol.

              It has no internal clocking or IO, and no parallel processing. The runtime behavior is predictable and deterministic. Users should write their own timing and IO function to feed in messages and ticks to trigger timeouts.

              func NewConsensus

              func NewConsensus(config *Config) (*Consensus, error)

                NewConsensus creates a BDLS consensus object to participant in consensus procedure, the consensus object returned is data in memory without goroutines or other non-deterministic objects, and errors will be returned if there is problem, with the given config.

                func (*Consensus) CurrentProof

                func (c *Consensus) CurrentProof() *SignedProto

                  CurrentProof returns current <decide> message for current height

                  func (*Consensus) CurrentState

                  func (c *Consensus) CurrentState() (height uint64, round uint64, data State)

                    CurrentState returns current state along with current height & round, It's caller's responsibility to check if ReceiveMessage() has created a new height.

                    func (*Consensus) HasProposed

                    func (c *Consensus) HasProposed(state State) bool

                      HasProposed checks whether some state has been proposed via <roundchange> <lock> or left in c.unconfirmed

                      func (*Consensus) Join

                      func (c *Consensus) Join(p PeerInterface) bool

                        Join adds a peer to consensus for message delivery, a peer is identified by its address.

                        func (*Consensus) Leave

                        func (c *Consensus) Leave(addr net.Addr) bool

                          Leave removes a peer from consensus, identified by its address

                          func (*Consensus) Propose

                          func (c *Consensus) Propose(s State)

                            Propose adds a new state to unconfirmed queue to particpate in consensus at next height.

                            func (*Consensus) ReceiveMessage

                            func (c *Consensus) ReceiveMessage(bts []byte, now time.Time) (err error)

                              ReceiveMessage processes incoming consensus messages, and returns error if message cannot be processed for some reason.

                              func (*Consensus) SetLatency

                              func (c *Consensus) SetLatency(latency time.Duration)

                                SetLatency sets participants expected latency for consensus core

                                func (*Consensus) Update

                                func (c *Consensus) Update(now time.Time) error

                                  Update will process timing event for the state machine, callers from outside MUST call this function periodically(like 20ms).

                                  func (*Consensus) ValidateDecideMessage

                                  func (c *Consensus) ValidateDecideMessage(bts []byte, targetState []byte) error

                                    ValidateDecideMessage validates a <decide> message for non-participants, the consensus core must be correctly initialized to validate. the targetState is to compare the target state enclosed in decide message

                                    type IPCPeer

                                    type IPCPeer struct {
                                    	sync.Mutex
                                    	// contains filtered or unexported fields
                                    }

                                      IPCPeer represents an in-process peer for testing, which sends messages directly via function call, message delivery latency can be customizable to emulate variety of network latency. Delay is randomized with standard normal distribution based on given parameters.

                                      func NewIPCPeer

                                      func NewIPCPeer(c *Consensus, latency time.Duration) *IPCPeer

                                        NewIPCPeer creates IPC based peer with latency, latency is distributed with standard normal distribution.

                                        func (*IPCPeer) Close

                                        func (p *IPCPeer) Close()

                                          Close this peer

                                          func (*IPCPeer) GetBytesCount

                                          func (p *IPCPeer) GetBytesCount() int64

                                            GetBytesCount returns messages bytes count this peer received

                                            func (*IPCPeer) GetLatencies

                                            func (p *IPCPeer) GetLatencies() (min time.Duration, max time.Duration, total time.Duration)

                                              GetLatencies returns actual generated latency

                                              func (*IPCPeer) GetLatestState

                                              func (p *IPCPeer) GetLatestState() (height uint64, round uint64, data State)

                                                GetLatestState returns latest state

                                                func (*IPCPeer) GetMessageCount

                                                func (p *IPCPeer) GetMessageCount() int64

                                                  GetMessageCount returns messages count this peer received

                                                  func (*IPCPeer) GetPublicKey

                                                  func (p *IPCPeer) GetPublicKey() *ecdsa.PublicKey

                                                    GetPublicKey returns peer's public key as identity

                                                    func (*IPCPeer) Propose

                                                    func (p *IPCPeer) Propose(s State)

                                                      Propose a state, awaiting to be finalized at next height.

                                                      func (*IPCPeer) RemoteAddr

                                                      func (p *IPCPeer) RemoteAddr() net.Addr

                                                        RemoteAddr implements Peer.RemoteAddr, the address is p's memory address

                                                        func (*IPCPeer) Send

                                                        func (p *IPCPeer) Send(msg []byte) error

                                                          Send implements Peer.Send

                                                          func (*IPCPeer) Update

                                                          func (p *IPCPeer) Update()

                                                            Update will call itself perodically

                                                            type Identity

                                                            type Identity [2 * SizeAxis]byte

                                                              Identity is a user-defined struct to encode X-axis and Y-axis for a publickey in an array

                                                              func DefaultPubKeyToIdentity

                                                              func DefaultPubKeyToIdentity(pubkey *ecdsa.PublicKey) (ret Identity)

                                                                default method to derive coordinate from public key

                                                                type Message

                                                                type Message struct {
                                                                	// Type of this message
                                                                	Type MessageType `protobuf:"varint,1,opt,name=Type,proto3,enum=bdls.MessageType" json:"Type,omitempty"`
                                                                	// Height in consensus
                                                                	Height uint64 `protobuf:"varint,2,opt,name=Height,proto3" json:"Height,omitempty"`
                                                                	// Round in consensus
                                                                	Round uint64 `protobuf:"varint,3,opt,name=Round,proto3" json:"Round,omitempty"`
                                                                	// Proposed state (optional)
                                                                	State []byte `protobuf:"bytes,4,opt,name=State,proto3" json:"State,omitempty"`
                                                                	// Proofs related
                                                                	Proof []*SignedProto `protobuf:"bytes,5,rep,name=Proof,proto3" json:"Proof,omitempty"`
                                                                	// for lock-release, it's an embeded <lock> message
                                                                	LockRelease          *SignedProto `protobuf:"bytes,6,opt,name=LockRelease,proto3" json:"LockRelease,omitempty"`
                                                                	XXX_NoUnkeyedLiteral struct{}     `json:"-"`
                                                                	XXX_unrecognized     []byte       `json:"-"`
                                                                	XXX_sizecache        int32        `json:"-"`
                                                                }

                                                                  Message defines a consensus message

                                                                  func DecodeMessage

                                                                  func DecodeMessage(bts []byte) (*Message, error)

                                                                    DecodeMessage decodes a binary representation of consensus message.

                                                                    func (*Message) Descriptor

                                                                    func (*Message) Descriptor() ([]byte, []int)

                                                                    func (*Message) GetHeight

                                                                    func (m *Message) GetHeight() uint64

                                                                    func (*Message) GetLockRelease

                                                                    func (m *Message) GetLockRelease() *SignedProto

                                                                    func (*Message) GetProof

                                                                    func (m *Message) GetProof() []*SignedProto

                                                                    func (*Message) GetRound

                                                                    func (m *Message) GetRound() uint64

                                                                    func (*Message) GetState

                                                                    func (m *Message) GetState() []byte

                                                                    func (*Message) GetType

                                                                    func (m *Message) GetType() MessageType

                                                                    func (*Message) Marshal

                                                                    func (m *Message) Marshal() (dAtA []byte, err error)

                                                                    func (*Message) MarshalTo

                                                                    func (m *Message) MarshalTo(dAtA []byte) (int, error)

                                                                    func (*Message) MarshalToSizedBuffer

                                                                    func (m *Message) MarshalToSizedBuffer(dAtA []byte) (int, error)

                                                                    func (*Message) ProtoMessage

                                                                    func (*Message) ProtoMessage()

                                                                    func (*Message) Reset

                                                                    func (m *Message) Reset()

                                                                    func (*Message) Size

                                                                    func (m *Message) Size() (n int)

                                                                    func (*Message) String

                                                                    func (m *Message) String() string

                                                                    func (*Message) Unmarshal

                                                                    func (m *Message) Unmarshal(dAtA []byte) error

                                                                    func (*Message) XXX_DiscardUnknown

                                                                    func (m *Message) XXX_DiscardUnknown()

                                                                    func (*Message) XXX_Marshal

                                                                    func (m *Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

                                                                    func (*Message) XXX_Merge

                                                                    func (m *Message) XXX_Merge(src proto.Message)

                                                                    func (*Message) XXX_Size

                                                                    func (m *Message) XXX_Size() int

                                                                    func (*Message) XXX_Unmarshal

                                                                    func (m *Message) XXX_Unmarshal(b []byte) error

                                                                    type MessageType

                                                                    type MessageType int32

                                                                      MessageType defines supported message types

                                                                      const (
                                                                      	// No operation, for default message type, and keepalive connection
                                                                      	MessageType_Nop MessageType = 0
                                                                      	// MessageRoundChange = <roundchange> message
                                                                      	MessageType_RoundChange MessageType = 1
                                                                      	// MessageLock = <lock> message
                                                                      	MessageType_Lock MessageType = 2
                                                                      	// MessageSelect = <select> message
                                                                      	MessageType_Select MessageType = 3
                                                                      	// MessageCommit = <commit> message
                                                                      	MessageType_Commit MessageType = 4
                                                                      	// MessageLockRelease = <lock-release> message
                                                                      	MessageType_LockRelease MessageType = 5
                                                                      	// MessageDecide = <decide> message
                                                                      	MessageType_Decide MessageType = 6
                                                                      	// MessageResync= <resync> message
                                                                      	MessageType_Resync MessageType = 7
                                                                      )

                                                                      func (MessageType) EnumDescriptor

                                                                      func (MessageType) EnumDescriptor() ([]byte, []int)

                                                                      func (MessageType) String

                                                                      func (x MessageType) String() string

                                                                      type PeerInterface

                                                                      type PeerInterface interface {
                                                                      	// GetPublicKey returns peer's public key as identity
                                                                      	GetPublicKey() *ecdsa.PublicKey
                                                                      	// RemoteAddr returns remote addr
                                                                      	RemoteAddr() net.Addr
                                                                      	// Send a msg to this peer
                                                                      	Send(msg []byte) error
                                                                      }

                                                                        PeerInterface is a channel for consensus to send message to the peer

                                                                        type PubKeyAxis

                                                                        type PubKeyAxis [SizeAxis]byte

                                                                          PubKeyAxis defines X-axis or Y-axis in a public key

                                                                          func (PubKeyAxis) Marshal

                                                                          func (t PubKeyAxis) Marshal() ([]byte, error)

                                                                            Marshal implements protobuf MarshalTo

                                                                            func (*PubKeyAxis) MarshalText

                                                                            func (t *PubKeyAxis) MarshalText() (text []byte, err error)

                                                                              String representation of Axis

                                                                              func (*PubKeyAxis) MarshalTo

                                                                              func (t *PubKeyAxis) MarshalTo(data []byte) (n int, err error)

                                                                                MarshalTo implements protobuf MarshalTo

                                                                                func (*PubKeyAxis) Size

                                                                                func (t *PubKeyAxis) Size() int

                                                                                  Size implements protobuf Size

                                                                                  func (*PubKeyAxis) String

                                                                                  func (t *PubKeyAxis) String() string

                                                                                    String representation of Axis

                                                                                    func (*PubKeyAxis) Unmarshal

                                                                                    func (t *PubKeyAxis) Unmarshal(data []byte) error

                                                                                      Unmarshal implements protobuf Unmarshal

                                                                                      type SignedProto

                                                                                      type SignedProto struct {
                                                                                      	Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"`
                                                                                      	// the Message encoded raw protobuf in bytes
                                                                                      	Message []byte `protobuf:"bytes,2,opt,name=Message,proto3" json:"Message,omitempty"`
                                                                                      	// signer's public key
                                                                                      	X PubKeyAxis `protobuf:"bytes,3,opt,name=x,proto3,customtype=PubKeyAxis" json:"x"`
                                                                                      	Y PubKeyAxis `protobuf:"bytes,4,opt,name=y,proto3,customtype=PubKeyAxis" json:"y"`
                                                                                      	// signature r,s for prefix+messages+version+x+y above
                                                                                      	R                    []byte   `protobuf:"bytes,5,opt,name=r,proto3" json:"r,omitempty"`
                                                                                      	S                    []byte   `protobuf:"bytes,6,opt,name=s,proto3" json:"s,omitempty"`
                                                                                      	XXX_NoUnkeyedLiteral struct{} `json:"-"`
                                                                                      	XXX_unrecognized     []byte   `json:"-"`
                                                                                      	XXX_sizecache        int32    `json:"-"`
                                                                                      }

                                                                                        SignedProto defines a message with signature and it's publickey

                                                                                        func DecodeSignedMessage

                                                                                        func DecodeSignedMessage(bts []byte) (*SignedProto, error)

                                                                                          DecodeSignedMessage decodes a binary representation of signed consensus message.

                                                                                          func (*SignedProto) Descriptor

                                                                                          func (*SignedProto) Descriptor() ([]byte, []int)

                                                                                          func (*SignedProto) GetMessage

                                                                                          func (m *SignedProto) GetMessage() []byte

                                                                                          func (*SignedProto) GetR

                                                                                          func (m *SignedProto) GetR() []byte

                                                                                          func (*SignedProto) GetS

                                                                                          func (m *SignedProto) GetS() []byte

                                                                                          func (*SignedProto) GetVersion

                                                                                          func (m *SignedProto) GetVersion() uint32

                                                                                          func (*SignedProto) Hash

                                                                                          func (sp *SignedProto) Hash() []byte

                                                                                            Hash concats and hash as follows: blake2b(signPrefix + version + pubkey.X + pubkey.Y+len_32bit(msg) + message)

                                                                                            func (*SignedProto) Marshal

                                                                                            func (m *SignedProto) Marshal() (dAtA []byte, err error)

                                                                                            func (*SignedProto) MarshalTo

                                                                                            func (m *SignedProto) MarshalTo(dAtA []byte) (int, error)

                                                                                            func (*SignedProto) MarshalToSizedBuffer

                                                                                            func (m *SignedProto) MarshalToSizedBuffer(dAtA []byte) (int, error)

                                                                                            func (*SignedProto) ProtoMessage

                                                                                            func (*SignedProto) ProtoMessage()

                                                                                            func (*SignedProto) PublicKey

                                                                                            func (sp *SignedProto) PublicKey(curve elliptic.Curve) *ecdsa.PublicKey

                                                                                              PublicKey returns the public key of this signed message

                                                                                              func (*SignedProto) Reset

                                                                                              func (m *SignedProto) Reset()

                                                                                              func (*SignedProto) Sign

                                                                                              func (sp *SignedProto) Sign(m *Message, privateKey *ecdsa.PrivateKey)

                                                                                                Sign the message with a private key

                                                                                                func (*SignedProto) Size

                                                                                                func (m *SignedProto) Size() (n int)

                                                                                                func (*SignedProto) String

                                                                                                func (m *SignedProto) String() string

                                                                                                func (*SignedProto) Unmarshal

                                                                                                func (m *SignedProto) Unmarshal(dAtA []byte) error

                                                                                                func (*SignedProto) Verify

                                                                                                func (sp *SignedProto) Verify(curve elliptic.Curve) bool

                                                                                                  Verify the signature of this signed message

                                                                                                  func (*SignedProto) XXX_DiscardUnknown

                                                                                                  func (m *SignedProto) XXX_DiscardUnknown()

                                                                                                  func (*SignedProto) XXX_Marshal

                                                                                                  func (m *SignedProto) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

                                                                                                  func (*SignedProto) XXX_Merge

                                                                                                  func (m *SignedProto) XXX_Merge(src proto.Message)

                                                                                                  func (*SignedProto) XXX_Size

                                                                                                  func (m *SignedProto) XXX_Size() int

                                                                                                  func (*SignedProto) XXX_Unmarshal

                                                                                                  func (m *SignedProto) XXX_Unmarshal(b []byte) error

                                                                                                  type State

                                                                                                  type State []byte

                                                                                                    State is the data to participant in consensus

                                                                                                    type StateHash

                                                                                                    type StateHash [blake2b.Size256]byte

                                                                                                      StateHash is a fixed size hash to identify a state

                                                                                                      Directories

                                                                                                      Path Synopsis
                                                                                                      Package agent-tcp implements a TCP based agent to participate in consensus Challenge-Response scheme has been adopted to do interactive authentication
                                                                                                      Package agent-tcp implements a TCP based agent to participate in consensus Challenge-Response scheme has been adopted to do interactive authentication
                                                                                                      cmd
                                                                                                      crypto
                                                                                                      blake2b
                                                                                                      Package blake2b implements the BLAKE2b hash algorithm defined by RFC 7693 and the extendable output function (XOF) BLAKE2Xb.
                                                                                                      Package blake2b implements the BLAKE2b hash algorithm defined by RFC 7693 and the extendable output function (XOF) BLAKE2Xb.
                                                                                                      btcec
                                                                                                      Package btcec implements support for the elliptic curves needed for bitcoin.
                                                                                                      Package btcec implements support for the elliptic curves needed for bitcoin.