You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Use Fabric Gateway client API in high-throughput (#1338)
The high-throughput sample used the deprecated Go SDK. This change
updates the sample to use the currently supported Fabric Gateway client
API and adds some automated testing to ensure the sample works
correctly.
Signed-off-by: Mark S. Lewis <Mark.S.Lewis@outlook.com>
Copy file name to clipboardExpand all lines: high-throughput/README.md
+28-13Lines changed: 28 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,6 +7,7 @@
7
7
# High-Throughput Network
8
8
9
9
## Purpose
10
+
10
11
This network is used to understand how to properly design the chaincode data model when handling thousands of transactions per second which all
11
12
update the same asset in the ledger. A naive implementation would use a single key to represent the data for the asset, and the chaincode would
12
13
then attempt to update this key every time a transaction involving it comes in. However, when many transactions all come in at once, in the time
@@ -17,6 +18,7 @@ which are aggregated when the value must be retrieved. In this way, no single ro
17
18
is considered.
18
19
19
20
## Use Case
21
+
20
22
The primary use case for this chaincode data model design is for applications in which a particular asset has an associated amount that is
21
23
frequently added to or removed from. For example, with a bank or credit card account, money is either paid to or paid out of it, and the amount
22
24
of money in the account is the result of all of these additions and subtractions aggregated together. A typical person's bank account may not be
@@ -94,18 +96,21 @@ and assumed to be correct and at minimal risk to either company simply due to Am
94
96
must be verified before approval and admittance to the chain.
95
97
96
98
## How
99
+
97
100
This sample provides the chaincode and scripts required to run a high-throughput application on the Fabric test network.
98
101
99
102
### Start the network
100
103
101
104
You can use the `startFabric.sh` script to create an instance of the Fabric test network with a single channel named `mychannel`. The script then deploys the `high-throughput` chaincode to the channel by installing it on the test network peers and committing the chaincode definition to the channel.
102
105
103
106
Change back into the `high-throughput` directory in `fabic-samples`. Start the network and deploy the chaincode by issuing the following command:
107
+
104
108
```
105
109
./startFabric.sh
106
110
```
107
111
108
112
If successful, you will see messages of the Fabric test network being created and the chaincode being deployed, followed by the execution time of the script:
113
+
109
114
```
110
115
Total setup execution time : 81 secs ...
111
116
```
@@ -115,60 +120,71 @@ The `high-throughput` chaincode is now ready to receive invocations.
115
120
### Invoke the chaincode
116
121
117
122
You can invoke the `high-througput` chaincode using a Go application in the `application-go` folder. The Go application will allow us to submit many transactions to the network concurrently. Navigate to the application:
123
+
118
124
```
119
125
cd application-go
120
126
```
121
127
122
128
#### Update
123
-
The format for update is: `go run app.go update name value operation` where `name` is the name of the variable to update, `value` is the value to add to the variable, and `operation` is either `+` or `-` depending on what type of operation you'd like to add to the variable.
124
129
125
-
Example: `go run app.go update myvar 100 +`
130
+
The format for update is: `go run . update name value operation` where `name` is the name of the variable to update, `value` is the value to add to the variable, and `operation` is either `+` or `-` depending on what type of operation you'd like to add to the variable.
131
+
132
+
Example: `go run . update myvar 100 +`
126
133
127
134
#### Query
128
-
You can query the value of a variable by running `go run app.go get name` where `name` is the name of the variable to get.
129
135
130
-
Example: `go run app.go get myvar`
136
+
You can query the value of a variable by running `go run . get name` where `name` is the name of the variable to get.
137
+
138
+
Example: `go run . get myvar`
131
139
132
140
#### Prune
141
+
133
142
Pruning takes all the deltas generated for a variable and combines them all into a single row, deleting all previous rows. This helps cleanup the ledger when many updates have been performed.
134
143
135
-
The format for pruning is: `go run app.go prune name` where `name` is the name of the variable to prune.
144
+
The format for pruning is: `go run . prune name` where `name` is the name of the variable to prune.
136
145
137
-
Example: `go run app.go prune myvar`
146
+
Example: `go run . prune myvar`
138
147
139
148
#### Delete
140
-
The format for delete is: `go run app.go delete name` where `name` is the name of the variable to delete.
141
149
142
-
Example: `go run app.go delete myvar`
150
+
The format for delete is: `go run . delete name` where `name` is the name of the variable to delete.
151
+
152
+
Example: `go run . delete myvar`
143
153
144
154
### Test the Network
145
155
146
-
The application provides two methods that demonstrate the advantages of this system by submitting many concurrent transactions to the smart contract: `manyUpdates` and `manyUpdatesTraditional`. The first function accepts the same arguments as `update-invoke.sh` but runs the invocation 1000 times in parallel. The final value, therefore, should be the given update value * 1000.
156
+
The application provides two methods that demonstrate the advantages of this system by submitting many concurrent transactions to the smart contract: `manyUpdates` and `manyUpdatesTraditional`. The first function accepts the same arguments as `update-invoke.sh` but runs the invocation 1000 times in parallel. The final value, therefore, should be the given update value \* 1000.
147
157
148
158
The second function, `manyUpdatesTraditional`, submits 1000 transactions that attempt to update the same key in the world state 1000 times.
149
159
150
160
Run the following command to create and update `testvar1` a 1000 times:
161
+
151
162
```
152
-
go run app.go manyUpdates testvar1 100 +
163
+
go run . manyUpdates testvar1 100 +
153
164
```
154
165
155
166
The application will query the variable after submitting the transaction. The result should be `100000`.
156
167
157
168
We will now see what happens when you try to run 1000 concurrent updates using a traditional transaction. Run the following command to create a variable named `testvar2`:
169
+
158
170
```
159
-
go run app.go update testvar2 100 +
171
+
go run . update testvar2 100 +
160
172
```
173
+
161
174
The variable will have a value of 100:
175
+
162
176
```
163
177
2020/10/27 18:01:45 Value of variable testvar2 : 100
164
178
```
165
179
166
180
Now lets try to update `testvar2` 1000 times in parallel:
181
+
167
182
```
168
-
go run app.go manyUpdatesTraditional testvar2 100 +
183
+
go run . manyUpdatesTraditional testvar2 100 +
169
184
```
170
185
171
186
When the program ends, you may see that none of the updates succeeded.
187
+
172
188
```
173
189
2020/10/27 18:03:15 Final value of variable testvar2 : 100
174
190
```
@@ -177,7 +193,6 @@ The transactions failed because multiple transactions in each block updated the
177
193
178
194
You can can examine the peer logs to view the messages generated by the rejected blocks:
0 commit comments