Explorar o código

Merge branch 'olympia-playground' into fix-compile-time-proposal-params-config

Mokhtar Naamani %!s(int64=3) %!d(string=hai) anos
pai
achega
1107fadf4b

+ 3 - 2
.github/workflows/create-ami.yml

@@ -61,8 +61,9 @@ jobs:
             ${{ steps.deploy_stack.outputs.PublicIp }}
           options: |
             --extra-vars "git_repo=https://github.com/${{ github.repository }} \
-                          branch_name=${{ steps.extract_branch.outputs.branch }} instance_id=${{ steps.deploy_stack.outputs.InstanceId }}
-                          ami_name=${{ env.ami_name }}
+                          branch_name=${{ steps.extract_branch.outputs.branch }} \
+                          instance_id=${{ steps.deploy_stack.outputs.InstanceId }} \
+                          ami_name=${{ env.ami_name }} \
                           proposal_parameters=${{ github.event.inputs.proposalParameters }}"
 
       - name: Delete CloudFormation Stack

+ 2 - 2
.github/workflows/deploy-playground.yml

@@ -92,8 +92,8 @@ jobs:
             --extra-vars "git_repo=${{ github.event.inputs.gitRepo }} \
                           branch_name=${{ github.event.inputs.branchName }} \
                           skip_chain_setup=${{ github.event.inputs.skipChainSetup }} \
-                          proposal_parameters='${{ github.event.inputs.proposalParameters }}' \
-                          stack_name=${{ env.STACK_NAME }}"
+                          stack_name=${{ env.STACK_NAME }} \
+                          proposal_parameters=${{ github.event.inputs.proposalParameters }}"
 
       - name: Save the endpoints file as an artifact
         uses: actions/upload-artifact@v2

+ 2 - 2
.pipelines/deploy-node-network-inputs.json

