lib/zold/patch.rb in zold-0.13.32 vs lib/zold/patch.rb in zold-0.13.33
- old
+ new
@@ -29,55 +29,73 @@
# Copyright:: Copyright (c) 2018 Yegor Bugayenko
# License:: MIT
module Zold
# A patch
class Patch
- def initialize(log: Log::Quiet.new)
+ def initialize(wallets, log: Log::Quiet.new)
+ raise 'Wallets can\'t be nil' if wallets.nil?
+ raise 'Wallets must be of type Wallets' unless wallets.is_a?(Wallets)
+ @wallets = wallets
+ @txns = []
@log = log
end
def to_s
- return 'empty' if @id.nil?
+ return 'empty' if @txns.empty?
"#{@txns.count} txns"
end
- def join(wallet)
+ def join(wallet, baseline = true)
if @id.nil?
@id = wallet.id
@key = wallet.key
- @txns = wallet.txns
- @log.debug("The baseline: #{@txns.count} transactions, the balance is #{wallet.balance}")
+ if baseline
+ @txns = wallet.txns
+ @log.debug("The baseline: #{@txns.count} transactions, the balance is #{wallet.balance}")
+ else
+ @log.debug("The baseline of #{@txns.count} transactions ignored")
+ end
@network = wallet.network
end
if wallet.network != @network
raise "The wallet is from a different network '#{wallet.network}', ours is '#{@network}'"
end
raise 'Public key mismatch' if wallet.key != @key
raise "Wallet ID mismatch: #{@id} != #{wallet.id}" if wallet.id != @id
- negative = @txns.select { |t| t.amount.negative? }
- max = negative.empty? ? 0 : negative.max_by(&:id).id
+ max = @txns.select { |t| t.amount.negative? }.map(&:id).max.to_i
wallet.txns.each do |txn|
next if @txns.find { |t| t == txn }
if txn.amount.negative?
if txn.id <= max
- @log.debug("Transaction ID is less than max #{max}: #{txn.to_text}")
+ @log.error("Transaction ID is less than max #{max}: #{txn.to_text}")
next
end
if @txns.find { |t| t.id == txn.id }
- @log.debug("Transaction ##{txn.id} already exists: #{txn.to_text}")
+ @log.error("Transaction ##{txn.id} already exists: #{txn.to_text}")
next
end
if !@txns.empty? && @txns.map(&:amount).inject(&:+) < txn.amount
@log.error("Transaction ##{txn.id} attempts to make the balance negative: #{txn.to_text}")
next
end
unless Signature.new.valid?(@key, wallet.id, txn)
@log.error("Invalid RSA signature at transaction ##{txn.id} of #{wallet.id}: #{txn.to_text}")
next
end
- elsif !txn.sign.nil? && !txn.sign.empty?
- @log.error("RSA signature is redundant at ##{txn.id} of #{wallet.id}: #{txn.to_text}")
- next
+ else
+ if !txn.sign.nil? && !txn.sign.empty?
+ @log.error("RSA signature is redundant at ##{txn.id} of #{wallet.id}: #{txn.to_text}")
+ next
+ end
+ payer = @wallets.find(txn.bnf)
+ unless payer.exists?
+ @log.error("Paying wallet #{wallet.id} is absent at ##{txn.id}: #{txn.to_text}")
+ next
+ end
+ unless payer.has?(txn.id, wallet.id)
+ @log.error("Paying wallet #{wallet.id} doesn't have transaction ##{txn.id}: #{txn.to_text}")
+ next
+ end
end
@log.debug("Merged on top: #{txn.to_text}")
@txns << txn
end
end