github.com/ZuluSpl0it/Sia@v1.3.7/modules/transactionpool/database.go (about) 1 package transactionpool 2 3 import ( 4 "encoding/json" 5 6 "github.com/NebulousLabs/Sia/build" 7 "github.com/NebulousLabs/Sia/encoding" 8 "github.com/NebulousLabs/Sia/modules" 9 "github.com/NebulousLabs/Sia/types" 10 11 "github.com/NebulousLabs/errors" 12 "github.com/coreos/bbolt" 13 ) 14 15 // database.go contains objects related to the layout of the transaction pool's 16 // database, as well as getters and setters. Logic for interacting with the 17 // database can be found in persist.go 18 19 // Buckets in the database. 20 var ( 21 // bucketBlockHeight holds the most recent block height seen by the 22 // transaction pool. 23 bucketBlockHeight = []byte("BlockHeight") 24 25 // bucketConfirmedTransactions holds the ids of every transaction that has 26 // been confirmed on the blockchain. 27 bucketConfirmedTransactions = []byte("ConfirmedTransactions") 28 29 // bucketFeeMedian stores all of the persist data relating to the fee 30 // median. 31 bucketFeeMedian = []byte("FeeMedian") 32 33 // bucketRecentConsensusChange holds the most recent consensus change seen 34 // by the transaction pool. 35 bucketRecentConsensusChange = []byte("RecentConsensusChange") 36 ) 37 38 // Explicitly named fields in the database. 39 var ( 40 // fieldBlockHeight is the field in bucketBlockHeight that holds the value of 41 // the most recent block height. 42 fieldBlockHeight = []byte("BlockHeight") 43 44 // fieldFeeMedian is the fee median persist data stored in a fee median 45 // field. 46 fieldFeeMedian = []byte("FeeMedian") 47 48 // fieldRecentBlockID is used to store the id of the most recent block seen 49 // by the transaction pool. 50 fieldRecentBlockID = []byte("RecentBlockID") 51 52 // fieldRecentConsensusChange is the field in bucketRecentConsensusChange 53 // that holds the value of the most recent consensus change. 54 fieldRecentConsensusChange = []byte("RecentConsensusChange") 55 ) 56 57 // Errors relating to the database. 58 var ( 59 // errNilConsensusChange is returned if there is no consensus change in the 60 // database. 61 errNilConsensusChange = errors.New("no consensus change found") 62 63 // errNilFeeMedian is the message returned if a database does not find fee 64 // median persistence. 65 errNilFeeMedian = errors.New("no fee median found") 66 67 // errNilRecentBlock is returned if there is no data stored in 68 // fieldRecentBlockID. 69 errNilRecentBlock = errors.New("no recent block found in the database") 70 ) 71 72 // Complex objects that get stored in database fields. 73 type ( 74 // medianPersist is the json object that gets stored in the database so that 75 // the transaction pool can persist its block based fee estimations. 76 medianPersist struct { 77 RecentMedians []types.Currency 78 RecentMedianFee types.Currency 79 } 80 ) 81 82 // deleteTransaction deletes a transaction from the list of confirmed 83 // transactions. 84 func (tp *TransactionPool) deleteTransaction(tx *bolt.Tx, id types.TransactionID) error { 85 return tx.Bucket(bucketConfirmedTransactions).Delete(id[:]) 86 } 87 88 // getBlockHeight returns the most recent block height from the database. 89 func (tp *TransactionPool) getBlockHeight(tx *bolt.Tx) (bh types.BlockHeight, err error) { 90 err = encoding.Unmarshal(tx.Bucket(bucketBlockHeight).Get(fieldBlockHeight), &bh) 91 return 92 } 93 94 // getFeeMedian will get the fee median struct stored in the database. 95 func (tp *TransactionPool) getFeeMedian(tx *bolt.Tx) (medianPersist, error) { 96 medianBytes := tp.dbTx.Bucket(bucketFeeMedian).Get(fieldFeeMedian) 97 if medianBytes == nil { 98 return medianPersist{}, errNilFeeMedian 99 } 100 101 var mp medianPersist 102 err := json.Unmarshal(medianBytes, &mp) 103 if err != nil { 104 return medianPersist{}, build.ExtendErr("unable to unmarshal median data:", err) 105 } 106 return mp, nil 107 } 108 109 // getRecentBlockID will fetch the most recent block id and most recent parent 110 // id from the database. 111 func (tp *TransactionPool) getRecentBlockID(tx *bolt.Tx) (recentID types.BlockID, err error) { 112 idBytes := tx.Bucket(bucketRecentConsensusChange).Get(fieldRecentBlockID) 113 if idBytes == nil { 114 return types.BlockID{}, errNilRecentBlock 115 } 116 copy(recentID[:], idBytes[:]) 117 if recentID == (types.BlockID{}) { 118 return types.BlockID{}, errNilRecentBlock 119 } 120 return recentID, nil 121 } 122 123 // getRecentConsensusChange returns the most recent consensus change from the 124 // database. 125 func (tp *TransactionPool) getRecentConsensusChange(tx *bolt.Tx) (cc modules.ConsensusChangeID, err error) { 126 ccBytes := tx.Bucket(bucketRecentConsensusChange).Get(fieldRecentConsensusChange) 127 if ccBytes == nil { 128 return modules.ConsensusChangeID{}, errNilConsensusChange 129 } 130 copy(cc[:], ccBytes) 131 return cc, nil 132 } 133 134 // putBlockHeight updates the transaction pool's block height. 135 func (tp *TransactionPool) putBlockHeight(tx *bolt.Tx, height types.BlockHeight) error { 136 tp.blockHeight = height 137 return tx.Bucket(bucketBlockHeight).Put(fieldBlockHeight, encoding.Marshal(height)) 138 } 139 140 // putFeeMedian puts a median fees object into the database. 141 func (tp *TransactionPool) putFeeMedian(tx *bolt.Tx, mp medianPersist) error { 142 objBytes, err := json.Marshal(mp) 143 if err != nil { 144 return err 145 } 146 return tx.Bucket(bucketFeeMedian).Put(fieldFeeMedian, objBytes) 147 } 148 149 // putRecentBlockID will store the most recent block id and the parent id of 150 // that block in the database. 151 func (tp *TransactionPool) putRecentBlockID(tx *bolt.Tx, recentID types.BlockID) error { 152 return tx.Bucket(bucketRecentConsensusChange).Put(fieldRecentBlockID, recentID[:]) 153 } 154 155 // putRecentConsensusChange updates the most recent consensus change seen by 156 // the transaction pool. 157 func (tp *TransactionPool) putRecentConsensusChange(tx *bolt.Tx, cc modules.ConsensusChangeID) error { 158 return tx.Bucket(bucketRecentConsensusChange).Put(fieldRecentConsensusChange, cc[:]) 159 } 160 161 // putTransaction adds a transaction to the list of confirmed transactions. 162 func (tp *TransactionPool) putTransaction(tx *bolt.Tx, id types.TransactionID) error { 163 return tx.Bucket(bucketConfirmedTransactions).Put(id[:], []byte{}) 164 }