github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/dlc/dlcdb.go (about) 1 package dlc 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "fmt" 7 8 "github.com/boltdb/bolt" 9 "github.com/mit-dci/lit/lnutil" 10 ) 11 12 // const strings for db usage 13 var ( 14 BKTOracles = []byte("Oracles") 15 BKTContracts = []byte("Contracts") 16 ) 17 18 // InitDB initializes the database for Discreet Log Contract storage 19 func (mgr *DlcManager) InitDB(dbPath string) error { 20 var err error 21 22 mgr.DLCDB, err = bolt.Open(dbPath, 0600, nil) 23 if err != nil { 24 return err 25 } 26 27 // Ensure buckets exist that we need 28 err = mgr.DLCDB.Update(func(tx *bolt.Tx) error { 29 _, err = tx.CreateBucketIfNotExists(BKTOracles) 30 if err != nil { 31 return err 32 } 33 _, err = tx.CreateBucketIfNotExists(BKTContracts) 34 return err 35 }) 36 37 return nil 38 } 39 40 // SaveOracle saves an oracle into the database. Generates a new index if the 41 // passed oracle doesn't have one 42 func (mgr *DlcManager) SaveOracle(o *DlcOracle) error { 43 err := mgr.DLCDB.Update(func(tx *bolt.Tx) error { 44 b := tx.Bucket(BKTOracles) 45 46 if o.Idx == 0 { 47 o.Idx, _ = b.NextSequence() 48 } 49 var wb bytes.Buffer 50 binary.Write(&wb, binary.BigEndian, o.Idx) 51 err := b.Put(wb.Bytes(), o.Bytes()) 52 53 if err != nil { 54 return err 55 } 56 57 return nil 58 }) 59 60 if err != nil { 61 return err 62 } 63 return nil 64 } 65 66 // LoadOracle loads an oracle from the database by index. 67 func (mgr *DlcManager) LoadOracle(idx uint64) (*DlcOracle, error) { 68 o := new(DlcOracle) 69 70 err := mgr.DLCDB.View(func(tx *bolt.Tx) error { 71 b := tx.Bucket(BKTOracles) 72 73 var wb bytes.Buffer 74 binary.Write(&wb, binary.BigEndian, idx) 75 76 v := b.Get(wb.Bytes()) 77 78 if v == nil { 79 return fmt.Errorf("Oracle %d does not exist", idx) 80 } 81 var err error 82 o, err = DlcOracleFromBytes(v) 83 if err != nil { 84 return err 85 } 86 o.Idx = idx 87 return nil 88 }) 89 90 if err != nil { 91 return nil, err 92 } 93 94 return o, nil 95 96 } 97 98 // ListOracles loads all oracles from the database and returns them as an array 99 func (mgr *DlcManager) ListOracles() ([]*DlcOracle, error) { 100 oracles := make([]*DlcOracle, 0) 101 err := mgr.DLCDB.View(func(tx *bolt.Tx) error { 102 b := tx.Bucket(BKTOracles) 103 c := b.Cursor() 104 105 for k, v := c.First(); k != nil; k, v = c.Next() { 106 buf := bytes.NewBuffer(k) 107 o, err := DlcOracleFromBytes(v) 108 if err != nil { 109 return err 110 } 111 binary.Read(buf, binary.BigEndian, &o.Idx) 112 oracles = append(oracles, o) 113 } 114 return nil 115 }) 116 117 if err != nil { 118 return nil, err 119 } 120 121 return oracles, nil 122 } 123 124 // SaveContract saves a contract into the database. Will generate a new index 125 // if the passed object doesn't have one. 126 func (mgr *DlcManager) SaveContract(c *lnutil.DlcContract) error { 127 err := mgr.DLCDB.Update(func(tx *bolt.Tx) error { 128 b := tx.Bucket(BKTContracts) 129 130 if c.Idx == 0 { 131 c.Idx, _ = b.NextSequence() 132 } 133 var wb bytes.Buffer 134 binary.Write(&wb, binary.BigEndian, c.Idx) 135 err := b.Put(wb.Bytes(), c.Bytes()) 136 137 if err != nil { 138 return err 139 } 140 141 return nil 142 }) 143 144 if err != nil { 145 return err 146 } 147 return nil 148 } 149 150 // LoadContract loads a contract from the database by index. 151 func (mgr *DlcManager) LoadContract(idx uint64) (*lnutil.DlcContract, error) { 152 c := new(lnutil.DlcContract) 153 154 err := mgr.DLCDB.View(func(tx *bolt.Tx) error { 155 b := tx.Bucket(BKTContracts) 156 157 var wb bytes.Buffer 158 binary.Write(&wb, binary.BigEndian, idx) 159 160 v := b.Get(wb.Bytes()) 161 162 if v == nil { 163 return fmt.Errorf("Contract %d does not exist", idx) 164 } 165 var err error 166 c, err = lnutil.DlcContractFromBytes(v) 167 if err != nil { 168 return err 169 } 170 c.Idx = idx 171 return nil 172 }) 173 174 if err != nil { 175 return nil, err 176 } 177 178 return c, nil 179 180 } 181 182 // ListContracts loads all contracts from the database 183 func (mgr *DlcManager) ListContracts() ([]*lnutil.DlcContract, error) { 184 contracts := make([]*lnutil.DlcContract, 0) 185 err := mgr.DLCDB.View(func(tx *bolt.Tx) error { 186 b := tx.Bucket(BKTContracts) 187 c := b.Cursor() 188 189 for k, v := c.First(); k != nil; k, v = c.Next() { 190 buf := bytes.NewBuffer(k) 191 c, err := lnutil.DlcContractFromBytes(v) 192 if err != nil { 193 return err 194 } 195 binary.Read(buf, binary.BigEndian, &c.Idx) 196 contracts = append(contracts, c) 197 } 198 return nil 199 }) 200 201 if err != nil { 202 return nil, err 203 } 204 205 return contracts, nil 206 }