fabric-gateway 0.2.0 → 0.4.1

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.
@@ -0,0 +1,247 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fabric
4
+ #
5
+ # Represents an endorsed transaction that can be submitted to the orderer for commit to the ledger,
6
+ # query the transaction results and its commit status.
7
+ #
8
+ class Transaction
9
+ attr_reader :network
10
+
11
+ include Fabric::Accessors::Network
12
+
13
+ # @return [Gateway::PreparedTransaction] Prepared Transaction
14
+ attr_reader :prepared_transaction
15
+
16
+ # @return [Fabric::Envelope]
17
+ attr_reader :envelope
18
+
19
+ #
20
+ # Creates a new Transaction instance.
21
+ #
22
+ # @param [Fabric::Network] network
23
+ # @param [Gateway::PreparedTransaction] prepared_transaction
24
+ #
25
+ def initialize(network, prepared_transaction)
26
+ @network = network
27
+ @prepared_transaction = prepared_transaction
28
+ @envelope = Envelope.new(prepared_transaction.envelope)
29
+ end
30
+
31
+ #
32
+ # Get the transaction result. This is obtained during the endorsement process when the transaction proposal is
33
+ # run on endorsing peers.
34
+ #
35
+ # @param [boolean] check_status set to true to raise exception if transaction has not yet been committed
36
+ #
37
+ # @return [String] Raw transaction result
38
+ #
39
+ def result(check_status: true)
40
+ raise Fabric::CommitError, status if check_status && !status.successful
41
+
42
+ envelope.result
43
+ end
44
+
45
+ #
46
+ # Returns the transaction ID from the prepared transaction.
47
+ #
48
+ # @return [String] transaction_id
49
+ #
50
+ def transaction_id
51
+ prepared_transaction.transaction_id
52
+ end
53
+
54
+ #
55
+ # Submit the transaction to the orderer to be committed to the ledger.
56
+ #
57
+ # @see https://www.rubydoc.info/gems/grpc/GRPC%2FClientStub:request_response
58
+ #
59
+ # @param [Hash] options gRPC call options
60
+ #
61
+ # @return [Fabric::Transaction] self
62
+ def submit(options = {})
63
+ sign_submit_request
64
+
65
+ client.submit(new_submit_request, options)
66
+
67
+ self
68
+ end
69
+
70
+ #
71
+ # Sign the transaction envelope.
72
+ #
73
+ # @return [void]
74
+ def sign_submit_request
75
+ return if submit_request_signed?
76
+
77
+ signature = signer.sign(envelope.payload_bytes)
78
+ self.submit_request_signature = signature
79
+ end
80
+
81
+ #
82
+ # Returns true if the transaction envelope has been signed.
83
+ #
84
+ # @return [Boolean] true if signed; false otherwise
85
+ #
86
+ def submit_request_signed?
87
+ @envelope.signed?
88
+ end
89
+
90
+ #
91
+ # Digest to be signed to support offline signing of the submit request
92
+ #
93
+ # @return [String] digest of the submit request
94
+ #
95
+ def submit_request_digest
96
+ envelope.payload_digest
97
+ end
98
+
99
+ #
100
+ # Sets the submit request signature. This is used to support offline signing of the submit request.
101
+ #
102
+ # @param [String] signature
103
+ #
104
+ # @return [void]
105
+ #
106
+ def submit_request_signature=(signature)
107
+ envelope.signature = signature
108
+ end
109
+
110
+ #
111
+ # Get status of the committed transaction. If the transaction has not yet committed, this method blocks until the
112
+ # commit occurs. If status is already queried, this returns status from cache and does not make additional queries.
113
+ #
114
+ # @see https://www.rubydoc.info/gems/grpc/GRPC%2FClientStub:request_response
115
+ #
116
+ # @param [Hash] options gRPC call options
117
+ #
118
+ # @return [Fabric::Status] status of the committed transaction
119
+ #
120
+ def status(options = {})
121
+ @status ||= query_status(options)
122
+ end
123
+
124
+ #
125
+ # Digest to be signed to support offline signing of the commit status request
126
+ #
127
+ # @return [String] digest of the commit status request
128
+ #
129
+ def status_request_digest
130
+ Fabric.crypto_suite.digest(signed_commit_status_request.request)
131
+ end
132
+
133
+ #
134
+ # Sets the status request signature. This is used to support offline signing of the commit status request.
135
+ #
136
+ # @param [String] signature
137
+ #
138
+ # @return [void]
139
+ #
140
+ def status_request_signature=(signature)
141
+ signed_commit_status_request.signature = signature
142
+ end
143
+
144
+ #
145
+ # Returns true if the signed commit status request has been signed.
146
+ #
147
+ # @return [Boolean] true if signed; false otherwise
148
+ #
149
+ def status_request_signed?
150
+ !signed_commit_status_request.signature.empty?
151
+ end
152
+
153
+ #
154
+ # Sign the signed commit status request
155
+ #
156
+ # @return [Fabric::Transaction] self
157
+ #
158
+ def sign_status_request
159
+ return if status_request_signed?
160
+
161
+ signature = signer.sign(signed_commit_status_request.request)
162
+ signed_commit_status_request.signature = signature
163
+
164
+ self
165
+ end
166
+
167
+ #
168
+ # Returns the current instance of the signed commit status request. Necessary so we can keep the state of the
169
+ # signature in the transaction object.
170
+ #
171
+ # @return [Gateway::SignedCommitStatusRequest] signed commit status request
172
+ #
173
+ def signed_commit_status_request
174
+ @signed_commit_status_request ||= new_signed_commit_status_request
175
+ end
176
+
177
+ private
178
+
179
+ #
180
+ # Actual status query call used by status method.
181
+ #
182
+ # @see https://www.rubydoc.info/gems/grpc/GRPC%2FClientStub:request_response
183
+ #
184
+ # @param [Hash] options gRPC call options
185
+ #
186
+ # @return [Fabric::Status] status of the committed transaction
187
+ #
188
+ def query_status(options = {})
189
+ sign_status_request
190
+
191
+ commit_status_response = client.commit_status(signed_commit_status_request, options)
192
+ new_status(commit_status_response)
193
+ end
194
+
195
+ #
196
+ # Generates a new signed commit status request
197
+ #
198
+ # @return [Gateway::SignedCommitStatusRequest] signed commit status request protobuf message
199
+ #
200
+ def new_signed_commit_status_request
201
+ ::Gateway::SignedCommitStatusRequest.new(
202
+ request: new_commit_status_request.to_proto
203
+ )
204
+ end
205
+
206
+ #
207
+ # Generates a new commit status request
208
+ #
209
+ # @return [Gateway::CommitStatusRequest] commit status request protobuf message
210
+ #
211
+ def new_commit_status_request
212
+ ::Gateway::CommitStatusRequest.new(
213
+ channel_id: network_name,
214
+ transaction_id: transaction_id,
215
+ identity: signer.to_proto
216
+ )
217
+ end
218
+
219
+ #
220
+ # Generates a new submit request.
221
+ #
222
+ # @return [Gateway::SubmitRequest] submit request protobuf message
223
+ #
224
+ def new_submit_request
225
+ ::Gateway::SubmitRequest.new(
226
+ transaction_id: transaction_id,
227
+ channel_id: network_name,
228
+ prepared_transaction: envelope.envelope
229
+ )
230
+ end
231
+
232
+ #
233
+ # New Status from CommitStatusResponse
234
+ #
235
+ # @param [Gateway::CommitStatusResponse] response commit status response
236
+ #
237
+ # @return [Fabric::Status] transaction status
238
+ #
239
+ def new_status(response)
240
+ Fabric::Status.new(
241
+ transaction_id,
242
+ response.block_number,
243
+ Fabric::Status::TRANSACTION_STATUSES[response.result]
244
+ )
245
+ end
246
+ end
247
+ end
@@ -11,19 +11,14 @@ module Fabric
11
11
  class Network
