hyperledger / fabric-gateway

Go, Node and Java client API for Hyperledger Fabric v2.4+
https://hyperledger.github.io/fabric-gateway/
Apache License 2.0
150 stars 87 forks source link

Node.js package @hyperledger/fabric-gateway 1.3.1 breaks on s390x #628

Closed silliman closed 12 months ago

silliman commented 12 months ago

The current version of the npm package for @hyperledger/fabric-gateway (version 1.3.1) causes an error on the s390x architecture due to the @noble/hashes not supporting s390x's "Big-endian" architecture.

To reproduce, I used the "application-gateway-typescript" sample front-end app within the the "asset-transfer-basic" folder of the hyperledger/fabric-samples GitHub repo.

When running the sample I received this error:

> asset-transfer-basic@1.0.0 start
> node dist/app.js

/home/barry/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript/node_modules/@noble/hashes/utils.js:28
    throw new Error('Non little-endian hardware is not supported');
    ^

Error: Non little-endian hardware is not supported
    at Object.<anonymous> (/home/barry/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript/node_modules/@noble/hashes/utils.js:28:11)
    at Module._compile (node:internal/modules/cjs/loader:1256:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
    at Module.load (node:internal/modules/cjs/loader:1119:32)
    at Module._load (node:internal/modules/cjs/loader:960:12)
    at Module.require (node:internal/modules/cjs/loader:1143:19)
    at require (node:internal/modules/cjs/helpers:121:18)
    at Object.<anonymous> (/home/barry/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript/node_modules/@noble/hashes/hmac.js:5:20)
    at Module._compile (node:internal/modules/cjs/loader:1256:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)

Research in the fabric-gateway GitHub repo showed that use of the @noble/hash and curves was added just after the 1.2.2 release of fabric-gateway, so as a workaround, if I use version 1.2.2 of @hyperledger/fabric-gateway, then things work.

I am testing on the same host that is running a Fabric 3.0.0-preview test network running on Ubuntu 20.04.6, using the hyperledger/fabric-samples GitHub repo's main branch, which was at commit f2c1c59 when I tested with it yesterday and today. (6-7 September 2023)

bestbeforetoday commented 12 months ago

@silliman Is it possible for you to try out @hyperledger/fabric-gateway@unstable to see if that successfully fixes the problem on s390x? A fix was published as @hyperledger/fabric-gateway@1.3.2-dev.20230911.1, and tagged as unstable. If this fix works for you then I will publish it as a v1.3.2 release.

silliman commented 12 months ago

Thank you @bestbeforetoday, the fix does work. I installed a new chaincode to get a fresh ledger, changed package.json to point to the @hyperledger/fabric-gateway@unstable and then the sample gives the expected results:

barry@fabric01:~/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript$ rm -rf node_modules package-lock.json
barry@fabric01:~/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript$ npm install

> asset-transfer-basic@1.0.0 prepare
> npm run build

> asset-transfer-basic@1.0.0 build
> tsc

added 177 packages, and audited 178 packages in 25s

35 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
barry@fabric01:~/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript$ grep fabric-gateway package-lock.json
                "@hyperledger/fabric-gateway": "unstable"
        "node_modules/@hyperledger/fabric-gateway": {
            "resolved": "https://registry.npmjs.org/@hyperledger/fabric-gateway/-/fabric-gateway-1.3.2-dev.20230911.1.tgz",
barry@fabric01:~/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript$ npm start

> asset-transfer-basic@1.0.0 start
> node dist/app.js

channelName:       mychannel
chaincodeName:     basicgo4
mspId:             Org1MSP
cryptoPath:        /home/barry/go/src/github.com/silliman/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com
keyDirectoryPath:  /home/barry/go/src/github.com/silliman/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/keystore
certPath:          /home/barry/go/src/github.com/silliman/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/signcerts/cert.pem
tlsCertPath:       /home/barry/go/src/github.com/silliman/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
peerEndpoint:      localhost:7051
peerHostAlias:     peer0.org1.example.com

--> Submit Transaction: InitLedger, function creates the initial set of assets on the ledger
*** Transaction committed successfully

--> Evaluate Transaction: GetAllAssets, function returns all the current assets on the ledger
*** Result: [
  {
    AppraisedValue: 300,
    Color: 'blue',
    ID: 'asset1',
    Owner: 'Tomoko',
    Size: 5
  },
  {
    AppraisedValue: 400,
    Color: 'red',
    ID: 'asset2',
    Owner: 'Brad',
    Size: 5
  },
  {
    AppraisedValue: 500,
    Color: 'green',
    ID: 'asset3',
    Owner: 'Jin Soo',
    Size: 10
  },
  {
    AppraisedValue: 600,
    Color: 'yellow',
    ID: 'asset4',
    Owner: 'Max',
    Size: 10
  },
  {
    AppraisedValue: 700,
    Color: 'black',
    ID: 'asset5',
    Owner: 'Adriana',
    Size: 15
  },
  {
    AppraisedValue: 800,
    Color: 'white',
    ID: 'asset6',
    Owner: 'Michel',
    Size: 15
  }
]

--> Submit Transaction: CreateAsset, creates new asset with ID, Color, Size, Owner and AppraisedValue arguments
*** Transaction committed successfully

--> Async Submit Transaction: TransferAsset, updates existing asset owner
*** Successfully submitted transaction to transfer ownership from Tom to Saptha
*** Waiting for transaction commit
*** Transaction committed successfully

--> Evaluate Transaction: ReadAsset, function returns asset attributes
*** Result: {
  AppraisedValue: 1300,
  Color: 'yellow',
  ID: 'asset1694449457740',
  Owner: 'Saptha',
  Size: 5
}

--> Submit Transaction: UpdateAsset asset70, asset70 does not exist and should return an error
*** Successfully caught the error: 
 EndorseError: 10 ABORTED: failed to endorse transaction, see attached details for more info
    at /home/barry/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript/node_modules/@hyperledger/fabric-gateway/dist/client.js:47:347
    at Object.callback (/home/barry/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript/node_modules/@hyperledger/fabric-gateway/dist/client.js:101:27)
    at Object.onReceiveStatus (/home/barry/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript/node_modules/@grpc/grpc-js/build/src/client.js:192:36)
    at Object.onReceiveStatus (/home/barry/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:360:141)
    ... 2 lines matching cause stack trace ...
    at process.processTicksAndRejections (node:internal/process/task_queues:77:11) {
  code: 10,
  details: [
    {
      address: 'peer0.org1.example.com:7051',
      message: 'chaincode response 500, the asset asset70 does not exist',
      mspId: 'Org1MSP'
    }
  ],
  cause: Error: 10 ABORTED: failed to endorse transaction, see attached details for more info
      at callErrorFromStatus (/home/barry/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript/node_modules/@grpc/grpc-js/build/src/call.js:31:19)
      at Object.onReceiveStatus (/home/barry/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript/node_modules/@grpc/grpc-js/build/src/client.js:192:76)
      at Object.onReceiveStatus (/home/barry/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:360:141)
      at Object.onReceiveStatus (/home/barry/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:323:181)
      at /home/barry/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript/node_modules/@grpc/grpc-js/build/src/resolving-call.js:99:78
      at process.processTicksAndRejections (node:internal/process/task_queues:77:11)
  for call at
      at Client.makeUnaryRequest (/home/barry/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript/node_modules/@grpc/grpc-js/build/src/client.js:160:32)
      at /home/barry/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript/node_modules/@hyperledger/fabric-gateway/dist/client.js:47:110
      at new Promise (<anonymous>)
      at GatewayClientImpl.endorse (/home/barry/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript/node_modules/@hyperledger/fabric-gateway/dist/client.js:47:16)
      at ProposalImpl.endorse (/home/barry/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript/node_modules/@hyperledger/fabric-gateway/dist/proposal.js:56:95)
      at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
      at async ContractImpl.submitAsync (/home/barry/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript/node_modules/@hyperledger/fabric-gateway/dist/contract.js:61:29)
      at async ContractImpl.submit (/home/barry/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript/node_modules/@hyperledger/fabric-gateway/dist/contract.js:53:27)
      at async updateNonExistentAsset (/home/barry/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript/dist/app.js:179:9)
      at async main (/home/barry/go/src/github.com/silliman/fabric-samples/asset-transfer-basic/application-gateway-typescript/dist/app.js:92:9) {
    code: 10,
    details: 'failed to endorse transaction, see attached details for more info',
    metadata: Metadata { internalRepr: [Map], options: {} }
  },
  transactionId: '6a51a379b7ff55c8413b8dcdb8658acd3f9cf092e63dd60965222bb16aad1005'
}
bestbeforetoday commented 12 months ago

Excellent! Thank you for the quick feedback. v1.3.2 has now been published including this fix.