lighstorm 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/.env.example +5 -0
  3. data/.github/workflows/ruby-rspec-tests.yml +39 -0
  4. data/.gitignore +1 -0
  5. data/.rspec +1 -0
  6. data/.rubocop.yml +10 -0
  7. data/Gemfile +4 -0
  8. data/Gemfile.lock +26 -2
  9. data/README.md +30 -371
  10. data/adapters/connections/channel_node/fee.rb +26 -0
  11. data/adapters/connections/channel_node/policy.rb +61 -0
  12. data/adapters/connections/channel_node.rb +74 -0
  13. data/adapters/connections/payment_channel.rb +28 -0
  14. data/adapters/edges/channel.rb +96 -0
  15. data/adapters/edges/forward.rb +40 -0
  16. data/adapters/edges/payment/purpose.rb +32 -0
  17. data/adapters/edges/payment.rb +50 -0
  18. data/adapters/invoice.rb +49 -0
  19. data/adapters/nodes/node.rb +111 -0
  20. data/adapters/payment_request.rb +76 -0
  21. data/components/cache.rb +3 -2
  22. data/components/lnd.rb +5 -1
  23. data/controllers/channel/actions/apply_gossip.rb +194 -0
  24. data/controllers/channel/actions/update_fee.rb +76 -0
  25. data/controllers/channel/all.rb +79 -0
  26. data/controllers/channel/find_by_id.rb +153 -0
  27. data/controllers/channel/mine.rb +114 -0
  28. data/controllers/channel.rb +27 -0
  29. data/controllers/forward/all.rb +244 -0
  30. data/controllers/forward/group_by_channel.rb +89 -0
  31. data/controllers/forward.rb +28 -0
  32. data/controllers/invoice/actions/create.rb +36 -0
  33. data/controllers/invoice/actions/pay.rb +28 -0
  34. data/controllers/invoice/actions/pay_through_route.rb +71 -0
  35. data/controllers/invoice/all.rb +70 -0
  36. data/controllers/invoice/find_by_secret_hash.rb +42 -0
  37. data/controllers/invoice.rb +36 -0
  38. data/controllers/node/actions/apply_gossip.rb +112 -0
  39. data/controllers/node/all.rb +63 -0
  40. data/controllers/node/find_by_public_key.rb +49 -0
  41. data/controllers/node/myself.rb +34 -0
  42. data/controllers/node.rb +27 -0
  43. data/controllers/payment/all.rb +368 -0
  44. data/controllers/payment.rb +21 -0
  45. data/docs/.nojekyll +0 -0
  46. data/docs/README.md +731 -0
  47. data/docs/_coverpage.md +12 -0
  48. data/docs/index.html +26 -0
  49. data/docs/vendor/docsify/docsify@4.js +1 -0
  50. data/docs/vendor/docsify-themeable/theme-simple-dark.css +3 -0
  51. data/docs/vendor/docsify-themeable/theme-simple-dark.css.map +1 -0
  52. data/docs/vendor/prismjs/prism-bash.min.js +1 -0
  53. data/docs/vendor/prismjs/prism-ruby.min.js +1 -0
  54. data/docs/vendor/prismjs/prism-tomorrow.min.css +1 -0
  55. data/lighstorm.gemspec +3 -1
  56. data/models/concerns/protectable.rb +23 -0
  57. data/models/connections/channel_node/accounting.rb +7 -14
  58. data/models/connections/channel_node/fee.rb +55 -84
  59. data/models/connections/channel_node/htlc/blocks/delta.rb +39 -0
  60. data/models/connections/channel_node/htlc.rb +65 -11
  61. data/models/connections/channel_node/policy.rb +15 -18
  62. data/models/connections/channel_node.rb +48 -22
  63. data/models/connections/forward_channel.rb +8 -43
  64. data/models/connections/payment_channel.rb +18 -39
  65. data/models/edges/channel/accounting.rb +45 -20
  66. data/models/edges/channel/hop.rb +65 -0
  67. data/models/edges/channel.rb +111 -169
  68. data/models/edges/forward.rb +9 -119
  69. data/models/edges/groups/{analysis.rb → channel_forwards/analysis.rb} +9 -9
  70. data/models/edges/groups/channel_forwards.rb +10 -40
  71. data/models/edges/payment.rb +29 -215
  72. data/models/errors.rb +32 -0
  73. data/models/invoice.rb +49 -0
  74. data/models/nodes/node/lightning.rb +11 -16
  75. data/models/nodes/node/platform.rb +13 -13
  76. data/models/nodes/node.rb +59 -103
  77. data/models/payment_request.rb +72 -0
  78. data/models/rate.rb +11 -1
  79. data/models/satoshis.rb +5 -6
  80. data/ports/dsl/lighstorm/errors.rb +5 -0
  81. data/ports/dsl/lighstorm.rb +11 -9
  82. data/ports/grpc/session.rb +26 -0
  83. data/ports/grpc.rb +80 -0
  84. data/static/cache.rb +12 -0
  85. data/static/spec.rb +3 -1
  86. metadata +62 -6
  87. data/models/connections/channel_node/constraints.rb +0 -24