12
12
  attr_reader :gateway, :name
13
13
 
14
+ # @!parse include Fabric::Accessors::Gateway
15
+ include Fabric::Accessors::Gateway
16
+
14
17
  def initialize(gateway, name)
15
18
  @gateway = gateway
16
19
  @name = name
17
20
  end
18
21
 
19
- def client
20
- gateway.client
21
- end
22
-
23
- def signer
24
- gateway.signer
25
- end
26
-
27
22
  #
28
23
  # Creates a new contract instance
29
24
  #
@@ -37,25 +32,39 @@ module Fabric
37
32
  end
38
33
 
39
34
  #
40
- # @TODO: original SDK has getChaincodeEvents and newChaincodeEventsRequest methods
41
- # @see https://github.com/hyperledger/fabric-gateway/blob/08118cf0a792898925d0b2710b0a9e7c5ec23228/node/src/network.ts
42
- # @see https://github.com/hyperledger/fabric-gateway/blob/main/pkg/client/network.go
35
+ # Get chaincode events emitted by transaction functions of a specific chaincode.
36
+ #
37
+ # @see Fabric::Client#chaincode_events Fabric::Client#chaincode_events - explanation of the different return types
38
+ # and example usage.
39
+ # @see https://www.rubydoc.info/gems/grpc/GRPC%2FClientStub:server_streamer Call options for options parameter
43
40
  #
