Browse Source

Merge branch 'olympia' into runtime-profiles

Mokhtar Naamani 3 years ago
parent
commit
e1c82b3357

File diff suppressed because it is too large
+ 0 - 0
chain-metadata.json


+ 0 - 6
query-node/manifest.yml

@@ -198,10 +198,6 @@ typegen:
     - content.BuyNowCanceled
     # Utility
     - joystreamUtility.UpdatedWorkingGroupBudget
-
-  calls:
-    # Proposals discussion
-    - proposalsDiscussion.addPost
   outDir: ./mappings/generated/types
   customTypes:
     lib: '@joystream/types/augment/all/types'
@@ -662,8 +658,6 @@ mappings:
     - event: proposalsEngine.ProposalCancelled
       handler: proposalsEngine_ProposalCancelled
     # Proposals discussion
-    - event: proposalsDiscussion.ThreadCreated
-      handler: proposalsDiscussion_ThreadCreated
     - event: proposalsDiscussion.PostCreated
       handler: proposalsDiscussion_PostCreated
     - event: proposalsDiscussion.PostUpdated

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

@@ -1,7 +1,7 @@
-import { DatabaseManager, SubstrateEvent, SubstrateExtrinsic, ExtrinsicArg } from '@joystream/hydra-common'
+import { DatabaseManager, SubstrateEvent } from '@joystream/hydra-common'
 import { Bytes } from '@polkadot/types'
 import { Codec } from '@polkadot/types/types'
-import { WorkingGroup as WGType, WorkerId, ThreadId } from '@joystream/types/augment/all'
+import { WorkingGroup as WGType, WorkerId } from '@joystream/types/augment/all'
 import { Worker, Event, Network, WorkingGroup as WGEntity } from 'query-node/dist/model'
 import { BaseModel } from '@joystream/warthog'
 import { metaToObject } from '@joystream/metadata-protobuf/utils'
@@ -89,110 +89,6 @@ export function invalidMetadata(extraInfo: string, data?: unknown): void {
   logger.info(errorMessage, data)
 }
 