@@ -1,254 +1,68 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'time'
4
- require 'date'
5
4
 
6
5
  require_relative '../satoshis'
7
6
 
8
7
  require_relative '../connections/payment_channel'
9
8
  require_relative '../nodes/node'
9
+ require_relative '../payment_request'
10
10
 
11
11
  module Lighstorm
12
12
  module Models
13
13
  class Payment
14
- KIND = :edge
14
+ attr_reader :_key, :hash, :request, :status, :created_at, :settled_at, :purpose
15
15
 
16
- attr_reader :data
16
+ def initialize(data)
17
+ @data = data
17
18
 
18
- def self.all(limit: nil, purpose: nil, hops: true, info: true)
19
- last_offset = 0
20
-
21
- payments = []
22
-
23
- loop do
24
- response = Cache.for('lightning.list_payments', params: { index_offset: last_offset }) do
25
- LND.instance.middleware('lightning.list_payments') do
26
- LND.instance.client.lightning.list_payments(index_offset: last_offset)
27
- end
28
- end
29
-
30
- response.payments.each do |raw_payment|
31
- case purpose
32
- when 'potential-submarine', 'submarine'
33
- payments << raw_payment if raw_potential_submarine?(raw_payment)
34
- when '!potential-submarine', '!submarine'
35
- payments << raw_payment unless raw_potential_submarine?(raw_payment)
36
- when 'rebalance'
37
- payments << raw_payment if raw_rebalance?(raw_payment)
38
- when '!rebalance'
39
- payments << raw_payment unless raw_rebalance?(raw_payment)
40
- when '!payment'
41
- payments << raw_payment if raw_potential_submarine?(raw_payment) || raw_rebalance?(raw_payment)
42
- when 'payment'
43
- payments << raw_payment if !raw_potential_submarine?(raw_payment) && !raw_rebalance?(raw_payment)
44
- else
45
- payments << raw_payment
46
- end
47
- end
48
-
49
- # Fortunately, payments are sorted in descending order. :)
50
- break if !limit.nil? && payments.size >= limit
51
-
52
- break if last_offset == response.last_index_offset || last_offset > response.last_index_offset
53
-
54
- last_offset = response.last_index_offset
55
- end
56
-
57
- payments = payments.sort_by { |raw_payment| -raw_payment.creation_time_ns }
58
-
59
- payments = payments[0..limit - 1] unless limit.nil?
60
-
61
- payments.map do |raw_payment|
62
- Payment.new(raw_payment, respond_hops: hops, respond_info: info)
63
- end
64
- end
65
-
66
- def self.first
67
- all(limit: 1).first
68
- end
69
-
70
- def self.last
71
- all.last
72
- end
73
-
74
- def initialize(raw, respond_hops: true, respond_info: true)
75
- @respond_hops = respond_hops
76
- @respond_info = respond_info
77
- @data = { list_payments: { payments: [raw] } }
78
- end
79
-
80
- def id
81
- @id ||= @data[:list_payments][:payments].first.payment_hash
19
+ @_key = data[:_key]
20
+ @status = data[:status]
21
+ @created_at = data[:created_at]
22
+ @settled_at = data[:settled_at]
23
+ @purpose = data[:purpose]
82
24
  end
83
25
 
84
- def hash
85
- @hash ||= @data[:list_payments][:payments].first.payment_hash
86
- end
87
-
88
- def status
89
- @status ||= @data[:list_payments][:payments].first.status
90
- end
91
-
92
- def created_at
93
- @created_at ||= DateTime.parse(Time.at(@data[:list_payments][:payments].first.creation_date).to_s)
94
- end
95
-
96
- def amount
97
- @amount ||= Satoshis.new(
98
- milisatoshis: @data[:list_payments][:payments].first.value_msat
99
- )
26
+ def request
27
+ @request ||= PaymentRequest.new(@data[:request])
100
28
  end
