Class: Bank

Inherits:
Object
  • Object
show all
Defined in:
lib/centralbank/bank.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(address) ⇒ Bank

Returns a new instance of Bank.



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/centralbank/bank.rb', line 7

def initialize( address )
  @address = address

  ## note: add address name for now to cache
  ##          allows to start more nodes in same folder / directory
  @cache = Cache.new( "data.#{address.downcase}.json" )
  h = @cache.read
  if h
    ## restore blockchain
    @chain = Blockchain.from_json( h['chain'] )
    ## restore pending (unconfirmed) transactions pool too
    @pending = Pool.from_json( h['transactions'] )
  else
    @chain   = Blockchain.new
    @chain  << [Tx.new( Centralbank.config.rand_coinbase,
                        @address,
                        Centralbank.config.mining_reward )]    # genesis (big bang!) starter block
    @pending = Pool.new
  end

  ## update ledger (balances) with confirmed transactions
  @ledger = Ledger.new( @chain )
end

Instance Attribute Details

#chainObject (readonly)

Returns the value of attribute chain.



4
5
6
# File 'lib/centralbank/bank.rb', line 4

def chain
  @chain
end

#ledgerObject (readonly)

Returns the value of attribute ledger.



4
5
6
# File 'lib/centralbank/bank.rb', line 4

def ledger
  @ledger
end

#pendingObject (readonly)

Returns the value of attribute pending.



4
5
6
# File 'lib/centralbank/bank.rb', line 4

def pending
  @pending
end

Instance Method Details

#add_transaction(tx) ⇒ Object



57
58
59
60
61
62
63
64
65
# File 'lib/centralbank/bank.rb', line 57

def add_transaction( tx )
  if tx.valid? && transaction_is_new?( tx )
    @pending << tx
    @cache.write as_json
    return true
  else
    return false
  end
end

#as_jsonObject



91
92
93
94
95
# File 'lib/centralbank/bank.rb', line 91

def as_json
  { chain:        @chain.as_json,
    transactions: @pending.as_json
  }
end

#mine_block!Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/centralbank/bank.rb', line 33

def mine_block!
  add_transaction( Tx.new( Centralbank.config.rand_coinbase,
                           @address,
                           Centralbank.config.mining_reward ))

  ## add mined (w/ computed/calculated hash) block
  @chain << @pending.transactions
  @pending = Pool.new   ## clear out/ empty pool (just create a new one for now)

  ## update ledger (balances) with new confirmed transactions
  @ledger = Ledger.new( @chain )

  @cache.write as_json
end

#resolve!(chain_new) ⇒ Object

check - how to name incoming chain - chain_new, chain_candidate - why? why not?

what's an intuitive name - what's gets used most often???


72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/centralbank/bank.rb', line 72

def resolve!( chain_new )
  # TODO this does not protect against invalid block shapes (bogus COINBASE transactions for example)

  if !chain_new.empty? && chain_new.last.valid? && chain_new.size > @chain.size
    @chain  = chain_new
    ## update ledger (balances) with new confirmed transactions
    @ledger = Ledger.new( @chain )

    ## document - keep only pending transaction not  yet (confirmed) in (new) blockchain ????
    @pending.update!( @chain.transactions )
    @cache.write as_json
    return true
  else
    return false
  end
end

#sufficient_funds?(wallet, amount) ⇒ Boolean

Returns:

  • (Boolean)


49
50
51
52
53
54
# File 'lib/centralbank/bank.rb', line 49

def sufficient_funds?( wallet, amount )
  ## (convenience) delegate for ledger
  ##  todo/check: use address instead of wallet - why? why not?
  ##   for now single address wallet (that is, wallet==address)
  @ledger.sufficient_funds?( wallet, amount )
end