Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Market Pallet: integration tests #108

Closed
th7nder opened this issue Jul 2, 2024 · 18 comments
Closed

Market Pallet: integration tests #108

th7nder opened this issue Jul 2, 2024 · 18 comments
Assignees
Labels
documentation Improvements or additions to documentation pallet-market Relates to the Market Pallet
Milestone

Comments

@th7nder
Copy link
Contributor

th7nder commented Jul 2, 2024

The testing should be done by running a local zombienet cluster, on kuberenetes or native (just testnet, just kube-testnet #124 ).

  • 1 minute = 5 blocks
  • 5 minutes = 25 blocks
  • 10 minutes = 50 blocks
  • 1 hour = 300 blocks
  • 24 hours = 1 day = 7200 blocks

Min Deal Duration = 180 days = 180 * 7200 = 1 296 000 blocks

The flows we want to test:

Current test-helper PR:

1. Publishing and slashing the deal

  1. Client calls market.add_balance(1 100 200 * 25) (5 minutes in blocks)

  2. Provider calls market.add_balance(25 100 200) (storage_provider_collateral)

  3. Client and Storage Provider discuss the deal off-chain. When they're finished, Storage Provider calls market.publish_storage_deals

market.publish_storage_deals({
    client: ALICE, (5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY)
    provider: CHARLIE, (5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y)
    label: 0xdeadbeef,
    start_block: current_block + 25 (5 minutes in blocks),
    end_block: current_block + 25 (5 minutes in blocks) + 25 (5 minutes in blocks),
    storage_price_per_block: 1 100 200,
    provider_collateral: 10% * 1 100 200 * 25 = 25 100 200,
    piece_cid: -> TODO: need to have a way to sign an IPLD cid?
    client_signature: -> TODO: need to have a way to sign an message, need to have a CLI
})
  1. We wait 5 minutes for the deal to be expired and cleared by cron_tick.
  2. As deal has not been activated,
    • client gets all of the money unlocked
    • storage provider gets all of the collateral slashed
  3. Client calls market.withdraw_balance(25 100 200), it succeeds.
  4. Provider calls market.withdraw_balance(25 100 200), it fails.

2. Publishing and successfully finishing a deal

  1. Client calls market.add_balance(1 100 200 * 25) (5 minutes in blocks)
  2. Provider calls market.add_balance(25 100 200) (storage_provider_collateral)
  3. Client and Storage Provider discuss the deal off-chain. When they're finished, Storage Provider calls market.publish_storage_deals
market.publish_storage_deals({
    client: ALICE, (5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY)
    provider: CHARLIE, (5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y)
    label: 0xdeadbeef,
    start_block: current_block + 25 (5 minutes in blocks),
    end_block: current_block + 25 (5 minutes in blocks) + 25 (5 minutes in blocks),
    storage_price_per_block: 1 100 200,
    provider_collateral: 10% * 1 100 200 * 25 = 25 100 200,
    piece_cid: -> TODO: need to have a way to sign an IPLD cid?
    client_signature: -> TODO: need to have a way to sign an message, need to have a CLI
})
  1. Storage Provider calls pre_commit:
storage_provider.pre_commit({
   sectorNumber: 1,
   sealedCid: 0x0, // it shouldn't be here!
   dealsId: [1] -> sourced from publish storage deal,
   expiration: 200,
   unsealedCid: ????? how do I get that 
})
  1. Storage Provider calls prove_commit:
storage_provider.prove_commit({
    sectorNumber: 1, 
    proof: 0x01 // will work anything with .len > 0
})
  1. We wait 5 minutes for the deal to be done and NOT CLEARED by cron_tick.
  2. As deal has finished:
    • all of the client's money is still locked.
    • storage provider can unlock its collateral.
  3. Provider calls market.settle_deal_payments, so client's money gets transfered to the provider.
market.settle_deal_payments({
  dealIds: [1]
}).
  1. Client calls market.withdraw_balance(25 100 200), it fails (it got transferred to the provider)
  2. Provider calls market.withdraw_balance(25 100 200 + 25 100 200), from the successful deal) it succeeds.

Verify deals for activation (blocked):

  • requires calling verify_deals_for_activation, so calling pre_commit

on_sector_terminate (blocked):

@th7nder th7nder self-assigned this Jul 2, 2024
@th7nder th7nder added the documentation Improvements or additions to documentation label Jul 2, 2024
@th7nder
Copy link
Contributor Author

th7nder commented Jul 15, 2024