101
29
 
102
30
  def fee
103
- @fee ||= Satoshis.new(
104
- milisatoshis: @data[:list_payments][:payments].first.fee_msat
105
- )
106
- end
107
-
108
- def purpose
109
- @purpose ||= Payment.raw_purpose(@data[:list_payments][:payments].first)
31
+ @fee ||= Satoshis.new(milisatoshis: @data[:fee][:milisatoshis])
110
32
  end
111
33
 
112
- def rebalance?
113
- return @rebalance unless @rebalance.nil?
114
-
115
- validated_htlcs_number!
116
-
117
- @rebalance = Payment.raw_rebalance?(
118
- @data[:list_payments][:payments].first
119
- )
120
-
121
- @rebalance
122
- end
123
-
124
- def self.raw_rebalance?(raw_payment)
125
- return false if raw_payment.htlcs.first.route.hops.size <= 2
126
-
127
- destination_public_key = raw_payment.htlcs.first.route.hops.last.pub_key
128
-
129
- Node.myself.public_key == destination_public_key
130
- end
131
-
132
- def self.raw_purpose(raw_payment)
133
- return 'potential-submarine' if raw_potential_submarine?(raw_payment)
134
- return 'rebalance' if raw_rebalance?(raw_payment)
135
-
136
- 'payment'
137
- end
138
-
139
- def self.raw_potential_submarine?(raw_payment)
140
- raw_payment.htlcs.first.route.hops.size == 1
141
- end
142
-
143
- def potential_submarine?
144
- validated_htlcs_number!
145
-
146
- @potential_submarine ||= Payment.raw_potential_submarine?(
147
- @data[:list_payments][:payments].first
148
- )
149
- end
150
-
151
- def validated_htlcs_number!
152
- return unless @data[:list_payments][:payments].first.htlcs.size > 1
34
+ def hops
35
+ return @hops if @hops
153
36
 
154
- raise "Unexpected number of HTLCs (#{@data[:list_payments][:payments].first.htlcs.size}) for Payment"
37
+ @data[:hops].last[:is_last] = true
38
+ @hops = @data[:hops].map do |hop|
39
+ PaymentChannel.new(hop, self)
40
+ end
155
41
  end
156
42
 
157
43
  def from
158
- return @from if @from
159
-
160
- if @hops
161
- @from = @hops.first
162
- return @from
163
- end
164
-
165
- validated_htlcs_number!
166
-
167
- @from = PaymentChannel.new(
168
- @data[:list_payments][:payments].first.htlcs.first.route.hops.first,
169
- 1, respond_info: @respond_info
170
- )
171
-
172
- @from
44
+ @from ||= hops.first
173
45
  end
174
46
 
175
47
  def to
176
- return @to if @to
177
-
178
- if @hops
179
-
180
- @to = rebalance? ? @hops[@hops.size - 2] : @hops.last
181
- return @to
182
- end
183
-
184
- validated_htlcs_number!
185
-
186
- @to = if rebalance?
187
- PaymentChannel.new(
188
- @data[:list_payments][:payments].first.htlcs.first.route.hops[
189
- @data[:list_payments][:payments].first.htlcs.first.route.hops.size - 2
190
- ],
191
- @data[:list_payments][:payments].first.htlcs.first.route.hops.size - 1,
192
- respond_info: @respond_info
193
- )
194
- else
195
- PaymentChannel.new(
196
- @data[:list_payments][:payments].first.htlcs.first.route.hops.last,
197
- @data[:list_payments][:payments].first.htlcs.first.route.hops.size,
198
- respond_info: @respond_info
199
- )
200
- end
201
-
202
- @to
203
- end
204
-
205
- def hops
206
- return @hops if @hops
207
-
208
- validated_htlcs_number!
209
-
210
- @hops = @data[:list_payments][:payments].first.htlcs.first.route.hops.map.with_index do |raw_hop, i|
211
- PaymentChannel.new(raw_hop, i + 1, respond_info: @respond_info)
212
- end
213
- end
214
-
215
- def preload_hops!
216
- hops
217
- true
48
+ @to ||= hops.last
218
49
  end
