Class: XRBP::NodeStore::Ledger
- Inherits:
-
Object
- Object
- XRBP::NodeStore::Ledger
- Includes:
- Amendments, Parser
- Defined in:
- lib/xrbp/nodestore/ledger.rb
Instance Method Summary collapse
-
#initialize(args = {}) ⇒ Ledger
constructor
A new instance of Ledger.
-
#order_book(input, output) ⇒ Object
Return all offers for the given input/output currency pair.
- #txs ⇒ Object
Methods included from Amendments
Constructor Details
#initialize(args = {}) ⇒ Ledger
Returns a new instance of Ledger.
12 13 14 15 16 17 18 19 20 |
# File 'lib/xrbp/nodestore/ledger.rb', line 12 def initialize(args={}) @db = args[:db] @hash = args[:hash] if @hash state_map.fetch_root [info["account_hash"]].pack("H*") tx_map.fetch_root [info["tx_hash"]].pack("H*") end end |
Instance Method Details
#order_book(input, output) ⇒ Object
Return all offers for the given input/output currency pair
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 |
# File 'lib/xrbp/nodestore/ledger.rb', line 152 def order_book(input, output) offers = [] # Start at order book index # Stop after max order book quality tip_index = Indexes::order_book(input, output) book_end = Indexes::get_quality_next(tip_index) global_freeze = global_frozen?(output[:account]) || global_frozen?(input[:account]) # transfer rate multipled to offer output to pay issuer rate = transfer_rate(output[:account]) balances = {} done = false # set true when we cannot traverse anymore direct = true # set true when we need to find next dir offer_dir = nil # current directory being travred dir_rate = nil # current directory quality offer_index = nil # index of current offer being processed book_entry = nil # index of next offer directory record until done if direct direct = false # Return first index after tip ledger_index = state_map.succ(tip_index, book_end) if ledger_index # retrieve offer_dir SLE from db offer_dir = state_map.read(ledger_index) else offer_dir = nil end if !offer_dir done = true else # Set new tip, get first offer at new tip tip_index = offer_dir.key dir_rate = STAmount.from_quality(Indexes::get_quality(tip_index)) offer_index, offer_dir, book_entry = state_map.cdir_first(tip_index) end end if !done # Read offer from db and process sle_offer = state_map.read(offer_index) if sle_offer # Direct info from nodestore offer owner_id = sle_offer.account_id(:account) taker_gets = sle_offer.amount(:taker_gets) taker_pays = sle_offer.amount(:taker_pays) # Owner / Output Calculation owner_funds = nil # how much of offer output the owner has first_owner_offer = true # owner_funds returned w/ first owner offer # issuer is offering it's own IOU, fully funded if output[:account] == owner_id owner_funds = taker_gets # all offers not ours are unfunded elsif global_freeze owner_funds.clear(output) else # if we have owner funds cached if balances[owner_id] owner_funds = balances[owner_id] first_owner_offer = false # did not find balance in cache else # lookup from nodestore owner_funds = account_holds(owner_id, output) # treat negative funds as zero owner_funds.clear if owner_funds < STAmount.zero end end offer = Hash[sle_offer.fields] # copy the offer fields to return taker_gets_funded = nil # how much offer owner will actually be able to fund owner_funds_limit = owner_funds # how much the offer owner has limited by the output transfer fee offer_rate = Rate.parity # offer base output transfer rate # Check if transfer fee applies, if rate != Rate.parity && # transfer fee # TODO: provide support for 'taker_id' rpc param: #taker_id != output[:account] && # not taking offers of own IOUs output[:account] != owner_id # offer owner not issuing own funds # Need to charge a transfer fee to offer owner. offer_rate = rate owner_funds_limit = owner_funds / offer_rate.to_amount end # Check if owner has enough funds to pay it all if owner_funds_limit >= taker_gets # Sufficient funds no shenanigans. taker_gets_funded = taker_gets else # Only set these fields, if not fully funded. taker_gets_funded = owner_funds_limit offer[:taker_gets_funded] = taker_gets_funded # the account that takes the offer will need to # pay the 'gets' amount actually funded times the dir_rate (quality) offer[:taker_pays_funded] = [taker_pays, taker_gets_funded * dir_rate].min # XXX: done in multiply operation in rippled offer[:taker_pays_funded].issue = taker_pays.issue end # Calculate how much owner will pay after this offer, # if no transfer fee, then the amount funded, # else the minimum of what the owner has or the # amount funded w/ transfer fee owner_pays = (Rate.parity == offer_rate) ? taker_gets_funded : [owner_funds, taker_gets_funded * offer_rate.to_amount].min # Update balance cache w/ new owner balance balances[owner_id] = owner_funds - owner_pays # Set additional params and store the offer # include all offers funded and unfunded offer[:quality] = dir_rate offer[:owner_funds] = owner_funds if first_owner_offer offers << offer else puts "missing offer" end # Retrieve next offer in offer_dir, # updating offer_index, offer_dir, book_entry appropriately offer_index, offer_dir, book_entry = *state_map.cdir_next(tip_index, offer_dir, book_entry) # if next offer not retrieved find next record after tip direct = true if !offer_index end end return offers end |
#txs ⇒ Object
22 23 24 |
# File 'lib/xrbp/nodestore/ledger.rb', line 22 def txs @txs ||= tx_map.collect { |tx| parse_tx_inner(tx.data) } end |