Browse Source

pioneer: update media app to work with new storage working group

Mokhtar Naamani 4 years ago
parent
commit
8eadf90f40

+ 5 - 5
pioneer/packages/joy-media/src/DiscoveryProvider.tsx

@@ -2,7 +2,7 @@ import React, { useState, useEffect, useContext, createContext } from 'react';
 import { Message } from 'semantic-ui-react';
 import axios, { CancelToken } from 'axios';
 
-import { AccountId } from '@polkadot/types/interfaces';
+import { StorageProviderId } from '@joystream/types/bureaucracy';
 import { Vec } from '@polkadot/types';
 import { Url } from '@joystream/types/discovery';
 import ApiContext from '@polkadot/react-api/ApiContext';
@@ -15,8 +15,8 @@ export type BootstrapNodes = {
 };
 
 export type DiscoveryProvider = {
-  resolveAssetEndpoint: (provider: AccountId, contentId?: string, cancelToken?: CancelToken) => Promise<string>;
-  reportUnreachable: (provider: AccountId) => void;
+  resolveAssetEndpoint: (provider: StorageProviderId, contentId?: string, cancelToken?: CancelToken) => Promise<string>;
+  reportUnreachable: (provider: StorageProviderId) => void;
 };
 
 export type DiscoveryProviderProps = {
@@ -41,7 +41,7 @@ type ProviderStats = {
 function newDiscoveryProvider ({ bootstrapNodes }: BootstrapNodes): DiscoveryProvider {
   const stats: Map<string, ProviderStats> = new Map();
 
-  const resolveAssetEndpoint = async (storageProvider: AccountId, contentId?: string, cancelToken?: CancelToken) => {
+  const resolveAssetEndpoint = async (storageProvider: StorageProviderId, contentId?: string, cancelToken?: CancelToken) => {
     const providerKey = storageProvider.toString();
 
     let stat = stats.get(providerKey);
@@ -98,7 +98,7 @@ function newDiscoveryProvider ({ bootstrapNodes }: BootstrapNodes): DiscoveryPro
     throw new Error('Resolving failed.');
   };
 
-  const reportUnreachable = (provider: AccountId) => {
+  const reportUnreachable = (provider: StorageProviderId) => {
     const key = provider.toString();
     const stat = stats.get(key);
     if (stat) {

+ 3 - 3
pioneer/packages/joy-media/src/Upload.tsx

@@ -11,7 +11,6 @@ import { SubmittableResult } from '@polkadot/api';
 import { Option } from '@polkadot/types/codec';
 import { withMulti, withApi } from '@polkadot/react-api';
 import { formatNumber } from '@polkadot/util';
-import { AccountId } from '@polkadot/types/interfaces';
 
 import translate from './translate';
 import { fileNameWoExt } from './utils';
@@ -24,6 +23,7 @@ import { ChannelId } from '@joystream/types/content-working-group';
 import { EditVideoView } from './upload/EditVideo.view';
 import { JoyInfo } from '@polkadot/joy-utils/JoyStatus';
 import { IterableFile } from './IterableFile';
+import { StorageProviderId } from '@joystream/types/bureaucracy';
 
 const MAX_FILE_SIZE_MB = 500;
 const MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * 1024 * 1024;
@@ -107,8 +107,8 @@ class Component extends React.PureComponent<Props, State> {
   private resetForm = () => {
     const { cancelSource } = this.state;
     this.setState({
+      ...defaultState(),
       cancelSource,
-      ...defaultState()
     });
   }
 
@@ -285,7 +285,7 @@ class Component extends React.PureComponent<Props, State> {
     }
   }
 
-  private uploadFileTo = async (storageProvider: AccountId) => {
+  private uploadFileTo = async (storageProvider: StorageProviderId) => {
     const { file, newContentId, cancelSource } = this.state;
     if (!file || !file.size) {
       this.setState({

+ 25 - 4
pioneer/packages/joy-media/src/common/MediaPlayerWithResolver.tsx

@@ -6,7 +6,7 @@ import { ApiProps } from '@polkadot/react-api/types';
 import { I18nProps } from '@polkadot/react-components/types';
 import { withMulti } from '@polkadot/react-api/with';
 import { Option } from '@polkadot/types/codec';
-import { AccountId } from '@polkadot/types/interfaces';
+import { StorageProviderId } from '@joystream/types/bureaucracy';
 
 import translate from '../translate';
 import { DiscoveryProviderProps, withDiscoveryProvider } from '../DiscoveryProvider';
@@ -14,6 +14,8 @@ import { DataObjectStorageRelationshipId, DataObjectStorageRelationship } from '
 import { Message } from 'semantic-ui-react';
 import { MediaPlayerView, RequiredMediaPlayerProps } from './MediaPlayerView';
 import { JoyInfo } from '@polkadot/joy-utils/JoyStatus';
+import { MultipleLinkedMapEntry} from '@polkadot/joy-utils/index';
+import { Worker } from '@joystream/types/bureaucracy';
 
 type Props = ApiProps & I18nProps & DiscoveryProviderProps & RequiredMediaPlayerProps;
 
@@ -29,6 +31,23 @@ function InnerComponent (props: Props) {
   const [contentType, setContentType] = useState<string>();
   const [cancelSource, setCancelSource] = useState<CancelTokenSource>(newCancelSource());
 
+  const getActiveStorageProviderIds = async () : Promise<StorageProviderId[]> => {
+    const nextId = await api.query.storageBureaucracy.nextWorkerId() as StorageProviderId;
+    // This is chain specfic, but if next id is still 0, it means no workers have been added,
+    // so the workerById is empty
+    if (nextId.eq(0)) {
+      return [];
+    }
+
+    const workers = new MultipleLinkedMapEntry<StorageProviderId, Worker>(
+      StorageProviderId,
+      Worker,
+      await api.query.storageBureaucracy.workerById()
+    );
+
+    return workers.linked_keys
+  }
+
   const resolveAsset = async () => {
     setError(undefined);
     setCancelSource(newCancelSource());
@@ -37,6 +56,7 @@ function InnerComponent (props: Props) {
 
     const allRelationships: Option<DataObjectStorageRelationship>[] = await Promise.all(rids.map((id) => api.query.dataObjectStorageRegistry.relationships(id))) as any;
 
+    // Providers that have signalled onchain that they have the asset
     let readyProviders = allRelationships.filter(r => r.isSome).map(r => r.unwrap())
       .filter(r => r.ready)
       .map(r => r.storage_provider);
@@ -49,10 +69,11 @@ function InnerComponent (props: Props) {
       return;
     }
 
-    // filter out providers no longer in actors list
-    const stakedActors = await api.query.actors.actorAccountIds() as unknown as AccountId[];
+    // filter out providers no longer active - relationships of providers that have left
+    // are not pruned onchain.
+    const activeProviders = await getActiveStorageProviderIds();
+    readyProviders = _.intersectionBy(activeProviders, readyProviders, provider => provider.toString());
 
-    readyProviders = _.intersectionBy(stakedActors, readyProviders, provider => provider.toString());
     console.log(`Found ${readyProviders.length} providers ready to serve content: ${readyProviders}`);
 
     // shuffle to spread the load