219
50
 
220
51
  def to_h
221
52
  response = {
222
- id: id,
223
- hash: hash,
53
+ _key: _key,
54
+ status: status,
224
55
  created_at: created_at,
56
+ settled_at: settled_at,
225
57
  purpose: purpose,
226
- status: status,
227
- amount: amount.to_h,
228
58
  fee: {
229
59
  milisatoshis: fee.milisatoshis,
230
- parts_per_million: fee.parts_per_million(amount.milisatoshis)
231
- }
232
- }
233
-
234
- if @respond_hops
235
- preload_hops!
236
- response[:from] = from.to_h
237
- response[:to] = to.to_h
238
- response[:hops] = hops.map(&:to_h)
239
- else
240
- response[:from] = from.to_h
241
- response[:to] = to.to_h
242
- end
243
-
244
- response
245
- end
246
-
247
- def raw
248
- {
249
- list_payments: {
250
- payments: [@data[:list_payments][:payments].first.to_h]
251
- }
60
+ parts_per_million: fee.parts_per_million(request.amount.milisatoshis)
61
+ },
62
+ request: request.to_h,
63
+ from: from.to_h,
64
+ to: to.to_h,
65
+ hops: hops.map(&:to_h)
252
66
  }
253
67
  end
254
68
  end
data/models/errors.rb ADDED
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lighstorm
4
+ module Errors
5
+ class LighstormError < StandardError; end
6
+
7
+ class ToDoError < LighstormError; end
8
+
9
+ class TooManyArgumentsError < LighstormError; end
10
+ class IncoherentGossipError < LighstormError; end
11
+ class MissingGossipHandlerError < LighstormError; end
12
+ class MissingCredentialsError < LighstormError; end
13
+ class MissingMilisatoshisError < LighstormError; end
14
+ class MissingPartsPerMillionError < LighstormError; end
15
+ class MissingTTLError < LighstormError; end
16
+ class NegativeNotAllowedError < LighstormError; end
17
+ class NotYourChannelError < LighstormError; end
18
+ class NotYourNodeError < LighstormError; end
19
+ class OperationNotAllowedError < LighstormError; end
20
+ class UnexpectedNumberOfHTLCsError < LighstormError; end
21
+ class UnknownChannelError < LighstormError; end
22
+
23
+ class UpdateChannelPolicyError < LighstormError
24
+ attr_reader :response
25
+
26
+ def initialize(message, response)
27
+ super(message)
28
+ @response = response
29
+ end
30
+ end
31
+ end
32
+ end
data/models/invoice.rb ADDED
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'satoshis'
4
+ require 'securerandom'
5
+
6
+ require_relative 'payment_request'
7
+
8
+ require_relative '../controllers/invoice/actions/create'
9
+ require_relative '../controllers/invoice/actions/pay'
10
+ require_relative '../controllers/invoice/actions/pay_through_route'
11
+
12
+ module Lighstorm
13
+ module Models
14
+ class Invoice
15
+ attr_reader :_key, :created_at, :settle_at, :state
16
+
17
+ def initialize(data)
18
+ @data = data
19
+
20
+ @_key = data[:_key]
21
+ @created_at = data[:created_at]
22
+ @settle_at = data[:settle_at]
23
+ @state = data[:state]
24
+ end
25
+
26
+ def request
27
+ @request ||= PaymentRequest.new(@data[:request])
28
+ end
29
+
30
+ def to_h
31
+ {
32
+ _key: _key,
33
+ created_at: created_at,
34
+ settle_at: settle_at,
35
+ state: state,
36
+ request: request.to_h
37
+ }
38
+ end
39
+
40
+ def pay!(route: nil, preview: false)
41
+ if route
42
+ Controllers::Invoice::PayThroughRoute.perform(self, route: route, preview: preview)
43
+ else
44
+ Controllers::Invoice::Pay.perform(self, preview: preview)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,28 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../../components/lnd'
4
-
5
3
  module Lighstorm
6
4
  module Models
7
5
  class Lightning
8
6
  IMPLEMENTATION = 'lnd'
9
7
 
10
- def initialize(platform, node)
11
- raise 'cannot provide platform details for a node that is not yours' unless node.myself?
12
-
13
- @platform = platform
14
- end
15
-
16
- def version
17
- @version ||= @platform.data[:get_info].version
18
- end
8
+ attr_reader :implementation, :version
19
9
 
