Skip to content

Commit 5fbe3b7

Browse files
authored
Merge pull request #3772 from Joystream/rhodes-update-1
Rhodes update 1
2 parents 451ff7c + bdec855 commit 5fbe3b7

17 files changed

Lines changed: 236 additions & 158 deletions

File tree

.github/workflows/runtime-upgrade.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ jobs:
7070
name: ${{ steps.compute_shasum.outputs.shasum }}-joystream-node-docker-image.tar.gz
7171
path: joystream-node-docker-image.tar.gz
7272

73-
runtime_upgrade_from_olympia:
73+
runtime_upgrade:
7474
# if: ${{ false }}
75-
name: Runtime Upgrade From Olypia
75+
name: Runtime Upgrade From Rhodes Spec 6
7676
needs: build_images
7777
runs-on: ubuntu-latest
7878
steps:
@@ -101,7 +101,7 @@ jobs:
101101
export HOME=${PWD}
102102
mkdir -p ${HOME}/.local/share/joystream-cli
103103
yarn joystream-cli api:setUri ws://localhost:9944
104-
# Olympia release production runtime profile
105-
export RUNTIME_TAG=6740a4ae2bf40fe7c670fb49943cbbe290277601
104+
# Rhodes release (spec 6) production runtime profile
105+
export RUNTIME_TAG=8c2e70abcb34a6892991355b61e804b7c1492290
106106
export TARGET_RUNTIME_TAG=latest
107107
tests/network-tests/run-migration-tests.sh

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ authors = ['Joystream contributors']
33
build = 'build.rs'
44
edition = '2018'
55
name = 'joystream-node'
6-
version = '6.6.0'
6+
version = '6.7.0'
77
default-run = "joystream-node"
88

99
[[bin]]