@@ -28,8 +28,8 @@
     "value": "t2.micro"
   },
   "ec2AMI": {
-    "description": "Pre-built AMI ID (ami-095792100b6e43a67)",
-    "value": "ami-095792100b6e43a67"
+    "description": "Pre-built AMI ID",
+    "value": "ami-0ce5f13e91397239a"
   },
   "volumeSize": {
     "description": "Validator and Build instance volume size in GB",

+ 14 - 12
cli/src/ExitCodes.ts

@@ -1,18 +1,20 @@
 enum ExitCodes {
   OK = 0,
 
-  InvalidInput = 400,
-  FileNotFound = 401,
-  InvalidFile = 402,
-  NoAccountFound = 403,
-  NoAccountSelected = 404,
-  AccessDenied = 405,
+  InvalidInput = 40,
+  FileNotFound = 41,
+  InvalidFile = 42,
+  NoAccountFound = 43,
+  NoAccountSelected = 44,
+  AccessDenied = 45,
 
-  UnexpectedException = 500,
-  FsOperationFailed = 501,
-  ApiError = 502,
-  StorageNodeError = 503,
-  ActionCurrentlyUnavailable = 504,
-  QueryNodeError = 505,
+  UnexpectedException = 50,
+  FsOperationFailed = 51,
+  ApiError = 52,
+  StorageNodeError = 53,
+  ActionCurrentlyUnavailable = 54,
+  QueryNodeError = 55,
+
+  // NOTE: never exceed exit code 255 or it will be modulated by `256` and create problems
 }
 export = ExitCodes

+ 1 - 1
cli/src/base/AccountsCommandBase.ts

@@ -381,7 +381,7 @@ export default abstract class AccountsCommandBase extends ApiCommandBase {
     const requiredStakingAccountBalance = !stakingStatus
       ? requiredStake.add(candidateTxFee).add(STAKING_ACCOUNT_CANDIDATE_STAKE)
       : requiredStake
-    const missingStakingAccountBalance = requiredStakingAccountBalance.sub(balances.availableBalance)
+    const missingStakingAccountBalance = requiredStakingAccountBalance.sub(balances.freeBalance)
     if (missingStakingAccountBalance.gtn(0)) {
       this.warn(
         `Not enough available staking account balance! Missing: ${chalk.cyanBright(

+ 8 - 6
cli/src/commands/working-groups/createOpening.ts

@@ -104,12 +104,14 @@ export default class WorkingGroupsCreateOpening extends WorkingGroupsCommandBase
     return getInputJson<WorkingGroupOpeningInputParameters>(filePath, WorkingGroupOpeningInputSchema)
   }
 
-  async promptForStakeTopUp(stakingAccount: string, fundsSource?: string): Promise<void> {
-    const requiredStake = this.getOriginalApi().consts[apiModuleByGroup[this.group]].leaderOpeningStake
-    this.log(`You need to stake ${chalk.bold(formatBalance(requiredStake))} in order to create a new opening.`)
+  async promptForStakeTopUp({ stake, stakingAccount }: GroupMember, fundsSource?: string): Promise<void> {
+    const newStake = this.getOriginalApi().consts[apiModuleByGroup[this.group]].leaderOpeningStake.add(stake)
+    this.log(
+      `You need to increase your lead stake to ${chalk.bold(formatBalance(newStake))} in order to create a new opening.`
+    )
 
-    const [balances] = await this.getApi().getAccountsBalancesInfo([stakingAccount])
-    const missingBalance = requiredStake.sub(balances.availableBalance)
+    const [balances] = await this.getApi().getAccountsBalancesInfo([stakingAccount.toString()])
+    const missingBalance = newStake.sub(balances.freeBalance)
     if (missingBalance.gtn(0)) {
       await this.requireConfirmation(
         `Do you wish to transfer remaining ${chalk.bold(
@@ -250,7 +252,7 @@ export default class WorkingGroupsCreateOpening extends WorkingGroupsCommandBase
       rememberedInput = openingJson
 
       if (!upcoming) {
-        await this.promptForStakeTopUp(lead.stakingAccount.toString(), stakeTopUpSource)
+        await this.promptForStakeTopUp(lead, stakeTopUpSource)
       }
 
       const createUpcomingOpeningActionMeta = this.prepareCreateUpcomingOpeningMetadata(

+ 1 - 1
devops/aws/deploy-infra.sample.cfg

@@ -11,7 +11,7 @@ BUILD_EC2_INSTANCE_TYPE=t2.large
 RPC_EC2_INSTANCE_TYPE=t2.medium
 
 # prebuilt AMI with joystream-node, chain-spec and subkey already built
-EC2_AMI_ID="ami-095792100b6e43a67"
+EC2_AMI_ID="ami-0ce5f13e91397239a"
 
 ACCOUNT_ID=$(aws sts get-caller-identity --profile $CLI_PROFILE --query Account --output text)
 

+ 6 - 4
distributor-node/src/command-base/ExitCodes.ts

@@ -1,9 +1,11 @@
 enum ExitCodes {
   OK = 0,
   Error = 1,
-  ApiError = 200,
-  InvalidInput = 400,
-  FileNotFound = 401,
-  InvalidFile = 402,
+  ApiError = 20,
+  InvalidInput = 40,
+  FileNotFound = 41,
+  InvalidFile = 42,
+
+  // NOTE: never exceed exit code 255 or it will be modulated by `256` and create problems
 }
 export = ExitCodes

+ 3 - 2
query-node/mappings/src/common.ts

@@ -259,10 +259,11 @@ export function getWorkingGroupModuleName(group: WorkingGroup): WorkingGroupModu
 export async function getWorker(
   store: DatabaseManager,
   groupName: WorkingGroupModuleName,
-  runtimeId: WorkerId | number
+  runtimeId: WorkerId | number,
+  relations: string[] = []
 ): Promise<Worker> {
   const workerDbId = `${groupName}-${runtimeId}`
-  const worker = await store.get(Worker, { where: { id: workerDbId } })
+  const worker = await store.get(Worker, { where: { id: workerDbId }, relations })
   if (!worker) {
     inconsistentState(`Expected worker not found by id ${workerDbId}`)
   }

+ 15 - 3
query-node/mappings/src/workingGroups.ts

@@ -338,7 +338,7 @@ async function handleWorkingGroupMetadataAction(
 async function handleTerminatedWorker({ store, event }: EventContext & StoreContext): Promise<void> {
   const [workerId, optPenalty, optRationale] = new WorkingGroups.TerminatedWorkerEvent(event).params
   const group = await getWorkingGroup(store, event)
-  const worker = await getWorker(store, group.name as WorkingGroupModuleName, workerId)
+  const worker = await getWorker(store, group.name as WorkingGroupModuleName, workerId, ['application'])
   const eventTime = new Date(event.blockTimestamp)
 
   const EventConstructor = worker.isLead ? TerminatedLeaderEvent : TerminatedWorkerEvent
@@ -359,6 +359,7 @@ async function handleTerminatedWorker({ store, event }: EventContext & StoreCont
   worker.stake = new BN(0)
   worker.rewardPerBlock = new BN(0)
   worker.updatedAt = eventTime
+  worker.isActive = isWorkerActive(worker)
 
   await store.save<Worker>(worker)
 }
@@ -373,6 +374,14 @@ export async function findLeaderSetEventByTxHash(store: DatabaseManager, txHash?
   return leaderSetEvent
 }
 
+// expects `worker.application` to be available
+function isWorkerActive(worker: Worker): boolean {
+  return (
+    worker.application.status.isTypeOf === 'ApplicationStatusAccepted' &&
+    worker.status.isTypeOf === 'WorkerStatusActive'
+  )
+}
+
 // Mapping functions
 export async function workingGroups_OpeningAdded({ store, event }: EventContext & StoreContext): Promise<void> {
   const [
@@ -536,6 +545,7 @@ export async function workingGroups_OpeningFilled({ store, event }: EventContext
               entry: openingFilledEvent,
               rewardPerBlock: opening.rewardPerBlock,
             })
+            worker.isActive = isWorkerActive(worker)
             await store.save<Worker>(worker)
             return worker
           }
@@ -787,7 +797,7 @@ export async function workingGroups_NewMissedRewardLevelReached({
 export async function workingGroups_WorkerExited({ store, event }: EventContext & StoreContext): Promise<void> {
   const [workerId] = new WorkingGroups.WorkerExitedEvent(event).params
   const group = await getWorkingGroup(store, event)
-  const worker = await getWorker(store, group.name as WorkingGroupModuleName, workerId)
+  const worker = await getWorker(store, group.name as WorkingGroupModuleName, workerId, ['application'])
   const eventTime = new Date(event.blockTimestamp)
 
   const workerExitedEvent = new WorkerExitedEvent({
@@ -807,6 +817,7 @@ export async function workingGroups_WorkerExited({ store, event }: EventContext
   worker.rewardPerBlock = new BN(0)
   worker.missingRewardAmount = undefined
   worker.updatedAt = eventTime
+  worker.isActive = isWorkerActive(worker)
 
   await store.save<Worker>(worker)
 }
@@ -907,7 +918,7 @@ export async function workingGroups_StakeDecreased({ store, event }: EventContex
 export async function workingGroups_WorkerStartedLeaving({ store, event }: EventContext & StoreContext): Promise<void> {
   const [workerId, optRationale] = new WorkingGroups.WorkerStartedLeavingEvent(event).params
   const group = await getWorkingGroup(store, event)
-  const worker = await getWorker(store, group.name as WorkingGroupModuleName, workerId)
+  const worker = await getWorker(store, group.name as WorkingGroupModuleName, workerId, ['application'])
   const eventTime = new Date(event.blockTimestamp)
 
   const workerStartedLeavingEvent = new WorkerStartedLeavingEvent({
@@ -923,6 +934,7 @@ export async function workingGroups_WorkerStartedLeaving({ store, event }: Event
   status.workerStartedLeavingEventId = workerStartedLeavingEvent.id
   worker.status = status
   worker.updatedAt = eventTime
+  worker.isActive = isWorkerActive(worker)
 
   await store.save<Worker>(worker)
 }

+ 8 - 0
query-node/schemas/workingGroups.graphql

@@ -34,6 +34,11 @@ type Worker @entity {
   "The group that the worker belongs to"
   group: WorkingGroup!
 
+  # This exposes internal Hydra value related to `group`. It will be internally set and updated by Hydra.
+  # See https://github.com/Joystream/joystream/pull/3043 for more info.
+  "The id the group that the worker belongs to"
+  groupId: ID!
+
   "Worker membership"
   membership: Membership!
 
@@ -52,6 +57,9 @@ type Worker @entity {
   "Whether the worker is also the working group lead"
   isLead: Boolean!
 
+  "Whether the worker is currently active"
+  isActive: Boolean!
+
   "Current role stake (in JOY)"
   stake: BigInt!
 

+ 1 - 1
runtime-modules/content/src/lib.rs

@@ -2221,7 +2221,7 @@ decl_event!(
             ContentActor,
             VideoId,
             Option<Royalty>,
-            Metadata,
+            Vec<u8>,
             Option<MemberId>,
             InitTransactionalStatus,
         ),

+ 2 - 2
runtime-modules/content/src/nft/types.rs

@@ -1,7 +1,7 @@
 use super::*;
 
 /// Metadata for Nft issuance
-pub type Metadata = Vec<u8>;
+pub type MetadataBytes = Vec<u8>;
 
 /// Owner royalty
 pub type Royalty = Perbill;
@@ -515,7 +515,7 @@ pub struct NftIssuanceParametersRecord<MemberId, InitTransactionalStatus> {
     /// Roayalty used for the author
     pub royalty: Option<Royalty>,
     /// Metadata
-    pub nft_metadata: Metadata,
+    pub nft_metadata: MetadataBytes,
     /// member id Nft will be issued to
     pub non_channel_owner: Option<MemberId>,
     /// Initial transactional status for the nft

+ 2 - 0
storage-node/src/command-base/ExitCodes.ts

@@ -13,6 +13,8 @@ enum ExitCodes {
   ServerError,
   ApiError = 200,
   UnsuccessfulRuntimeCall,
+
+  // NOTE: never exceed exit code 255 or it will be modulated by `256` and create problems
 }
 
 export = ExitCodes

+ 4 - 3
types/augment/all/defs.json

@@ -565,18 +565,19 @@
     "ConstitutionInfo": {
         "text_hash": "Hash"
     },
-    "BountyId": "u32",
-    "EntryId": "u32",
+    "BountyId": "u64",
+    "EntryId": "u64",
     "BountyActor": {
         "_enum": {
             "Council": "Null",
             "Member": "MemberId"
         }
     },
+    "AssuranceContractType_Closed": "BTreeSet<MemberId>",
     "AssuranceContractType": {
         "_enum": {
             "Open": "Null",
-            "Closed": "Vec<MemberId>"
+            "Closed": "AssuranceContractType_Closed"
         }
     },
     "FundingType_Limited": {

+ 6 - 3
types/augment/all/types.ts

@@ -60,9 +60,12 @@ export interface Approved extends Enum {
 export interface AssuranceContractType extends Enum {
   readonly isOpen: boolean;
   readonly isClosed: boolean;
-  readonly asClosed: Vec<MemberId>;
+  readonly asClosed: AssuranceContractType_Closed;
 }
 
+/** @name AssuranceContractType_Closed */
+export interface AssuranceContractType_Closed extends BTreeSet<MemberId> {}
+
 /** @name Auction */
 export interface Auction extends Struct {
   readonly starting_price: u128;
@@ -157,7 +160,7 @@ export interface BountyCreationParameters extends Struct {
 }
 
 /** @name BountyId */
-export interface BountyId extends u32 {}
+export interface BountyId extends u64 {}
 
 /** @name BuyMembershipParameters */
 export interface BuyMembershipParameters extends Struct {
@@ -459,7 +462,7 @@ export interface Entry extends Struct {
 }
 
 /** @name EntryId */
-export interface EntryId extends u32 {}
+export interface EntryId extends u64 {}
 
 /** @name ExecutionFailed */
 export interface ExecutionFailed extends Struct {

+ 3 - 3
types/package.json

@@ -5,11 +5,11 @@
   "main": "index.js",
   "types": "index.d.ts",
   "scripts": {
-    "prepublishOnly": "npm run build",
-    "prepack": "npm run build",
+    "prepublishOnly": "yarn clean && yarn build",
+    "prepack": "yarn clean && yarn build",
     "compile": "tsc --build tsconfig.json",
     "clean": "git clean -xdf -e node_modules",
-    "build": "yarn clean; yarn compile && yarn generate:all",
+    "build": "yarn compile && yarn generate:all",
     "lint": "eslint ./ --ext .ts",
     "format": "prettier ./ --write",
     "check:augment": "tsc --build tsconfig-augment.json && tsc --build tsconfig-augment-codec.json",

+ 7 - 4
types/src/bounty.ts

@@ -1,17 +1,19 @@
-import { Null, u32, u128, bool, Option, Vec, BTreeMap } from '@polkadot/types'
+import { Null, u32, u64, u128, bool, Option, BTreeSet, BTreeMap } from '@polkadot/types'
 import { JoyEnum, JoyStructDecorated, MemberId, AccountId } from './common'
 
-export class BountyId extends u32 {}
-export class EntryId extends u32 {}
+export class BountyId extends u64 {}
+export class EntryId extends u64 {}
 
 export class BountyActor extends JoyEnum({
   Council: Null,
   Member: MemberId,
 }) {}
 
+export class AssuranceContractType_Closed extends BTreeSet.with(MemberId) {}
+
 export class AssuranceContractType extends JoyEnum({
   Open: Null,
-  Closed: Vec.with(MemberId), // FIXME: @polkadot/typegen Error: Enum: AssuranceContractType: Unhandled nested "BTreeSet"
+  Closed: AssuranceContractType_Closed,
 }) {}
 
 export class FundingType_Perpetual extends JoyStructDecorated({
@@ -63,6 +65,7 @@ export const bountyTypes = {
   BountyId,
   EntryId,
   BountyActor,
+  AssuranceContractType_Closed,
   AssuranceContractType,
   FundingType_Limited,
   FundingType_Perpetual,

+ 1 - 2
utils/api-scripts/src/initialize-lead.ts

@@ -22,7 +22,6 @@ const workingGroupModules = [
 type WorkingGroupModuleName = typeof workingGroupModules[number]
 
 const MIN_APPLICATION_STAKE = new BN(2000)
-const STAKING_ACCOUNT_CANDIDATE_STAKE = new BN(200)
 
 async function main() {
   // Init api
@@ -102,7 +101,7 @@ async function main() {
     // Set up stake account
     const addCandidateTx = api.tx.members.addStakingAccountCandidate(memberId)
     const addCandidateFee = (await addCandidateTx.paymentInfo(StakeKeyPair.address)).partialFee
-    const stakingAccountBalance = MIN_APPLICATION_STAKE.add(STAKING_ACCOUNT_CANDIDATE_STAKE).add(addCandidateFee)
+    const stakingAccountBalance = MIN_APPLICATION_STAKE.add(addCandidateFee)
     console.log('Setting up staking account...')
     await txHelper.sendAndCheck(
       LeadKeyPair,