20
- def raw
21
- { get_info: @data[:get_info].to_h }
22
- end
10
+ def initialize(node)
11
+ raise Errors::NotYourNodeError unless node.myself?
23
12
 
24
- def implementation
25
- @implementation ||= IMPLEMENTATION
13
+ @implementation = IMPLEMENTATION
14
+ @version = node.data[:platform][:lightning][:version]
26
15
  end
27
16
 
28
17
  def to_h
@@ -31,6 +20,12 @@ module Lighstorm
31
20
  version: version
32
21
  }
33
22
  end
23
+
24
+ def dump
25
+ Marshal.load(
26
+ Marshal.dump({ implementation: implementation, version: version })
27
+ )
28
+ end
34
29
  end
35
30
  end
36
31
  end
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../../components/lnd'
4
-
5
3
  require_relative 'lightning'
6
4
 
5
+ require_relative '../../..//ports/grpc'
6
+ require_relative '../../../adapters/nodes/node'
7
+
7
8
  module Lighstorm
8
9
  module Models
9
10
  class Platform
@@ -11,26 +12,19 @@ module Lighstorm
11
12
 
12
13
  def initialize(node)
13
14
  @node = node
14
-
15
- response = Cache.for('lightning.get_info') do
16
- LND.instance.middleware('lightning.get_info') do
17
- LND.instance.client.lightning.get_info
18
- end
19
- end
20
-
21
- @data = { get_info: response }
15
+ @data = @node.data[:platform]
22
16
  end
23
17
 
24
18
  def blockchain
25
- @blockchain ||= @data[:get_info].chains.first.chain
19
+ @blockchain ||= @data ? @data[:blockchain] : nil
26
20
  end
27
21
 
28
22
  def network
29
- @network ||= @data[:get_info].chains.first.network
23
+ @network ||= @data ? @data[:network] : nil
30
24
  end
31
25
 
32
26
  def lightning
33
- @lightning ||= Lightning.new(self, @node)
27
+ @lightning ||= Lightning.new(@node)
34
28
  end
35
29
 
36
30
  def to_h
@@ -43,6 +37,12 @@ module Lighstorm
43
37
 
44
38
  response
45
39
  end
40
+
41
+ def dump
42
+ data = Marshal.load(Marshal.dump(@data))
43
+ data.merge(lightning: lightning.dump) if @node.myself?
44
+ data
45
+ end
46
46
  end
47
47
  end
48
48
  end
data/models/nodes/node.rb CHANGED
@@ -1,46 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../components/lnd'
4
-
5
- require_relative '../edges/channel'
3
+ require_relative '../../controllers/node/actions/apply_gossip'
4
+ require_relative '../../controllers/channel'
5
+ require_relative '../../adapters/nodes/node'
6
+ require_relative '../concerns/protectable'
7
+ require_relative '../errors'
6
8
 
7
9
  require_relative 'node/platform'
8
10
 
9
11
  module Lighstorm
10
12
  module Models
11
13
  class Node
12
- KIND = :node
13
-
14
- attr_reader :alias, :public_key, :color
14
+ include Protectable
15
15
 
16
- def self.myself
17
- response = Cache.for('lightning.get_info') do
18
- LND.instance.middleware('lightning.get_info') do
19
- LND.instance.client.lightning.get_info
20
- end
21
- end
16
+ attr_reader :data, :_key, :alias, :public_key, :color
22
17
 
23
- Node.find_by_public_key(response.identity_pubkey, myself: true)
24
- end
18
+ def initialize(data)
19
+ @data = data
25
20
 
26
- def self.find_by_public_key(public_key, myself: false)
27
- Node.new({ public_key: public_key }, myself: myself)
28
- end
29
-
30
- def self.all
31
- response = LND.instance.middleware('lightning.describe_graph') do
32
- LND.instance.client.lightning.describe_graph
33
- end
34
-
35
- myself_public_key = myself.public_key
36
-
37
- response.nodes.map do |raw_node|
38
- Node.new({ describe_graph: raw_node }, myself: raw_node.pub_key == myself_public_key)
39
- end
21
+ @_key = @data[:_key]
22
+ @alias = @data[:alias]
23
+ @public_key = @data[:public_key]
24
+ @color = @data[:color]
40
25
  end
41
26
 
42
27
  def myself?
43
- @myself
28
+ @data[:myself] == true
44
29
  end