-/// //////////////// Sudo extrinsic calls ///////////////////////////////////////
-
-// soft-peg interface for typegen-generated `*Call` types
-export interface IGenericExtrinsicObject<T> {
-  readonly extrinsic: SubstrateExtrinsic
-  readonly expectedArgTypes: string[]
-  args: T
-}
-
-// arguments for calling extrinsic as sudo
-export interface ISudoCallArgs<T> extends ExtrinsicArg {
-  args: T
-  callIndex: string
-}
-
-/*
-  Extracts extrinsic arguments from the Substrate event. Supports both direct extrinsic calls and sudo calls.
-*/
-export function extractExtrinsicArgs<DataParams, EventObject extends IGenericExtrinsicObject<DataParams>>(
-  rawEvent: SubstrateEvent,
-  callFactoryConstructor: new (event: SubstrateEvent) => EventObject,
-
-  // in ideal world this parameter would not be needed, but there is no way to associate parameters
-  // used in sudo to extrinsic parameters without it
-  argsIndeces: Record<keyof DataParams, number>
-): EventObject['args'] {
-  const CallFactory = callFactoryConstructor
-  // this is equal to DataParams but only this notation works properly
-  // escape when extrinsic info is not available
-  if (!rawEvent.extrinsic) {
-    throw new Error('Invalid event - no extrinsic set') // this should never happen
-  }
-
-  // regural extrinsic call?
-  if (rawEvent.extrinsic.section !== 'sudo') {
-    return new CallFactory(rawEvent).args
-  }
-
-  // sudo extrinsic call
-
-  const callArgs = extractSudoCallParameters<DataParams>(rawEvent)
-
-  // convert naming convention (underscore_names to camelCase)
-  const clearArgs = Object.keys(callArgs.args).reduce((acc, key) => {
-    const formattedName = key.replace(/_([a-z])/g, (tmp) => tmp[1].toUpperCase())
-
-    acc[formattedName] = callArgs.args[key]
-
-    return acc
-  }, {} as DataParams)
-
-  // prepare partial event object
-  const partialEvent = {
-    extrinsic: ({
-      args: Object.keys(argsIndeces).reduce((acc, key) => {
-        acc[argsIndeces[key]] = {
-          value: clearArgs[key],
-        }
-
-        return acc
-      }, [] as unknown[]),
-    } as unknown) as SubstrateExtrinsic,
-  } as SubstrateEvent
-
-  // create event object and extract processed args
-  const finalArgs = new CallFactory(partialEvent).args
-
-  return finalArgs
-}
-
-/*
-  Extracts extrinsic call parameters used inside of sudo call.
-*/
-export function extractSudoCallParameters<DataParams>(rawEvent: SubstrateEvent): ISudoCallArgs<DataParams> {
-  if (!rawEvent.extrinsic) {
-    throw new Error('Invalid event - no extrinsic set') // this should never happen
-  }
-
-  // see Substrate's sudo frame for more info about sudo extrinsics and `call` argument index
-  const argIndex =
-    false ||
-    (rawEvent.extrinsic.method === 'sudoAs' && 1) || // who, *call*
-    (rawEvent.extrinsic.method === 'sudo' && 0) || // *call*
-    (rawEvent.extrinsic.method === 'sudoUncheckedWeight' && 0) // *call*, _weight
-
-  // ensure `call` argument was found
-  if (argIndex === false) {
-    // this could possibly happen in sometime in future if new sudo options are introduced in Substrate
-    throw new Error('Not implemented situation with sudo')
-  }
-
-  // typecast call arguments
-  const callArgs = (rawEvent.extrinsic.args[argIndex].value as unknown) as ISudoCallArgs<DataParams>
-
-  return callArgs
-}
-
-// FIXME:
-type MappingsMemoryCache = {
-  lastCreatedProposalThreadId?: ThreadId
-}
-
-export const MemoryCache: MappingsMemoryCache = {}
-
 export function deserializeMetadata<T>(
   metadataType: AnyMetadataClass<T>,
   metadataBytes: Bytes

+ 7 - 9
query-node/mappings/src/proposals.ts

@@ -66,7 +66,6 @@ import {
   genericEventFields,
   getWorkingGroupModuleName,
   INT32MAX,
-  MemoryCache,
   perpareString,
   toNumber,
 } from './common'
@@ -352,16 +351,15 @@ async function handleRuntimeUpgradeProposalExecution(event: SubstrateEvent, stor
 }
 
 export async function proposalsCodex_ProposalCreated({ store, event }: EventContext & StoreContext): Promise<void> {
-  const [proposalId, generalProposalParameters, runtimeProposalDetails] = new ProposalsCodex.ProposalCreatedEvent(
-    event
-  ).params
+  const [
+    proposalId,
+    generalProposalParameters,
+    runtimeProposalDetails,
+    proposalThreadId,
+  ] = new ProposalsCodex.ProposalCreatedEvent(event).params
   const eventTime = new Date(event.blockTimestamp)
   const proposalDetails = await parseProposalDetails(event, store, runtimeProposalDetails)
 
-  if (!MemoryCache.lastCreatedProposalThreadId) {
-    throw new Error('Unexpected state: MemoryCache.lastCreatedProposalThreadId is empty')
-  }
-
   const proposal = new Proposal({
     id: proposalId.toString(),
     createdAt: eventTime,
@@ -384,7 +382,7 @@ export async function proposalsCodex_ProposalCreated({ store, event }: EventCont
 
   // Thread is always created along with the proposal
   const proposalThread = new ProposalDiscussionThread({
-    id: MemoryCache.lastCreatedProposalThreadId.toString(),
+    id: proposalThreadId.toString(),
     createdAt: eventTime,
     updatedAt: eventTime,
     mode: new ProposalDiscussionThreadModeOpen(),

+ 3 - 34
query-node/mappings/src/proposalsDiscussion.ts

@@ -17,7 +17,7 @@ import {
   ProposalDiscussionPostDeletedEvent,
   ProposalDiscussionPostStatusRemoved,
 } from 'query-node/dist/model'
-import { bytesToString, deserializeMetadata, genericEventFields, MemoryCache } from './common'
+import { bytesToString, deserializeMetadata, genericEventFields } from './common'
 import { ProposalsDiscussion } from '../generated/types'
 import { ProposalsDiscussionPostMetadata } from '@joystream/metadata-protobuf'
 import { In } from 'typeorm'
@@ -40,39 +40,8 @@ async function getThread(store: DatabaseManager, id: string) {
   return thread
 }
 
-export async function proposalsDiscussion_ThreadCreated({ event }: EventContext & StoreContext): Promise<void> {
-  const [threadId] = new ProposalsDiscussion.ThreadCreatedEvent(event).params
-  MemoryCache.lastCreatedProposalThreadId = threadId
-}
-
 export async function proposalsDiscussion_PostCreated({ event, store }: EventContext & StoreContext): Promise<void> {
-  // FIXME: extremely ugly and insecure workaround for `batch` and `sudo` calls support.
-  // Ideally this data would be part of the event data
-  let editable: boolean
-
-  if (!event.extrinsic) {
-    throw new Error('Missing extrinsic for proposalsDiscussion.PostCreated event!')
-  } else if (event.extrinsic.section === 'utility' && event.extrinsic.method === 'batch') {
-    // We cannot use new Utility.BatchCall(event).args, because createTypeUnsafe fails on Call
-    // First (and only) argument of utility.batch is "calls"
-    const calls = event.extrinsic.args[0].value as any[]
-    // proposalsDiscussion.addPost call index is currently 0x1f00
-    const call = calls.find((c) => c.callIndex === '0x1f00')
-    if (!call) {
-      throw new Error('Could not find proposalsDiscussion.addPostCall in a batch!')
-    }
-    editable = call.args.editable
-  } else if (
-    event.extrinsic.section === 'sudo' &&
-    (event.extrinsic.method === 'sudo' || event.extrinsic.method === 'sudoAs')
-  ) {
-    // Extract call arg
-    editable = (event.extrinsic.args[0].value as any).args.editable
-  } else {
-    editable = new ProposalsDiscussion.AddPostCall(event).args.editable.valueOf()
-  }
-
-  const [postId, memberId, threadId, metadataBytes] = new ProposalsDiscussion.PostCreatedEvent(event).params
+  const [postId, memberId, threadId, metadataBytes, editable] = new ProposalsDiscussion.PostCreatedEvent(event).params
   const eventTime = new Date(event.blockTimestamp)
 
   const metadata = deserializeMetadata(ProposalsDiscussionPostMetadata, metadataBytes)
@@ -89,7 +58,7 @@ export async function proposalsDiscussion_PostCreated({ event, store }: EventCon
     createdAt: eventTime,
     updatedAt: eventTime,
     author: new Membership({ id: memberId.toString() }),
-    status: editable ? new ProposalDiscussionPostStatusActive() : new ProposalDiscussionPostStatusLocked(),
+    status: editable.isTrue ? new ProposalDiscussionPostStatusActive() : new ProposalDiscussionPostStatusLocked(),
     isVisible: true,
     text,
     repliesTo,

+ 14 - 2
query-node/mappings/src/storage/index.ts

@@ -1,7 +1,7 @@
 /*
 eslint-disable @typescript-eslint/naming-convention
 */
-import { EventContext, StoreContext } from '@joystream/hydra-common'
+import { DatabaseManager, EventContext, StoreContext } from '@joystream/hydra-common'
 import { Storage } from '../../generated/types/storage'
 import {
   DistributionBucket,
@@ -410,6 +410,15 @@ export async function storage_DistributionBucketDeleted({ event, store }: EventC
       return store.save<StorageBag>(bag)
     })
   )
+
+  // Remove invited bucket operators
+  const invitedOperators = await store.getMany(DistributionBucketOperator, {
+    where: {
+      status: DistributionBucketOperatorStatus.INVITED,
+      distributionBucket,
+    },
+  })
+  await Promise.all(invitedOperators.map((operator) => removeDistributionBucketOperator(store, operator)))
   await store.remove<DistributionBucket>(distributionBucket)
 }
 
@@ -508,8 +517,11 @@ export async function storage_DistributionBucketOperatorRemoved({
   const [bucketId, workerId] = new Storage.DistributionBucketOperatorRemovedEvent(event).params
 
   // TODO: Cascade remove on db level (would require changes in Hydra / comitting autogenerated files)
-
   const operator = await getDistributionBucketOperatorWithMetadata(store, distributionOperatorId(bucketId, workerId))
+  await removeDistributionBucketOperator(store, operator)
+}
+
+async function removeDistributionBucketOperator(store: DatabaseManager, operator: DistributionBucketOperator) {
   await store.remove<DistributionBucketOperator>(operator)
   if (operator.metadata) {
     await store.remove<DistributionBucketOperatorMetadata>(operator.metadata)

+ 7 - 1
runtime-modules/proposals/codex/src/benchmarking.rs

@@ -160,7 +160,13 @@ fn create_proposal_verify<T: Trait>(
     );
 
     assert_last_event::<T>(
-        RawEvent::ProposalCreated(proposal_id, proposal_parameters, proposal_details).into(),
+        RawEvent::ProposalCreated(
+            proposal_id,
+            proposal_parameters,
+            proposal_details,
+            thread_id,
+        )
+        .into(),
     );
 
     assert!(

+ 4 - 2
runtime-modules/proposals/codex/src/lib.rs

@@ -260,13 +260,15 @@ decl_event! {
         GeneralProposalParameters = GeneralProposalParameters<T>,
         ProposalDetailsOf = ProposalDetailsOf<T>,
         <T as proposals_engine::Trait>::ProposalId,
+        <T as proposals_discussion::Trait>::ThreadId
     {
         /// A proposal was created
         /// Params:
         /// - Id of a newly created proposal after it was saved in storage.
         /// - General proposal parameter. Parameters shared by all proposals
         /// - Proposal Details. Parameter of proposal with a variant for each kind of proposal
-        ProposalCreated(ProposalId, GeneralProposalParameters, ProposalDetailsOf),
+        /// - Id of a newly created proposal thread
+        ProposalCreated(ProposalId, GeneralProposalParameters, ProposalDetailsOf, ThreadId),
     }
 }
 
@@ -515,7 +517,7 @@ decl_module! {
 
             <ThreadIdByProposalId<T>>::insert(proposal_id, discussion_thread_id);
 
-            Self::deposit_event(RawEvent::ProposalCreated(proposal_id, general_proposal_parameters, proposal_details));
+            Self::deposit_event(RawEvent::ProposalCreated(proposal_id, general_proposal_parameters, proposal_details, discussion_thread_id));
         }
     }
 }

+ 1 - 0
runtime-modules/proposals/codex/src/tests/mod.rs

@@ -126,6 +126,7 @@ where
                 proposal_id,
                 self.general_proposal_parameters.clone(),
                 self.proposal_details.clone(),
+                thread_id,
             )
             .into(),
         );

Some files were not shown because too many files changed in this diff