github.com/Synthesix/Sia@v1.3.3-0.20180413141344-f863baeed3ca/modules/explorer/info.go (about) 1 package explorer 2 3 import ( 4 "github.com/Synthesix/Sia/build" 5 "github.com/Synthesix/Sia/modules" 6 "github.com/Synthesix/Sia/types" 7 "github.com/coreos/bbolt" 8 ) 9 10 // Block takes a block ID and finds the corresponding block, provided that the 11 // block is in the consensus set. 12 func (e *Explorer) Block(id types.BlockID) (types.Block, types.BlockHeight, bool) { 13 var height types.BlockHeight 14 err := e.db.View(dbGetAndDecode(bucketBlockIDs, id, &height)) 15 if err != nil { 16 return types.Block{}, 0, false 17 } 18 block, exists := e.cs.BlockAtHeight(height) 19 if !exists { 20 return types.Block{}, 0, false 21 } 22 return block, height, true 23 } 24 25 // BlockFacts returns a set of statistics about the blockchain as they appeared 26 // at a given block height, and a bool indicating whether facts exist for the 27 // given height. 28 func (e *Explorer) BlockFacts(height types.BlockHeight) (modules.BlockFacts, bool) { 29 var bf blockFacts 30 err := e.db.View(e.dbGetBlockFacts(height, &bf)) 31 if err != nil { 32 return modules.BlockFacts{}, false 33 } 34 35 return bf.BlockFacts, true 36 } 37 38 // LatestBlockFacts returns a set of statistics about the blockchain as they appeared 39 // at the latest block height in the explorer's consensus set. 40 func (e *Explorer) LatestBlockFacts() modules.BlockFacts { 41 var bf blockFacts 42 err := e.db.View(func(tx *bolt.Tx) error { 43 var height types.BlockHeight 44 err := dbGetInternal(internalBlockHeight, &height)(tx) 45 if err != nil { 46 return err 47 } 48 return e.dbGetBlockFacts(height, &bf)(tx) 49 }) 50 if err != nil { 51 build.Critical(err) 52 } 53 return bf.BlockFacts 54 } 55 56 // Transaction takes a transaction ID and finds the block containing the 57 // transaction. Because of the miner payouts, the transaction ID might be a 58 // block ID. To find the transaction, iterate through the block. 59 func (e *Explorer) Transaction(id types.TransactionID) (types.Block, types.BlockHeight, bool) { 60 var height types.BlockHeight 61 err := e.db.View(dbGetAndDecode(bucketTransactionIDs, id, &height)) 62 if err != nil { 63 return types.Block{}, 0, false 64 } 65 block, exists := e.cs.BlockAtHeight(height) 66 if !exists { 67 return types.Block{}, 0, false 68 } 69 return block, height, true 70 } 71 72 // UnlockHash returns the IDs of all the transactions that contain the unlock 73 // hash. An empty set indicates that the unlock hash does not appear in the 74 // blockchain. 75 func (e *Explorer) UnlockHash(uh types.UnlockHash) []types.TransactionID { 76 var ids []types.TransactionID 77 err := e.db.View(dbGetTransactionIDSet(bucketUnlockHashes, uh, &ids)) 78 if err != nil { 79 ids = nil 80 } 81 return ids 82 } 83 84 // SiacoinOutput returns the siacoin output associated with the specified ID. 85 func (e *Explorer) SiacoinOutput(id types.SiacoinOutputID) (types.SiacoinOutput, bool) { 86 var sco types.SiacoinOutput 87 err := e.db.View(dbGetAndDecode(bucketSiacoinOutputs, id, &sco)) 88 if err != nil { 89 return types.SiacoinOutput{}, false 90 } 91 return sco, true 92 } 93 94 // SiacoinOutputID returns all of the transactions that contain the specified 95 // siacoin output ID. An empty set indicates that the siacoin output ID does 96 // not appear in the blockchain. 97 func (e *Explorer) SiacoinOutputID(id types.SiacoinOutputID) []types.TransactionID { 98 var ids []types.TransactionID 99 err := e.db.View(dbGetTransactionIDSet(bucketSiacoinOutputIDs, id, &ids)) 100 if err != nil { 101 ids = nil 102 } 103 return ids 104 } 105 106 // FileContractHistory returns the history associated with the specified file 107 // contract ID, which includes the file contract itself and all of the 108 // revisions that have been submitted to the blockchain. The first bool 109 // indicates whether the file contract exists, and the second bool indicates 110 // whether a storage proof was successfully submitted for the file contract. 111 func (e *Explorer) FileContractHistory(id types.FileContractID) (fc types.FileContract, fcrs []types.FileContractRevision, fcE bool, spE bool) { 112 var history fileContractHistory 113 err := e.db.View(dbGetAndDecode(bucketFileContractHistories, id, &history)) 114 fc = history.Contract 115 fcrs = history.Revisions 116 fcE = err == nil 117 spE = history.StorageProof.ParentID == id 118 return 119 } 120 121 // FileContractID returns all transactions that contain the specified 122 // file contract ID. An empty set indicates that the file contract ID does not 123 // appear in the blockchain. 124 func (e *Explorer) FileContractID(id types.FileContractID) []types.TransactionID { 125 var ids []types.TransactionID 126 err := e.db.View(dbGetTransactionIDSet(bucketFileContractIDs, id, &ids)) 127 if err != nil { 128 ids = nil 129 } 130 return ids 131 } 132 133 // FileContractPayouts returns all of the spendable siacoin outputs which are the 134 // result of a FileContract. An empty set indicates that the file contract is 135 // still open 136 func (e *Explorer) FileContractPayouts(id types.FileContractID) ([]types.SiacoinOutput, error) { 137 var history fileContractHistory 138 err := e.db.View(dbGetAndDecode(bucketFileContractHistories, id, &history)) 139 if err != nil { 140 return []types.SiacoinOutput{}, err 141 } 142 143 fc := history.Contract 144 var outputs []types.SiacoinOutput 145 146 for i := range fc.ValidProofOutputs { 147 scoid := id.StorageProofOutputID(types.ProofValid, uint64(i)) 148 149 sco, found := e.SiacoinOutput(scoid) 150 if found { 151 outputs = append(outputs, sco) 152 } 153 } 154 for i := range fc.MissedProofOutputs { 155 scoid := id.StorageProofOutputID(types.ProofMissed, uint64(i)) 156 157 sco, found := e.SiacoinOutput(scoid) 158 if found { 159 outputs = append(outputs, sco) 160 } 161 } 162 163 return outputs, nil 164 } 165 166 // SiafundOutput returns the siafund output associated with the specified ID. 167 func (e *Explorer) SiafundOutput(id types.SiafundOutputID) (types.SiafundOutput, bool) { 168 var sco types.SiafundOutput 169 err := e.db.View(dbGetAndDecode(bucketSiafundOutputs, id, &sco)) 170 if err != nil { 171 return types.SiafundOutput{}, false 172 } 173 return sco, true 174 } 175 176 // SiafundOutputID returns all of the transactions that contain the specified 177 // siafund output ID. An empty set indicates that the siafund output ID does 178 // not appear in the blockchain. 179 func (e *Explorer) SiafundOutputID(id types.SiafundOutputID) []types.TransactionID { 180 var ids []types.TransactionID 181 err := e.db.View(dbGetTransactionIDSet(bucketSiafundOutputIDs, id, &ids)) 182 if err != nil { 183 ids = nil 184 } 185 return ids 186 }