runtime-modules/content/src/lib.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,7 +1275,7 @@ decl_module! {
12751275
) -> DispatchResult {
12761276
let channel = Self::ensure_channel_exists(&item.channel_id)?;
12771277

1278-
let reward_account = Self::ensure_reward_account(&channel)?;
1278+
let reward_account = Self::ensure_channel_has_beneficiary_account(&channel)?;
12791279

12801280
ensure_actor_authorized_to_claim_payment::<T>(origin, &actor, &channel.owner)?;
12811281

@@ -1662,7 +1662,7 @@ decl_module! {
16621662
let royalty_payment = Self::build_royalty_payment(&video, nft.creator_royalty);
16631663
let updated_nft = Self::complete_auction(
16641664
nft,
1665-
video.in_channel,
1665+
&video,
16661666
royalty_payment,
16671667
participant_id,
16681668
buy_now_price,
@@ -1770,7 +1770,7 @@ decl_module! {
17701770
let royalty_payment = Self::build_royalty_payment(&video, nft.creator_royalty);
17711771
let updated_nft = Self::complete_auction(
17721772
nft,
1773-
video.in_channel,
1773+
&video,
17741774
royalty_payment,
17751775
participant_id,
17761776
buy_now_price,
@@ -1882,7 +1882,7 @@ decl_module! {
18821882
let royalty_payment = Self::build_royalty_payment(&video, nft.creator_royalty);
18831883
let updated_nft = Self::complete_auction(
18841884
nft,
1885-
video.in_channel,
1885+
&video,
18861886
royalty_payment,
18871887
top_bidder_id,
18881888
top_bid.amount
@@ -1935,7 +1935,7 @@ decl_module! {
19351935
let royalty_payment = Self::build_royalty_payment(&video, nft.creator_royalty);
19361936
let updated_nft = Self::complete_auction(
19371937
nft,
1938-
video.in_channel,
1938+
&video,
19391939
royalty_payment,
19401940
winner_id,
19411941
bid.amount,
@@ -2046,7 +2046,7 @@ decl_module! {
20462046
Self::ensure_new_pending_offer_available_to_proceed(&nft, &receiver_account_id)?;
20472047

20482048
// account_id where the nft offer price is deposited
2049-
let nft_owner_account = Self::ensure_owner_account_id(video.in_channel, &nft).ok();
2049+
let nft_owner_account = Self::ensure_nft_owner_has_beneficiary_account(&video, &nft).ok();
20502050
//
20512051
// == MUTATION SAFE ==
20522052
//
@@ -2122,7 +2122,7 @@ decl_module! {
21222122
Self::ensure_can_buy_now(&nft, &participant_account_id, price_commit)?;
21232123

21242124
// seller account
2125-
let old_nft_owner_account_id = Self::ensure_owner_account_id(video.in_channel, &nft).ok();
2125+
let old_nft_owner_account_id = Self::ensure_nft_owner_has_beneficiary_account(&video, &nft).ok();
21262126

21272127
//
21282128
// == MUTATION SAFE ==
@@ -2428,7 +2428,7 @@ impl<T: Trait> Module<T> {
24282428
Ok(())
24292429
}
24302430

2431-
pub(crate) fn ensure_reward_account(
2431+
pub(crate) fn ensure_channel_has_beneficiary_account(
24322432
channel: &Channel<T>,
24332433
) -> Result<T::AccountId, DispatchError> {
24342434
if let Some(reward_account) = &channel.reward_account {

runtime-modules/content/src/nft/mod.rs

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -363,12 +363,12 @@ impl<T: Trait> Module<T> {
363363

364364
pub(crate) fn complete_auction(
365365
nft: Nft<T>,
366-
in_channel: T::ChannelId,
366+
video: &Video<T>,
367367
royalty_payment: Option<(Royalty, T::AccountId)>,
368368
winner_id: T::MemberId,
369369
amount: BalanceOf<T>,
370370
) -> Nft<T> {
371-
let account_deposit_into = Self::ensure_owner_account_id(in_channel, &nft).ok();
371+
let account_deposit_into = Self::ensure_nft_owner_has_beneficiary_account(video, &nft).ok();
372372
let account_withdraw_from = ContentTreasury::<T>::module_account_id();
373373

374374
Self::complete_payment(
@@ -382,15 +382,25 @@ impl<T: Trait> Module<T> {
382382
.with_member_owner(winner_id)
383383
}
384384

385-
pub(crate) fn ensure_owner_account_id(
386-
channel_id: T::ChannelId,
385+
/// NFT owned by:
386+
/// - Member: member controller account is used
387+
/// - Channel: then if reward account is:
388+
/// - `Some(acc)` -> use `acc` as reward account
389+
/// - `None` -> then if channel owner is:
390+
/// - `Member` -> use member controller account
391+
/// - `CuratorGroup` -> Error
392+
/// In order to statically guarantee that `video.in_channel` exists, by leveraging the
393+
/// Runtime invariant: `video` exists => `video.in_channel` exists
394+
pub(crate) fn ensure_nft_owner_has_beneficiary_account(
395+
video: &Video<T>,
387396
nft: &Nft<T>,
388397
) -> Result<T::AccountId, DispatchError> {
389398
match nft.owner {
390399
NftOwner::Member(member_id) => T::MemberAuthenticator::controller_account_id(member_id),
391-
NftOwner::ChannelOwner => Self::channel_by_id(channel_id)
392-
.reward_account
393-
.ok_or_else(|| Error::<T>::RewardAccountIsNotSet.into()),
400+
NftOwner::ChannelOwner => {
401+
let channel = Self::channel_by_id(&video.in_channel);
402+
Self::ensure_channel_has_beneficiary_account(&channel)
403+
}
394404
}
395405
}
396406

@@ -462,20 +472,9 @@ impl<T: Trait> Module<T> {
462472
// payment is none if there is no royalty
463473
if let Some(royalty) = creator_royalty {
464474
let channel = Self::channel_by_id(&video.in_channel);
465-
// use reward account if specified
466-
if let Some(creator_reward_account) = channel.reward_account {
467-
Some((royalty, creator_reward_account))
468-
} else {
469-
// otherwise resort to controller account for member owned channels
470-
if let ChannelOwner::Member(member_id) = channel.owner {
471-
T::MemberAuthenticator::controller_account_id(member_id)
472-
.ok()
473-
.map(|reward_account| (royalty, reward_account))
474-
} else {
475-
// no royalty paid for curator owned channel with unspecified reward account
476-
None
477-
}
478-
}
475+
Self::ensure_channel_has_beneficiary_account(&channel)
476+
.ok()
477+
.map(|reward_acc| (royalty, reward_acc))
479478
} else {
480479
None
481480
}

runtime-modules/content/src/tests/fixtures.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1374,7 +1374,8 @@ impl ClaimChannelRewardFixture {
13741374
pub fn call_and_assert(&self, expected_result: DispatchResult) {
13751375
let origin = Origin::signed(self.sender.clone());
13761376
let channel = Content::channel_by_id(self.item.channel_id);
1377-
let reward_account = Content::ensure_reward_account(&channel).unwrap_or_default();
1377+
let reward_account =
1378+
Content::ensure_channel_has_beneficiary_account(&channel).unwrap_or_default();
13781379
let balance_pre = Balances::<Test>::usable_balance(&reward_account);
13791380
let payout_earned_pre =
13801381
Content::channel_by_id(self.item.channel_id).cumulative_payout_earned;

runtime-modules/content/src/tests/nft/accept_incoming_offer.rs

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#![cfg(test)]
2+
use crate::tests::curators;
23
use crate::tests::fixtures::{
34
create_default_member_owned_channel_with_video, create_initial_storage_buckets_helper,
4-
increase_account_balance_helper, UpdateChannelFixture,
5+
increase_account_balance_helper, CreateChannelFixture, CreateVideoFixture,
56
};
67
use crate::tests::mock::*;
78
use crate::*;
@@ -180,45 +181,50 @@ fn accept_incoming_offer_no_incoming_offers() {
180181
}
181182

182183
#[test]
183-
fn accept_incoming_offer_reward_account_is_not_set_succeeds_with_member_owner_channel() {
184+
fn accept_incoming_offer_ok_with_reward_account_not_set_succeeds_with_member_owner_channel() {
185+
let video_id = 1u64;
184186
with_default_mock_builder(|| {
185187
// Run to block one to see emitted events
186188
run_to_block(1);
187-
188-
let video_id = NextVideoId::<Test>::get();
189-
create_initial_storage_buckets_helper();
190-
increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
191-
create_default_member_owned_channel_with_video();
192-
193-
UpdateChannelFixture::default()
189+
// channel with no reward account
190+
CreateChannelFixture::default()
191+
.with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
192+
.with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
193+
.call();
194+
CreateVideoFixture::default()
194195
.with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
195196
.with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
196-
.with_reward_account(Some(None))
197-
.call_and_assert(Ok(()));
197+
.call();
198198

199-
// Issue nft
200199
assert_ok!(Content::issue_nft(
201200
Origin::signed(DEFAULT_MEMBER_ACCOUNT_ID),
202201
ContentActor::Member(DEFAULT_MEMBER_ID),
203202
video_id,
204203
NftIssuanceParameters::<Test>::default(),
205204
));
206205

206+
increase_account_balance_helper(SECOND_MEMBER_ACCOUNT_ID, DEFAULT_NFT_PRICE);
207+
207208
// Offer nft
208209
assert_ok!(Content::offer_nft(
209210
Origin::signed(DEFAULT_MEMBER_ACCOUNT_ID),
210211
video_id,
211212
ContentActor::Member(DEFAULT_MEMBER_ID),
212213
SECOND_MEMBER_ID,
213-
None,
214+
Some(100u64), // price
214215
));
215216

216217
// Make an attempt to accept incoming nft offer if sender is owner and reward account is not set
217-
let accept_incoming_offer_result =
218-
Content::accept_incoming_offer(Origin::signed(SECOND_MEMBER_ACCOUNT_ID), video_id);
218+
assert_ok!(Content::accept_incoming_offer(
219+
Origin::signed(SECOND_MEMBER_ACCOUNT_ID),
220+
video_id
221+
));
219222

220-
// Failure checked
221-
assert_ok!(accept_incoming_offer_result,);
223+
// check owner balance increased by net profit
224+
assert_eq!(
225+
Balances::<Test>::usable_balance(DEFAULT_MEMBER_ACCOUNT_ID),
226+
100u64 - (Content::platform_fee_percentage() * 100u64)
227+
);
222228
})
223229
}
224230

@@ -228,31 +234,31 @@ fn accept_incoming_offer_reward_account_burns_token_with_curator_owner_channel()
228234
// Run to block one to see emitted events
229235
run_to_block(1);
230236

231-
let video_id = NextVideoId::<Test>::get();
232-
create_initial_storage_buckets_helper();
233-
increase_account_balance_helper(DEFAULT_MEMBER_ACCOUNT_ID, INITIAL_BALANCE);
234-
increase_account_balance_helper(SECOND_MEMBER_ACCOUNT_ID, DEFAULT_NFT_PRICE);
235-
create_default_member_owned_channel_with_video();
237+
let curator_group_id = curators::add_curator_to_new_group(DEFAULT_CURATOR_ID);
238+
let video_id = Content::next_video_id();
239+
let curator_actor = ContentActor::Curator(curator_group_id, DEFAULT_CURATOR_ID);
240+
CreateChannelFixture::default()
241+
.with_sender(DEFAULT_CURATOR_ACCOUNT_ID)
242+
.with_actor(curator_actor)
243+
.call();
244+
CreateVideoFixture::default()
245+
.with_sender(DEFAULT_CURATOR_ACCOUNT_ID)
246+
.with_actor(ContentActor::Curator(curator_group_id, DEFAULT_CURATOR_ID))
247+
.call();
236248

237-
UpdateChannelFixture::default()
238-
.with_sender(DEFAULT_MEMBER_ACCOUNT_ID)
239-
.with_actor(ContentActor::Member(DEFAULT_MEMBER_ID))
240-
.with_reward_account(Some(None))
241-
.call_and_assert(Ok(()));
242-
243-
// Issue nft
244249
assert_ok!(Content::issue_nft(
245-
Origin::signed(DEFAULT_MEMBER_ACCOUNT_ID),
246-
ContentActor::Member(DEFAULT_MEMBER_ID),
250+
Origin::signed(DEFAULT_CURATOR_ACCOUNT_ID),
251+
curator_actor,
247252
video_id,
248253
NftIssuanceParameters::<Test>::default(),
249254
));
250255

256+
increase_account_balance_helper(SECOND_MEMBER_ACCOUNT_ID, DEFAULT_NFT_PRICE);
251257
// Offer nft
252258
assert_ok!(Content::offer_nft(
253-
Origin::signed(DEFAULT_MEMBER_ACCOUNT_ID),
259+
Origin::signed(DEFAULT_CURATOR_ACCOUNT_ID),
254260
video_id,
255-
ContentActor::Member(DEFAULT_MEMBER_ID),
261+
curator_actor,
256262
SECOND_MEMBER_ID,
257263
Some(DEFAULT_NFT_PRICE),
258264
));

0 commit comments

Comments
 (0)