44
- # @return [?] ?
41
+ # @param [Fabric::Contract] contract the chaincode to listen for events on
42
+ # @param [Integer] start_block Block number at which to start reading chaincode events.
43
+ # @param [Hash] call_options gRPC call options (merged with default_call_options from initializer)
44
+ # @yield [chaincode_event] loops through the chaincode events
45
+ # @yieldparam chaincode_event [Gateway::ChaincodeEventsResponse] the chaincode event
45
46
  #
46
- def new_chaincode_events
47
- raise NotYetImplemented
47
+ # @return [Enumerator|GRPC::ActiveCall::Operation|nil] Dependent on parameters passed;
48
+ # please see Fabric::Client#get_chaincode_events
49
+ #
50
+ def chaincode_events(contract, start_block: nil, call_options: {}, &block)
51
+ new_chaincode_events_request(contract, start_block: start_block).get_events(call_options, &block)
48
52
  end
49
53
 
50
54
  #
51
- # @TODO: original SDK has getChaincodeEvents and newChaincodeEventsRequest methods
52
- # @see https://github.com/hyperledger/fabric-gateway/blob/08118cf0a792898925d0b2710b0a9e7c5ec23228/node/src/network.ts
53
- # @see https://github.com/hyperledger/fabric-gateway/blob/main/pkg/client/network.go
55
+ # Create a request to receive chaincode events emitted by transaction functions of a specific chaincode. Supports
56
+ # off-line signing flow.
57
+ #
58
+ # @note I'm lying. I just copy and pasted the description from the node SDK. Offline signing should work, but it has
59
+ # not been explicitly tested.
60
+ # @todo Test off-line signing flow.
54
61
  #
55
- # @return [?] ?
62
+ # @param [Fabric::Contract] contract the chaincode to listen for events on
63
+ # @param [Integer] start_block Block number at which to start reading chaincode events.
64
+ # @return [Fabric::ChaincodeEventsRequest] Encapsulated ChaincodeEventsRequest
56
65
  #
57
- def new_chaincode_events_request
58
- raise NotImplementedError
66
+ def new_chaincode_events_request(contract, start_block: nil)
67
+ ChaincodeEventsRequest.new(contract, start_block: start_block)
59
68
  end
60
69
  end
61
70
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fabric
4
- VERSION = '0.2.0'
4
+ VERSION = '0.4.1'
5
5
  end
data/lib/fabric.rb CHANGED
@@ -1,19 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'gateway/gateway_pb'
4
+ require 'gateway/gateway_services_pb'
5
+
6
+ require 'fabric/accessors/gateway'
7
+ require 'fabric/accessors/network'
8
+ require 'fabric/accessors/contract'
9
+
10
+ require 'fabric/entities/envelope'
11
+ require 'fabric/entities/identity'
12
+ require 'fabric/entities/proposal'
13
+ require 'fabric/entities/proposed_transaction'
14
+ require 'fabric/entities/status'
15
+ require 'fabric/entities/transaction'
16
+ require 'fabric/entities/chaincode_events_requests'
17
+
3
18
  require 'fabric/constants'
4
19
  require 'fabric/contract'
5
20
  require 'fabric/client'
6
21
  require 'fabric/ec_crypto_suite'
7
22
  require 'fabric/gateway'
8
- require 'fabric/identity'
9
23
  require 'fabric/network'
10
- require 'fabric/proposal'
11
- require 'fabric/proposed_transaction'
12
24
  require 'fabric/version'
13
25
 
14
- require 'gateway/gateway_pb'
15
- require 'gateway/gateway_services_pb'
16
-
17
26
  #
18
27
  # Hyperledger Fabric Gateway SDK
19
28
  #
@@ -25,14 +34,20 @@ module Fabric
25
34
  #
26
35
  # CommitError