45
30
 
46
31
  def platform
@@ -48,98 +33,69 @@ module Lighstorm
48
33
  end
49
34
 
50
35
  def channels
51
- if myself?
52
- Channel.mine
53
- else
54
- Channel.all
55
- end
56
- end
36
+ raise Errors::NotYourNodeError unless myself?
57
37
 
58
- def raw
59
- {
60
- get_node_info: @data[:get_node_info].to_h,
61
- describe_graph: @data[:describe_graph].to_h
62
- }
38
+ Controllers::Channel.mine
63
39
  end
64
40
 
65
41
  def to_h
66
- if (@data[:get_node_info] || @data[:describe_graph]) && myself?
67
- {
68
- alias: @alias,
69
- public_key: @public_key,
70
- color: @color,
71
- platform: platform.to_h
72
- }
73
- elsif @data[:get_node_info] || @data[:describe_graph]
74
- {
75
- alias: @alias,
76
- public_key: @public_key,
77
- color: @color
78
- }
79
- else
80
- {
81
- public_key: @public_key
82
- }
83
- end
84
- end
42
+ result = {
43
+ _key: _key,
44
+ public_key: public_key
45
+ }
85
46
 
86
- def myself
87
- return @myself unless @myself.nil?
47
+ result[:alias] = @alias unless self.alias.nil?
48
+ result[:color] = @color unless color.nil?
88
49
 
89
- response_get_info = Cache.for('lightning.get_info') do
90
- LND.instance.middleware('lightning.get_info') do
91
- LND.instance.client.lightning.get_info
92
- end
93
- end
50
+ result[:platform] = platform.to_h if @data[:platform]
94
51
 
95
- @myself = public_key == response_get_info.identity_pubkey
52
+ result
96
53
  end
97
54
 
98
- def error?
99
- !@data[:error].nil?
55
+ def dump
56
+ result = Marshal.load(Marshal.dump(@data))
57
+
58
+ result[:platform] = platform.dump if @data[:platform]
59
+
60
+ result
100
61
  end
101
62
 
102
- def error
103
- @data[:error]
63
+ def alias=(value)
64
+ protect!(value)
65
+
66
+ @alias = value[:value]
67
+
68
+ @data[:alias] = @alias
69
+
70
+ self.alias
104
71
  end
105
72
 
106
- def initialize(params, myself: false, fetch: true)
107
- if params[:public_key] && fetch
108
- begin
109
- response = Cache.for('lightning.get_node_info', params: { pub_key: params[:public_key] }) do
110
- LND.instance.middleware('lightning.get_node_info') do
111
- LND.instance.client.lightning.get_node_info(pub_key: params[:public_key])
112
- end
113
- end
114
-
115
- @data = { get_node_info: response }
116
- @raw_node = response.node
117
- rescue StandardError => e
118
- @data = { get_node_info: nil, error: e }
119
- @public_key = params[:public_key]
120
- end
121
- elsif params[:describe_graph]
122
- @data = { describe_graph: params[:describe_graph] }
123
-
124
- @raw_node = params[:describe_graph]
125
- else
126
- @data = {}
127
- end
73
+ def color=(value)
74
+ protect!(value)
128
75
 
129
- @myself = myself
76
+ @color = value[:value]
130
77
 
131
- if params[:public_key] && !fetch
132
- @public_key = params[:public_key]
133
- return
134
- end
78
+ @data[:color] = @color
79
+
80
+ color
81
+ end
135
82
 
136
- @myself = myself
83
+ def self.adapt(gossip: nil, dump: nil)
84
+ raise TooManyArgumentsError, 'you need to pass gossip: or dump:, not both' if !gossip.nil? && !dump.nil?
137
85
 
138
- return unless @raw_node
86
+ raise ArgumentError, 'missing gossip: or dump:' if gossip.nil? && dump.nil?
87
+
88
+ if !gossip.nil?
89
+ new(Adapter::Node.subscribe_channel_graph(gossip))
90
+ elsif !dump.nil?
91
+ new(dump)
92
+ end
93
+ end
139
94
 
140
- @alias = @raw_node.alias
141
- @public_key = @raw_node.pub_key
142
- @color = @raw_node.color
95
+ def apply!(gossip:)
96
+ Controllers::Node::ApplyGossip.perform(
97
+ self, gossip
98
+ )
143
99
  end
144
100
  end
145
101
  end