lib.rs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. pub mod structures;
  2. #[cfg(test)]
  3. mod tests {
  4. use std::{
  5. thread,
  6. time::{Duration, Instant},
  7. };
  8. use super::structures::{block::Block, node::Node};
  9. use darkfi::{crypto::token_id::generate_id2, util::NetworkName};
  10. #[test]
  11. fn protocol_execution() {
  12. // Genesis block is generated.
  13. let mut genesis_block = Block::new(
  14. String::from("⊥"),
  15. 0,
  16. vec![],
  17. String::from("proof"),
  18. String::from("r"),
  19. String::from("s"),
  20. );
  21. genesis_block.metadata.sm.notarized = true;
  22. genesis_block.metadata.sm.finalized = true;
  23. let genesis_time = Instant::now();
  24. // We create some nodes to participate in the Protocol.
  25. let mut node0 = Node::new(0, genesis_time, genesis_block.clone());
  26. let mut node1 = Node::new(1, genesis_time, genesis_block.clone());
  27. let mut node2 = Node::new(2, genesis_time, genesis_block.clone());
  28. // We store nodes public keys for voting.
  29. let node0_public_key = node0.public_key;
  30. let node1_public_key = node1.public_key;
  31. let node2_public_key = node2.public_key;
  32. // We simulate some epochs to test consistency.
  33. let token_id = generate_id2("STREAMLET", &NetworkName::Ethereum).unwrap();
  34. let tx = node0.generate_transaction(token_id, 100, &node1_public_key).unwrap();
  35. node0.receive_transaction(tx.clone());
  36. node0.broadcast_transaction(vec![&mut node1, &mut node2], tx);
  37. let tx = node1.generate_transaction(token_id, 200, &node2_public_key).unwrap();
  38. node1.receive_transaction(tx.clone());
  39. node1.broadcast_transaction(vec![&mut node0, &mut node2], tx);
  40. let tx = node2.generate_transaction(token_id, 300, &node1_public_key).unwrap();
  41. node2.receive_transaction(tx.clone());
  42. node2.broadcast_transaction(vec![&mut node0, &mut node1], tx);
  43. // Each node checks if they are the epoch leader. Leader will propose the block.
  44. let (leader_public_key, block_proposal) = if node0.check_if_epoch_leader(3) {
  45. node0.propose_block()
  46. } else if node1.check_if_epoch_leader(3) {
  47. node1.propose_block()
  48. } else {
  49. node2.propose_block()
  50. };
  51. // Leader broadcasts the proposed_block to rest nodes and they vote on it.
  52. let node0_vote =
  53. node0.receive_proposed_block(&leader_public_key, &block_proposal, 3).unwrap();
  54. let node1_vote =
  55. node1.receive_proposed_block(&leader_public_key, &block_proposal, 3).unwrap();
  56. let node2_vote =
  57. node2.receive_proposed_block(&leader_public_key, &block_proposal, 3).unwrap();
  58. // Each node broadcasts its vote to rest nodes.
  59. node0.receive_vote(&node0_public_key, &node0_vote, 3);
  60. node0.receive_vote(&node1_public_key, &node1_vote, 3);
  61. node0.receive_vote(&node2_public_key, &node2_vote, 3);
  62. node1.receive_vote(&node0_public_key, &node0_vote, 3);
  63. node1.receive_vote(&node1_public_key, &node1_vote, 3);
  64. node1.receive_vote(&node2_public_key, &node2_vote, 3);
  65. node2.receive_vote(&node0_public_key, &node0_vote, 3);
  66. node2.receive_vote(&node1_public_key, &node1_vote, 3);
  67. node2.receive_vote(&node2_public_key, &node2_vote, 3);
  68. // We verify that all nodes have the same blockchain on round end.
  69. verify_outputs(&node0, &node1, &node2);
  70. // We use thread sleep to simulate sinchronization period.
  71. thread::sleep(Duration::new(5, 0));
  72. // Next round.
  73. let tx = node0.generate_transaction(token_id, 400, &node1_public_key).unwrap();
  74. node0.receive_transaction(tx.clone());
  75. node0.broadcast_transaction(vec![&mut node1, &mut node2], tx);
  76. let tx = node1.generate_transaction(token_id, 500, &node2_public_key).unwrap();
  77. node1.receive_transaction(tx.clone());
  78. node1.broadcast_transaction(vec![&mut node0, &mut node2], tx);
  79. //let tx = node2.generate_transaction(token_id, 600, &node1_public_key).unwrap();
  80. //node2.receive_transaction(tx.clone());
  81. //node2.broadcast_transaction(vec![&mut node0, &mut node1], tx);
  82. // Each node checks if they are the epoch leader. Leader will propose the block.
  83. let (leader_public_key, block_proposal) = if node0.check_if_epoch_leader(3) {
  84. node0.propose_block()
  85. } else if node1.check_if_epoch_leader(3) {
  86. node1.propose_block()
  87. } else {
  88. node2.propose_block()
  89. };
  90. // Leader broadcasts the proposed_block to rest nodes and they vote on it.
  91. let node0_vote =
  92. node0.receive_proposed_block(&leader_public_key, &block_proposal, 3).unwrap();
  93. let node1_vote =
  94. node1.receive_proposed_block(&leader_public_key, &block_proposal, 3).unwrap();
  95. let node2_vote =
  96. node2.receive_proposed_block(&leader_public_key, &block_proposal, 3).unwrap();
  97. // Each node broadcasts its vote to rest nodes.
  98. node0.receive_vote(&node0_public_key, &node0_vote, 3);
  99. node0.receive_vote(&node1_public_key, &node1_vote, 3);
  100. node0.receive_vote(&node2_public_key, &node2_vote, 3);
  101. node1.receive_vote(&node0_public_key, &node0_vote, 3);
  102. node1.receive_vote(&node1_public_key, &node1_vote, 3);
  103. node1.receive_vote(&node2_public_key, &node2_vote, 3);
  104. node2.receive_vote(&node0_public_key, &node0_vote, 3);
  105. node2.receive_vote(&node1_public_key, &node1_vote, 3);
  106. node2.receive_vote(&node2_public_key, &node2_vote, 3);
  107. // We verify that all nodes have the same blockchain on round end.
  108. verify_outputs(&node0, &node1, &node2);
  109. // We use thread sleep to simulate sinchronization period.
  110. thread::sleep(Duration::new(5, 0));
  111. // Next round.
  112. let tx = node0.generate_transaction(token_id, 700, &node1_public_key).unwrap();
  113. node0.receive_transaction(tx.clone());
  114. node0.broadcast_transaction(vec![&mut node1, &mut node2], tx);
  115. //let tx = node1.generate_transaction(token_id, 800, &node2_public_key).unwrap();
  116. //node1.receive_transaction(tx.clone());
  117. //node1.broadcast_transaction(vec![&mut node0, &mut node2], tx);
  118. //let tx = node2.generate_transaction(token_id, 900, &node1_public_key).unwrap();
  119. //node2.receive_transaction(tx.clone());
  120. //node2.broadcast_transaction(vec![&mut node0, &mut node1], tx);
  121. // Each node checks if they are the epoch leader. Leader will propose the block.
  122. let (leader_public_key, block_proposal) = if node0.check_if_epoch_leader(3) {
  123. node0.propose_block()
  124. } else if node1.check_if_epoch_leader(3) {
  125. node1.propose_block()
  126. } else {
  127. node2.propose_block()
  128. };
  129. // Leader broadcasts the proposed_block to rest nodes and they vote on it.
  130. let node0_vote =
  131. node0.receive_proposed_block(&leader_public_key, &block_proposal, 3).unwrap();
  132. let node1_vote =
  133. node1.receive_proposed_block(&leader_public_key, &block_proposal, 3).unwrap();
  134. let node2_vote =
  135. node2.receive_proposed_block(&leader_public_key, &block_proposal, 3).unwrap();
  136. // Each node broadcasts its vote to rest nodes.
  137. node0.receive_vote(&node0_public_key, &node0_vote, 3);
  138. node0.receive_vote(&node1_public_key, &node1_vote, 3);
  139. node0.receive_vote(&node2_public_key, &node2_vote, 3);
  140. node1.receive_vote(&node0_public_key, &node0_vote, 3);
  141. node1.receive_vote(&node1_public_key, &node1_vote, 3);
  142. node1.receive_vote(&node2_public_key, &node2_vote, 3);
  143. node2.receive_vote(&node0_public_key, &node0_vote, 3);
  144. node2.receive_vote(&node1_public_key, &node1_vote, 3);
  145. node2.receive_vote(&node2_public_key, &node2_vote, 3);
  146. // We verify that all nodes have the same blockchain on round end.
  147. verify_outputs(&node0, &node1, &node2);
  148. }
  149. fn verify_outputs(node0: &Node, node1: &Node, node2: &Node) {
  150. assert!(node0.output() == node1.output());
  151. assert!(node1.output() == node2.output());
  152. }
  153. }