27
36
  #
28
- # @TODO: TEST ME!
37
+ # TODO: Add RSpec Tests for CommitError
38
+ # @todo TEST ME!
29
39
  #
30
40
  class CommitError < Error
31
41
  attr_reader :code, :transaction_id
32
42
 
43
+ #
44
+ # Creates a transaction commit error from the status
45
+ #
46
+ # @param [Fabric::Status] status transaction status
47
+ #
33
48
  def initialize(status)
34
- super("Transaction #{status.transaction_id} failed to commit with status code #{status.code} -" +
35
- Protos::TxValidationCode.lookup(status.code).to_s)
49
+ super("Transaction #{status.transaction_id} failed to commit with status code #{status.code} - " +
50
+ Status::TRANSACTION_STATUSES.key(status.code).to_s)
36
51
  @code = code
37
52
  @transaction_id = status.transaction_id
38
53
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fabric-gateway
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Chan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-12-29 00:00:00.000000000 Z
11
+ date: 2022-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-protobuf
@@ -72,14 +72,28 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '1.42'
75
+ version: 1.46.2
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '1.42'
82
+ version: 1.46.2
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake-notes
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.2.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.2.0
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: rubocop
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -136,8 +150,21 @@ dependencies:
136
150
  - - "~>"
137
151
  - !ruby/object:Gem::Version
138
152
  version: 0.9.4
139
- description: 'Hyperledger Fabric Gateway gRPC SDK generated directly from protos found
140
- at: https://github.com/hyperledger/fabric-protos.'
153
+ - !ruby/object:Gem::Dependency
154
+ name: yard
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: 0.9.27
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: 0.9.27
167
+ description: Ruby port of the Hyperledger Fabric Gateway SDK
141
168
  email:
142
169
  - jonathan.chan@ethicalidentity.com
143
170
  executables: []
@@ -145,8 +172,11 @@ extensions: []
145
172
  extra_rdoc_files: []
146
173
  files:
147
174
  - ".editorconfig"
175
+ - ".github/workflows/codeql-analysis.yml"
148
176
  - ".github/workflows/rspec.yml"
149
177
  - ".github/workflows/rubocop.yml"
178
+ - ".github/workflows/todo.yml"
179
+ - ".github/workflows/yardoc.yml"
150
180
  - ".gitignore"
151
181
  - ".gitmodules"
152
182
  - ".rspec"
@@ -154,6 +184,7 @@ files:
154
184
  - ".ruby-version"
155
185
  - ".travis.yml"
156
186
  - ".vscode/settings.json"
187
+ - ".yardopts"
157
188
  - CHANGELOG.md
158
189
  - CODE_OF_CONDUCT.md
159
190
  - Gemfile
@@ -171,15 +202,22 @@ files:
171
202
  - lib/common/policies_pb.rb
172
203
  - lib/fabric.rb
173
204
  - lib/fabric/.DS_Store
205
+ - lib/fabric/accessors/contract.rb
206
+ - lib/fabric/accessors/gateway.rb
207
+ - lib/fabric/accessors/network.rb
174
208
  - lib/fabric/client.rb
175
209
  - lib/fabric/constants.rb
176
210
  - lib/fabric/contract.rb
177
211
  - lib/fabric/ec_crypto_suite.rb
212
+ - lib/fabric/entities/chaincode_events_requests.rb
213
+ - lib/fabric/entities/envelope.rb
214
+ - lib/fabric/entities/identity.rb
215
+ - lib/fabric/entities/proposal.rb
216
+ - lib/fabric/entities/proposed_transaction.rb
217
+ - lib/fabric/entities/status.rb
218
+ - lib/fabric/entities/transaction.rb
178
219
  - lib/fabric/gateway.rb
179
- - lib/fabric/identity.rb
180
220
  - lib/fabric/network.rb
181
- - lib/fabric/proposal.rb
182
- - lib/fabric/proposed_transaction.rb
183
221
  - lib/fabric/version.rb
184
222
  - lib/gateway/gateway_pb.rb
185
223
  - lib/gateway/gateway_services_pb.rb
@@ -217,5 +255,5 @@ requirements: []
217
255
  rubygems_version: 3.1.6
218
256
  signing_key:
219
257
  specification_version: 4
220
- summary: Hyperledger Fabric Gateway gRPC SDK
258
+ summary: Hyperledger Fabric Gateway SDK
221
259
  test_files: []