gitlab.com/SiaPrime/SiaPrime@v1.4.1/modules/explorer/info.go (about)

     1  package explorer
     2  
     3  import (
     4  	bolt "github.com/coreos/bbolt"
     5  	"gitlab.com/SiaPrime/SiaPrime/build"
     6  	"gitlab.com/SiaPrime/SiaPrime/modules"
     7  	"gitlab.com/SiaPrime/SiaPrime/types"
     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  }