diff --git a/.eslintignore b/.eslintignore index f05b1f265d..e998250561 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1,3 @@ node_modules test +.tmp/ \ No newline at end of file diff --git a/.gitignore b/.gitignore index 6203d7b5ac..8ac14f252e 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ typings/ examples/simple-asset-transfer/fabric/**/hfc-key-store/ bin/ +.tmp/ \ No newline at end of file diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000000..cecf93dc7f --- /dev/null +++ b/.npmignore @@ -0,0 +1,8 @@ +.github/ +.tmp/ +.vscode/ +bin/ +docs/ +examples/ +testes/ +tools/ \ No newline at end of file diff --git a/docs/architecture/leader-election/deployment-diagram.puml b/docs/architecture/leader-election/deployment-diagram.puml new file mode 100644 index 0000000000..3a51113460 --- /dev/null +++ b/docs/architecture/leader-election/deployment-diagram.puml @@ -0,0 +1,46 @@ +@startuml leader-election-etcd-leases-deployment-caption +!include +!include +!include + +center header +Hyperledger Blockchain Integration Framework + +endheader + +title + Leader Election Deployment Diagram + +end title + +center footer Hyperledger Blockchain Integration Framework, 2019 + +frame BIF { + + frame Etcd_Cluster as ec { + OFF_DATABASE_SERVER(etcd1,"Etcd 1") + OFF_DATABASE_SERVER(etcd2,"Etcd 2") + OFF_DATABASE_SERVER(etcdn,"Etcd N") + } + + frame Validator_Cluster as vc { + OFF_APPLICATION_SERVER(bvn1,"Validator 1") + OFF_APPLICATION_SERVER(bvn2,"Validator 2") + OFF_APPLICATION_SERVER(bvnn,"Validator N") + } + +} + +bvn2 <~~> bvnn +bvn1 <~> bvn2 +bvn1 <~> bvnn + +etcd1 <~~> etcd2 +etcd1 <~> etcdn +etcd2 <~> etcdn + +bvn1 <=[#blue]=> ec +bvn2 <=[#blue]=> ec +bvnn <=[#blue]=> ec + +@enduml diff --git a/docs/architecture/leader-election/etcd-leases.md b/docs/architecture/leader-election/etcd-leases.md new file mode 100644 index 0000000000..d400baaebe --- /dev/null +++ b/docs/architecture/leader-election/etcd-leases.md @@ -0,0 +1,22 @@ +# Leader Election via Etcd's Distributed Synchronization Primitives + +## Summary + +Validators nodes self-elect a leader by leveraging the Etcd API's `watch` and `lease` features. BIF depends on Etcd API version 3, but other than that it's able to work with any Etcd cluster or single node configuration as long as connectivity is achievable. + +At startup, each node attempts to make themselves leader, which will only succeed if there is no current leader. + +If a validator node fails to become leader, it starts acting as a follower. +The identity of the leader node is stored under a specific key in Etcd on which the leader holds the lease. + +Followers are watching the key storing the leaders identity and react to changes as soon as the change is detected, there is no polling that would waste network/compute resources. + +Stability of the leader election is guaranteed by the Raft algorithm that Etcd uses under the hood. + +## Deployment Diagram + +![leader-election-etcd-leases-deployment-caption](https://www.plantuml.com/plantuml/png/0/bPDHIyCm58NVyokkyqN1CbUVX6siSnqEn8cJlOYCBBtJOfgKD9qCqT_kJLPhf-Am5Cev-UxDIT8C2ikDBJC94dc29a29mgPQ1MX54f1PO14ac4kzoL3PGF3S3RE3L0bP9WXTM-OyCMTjeRDCgtvZHAzMgS3s3CqQJT5EkELBwhSelF47oVDSfeAxYMgO2PeU3JpvdEnoawEHc3oIDPHQF8iddYgO4FDeV2MC3S_mHPjdnb0bLHspgPN80Bfb_yfR45TBXb6zJ1YbdDfatNRPzzMmBViCiTBQVVuJuWJ2qyuvOojdm70oXbT6CROofirUNCYoS5rv0IXe5EYPZiUBKNGN3QDPl9Z5j_FuziYTJEUavMgWqph-amihBjp3gOgxzjpRLx8vboaTd3RDUEjclEZcvcfo4TrDfjUV7PThHG7hqfsKl-DX4m_tugg9rvdfTQsW-_xU1qSvsI7fLRYZ51shsySjxBUgDhPQUHqsTDMWTt-ub2K-zCWNrOm_FFNTOmFwZUYYVG00 "leader-election-etcd-leases-deployment-caption") + +## Validator Node State Diagram + +![state-diagram-validator](https://www.plantuml.com/plantuml/png/0/XL9DRy8m3BtdL_WsQLgrZziGGkm3j4re5v1sM7R86WCHgLsbPen_FxUbG4yxrNrvp-_PoRWIbsHRHD12CFF1hP8hiXyNWtV2oHW94X4i3RUZ6JgF2IOHSmbCCAyryDngXjVRaIMpP1RbM7hPbvWY-fN-FKRED_dQ1O9N4bHwev-g37USDbTmTtDxRypdvHTasQXkd0IzENmRxCcHhpDXXmxWdJs-pQ5Cd6DL6NEam00UHB0efG9Xu6zHQqlgIm9g7D5LQ8cNC97SmmRtffrj07DKJOUgs184kQY0Trfu95t7tamvHjxLz0yd-HfRXQLM0Xvr1KKWjOXDMzKVjMSfTQfJfoQJIYdeu1qCvuDtdCLY1lXRXeI7rF-nUexTe2shMOaQddEKj6ZoE-b5wUETTHyrfxevqXirPepazOtz0G00 "state-diagram-validator") \ No newline at end of file diff --git a/docs/architecture/leader-election/state-diagram-validator.puml b/docs/architecture/leader-election/state-diagram-validator.puml new file mode 100644 index 0000000000..598cf0ac09 --- /dev/null +++ b/docs/architecture/leader-election/state-diagram-validator.puml @@ -0,0 +1,25 @@ +@startuml state-diagram-validator + +title \nLeader Election State Diagram\n +footer \nHyperledger Blockchain Integration Framework, 2019 + +[*] --> Started +Started --> Candidate +Started: NodeJS process + +Candidate : Attempts to obtain\ngrant on lease\nof Etcd key +Leader: Sets Etcd key to\n it's own identity +Follower: Watches Etcd\nkey to determine\nleader's identity + +Candidate -> Follower: lease denied +Follower -> Candidate: lease TTL expire +Leader -> Candidate: lease TTL expire +Candidate -> Leader: lease granted + +Candidate --> Terminated +Follower --> Terminated +Leader --> Terminated + +Terminated --> [*] + +@enduml \ No newline at end of file diff --git a/examples/simple-asset-transfer/app.js b/examples/simple-asset-transfer/app.js index 19915c55fd..d04e86b2cc 100755 --- a/examples/simple-asset-transfer/app.js +++ b/examples/simple-asset-transfer/app.js @@ -1,4 +1,4 @@ -const Validator = require(`@hyperledger-labs/blockchain-integration-framework`).Validator; +const { Validator } = require(`@hyperledger-labs/blockchain-integration-framework`); const { genKeyFile } = require(`@hyperledger-labs/blockchain-integration-framework`).cryptoUtils; const ConnectorFabric = require(`./fabric/connector`); const ConnectorQuorum = require(`./quorum/connector`); @@ -7,14 +7,11 @@ const ConnectorCorda = require(`./corda/connector`); (async () => { const keypair = await genKeyFile(`/federation/keypair`); const validatorOptions = { + etcdHosts: process.env.ETCD_HOSTS.split(','), clientRepAddr: process.env.CLIENT_REP_ADDR, pubAddr: process.env.PUB_ADDR, repAddr: process.env.REP_ADDR, - leaderPubAddr: process.env.LEAD_PUB_ADDR, - leaderRepAddr: process.env.LEAD_REP_ADDR, - leaderClientRepAddr: process.env.LEAD_CLIENT_REP_ADDR, dlType: process.env.DLT_TYPE, - type: process.env.TYPE, pubKey: keypair.pk, privKey: keypair.sk, }; diff --git a/examples/simple-asset-transfer/federations/docker-compose-corda.yml b/examples/simple-asset-transfer/federations/docker-compose-corda.yml index 4618f99464..a92ff37cbe 100644 --- a/examples/simple-asset-transfer/federations/docker-compose-corda.yml +++ b/examples/simple-asset-transfer/federations/docker-compose-corda.yml @@ -12,6 +12,7 @@ services: corda_validator1: image: "federation/validator" environment: + ETCD_HOSTS: "http://etcd1:2379,http://etcd2:2379,http://etcd3:2379" CLIENT_REP_ADDR: "tcp://192.21.0.2:7009" PUB_ADDR: "tcp://192.21.0.2:3009" REP_ADDR: "tcp://192.21.0.2:5009" @@ -19,7 +20,6 @@ services: USER_NAME: "test" PASSWORD: "A665A45920422F9D417E4867EFDC4FB8A04A1F3FFF1FA07E998E86F7F7A27AE3" DLT_TYPE: "CORDA" - TYPE: "LEADER" mem_limit: 6g networks: corda-network: @@ -30,21 +30,22 @@ services: - "7009:7009" - "3009:3009" - "5009:5009" - + depends_on: + - etcd1 + - etcd2 + - etcd3 + corda_validator2: image: "federation/validator" environment: + ETCD_HOSTS: "http://etcd1:2379,http://etcd2:2379,http://etcd3:2379" CLIENT_REP_ADDR: "tcp://192.21.0.3:7010" PUB_ADDR: "tcp://192.21.0.3:3010" REP_ADDR: "tcp://192.21.0.3:5010" - LEAD_PUB_ADDR: "tcp://192.21.0.2:3009" - LEAD_REP_ADDR: "tcp://192.21.0.2:5009" USER_NAME: "test" PASSWORD: "A665A45920422F9D417E4867EFDC4FB8A04A1F3FFF1FA07E998E86F7F7A27AE3" - LEAD_CLIENT_REP_ADDR: "tcp://192.21.0.2:7009" URL: "http://192.21.0.1:10052" DLT_TYPE: "CORDA" - TYPE: "FOLLOWER" mem_limit: 6g expose: - "10052" @@ -56,21 +57,20 @@ services: corda-network: ipv4_address: 192.21.0.3 depends_on: - - "corda_validator1" + - etcd1 + - etcd2 + - etcd3 corda_validator3: image: "federation/validator" environment: + ETCD_HOSTS: "http://etcd1:2379,http://etcd2:2379,http://etcd3:2379" CLIENT_REP_ADDR: "tcp://192.21.0.4:7011" PUB_ADDR: "tcp://192.21.0.4:3011" REP_ADDR: "tcp://192.21.0.4:5011" - LEAD_PUB_ADDR: "tcp://192.21.0.2:3009" - LEAD_REP_ADDR: "tcp://192.21.0.2:5009" USER_NAME: "test" PASSWORD: "A665A45920422F9D417E4867EFDC4FB8A04A1F3FFF1FA07E998E86F7F7A27AE3" - LEAD_CLIENT_REP_ADDR: "tcp://192.21.0.2:7009" URL: "http://192.21.0.1:10053" - TYPE: "FOLLOWER" DLT_TYPE: "CORDA" mem_limit: 6g expose: @@ -83,22 +83,21 @@ services: corda-network: ipv4_address: 192.21.0.4 depends_on: - - "corda_validator1" + - etcd1 + - etcd2 + - etcd3 corda_validator4: image: "federation/validator" environment: + ETCD_HOSTS: "http://etcd1:2379,http://etcd2:2379,http://etcd3:2379" CLIENT_REP_ADDR: "tcp://192.21.0.5:7012" PUB_ADDR: "tcp://192.21.0.5:3012" REP_ADDR: "tcp://192.21.0.5:5012" - LEAD_PUB_ADDR: "tcp://192.21.0.2:3009" - LEAD_REP_ADDR: "tcp://192.21.0.2:5009" USER_NAME: "test" PASSWORD: "A665A45920422F9D417E4867EFDC4FB8A04A1F3FFF1FA07E998E86F7F7A27AE3" - LEAD_CLIENT_REP_ADDR: "tcp://192.21.0.2:7009" URL: "http://192.21.0.1:10054" DLT_TYPE: "CORDA" - TYPE: "FOLLOWER" mem_limit: 6g expose: - "10054" @@ -110,4 +109,54 @@ services: corda-network: ipv4_address: 192.21.0.5 depends_on: - - "corda_validator1" + - etcd1 + - etcd2 + - etcd3 + + etcd1: + image: bitnami/etcd:3 + environment: + - ALLOW_NONE_AUTHENTICATION=yes + - ETCD_NAME=etcd1 + - ETCD_INITIAL_ADVERTISE_PEER_URLS=http://etcd1:2380 + - ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380 + - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 + - ETCD_ADVERTISE_CLIENT_URLS=http://etcd1:2379 + - ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster + - ETCD_INITIAL_CLUSTER=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380 + - ETCD_INITIAL_CLUSTER_STATE=new + networks: + corda-network: + ipv4_address: 192.21.0.50 + + etcd2: + image: bitnami/etcd:3 + environment: + - ALLOW_NONE_AUTHENTICATION=yes + - ETCD_NAME=etcd2 + - ETCD_INITIAL_ADVERTISE_PEER_URLS=http://etcd2:2380 + - ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380 + - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 + - ETCD_ADVERTISE_CLIENT_URLS=http://etcd2:2379 + - ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster + - ETCD_INITIAL_CLUSTER=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380 + - ETCD_INITIAL_CLUSTER_STATE=new + networks: + corda-network: + ipv4_address: 192.21.0.51 + + etcd3: + image: bitnami/etcd:3 + environment: + - ALLOW_NONE_AUTHENTICATION=yes + - ETCD_NAME=etcd3 + - ETCD_INITIAL_ADVERTISE_PEER_URLS=http://etcd3:2380 + - ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380 + - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 + - ETCD_ADVERTISE_CLIENT_URLS=http://etcd3:2379 + - ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster + - ETCD_INITIAL_CLUSTER=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380 + - ETCD_INITIAL_CLUSTER_STATE=new + networks: + corda-network: + ipv4_address: 192.21.0.52 diff --git a/examples/simple-asset-transfer/federations/docker-compose-fabric.yml b/examples/simple-asset-transfer/federations/docker-compose-fabric.yml index 87c2ca4a8b..e95bd4f821 100644 --- a/examples/simple-asset-transfer/federations/docker-compose-fabric.yml +++ b/examples/simple-asset-transfer/federations/docker-compose-fabric.yml @@ -12,6 +12,7 @@ services: fabric_validator1: image: "federation/validator" environment: + ETCD_HOSTS: "http://etcd1:2379,http://etcd2:2379,http://etcd3:2379" CLIENT_REP_ADDR: "tcp://172.20.0.5:7001" PUB_ADDR: "tcp://172.20.0.5:3001" REP_ADDR: "tcp://172.20.0.5:5001" @@ -33,18 +34,20 @@ services: - "3001:3001" - "5001:5001" - "9001:9001" - + depends_on: + - etcd1 + - etcd2 + - etcd3 + fabric_validator2: image: "federation/validator" environment: + ETCD_HOSTS: "http://etcd1:2379,http://etcd2:2379,http://etcd3:2379" CLIENT_REP_ADDR: "tcp://172.20.0.6:7002" PUB_ADDR: "tcp://172.20.0.6:3002" REP_ADDR: "tcp://172.20.0.6:5002" USER_NAME: "Mike" ORG_NAME: "Org1" - LEAD_PUB_ADDR: "tcp://172.20.0.5:3001" - LEAD_REP_ADDR: "tcp://172.20.0.5:5001" - LEAD_CLIENT_REP_ADDR: "tcp://172.20.0.5:7001" URL: "http://172.20.0.1:4000" PEER_NAME: "peer1.org1.example.com" DLT_TYPE: "FABRIC" @@ -62,19 +65,19 @@ services: fabric-network: ipv4_address: 172.20.0.6 depends_on: - - "fabric_validator1" + - etcd1 + - etcd2 + - etcd3 fabric_validator3: image: "federation/validator" environment: + ETCD_HOSTS: "http://etcd1:2379,http://etcd2:2379,http://etcd3:2379" CLIENT_REP_ADDR: "tcp://172.20.0.7:7003" PUB_ADDR: "tcp://172.20.0.7:3003" REP_ADDR: "tcp://172.20.0.7:5003" USER_NAME: "Hugo" ORG_NAME: "Org2" - LEAD_PUB_ADDR: "tcp://172.20.0.5:3001" - LEAD_REP_ADDR: "tcp://172.20.0.5:5001" - LEAD_CLIENT_REP_ADDR: "tcp://172.20.0.5:7001" URL: "http://172.20.0.1:4000" PEER_NAME: "peer0.org2.example.com" TYPE: "FOLLOWER" @@ -92,19 +95,19 @@ services: fabric-network: ipv4_address: 172.20.0.7 depends_on: - - "fabric_validator1" + - etcd1 + - etcd2 + - etcd3 fabric_validator4: image: "federation/validator" environment: + ETCD_HOSTS: "http://etcd1:2379,http://etcd2:2379,http://etcd3:2379" CLIENT_REP_ADDR: "tcp://172.20.0.8:7004" PUB_ADDR: "tcp://172.20.0.8:3004" REP_ADDR: "tcp://172.20.0.8:5004" USER_NAME: "Luca" ORG_NAME: "Org2" - LEAD_PUB_ADDR: "tcp://172.20.0.5:3001" - LEAD_REP_ADDR: "tcp://172.20.0.5:5001" - LEAD_CLIENT_REP_ADDR: "tcp://172.20.0.5:7001" URL: "http://172.20.0.1:4000" PEER_NAME: "peer1.org2.example.com" DLT_TYPE: "FABRIC" @@ -122,4 +125,54 @@ services: fabric-network: ipv4_address: 172.20.0.8 depends_on: - - "fabric_validator1" + - etcd1 + - etcd2 + - etcd3 + + etcd1: + image: bitnami/etcd:3 + environment: + - ALLOW_NONE_AUTHENTICATION=yes + - ETCD_NAME=etcd1 + - ETCD_INITIAL_ADVERTISE_PEER_URLS=http://etcd1:2380 + - ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380 + - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 + - ETCD_ADVERTISE_CLIENT_URLS=http://etcd1:2379 + - ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster + - ETCD_INITIAL_CLUSTER=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380 + - ETCD_INITIAL_CLUSTER_STATE=new + networks: + fabric-network: + ipv4_address: 172.20.0.50 + + etcd2: + image: bitnami/etcd:3 + environment: + - ALLOW_NONE_AUTHENTICATION=yes + - ETCD_NAME=etcd2 + - ETCD_INITIAL_ADVERTISE_PEER_URLS=http://etcd2:2380 + - ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380 + - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 + - ETCD_ADVERTISE_CLIENT_URLS=http://etcd2:2379 + - ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster + - ETCD_INITIAL_CLUSTER=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380 + - ETCD_INITIAL_CLUSTER_STATE=new + networks: + fabric-network: + ipv4_address: 172.20.0.51 + + etcd3: + image: bitnami/etcd:3 + environment: + - ALLOW_NONE_AUTHENTICATION=yes + - ETCD_NAME=etcd3 + - ETCD_INITIAL_ADVERTISE_PEER_URLS=http://etcd3:2380 + - ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380 + - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 + - ETCD_ADVERTISE_CLIENT_URLS=http://etcd3:2379 + - ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster + - ETCD_INITIAL_CLUSTER=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380 + - ETCD_INITIAL_CLUSTER_STATE=new + networks: + fabric-network: + ipv4_address: 172.20.0.52 diff --git a/examples/simple-asset-transfer/federations/docker-compose-quorum.yml b/examples/simple-asset-transfer/federations/docker-compose-quorum.yml index ea1a5d0fd3..2f2e2a1df8 100644 --- a/examples/simple-asset-transfer/federations/docker-compose-quorum.yml +++ b/examples/simple-asset-transfer/federations/docker-compose-quorum.yml @@ -12,6 +12,7 @@ services: quorum_validator1: image: "federation/validator" environment: + ETCD_HOSTS: "http://etcd1:2379,http://etcd2:2379,http://etcd3:2379" CLIENT_REP_ADDR: "tcp://192.20.0.2:7005" PUB_ADDR: "tcp://192.20.0.2:3005" REP_ADDR: "tcp://192.20.0.2:5005" @@ -19,7 +20,6 @@ services: USER_NAME: "test" PASSWORD: "A665A45920422F9D417E4867EFDC4FB8A04A1F3FFF1FA07E998E86F7F7A27AE3" DLT_TYPE: "QUORUM" - TYPE: "LEADER" API_PORT: 9005 mem_limit: 6g networks: @@ -32,21 +32,22 @@ services: - "3005:3005" - "5005:5005" - "9005:9005" - + depends_on: + - etcd1 + - etcd2 + - etcd3 + quorum_validator2: image: "federation/validator" environment: + ETCD_HOSTS: "http://etcd1:2379,http://etcd2:2379,http://etcd3:2379" CLIENT_REP_ADDR: "tcp://192.20.0.3:7006" PUB_ADDR: "tcp://192.20.0.3:3006" REP_ADDR: "tcp://192.20.0.3:5006" - LEAD_PUB_ADDR: "tcp://192.20.0.2:3005" - LEAD_REP_ADDR: "tcp://192.20.0.2:5005" USER_NAME: "test" PASSWORD: "A665A45920422F9D417E4867EFDC4FB8A04A1F3FFF1FA07E998E86F7F7A27AE3" - LEAD_CLIENT_REP_ADDR: "tcp://192.20.0.2:7005" URL: "http://192.20.0.1:5051" DLT_TYPE: "QUORUM" - TYPE: "FOLLOWER" API_PORT: 9006 mem_limit: 6g expose: @@ -60,21 +61,20 @@ services: quorum-network: ipv4_address: 192.20.0.3 depends_on: - - "quorum_validator1" + - etcd1 + - etcd2 + - etcd3 quorum_validator3: image: "federation/validator" environment: + ETCD_HOSTS: "http://etcd1:2379,http://etcd2:2379,http://etcd3:2379" CLIENT_REP_ADDR: "tcp://192.20.0.4:7007" PUB_ADDR: "tcp://192.20.0.4:3007" REP_ADDR: "tcp://192.20.0.4:5007" - LEAD_PUB_ADDR: "tcp://192.20.0.2:3005" - LEAD_REP_ADDR: "tcp://192.20.0.2:5005" USER_NAME: "test" PASSWORD: "A665A45920422F9D417E4867EFDC4FB8A04A1F3FFF1FA07E998E86F7F7A27AE3" - LEAD_CLIENT_REP_ADDR: "tcp://192.20.0.2:7005" URL: "http://192.20.0.1:5052" - TYPE: "FOLLOWER" DLT_TYPE: "QUORUM" API_PORT: 9007 mem_limit: 6g @@ -89,22 +89,21 @@ services: quorum-network: ipv4_address: 192.20.0.4 depends_on: - - "quorum_validator1" + - etcd1 + - etcd2 + - etcd3 quorum_validator4: image: "federation/validator" environment: + ETCD_HOSTS: "http://etcd1:2379,http://etcd2:2379,http://etcd3:2379" CLIENT_REP_ADDR: "tcp://192.20.0.5:7008" PUB_ADDR: "tcp://192.20.0.5:3008" REP_ADDR: "tcp://192.20.0.5:5008" - LEAD_PUB_ADDR: "tcp://192.20.0.2:3005" - LEAD_REP_ADDR: "tcp://192.20.0.2:5005" USER_NAME: "test" PASSWORD: "A665A45920422F9D417E4867EFDC4FB8A04A1F3FFF1FA07E998E86F7F7A27AE3" - LEAD_CLIENT_REP_ADDR: "tcp://192.20.0.2:7005" URL: "http://192.20.0.1:5053" DLT_TYPE: "QUORUM" - TYPE: "FOLLOWER" API_PORT: 9008 mem_limit: 6g expose: @@ -118,4 +117,54 @@ services: quorum-network: ipv4_address: 192.20.0.5 depends_on: - - "quorum_validator1" + - etcd1 + - etcd2 + - etcd3 + + etcd1: + image: bitnami/etcd:3 + environment: + - ALLOW_NONE_AUTHENTICATION=yes + - ETCD_NAME=etcd1 + - ETCD_INITIAL_ADVERTISE_PEER_URLS=http://etcd1:2380 + - ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380 + - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 + - ETCD_ADVERTISE_CLIENT_URLS=http://etcd1:2379 + - ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster + - ETCD_INITIAL_CLUSTER=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380 + - ETCD_INITIAL_CLUSTER_STATE=new + networks: + quorum-network: + ipv4_address: 192.20.0.50 + + etcd2: + image: bitnami/etcd:3 + environment: + - ALLOW_NONE_AUTHENTICATION=yes + - ETCD_NAME=etcd2 + - ETCD_INITIAL_ADVERTISE_PEER_URLS=http://etcd2:2380 + - ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380 + - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 + - ETCD_ADVERTISE_CLIENT_URLS=http://etcd2:2379 + - ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster + - ETCD_INITIAL_CLUSTER=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380 + - ETCD_INITIAL_CLUSTER_STATE=new + networks: + quorum-network: + ipv4_address: 192.20.0.51 + + etcd3: + image: bitnami/etcd:3 + environment: + - ALLOW_NONE_AUTHENTICATION=yes + - ETCD_NAME=etcd3 + - ETCD_INITIAL_ADVERTISE_PEER_URLS=http://etcd3:2380 + - ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380 + - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 + - ETCD_ADVERTISE_CLIENT_URLS=http://etcd3:2379 + - ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster + - ETCD_INITIAL_CLUSTER=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380 + - ETCD_INITIAL_CLUSTER_STATE=new + networks: + quorum-network: + ipv4_address: 192.20.0.52 diff --git a/examples/simple-asset-transfer/package-lock.json b/examples/simple-asset-transfer/package-lock.json index 950a259dd4..6376ee9fc0 100644 --- a/examples/simple-asset-transfer/package-lock.json +++ b/examples/simple-asset-transfer/package-lock.json @@ -4,10 +4,20 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@grpc/proto-loader": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.5.3.tgz", + "integrity": "sha512-8qvUtGg77G2ZT2HqdqYoM/OY97gQd/0crSG34xNmZ4ZOsv3aQT/FQV9QfZPazTGna6MIoyUd+u6AxsoZjJ/VMQ==", + "requires": { + "lodash.camelcase": "^4.3.0", + "protobufjs": "^6.8.6" + } + }, "@hyperledger-labs/blockchain-integration-framework": { - "version": "git+https://github.com/hyperledger-labs/blockchain-integration-framework.git#d8b959023e6235089dbc333b24ada88c87b881a5", - "from": "git+https://github.com/hyperledger-labs/blockchain-integration-framework.git#fix/peter.somogyvari/make-ci-pass", + "version": "file:../../.tmp/hyperledger-labs-blockchain-integration-framework-dev.tgz", + "integrity": "sha512-CCqK+QlcReTgTd323KHhKnMlmVcG0leKa511IHr3BhFskUPjVcpmq8eSpZpBWi6ruZkyhuEcJGb3F8vxQbD8yw==", "requires": { + "etcd3": "0.2.13", "log4js": "^4.1.0", "prettier": "^1.16.4", "request": "^2.88.0", @@ -15,11 +25,66 @@ "secp256k1": "^3.6.2", "sha3": "^2.0.1", "truffle": "^5.0.14", - "web3": "1.2.2", - "web3-utils": "1.2.2", + "uuid": "3.3.3", + "web3": "1.2.4", + "web3-utils": "1.2.4", "zeromq": "^5.1.0" } }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -33,6 +98,14 @@ "defer-to-connect": "^1.0.1" } }, + "@types/bignumber.js": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/bignumber.js/-/bignumber.js-5.0.0.tgz", + "integrity": "sha512-0DH7aPGCClywOFaxxjE6UwpN2kQYe9LwuDQMv+zYA97j5GkOMo8e66LYT+a8JYU7jfmUFRZLa9KycxHDsKXJCA==", + "requires": { + "bignumber.js": "*" + } + }, "@types/bn.js": { "version": "4.11.5", "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.5.tgz", @@ -41,10 +114,60 @@ "@types/node": "*" } }, + "@types/bytebuffer": { + "version": "5.0.40", + "resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.40.tgz", + "integrity": "sha512-h48dyzZrPMz25K6Q4+NCwWaxwXany2FhQg/ErOcdZS1ZpsaDnDMZg8JYLMTGz7uvXKrcKGJUZJlZObyfgdaN9g==", + "requires": { + "@types/long": "*", + "@types/node": "*" + } + }, + "@types/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz", + "integrity": "sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q==" + }, "@types/node": { - "version": "12.12.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.8.tgz", - "integrity": "sha512-XLla8N+iyfjvsa0KKV+BP/iGSoTmwxsu5Ci5sM33z9TjohF72DEz95iNvD6pPmemvbQgxAv/909G73gUn8QR7w==" + "version": "10.17.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.5.tgz", + "integrity": "sha512-RElZIr/7JreF1eY6oD5RF3kpmdcreuQPjg5ri4oQ5g9sq7YWU8HkfB3eH8GwAwxf5OaCh0VPi7r4N/yoTGelrA==" + }, + "@web3-js/scrypt-shim": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@web3-js/scrypt-shim/-/scrypt-shim-0.1.0.tgz", + "integrity": "sha512-ZtZeWCc/s0nMcdx/+rZwY1EcuRdemOK9ag21ty9UsHkFxsNb/AaoucUz0iPuyGe0Ku+PFuRmWZG7Z7462p9xPw==", + "requires": { + "scryptsy": "^2.1.0", + "semver": "^6.3.0" + } + }, + "@web3-js/websocket": { + "version": "1.0.30", + "resolved": "https://registry.npmjs.org/@web3-js/websocket/-/websocket-1.0.30.tgz", + "integrity": "sha512-fDwrD47MiDrzcJdSeTLF75aCcxVVt8B1N74rA+vh2XCAvFy4tEWJjtnUtj2QG7/zlQ6g9cQ88bZFBxwd9/FmtA==", + "requires": { + "debug": "^2.2.0", + "es5-ext": "^0.10.50", + "nan": "^2.14.0", + "typedarray-to-buffer": "^3.1.5", + "yaeti": "^0.0.6" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } }, "accepts": { "version": "1.3.7", @@ -195,6 +318,15 @@ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, + "ascli": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz", + "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=", + "requires": { + "colour": "~0.7.1", + "optjs": "~3.2.2" + } + }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -346,6 +478,11 @@ "tweetnacl": "^0.14.3" } }, + "bignumber.js": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-5.0.0.tgz", + "integrity": "sha512-KWTu6ZMVk9sxlDJQh2YH1UOnfDP8O8TpxUxgQG/vKASoSnEjK9aVuOueFaPcQEYQ5fyNXNTOYwYw3099RYebWg==" + }, "bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", @@ -448,6 +585,12 @@ "color-convert": "^1.9.0" } }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -625,6 +768,21 @@ "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", "dev": true }, + "bytebuffer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", + "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", + "requires": { + "long": "~3" + }, + "dependencies": { + "long": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", + "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=" + } + } + }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -680,10 +838,9 @@ } }, "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" }, "camelcase-keys": { "version": "2.1.0", @@ -693,14 +850,6 @@ "requires": { "camelcase": "^2.0.0", "map-obj": "^1.0.0" - }, - "dependencies": { - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - } } }, "capture-stack-trace": { @@ -786,7 +935,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1", @@ -827,6 +975,11 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, + "colour": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz", + "integrity": "sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g=" + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1065,8 +1218,7 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, "decode-uri-component": { "version": "0.2.0", @@ -1199,6 +1351,98 @@ "require-package-name": "^2.0.1", "walkdir": "0.0.11", "yargs": "^8.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "dev": true, + "requires": { + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "yargs": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", + "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", + "dev": true, + "requires": { + "camelcase": "^4.1.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "read-pkg-up": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^7.0.0" + } + } } }, "depd": { @@ -1404,6 +1648,16 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, + "etcd3": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/etcd3/-/etcd3-0.2.13.tgz", + "integrity": "sha512-9zVnoebQRwOGivGT9/bFHQsjkcZttgzyDU50G1J27tdU76vmgp78YGOAEe9zzEjU6IEFa2KYYUg5AyMKDOp37A==", + "requires": { + "@grpc/proto-loader": "^0.5.1", + "bignumber.js": "^5.0.0", + "grpc": "^1.21.1" + } + }, "eth-ens-namehash": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", @@ -1494,11 +1748,6 @@ "xmlhttprequest": "1.8.0" }, "dependencies": { - "@types/node": { - "version": "10.17.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.5.tgz", - "integrity": "sha512-RElZIr/7JreF1eY6oD5RF3kpmdcreuQPjg5ri4oQ5g9sq7YWU8HkfB3eH8GwAwxf5OaCh0VPi7r4N/yoTGelrA==" - }, "elliptic": { "version": "6.3.3", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.3.3.tgz", @@ -2097,6 +2346,435 @@ "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" }, + "grpc": { + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.24.2.tgz", + "integrity": "sha512-EG3WH6AWMVvAiV15d+lr+K77HJ/KV/3FvMpjKjulXHbTwgDZkhkcWbwhxFAoTdxTkQvy0WFcO3Nog50QBbHZWw==", + "requires": { + "@types/bytebuffer": "^5.0.40", + "lodash.camelcase": "^4.3.0", + "lodash.clone": "^4.5.0", + "nan": "^2.13.2", + "node-pre-gyp": "^0.14.0", + "protobufjs": "^5.0.3" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.3", + "bundled": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true + }, + "debug": { + "version": "3.2.6", + "bundled": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true + }, + "fs-minipass": { + "version": "1.2.7", + "bundled": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.4", + "bundled": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.3", + "bundled": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "bundled": true + }, + "ini": { + "version": "1.3.5", + "bundled": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "bundled": true + }, + "minipass": { + "version": "2.9.0", + "bundled": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "bundled": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "bundled": true + } + } + }, + "ms": { + "version": "2.1.2", + "bundled": true + }, + "needle": { + "version": "2.4.0", + "bundled": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.14.0", + "bundled": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true + }, + "npm-packlist": { + "version": "1.4.6", + "bundled": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true + }, + "process-nextick-args": { + "version": "2.0.1", + "bundled": true + }, + "protobufjs": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.3.tgz", + "integrity": "sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==", + "requires": { + "ascli": "~1", + "bytebuffer": "~5", + "glob": "^7.0.5", + "yargs": "^3.10.0" + } + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.7.1", + "bundled": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true + }, + "sax": { + "version": "1.2.4", + "bundled": true + }, + "semver": { + "version": "5.7.1", + "bundled": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true + }, + "tar": { + "version": "4.4.13", + "bundled": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true + }, + "yallist": { + "version": "3.1.1", + "bundled": true + } + } + }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -2364,8 +3042,7 @@ "invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" }, "ipaddr.js": { "version": "1.9.0", @@ -2688,7 +3365,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, "requires": { "invert-kv": "^1.0.0" } @@ -2740,6 +3416,16 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + }, + "lodash.clone": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", + "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=" + }, "lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -2798,6 +3484,11 @@ "streamroller": "^1.0.6" } }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -3343,6 +4034,11 @@ "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", "dev": true }, + "optjs": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", + "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=" + }, "ora": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/ora/-/ora-0.2.3.tgz", @@ -3361,37 +4057,11 @@ "integrity": "sha1-DxMEcVhM0zURxew4yNWSE/msXiA=" }, "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "dev": true, + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - }, - "dependencies": { - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - } + "lcid": "^1.0.0" } }, "p-cancelable": { @@ -3731,6 +4401,26 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "protobufjs": { + "version": "6.8.8", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", + "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.0", + "@types/node": "^10.1.0", + "long": "^4.0.0" + } + }, "proxy-addr": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", @@ -4109,14 +4799,6 @@ "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.3.tgz", "integrity": "sha1-uwBAvgMEPamgEqLOqfyfhSz8h9Q=" }, - "scrypt-shim": { - "version": "github:web3-js/scrypt-shim#be5e616323a8b5e568788bf94d03c1b8410eac54", - "from": "github:web3-js/scrypt-shim", - "requires": { - "scryptsy": "^2.1.0", - "semver": "^6.3.0" - } - }, "scryptsy": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-2.1.0.tgz", @@ -4947,151 +5629,159 @@ "dev": true }, "web3": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.2.2.tgz", - "integrity": "sha512-/ChbmB6qZpfGx6eNpczt5YSUBHEA5V2+iUCbn85EVb3Zv6FVxrOo5Tv7Lw0gE2tW7EEjASbCyp3mZeiZaCCngg==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/web3/-/web3-1.2.4.tgz", + "integrity": "sha512-xPXGe+w0x0t88Wj+s/dmAdASr3O9wmA9mpZRtixGZxmBexAF0MjfqYM+MS4tVl5s11hMTN3AZb8cDD4VLfC57A==", "requires": { "@types/node": "^12.6.1", - "web3-bzz": "1.2.2", - "web3-core": "1.2.2", - "web3-eth": "1.2.2", - "web3-eth-personal": "1.2.2", - "web3-net": "1.2.2", - "web3-shh": "1.2.2", - "web3-utils": "1.2.2" + "web3-bzz": "1.2.4", + "web3-core": "1.2.4", + "web3-eth": "1.2.4", + "web3-eth-personal": "1.2.4", + "web3-net": "1.2.4", + "web3-shh": "1.2.4", + "web3-utils": "1.2.4" + }, + "dependencies": { + "@types/node": { + "version": "12.12.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.10.tgz", + "integrity": "sha512-rhG2F0v4nNMqcPM4dMSne7R9iBzehUnARYbJq7G36CoczcqjNWuriAy6kd6quT30ISmfBhIRFVYDMSLrBASHNw==" + } } }, "web3-bzz": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.2.2.tgz", - "integrity": "sha512-b1O2ObsqUN1lJxmFSjvnEC4TsaCbmh7Owj3IAIWTKqL9qhVgx7Qsu5O9cD13pBiSPNZJ68uJPaKq380QB4NWeA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.2.4.tgz", + "integrity": "sha512-MqhAo/+0iQSMBtt3/QI1rU83uvF08sYq8r25+OUZ+4VtihnYsmkkca+rdU0QbRyrXY2/yGIpI46PFdh0khD53A==", "requires": { "@types/node": "^10.12.18", "got": "9.6.0", "swarm-js": "0.1.39", "underscore": "1.9.1" - }, - "dependencies": { - "@types/node": { - "version": "10.17.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.5.tgz", - "integrity": "sha512-RElZIr/7JreF1eY6oD5RF3kpmdcreuQPjg5ri4oQ5g9sq7YWU8HkfB3eH8GwAwxf5OaCh0VPi7r4N/yoTGelrA==" - } } }, "web3-core": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.2.2.tgz", - "integrity": "sha512-miHAX3qUgxV+KYfaOY93Hlc3kLW2j5fH8FJy6kSxAv+d4d5aH0wwrU2IIoJylQdT+FeenQ38sgsCnFu9iZ1hCQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.2.4.tgz", + "integrity": "sha512-CHc27sMuET2cs1IKrkz7xzmTdMfZpYswe7f0HcuyneTwS1yTlTnHyqjAaTy0ZygAb/x4iaVox+Gvr4oSAqSI+A==", "requires": { + "@types/bignumber.js": "^5.0.0", "@types/bn.js": "^4.11.4", "@types/node": "^12.6.1", - "web3-core-helpers": "1.2.2", - "web3-core-method": "1.2.2", - "web3-core-requestmanager": "1.2.2", - "web3-utils": "1.2.2" + "web3-core-helpers": "1.2.4", + "web3-core-method": "1.2.4", + "web3-core-requestmanager": "1.2.4", + "web3-utils": "1.2.4" + }, + "dependencies": { + "@types/node": { + "version": "12.12.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.10.tgz", + "integrity": "sha512-rhG2F0v4nNMqcPM4dMSne7R9iBzehUnARYbJq7G36CoczcqjNWuriAy6kd6quT30ISmfBhIRFVYDMSLrBASHNw==" + } } }, "web3-core-helpers": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.2.tgz", - "integrity": "sha512-HJrRsIGgZa1jGUIhvGz4S5Yh6wtOIo/TMIsSLe+Xay+KVnbseJpPprDI5W3s7H2ODhMQTbogmmUFquZweW2ImQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.4.tgz", + "integrity": "sha512-U7wbsK8IbZvF3B7S+QMSNP0tni/6VipnJkB0tZVEpHEIV2WWeBHYmZDnULWcsS/x/jn9yKhJlXIxWGsEAMkjiw==", "requires": { "underscore": "1.9.1", - "web3-eth-iban": "1.2.2", - "web3-utils": "1.2.2" + "web3-eth-iban": "1.2.4", + "web3-utils": "1.2.4" } }, "web3-core-method": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.2.2.tgz", - "integrity": "sha512-szR4fDSBxNHaF1DFqE+j6sFR/afv9Aa36OW93saHZnrh+iXSrYeUUDfugeNcRlugEKeUCkd4CZylfgbK2SKYJA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.2.4.tgz", + "integrity": "sha512-8p9kpL7di2qOVPWgcM08kb+yKom0rxRCMv6m/K+H+yLSxev9TgMbCgMSbPWAHlyiF3SJHw7APFKahK5Z+8XT5A==", "requires": { "underscore": "1.9.1", - "web3-core-helpers": "1.2.2", - "web3-core-promievent": "1.2.2", - "web3-core-subscriptions": "1.2.2", - "web3-utils": "1.2.2" + "web3-core-helpers": "1.2.4", + "web3-core-promievent": "1.2.4", + "web3-core-subscriptions": "1.2.4", + "web3-utils": "1.2.4" } }, "web3-core-promievent": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.2.2.tgz", - "integrity": "sha512-tKvYeT8bkUfKABcQswK6/X79blKTKYGk949urZKcLvLDEaWrM3uuzDwdQT3BNKzQ3vIvTggFPX9BwYh0F1WwqQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.2.4.tgz", + "integrity": "sha512-gEUlm27DewUsfUgC3T8AxkKi8Ecx+e+ZCaunB7X4Qk3i9F4C+5PSMGguolrShZ7Zb6717k79Y86f3A00O0VAZw==", "requires": { "any-promise": "1.3.0", "eventemitter3": "3.1.2" } }, "web3-core-requestmanager": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.2.2.tgz", - "integrity": "sha512-a+gSbiBRHtHvkp78U2bsntMGYGF2eCb6219aMufuZWeAZGXJ63Wc2321PCbA8hF9cQrZI4EoZ4kVLRI4OF15Hw==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.2.4.tgz", + "integrity": "sha512-eZJDjyNTDtmSmzd3S488nR/SMJtNnn/GuwxnMh3AzYCqG3ZMfOylqTad2eYJPvc2PM5/Gj1wAMQcRpwOjjLuPg==", "requires": { "underscore": "1.9.1", - "web3-core-helpers": "1.2.2", - "web3-providers-http": "1.2.2", - "web3-providers-ipc": "1.2.2", - "web3-providers-ws": "1.2.2" + "web3-core-helpers": "1.2.4", + "web3-providers-http": "1.2.4", + "web3-providers-ipc": "1.2.4", + "web3-providers-ws": "1.2.4" } }, "web3-core-subscriptions": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.2.2.tgz", - "integrity": "sha512-QbTgigNuT4eicAWWr7ahVpJyM8GbICsR1Ys9mJqzBEwpqS+RXTRVSkwZ2IsxO+iqv6liMNwGregbJLq4urMFcQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.2.4.tgz", + "integrity": "sha512-3D607J2M8ymY9V+/WZq4MLlBulwCkwEjjC2U+cXqgVO1rCyVqbxZNCmHyNYHjDDCxSEbks9Ju5xqJxDSxnyXEw==", "requires": { "eventemitter3": "3.1.2", "underscore": "1.9.1", - "web3-core-helpers": "1.2.2" + "web3-core-helpers": "1.2.4" } }, "web3-eth": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.2.2.tgz", - "integrity": "sha512-UXpC74mBQvZzd4b+baD4Ocp7g+BlwxhBHumy9seyE/LMIcMlePXwCKzxve9yReNpjaU16Mmyya6ZYlyiKKV8UA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.2.4.tgz", + "integrity": "sha512-+j+kbfmZsbc3+KJpvHM16j1xRFHe2jBAniMo1BHKc3lho6A8Sn9Buyut6odubguX2AxoRArCdIDCkT9hjUERpA==", "requires": { "underscore": "1.9.1", - "web3-core": "1.2.2", - "web3-core-helpers": "1.2.2", - "web3-core-method": "1.2.2", - "web3-core-subscriptions": "1.2.2", - "web3-eth-abi": "1.2.2", - "web3-eth-accounts": "1.2.2", - "web3-eth-contract": "1.2.2", - "web3-eth-ens": "1.2.2", - "web3-eth-iban": "1.2.2", - "web3-eth-personal": "1.2.2", - "web3-net": "1.2.2", - "web3-utils": "1.2.2" + "web3-core": "1.2.4", + "web3-core-helpers": "1.2.4", + "web3-core-method": "1.2.4", + "web3-core-subscriptions": "1.2.4", + "web3-eth-abi": "1.2.4", + "web3-eth-accounts": "1.2.4", + "web3-eth-contract": "1.2.4", + "web3-eth-ens": "1.2.4", + "web3-eth-iban": "1.2.4", + "web3-eth-personal": "1.2.4", + "web3-net": "1.2.4", + "web3-utils": "1.2.4" } }, "web3-eth-abi": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.2.2.tgz", - "integrity": "sha512-Yn/ZMgoOLxhTVxIYtPJ0eS6pnAnkTAaJgUJh1JhZS4ekzgswMfEYXOwpMaD5eiqPJLpuxmZFnXnBZlnQ1JMXsw==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.2.4.tgz", + "integrity": "sha512-8eLIY4xZKoU3DSVu1pORluAw9Ru0/v4CGdw5so31nn+7fR8zgHMgwbFe0aOqWQ5VU42PzMMXeIJwt4AEi2buFg==", "requires": { "ethers": "4.0.0-beta.3", "underscore": "1.9.1", - "web3-utils": "1.2.2" + "web3-utils": "1.2.4" } }, "web3-eth-accounts": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.2.2.tgz", - "integrity": "sha512-KzHOEyXOEZ13ZOkWN3skZKqSo5f4Z1ogPFNn9uZbKCz+kSp+gCAEKxyfbOsB/JMAp5h7o7pb6eYsPCUBJmFFiA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.2.4.tgz", + "integrity": "sha512-04LzT/UtWmRFmi4hHRewP5Zz43fWhuHiK5XimP86sUQodk/ByOkXQ3RoXyGXFMNoRxdcAeRNxSfA2DpIBc9xUw==", "requires": { + "@web3-js/scrypt-shim": "^0.1.0", "any-promise": "1.3.0", "crypto-browserify": "3.12.0", "eth-lib": "0.2.7", "ethereumjs-common": "^1.3.2", "ethereumjs-tx": "^2.1.1", - "scrypt-shim": "github:web3-js/scrypt-shim#be5e616323a8b5e568788bf94d03c1b8410eac54", "underscore": "1.9.1", "uuid": "3.3.2", - "web3-core": "1.2.2", - "web3-core-helpers": "1.2.2", - "web3-core-method": "1.2.2", - "web3-utils": "1.2.2" + "web3-core": "1.2.4", + "web3-core-helpers": "1.2.4", + "web3-core-method": "1.2.4", + "web3-utils": "1.2.4" }, "dependencies": { "eth-lib": { @@ -5112,112 +5802,119 @@ } }, "web3-eth-contract": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.2.2.tgz", - "integrity": "sha512-EKT2yVFws3FEdotDQoNsXTYL798+ogJqR2//CaGwx3p0/RvQIgfzEwp8nbgA6dMxCsn9KOQi7OtklzpnJMkjtA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.2.4.tgz", + "integrity": "sha512-b/9zC0qjVetEYnzRA1oZ8gF1OSSUkwSYi5LGr4GeckLkzXP7osEnp9lkO/AQcE4GpG+l+STnKPnASXJGZPgBRQ==", "requires": { "@types/bn.js": "^4.11.4", "underscore": "1.9.1", - "web3-core": "1.2.2", - "web3-core-helpers": "1.2.2", - "web3-core-method": "1.2.2", - "web3-core-promievent": "1.2.2", - "web3-core-subscriptions": "1.2.2", - "web3-eth-abi": "1.2.2", - "web3-utils": "1.2.2" + "web3-core": "1.2.4", + "web3-core-helpers": "1.2.4", + "web3-core-method": "1.2.4", + "web3-core-promievent": "1.2.4", + "web3-core-subscriptions": "1.2.4", + "web3-eth-abi": "1.2.4", + "web3-utils": "1.2.4" } }, "web3-eth-ens": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.2.2.tgz", - "integrity": "sha512-CFjkr2HnuyMoMFBoNUWojyguD4Ef+NkyovcnUc/iAb9GP4LHohKrODG4pl76R5u61TkJGobC2ij6TyibtsyVYg==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.2.4.tgz", + "integrity": "sha512-g8+JxnZlhdsCzCS38Zm6R/ngXhXzvc3h7bXlxgKU4coTzLLoMpgOAEz71GxyIJinWTFbLXk/WjNY0dazi9NwVw==", "requires": { "eth-ens-namehash": "2.0.8", "underscore": "1.9.1", - "web3-core": "1.2.2", - "web3-core-helpers": "1.2.2", - "web3-core-promievent": "1.2.2", - "web3-eth-abi": "1.2.2", - "web3-eth-contract": "1.2.2", - "web3-utils": "1.2.2" + "web3-core": "1.2.4", + "web3-core-helpers": "1.2.4", + "web3-core-promievent": "1.2.4", + "web3-eth-abi": "1.2.4", + "web3-eth-contract": "1.2.4", + "web3-utils": "1.2.4" } }, "web3-eth-iban": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.2.tgz", - "integrity": "sha512-gxKXBoUhaTFHr0vJB/5sd4i8ejF/7gIsbM/VvemHT3tF5smnmY6hcwSMmn7sl5Gs+83XVb/BngnnGkf+I/rsrQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.4.tgz", + "integrity": "sha512-D9HIyctru/FLRpXakRwmwdjb5bWU2O6UE/3AXvRm6DCOf2e+7Ve11qQrPtaubHfpdW3KWjDKvlxV9iaFv/oTMQ==", "requires": { "bn.js": "4.11.8", - "web3-utils": "1.2.2" + "web3-utils": "1.2.4" } }, "web3-eth-personal": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.2.2.tgz", - "integrity": "sha512-4w+GLvTlFqW3+q4xDUXvCEMU7kRZ+xm/iJC8gm1Li1nXxwwFbs+Y+KBK6ZYtoN1qqAnHR+plYpIoVo27ixI5Rg==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.2.4.tgz", + "integrity": "sha512-5Russ7ZECwHaZXcN3DLuLS7390Vzgrzepl4D87SD6Sn1DHsCZtvfdPIYwoTmKNp69LG3mORl7U23Ga5YxqkICw==", "requires": { "@types/node": "^12.6.1", - "web3-core": "1.2.2", - "web3-core-helpers": "1.2.2", - "web3-core-method": "1.2.2", - "web3-net": "1.2.2", - "web3-utils": "1.2.2" + "web3-core": "1.2.4", + "web3-core-helpers": "1.2.4", + "web3-core-method": "1.2.4", + "web3-net": "1.2.4", + "web3-utils": "1.2.4" + }, + "dependencies": { + "@types/node": { + "version": "12.12.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.10.tgz", + "integrity": "sha512-rhG2F0v4nNMqcPM4dMSne7R9iBzehUnARYbJq7G36CoczcqjNWuriAy6kd6quT30ISmfBhIRFVYDMSLrBASHNw==" + } } }, "web3-net": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.2.2.tgz", - "integrity": "sha512-K07j2DXq0x4UOJgae65rWZKraOznhk8v5EGSTdFqASTx7vWE/m+NqBijBYGEsQY1lSMlVaAY9UEQlcXK5HzXTw==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.2.4.tgz", + "integrity": "sha512-wKOsqhyXWPSYTGbp7ofVvni17yfRptpqoUdp3SC8RAhDmGkX6irsiT9pON79m6b3HUHfLoBilFQyt/fTUZOf7A==", "requires": { - "web3-core": "1.2.2", - "web3-core-method": "1.2.2", - "web3-utils": "1.2.2" + "web3-core": "1.2.4", + "web3-core-method": "1.2.4", + "web3-utils": "1.2.4" } }, "web3-providers-http": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.2.2.tgz", - "integrity": "sha512-BNZ7Hguy3eBszsarH5gqr9SIZNvqk9eKwqwmGH1LQS1FL3NdoOn7tgPPdddrXec4fL94CwgNk4rCU+OjjZRNDg==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.2.4.tgz", + "integrity": "sha512-dzVCkRrR/cqlIrcrWNiPt9gyt0AZTE0J+MfAu9rR6CyIgtnm1wFUVVGaxYRxuTGQRO4Dlo49gtoGwaGcyxqiTw==", "requires": { - "web3-core-helpers": "1.2.2", + "web3-core-helpers": "1.2.4", "xhr2-cookies": "1.1.0" } }, "web3-providers-ipc": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.2.2.tgz", - "integrity": "sha512-t97w3zi5Kn/LEWGA6D9qxoO0LBOG+lK2FjlEdCwDQatffB/+vYrzZ/CLYVQSoyFZAlsDoBasVoYSWZK1n39aHA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.2.4.tgz", + "integrity": "sha512-8J3Dguffin51gckTaNrO3oMBo7g+j0UNk6hXmdmQMMNEtrYqw4ctT6t06YOf9GgtOMjSAc1YEh3LPrvgIsR7og==", "requires": { "oboe": "2.1.4", "underscore": "1.9.1", - "web3-core-helpers": "1.2.2" + "web3-core-helpers": "1.2.4" } }, "web3-providers-ws": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.2.2.tgz", - "integrity": "sha512-Wb1mrWTGMTXOpJkL0yGvL/WYLt8fUIXx8k/l52QB2IiKzvyd42dTWn4+j8IKXGSYYzOm7NMqv6nhA5VDk12VfA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.2.4.tgz", + "integrity": "sha512-F/vQpDzeK+++oeeNROl1IVTufFCwCR2hpWe5yRXN0ApLwHqXrMI7UwQNdJ9iyibcWjJf/ECbauEEQ8CHgE+MYQ==", "requires": { + "@web3-js/websocket": "^1.0.29", "underscore": "1.9.1", - "web3-core-helpers": "1.2.2", - "websocket": "github:web3-js/WebSocket-Node#905deb4812572b344f5801f8c9ce8bb02799d82e" + "web3-core-helpers": "1.2.4" } }, "web3-shh": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.2.2.tgz", - "integrity": "sha512-og258NPhlBn8yYrDWjoWBBb6zo1OlBgoWGT+LL5/LPqRbjPe09hlOYHgscAAr9zZGtohTOty7RrxYw6Z6oDWCg==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.2.4.tgz", + "integrity": "sha512-z+9SCw0dE+69Z/Hv8809XDbLj7lTfEv9Sgu8eKEIdGntZf4v7ewj5rzN5bZZSz8aCvfK7Y6ovz1PBAu4QzS4IQ==", "requires": { - "web3-core": "1.2.2", - "web3-core-method": "1.2.2", - "web3-core-subscriptions": "1.2.2", - "web3-net": "1.2.2" + "web3-core": "1.2.4", + "web3-core-method": "1.2.4", + "web3-core-subscriptions": "1.2.4", + "web3-net": "1.2.4" } }, "web3-utils": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.2.tgz", - "integrity": "sha512-joF+s3243TY5cL7Z7y4h1JsJpUCf/kmFmj+eJar7Y2yNIGVcW961VyrAms75tjUysSuHaUQ3eQXjBEUJueT52A==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.4.tgz", + "integrity": "sha512-+S86Ip+jqfIPQWvw2N/xBQq5JNqCO0dyvukGdJm8fEWHZbckT4WxSpHbx+9KLEWY4H4x9pUwnoRkK87pYyHfgQ==", "requires": { "bn.js": "4.11.8", "eth-lib": "0.2.7", @@ -5241,32 +5938,6 @@ } } }, - "websocket": { - "version": "github:web3-js/WebSocket-Node#905deb4812572b344f5801f8c9ce8bb02799d82e", - "from": "github:web3-js/WebSocket-Node#polyfill/globalThis", - "requires": { - "debug": "^2.2.0", - "es5-ext": "^0.10.50", - "nan": "^2.14.0", - "typedarray-to-buffer": "^3.1.5", - "yaeti": "^0.0.6" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -5355,11 +6026,15 @@ } } }, + "window-size": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", + "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=" + }, "wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1" @@ -5458,8 +6133,7 @@ "y18n": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" }, "yaeti": { "version": "0.0.6", @@ -5472,57 +6146,17 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "yargs": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", - "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", - "dev": true, + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", + "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", "requires": { - "camelcase": "^4.1.0", - "cliui": "^3.2.0", + "camelcase": "^2.0.1", + "cliui": "^3.0.3", "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "read-pkg-up": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } + "os-locale": "^1.4.0", + "string-width": "^1.0.1", + "window-size": "^0.1.4", + "y18n": "^3.2.0" } }, "yargs-parser": { @@ -5532,6 +6166,14 @@ "dev": true, "requires": { "camelcase": "^4.1.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + } } }, "yauzl": { @@ -5544,9 +6186,9 @@ } }, "zeromq": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/zeromq/-/zeromq-5.1.1.tgz", - "integrity": "sha512-ZInBjczu5qjKW9WFnFcaOoAqCqDqTn1QqVzB6nTt5SGu9OQb9K8qk9RjBoXJY+fxTpRDparqBnhFxYBZFEgJyw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/zeromq/-/zeromq-5.2.0.tgz", + "integrity": "sha512-qsckhCmrg6et6zrAJytC971SSN/4iLxKgkXK1Wqn2Gij5KXMY+TA+3cy/iFwehaWdU5usg5HNOOgaBdjSqtCVw==", "requires": { "nan": "^2.14.0", "prebuild-install": "^5.3.2" diff --git a/examples/simple-asset-transfer/package.json b/examples/simple-asset-transfer/package.json index 9c40418b48..7b9a0c3a34 100644 --- a/examples/simple-asset-transfer/package.json +++ b/examples/simple-asset-transfer/package.json @@ -2,13 +2,12 @@ "version": "0.1.0", "name": "@hyperledger-labs/blockchain-integration-framework.examples.simple-asset-transfer", "dependencies": { - "@hyperledger-labs/blockchain-integration-framework": "git+https://github.com/hyperledger-labs/blockchain-integration-framework.git#fix/peter.somogyvari/make-ci-pass", + "@hyperledger-labs/blockchain-integration-framework": "../../.tmp/hyperledger-labs-blockchain-integration-framework-dev.tgz", "cookie-parser": "^1.4.4", "express-bearer-token": "^2.4.0", "express-jwt": "^5.3.1", "express-session": "^1.16.2", - "request-promise": "^4.2.4", - "typedarray-to-buffer": "^3.1.5" + "request-promise": "^4.2.4" }, "devDependencies": { "npm-check": "^5.9.0" @@ -22,23 +21,23 @@ "fabric:down": "fuser -k -n tcp 4000 ; docker-compose -f fabric/artifacts/docker-compose.yaml rm -sf", "fabric:log": "docker-compose -f fabric/artifacts/docker-compose.yaml logs -f", "fed:build": "docker build --no-cache --force-rm -t federation/validator .", - "fed:fabric": "docker-compose -p federation-fabric -f ./federations/docker-compose-fabric.yml up --renew-anon-volumes -d", - "fed:fabric:down": "docker-compose -p federation-fabric -f ./federations/docker-compose-fabric.yml rm -sf", - "fed:fabric:log": "docker-compose -p federation-fabric -f ./federations/docker-compose-fabric.yml logs -f", - "fed:quorum": "docker-compose -p federation-quorum -f ./federations/docker-compose-quorum.yml up --renew-anon-volumes -d", - "fed:quorum:down": "docker-compose -p federation-quorum -f ./federations/docker-compose-quorum.yml rm -sf", - "fed:quorum:log": "docker-compose -p federation-quorum -f ./federations/docker-compose-quorum.yml logs -f", - "fed:corda": "docker-compose -p federation-corda -f ./federations/docker-compose-corda.yml up --renew-anon-volumes -d", - "fed:corda:down": "docker-compose -p federation-corda -f ./federations/docker-compose-corda.yml rm -sf", - "fed:corda:log": "docker-compose -p federation-corda -f ./federations/docker-compose-corda.yml logs -f", + "fed:fabric": "docker-compose -p federation-fabric -f ./federations/docker-compose-fabric.yml --compatibility up --renew-anon-volumes -d", + "fed:fabric:down": "docker-compose -p federation-fabric -f ./federations/docker-compose-fabric.yml --compatibility rm -sf", + "fed:fabric:log": "docker-compose -p federation-fabric -f ./federations/docker-compose-fabric.yml --compatibility logs -f", + "fed:quorum": "docker-compose -p federation-quorum -f ./federations/docker-compose-quorum.yml --compatibility up --renew-anon-volumes -d", + "fed:quorum:down": "docker-compose -p federation-quorum -f ./federations/docker-compose-quorum.yml --compatibility rm -sf", + "fed:quorum:log": "docker-compose -p federation-quorum -f ./federations/docker-compose-quorum.yml --compatibility logs -f", + "fed:corda": "docker-compose -p federation-corda -f ./federations/docker-compose-corda.yml --compatibility up --renew-anon-volumes -d", + "fed:corda:down": "docker-compose -p federation-corda -f ./federations/docker-compose-corda.yml --compatibility rm -sf", + "fed:corda:log": "docker-compose -p federation-corda -f ./federations/docker-compose-corda.yml --compatibility logs -f", "install-all": "npm i && cd fabric/api && npm i && cd - && cd quorum/api && npm i", - "quorum": "QUORUM_CONSENSUS=raft docker-compose -p quorum -f ./quorum/platform/docker-compose.yml up --renew-anon-volumes -d", - "quorum:down": "docker-compose -p quorum -f ./quorum/platform/docker-compose.yml rm -sf", - "quorum:log": "docker-compose -p quorum -f ./quorum/platform/docker-compose.yml logs -f", - "quorum:api": "docker-compose -p quorum-api -f ./quorum/api/docker-compose.yml up --renew-anon-volumes -d", + "quorum": "QUORUM_CONSENSUS=raft docker-compose -p quorum -f ./quorum/platform/docker-compose.yml --compatibility up --renew-anon-volumes -d", + "quorum:down": "docker-compose -p quorum -f ./quorum/platform/docker-compose.yml --compatibility rm -sf", + "quorum:log": "docker-compose -p quorum -f ./quorum/platform/docker-compose.yml --compatibility logs -f", + "quorum:api": "docker-compose -p quorum-api -f ./quorum/api/docker-compose.yml --compatibility up --renew-anon-volumes -d", "quorum:api:build": "docker build --no-cache -t federation/qserver -f quorum/api/Dockerfile quorum", - "quorum:api:down": "docker-compose -p quorum-api -f ./quorum/api/docker-compose.yml rm -sf", - "quorum:api:log": "docker-compose -p quorum-api -f ./quorum/api/docker-compose.yml logs -f", + "quorum:api:down": "docker-compose -p quorum-api -f ./quorum/api/docker-compose.yml --compatibility rm -sf", + "quorum:api:log": "docker-compose -p quorum-api -f ./quorum/api/docker-compose.yml --compatibility logs -f", "scenario:share": "cd scenarios && node share-pub-keys.js", "scenario:FtQ": "cd scenarios && node fabric-to-quorum.js", "scenario:QtF": "cd scenarios && node quorum-to-fabric.js", @@ -48,7 +47,8 @@ "scenario:QtC": "cd scenarios && node quorum-to-corda.js", "test": "../../node_modules/.bin/cross-env NODE_ENV=test ../../node_modules/.bin/mocha --ui bdd --reporter spec --colors tests/*.js --recursive --exit", "test:bc": "BLOCKCHAIN=true npm run test", - "upgrade-interactive": "npm-check --update" + "upgrade-interactive": "npm-check --update", + "preinstall": "node ../../tools/create-local-npm-package.js" }, "private": true, "engines": { diff --git a/examples/simple-asset-transfer/quorum/platform/docker-compose.yml b/examples/simple-asset-transfer/quorum/platform/docker-compose.yml index f29c64be9c..6b349b302c 100644 --- a/examples/simple-asset-transfer/quorum/platform/docker-compose.yml +++ b/examples/simple-asset-transfer/quorum/platform/docker-compose.yml @@ -187,7 +187,7 @@ x-tx-manager-def: --publickeys=/examples/keys/tm$${NODE_ID}.pub \ --privatekeys=/examples/keys/tm$${NODE_ID}.key \ --storage=$${DDIR} \ - --verbosity=4 + --verbosity=1 ;; *) echo "Invalid Transaction Manager" diff --git a/package-lock.json b/package-lock.json index 454f395184..643c430559 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,6 +40,69 @@ "regenerator-runtime": "^0.13.2" } }, + "@grpc/proto-loader": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.5.3.tgz", + "integrity": "sha512-8qvUtGg77G2ZT2HqdqYoM/OY97gQd/0crSG34xNmZ4ZOsv3aQT/FQV9QfZPazTGna6MIoyUd+u6AxsoZjJ/VMQ==", + "requires": { + "lodash.camelcase": "^4.3.0", + "protobufjs": "^6.8.6" + } + }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -69,6 +132,20 @@ "@types/node": "*" } }, + "@types/bytebuffer": { + "version": "5.0.40", + "resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.40.tgz", + "integrity": "sha512-h48dyzZrPMz25K6Q4+NCwWaxwXany2FhQg/ErOcdZS1ZpsaDnDMZg8JYLMTGz7uvXKrcKGJUZJlZObyfgdaN9g==", + "requires": { + "@types/long": "*", + "@types/node": "*" + } + }, + "@types/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz", + "integrity": "sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q==" + }, "@types/node": { "version": "12.12.8", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.8.tgz", @@ -341,6 +418,15 @@ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, + "ascli": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz", + "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=", + "requires": { + "colour": "~0.7.1", + "optjs": "~3.2.2" + } + }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -924,6 +1010,21 @@ "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", "dev": true }, + "bytebuffer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", + "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", + "requires": { + "long": "~3" + }, + "dependencies": { + "long": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", + "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=" + } + } + }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -1312,6 +1413,11 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, + "colour": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz", + "integrity": "sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g=" + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1577,8 +1683,7 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, "decode-uri-component": { "version": "0.2.0", @@ -2447,6 +2552,23 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, + "etcd3": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/etcd3/-/etcd3-0.2.13.tgz", + "integrity": "sha512-9zVnoebQRwOGivGT9/bFHQsjkcZttgzyDU50G1J27tdU76vmgp78YGOAEe9zzEjU6IEFa2KYYUg5AyMKDOp37A==", + "requires": { + "@grpc/proto-loader": "^0.5.1", + "bignumber.js": "^5.0.0", + "grpc": "^1.21.1" + }, + "dependencies": { + "bignumber.js": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-5.0.0.tgz", + "integrity": "sha512-KWTu6ZMVk9sxlDJQh2YH1UOnfDP8O8TpxUxgQG/vKASoSnEjK9aVuOueFaPcQEYQ5fyNXNTOYwYw3099RYebWg==" + } + } + }, "eth-ens-namehash": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", @@ -3860,6 +3982,486 @@ "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" }, + "grpc": { + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.24.2.tgz", + "integrity": "sha512-EG3WH6AWMVvAiV15d+lr+K77HJ/KV/3FvMpjKjulXHbTwgDZkhkcWbwhxFAoTdxTkQvy0WFcO3Nog50QBbHZWw==", + "requires": { + "@types/bytebuffer": "^5.0.40", + "lodash.camelcase": "^4.3.0", + "lodash.clone": "^4.5.0", + "nan": "^2.13.2", + "node-pre-gyp": "^0.14.0", + "protobufjs": "^5.0.3" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + }, + "chownr": { + "version": "1.1.3", + "bundled": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true + }, + "debug": { + "version": "3.2.6", + "bundled": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true + }, + "fs-minipass": { + "version": "1.2.7", + "bundled": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.4", + "bundled": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.3", + "bundled": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "bundled": true + }, + "ini": { + "version": "1.3.5", + "bundled": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "bundled": true + }, + "minipass": { + "version": "2.9.0", + "bundled": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "bundled": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "bundled": true + } + } + }, + "ms": { + "version": "2.1.2", + "bundled": true + }, + "needle": { + "version": "2.4.0", + "bundled": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.14.0", + "bundled": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true + }, + "npm-packlist": { + "version": "1.4.6", + "bundled": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "requires": { + "lcid": "^1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true + }, + "process-nextick-args": { + "version": "2.0.1", + "bundled": true + }, + "protobufjs": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.3.tgz", + "integrity": "sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==", + "requires": { + "ascli": "~1", + "bytebuffer": "~5", + "glob": "^7.0.5", + "yargs": "^3.10.0" + } + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.7.1", + "bundled": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true + }, + "sax": { + "version": "1.2.4", + "bundled": true + }, + "semver": { + "version": "5.7.1", + "bundled": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true + }, + "tar": { + "version": "4.4.13", + "bundled": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, + "yallist": { + "version": "3.1.1", + "bundled": true + }, + "yargs": { + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", + "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", + "requires": { + "camelcase": "^2.0.1", + "cliui": "^3.0.3", + "decamelize": "^1.1.1", + "os-locale": "^1.4.0", + "string-width": "^1.0.1", + "window-size": "^0.1.4", + "y18n": "^3.2.0" + } + } + } + }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -4218,8 +4820,7 @@ "invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" }, "ipaddr.js": { "version": "1.9.0", @@ -4743,7 +5344,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, "requires": { "invert-kv": "^1.0.0" } @@ -4806,6 +5406,16 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + }, + "lodash.clone": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", + "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=" + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -4863,6 +5473,11 @@ "streamroller": "^1.0.6" } }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -5924,6 +6539,11 @@ "word-wrap": "~1.2.3" } }, + "optjs": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", + "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=" + }, "ora": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/ora/-/ora-0.2.3.tgz", @@ -6409,6 +7029,33 @@ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, + "protobufjs": { + "version": "6.8.8", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", + "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.0", + "@types/node": "^10.1.0", + "long": "^4.0.0" + }, + "dependencies": { + "@types/node": { + "version": "10.17.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.5.tgz", + "integrity": "sha512-RElZIr/7JreF1eY6oD5RF3kpmdcreuQPjg5ri4oQ5g9sq7YWU8HkfB3eH8GwAwxf5OaCh0VPi7r4N/yoTGelrA==" + } + } + }, "proxy-addr": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", @@ -8587,6 +9234,11 @@ } } }, + "window-size": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", + "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=" + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", diff --git a/package.json b/package.json index 835b839e08..b17a71c2c8 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "upgrade-interactive": "npm-check --update" }, "dependencies": { + "etcd3": "0.2.13", "log4js": "^4.1.0", "prettier": "^1.16.4", "request": "^2.88.0", @@ -26,6 +27,7 @@ "secp256k1": "^3.6.2", "sha3": "^2.0.1", "truffle": "^5.0.14", + "uuid": "3.3.3", "web3": "1.2.4", "web3-utils": "1.2.4", "zeromq": "^5.1.0" diff --git a/src/Validator.js b/src/Validator.js index bdb4876f2f..4d18587dd8 100644 --- a/src/Validator.js +++ b/src/Validator.js @@ -1,6 +1,8 @@ /* eslint no-use-before-define: ["error", { "variables": false }] */ const zmq = require(`zeromq`); const log4js = require(`log4js`); +const { Etcd3 } = require('etcd3'); +const uuidV4 = require('uuid/v4'); const fedcom = require(`./federation-communication`); const conf = require(`../config.json`); @@ -11,6 +13,8 @@ const Multisig = require(`./Multisig`); const logger = log4js.getLogger(`Validator`); logger.level = `DEBUG`; +const BIF_LEADER = 'bif/leader'; + /** * Validator * @@ -43,27 +47,13 @@ class Validator { * @param {String} options.clientRepAddr Client Rep address * @param {String} options.pubAddr Public address * @param {String} options.repAddr Rep address - * @param {String} options.leaderPubAddr Leader Public address - * @param {String} options.leaderRepAddr Leader Rep address - * @param {String} options.leaderClientRepAddr Leader Client Rep address - * @param {String} options.type Validator type */ constructor(blockchainClient, options) { if (!(blockchainClient instanceof Connector)) { throw new Error(`Validator needs a valid connector to get started`); } this.blockchainClient = blockchainClient; - Object.assign(this, options); - if (this.type === fedcom.VALIDATOR_TYPE.LEADER) { - this.leaderPubAddr = options.pubAddr; - this.leaderRepAddr = options.repAddr; - this.leaderClientRepAddr = options.clientRepAddr; - } else { - this.leaderPubAddr = options.leaderPubAddr; - this.leaderRepAddr = options.leaderRepAddr; - this.leaderClientRepAddr = options.leaderClientRepAddr; - } this.publishSocket = null; this.requestSocket = null; @@ -72,6 +62,89 @@ class Validator { this.clientRepSocket = null; this.currentMultisig = new Multisig(); this.electionTimeout = conf.electionTimeout; + this.randomizedLeadershipPoolInterval = this.electionTimeout / 3 + (Math.random() * this.electionTimeout) / 3; + + this.selfNodeInfo = { + id: uuidV4(), + pid: process.pid, + startedAt: new Date(), + networkInfo: { + leaderPubAddr: this.pubAddr, + leaderRepAddr: this.repAddr, + leaderClientRepAddr: this.clientRepAddr, + }, + }; + + logger.debug(`Creating new validator instance. Node info: `, JSON.stringify(this.selfNodeInfo)); + + // etcd setup + this.EtcdConstructor = typeof this.EtcdConstructor === 'function' ? this.EtcdConstructor : Etcd3; + this.etcdClient = this.createEtcdClient(); + + this.setupLeaderElections(); + } + + isCurrentNodeLeader() { + return typeof this.leaderNodeInfo === 'object' && this.leaderNodeInfo.id === this.selfNodeInfo.id; + } + + createEtcdClient() { + if (typeof this.EtcdConstructor !== 'function') { + throw new TypeError(`Validator#createEtcdClient() expected this.EtcdConstructor to be function.`); + } + if (!Array.isArray(this.etcdHosts)) { + throw new TypeError(`Validator#createEtcdClient() expected this.etcdHosts to be an Array.`); + } + logger.debug(`Creating etcd client with hosts`, this.etcdHosts); + return new this.EtcdConstructor({ + hosts: this.etcdHosts, + }); + } + + async setupLeaderElections() { + // Setup the watcher + const watcher = await this.etcdClient + .watch() + .key(BIF_LEADER) + .create(); + logger.debug(`Etcd watcher set up OK.`); + + watcher + .on('disconnected', () => logger.debug('[WATCH] disconnected...', this.selfNodeInfo)) + .on('connected', () => logger.debug('[WATCH] successfully reconnected!', this.selfNodeInfo)) + .on('put', res => { + const newLeaderNodeInfoJson = res.value.toString('utf8'); + logger.debug(`[WATCH] key ${BIF_LEADER} got set to new value: `, newLeaderNodeInfoJson); + const newLeaderNodeInfo = JSON.parse(newLeaderNodeInfoJson); + this.switchToNewLeader(newLeaderNodeInfo); + }); + // Finished settig up watcher + + const leaseTtlSeconds = Math.round(this.electionTimeout / 1000); + logger.debug(`Creating lease with TTL=${leaseTtlSeconds} seconds...`); + const theLease = this.etcdClient.lease(leaseTtlSeconds); + + theLease.on('lost', () => logger.debug(['LEASE:keepaliveLost'])); + theLease.on('keepaliveFailed', () => logger.warn(['LEASE:keepaliveFailed'])); + theLease.on('keepaliveEstablished', () => logger.debug(['LEASE:keepaliveEstablished'])); + + this.attemptToBecomeLeader(theLease); + setInterval(this.attemptToBecomeLeader.bind(this, theLease), this.randomizedLeadershipPoolInterval); + } + + attemptToBecomeLeader(theLease) { + if (this.isCurrentNodeLeader()) { + return; + } + this.etcdClient + .if(BIF_LEADER, 'Lease', '==', 0) + .then(theLease.put(BIF_LEADER).value(JSON.stringify(this.selfNodeInfo))) + .else(this.etcdClient.get(BIF_LEADER)) + .commit() + // .then(transactionResponse => { + // logger.debug(`TransactionResponse=${JSON.stringify(transactionResponse)}`); + // }) + .catch(ex => logger.error('Leadership attempt failed with exception:', ex)); } /** @@ -80,12 +153,6 @@ class Validator { */ start() { this.startClientServer(); - - if (this.type === fedcom.VALIDATOR_TYPE.LEADER) { - this.startAsLeader(); - } else { - this.startAsFollower(); - } } /** @@ -93,7 +160,7 @@ class Validator { * @return {void} */ stop() { - if (this.type === fedcom.VALIDATOR_TYPE.LEADER) { + if (this.isCurrentNodeLeader()) { clearInterval(this.intervalExec); this.requestSocket.close(); } @@ -108,17 +175,11 @@ class Validator { */ startAsLeader() { logger.debug(`Starting as Leader ...`); - logger.debug( - `I am : - (${this.pubAddr}, - ${this.repAddr}, - ${this.clientRepAddr})` - ); + logger.debug(`I am : (${this.pubAddr}, ${this.repAddr}, ${this.clientRepAddr})`); this.type = fedcom.VALIDATOR_TYPE.LEADER; this.publishSocket = zmq.socket(`pub`); this.publishSocket.bindSync(this.leaderPubAddr); - this.intervalExec = this.newLeaderElection(); this.requestSocket = zmq.socket(`rep`); this.requestSocket.bindSync(this.leaderRepAddr); this.requestSocket.on(`message`, fedcom.ValidatorAsLeaderMessage.bind(this)); @@ -131,12 +192,7 @@ class Validator { */ startAsFollower() { logger.debug(`Starting as Follower... `); - logger.debug( - `My Leader is : - (${this.leaderPubAddr}, - ${this.leaderRepAddr}, - ${this.leaderClientRepAddr})` - ); + logger.debug(`My Leader is : (${this.leaderPubAddr}, ${this.leaderRepAddr}, ${this.leaderClientRepAddr})`); this.type = fedcom.VALIDATOR_TYPE.FOLLOWER; this.publishSocket = zmq.socket(`sub`); @@ -211,17 +267,6 @@ class Validator { } } - /** - * Select on validator in the specified pool to be the leader of the next round - * @static - * @param {string[]} aliveValidators - Alive Validators - * @return {string} Next Leader Address - */ - static selectNextLeader(aliveValidators) { - const index = Math.floor(Math.random() * Math.floor(aliveValidators.length)); - return aliveValidators[index]; - } - /** * Sign locally and broadcast remaining job to alive validators * @param {string} type Validator type @@ -249,63 +294,34 @@ class Validator { return new Promise(resolve => setTimeout(resolve.bind(this, true), conf.timeout)); } - /** - * Prepare validator pool and select new leader - * @return {string} Interval Id. - */ - newLeaderElection() { - return setInterval(() => { - this.availableFollowers = []; - - logger.debug(`Sending heartbeat request`); - this.publishSocket.send([fedcom.MSG_TYPE.HEARTBEAT, `{}`]); - - setTimeout(() => { - // Select the next leader - if (this.availableFollowers.length !== 0) { - const nextLeader = Validator.selectNextLeader(this.availableFollowers); - this.publishSocket.send([fedcom.MSG_TYPE.NEWLEADER, JSON.stringify(nextLeader)]); - // Switch from leader to follower - this.switchToNewLeader(nextLeader); - } - }, conf.timeout); - }, this.electionTimeout); - } - /** * Change local parameters to adjust to new leader - * @param {Object} newLeader - * @param {string} newLeader.pub New Leader Public Address - * @param {string} newLeader.rep New Leader Rep Address - * @param {string} newLeader.clientRep New Leader Client Rep Address * @return {void} */ - switchToNewLeader(newLeader) { - // Update leader address - this.leaderPubAddr = newLeader.pub; - this.leaderRepAddr = newLeader.rep; - this.leaderClientRepAddr = newLeader.clientRep; + switchToNewLeader(newLeaderNodeInfo) { + this.leaderNodeInfo = newLeaderNodeInfo; + + // TODO(peter.somogyvari): Once leader election has enough test coverage, get rid of these property assignments + // and just use the this.leaderNodeInfo.networkInfo object directly everywhere. + this.leaderPubAddr = this.leaderNodeInfo.networkInfo.leaderPubAddr; + this.leaderRepAddr = this.leaderNodeInfo.networkInfo.leaderRepAddr; + this.leaderClientRepAddr = this.leaderNodeInfo.networkInfo.leaderClientRepAddr; // Stop the pub and rep sockets - this.publishSocket.close(); + if (this.publishSocket) { + this.publishSocket.close(); + } - if (this.type === fedcom.VALIDATOR_TYPE.LEADER) { - // REFAC: this if content could go to line ~206 - // (right before newLeaderElection/switchToNewLeader) - // but that would need to refac the test + if (this.requestSocket) { this.requestSocket.close(); this.requestSocket = null; - clearInterval(this.intervalExec); - this.intervalExec = null; } - if (this.pubAddr === newLeader.pub) { + if (this.isCurrentNodeLeader()) { this.startAsLeader(); - return; + } else { + this.startAsFollower(); } - - // Follower updates its references to the new leader - this.startAsFollower(); } } diff --git a/tests/client.js b/tests/client.js index a0b0a72a04..6fc544c67b 100644 --- a/tests/client.js +++ b/tests/client.js @@ -124,6 +124,7 @@ describe(`Client module`, function() { pubKey: `031b3e4b65070268bd2ce3652966f75ebdf7184f637fd24a4fe0417c2dcb92fd9b`, }; const validatorOptions1 = { + etcdHosts: ['http://localhost:2379'], ...validatorKeys, type: fedcom.VALIDATOR_TYPE.LEADER, clientRepAddr: `tcp://127.0.0.1:7103`, @@ -137,7 +138,11 @@ describe(`Client module`, function() { validator1 = new Validator(connector1, validatorOptions1); validator1.start(); + // self promote to leader manually for test since there's no etd cluster, we need to fake/rig the election + validator1.switchToNewLeader(validator1.selfNodeInfo); + const validatorOptions2 = { + etcdHosts: ['http://localhost:2379'], ...validatorKeys, type: fedcom.VALIDATOR_TYPE.FOLLOWER, leaderClientRepAddr: `tcp://127.0.0.1:7103`, diff --git a/tests/validator.js b/tests/validator.js index 7b88ebd10f..aec41bf69e 100644 --- a/tests/validator.js +++ b/tests/validator.js @@ -3,7 +3,7 @@ /* eslint func-names: ["error", "never"] */ const chai = require(`chai`); const zmq = require(`zeromq`); - +const uuidV4 = require('uuid/v4'); const fedcom = require(`../src/federation-communication`); const Validator = require(`../src/Validator`); const Multisig = require(`../src/Multisig`); @@ -34,6 +34,7 @@ describe(`Validator module`, function() { it(`Create a leader`, function() { // Lets set the leader to be validator 1 const leaderOptions = { + etcdHosts: ['http://localhost:2379'], ...keyOptions, ...addrOptions, type: fedcom.VALIDATOR_TYPE.LEADER, @@ -50,6 +51,7 @@ describe(`Validator module`, function() { it(`Create a follower`, function() { // leader is considered to be validator 2 const followerOptions = { + etcdHosts: ['http://localhost:2379'], ...keyOptions, ...addrOptions, type: fedcom.VALIDATOR_TYPE.FOLLOWER, @@ -101,15 +103,20 @@ describe(`Validator module`, function() { }); describe(`Switch to new leader`, function() { - const newLeader = { - type: fedcom.MSG_TYPE.HEARTBEAT, - pub: `tcp://127.0.0.1:13003`, - rep: `tcp://127.0.0.1:15003`, - clientRep: `tcp://127.0.0.1:17003`, + const newLeaderNodeInfo = { + id: uuidV4(), + pid: process.pid, + startedAt: new Date(), + networkInfo: { + leaderRepAddr: `tcp://127.0.0.1:15003`, + leaderPubAddr: `tcp://127.0.0.1:13003`, + leaderClientRepAddr: `tcp://127.0.0.1:17003`, + }, }; it(`Switch from leader to follower`, function() { const leaderOptions = { + etcdHosts: ['http://localhost:2379'], ...keyOptions, ...addrOptions, type: fedcom.VALIDATOR_TYPE.LEADER, @@ -118,12 +125,11 @@ describe(`Validator module`, function() { // Validator starting as leader validator.start(); - validator.switchToNewLeader(newLeader); + validator.switchToNewLeader(newLeaderNodeInfo); chai.expect(validator.leaderPubAddr).to.equal(`tcp://127.0.0.1:13003`); chai.expect(validator.leaderRepAddr).to.equal(`tcp://127.0.0.1:15003`); chai.expect(validator.leaderClientRepAddr).to.equal(`tcp://127.0.0.1:17003`); - chai.expect(validator.type).to.equal(fedcom.VALIDATOR_TYPE.FOLLOWER); // Stop the validator validator.stop(); @@ -134,6 +140,7 @@ describe(`Validator module`, function() { // Its leader is follower 2 // It has been elected leader const followerOptions = { + etcdHosts: ['http://localhost:2379'], ...keyOptions, clientRepAddr: `tcp://127.0.0.1:17003`, pubAddr: `tcp://127.0.0.1:13003`, @@ -141,19 +148,17 @@ describe(`Validator module`, function() { leaderPubAddr: `tcp://127.0.0.1:13002`, leaderRepAddr: `tcp://127.0.0.1:15002`, leaderClientRepAddr: `tcp://127.0.0.1:17002`, - type: fedcom.VALIDATOR_TYPE.FOLLOWER, }; const validator = new Validator(new Connector.FABRIC(config.blockchains.fabric), followerOptions); // Validator starting as follower 3 validator.start(); // New leader is follower 3 - validator.switchToNewLeader(newLeader); + validator.switchToNewLeader(newLeaderNodeInfo); chai.expect(validator.leaderPubAddr).to.equal(`tcp://127.0.0.1:13003`); chai.expect(validator.leaderRepAddr).to.equal(`tcp://127.0.0.1:15003`); chai.expect(validator.leaderClientRepAddr).to.equal(`tcp://127.0.0.1:17003`); - chai.expect(validator.type).to.equal(fedcom.VALIDATOR_TYPE.LEADER); // Stop the validator validator.stop(); @@ -164,6 +169,7 @@ describe(`Validator module`, function() { // His leader is follower 2 // Elected validator is follower 3 const followerOptions = { + etcdHosts: ['http://localhost:2379'], ...keyOptions, ...addrOptions, type: fedcom.VALIDATOR_TYPE.FOLLOWER, @@ -176,7 +182,7 @@ describe(`Validator module`, function() { validator.start(); // New leader is follower 3 - validator.switchToNewLeader(newLeader); + validator.switchToNewLeader(newLeaderNodeInfo); chai.expect(validator.leaderPubAddr).to.equal(`tcp://127.0.0.1:13003`); chai.expect(validator.leaderRepAddr).to.equal(`tcp://127.0.0.1:15003`); @@ -195,12 +201,19 @@ describe(`Validator module`, function() { it(`The messages are well published via the right addr`, async function() { const leaderOptions = { + etcdHosts: ['http://localhost:2379'], ...keyOptions, ...addrOptions, - type: fedcom.VALIDATOR_TYPE.LEADER, }; leader = new Validator(new Connector.FABRIC(config.blockchains.fabric), leaderOptions); + // self promote to leader manually for test since there's no etd cluster, we need to fake/rig the election + leader.leaderNodeInfo = leader.selfNodeInfo; + // sets this.leaderPubAddr, this.leaderRepAddr, this.leaderClientRepAddr according to new leader + Object.assign(leader, leader.leaderNodeInfo.networkInfo); + + chai.expect(leader.isCurrentNodeLeader()).to.equal(true); + // Validator starting as leader leader.startAsLeader(); @@ -209,14 +222,14 @@ describe(`Validator module`, function() { new Promise((resolve, reject) => { const socket = zmq.socket(`sub`); try { - socket.connect(`tcp://127.0.0.1:13001`); + socket.connect(leader.leaderPubAddr); socket.subscribe(``); } catch (error) { reject(error); } - socket.on(`message`, type => { - resolve(type.toString()); + socket.on(`message`, typeBuffer => { + resolve(typeBuffer.toString()); clearInterval(leader.intervalExec); leader.publishSocket.close(); leader.requestSocket.close(); @@ -224,13 +237,21 @@ describe(`Validator module`, function() { }); }); - const type = await receiveBroadcast(); - const ok = [fedcom.MSG_TYPE.HEARTBEAT, fedcom.MSG_TYPE.NEWLEADER, fedcom.MSG_TYPE.SIGN].includes(type); - chai.expect(ok).to.equal(true); + setTimeout(() => { + const targetDLTType = `FABRIC`; + const data = {}; + const type = fedcom.MSG_TYPE.SIGN; + const signatureReq = { type, data, targetDLTType, requester: leader.leaderRepAddr }; + leader.publishSocket.send([fedcom.MSG_TYPE.SIGN, JSON.stringify(signatureReq)]); + }, 100); + + const broadcastedType = await receiveBroadcast(); // if message didn't arrive this will cause the test to time out + chai.expect(broadcastedType).to.equal(fedcom.MSG_TYPE.SIGN); }); it(`The leader listens to heartbeat messages at repAddr`, async function() { const leaderOptions = { + etcdHosts: ['http://localhost:2379'], ...keyOptions, clientRepAddr: `tcp://127.0.0.1:17002`, pubAddr: `tcp://127.0.0.1:13002`, @@ -239,6 +260,13 @@ describe(`Validator module`, function() { }; const validator = new Validator(new Connector.FABRIC(config.blockchains.fabric), leaderOptions); + // self promote to leader manually for test since there's no etd cluster, we need to fake/rig the election + validator.leaderNodeInfo = validator.selfNodeInfo; + // sets this.leaderPubAddr, this.leaderRepAddr, this.leaderClientRepAddr according to new leader + Object.assign(validator, validator.leaderNodeInfo.networkInfo); + + chai.expect(validator.isCurrentNodeLeader()).to.equal(true); + // Validator starting as leader validator.startAsLeader(); const heartbeat = { @@ -274,6 +302,7 @@ describe(`Validator module`, function() { it(`The leader listens to signature messages at repAddr`, async function() { const leaderOptions = { + etcdHosts: ['http://localhost:2379'], ...keyOptions, clientRepAddr: `tcp://127.0.0.1:17003`, pubAddr: `tcp://127.0.0.1:13003`, @@ -282,6 +311,12 @@ describe(`Validator module`, function() { }; const validator = new Validator(new Connector.FABRIC(config.blockchains.fabric), leaderOptions); + // self promote to leader manually for test since there's no etd cluster, we need to fake/rig the election + validator.leaderNodeInfo = validator.selfNodeInfo; + // sets this.leaderPubAddr, this.leaderRepAddr, this.leaderClientRepAddr according to new leader + Object.assign(validator, validator.leaderNodeInfo.networkInfo); + + chai.expect(validator.isCurrentNodeLeader()).to.equal(true); // Validator starting as leader validator.startAsLeader(); const signature = { @@ -388,7 +423,8 @@ describe(`Validator module`, function() { // chai.expect(signature).to.have.own.property(`signature`); // chai.expect(signature).to.deep.equal({ // type: fedcom.MSG_TYPE.SIGN, - // signature: `31a5012bcdaf27b75d34c78d643d262c8b01db477dc65f308189866cfac0f82461362e3b00039007c2f1da164de7aeeba2f491711cde191957d51cc408eb1787`, // eslint-disable-line + // eslint-disable-next-line + // signature: `31a5012bcdaf27b75d34c78d643d262c8b01db477dc65f308189866cfac0f82461362e3b00039007c2f1da164de7aeeba2f491711cde191957d51cc408eb1787`, // pubKey: `031b3e4b65070268bd2ce3652966f75ebdf7184f637fd24a4fe0417c2dcb92fd9b`, // }); // }); @@ -401,6 +437,7 @@ describe(`Validator module`, function() { before(function() { const leaderOptions = { + etcdHosts: ['http://localhost:2379'], ...keyOptions, ...addrOptions, type: fedcom.VALIDATOR_TYPE.LEADER, @@ -483,6 +520,7 @@ describe(`Validator module`, function() { before(function() { const followerOptions = { + etcdHosts: ['http://localhost:2379'], ...keyOptions, clientRepAddr: `tcp://127.0.0.1:17005`, pubAddr: `tcp://127.0.0.1:13005`, diff --git a/tools/create-local-npm-package.js b/tools/create-local-npm-package.js new file mode 100755 index 0000000000..4f94acef09 --- /dev/null +++ b/tools/create-local-npm-package.js @@ -0,0 +1,73 @@ +/* eslint-disable no-console */ +const { execSync } = require('child_process'); +const fs = require('fs'); +const { join } = require('path'); + +const TAG = '[create-local-npm-package]'; +const PROJECT_ROOT = join(__dirname, '../'); // step out of the tools dir to project root +const TMP_DIR = join(PROJECT_ROOT, './.tmp'); + +/** + * A short, self-contained script with zero non-builtin dependencies (so that it doesn't require package.sjon/npm install) + * to be executed. It just needs NodeJS installed on the host operating system to be ready to go. + * + * The script is responsible for generating an npm package archivel file with a fixed name that can be used to install + * BIF locally for the examples without having to depend on remote Github URLs/registries for installation (which + * hugely complicates things and makes the whole process less deterministic) + * + * CWD (current working directory) agnostic: script anchors paths based on assumption that it is one level down from + * the root directory in the tools sub-folder so it will work regardless of where it was invoked from. This was + * necessary to make it easy to call the script from the examples/ sub-folders without having to bother about relative + * paths/project root resolution/normalization. + * + * Step by step this is what the script does: + * 1. Prints diagnostic info for debugging purposes about node and npm versions. + * 2. Reads the package.json file's contents form the project root directory + * 3. Gets version, package name from package.json contents (after parsing the JSON string) + * 4. Assembles the package file name that npm pack will produce based on the metadata (version, name) of the package + * obtained in step 3). + * 5. Invokes shell `npm pack` so that npm generates the package file that we already know the name of from step 4) + * 6. Renames and moves the generated package file so that a) it does not have a version in it's name and b) it resides + * in a directory that is not under version control (.tmp directory). + * 7. Prints success or failure depending on what happened. + * + */ +const main = async () => { + if (!fs.existsSync(TMP_DIR)) { + fs.mkdirSync(TMP_DIR); + } + + const nodeVersion = execSync('node --version') + .toString() + .trim(); + + const npmVersion = execSync('npm --version') + .toString() + .trim(); + + console.log(`${new Date().toJSON()} ${TAG} - NodeVersion=${nodeVersion}, npmVersion=${npmVersion}`); + + const packageFileName = execSync('npm pack', { cwd: PROJECT_ROOT }) + .toString() + .trim(); + + console.log(`${new Date().toJSON()} ${TAG} - packageFileName: "${packageFileName}"`); + + const packageJsonRaw = fs.readFileSync(join(PROJECT_ROOT, 'package.json')); + const packageJson = JSON.parse(packageJsonRaw); + console.log(`${new Date().toJSON()} ${TAG} - packageJson.version=${packageJson.version}`); + + const newPackageFileName = packageFileName.replace(packageJson.version, 'dev'); + fs.renameSync(join(PROJECT_ROOT, packageFileName), join(TMP_DIR, newPackageFileName)); + return newPackageFileName; +}; + +main() + .then(newPackageFileName => { + console.log(`${new Date().toJSON()} ${TAG} - SUCCESS_4d21b660-7676-4394-b853-642ce3617bed ${newPackageFileName}`); + process.exit(0); + }) + .catch(ex => { + console.error(`${new Date().toJSON()} ${TAG} - FAILURE_4d21b660-7676-4394-b853-642ce3617bed Process crashed:`, ex); + process.exit(1); + });