github.com/ZuluSpl0it/Sia@v1.3.7/siatest/consensus/consensus_test.go (about) 1 package consensus 2 3 import ( 4 "reflect" 5 "testing" 6 7 "github.com/NebulousLabs/Sia/node" 8 "github.com/NebulousLabs/Sia/siatest" 9 "github.com/NebulousLabs/Sia/types" 10 ) 11 12 // TestApiHeight checks if the consensus api endpoint works 13 func TestApiHeight(t *testing.T) { 14 if testing.Short() { 15 t.SkipNow() 16 } 17 testdir, err := siatest.TestDir(t.Name()) 18 if err != nil { 19 t.Fatal(err) 20 } 21 22 // Create a new server 23 testNode, err := siatest.NewNode(node.AllModules(testdir)) 24 if err != nil { 25 t.Fatal(err) 26 } 27 defer func() { 28 if err := testNode.Close(); err != nil { 29 t.Fatal(err) 30 } 31 }() 32 33 // Send GET request 34 cg, err := testNode.ConsensusGet() 35 if err != nil { 36 t.Fatal(err) 37 } 38 height := cg.Height 39 40 // Mine a block 41 if err := testNode.MineBlock(); err != nil { 42 t.Fatal(err) 43 } 44 45 // Request height again and check if it increased 46 cg, err = testNode.ConsensusGet() 47 if err != nil { 48 t.Fatal(err) 49 } 50 if cg.Height != height+1 { 51 t.Fatal("Height should have increased by 1 block") 52 } 53 } 54 55 // TestConsensusBlocksIDGet tests the /consensus/blocks endpoint 56 func TestConsensusBlocksIDGet(t *testing.T) { 57 if testing.Short() { 58 t.SkipNow() 59 } 60 // Create a testgroup 61 groupParams := siatest.GroupParams{ 62 Hosts: 1, 63 Renters: 1, 64 Miners: 1, 65 } 66 tg, err := siatest.NewGroupFromTemplate(groupParams) 67 if err != nil { 68 t.Fatal("Failed to create group: ", err) 69 } 70 defer func() { 71 if err := tg.Close(); err != nil { 72 t.Fatal(err) 73 } 74 }() 75 76 testNode := tg.Miners()[0] 77 78 // Send /consensus request 79 endBlock, err := testNode.ConsensusGet() 80 if err != nil { 81 t.Fatal("Failed to call ConsensusGet():", err) 82 } 83 84 // Loop over blocks and compare 85 var i types.BlockHeight 86 var zeroID types.BlockID 87 for i = 0; i <= endBlock.Height; i++ { 88 cbhg, err := testNode.ConsensusBlocksHeightGet(i) 89 if err != nil { 90 t.Fatal("Failed to retrieve block by height:", err) 91 } 92 cbig, err := testNode.ConsensusBlocksIDGet(cbhg.ID) 93 if err != nil { 94 t.Fatal("Failed to retrieve block by ID:", err) 95 } 96 // Confirm blocks received by both endpoints are the same 97 if !reflect.DeepEqual(cbhg, cbig) { 98 t.Fatal("Blocks not equal") 99 } 100 // Confirm Fields were set properly 101 // Ignore ParentID and MinerPayouts for genisis block 102 if cbig.ParentID == zeroID && i != 0 { 103 t.Fatal("ParentID wasn't set correctly") 104 } 105 if len(cbig.MinerPayouts) == 0 && i != 0 { 106 t.Fatal("Block has no miner payouts") 107 } 108 if cbig.Timestamp == types.Timestamp(0) { 109 t.Fatal("Timestamp wasn't set correctly") 110 } 111 if len(cbig.Transactions) == 0 { 112 t.Fatal("Block doesn't have any transactions even though it should") 113 } 114 115 // Verify IDs 116 for _, tx := range cbhg.Transactions { 117 // Building transaction of type Transaction to use as 118 // comparison for ID creation 119 txn := types.Transaction{ 120 SiacoinInputs: tx.SiacoinInputs, 121 FileContractRevisions: tx.FileContractRevisions, 122 StorageProofs: tx.StorageProofs, 123 SiafundInputs: tx.SiafundInputs, 124 MinerFees: tx.MinerFees, 125 ArbitraryData: tx.ArbitraryData, 126 TransactionSignatures: tx.TransactionSignatures, 127 } 128 for _, sco := range tx.SiacoinOutputs { 129 txn.SiacoinOutputs = append(txn.SiacoinOutputs, types.SiacoinOutput{ 130 Value: sco.Value, 131 UnlockHash: sco.UnlockHash, 132 }) 133 } 134 for i, fc := range tx.FileContracts { 135 txn.FileContracts = append(txn.FileContracts, types.FileContract{ 136 FileSize: fc.FileSize, 137 FileMerkleRoot: fc.FileMerkleRoot, 138 WindowStart: fc.WindowStart, 139 WindowEnd: fc.WindowEnd, 140 Payout: fc.Payout, 141 UnlockHash: fc.UnlockHash, 142 RevisionNumber: fc.RevisionNumber, 143 }) 144 for _, vp := range fc.ValidProofOutputs { 145 txn.FileContracts[i].ValidProofOutputs = append(txn.FileContracts[i].ValidProofOutputs, types.SiacoinOutput{ 146 Value: vp.Value, 147 UnlockHash: vp.UnlockHash, 148 }) 149 } 150 for _, mp := range fc.MissedProofOutputs { 151 txn.FileContracts[i].MissedProofOutputs = append(txn.FileContracts[i].MissedProofOutputs, types.SiacoinOutput{ 152 Value: mp.Value, 153 UnlockHash: mp.UnlockHash, 154 }) 155 } 156 } 157 for _, sfo := range tx.SiafundOutputs { 158 txn.SiafundOutputs = append(txn.SiafundOutputs, types.SiafundOutput{ 159 Value: sfo.Value, 160 UnlockHash: sfo.UnlockHash, 161 ClaimStart: types.ZeroCurrency, 162 }) 163 } 164 165 // Verify SiacoinOutput IDs 166 for i, sco := range tx.SiacoinOutputs { 167 if sco.ID != txn.SiacoinOutputID(uint64(i)) { 168 t.Fatalf("SiacoinOutputID not as expected, got %v expected %v", sco.ID, txn.SiacoinOutputID(uint64(i))) 169 } 170 } 171 172 // FileContracts 173 for i, fc := range tx.FileContracts { 174 // Verify FileContract ID 175 fcid := txn.FileContractID(uint64(i)) 176 if fc.ID != fcid { 177 t.Fatalf("FileContract ID not as expected, got %v expected %v", fc.ID, fcid) 178 } 179 // Verify ValidProof IDs 180 for j, vp := range fc.ValidProofOutputs { 181 if vp.ID != fcid.StorageProofOutputID(types.ProofValid, uint64(j)) { 182 t.Fatalf("File Contract ValidProofOutputID not as expected, got %v expected %v", vp.ID, fcid.StorageProofOutputID(types.ProofValid, uint64(j))) 183 } 184 } 185 // Verify MissedProof IDs 186 for j, mp := range fc.MissedProofOutputs { 187 if mp.ID != fcid.StorageProofOutputID(types.ProofMissed, uint64(j)) { 188 t.Fatalf("File Contract MissedProofOutputID not as expected, got %v expected %v", mp.ID, fcid.StorageProofOutputID(types.ProofMissed, uint64(j))) 189 } 190 } 191 } 192 193 // Verify SiafundOutput IDs 194 for i, sfo := range tx.SiafundOutputs { 195 // Failing, switch back to != 196 if sfo.ID != txn.SiafundOutputID(uint64(i)) { 197 t.Fatalf("SiafundOutputID not as expected, got %v expected %v", sfo.ID, txn.SiafundOutputID(uint64(i))) 198 } 199 } 200 } 201 } 202 }