Issue 1: #137

  • pre_commit_sector requires sealed_cid (it's supposed to be calculated during the sealing sector and sent through prove_commit sector)
  • Current workaround, set it to 0x0

@th7nder
Copy link
Contributor Author

th7nder commented Jul 15, 2024

Issue 2:

@th7nder
Copy link
Contributor Author

th7nder commented Jul 16, 2024

Issue 3: #138

  • Logs show wasm:stripped in some places:
2024-07-16 10:43:36.021 ERROR tokio-runtime-worker runtime::market: [Parachain] insane deal: idx 0, error: <wasm:stripped>   

It happens, because:

    #[derive(RuntimeDebug)]
    pub enum ProposalError {
    

So the debug is not implemented in WASM.

 log::error!(target: LOG_TARGET, "insane deal: idx {}, error: {:?}", idx, e);

Possible solutions:

On the other hand...
This error design of publish_storage_deals sucks (#121), from the user perspective.

@th7nder
Copy link
Contributor Author

th7nder commented Jul 16, 2024

Issue 4: #139

  • MinDealDuration is set to 180 DAYS, should be way less if we want to have testing not waiting for 180 days for a deal to end :D

https://github.com/eigerco/polka-storage/blob/develop/runtime/src/configs/mod.rs#L349

@cernicc cernicc self-assigned this Jul 16, 2024
@th7nder
Copy link
Contributor Author

th7nder commented Jul 16, 2024

Success number one!
Part of test number 2.

Called:

market.add_balance(ALICE, 25100200300);
market.add_balance(CHARLIE, 25100200300);

market.publish_storage_deals({
            piece_cid: 0x0155a0e4022022e14069bfa61a3c7440209dbc8922d591719a1b5cf96cf1262b0fc6aec0b60f,
            piece_size: 1,
            client,
            provider,
            label: bounded_vec![0xde, 0xad],
            start_block: 100,
            end_block: 741265708,
            storage_price_per_block: 1,
            provider_collateral: 1,
            state: DealState::<BlockNumber>::Published,
            client_signature: 0xc84e3a723e61b8d9613e1312beabebf7f498946d5cbe7aee6c25912eb2e78a69ea3c88b6f9486f098cd9c640c76dde0fa6c62af872851b383c562af2f437ea87
})

aaand it succeeded.
image image

@jmg-duarte
Copy link
Contributor

MinDealDuration is set to 180 DAYS, should be way less if we want to have testing not waiting for 180 days for a deal to end :D

Feature gate this or similar

@th7nder
Copy link
Contributor Author

th7nder commented Jul 17, 2024

@jmg-duarte wdym by feature gate?

@cernicc
Copy link
Member

cernicc commented Jul 17, 2024

I think he means that we could have a feature "testnet" or similar. And when we compile the parachain with that feature we would use a different pallet config. Is it possible to do it that way? .. Could we create a Testnet runtime that specifies it's own config? Like the Test runtime that we are using for tests?

@cernicc
Copy link
Member

cernicc commented Jul 17, 2024

Could we have something like that? Checking of the future flags is wrong, but the idea is there :D

#[cfg(feature = "testnet")]
impl pallet_market::Config for Runtime {
    type RuntimeEvent = RuntimeEvent;
    type Currency = Balances;
    type PalletId = MarketPalletId;
    type OffchainSignature = MultiSignature;
    type OffchainPublic = AccountPublic;
    type MaxDeals = ConstU32<128>;
    type BlocksPerDay = ConstU32<DAYS>;
    type MinDealDuration = ConstU32<{ MINUTES }>;
    type MaxDealDuration = ConstU32<{ MINUTES * 10 }>;
    type MaxDealsPerBlock = ConstU32<128>;
}
if_not testnet
impl pallet_market::Config for Runtime {
    type RuntimeEvent = RuntimeEvent;
    type Currency = Balances;
    type PalletId = MarketPalletId;
    type OffchainSignature = MultiSignature;
    type OffchainPublic = AccountPublic;
    type MaxDeals = ConstU32<128>;
    type BlocksPerDay = ConstU32<DAYS>;
    type MinDealDuration = ConstU32<{ DAYS * 180 }>;
    type MaxDealDuration = ConstU32<{ DAYS * 1278 }>;
    type MaxDealsPerBlock = ConstU32<128>;
}

@cernicc
Copy link
Member

cernicc commented Jul 17, 2024

Or maybe better yet

impl pallet_market::Config for Runtime {
    type RuntimeEvent = RuntimeEvent;
    type Currency = Balances;
    type PalletId = MarketPalletId;
    type OffchainSignature = MultiSignature;
    type OffchainPublic = AccountPublic;
    type MaxDeals = ConstU32<128>;
    type BlocksPerDay = ConstU32<DAYS>;
    #[cfg(feature = "testnet")]
    type MinDealDuration = ConstU32<{ MINUTES }>;
    #[cfg(not(feature = "testnet"))]
    type MinDealDuration = ConstU32<{ DAYS * 180 }>;
    type MaxDealDuration = ConstU32<{ DAYS * 1278 }>;
    type MaxDealsPerBlock = ConstU32<128>;
}

@cernicc
Copy link
Member

cernicc commented Jul 17, 2024

Issue 5: #135

@th7nder
Copy link
Contributor Author

th7nder commented Jul 17, 2024

Issue 6: #136

When calling register_storage_provider, getting ConversionError (god knows why).

There are mismatch issues with BlockNumber and block types... (u64 in register_storage_provider (assign proving period)) and BlockNumber configuration in runtime.

BlockNumber in runtime == u32
Try into fails, as storage provider tries to fit u64 into u32

@th7nder
Copy link
Contributor Author

th7nder commented Jul 17, 2024

Issue 7: #139

Cannot pre_commit sector, as the numbers for T::MaxProveCommitDuration do not match those I set in Market Pallet.

@th7nder
Copy link
Contributor Author

th7nder commented Jul 17, 2024

Issue 8:
I was able to pre_commit not existing deal. #117

@th7nder
Copy link
Contributor Author

th7nder commented Jul 17, 2024

Issue 9: #140
Market Pallet does not emit event when slashing a deal.
Not sure whether we should, but... I needed to go into the logs to verify that.

@th7nder
Copy link
Contributor Author

th7nder commented Jul 17, 2024

Issue 10: #141

Even though the deal has been activated, it cannot be settled after it ended.

pallet_market::pallet: [Parachain] on_finalize: deal 0 has been properly activated before, all good.

image

@th7nder
Copy link
Contributor Author

th7nder commented Jul 17, 2024

Managed to perform 2. successfully! (with some hacks in the code, #133 )
image

Issue 11:
However, the Collateral was not unlocked after settle deal payments? (#142)

image

@th7nder
Copy link
Contributor Author

th7nder commented Jul 30, 2024

Done!

@th7nder th7nder closed this as completed Jul 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation pallet-market Relates to the Market Pallet
Projects
None yet
Development

No branches or pull requests

3 participants