Browse Source

storage-node-v2: Add ‘AcceptInvitation’ command.

- Add ‘AcceptStorageBucketInvitation’ command for storage bucket providers.
Shamil Gadelshin 3 years ago
parent
commit
2e2b125056

+ 23 - 4
storage-node-v2/README.md

@@ -29,7 +29,8 @@ USAGE
 # Commands
 <!-- commands -->
 * [`storage-node help [COMMAND]`](#storage-node-help-command)
-* [`storage-node wg:leader:create-bucket [FILE]`](#storage-node-wgleadercreate-bucket-file)
+* [`storage-node wg:leader:create-bucket`](#storage-node-wgleadercreate-bucket)
+* [`storage-node wg:operator:accept-invitation [FILE]`](#storage-node-wgoperatoraccept-invitation-file)
 
 ## `storage-node help [COMMAND]`
 
@@ -48,13 +49,31 @@ OPTIONS
 
 _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v3.2.2/src/commands/help.ts)_
 
-## `storage-node wg:leader:create-bucket [FILE]`
+## `storage-node wg:leader:create-bucket`
+
+Create new storage bucket. Requires storage working group leader permissions.
+
+```
+USAGE
+  $ storage-node wg:leader:create-bucket
+
+OPTIONS
+  -a, --allow          Accepts new bags
+  -d, --dev            Use development mode
+  -h, --help           show CLI help
+  -n, --number=number  Storage bucket max total objects number
+  -s, --size=size      Storage bucket max total objects size
+```
+
+_See code: [src/commands/wg/leader/create-bucket.ts](https://github.com/shamil-gadelshin/storage-node-v2/blob/v0.1.0/src/commands/wg/leader/create-bucket.ts)_
+
+## `storage-node wg:operator:accept-invitation [FILE]`
 
 describe the command here
 
 ```
 USAGE
-  $ storage-node wg:leader:create-bucket [FILE]
+  $ storage-node wg:operator:accept-invitation [FILE]
 
 OPTIONS
   -f, --force
@@ -62,5 +81,5 @@ OPTIONS
   -n, --name=name  name to print
 ```
 
-_See code: [src/commands/wg/leader/create-bucket.ts](https://github.com/shamil-gadelshin/storage-node-v2/blob/v0.1.0/src/commands/wg/leader/create-bucket.ts)_
+_See code: [src/commands/wg/operator/accept-invitation.ts](https://github.com/shamil-gadelshin/storage-node-v2/blob/v0.1.0/src/commands/wg/operator/accept-invitation.ts)_
 <!-- commandsstop -->

+ 8 - 5
storage-node-v2/src/commands/wg/leader/create-bucket.ts

@@ -13,26 +13,29 @@ export default class WgLeaderCreateBucket extends Command {
     number: flags.integer({
       char: 'n',
       description: 'Storage bucket max total objects number',
+    }),   
+    invited: flags.integer({
+      char: 'i',
+      description: 'Invited storage operator ID (storage WG worker ID)',
     }),
     allow: flags.boolean({ char: 'a', description: 'Accepts new bags' }),
-    dev: flags.boolean({ char: 'd', description: 'Development API' }),
+    dev: flags.boolean({ char: 'd', description: 'Use development mode' }),
   }
 
-  static args = [{ name: 'file' }]
-
   async run() {
     const { flags } = this.parse(WgLeaderCreateBucket)
 
     const objectSize = flags.size ?? 0
     const objectNumber = flags.number ?? 0
-    const allowNewBags = flags.allow ?? true
+    const allowNewBags = flags.allow ?? false
+    const invitedWorker = flags.invited
 
     this.log('Creating storage bucket...')
     if (flags.dev) {
       this.log('development mode is ON')
     }
 
-    await createStorageBucket(null, allowNewBags, objectSize, objectNumber)
+    await createStorageBucket(invitedWorker, allowNewBags, objectSize, objectNumber)
   }
 
   async finally(err: any) {

+ 44 - 0
storage-node-v2/src/commands/wg/operator/accept-invitation.ts

@@ -0,0 +1,44 @@
+import {Command, flags} from '@oclif/command'
+import { acceptStorageBucketInvitation } from '../../../services/api'
+
+export default class WgOperatorAcceptInvitation extends Command {
+  static description = 'Accept pending storage bucket invitation.'
+
+  static flags = {
+    help: flags.help({char: 'h'}),
+    worker: flags.integer({
+      char: 'w',
+      required: true,
+      description: 'Storage operator worker ID',
+    }),
+    bucket: flags.integer({
+      char: 'b',
+      required: true,
+      description: 'Storage bucket ID',
+    }),
+    dev: flags.boolean({ char: 'd', description: 'Use development mode' }),
+  }
+
+  static args = [{name: 'file'}]
+
+  async run() {
+    const { flags } = this.parse(WgOperatorAcceptInvitation)
+
+    const worker = flags.worker ?? 0
+    const bucket = flags.bucket ?? 0
+
+    this.log('Accepting pending storage bucket invitation...')
+    if (flags.dev) {
+      this.log('development mode is ON')
+    }
+
+    await acceptStorageBucketInvitation(worker, bucket)
+  }
+
+  async finally(err: any) {
+    // called after run and catch regardless of whether or not the command errored
+    // We'll force exit here, in case there is no error, to prevent console.log from hanging the process
+    if (!err) this.exit(0)
+    super.finally(err)
+  }
+}

+ 45 - 3
storage-node-v2/src/services/api.ts

@@ -41,14 +41,56 @@ export async function createStorageBucket(
         objectsLimit
       )
       .signAndSend(alice)
+      console.log(`Submitted with hash ${txHash}`)
 
-    // Show the hash
-    console.log(`Submitted with hash ${txHash}`)
+      // const unsub = await api.tx.storage
+      // .createStorageBucket(
+      //   invitedWorkerValue,
+      //   allowedNewBags,
+      //   sizeLimit,
+      //   objectsLimit
+      // )
+      // .signAndSend(alice, (result) => {
+      //   console.log(`Current status is ${result.status}`);
+
+      //   if (result.status.isInBlock) {
+      //     console.log(`Transaction included at blockHash ${result.status.asInBlock}`);
+      //   } else if (result.status.isFinalized) {
+      //     console.log(`Transaction finalized at blockHash ${result.status.asFinalized}`);
+      //     unsub();
+      //   }
+      // });
+    
+  } catch (err) {
+    console.error(`Api Error: ${err}`)
+  }
+}
+
+export async function acceptStorageBucketInvitation(
+  workerId: number,
+  storageBucketId: number,
+): Promise<void> {
+  try {
+    let api = await createApi()
+
+    const keyring = new Keyring({ type: 'sr25519' })
+    const alice = keyring.addFromUri('//Alice')
+
+
+    const txHash = await api.tx.storage
+      .acceptStorageBucketInvitation(
+        workerId,
+        storageBucketId,
+      )
+      .signAndSend(alice)
+      console.log(`Submitted with hash ${txHash}`)
+    
   } catch (err) {
     console.error(`Api Error: ${err}`)
   }
 }
 
+
 async function createApi() {
   const wsProvider = new WsProvider('ws://localhost:9944')
   let extendedTypes = createExtendedTypes(types)
@@ -58,7 +100,7 @@ async function createApi() {
 
 function createExtendedTypes(defaultTypes: RegistryTypes) {
   let extendedTypes = types
-  extendedTypes.StorageBucketId = {}
+  extendedTypes.StorageBucketId = 'u64'
   extendedTypes.BagId = {}
   extendedTypes.UploadParameters = {}
   extendedTypes.DynamicBagId = {}

+ 0 - 17
storage-node-v2/test/commands/wg.test.ts

@@ -1,17 +0,0 @@
-import {expect, test} from '@oclif/test'
-
-describe('wg', () => {
-  test
-  .stdout()
-  .command(['wg'])
-  .it('runs hello', ctx => {
-    expect(ctx.stdout).to.contain('hello world')
-  })
-
-  test
-  .stdout()
-  .command(['wg', '--name', 'jeff'])
-  .it('runs hello --name jeff', ctx => {
-    expect(ctx.stdout).to.contain('hello jeff')
-  })
-})

+ 3 - 3
storage-node-v2/test/commands/hello.test.ts → storage-node-v2/test/commands/wg/operator/accept-invitation.test.ts

@@ -1,16 +1,16 @@
 import {expect, test} from '@oclif/test'
 
-describe('hello', () => {
+describe('wg:operator:accept-invitation', () => {
   test
   .stdout()
-  .command(['hello'])
+  .command(['wg:operator:accept-invitation'])
   .it('runs hello', ctx => {
     expect(ctx.stdout).to.contain('hello world')
   })
 
   test
   .stdout()
-  .command(['hello', '--name', 'jeff'])
+  .command(['wg:operator:accept-invitation', '--name', 'jeff'])
   .it('runs hello --name jeff', ctx => {
     expect(ctx.stdout).to.contain('hello jeff')
   })