From 4239f279f5e8194afdb3f9fbba5c4f27ac228b3d Mon Sep 17 00:00:00 2001 From: yahortsaryk Date: Thu, 26 Oct 2023 23:31:02 +0200 Subject: [PATCH 01/17] feat: payment pallet prototype --- Cargo.lock | 351 +++++++++++++++++---------------- Cargo.toml | 1 + pallets/ddc-payouts/Cargo.toml | 40 ++++ pallets/ddc-payouts/src/lib.rs | 345 ++++++++++++++++++++++++++++++++ primitives/src/lib.rs | 1 + runtime/cere-dev/Cargo.toml | 2 + runtime/cere-dev/src/lib.rs | 8 +- 7 files changed, 582 insertions(+), 166 deletions(-) create mode 100644 pallets/ddc-payouts/Cargo.toml create mode 100644 pallets/ddc-payouts/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index c24b3b135..1f222c0a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -814,6 +814,7 @@ dependencies = [ "pallet-ddc-clusters", "pallet-ddc-metrics-offchain-worker", "pallet-ddc-nodes", + "pallet-ddc-payouts", "pallet-ddc-staking", "pallet-ddc-validator", "pallet-democracy", @@ -2069,7 +2070,7 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "fork-tree" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "parity-scale-codec", ] @@ -2086,7 +2087,7 @@ dependencies = [ [[package]] name = "frame-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-support", "frame-system", @@ -2109,7 +2110,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "Inflector", "array-bytes 4.2.0", @@ -2160,7 +2161,7 @@ dependencies = [ [[package]] name = "frame-election-provider-solution-type" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -2171,7 +2172,7 @@ dependencies = [ [[package]] name = "frame-election-provider-support" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-election-provider-solution-type", "frame-support", @@ -2187,7 +2188,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-support", "frame-system", @@ -2216,7 +2217,7 @@ dependencies = [ [[package]] name = "frame-support" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "bitflags 1.3.2", "frame-metadata", @@ -2248,7 +2249,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "Inflector", "cfg-expr", @@ -2262,7 +2263,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate", @@ -2274,7 +2275,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "proc-macro2", "quote", @@ -2284,7 +2285,7 @@ dependencies = [ [[package]] name = "frame-system" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-support", "log", @@ -2302,7 +2303,7 @@ dependencies = [ [[package]] name = "frame-system-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-support", @@ -2317,7 +2318,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "parity-scale-codec", "sp-api", @@ -2326,7 +2327,7 @@ dependencies = [ [[package]] name = "frame-try-runtime" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-support", "parity-scale-codec", @@ -4374,7 +4375,7 @@ dependencies = [ [[package]] name = "node-primitives" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-system", "parity-scale-codec", @@ -4583,7 +4584,7 @@ dependencies = [ [[package]] name = "pallet-authority-discovery" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-support", "frame-system", @@ -4599,7 +4600,7 @@ dependencies = [ [[package]] name = "pallet-authorship" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-support", "frame-system", @@ -4614,7 +4615,7 @@ dependencies = [ [[package]] name = "pallet-babe" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-support", @@ -4638,7 +4639,7 @@ dependencies = [ [[package]] name = "pallet-bags-list" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -4658,7 +4659,7 @@ dependencies = [ [[package]] name = "pallet-balances" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-support", @@ -4673,7 +4674,7 @@ dependencies = [ [[package]] name = "pallet-bounties" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-support", @@ -4724,7 +4725,7 @@ dependencies = [ [[package]] name = "pallet-child-bounties" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-support", @@ -4743,7 +4744,7 @@ dependencies = [ [[package]] name = "pallet-collective" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-support", @@ -4760,7 +4761,7 @@ dependencies = [ [[package]] name = "pallet-contracts" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "bitflags 1.3.2", "frame-benchmarking", @@ -4788,7 +4789,7 @@ dependencies = [ [[package]] name = "pallet-contracts-primitives" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "bitflags 1.3.2", "parity-scale-codec", @@ -4803,7 +4804,7 @@ dependencies = [ [[package]] name = "pallet-contracts-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "proc-macro2", "quote", @@ -4813,7 +4814,7 @@ dependencies = [ [[package]] name = "pallet-contracts-rpc" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "jsonrpsee", "pallet-contracts-primitives", @@ -4830,7 +4831,7 @@ dependencies = [ [[package]] name = "pallet-contracts-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "pallet-contracts-primitives", "parity-scale-codec", @@ -4926,6 +4927,26 @@ dependencies = [ "substrate-test-utils", ] +[[package]] +name = "pallet-ddc-payouts" +version = "4.8.1" +dependencies = [ + "ddc-primitives", + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-std", + "sp-tracing", + "substrate-test-utils", +] + [[package]] name = "pallet-ddc-staking" version = "4.8.1" @@ -4985,7 +5006,7 @@ dependencies = [ [[package]] name = "pallet-democracy" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-support", @@ -5001,7 +5022,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-multi-phase" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -5025,7 +5046,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-support-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -5038,7 +5059,7 @@ dependencies = [ [[package]] name = "pallet-elections-phragmen" version = "5.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-support", @@ -5094,7 +5115,7 @@ dependencies = [ [[package]] name = "pallet-fast-unstake" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -5115,7 +5136,7 @@ dependencies = [ [[package]] name = "pallet-grandpa" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-support", @@ -5138,7 +5159,7 @@ dependencies = [ [[package]] name = "pallet-identity" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "enumflags2", "frame-benchmarking", @@ -5154,7 +5175,7 @@ dependencies = [ [[package]] name = "pallet-im-online" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-support", @@ -5174,7 +5195,7 @@ dependencies = [ [[package]] name = "pallet-indices" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-support", @@ -5191,7 +5212,7 @@ dependencies = [ [[package]] name = "pallet-membership" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-support", @@ -5208,7 +5229,7 @@ dependencies = [ [[package]] name = "pallet-multisig" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-support", @@ -5223,7 +5244,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools" version = "1.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-support", "frame-system", @@ -5240,7 +5261,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools-benchmarking" version = "1.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -5260,7 +5281,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools-runtime-api" version = "1.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "parity-scale-codec", "sp-api", @@ -5270,7 +5291,7 @@ dependencies = [ [[package]] name = "pallet-offences" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-support", "frame-system", @@ -5287,7 +5308,7 @@ dependencies = [ [[package]] name = "pallet-offences-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -5310,7 +5331,7 @@ dependencies = [ [[package]] name = "pallet-proxy" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-support", @@ -5325,7 +5346,7 @@ dependencies = [ [[package]] name = "pallet-randomness-collective-flip" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-support", "frame-system", @@ -5339,7 +5360,7 @@ dependencies = [ [[package]] name = "pallet-recovery" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-support", @@ -5354,7 +5375,7 @@ dependencies = [ [[package]] name = "pallet-scheduler" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-support", @@ -5370,7 +5391,7 @@ dependencies = [ [[package]] name = "pallet-session" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-support", "frame-system", @@ -5391,7 +5412,7 @@ dependencies = [ [[package]] name = "pallet-session-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-support", @@ -5407,7 +5428,7 @@ dependencies = [ [[package]] name = "pallet-society" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-support", "frame-system", @@ -5421,7 +5442,7 @@ dependencies = [ [[package]] name = "pallet-staking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -5444,7 +5465,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-curve" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -5455,7 +5476,7 @@ dependencies = [ [[package]] name = "pallet-sudo" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-support", "frame-system", @@ -5469,7 +5490,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-support", @@ -5487,7 +5508,7 @@ dependencies = [ [[package]] name = "pallet-tips" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-support", @@ -5506,7 +5527,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-support", "frame-system", @@ -5522,7 +5543,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "jsonrpsee", "pallet-transaction-payment-rpc-runtime-api", @@ -5537,7 +5558,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -5548,7 +5569,7 @@ dependencies = [ [[package]] name = "pallet-transaction-storage" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-support", "frame-system", @@ -5566,7 +5587,7 @@ dependencies = [ [[package]] name = "pallet-treasury" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-support", @@ -5583,7 +5604,7 @@ dependencies = [ [[package]] name = "pallet-utility" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-support", @@ -5599,7 +5620,7 @@ dependencies = [ [[package]] name = "pallet-vesting" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-benchmarking", "frame-support", @@ -6485,7 +6506,7 @@ checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] name = "remote-externalities" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "env_logger 0.9.3", "jsonrpsee", @@ -6744,7 +6765,7 @@ dependencies = [ [[package]] name = "sc-allocator" version = "4.1.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "log", "sp-core", @@ -6755,7 +6776,7 @@ dependencies = [ [[package]] name = "sc-authority-discovery" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "async-trait", "futures", @@ -6782,7 +6803,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "futures", "futures-timer", @@ -6805,7 +6826,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -6821,7 +6842,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "impl-trait-for-tuples", "memmap2", @@ -6838,7 +6859,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -6849,7 +6870,7 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "array-bytes 4.2.0", "chrono", @@ -6889,7 +6910,7 @@ dependencies = [ [[package]] name = "sc-client-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "fnv", "futures", @@ -6917,7 +6938,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "hash-db", "kvdb", @@ -6942,7 +6963,7 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "async-trait", "futures", @@ -6966,7 +6987,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "async-trait", "fork-tree", @@ -7008,7 +7029,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe-rpc" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "futures", "jsonrpsee", @@ -7030,7 +7051,7 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "fork-tree", "parity-scale-codec", @@ -7043,7 +7064,7 @@ dependencies = [ [[package]] name = "sc-consensus-slots" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "async-trait", "futures", @@ -7067,7 +7088,7 @@ dependencies = [ [[package]] name = "sc-consensus-uncles" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "sc-client-api", "sp-authorship", @@ -7078,7 +7099,7 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "lazy_static", "lru", @@ -7105,7 +7126,7 @@ dependencies = [ [[package]] name = "sc-executor-common" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "environmental", "parity-scale-codec", @@ -7121,7 +7142,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "log", "parity-scale-codec", @@ -7136,7 +7157,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "cfg-if", "libc", @@ -7156,7 +7177,7 @@ dependencies = [ [[package]] name = "sc-finality-grandpa" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "ahash", "array-bytes 4.2.0", @@ -7197,7 +7218,7 @@ dependencies = [ [[package]] name = "sc-finality-grandpa-rpc" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "finality-grandpa", "futures", @@ -7218,7 +7239,7 @@ dependencies = [ [[package]] name = "sc-informant" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "ansi_term 0.12.1", "futures", @@ -7235,7 +7256,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "array-bytes 4.2.0", "async-trait", @@ -7250,7 +7271,7 @@ dependencies = [ [[package]] name = "sc-network" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "array-bytes 4.2.0", "async-trait", @@ -7297,7 +7318,7 @@ dependencies = [ [[package]] name = "sc-network-bitswap" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "cid", "futures", @@ -7317,7 +7338,7 @@ dependencies = [ [[package]] name = "sc-network-common" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "async-trait", "bitflags 1.3.2", @@ -7343,7 +7364,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "ahash", "futures", @@ -7361,7 +7382,7 @@ dependencies = [ [[package]] name = "sc-network-light" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "array-bytes 4.2.0", "futures", @@ -7382,7 +7403,7 @@ dependencies = [ [[package]] name = "sc-network-sync" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "array-bytes 4.2.0", "fork-tree", @@ -7410,7 +7431,7 @@ dependencies = [ [[package]] name = "sc-network-transactions" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "array-bytes 4.2.0", "futures", @@ -7429,7 +7450,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "array-bytes 4.2.0", "bytes", @@ -7459,7 +7480,7 @@ dependencies = [ [[package]] name = "sc-peerset" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "futures", "libp2p", @@ -7472,7 +7493,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -7481,7 +7502,7 @@ dependencies = [ [[package]] name = "sc-rpc" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "futures", "hash-db", @@ -7511,7 +7532,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "futures", "jsonrpsee", @@ -7534,7 +7555,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "futures", "jsonrpsee", @@ -7547,7 +7568,7 @@ dependencies = [ [[package]] name = "sc-service" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "async-trait", "directories", @@ -7617,7 +7638,7 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "log", "parity-scale-codec", @@ -7631,7 +7652,7 @@ dependencies = [ [[package]] name = "sc-sync-state-rpc" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -7650,7 +7671,7 @@ dependencies = [ [[package]] name = "sc-sysinfo" version = "6.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "futures", "libc", @@ -7669,7 +7690,7 @@ dependencies = [ [[package]] name = "sc-telemetry" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "chrono", "futures", @@ -7687,7 +7708,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "ansi_term 0.12.1", "atty", @@ -7718,7 +7739,7 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -7729,7 +7750,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "futures", "futures-timer", @@ -7755,7 +7776,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "futures", "log", @@ -7768,7 +7789,7 @@ dependencies = [ [[package]] name = "sc-utils" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "futures", "futures-timer", @@ -8191,7 +8212,7 @@ dependencies = [ [[package]] name = "sp-api" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "hash-db", "log", @@ -8209,7 +8230,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "blake2", "proc-macro-crate", @@ -8221,7 +8242,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "parity-scale-codec", "scale-info", @@ -8234,7 +8255,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "integer-sqrt", "num-traits", @@ -8249,7 +8270,7 @@ dependencies = [ [[package]] name = "sp-authority-discovery" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "parity-scale-codec", "scale-info", @@ -8262,7 +8283,7 @@ dependencies = [ [[package]] name = "sp-authorship" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "async-trait", "parity-scale-codec", @@ -8274,7 +8295,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "parity-scale-codec", "sp-api", @@ -8286,7 +8307,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "futures", "log", @@ -8304,7 +8325,7 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "async-trait", "futures", @@ -8323,7 +8344,7 @@ dependencies = [ [[package]] name = "sp-consensus-babe" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "async-trait", "merlin", @@ -8346,7 +8367,7 @@ dependencies = [ [[package]] name = "sp-consensus-slots" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "parity-scale-codec", "scale-info", @@ -8360,7 +8381,7 @@ dependencies = [ [[package]] name = "sp-consensus-vrf" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "parity-scale-codec", "scale-info", @@ -8373,7 +8394,7 @@ dependencies = [ [[package]] name = "sp-core" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "array-bytes 4.2.0", "base58", @@ -8419,7 +8440,7 @@ dependencies = [ [[package]] name = "sp-core-hashing" version = "4.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "blake2", "byteorder", @@ -8433,7 +8454,7 @@ dependencies = [ [[package]] name = "sp-core-hashing-proc-macro" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "proc-macro2", "quote", @@ -8444,7 +8465,7 @@ dependencies = [ [[package]] name = "sp-database" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "kvdb", "parking_lot 0.12.1", @@ -8453,7 +8474,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "4.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "proc-macro2", "quote", @@ -8463,7 +8484,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.12.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "environmental", "parity-scale-codec", @@ -8474,7 +8495,7 @@ dependencies = [ [[package]] name = "sp-finality-grandpa" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "finality-grandpa", "log", @@ -8492,7 +8513,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "async-trait", "impl-trait-for-tuples", @@ -8506,7 +8527,7 @@ dependencies = [ [[package]] name = "sp-io" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "bytes", "futures", @@ -8532,7 +8553,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "lazy_static", "sp-core", @@ -8543,7 +8564,7 @@ dependencies = [ [[package]] name = "sp-keystore" version = "0.12.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "async-trait", "futures", @@ -8560,7 +8581,7 @@ dependencies = [ [[package]] name = "sp-maybe-compressed-blob" version = "4.1.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "thiserror", "zstd", @@ -8569,7 +8590,7 @@ dependencies = [ [[package]] name = "sp-npos-elections" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "parity-scale-codec", "scale-info", @@ -8583,7 +8604,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "sp-api", "sp-core", @@ -8593,7 +8614,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "4.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "backtrace", "lazy_static", @@ -8603,7 +8624,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "rustc-hash", "serde", @@ -8613,7 +8634,7 @@ dependencies = [ [[package]] name = "sp-runtime" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "either", "hash256-std-hasher", @@ -8636,7 +8657,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -8654,7 +8675,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "Inflector", "proc-macro-crate", @@ -8666,7 +8687,7 @@ dependencies = [ [[package]] name = "sp-sandbox" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "log", "parity-scale-codec", @@ -8680,7 +8701,7 @@ dependencies = [ [[package]] name = "sp-session" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "parity-scale-codec", "scale-info", @@ -8694,7 +8715,7 @@ dependencies = [ [[package]] name = "sp-staking" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "parity-scale-codec", "scale-info", @@ -8705,7 +8726,7 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.12.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "hash-db", "log", @@ -8727,12 +8748,12 @@ dependencies = [ [[package]] name = "sp-std" version = "4.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" [[package]] name = "sp-storage" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "impl-serde", "parity-scale-codec", @@ -8745,7 +8766,7 @@ dependencies = [ [[package]] name = "sp-tasks" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "log", "sp-core", @@ -8758,7 +8779,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "async-trait", "futures-timer", @@ -8774,7 +8795,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "parity-scale-codec", "sp-std", @@ -8786,7 +8807,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "sp-api", "sp-runtime", @@ -8795,7 +8816,7 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "async-trait", "log", @@ -8811,7 +8832,7 @@ dependencies = [ [[package]] name = "sp-trie" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "ahash", "hash-db", @@ -8834,7 +8855,7 @@ dependencies = [ [[package]] name = "sp-version" version = "5.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "impl-serde", "parity-scale-codec", @@ -8851,7 +8872,7 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "parity-scale-codec", "proc-macro2", @@ -8862,7 +8883,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "6.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "impl-trait-for-tuples", "log", @@ -8875,7 +8896,7 @@ dependencies = [ [[package]] name = "sp-weights" version = "4.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -9016,7 +9037,7 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "platforms 2.0.0", ] @@ -9024,7 +9045,7 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "frame-system-rpc-runtime-api", "futures", @@ -9045,7 +9066,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "futures-util", "hyper", @@ -9058,7 +9079,7 @@ dependencies = [ [[package]] name = "substrate-state-trie-migration-rpc" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "jsonrpsee", "log", @@ -9079,7 +9100,7 @@ dependencies = [ [[package]] name = "substrate-test-utils" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "futures", "substrate-test-utils-derive", @@ -9089,7 +9110,7 @@ dependencies = [ [[package]] name = "substrate-test-utils-derive" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -9100,7 +9121,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" version = "5.0.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "ansi_term 0.12.1", "build-helper", @@ -9561,7 +9582,7 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "try-runtime-cli" version = "0.10.0-dev" -source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.30#a3ed0119c45cdd0d571ad34e5b3ee7518c8cef8d" dependencies = [ "clap", "frame-try-runtime", diff --git a/Cargo.toml b/Cargo.toml index 835a9919a..538f83fb3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,7 @@ members = [ "pallets/ddc-accounts", "pallets/ddc-nodes", "pallets/ddc-clusters", + "pallets/ddc-payouts", "primitives", ] diff --git a/pallets/ddc-payouts/Cargo.toml b/pallets/ddc-payouts/Cargo.toml new file mode 100644 index 000000000..8f171e21b --- /dev/null +++ b/pallets/ddc-payouts/Cargo.toml @@ -0,0 +1,40 @@ +[package] +name = "pallet-ddc-payouts" +version = "4.8.1" +edition = "2021" + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.1.5", default-features = false, features = ["derive"] } +ddc-primitives = { version = "0.1.0", default-features = false, path = "../../primitives" } +frame-benchmarking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30", optional = true } +frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } +frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } +log = { version = "0.4.17", default-features = false } +scale-info = { version = "2.1.2", default-features = false, features = ["derive"] } +sp-io = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } +sp-runtime = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } +sp-staking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } +sp-std = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } +sp-core = { version = "6.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30", default-features = false } + +[dev-dependencies] +sp-core = { version = "6.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } +sp-tracing = { version = "5.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } +substrate-test-utils = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } + +[features] +default = ["std"] +std = [ + "codec/std", + "ddc-primitives/std", + "frame-support/std", + "frame-system/std", + "frame-benchmarking/std", + "scale-info/std", + "sp-io/std", + "sp-runtime/std", + "sp-staking/std", + "sp-std/std", + "sp-core/std", +] +runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] diff --git a/pallets/ddc-payouts/src/lib.rs b/pallets/ddc-payouts/src/lib.rs new file mode 100644 index 000000000..e676f2eb3 --- /dev/null +++ b/pallets/ddc-payouts/src/lib.rs @@ -0,0 +1,345 @@ +//! # DDC Payouts Pallet +//! +//! The DDC Payouts pallet is used to distribute payouts based on DAC validation +//! +//! - [`Config`] +//! - [`Call`] +//! - [`Pallet`] +//! +//! ## GenesisConfig +//! +//! The DDC Payouts pallet depends on the [`GenesisConfig`]. The +//! `GenesisConfig` is optional and allow to set some initial nodes in DDC. + +#![cfg_attr(not(feature = "std"), no_std)] +#![recursion_limit = "256"] + +use ddc_primitives::{ClusterId, DdcEra}; +use frame_support::{pallet_prelude::*, parameter_types, BoundedVec}; +use frame_system::pallet_prelude::*; +pub use pallet::*; +use sp_runtime::Perbill; +use sp_std::{ops::Mul, prelude::*}; + +type BatchIndex = u16; + +parameter_types! { + pub MaxBatchesCount: u16 = 1000; +} + +#[frame_support::pallet] +pub mod pallet { + + use super::*; + + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + } + + #[pallet::event] + #[pallet::generate_deposit(pub(crate) fn deposit_event)] + pub enum Event { + BillingReportInitialized { cluster_id: ClusterId, era: DdcEra }, + ChargingStarted { cluster_id: ClusterId, era: DdcEra }, + ChargingFinished { cluster_id: ClusterId, era: DdcEra }, + RewardingStarted { cluster_id: ClusterId, era: DdcEra }, + RewardingFinished { cluster_id: ClusterId, era: DdcEra }, + BillingReportFinalized { cluster_id: ClusterId, era: DdcEra }, + } + + #[pallet::error] + pub enum Error { + BillingReportDoesNotExist, + NotExpectedState, + BatchIndexAlreadyProcessed, + BatchIndexIsOutOfRange, + BatchesMissed, + NotDistributedBalance, + BatchIndexOverflow, + BoundedVecOverflow, + } + + #[pallet::storage] + #[pallet::getter(fn active_billing_reports)] + pub type ActiveBillingReports = StorageDoubleMap< + _, + Blake2_128Concat, + ClusterId, + Blake2_128Concat, + DdcEra, + BillingReport, + ValueQuery, + >; + + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Default)] + pub struct BillingReport { + state: State, + total_balance: u128, + distributed_balance: u128, + // stage 1 + charging_max_batch_index: BatchIndex, + charging_processed_batches: BoundedVec, + // stage 2 + rewarding_max_batch_index: BatchIndex, + rewarding_processed_batches: BoundedVec, + } + + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Default)] + pub enum State { + #[default] + NotInitialized, + Initialized, + ChargingCustomers, + CustomersCharged, + RewardingProviders, + ProvidersRewarded, + Finalized, + } + + #[pallet::call] + impl Pallet { + #[pallet::weight(10_000)] + pub fn begin_billing_report( + origin: OriginFor, + cluster_id: ClusterId, + era: DdcEra, + ) -> DispatchResult { + ensure_signed(origin)?; // todo: check that the caller is DAC account + + let mut billing_report = BillingReport::default(); + billing_report.state = State::Initialized; + ActiveBillingReports::::insert(cluster_id.clone(), era, billing_report); + + Self::deposit_event(Event::::BillingReportInitialized { cluster_id, era }); + + Ok(()) + } + + #[pallet::weight(10_000)] + pub fn begin_charging_customers( + origin: OriginFor, + cluster_id: ClusterId, + era: DdcEra, + max_batch_index: BatchIndex, + ) -> DispatchResult { + ensure_signed(origin)?; + + ensure!( + max_batch_index > 0 && max_batch_index < MaxBatchesCount::get(), + Error::::BatchIndexOverflow + ); + + let mut billing_report = ActiveBillingReports::::try_get(cluster_id.clone(), era) + .map_err(|_| Error::::BillingReportDoesNotExist)?; + + ensure!(billing_report.state == State::Initialized, Error::::NotExpectedState); + + billing_report.charging_max_batch_index = max_batch_index; + billing_report.state = State::ChargingCustomers; + ActiveBillingReports::::insert(cluster_id.clone(), era, billing_report); + + Self::deposit_event(Event::::ChargingStarted { cluster_id, era }); + + Ok(()) + } + + #[pallet::weight(10_000)] + pub fn send_charging_customers_batch( + origin: OriginFor, + cluster_id: ClusterId, + era: DdcEra, + batch_index: BatchIndex, + payers: Vec<(T::AccountId, u128)>, + ) -> DispatchResult { + ensure_signed(origin)?; + + let billing_report = ActiveBillingReports::::try_get(cluster_id.clone(), era) + .map_err(|_| Error::::BillingReportDoesNotExist)?; + + ensure!(billing_report.state == State::ChargingCustomers, Error::::NotExpectedState); + ensure!( + billing_report.charging_max_batch_index >= batch_index, + Error::::BatchIndexIsOutOfRange + ); + ensure!( + !billing_report.charging_processed_batches.contains(&batch_index), + Error::::BatchIndexAlreadyProcessed + ); + + let mut updated_billing_report = billing_report.clone(); + for payer in payers { + let _customer = payer.0; // todo: charge customer + let amount = payer.1; + updated_billing_report.total_balance += amount; + } + + updated_billing_report + .charging_processed_batches + .try_push(batch_index) + .map_err(|_| Error::::BoundedVecOverflow)?; + + ActiveBillingReports::::insert(cluster_id, era, updated_billing_report); + + Ok(()) + } + + #[pallet::weight(10_000)] + pub fn end_charging_customers( + origin: OriginFor, + cluster_id: ClusterId, + era: DdcEra, + ) -> DispatchResult { + ensure_signed(origin)?; + + let mut billing_report = ActiveBillingReports::::try_get(cluster_id.clone(), era) + .map_err(|_| Error::::BillingReportDoesNotExist)?; + + ensure!(billing_report.state == State::ChargingCustomers, Error::::NotExpectedState); + ensure!( + billing_report.charging_max_batch_index as usize == + billing_report.charging_processed_batches.len() - 1usize, + Error::::BatchesMissed + ); + + billing_report.state = State::CustomersCharged; + ActiveBillingReports::::insert(cluster_id.clone(), era, billing_report); + + Self::deposit_event(Event::::ChargingFinished { cluster_id, era }); + + Ok(()) + } + + #[pallet::weight(10_000)] + pub fn begin_rewarding_providers( + origin: OriginFor, + cluster_id: ClusterId, + era: DdcEra, + max_batch_index: BatchIndex, + ) -> DispatchResult { + ensure_signed(origin)?; + + ensure!( + max_batch_index > 0 && max_batch_index < MaxBatchesCount::get(), + Error::::BatchIndexOverflow + ); + + let mut billing_report = ActiveBillingReports::::try_get(cluster_id.clone(), era) + .map_err(|_| Error::::BillingReportDoesNotExist)?; + + ensure!(billing_report.state == State::CustomersCharged, Error::::NotExpectedState); + + billing_report.rewarding_max_batch_index = max_batch_index; + billing_report.state = State::RewardingProviders; + ActiveBillingReports::::insert(cluster_id.clone(), era, billing_report); + + Self::deposit_event(Event::::RewardingStarted { cluster_id, era }); + + Ok(()) + } + + #[pallet::weight(10_000)] + pub fn send_rewarding_providers_batch( + origin: OriginFor, + cluster_id: ClusterId, + era: DdcEra, + batch_index: BatchIndex, + payees: Vec<(T::AccountId, Perbill)>, + ) -> DispatchResult { + ensure_signed(origin)?; + + let billing_report = ActiveBillingReports::::try_get(cluster_id.clone(), era) + .map_err(|_| Error::::BillingReportDoesNotExist)?; + + ensure!( + billing_report.state == State::RewardingProviders, + Error::::NotExpectedState + ); + ensure!( + billing_report.rewarding_max_batch_index >= batch_index, + Error::::BatchIndexIsOutOfRange + ); + ensure!( + !billing_report.rewarding_processed_batches.contains(&batch_index), + Error::::BatchIndexAlreadyProcessed + ); + + let mut updated_billing_report = billing_report.clone(); + for payee in payees { + let _provider = payee.0; // todo: reward provider + let share = payee.1; + let amount = share.mul(billing_report.total_balance); + updated_billing_report.distributed_balance += amount; + } + + updated_billing_report + .rewarding_processed_batches + .try_push(batch_index) + .map_err(|_| Error::::BoundedVecOverflow)?; + + ActiveBillingReports::::insert(cluster_id, era, updated_billing_report); + + Ok(()) + } + + #[pallet::weight(10_000)] + pub fn end_rewarding_providers( + origin: OriginFor, + cluster_id: ClusterId, + era: DdcEra, + ) -> DispatchResult { + ensure_signed(origin)?; + + let mut billing_report = ActiveBillingReports::::try_get(cluster_id.clone(), era) + .map_err(|_| Error::::BillingReportDoesNotExist)?; + + ensure!( + billing_report.state == State::RewardingProviders, + Error::::NotExpectedState + ); + ensure!( + billing_report.rewarding_max_batch_index as usize == + billing_report.rewarding_processed_batches.len() - 1usize, + Error::::BatchesMissed + ); + + billing_report.state = State::ProvidersRewarded; + ActiveBillingReports::::insert(cluster_id.clone(), era, billing_report); + + Self::deposit_event(Event::::RewardingFinished { cluster_id, era }); + + Ok(()) + } + + #[pallet::weight(10_000)] + pub fn end_billing_report( + origin: OriginFor, + cluster_id: ClusterId, + era: DdcEra, + ) -> DispatchResult { + ensure_signed(origin)?; + + let mut billing_report = ActiveBillingReports::::try_get(cluster_id.clone(), era) + .map_err(|_| Error::::BillingReportDoesNotExist)?; + + ensure!(billing_report.state == State::ProvidersRewarded, Error::::NotExpectedState); + ensure!( + billing_report.total_balance == billing_report.distributed_balance, + Error::::NotDistributedBalance + ); + + billing_report.state = State::Finalized; + // todo: clear and archive billing_report + ActiveBillingReports::::insert(cluster_id.clone(), era, billing_report); + + Self::deposit_event(Event::::BillingReportFinalized { cluster_id, era }); + + Ok(()) + } + } +} diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index de23aa1fd..f8d9be6ee 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -9,6 +9,7 @@ use sp_core::hash::H160; use sp_runtime::{AccountId32, RuntimeDebug}; pub type ClusterId = H160; +pub type DdcEra = u64; #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq)] diff --git a/runtime/cere-dev/Cargo.toml b/runtime/cere-dev/Cargo.toml index 71b9c5112..14b228d39 100644 --- a/runtime/cere-dev/Cargo.toml +++ b/runtime/cere-dev/Cargo.toml @@ -106,6 +106,7 @@ pallet-erc20 = { version = "4.8.1", default-features = false, path = "../../pall pallet-ddc-metrics-offchain-worker = { version = "4.8.1", default-features = false, path = "../../pallets/ddc-metrics-offchain-worker" } pallet-ddc-nodes = { version = "4.8.1", default-features = false, path = "../../pallets/ddc-nodes" } pallet-ddc-clusters = { version = "4.8.1", default-features = false, path = "../../pallets/ddc-clusters" } +pallet-ddc-payouts = { version = "4.8.1", default-features = false, path = "../../pallets/ddc-payouts" } [build-dependencies] substrate-wasm-builder = { version = "5.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } @@ -189,6 +190,7 @@ std = [ "pallet-ddc-accounts/std", "pallet-ddc-nodes/std", "pallet-ddc-clusters/std", + "pallet-ddc-payouts/std", ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", diff --git a/runtime/cere-dev/src/lib.rs b/runtime/cere-dev/src/lib.rs index 3279c7529..7f13e599f 100644 --- a/runtime/cere-dev/src/lib.rs +++ b/runtime/cere-dev/src/lib.rs @@ -52,6 +52,7 @@ pub use pallet_ddc_accounts; pub use pallet_ddc_clusters; pub use pallet_ddc_metrics_offchain_worker; pub use pallet_ddc_nodes; +pub use pallet_ddc_payouts; pub use pallet_ddc_staking; use pallet_election_provider_multi_phase::SolutionAccuracyOf; use pallet_grandpa::{ @@ -1372,6 +1373,10 @@ impl pallet_ddc_clusters::Config for Runtime { type NodeRepository = pallet_ddc_nodes::Pallet; } +impl pallet_ddc_payouts::Config for Runtime { + type RuntimeEvent = RuntimeEvent; +} + construct_runtime!( pub enum Runtime where Block = Block, @@ -1427,7 +1432,8 @@ construct_runtime!( DdcValidator: pallet_ddc_validator, DdcAccounts: pallet_ddc_accounts, DdcNodes: pallet_ddc_nodes, - DdcClusters: pallet_ddc_clusters + DdcClusters: pallet_ddc_clusters, + DdcPayouts: pallet_ddc_payouts } ); From b489d542841b907e815da8b069778222d9810272 Mon Sep 17 00:00:00 2001 From: yahortsaryk Date: Thu, 2 Nov 2023 00:19:03 +0100 Subject: [PATCH 02/17] feat: generating a vault address for each billing report --- pallets/ddc-payouts/src/lib.rs | 46 +++++++++++++++++++++++++++++++--- primitives/src/lib.rs | 2 +- runtime/cere-dev/src/lib.rs | 5 ++++ 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/pallets/ddc-payouts/src/lib.rs b/pallets/ddc-payouts/src/lib.rs index e676f2eb3..f647f7047 100644 --- a/pallets/ddc-payouts/src/lib.rs +++ b/pallets/ddc-payouts/src/lib.rs @@ -31,6 +31,9 @@ parameter_types! { pub mod pallet { use super::*; + use frame_support::PalletId; + use sp_io::hashing::blake2_128; + use sp_runtime::traits::{AccountIdConversion, Zero}; #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] @@ -40,6 +43,8 @@ pub mod pallet { #[pallet::config] pub trait Config: frame_system::Config { type RuntimeEvent: From> + IsType<::RuntimeEvent>; + #[pallet::constant] + type PalletId: Get; } #[pallet::event] @@ -73,13 +78,15 @@ pub mod pallet { ClusterId, Blake2_128Concat, DdcEra, - BillingReport, + BillingReport, ValueQuery, >; - #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Default)] - pub struct BillingReport { + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq)] + #[scale_info(skip_type_params(T))] + pub struct BillingReport { state: State, + vault: T::AccountId, total_balance: u128, distributed_balance: u128, // stage 1 @@ -90,6 +97,21 @@ pub mod pallet { rewarding_processed_batches: BoundedVec, } + impl Default for BillingReport { + fn default() -> Self { + Self { + state: State::default(), + vault: T::PalletId::get().into_account_truncating(), + total_balance: Zero::zero(), + distributed_balance: Zero::zero(), + charging_max_batch_index: Zero::zero(), + charging_processed_batches: BoundedVec::default(), + rewarding_max_batch_index: Zero::zero(), + rewarding_processed_batches: BoundedVec::default(), + } + } + } + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq, Default)] pub enum State { #[default] @@ -113,6 +135,7 @@ pub mod pallet { ensure_signed(origin)?; // todo: check that the caller is DAC account let mut billing_report = BillingReport::default(); + billing_report.vault = Self::sub_account_id(cluster_id.clone(), era); billing_report.state = State::Initialized; ActiveBillingReports::::insert(cluster_id.clone(), era, billing_report); @@ -342,4 +365,21 @@ pub mod pallet { Ok(()) } } + + impl Pallet { + fn account_id() -> T::AccountId { + T::PalletId::get().into_account_truncating() + } + + fn sub_account_id(cluster_id: ClusterId, era: DdcEra) -> T::AccountId { + let mut bytes = Vec::new(); + bytes.extend_from_slice(&cluster_id[..]); + bytes.extend_from_slice(&era.encode()); + let hash = blake2_128(&bytes); + // "modl" + "payouts_" + hash is 28 bytes, the T::AccountId is 32 bytes, so we should be + // safe from the truncation and possible collisions caused by it. The rest 4 bytes will + // be fulfilled with trailing zeros. + T::PalletId::get().into_sub_account_truncating(hash) + } + } } diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index f8d9be6ee..38bf95d96 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -9,7 +9,7 @@ use sp_core::hash::H160; use sp_runtime::{AccountId32, RuntimeDebug}; pub type ClusterId = H160; -pub type DdcEra = u64; +pub type DdcEra = u32; #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq)] diff --git a/runtime/cere-dev/src/lib.rs b/runtime/cere-dev/src/lib.rs index 99d5d06ac..886ea9f25 100644 --- a/runtime/cere-dev/src/lib.rs +++ b/runtime/cere-dev/src/lib.rs @@ -1374,8 +1374,13 @@ impl pallet_ddc_clusters::Config for Runtime { type NodeRepository = pallet_ddc_nodes::Pallet; } +parameter_types! { + pub const PayoutsPalletId: PalletId = PalletId(*b"payouts_"); +} + impl pallet_ddc_payouts::Config for Runtime { type RuntimeEvent = RuntimeEvent; + type PalletId = PayoutsPalletId; } construct_runtime!( From 6d15896362c0c53c2bf3ec34951c68e1adadab68 Mon Sep 17 00:00:00 2001 From: Victor Genin Date: Thu, 9 Nov 2023 00:43:45 +0200 Subject: [PATCH 03/17] validation + node rewards --- pallets/ddc-payouts/src/lib.rs | 290 +++++++++++++++++++++++++++------ runtime/cere-dev/src/lib.rs | 1 + 2 files changed, 245 insertions(+), 46 deletions(-) diff --git a/pallets/ddc-payouts/src/lib.rs b/pallets/ddc-payouts/src/lib.rs index f647f7047..8f7aefa98 100644 --- a/pallets/ddc-payouts/src/lib.rs +++ b/pallets/ddc-payouts/src/lib.rs @@ -15,21 +15,62 @@ #![recursion_limit = "256"] use ddc_primitives::{ClusterId, DdcEra}; -use frame_support::{pallet_prelude::*, parameter_types, BoundedVec}; +use frame_support::{ + pallet_prelude::*, + parameter_types, + sp_runtime::SaturatedConversion, + traits::{Currency, ExistenceRequirement, LockableCurrency}, + BoundedBTreeSet, +}; use frame_system::pallet_prelude::*; pub use pallet::*; use sp_runtime::Perbill; -use sp_std::{ops::Mul, prelude::*}; +use sp_std::prelude::*; type BatchIndex = u16; +#[derive(PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Default, Clone)] +pub struct CustomerUsage { + pub transferred_bytes: u128, + pub stored_bytes: u128, + pub number_of_puts: u128, + pub number_of_gets: u128, +} + +#[derive(PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Default, Clone)] +pub struct NodeUsage { + pub transferred_bytes: u128, + pub stored_bytes: u128, + pub number_of_puts: u128, + pub number_of_gets: u128, +} + +#[derive(PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Default, Clone)] +pub struct NodeReward { + pub transfer: u128, + pub storage: u128, + pub puts: u128, + pub gets: u128, +} + +#[derive(PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Default, Clone)] +pub struct CustomerCharge { + pub transfer: u128, + pub storage: u128, + pub puts: u128, + pub gets: u128, +} + +/// The balance type of this pallet. +pub type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; + parameter_types! { pub MaxBatchesCount: u16 = 1000; } #[frame_support::pallet] pub mod pallet { - use super::*; use frame_support::PalletId; use sp_io::hashing::blake2_128; @@ -45,6 +86,8 @@ pub mod pallet { type RuntimeEvent: From> + IsType<::RuntimeEvent>; #[pallet::constant] type PalletId: Get; + + type Currency: LockableCurrency; } #[pallet::event] @@ -52,22 +95,27 @@ pub mod pallet { pub enum Event { BillingReportInitialized { cluster_id: ClusterId, era: DdcEra }, ChargingStarted { cluster_id: ClusterId, era: DdcEra }, + Charged { cluster_id: ClusterId, era: DdcEra, customer_id: T::AccountId, amount: u128 }, ChargingFinished { cluster_id: ClusterId, era: DdcEra }, RewardingStarted { cluster_id: ClusterId, era: DdcEra }, + Rewarded { cluster_id: ClusterId, era: DdcEra, node_id: T::AccountId, amount: u128 }, RewardingFinished { cluster_id: ClusterId, era: DdcEra }, BillingReportFinalized { cluster_id: ClusterId, era: DdcEra }, } #[pallet::error] + #[derive(PartialEq)] pub enum Error { BillingReportDoesNotExist, NotExpectedState, + Unauthorised, BatchIndexAlreadyProcessed, BatchIndexIsOutOfRange, BatchesMissed, NotDistributedBalance, BatchIndexOverflow, BoundedVecOverflow, + ArithmeticOverflow, } #[pallet::storage] @@ -82,19 +130,26 @@ pub mod pallet { ValueQuery, >; + #[pallet::storage] + #[pallet::getter(fn dac_account)] + pub type DACAccount = StorageValue<_, T::AccountId>; + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq)] #[scale_info(skip_type_params(T))] pub struct BillingReport { state: State, vault: T::AccountId, - total_balance: u128, - distributed_balance: u128, + dac_account: Option, + total_charged_balance: u128, + total_distributed_balance: u128, + total_node_expected_reward: NodeReward, + total_node_expected_usage: NodeUsage, // stage 1 charging_max_batch_index: BatchIndex, - charging_processed_batches: BoundedVec, + charging_processed_batches: BoundedBTreeSet, // stage 2 rewarding_max_batch_index: BatchIndex, - rewarding_processed_batches: BoundedVec, + rewarding_processed_batches: BoundedBTreeSet, } impl Default for BillingReport { @@ -102,12 +157,15 @@ pub mod pallet { Self { state: State::default(), vault: T::PalletId::get().into_account_truncating(), - total_balance: Zero::zero(), - distributed_balance: Zero::zero(), + dac_account: Option::None, + total_charged_balance: Zero::zero(), + total_distributed_balance: Zero::zero(), + total_node_expected_usage: NodeUsage::default(), + total_node_expected_reward: NodeReward::default(), charging_max_batch_index: Zero::zero(), - charging_processed_batches: BoundedVec::default(), + charging_processed_batches: BoundedBTreeSet::default(), rewarding_max_batch_index: Zero::zero(), - rewarding_processed_batches: BoundedVec::default(), + rewarding_processed_batches: BoundedBTreeSet::default(), } } } @@ -132,7 +190,11 @@ pub mod pallet { cluster_id: ClusterId, era: DdcEra, ) -> DispatchResult { - ensure_signed(origin)?; // todo: check that the caller is DAC account + let caller = ensure_signed(origin)?; + ensure!( + Self::dac_account().ok_or(Error::::Unauthorised)? == caller, + Error::::Unauthorised + ); let mut billing_report = BillingReport::default(); billing_report.vault = Self::sub_account_id(cluster_id.clone(), era); @@ -151,7 +213,11 @@ pub mod pallet { era: DdcEra, max_batch_index: BatchIndex, ) -> DispatchResult { - ensure_signed(origin)?; + let caller = ensure_signed(origin)?; + ensure!( + Self::dac_account().ok_or(Error::::Unauthorised)? == caller, + Error::::Unauthorised + ); ensure!( max_batch_index > 0 && max_batch_index < MaxBatchesCount::get(), @@ -178,9 +244,13 @@ pub mod pallet { cluster_id: ClusterId, era: DdcEra, batch_index: BatchIndex, - payers: Vec<(T::AccountId, u128)>, + payers: Vec<(T::AccountId, CustomerUsage)>, ) -> DispatchResult { - ensure_signed(origin)?; + let caller = ensure_signed(origin)?; + ensure!( + Self::dac_account().ok_or(Error::::Unauthorised)? == caller, + Error::::Unauthorised + ); let billing_report = ActiveBillingReports::::try_get(cluster_id.clone(), era) .map_err(|_| Error::::BillingReportDoesNotExist)?; @@ -197,14 +267,31 @@ pub mod pallet { let mut updated_billing_report = billing_report.clone(); for payer in payers { - let _customer = payer.0; // todo: charge customer - let amount = payer.1; - updated_billing_report.total_balance += amount; + let customer_charge = + get_customer_charge(&payer.1).ok_or(Error::::ArithmeticOverflow)?; + let amount = (|| -> Option { + customer_charge + .transfer + .checked_add(customer_charge.storage)? + .checked_add(customer_charge.puts)? + .checked_add(customer_charge.gets) + })() + .ok_or(Error::::ArithmeticOverflow)?; + + // todo: charge customer + let customer_id = payer.0; + + updated_billing_report + .total_charged_balance + .checked_add(amount) + .ok_or(Error::::ArithmeticOverflow)?; + + Self::deposit_event(Event::::Charged { cluster_id, era, customer_id, amount }); } updated_billing_report .charging_processed_batches - .try_push(batch_index) + .try_insert(batch_index) .map_err(|_| Error::::BoundedVecOverflow)?; ActiveBillingReports::::insert(cluster_id, era, updated_billing_report); @@ -218,17 +305,20 @@ pub mod pallet { cluster_id: ClusterId, era: DdcEra, ) -> DispatchResult { - ensure_signed(origin)?; + let caller = ensure_signed(origin)?; + ensure!( + Self::dac_account().ok_or(Error::::Unauthorised)? == caller, + Error::::Unauthorised + ); let mut billing_report = ActiveBillingReports::::try_get(cluster_id.clone(), era) .map_err(|_| Error::::BillingReportDoesNotExist)?; ensure!(billing_report.state == State::ChargingCustomers, Error::::NotExpectedState); - ensure!( - billing_report.charging_max_batch_index as usize == - billing_report.charging_processed_batches.len() - 1usize, - Error::::BatchesMissed - ); + validate_batches::( + &billing_report.charging_processed_batches, + &billing_report.charging_max_batch_index, + )?; billing_report.state = State::CustomersCharged; ActiveBillingReports::::insert(cluster_id.clone(), era, billing_report); @@ -244,8 +334,13 @@ pub mod pallet { cluster_id: ClusterId, era: DdcEra, max_batch_index: BatchIndex, + total_node_usage: NodeUsage, ) -> DispatchResult { - ensure_signed(origin)?; + let caller = ensure_signed(origin)?; + ensure!( + Self::dac_account().ok_or(Error::::Unauthorised)? == caller, + Error::::Unauthorised + ); ensure!( max_batch_index > 0 && max_batch_index < MaxBatchesCount::get(), @@ -257,7 +352,12 @@ pub mod pallet { ensure!(billing_report.state == State::CustomersCharged, Error::::NotExpectedState); + let total = + get_total_usage_reward(&total_node_usage).ok_or(Error::::ArithmeticOverflow)?; + + billing_report.total_node_expected_usage = total_node_usage; billing_report.rewarding_max_batch_index = max_batch_index; + billing_report.total_node_expected_reward = total; billing_report.state = State::RewardingProviders; ActiveBillingReports::::insert(cluster_id.clone(), era, billing_report); @@ -272,9 +372,13 @@ pub mod pallet { cluster_id: ClusterId, era: DdcEra, batch_index: BatchIndex, - payees: Vec<(T::AccountId, Perbill)>, + payees: Vec<(T::AccountId, NodeUsage)>, ) -> DispatchResult { - ensure_signed(origin)?; + let caller = ensure_signed(origin)?; + ensure!( + Self::dac_account().ok_or(Error::::Unauthorised)? == caller, + Error::::Unauthorised + ); let billing_report = ActiveBillingReports::::try_get(cluster_id.clone(), era) .map_err(|_| Error::::BillingReportDoesNotExist)?; @@ -294,15 +398,41 @@ pub mod pallet { let mut updated_billing_report = billing_report.clone(); for payee in payees { - let _provider = payee.0; // todo: reward provider - let share = payee.1; - let amount = share.mul(billing_report.total_balance); - updated_billing_report.distributed_balance += amount; + let node_reward = get_node_reward( + &payee.1, + &billing_report.total_node_expected_usage, + &billing_report.total_node_expected_reward, + ); + let amount = (|| -> Option { + node_reward + .transfer + .checked_add(node_reward.storage)? + .checked_add(node_reward.puts)? + .checked_add(node_reward.gets) + })() + .ok_or(Error::::ArithmeticOverflow)?; + + let node_id = payee.0; + let charge: BalanceOf = amount.saturated_into::>(); + + ::Currency::transfer( + &updated_billing_report.vault, + &node_id, + charge, + ExistenceRequirement::KeepAlive, + )?; + + updated_billing_report + .total_distributed_balance + .checked_add(amount) + .ok_or(Error::::ArithmeticOverflow)?; + + Self::deposit_event(Event::::Rewarded { cluster_id, era, node_id, amount }); } updated_billing_report .rewarding_processed_batches - .try_push(batch_index) + .try_insert(batch_index) .map_err(|_| Error::::BoundedVecOverflow)?; ActiveBillingReports::::insert(cluster_id, era, updated_billing_report); @@ -316,7 +446,11 @@ pub mod pallet { cluster_id: ClusterId, era: DdcEra, ) -> DispatchResult { - ensure_signed(origin)?; + let caller = ensure_signed(origin)?; + ensure!( + Self::dac_account().ok_or(Error::::Unauthorised)? == caller, + Error::::Unauthorised + ); let mut billing_report = ActiveBillingReports::::try_get(cluster_id.clone(), era) .map_err(|_| Error::::BillingReportDoesNotExist)?; @@ -325,11 +459,11 @@ pub mod pallet { billing_report.state == State::RewardingProviders, Error::::NotExpectedState ); - ensure!( - billing_report.rewarding_max_batch_index as usize == - billing_report.rewarding_processed_batches.len() - 1usize, - Error::::BatchesMissed - ); + + validate_batches::( + &billing_report.rewarding_processed_batches, + &billing_report.rewarding_max_batch_index, + )?; billing_report.state = State::ProvidersRewarded; ActiveBillingReports::::insert(cluster_id.clone(), era, billing_report); @@ -345,27 +479,91 @@ pub mod pallet { cluster_id: ClusterId, era: DdcEra, ) -> DispatchResult { - ensure_signed(origin)?; + let caller = ensure_signed(origin)?; + ensure!( + Self::dac_account().ok_or(Error::::Unauthorised)? == caller, + Error::::Unauthorised + ); - let mut billing_report = ActiveBillingReports::::try_get(cluster_id.clone(), era) + let billing_report = ActiveBillingReports::::try_get(cluster_id.clone(), era) .map_err(|_| Error::::BillingReportDoesNotExist)?; ensure!(billing_report.state == State::ProvidersRewarded, Error::::NotExpectedState); ensure!( - billing_report.total_balance == billing_report.distributed_balance, + billing_report.total_charged_balance == billing_report.total_distributed_balance, Error::::NotDistributedBalance ); - billing_report.state = State::Finalized; - // todo: clear and archive billing_report - ActiveBillingReports::::insert(cluster_id.clone(), era, billing_report); - + ActiveBillingReports::::remove(cluster_id.clone(), era); Self::deposit_event(Event::::BillingReportFinalized { cluster_id, era }); Ok(()) } } + fn get_node_reward( + node_usage: &NodeUsage, + total_usage: &NodeUsage, + total_reward: &NodeReward, + ) -> NodeReward { + let mut node_reward = NodeReward::default(); + + let mut ratio = + Perbill::from_rational(node_usage.transferred_bytes, total_usage.transferred_bytes); + node_reward.transfer = (ratio * total_reward.transfer) as u128; + + ratio = Perbill::from_rational(node_usage.stored_bytes, total_usage.stored_bytes); + node_reward.storage = (ratio * total_reward.storage) as u128; + + ratio = Perbill::from_rational(node_usage.number_of_puts, total_usage.number_of_puts); + node_reward.puts = (ratio * total_reward.puts) as u128; + + ratio = Perbill::from_rational(node_usage.number_of_gets, total_usage.number_of_gets); + node_reward.gets = (ratio * total_reward.gets) as u128; + + node_reward + } + + // todo: to calculate actual charge based on the metrics + fn get_total_usage_reward(total_usage: &NodeUsage) -> Option { + let mut total = NodeReward::default(); + + total.transfer = 1; + total.storage = 2; + total.puts = 3; + total.gets = 4; + + Option::Some(total) + } + + // todo: to calculate actual charge based on the metrics + fn get_customer_charge(usage: &CustomerUsage) -> Option { + let mut total = CustomerCharge::default(); + + total.transfer = 1; + total.storage = 2; + total.puts = 3; + total.gets = 4; + + Option::Some(total) + } + + fn validate_batches( + batches: &BoundedBTreeSet, + max_batch_index: &BatchIndex, + ) -> DispatchResult { + // Check if the Vec contains all integers between 1 and rewarding_max_batch_index + ensure!(!batches.is_empty(), Error::::BatchesMissed); + + ensure!(*max_batch_index as usize == batches.len() - 1usize, Error::::BatchesMissed); + + for index in 0..*max_batch_index { + ensure!(batches.contains(&index), Error::::BatchesMissed); + } + + Ok(()) + } + impl Pallet { fn account_id() -> T::AccountId { T::PalletId::get().into_account_truncating() diff --git a/runtime/cere-dev/src/lib.rs b/runtime/cere-dev/src/lib.rs index 886ea9f25..4a2f02f63 100644 --- a/runtime/cere-dev/src/lib.rs +++ b/runtime/cere-dev/src/lib.rs @@ -1381,6 +1381,7 @@ parameter_types! { impl pallet_ddc_payouts::Config for Runtime { type RuntimeEvent = RuntimeEvent; type PalletId = PayoutsPalletId; + type Currency = Balances; } construct_runtime!( From 7ca5bf0553fba24f12bbe0b3b25a4211a29dd14b Mon Sep 17 00:00:00 2001 From: Victor Genin Date: Mon, 13 Nov 2023 14:41:15 +0200 Subject: [PATCH 04/17] payout<->customers --- Cargo.lock | 2 + pallets/ddc-customers/src/lib.rs | 84 +++++++++++--------- pallets/ddc-payouts/Cargo.toml | 1 + pallets/ddc-payouts/src/lib.rs | 132 ++++++++++++++++++++++++------- primitives/Cargo.toml | 1 - primitives/src/lib.rs | 1 - runtime/cere-dev/src/lib.rs | 2 + traits/Cargo.toml | 1 + traits/src/customer.rs | 8 ++ traits/src/lib.rs | 1 + 10 files changed, 163 insertions(+), 70 deletions(-) create mode 100644 traits/src/customer.rs diff --git a/Cargo.lock b/Cargo.lock index f38bc9c18..1505a42b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1655,6 +1655,7 @@ dependencies = [ "frame-support", "frame-system", "sp-core", + "sp-runtime", "sp-staking", "sp-std", ] @@ -5004,6 +5005,7 @@ name = "pallet-ddc-payouts" version = "4.8.1" dependencies = [ "ddc-primitives", + "ddc-traits", "frame-benchmarking", "frame-support", "frame-system", diff --git a/pallets/ddc-customers/src/lib.rs b/pallets/ddc-customers/src/lib.rs index d544ced22..e29902af8 100644 --- a/pallets/ddc-customers/src/lib.rs +++ b/pallets/ddc-customers/src/lib.rs @@ -4,7 +4,7 @@ use codec::{Decode, Encode, HasCompact}; use ddc_primitives::{BucketId, ClusterId}; -use ddc_traits::cluster::ClusterVisitor; +use ddc_traits::{cluster::ClusterVisitor, customer::CustomerCharger}; use frame_support::{ parameter_types, traits::{Currency, DefensiveSaturating, ExistenceRequirement}, @@ -171,6 +171,11 @@ pub mod pallet { pub fn DefaultBucketCount() -> BucketId { 0 } + + #[pallet::storage] + #[pallet::getter(fn dac_account)] + pub type DACAccount = StorageValue<_, T::AccountId>; + #[pallet::storage] #[pallet::getter(fn buckets_count)] pub type BucketsCount = @@ -191,12 +196,12 @@ pub mod pallet { /// it will not be emitted for staking rewards when they are added to stake. Deposited(T::AccountId, BalanceOf), /// An account has initiated unlock for amount. \[owner, amount\] - InitiatDepositUnlock(T::AccountId, BalanceOf), + InitialDepositUnlock(T::AccountId, BalanceOf), /// An account has called `withdraw_unlocked_deposit` and removed unlocking chunks worth /// `Balance` from the unlocking queue. \[owner, amount\] Withdrawn(T::AccountId, BalanceOf), - /// Total amount charged from all accounts to pay CDN nodes - Charged(BalanceOf), + /// The acconut has been charged for the usage + Charged(T::AccountId, BalanceOf), /// Bucket with specific id created BucketCreated(BucketId), } @@ -221,6 +226,10 @@ pub mod pallet { BucketDoesNotExist, /// DDC Cluster with provided id doesn't exist ClusterDoesNotExist, + // unauthorised operation + Unauthorised, + // Arithmetic underflow + ArithmeticUnderflow, } #[pallet::genesis_config] @@ -351,7 +360,7 @@ pub mod pallet { /// can co-exists at the same time. In that case, [`Call::withdraw_unlocked_deposit`] need /// to be called first to remove some of the chunks (if possible). /// - /// Emits `InitiatDepositUnlock`. + /// Emits `InitialDepositUnlock`. /// /// See also [`Call::withdraw_unlocked_deposit`]. #[pallet::weight(10_000)] @@ -380,7 +389,6 @@ pub mod pallet { let current_block = >::block_number(); // Note: locking for extra block to allow for accounting let block = current_block + ::UnlockingDelay::get(); - log::debug!("Block for the unlock: {:?}", block); if let Some(chunk) = ledger.unlocking.last_mut().filter(|chunk| chunk.block == block) @@ -398,7 +406,7 @@ pub mod pallet { Self::update_ledger(&owner, &ledger); - Self::deposit_event(Event::::InitiatDepositUnlock(ledger.owner, value)); + Self::deposit_event(Event::::InitialDepositUnlock(ledger.owner, value)); } Ok(()) } @@ -451,7 +459,7 @@ pub mod pallet { ::Currency::transfer( &account_id, &owner, - value, + value.clone(), ExistenceRequirement::KeepAlive, )?; Self::deposit_event(Event::::Withdrawn(owner, value)); @@ -506,40 +514,38 @@ pub mod pallet { Ok(()) } + } - // Charge payments from content owners - pub fn charge_content_owners( - paying_accounts: Vec>>, - pricing: u128, + impl CustomerCharger for Pallet { + fn charge_content_owner( + content_owner: T::AccountId, + billing_vault: T::AccountId, + amount: u128, ) -> DispatchResult { - let mut total_charged = BalanceOf::::zero(); - - for bucket_details in paying_accounts.iter() { - let bucket: Bucket = Self::buckets(bucket_details.bucket_id) - .ok_or(Error::::BucketDoesNotExist)?; - let content_owner = bucket.owner_id; - let amount = bucket_details.amount * pricing.saturated_into::>(); - - let mut ledger = Self::ledger(&content_owner).ok_or(Error::::NotOwner)?; - if ledger.active >= amount { - ledger.total -= amount; - ledger.active -= amount; - total_charged += amount; - Self::update_ledger(&content_owner, &ledger); - } else { - let diff = amount - ledger.active; - total_charged += ledger.active; - ledger.total -= ledger.active; - ledger.active = BalanceOf::::zero(); - let (ledger, charged) = ledger.charge_unlocking(diff); - Self::update_ledger(&content_owner, &ledger); - total_charged += charged; - } - } - log::debug!("Total charged: {:?}", &total_charged); + let mut ledger = Self::ledger(&content_owner).ok_or(Error::::NotOwner)?; + let mut amount_to_deduct = amount.saturated_into::>(); + + ensure!(ledger.total >= ledger.active, Error::::ArithmeticUnderflow); + if ledger.active >= amount_to_deduct { + ledger.active -= amount_to_deduct; + ledger.total -= amount_to_deduct; + Self::update_ledger(&content_owner, &ledger); + } else { + let diff = amount_to_deduct - ledger.active; + ledger.total -= ledger.active; + amount_to_deduct = ledger.active; + ledger.active = BalanceOf::::zero(); + let (ledger, _charged) = ledger.charge_unlocking(diff); + Self::update_ledger(&content_owner, &ledger); + }; - Self::deposit_event(Event::::Charged(total_charged)); - log::debug!("Deposit event executed"); + ::Currency::transfer( + &Self::account_id(), + &billing_vault, + amount_to_deduct, + ExistenceRequirement::KeepAlive, + )?; + Self::deposit_event(Event::::Charged(content_owner, amount_to_deduct)); Ok(()) } diff --git a/pallets/ddc-payouts/Cargo.toml b/pallets/ddc-payouts/Cargo.toml index 8f171e21b..ffba7a6d5 100644 --- a/pallets/ddc-payouts/Cargo.toml +++ b/pallets/ddc-payouts/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [dependencies] codec = { package = "parity-scale-codec", version = "3.1.5", default-features = false, features = ["derive"] } ddc-primitives = { version = "0.1.0", default-features = false, path = "../../primitives" } +ddc-traits = { version = "0.1.0", default-features = false, path = "../../traits" } frame-benchmarking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30", optional = true } frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } diff --git a/pallets/ddc-payouts/src/lib.rs b/pallets/ddc-payouts/src/lib.rs index 8f7aefa98..e44d93de3 100644 --- a/pallets/ddc-payouts/src/lib.rs +++ b/pallets/ddc-payouts/src/lib.rs @@ -15,6 +15,7 @@ #![recursion_limit = "256"] use ddc_primitives::{ClusterId, DdcEra}; +use ddc_traits::customer::CustomerCharger; use frame_support::{ pallet_prelude::*, parameter_types, @@ -88,19 +89,55 @@ pub mod pallet { type PalletId: Get; type Currency: LockableCurrency; + + type CustomerCharger: CustomerCharger; } #[pallet::event] #[pallet::generate_deposit(pub(crate) fn deposit_event)] pub enum Event { - BillingReportInitialized { cluster_id: ClusterId, era: DdcEra }, - ChargingStarted { cluster_id: ClusterId, era: DdcEra }, - Charged { cluster_id: ClusterId, era: DdcEra, customer_id: T::AccountId, amount: u128 }, - ChargingFinished { cluster_id: ClusterId, era: DdcEra }, - RewardingStarted { cluster_id: ClusterId, era: DdcEra }, - Rewarded { cluster_id: ClusterId, era: DdcEra, node_id: T::AccountId, amount: u128 }, - RewardingFinished { cluster_id: ClusterId, era: DdcEra }, - BillingReportFinalized { cluster_id: ClusterId, era: DdcEra }, + BillingReportInitialized { + cluster_id: ClusterId, + era: DdcEra, + }, + ChargingStarted { + cluster_id: ClusterId, + era: DdcEra, + }, + Charged { + cluster_id: ClusterId, + era: DdcEra, + customer_id: T::AccountId, + amount: u128, + }, + ChargeFailed { + cluster_id: ClusterId, + era: DdcEra, + customer_id: T::AccountId, + amount: u128, + }, + ChargingFinished { + cluster_id: ClusterId, + era: DdcEra, + }, + RewardingStarted { + cluster_id: ClusterId, + era: DdcEra, + }, + Rewarded { + cluster_id: ClusterId, + era: DdcEra, + node_provider_id: T::AccountId, + amount: u128, + }, + RewardingFinished { + cluster_id: ClusterId, + era: DdcEra, + }, + BillingReportFinalized { + cluster_id: ClusterId, + era: DdcEra, + }, } #[pallet::error] @@ -131,7 +168,7 @@ pub mod pallet { >; #[pallet::storage] - #[pallet::getter(fn dac_account)] + #[pallet::getter(fn authorised_caller)] pub type DACAccount = StorageValue<_, T::AccountId>; #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq)] @@ -139,7 +176,7 @@ pub mod pallet { pub struct BillingReport { state: State, vault: T::AccountId, - dac_account: Option, + authorised_caller: Option, total_charged_balance: u128, total_distributed_balance: u128, total_node_expected_reward: NodeReward, @@ -157,7 +194,7 @@ pub mod pallet { Self { state: State::default(), vault: T::PalletId::get().into_account_truncating(), - dac_account: Option::None, + authorised_caller: Option::None, total_charged_balance: Zero::zero(), total_distributed_balance: Zero::zero(), total_node_expected_usage: NodeUsage::default(), @@ -192,7 +229,7 @@ pub mod pallet { ) -> DispatchResult { let caller = ensure_signed(origin)?; ensure!( - Self::dac_account().ok_or(Error::::Unauthorised)? == caller, + Self::authorised_caller().ok_or(Error::::Unauthorised)? == caller, Error::::Unauthorised ); @@ -215,7 +252,7 @@ pub mod pallet { ) -> DispatchResult { let caller = ensure_signed(origin)?; ensure!( - Self::dac_account().ok_or(Error::::Unauthorised)? == caller, + Self::authorised_caller().ok_or(Error::::Unauthorised)? == caller, Error::::Unauthorised ); @@ -248,7 +285,7 @@ pub mod pallet { ) -> DispatchResult { let caller = ensure_signed(origin)?; ensure!( - Self::dac_account().ok_or(Error::::Unauthorised)? == caller, + Self::authorised_caller().ok_or(Error::::Unauthorised)? == caller, Error::::Unauthorised ); @@ -278,15 +315,45 @@ pub mod pallet { })() .ok_or(Error::::ArithmeticOverflow)?; - // todo: charge customer let customer_id = payer.0; - updated_billing_report - .total_charged_balance - .checked_add(amount) - .ok_or(Error::::ArithmeticOverflow)?; - - Self::deposit_event(Event::::Charged { cluster_id, era, customer_id, amount }); + // todo: decouple AccountId from [u8; 32] + let vault_temp: Vec = vec![0; 32]; + let customer_temp: Vec = vec![0; 32]; + let mut customer_addr: [u8; 32] = [0; 32]; + customer_addr.copy_from_slice(&customer_temp[0..32]); + let mut vault_addr: [u8; 32] = [0; 32]; + vault_addr.copy_from_slice(&vault_temp[0..32]); + + match T::CustomerCharger::charge_content_owner( + customer_id.clone(), + updated_billing_report.vault.clone(), + amount, + ) { + Ok(_) => { + updated_billing_report + .total_charged_balance + .checked_add(amount) + .ok_or(Error::::ArithmeticOverflow)?; + + Self::deposit_event(Event::::Charged { + cluster_id, + era, + customer_id, + amount, + }); + }, + Err(e) => { + // todo: save problematic charge + // todo: add logs + Self::deposit_event(Event::::ChargeFailed { + cluster_id, + era, + customer_id, + amount, + }); + }, + } } updated_billing_report @@ -307,7 +374,7 @@ pub mod pallet { ) -> DispatchResult { let caller = ensure_signed(origin)?; ensure!( - Self::dac_account().ok_or(Error::::Unauthorised)? == caller, + Self::authorised_caller().ok_or(Error::::Unauthorised)? == caller, Error::::Unauthorised ); @@ -338,7 +405,7 @@ pub mod pallet { ) -> DispatchResult { let caller = ensure_signed(origin)?; ensure!( - Self::dac_account().ok_or(Error::::Unauthorised)? == caller, + Self::authorised_caller().ok_or(Error::::Unauthorised)? == caller, Error::::Unauthorised ); @@ -376,7 +443,7 @@ pub mod pallet { ) -> DispatchResult { let caller = ensure_signed(origin)?; ensure!( - Self::dac_account().ok_or(Error::::Unauthorised)? == caller, + Self::authorised_caller().ok_or(Error::::Unauthorised)? == caller, Error::::Unauthorised ); @@ -412,12 +479,12 @@ pub mod pallet { })() .ok_or(Error::::ArithmeticOverflow)?; - let node_id = payee.0; + let node_provider_id = payee.0; let charge: BalanceOf = amount.saturated_into::>(); ::Currency::transfer( &updated_billing_report.vault, - &node_id, + &node_provider_id, charge, ExistenceRequirement::KeepAlive, )?; @@ -427,7 +494,12 @@ pub mod pallet { .checked_add(amount) .ok_or(Error::::ArithmeticOverflow)?; - Self::deposit_event(Event::::Rewarded { cluster_id, era, node_id, amount }); + Self::deposit_event(Event::::Rewarded { + cluster_id, + era, + node_provider_id, + amount, + }); } updated_billing_report @@ -448,7 +520,7 @@ pub mod pallet { ) -> DispatchResult { let caller = ensure_signed(origin)?; ensure!( - Self::dac_account().ok_or(Error::::Unauthorised)? == caller, + Self::authorised_caller().ok_or(Error::::Unauthorised)? == caller, Error::::Unauthorised ); @@ -481,7 +553,7 @@ pub mod pallet { ) -> DispatchResult { let caller = ensure_signed(origin)?; ensure!( - Self::dac_account().ok_or(Error::::Unauthorised)? == caller, + Self::authorised_caller().ok_or(Error::::Unauthorised)? == caller, Error::::Unauthorised ); @@ -574,6 +646,8 @@ pub mod pallet { bytes.extend_from_slice(&cluster_id[..]); bytes.extend_from_slice(&era.encode()); let hash = blake2_128(&bytes); + // todo: assumes AccountId is 32 bytes, which is not ideal + // "modl" + "payouts_" + hash is 28 bytes, the T::AccountId is 32 bytes, so we should be // safe from the truncation and possible collisions caused by it. The rest 4 bytes will // be fulfilled with trailing zeros. diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 178800a4b..2656e5487 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -7,7 +7,6 @@ edition = "2021" codec = { package = "parity-scale-codec", version = "3.1.5", default-features = false, features = ["derive"] } scale-info = { version = "2.1.2", default-features = false, features = ["derive"] } serde = { version = "1.0.136", default-features = false, features = [ "derive" ], optional = true } - sp-core = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } sp-runtime = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index 16998c344..f9732f7ce 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -4,7 +4,6 @@ use codec::{Decode, Encode}; use scale_info::TypeInfo; #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; - use sp_core::hash::H160; use sp_runtime::{AccountId32, RuntimeDebug}; diff --git a/runtime/cere-dev/src/lib.rs b/runtime/cere-dev/src/lib.rs index 1e24cd1ae..f0274265c 100644 --- a/runtime/cere-dev/src/lib.rs +++ b/runtime/cere-dev/src/lib.rs @@ -1355,6 +1355,8 @@ impl pallet_ddc_payouts::Config for Runtime { type RuntimeEvent = RuntimeEvent; type PalletId = PayoutsPalletId; type Currency = Balances; + + type CustomerCharger = DdcCustomers; } construct_runtime!( diff --git a/traits/Cargo.toml b/traits/Cargo.toml index b224e2d28..cf6f08ee7 100644 --- a/traits/Cargo.toml +++ b/traits/Cargo.toml @@ -10,3 +10,4 @@ sp-staking = { version = "4.0.0-dev", default-features = false, git = "https://g frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } ddc-primitives = { version = "0.1.0", default-features = false, path = "../primitives" } +sp-runtime = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } diff --git a/traits/src/customer.rs b/traits/src/customer.rs new file mode 100644 index 000000000..73bbf784a --- /dev/null +++ b/traits/src/customer.rs @@ -0,0 +1,8 @@ +pub trait CustomerCharger { + // todo: WIP for decoupling payout and customers + fn charge_content_owner( + content_owner: T::AccountId, + billing_vault: T::AccountId, + amount: u128, + ) -> sp_runtime::DispatchResult; +} diff --git a/traits/src/lib.rs b/traits/src/lib.rs index f6eb2b0a4..b3b4f9787 100644 --- a/traits/src/lib.rs +++ b/traits/src/lib.rs @@ -1,4 +1,5 @@ #![cfg_attr(not(feature = "std"), no_std)] pub mod cluster; +pub mod customer; pub mod staking; From 6939d9e82a2ff3f006e7be0b38a966311b24b1ae Mon Sep 17 00:00:00 2001 From: Victor Genin Date: Mon, 13 Nov 2023 19:03:29 +0200 Subject: [PATCH 05/17] payout <> clusters --- Cargo.lock | 16 ++ pallets/ddc-clusters/src/cluster.rs | 7 +- pallets/ddc-clusters/src/lib.rs | 10 +- pallets/ddc-payouts/Cargo.toml | 15 +- pallets/ddc-payouts/src/lib.rs | 243 +++++++++++++++++++--------- primitives/src/lib.rs | 7 + runtime/cere-dev/src/lib.rs | 2 +- traits/src/cluster.rs | 6 +- 8 files changed, 206 insertions(+), 100 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1505a42b9..204e0fe17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -689,6 +689,15 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" +[[package]] +name = "byte-unit" +version = "4.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da78b32057b8fdfc352504708feeba7216dcd65a2c9ab02978cbd288d1279b6c" +dependencies = [ + "utf8-width", +] + [[package]] name = "byteorder" version = "1.5.0" @@ -5004,6 +5013,7 @@ dependencies = [ name = "pallet-ddc-payouts" version = "4.8.1" dependencies = [ + "byte-unit", "ddc-primitives", "ddc-traits", "frame-benchmarking", @@ -9804,6 +9814,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "utf8-width" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5190c9442dcdaf0ddd50f37420417d219ae5261bbf5db120d0f9bab996c9cba1" + [[package]] name = "valuable" version = "0.1.0" diff --git a/pallets/ddc-clusters/src/cluster.rs b/pallets/ddc-clusters/src/cluster.rs index 4be19d73f..7fc6e07e4 100644 --- a/pallets/ddc-clusters/src/cluster.rs +++ b/pallets/ddc-clusters/src/cluster.rs @@ -1,6 +1,6 @@ use crate::pallet::Error; use codec::{Decode, Encode}; -use ddc_primitives::ClusterId; +use ddc_primitives::{ClusterId, ClusterPricingParams}; use frame_support::{pallet_prelude::*, parameter_types}; use scale_info::TypeInfo; use sp_runtime::Perbill; @@ -41,10 +41,7 @@ pub struct ClusterGovParams { pub storage_bond_size: Balance, pub storage_chill_delay: BlockNumber, pub storage_unbonding_delay: BlockNumber, - pub unit_per_mb_stored: u128, - pub unit_per_mb_streamed: u128, - pub unit_per_put_request: u128, - pub unit_per_get_request: u128, + pub pricing: ClusterPricingParams, } impl Cluster { diff --git a/pallets/ddc-clusters/src/lib.rs b/pallets/ddc-clusters/src/lib.rs index cb4aafb7b..ee410b7db 100644 --- a/pallets/ddc-clusters/src/lib.rs +++ b/pallets/ddc-clusters/src/lib.rs @@ -19,7 +19,7 @@ use crate::{ cluster::{Cluster, ClusterError, ClusterGovParams, ClusterParams}, node_provider_auth::{NodeProviderAuthContract, NodeProviderAuthContractError}, }; -use ddc_primitives::{ClusterId, NodePubKey, NodeType}; +use ddc_primitives::{ClusterId, ClusterPricingParams, NodePubKey, NodeType}; use ddc_traits::{ cluster::{ClusterVisitor, ClusterVisitorError}, staking::{StakingVisitor, StakingVisitorError}, @@ -272,6 +272,14 @@ pub mod pallet { } } + fn get_pricing_params( + cluster_id: &ClusterId, + ) -> Result { + let cluster_gov_params = ClustersGovParams::::try_get(cluster_id) + .map_err(|_| ClusterVisitorError::ClusterGovParamsNotSet)?; + Ok(cluster_gov_params.pricing) + } + fn get_chill_delay( cluster_id: &ClusterId, node_type: NodeType, diff --git a/pallets/ddc-payouts/Cargo.toml b/pallets/ddc-payouts/Cargo.toml index ffba7a6d5..d10c1b690 100644 --- a/pallets/ddc-payouts/Cargo.toml +++ b/pallets/ddc-payouts/Cargo.toml @@ -17,6 +17,7 @@ sp-runtime = { version = "6.0.0", default-features = false, git = "https://githu sp-staking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } sp-std = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } sp-core = { version = "6.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30", default-features = false } +byte-unit = { version = "4.0.19", default-features = false, features = ["u128"] } [dev-dependencies] sp-core = { version = "6.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } @@ -25,17 +26,5 @@ substrate-test-utils = { version = "4.0.0-dev", git = "https://github.com/parity [features] default = ["std"] -std = [ - "codec/std", - "ddc-primitives/std", - "frame-support/std", - "frame-system/std", - "frame-benchmarking/std", - "scale-info/std", - "sp-io/std", - "sp-runtime/std", - "sp-staking/std", - "sp-std/std", - "sp-core/std", -] +std = ["codec/std", "ddc-primitives/std", "frame-support/std", "frame-system/std", "frame-benchmarking/std", "scale-info/std", "sp-io/std", "sp-runtime/std", "sp-staking/std", "sp-std/std", "sp-core/std"] runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] diff --git a/pallets/ddc-payouts/src/lib.rs b/pallets/ddc-payouts/src/lib.rs index e44d93de3..77a66aa45 100644 --- a/pallets/ddc-payouts/src/lib.rs +++ b/pallets/ddc-payouts/src/lib.rs @@ -15,13 +15,13 @@ #![recursion_limit = "256"] use ddc_primitives::{ClusterId, DdcEra}; -use ddc_traits::customer::CustomerCharger; +use ddc_traits::{cluster::ClusterVisitor, customer::CustomerCharger}; use frame_support::{ pallet_prelude::*, parameter_types, sp_runtime::SaturatedConversion, traits::{Currency, ExistenceRequirement, LockableCurrency}, - BoundedBTreeSet, + BoundedBTreeMap, BoundedBTreeSet, }; use frame_system::pallet_prelude::*; pub use pallet::*; @@ -54,6 +54,14 @@ pub struct NodeReward { pub gets: u128, } +#[derive(PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Default, Clone)] +pub struct BillingReportDebt { + pub cluster_id: ClusterId, + pub era: DdcEra, + pub batch_index: BatchIndex, + pub amount: u128, +} + #[derive(PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Default, Clone)] pub struct CustomerCharge { pub transfer: u128, @@ -91,6 +99,7 @@ pub mod pallet { type Currency: LockableCurrency; type CustomerCharger: CustomerCharger; + type ClusterVisitor: ClusterVisitor; } #[pallet::event] @@ -153,6 +162,7 @@ pub mod pallet { BatchIndexOverflow, BoundedVecOverflow, ArithmeticOverflow, + NotExpectedClusterState, } #[pallet::storage] @@ -171,16 +181,25 @@ pub mod pallet { #[pallet::getter(fn authorised_caller)] pub type DACAccount = StorageValue<_, T::AccountId>; + #[pallet::storage] + #[pallet::getter(fn debtor_customers)] + pub type DebtorCustomers = StorageMap< + _, + Blake2_128Concat, + T::AccountId, + BoundedBTreeMap, + ValueQuery, + >; + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq)] #[scale_info(skip_type_params(T))] pub struct BillingReport { state: State, vault: T::AccountId, authorised_caller: Option, - total_charged_balance: u128, - total_distributed_balance: u128, - total_node_expected_reward: NodeReward, - total_node_expected_usage: NodeUsage, + total_customer_charge: CustomerCharge, + total_distributed_reward: u128, + total_node_usage: NodeUsage, // stage 1 charging_max_batch_index: BatchIndex, charging_processed_batches: BoundedBTreeSet, @@ -195,10 +214,9 @@ pub mod pallet { state: State::default(), vault: T::PalletId::get().into_account_truncating(), authorised_caller: Option::None, - total_charged_balance: Zero::zero(), - total_distributed_balance: Zero::zero(), - total_node_expected_usage: NodeUsage::default(), - total_node_expected_reward: NodeReward::default(), + total_customer_charge: CustomerCharge::default(), + total_distributed_reward: Zero::zero(), + total_node_usage: NodeUsage::default(), charging_max_batch_index: Zero::zero(), charging_processed_batches: BoundedBTreeSet::default(), rewarding_max_batch_index: Zero::zero(), @@ -233,6 +251,11 @@ pub mod pallet { Error::::Unauthorised ); + ensure!( + ActiveBillingReports::::try_get(cluster_id.clone(), era).is_ok() == false, + Error::::NotExpectedState + ); + let mut billing_report = BillingReport::default(); billing_report.vault = Self::sub_account_id(cluster_id.clone(), era); billing_report.state = State::Initialized; @@ -304,9 +327,8 @@ pub mod pallet { let mut updated_billing_report = billing_report.clone(); for payer in payers { - let customer_charge = - get_customer_charge(&payer.1).ok_or(Error::::ArithmeticOverflow)?; - let amount = (|| -> Option { + let customer_charge = get_customer_charge::(cluster_id, &payer.1)?; + let total_customer_charge = (|| -> Option { customer_charge .transfer .checked_add(customer_charge.storage)? @@ -315,42 +337,82 @@ pub mod pallet { })() .ok_or(Error::::ArithmeticOverflow)?; - let customer_id = payer.0; + let temp_total_customer_storage_charge = updated_billing_report + .total_customer_charge + .storage + .checked_add(customer_charge.storage) + .ok_or(Error::::ArithmeticOverflow)?; + + let temp_total_customer_transfer_charge = updated_billing_report + .total_customer_charge + .transfer + .checked_add(customer_charge.transfer) + .ok_or(Error::::ArithmeticOverflow)?; + + let temp_total_customer_puts_charge = updated_billing_report + .total_customer_charge + .puts + .checked_add(customer_charge.puts) + .ok_or(Error::::ArithmeticOverflow)?; - // todo: decouple AccountId from [u8; 32] - let vault_temp: Vec = vec![0; 32]; - let customer_temp: Vec = vec![0; 32]; - let mut customer_addr: [u8; 32] = [0; 32]; - customer_addr.copy_from_slice(&customer_temp[0..32]); - let mut vault_addr: [u8; 32] = [0; 32]; - vault_addr.copy_from_slice(&vault_temp[0..32]); + let temp_total_customer_gets_charge = updated_billing_report + .total_customer_charge + .gets + .checked_add(customer_charge.gets) + .ok_or(Error::::ArithmeticOverflow)?; + let customer_id = payer.0; match T::CustomerCharger::charge_content_owner( customer_id.clone(), updated_billing_report.vault.clone(), - amount, + total_customer_charge, ) { Ok(_) => { - updated_billing_report - .total_charged_balance - .checked_add(amount) - .ok_or(Error::::ArithmeticOverflow)?; + updated_billing_report.total_customer_charge.storage = + temp_total_customer_storage_charge; + updated_billing_report.total_customer_charge.transfer = + temp_total_customer_transfer_charge; + updated_billing_report.total_customer_charge.puts = + temp_total_customer_puts_charge; + updated_billing_report.total_customer_charge.gets = + temp_total_customer_gets_charge; Self::deposit_event(Event::::Charged { cluster_id, era, customer_id, - amount, + amount: total_customer_charge, }); }, Err(e) => { // todo: save problematic charge // todo: add logs + updated_billing_report + .charging_processed_batches + .try_insert(batch_index) + .map_err(|_| Error::::BoundedVecOverflow)?; + + /* --- + DebtorCustomers = StorageMap< + _, + Blake2_128Concat, + T::AccountId, + BoundedBTreeMap, + let mut debtor_customers = DebtorCustomers::::try_get(cluster_id.clone(), era) + .map_err(|_| Error::::BillingReportDoesNotExist)?; + + ensure!(billing_report.state == State::Initialized, Error::::NotExpectedState); + + billing_report.charging_max_batch_index = max_batch_index; + billing_report.state = State::ChargingCustomers; + ActiveBillingReports::::insert(cluster_id.clone(), era, billing_report); + --- */ + Self::deposit_event(Event::::ChargeFailed { cluster_id, era, customer_id, - amount, + amount: total_customer_charge, }); }, } @@ -419,12 +481,8 @@ pub mod pallet { ensure!(billing_report.state == State::CustomersCharged, Error::::NotExpectedState); - let total = - get_total_usage_reward(&total_node_usage).ok_or(Error::::ArithmeticOverflow)?; - - billing_report.total_node_expected_usage = total_node_usage; + billing_report.total_node_usage = total_node_usage; billing_report.rewarding_max_batch_index = max_batch_index; - billing_report.total_node_expected_reward = total; billing_report.state = State::RewardingProviders; ActiveBillingReports::::insert(cluster_id.clone(), era, billing_report); @@ -465,12 +523,13 @@ pub mod pallet { let mut updated_billing_report = billing_report.clone(); for payee in payees { - let node_reward = get_node_reward( + let node_reward = get_node_reward::( &payee.1, - &billing_report.total_node_expected_usage, - &billing_report.total_node_expected_reward, - ); - let amount = (|| -> Option { + &billing_report.total_node_usage, + &billing_report.total_customer_charge, + ) + .ok_or(Error::::ArithmeticOverflow)?; + let amount_to_reward = (|| -> Option { node_reward .transfer .checked_add(node_reward.storage)? @@ -480,25 +539,25 @@ pub mod pallet { .ok_or(Error::::ArithmeticOverflow)?; let node_provider_id = payee.0; - let charge: BalanceOf = amount.saturated_into::>(); + let reward: BalanceOf = amount_to_reward.saturated_into::>(); ::Currency::transfer( &updated_billing_report.vault, &node_provider_id, - charge, + reward, ExistenceRequirement::KeepAlive, )?; updated_billing_report - .total_distributed_balance - .checked_add(amount) + .total_distributed_reward + .checked_add(amount_to_reward) .ok_or(Error::::ArithmeticOverflow)?; Self::deposit_event(Event::::Rewarded { cluster_id, era, node_provider_id, - amount, + amount: amount_to_reward, }); } @@ -561,8 +620,18 @@ pub mod pallet { .map_err(|_| Error::::BillingReportDoesNotExist)?; ensure!(billing_report.state == State::ProvidersRewarded, Error::::NotExpectedState); + let expected_amount_to_reward = (|| -> Option { + billing_report + .total_customer_charge + .transfer + .checked_add(billing_report.total_customer_charge.storage)? + .checked_add(billing_report.total_customer_charge.puts)? + .checked_add(billing_report.total_customer_charge.gets) + })() + .ok_or(Error::::ArithmeticOverflow)?; + ensure!( - billing_report.total_charged_balance == billing_report.total_distributed_balance, + expected_amount_to_reward == billing_report.total_distributed_reward, Error::::NotDistributedBalance ); @@ -573,51 +642,67 @@ pub mod pallet { } } - fn get_node_reward( + fn get_node_reward( node_usage: &NodeUsage, - total_usage: &NodeUsage, - total_reward: &NodeReward, - ) -> NodeReward { + total_nodes_usage: &NodeUsage, + total_customer_charge: &CustomerCharge, + ) -> Option { let mut node_reward = NodeReward::default(); - let mut ratio = - Perbill::from_rational(node_usage.transferred_bytes, total_usage.transferred_bytes); - node_reward.transfer = (ratio * total_reward.transfer) as u128; - - ratio = Perbill::from_rational(node_usage.stored_bytes, total_usage.stored_bytes); - node_reward.storage = (ratio * total_reward.storage) as u128; + let mut ratio = Perbill::from_rational( + node_usage.transferred_bytes, + total_nodes_usage.transferred_bytes, + ); + node_reward.transfer = (ratio * total_customer_charge.transfer) as u128; - ratio = Perbill::from_rational(node_usage.number_of_puts, total_usage.number_of_puts); - node_reward.puts = (ratio * total_reward.puts) as u128; + ratio = Perbill::from_rational(node_usage.stored_bytes, total_nodes_usage.stored_bytes); + node_reward.storage = (ratio * total_customer_charge.storage) as u128; - ratio = Perbill::from_rational(node_usage.number_of_gets, total_usage.number_of_gets); - node_reward.gets = (ratio * total_reward.gets) as u128; + ratio = Perbill::from_rational(node_usage.number_of_puts, total_nodes_usage.number_of_puts); + node_reward.puts = (ratio * total_customer_charge.puts) as u128; - node_reward - } - - // todo: to calculate actual charge based on the metrics - fn get_total_usage_reward(total_usage: &NodeUsage) -> Option { - let mut total = NodeReward::default(); + ratio = Perbill::from_rational(node_usage.number_of_gets, total_nodes_usage.number_of_gets); + node_reward.gets = (ratio * total_customer_charge.gets) as u128; - total.transfer = 1; - total.storage = 2; - total.puts = 3; - total.gets = 4; - - Option::Some(total) + Some(node_reward) } - // todo: to calculate actual charge based on the metrics - fn get_customer_charge(usage: &CustomerUsage) -> Option { + fn get_customer_charge( + cluster_id: ClusterId, + usage: &CustomerUsage, + ) -> Result> { let mut total = CustomerCharge::default(); - total.transfer = 1; - total.storage = 2; - total.puts = 3; - total.gets = 4; - - Option::Some(total) + let pricing = T::ClusterVisitor::get_pricing_params(&cluster_id) + .map_err(|_| Error::::NotExpectedClusterState)?; + + total.transfer = (|| -> Option { + usage + .transferred_bytes + .checked_mul(pricing.unit_per_mb_streamed)? + .checked_div(byte_unit::MEBIBYTE) + })() + .ok_or(Error::::ArithmeticOverflow)?; + + total.storage = (|| -> Option { + usage + .stored_bytes + .checked_mul(pricing.unit_per_mb_stored)? + .checked_div(byte_unit::MEBIBYTE) + })() + .ok_or(Error::::ArithmeticOverflow)?; + + total.gets = usage + .number_of_gets + .checked_mul(pricing.unit_per_get_request) + .ok_or(Error::::ArithmeticOverflow)?; + + total.puts = usage + .number_of_puts + .checked_mul(pricing.unit_per_put_request) + .ok_or(Error::::ArithmeticOverflow)?; + + Ok(total) } fn validate_batches( @@ -646,7 +731,7 @@ pub mod pallet { bytes.extend_from_slice(&cluster_id[..]); bytes.extend_from_slice(&era.encode()); let hash = blake2_128(&bytes); - // todo: assumes AccountId is 32 bytes, which is not ideal + // todo: assumes AccountId is 32 bytes, which is not ideal -> rewrite it // "modl" + "payouts_" + hash is 28 bytes, the T::AccountId is 32 bytes, so we should be // safe from the truncation and possible collisions caused by it. The rest 4 bytes will diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index f9732f7ce..0ec6c6924 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -11,6 +11,13 @@ pub type ClusterId = H160; pub type DdcEra = u32; pub type BucketId = u64; +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq)] +pub struct ClusterPricingParams { + pub unit_per_mb_stored: u128, + pub unit_per_mb_streamed: u128, + pub unit_per_put_request: u128, + pub unit_per_get_request: u128, +} #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo, PartialEq)] pub enum NodePubKey { diff --git a/runtime/cere-dev/src/lib.rs b/runtime/cere-dev/src/lib.rs index f0274265c..dcac54c46 100644 --- a/runtime/cere-dev/src/lib.rs +++ b/runtime/cere-dev/src/lib.rs @@ -1355,8 +1355,8 @@ impl pallet_ddc_payouts::Config for Runtime { type RuntimeEvent = RuntimeEvent; type PalletId = PayoutsPalletId; type Currency = Balances; - type CustomerCharger = DdcCustomers; + type ClusterVisitor = DdcClusters; } construct_runtime!( diff --git a/traits/src/cluster.rs b/traits/src/cluster.rs index bbd21ed32..cdb3a5e21 100644 --- a/traits/src/cluster.rs +++ b/traits/src/cluster.rs @@ -1,4 +1,4 @@ -use ddc_primitives::{ClusterId, NodePubKey, NodeType}; +use ddc_primitives::{ClusterId, ClusterPricingParams, NodePubKey, NodeType}; use frame_system::Config; pub trait ClusterVisitor { @@ -11,6 +11,10 @@ pub trait ClusterVisitor { node_type: NodeType, ) -> Result; + fn get_pricing_params( + cluster_id: &ClusterId, + ) -> Result; + fn get_chill_delay( cluster_id: &ClusterId, node_type: NodeType, From fca97a3c5ab4874a26a7600becb7ecd8def317f9 Mon Sep 17 00:00:00 2001 From: Victor Genin Date: Mon, 13 Nov 2023 20:16:44 +0200 Subject: [PATCH 06/17] customer debtors --- pallets/ddc-payouts/src/lib.rs | 48 ++++++++++++++++------------------ 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/pallets/ddc-payouts/src/lib.rs b/pallets/ddc-payouts/src/lib.rs index 77a66aa45..bf1a286dc 100644 --- a/pallets/ddc-payouts/src/lib.rs +++ b/pallets/ddc-payouts/src/lib.rs @@ -183,11 +183,13 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn debtor_customers)] - pub type DebtorCustomers = StorageMap< + pub type DebtorCustomers = StorageDoubleMap< _, Blake2_128Concat, + ClusterId, + Blake2_128Concat, T::AccountId, - BoundedBTreeMap, + u128, ValueQuery, >; @@ -361,7 +363,7 @@ pub mod pallet { .checked_add(customer_charge.gets) .ok_or(Error::::ArithmeticOverflow)?; - let customer_id = payer.0; + let customer_id = payer.0.clone(); match T::CustomerCharger::charge_content_owner( customer_id.clone(), updated_billing_report.vault.clone(), @@ -385,28 +387,24 @@ pub mod pallet { }); }, Err(e) => { - // todo: save problematic charge - // todo: add logs - updated_billing_report - .charging_processed_batches - .try_insert(batch_index) - .map_err(|_| Error::::BoundedVecOverflow)?; - - /* --- - DebtorCustomers = StorageMap< - _, - Blake2_128Concat, - T::AccountId, - BoundedBTreeMap, - let mut debtor_customers = DebtorCustomers::::try_get(cluster_id.clone(), era) - .map_err(|_| Error::::BillingReportDoesNotExist)?; - - ensure!(billing_report.state == State::Initialized, Error::::NotExpectedState); - - billing_report.charging_max_batch_index = max_batch_index; - billing_report.state = State::ChargingCustomers; - ActiveBillingReports::::insert(cluster_id.clone(), era, billing_report); - --- */ + let customer_debt = BillingReportDebt { + cluster_id, + era, + batch_index, + amount: total_customer_charge, + }; + let mut customer_dept = + DebtorCustomers::::try_get(cluster_id, customer_id.clone()) + .unwrap_or(Zero::zero()); + + customer_dept = customer_dept + .checked_add(total_customer_charge) + .ok_or(Error::::ArithmeticOverflow)?; + DebtorCustomers::::insert( + cluster_id, + customer_id.clone(), + customer_dept, + ); Self::deposit_event(Event::::ChargeFailed { cluster_id, From b6c7951877286e012af5101d7902596c43476a87 Mon Sep 17 00:00:00 2001 From: Victor Genin Date: Mon, 13 Nov 2023 22:53:57 +0200 Subject: [PATCH 07/17] dprint fmt --- Cargo.toml | 34 ++++---- pallets/ddc-payouts/Cargo.toml | 18 +++- primitives/Cargo.toml | 2 +- runtime/cere-dev/Cargo.toml | 152 ++++++++++++++++----------------- traits/Cargo.toml | 2 +- 5 files changed, 110 insertions(+), 98 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index aa71105e8..aacb4cf63 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,23 +18,23 @@ substrate-build-script-utils = { version = "3.0.0", git = "https://github.com/pa [workspace] members = [ - "cli", - "node/client", - "node/service", - "rpc", - "runtime/cere", - "runtime/cere-dev", - "pallets/chainbridge", - "pallets/ddc", - "pallets/ddc-staking", - "pallets/erc721", - "pallets/erc20", - "pallets/ddc-metrics-offchain-worker", - "pallets/ddc-customers", - "pallets/ddc-nodes", - "pallets/ddc-clusters", - "pallets/ddc-payouts", - "primitives", + "cli", + "node/client", + "node/service", + "rpc", + "runtime/cere", + "runtime/cere-dev", + "pallets/chainbridge", + "pallets/ddc", + "pallets/ddc-staking", + "pallets/erc721", + "pallets/erc20", + "pallets/ddc-metrics-offchain-worker", + "pallets/ddc-customers", + "pallets/ddc-nodes", + "pallets/ddc-clusters", + "pallets/ddc-payouts", + "primitives", ] [profile.release] diff --git a/pallets/ddc-payouts/Cargo.toml b/pallets/ddc-payouts/Cargo.toml index d10c1b690..ed77fa188 100644 --- a/pallets/ddc-payouts/Cargo.toml +++ b/pallets/ddc-payouts/Cargo.toml @@ -4,6 +4,7 @@ version = "4.8.1" edition = "2021" [dependencies] +byte-unit = { version = "4.0.19", default-features = false, features = ["u128"] } codec = { package = "parity-scale-codec", version = "3.1.5", default-features = false, features = ["derive"] } ddc-primitives = { version = "0.1.0", default-features = false, path = "../../primitives" } ddc-traits = { version = "0.1.0", default-features = false, path = "../../traits" } @@ -12,12 +13,11 @@ frame-support = { version = "4.0.0-dev", default-features = false, git = "https: frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } log = { version = "0.4.17", default-features = false } scale-info = { version = "2.1.2", default-features = false, features = ["derive"] } +sp-core = { version = "6.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30", default-features = false } sp-io = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } sp-runtime = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } sp-staking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } sp-std = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } -sp-core = { version = "6.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30", default-features = false } -byte-unit = { version = "4.0.19", default-features = false, features = ["u128"] } [dev-dependencies] sp-core = { version = "6.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } @@ -26,5 +26,17 @@ substrate-test-utils = { version = "4.0.0-dev", git = "https://github.com/parity [features] default = ["std"] -std = ["codec/std", "ddc-primitives/std", "frame-support/std", "frame-system/std", "frame-benchmarking/std", "scale-info/std", "sp-io/std", "sp-runtime/std", "sp-staking/std", "sp-std/std", "sp-core/std"] +std = [ + "codec/std", + "ddc-primitives/std", + "frame-support/std", + "frame-system/std", + "frame-benchmarking/std", + "scale-info/std", + "sp-io/std", + "sp-runtime/std", + "sp-staking/std", + "sp-std/std", + "sp-core/std", +] runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index a7b80e589..3986f6b98 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] codec = { package = "parity-scale-codec", version = "3.1.5", default-features = false, features = ["derive"] } scale-info = { version = "2.1.2", default-features = false, features = ["derive"] } -serde = { version = "1.0.136", default-features = false, features = [ "derive" ], optional = true } +serde = { version = "1.0.136", default-features = false, features = ["derive"], optional = true } sp-core = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } sp-runtime = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } diff --git a/runtime/cere-dev/Cargo.toml b/runtime/cere-dev/Cargo.toml index 88c42e493..dc83eeb30 100644 --- a/runtime/cere-dev/Cargo.toml +++ b/runtime/cere-dev/Cargo.toml @@ -64,6 +64,7 @@ pallet-ddc-clusters = { version = "4.8.1", default-features = false, path = "../ pallet-ddc-customers = { version = "0.1.0", default-features = false, path = "../../pallets/ddc-customers" } pallet-ddc-metrics-offchain-worker = { version = "4.8.1", default-features = false, path = "../../pallets/ddc-metrics-offchain-worker" } pallet-ddc-nodes = { version = "4.8.1", default-features = false, path = "../../pallets/ddc-nodes" } +pallet-ddc-payouts = { version = "4.8.1", default-features = false, path = "../../pallets/ddc-payouts" } pallet-ddc-staking = { version = "4.8.1", default-features = false, path = "../../pallets/ddc-staking" } pallet-democracy = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } pallet-election-provider-multi-phase = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } @@ -100,7 +101,6 @@ pallet-transaction-payment-rpc-runtime-api = { version = "4.0.0-dev", default-fe pallet-treasury = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } pallet-utility = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } pallet-vesting = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } -pallet-ddc-payouts = { version = "4.8.1", default-features = false, path = "../../pallets/ddc-payouts" } [build-dependencies] substrate-wasm-builder = { version = "5.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } @@ -109,81 +109,81 @@ substrate-wasm-builder = { version = "5.0.0-dev", git = "https://github.com/pari default = ["std"] with-tracing = ["frame-executive/with-tracing"] std = [ - "sp-authority-discovery/std", - "pallet-authority-discovery/std", - "pallet-authorship/std", - "sp-consensus-babe/std", - "pallet-babe/std", - "pallet-bags-list/std", - "pallet-balances/std", - "pallet-bounties/std", - "sp-block-builder/std", - "codec/std", - "scale-info/std", - "pallet-collective/std", - "pallet-contracts/std", - "pallet-contracts-primitives/std", - "pallet-contracts-rpc-runtime-api/std", - "pallet-democracy/std", - "pallet-fast-unstake/std", - "pallet-elections-phragmen/std", - "frame-executive/std", - "pallet-cere-ddc/std", - "pallet-chainbridge/std", - "pallet-erc721/std", - "pallet-erc20/std", - "pallet-grandpa/std", - "pallet-im-online/std", - "pallet-indices/std", - "sp-inherents/std", - "pallet-membership/std", - "pallet-multisig/std", - "pallet-nomination-pools/std", - "pallet-nomination-pools-runtime-api/std", - "pallet-identity/std", - "pallet-scheduler/std", - "node-primitives/std", - "sp-offchain/std", - "pallet-offences/std", - "pallet-proxy/std", - "sp-core/std", - "pallet-randomness-collective-flip/std", - "sp-std/std", - "pallet-session/std", - "sp-api/std", - "sp-runtime/std", - "sp-staking/std", - "pallet-staking/std", - "sp-session/std", - "pallet-sudo/std", - "frame-support/std", - "frame-benchmarking/std", - "frame-system-rpc-runtime-api/std", - "frame-system/std", - "pallet-election-provider-multi-phase/std", - "pallet-timestamp/std", - "pallet-tips/std", - "pallet-transaction-payment-rpc-runtime-api/std", - "pallet-transaction-payment/std", - "pallet-treasury/std", - "sp-transaction-pool/std", - "pallet-utility/std", - "sp-version/std", - "pallet-society/std", - "pallet-recovery/std", - "pallet-vesting/std", - "log/std", - "frame-try-runtime/std", - "sp-io/std", - "pallet-child-bounties/std", - "pallet-ddc-metrics-offchain-worker/std", - "pallet-ddc-staking/std", - "cere-runtime-common/std", - "cere-dev-runtime-constants/std", - "pallet-ddc-customers/std", - "pallet-ddc-nodes/std", - "pallet-ddc-clusters/std", - "pallet-ddc-payouts/std", + "sp-authority-discovery/std", + "pallet-authority-discovery/std", + "pallet-authorship/std", + "sp-consensus-babe/std", + "pallet-babe/std", + "pallet-bags-list/std", + "pallet-balances/std", + "pallet-bounties/std", + "sp-block-builder/std", + "codec/std", + "scale-info/std", + "pallet-collective/std", + "pallet-contracts/std", + "pallet-contracts-primitives/std", + "pallet-contracts-rpc-runtime-api/std", + "pallet-democracy/std", + "pallet-fast-unstake/std", + "pallet-elections-phragmen/std", + "frame-executive/std", + "pallet-cere-ddc/std", + "pallet-chainbridge/std", + "pallet-erc721/std", + "pallet-erc20/std", + "pallet-grandpa/std", + "pallet-im-online/std", + "pallet-indices/std", + "sp-inherents/std", + "pallet-membership/std", + "pallet-multisig/std", + "pallet-nomination-pools/std", + "pallet-nomination-pools-runtime-api/std", + "pallet-identity/std", + "pallet-scheduler/std", + "node-primitives/std", + "sp-offchain/std", + "pallet-offences/std", + "pallet-proxy/std", + "sp-core/std", + "pallet-randomness-collective-flip/std", + "sp-std/std", + "pallet-session/std", + "sp-api/std", + "sp-runtime/std", + "sp-staking/std", + "pallet-staking/std", + "sp-session/std", + "pallet-sudo/std", + "frame-support/std", + "frame-benchmarking/std", + "frame-system-rpc-runtime-api/std", + "frame-system/std", + "pallet-election-provider-multi-phase/std", + "pallet-timestamp/std", + "pallet-tips/std", + "pallet-transaction-payment-rpc-runtime-api/std", + "pallet-transaction-payment/std", + "pallet-treasury/std", + "sp-transaction-pool/std", + "pallet-utility/std", + "sp-version/std", + "pallet-society/std", + "pallet-recovery/std", + "pallet-vesting/std", + "log/std", + "frame-try-runtime/std", + "sp-io/std", + "pallet-child-bounties/std", + "pallet-ddc-metrics-offchain-worker/std", + "pallet-ddc-staking/std", + "cere-runtime-common/std", + "cere-dev-runtime-constants/std", + "pallet-ddc-customers/std", + "pallet-ddc-nodes/std", + "pallet-ddc-clusters/std", + "pallet-ddc-payouts/std", ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", diff --git a/traits/Cargo.toml b/traits/Cargo.toml index aa4110332..21512a39f 100644 --- a/traits/Cargo.toml +++ b/traits/Cargo.toml @@ -5,5 +5,5 @@ edition = "2021" [dependencies] ddc-primitives = { version = "0.1.0", default-features = false, path = "../primitives" } -sp-runtime = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } +sp-runtime = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30" } From dd4eb362134198dd68e42d7e09a41c048aad1114 Mon Sep 17 00:00:00 2001 From: Victor Genin Date: Tue, 14 Nov 2023 01:54:40 +0200 Subject: [PATCH 08/17] clippy --- pallets/ddc-customers/src/lib.rs | 2 +- pallets/ddc-payouts/src/lib.rs | 66 +++++++++++++++----------------- pallets/ddc-staking/src/mock.rs | 13 ++++++- 3 files changed, 43 insertions(+), 38 deletions(-) diff --git a/pallets/ddc-customers/src/lib.rs b/pallets/ddc-customers/src/lib.rs index 94255b20c..2454eae19 100644 --- a/pallets/ddc-customers/src/lib.rs +++ b/pallets/ddc-customers/src/lib.rs @@ -459,7 +459,7 @@ pub mod pallet { ::Currency::transfer( &account_id, &owner, - value.clone(), + value, ExistenceRequirement::KeepAlive, )?; Self::deposit_event(Event::::Withdrawn(owner, value)); diff --git a/pallets/ddc-payouts/src/lib.rs b/pallets/ddc-payouts/src/lib.rs index bf1a286dc..60cc3ab75 100644 --- a/pallets/ddc-payouts/src/lib.rs +++ b/pallets/ddc-payouts/src/lib.rs @@ -15,13 +15,13 @@ #![recursion_limit = "256"] use ddc_primitives::{ClusterId, DdcEra}; -use ddc_traits::{cluster::ClusterVisitor, customer::CustomerCharger}; +use ddc_traits::{cluster::ClusterVisitor, customer::CustomerCharger as ICustomerCharger}; use frame_support::{ pallet_prelude::*, parameter_types, sp_runtime::SaturatedConversion, traits::{Currency, ExistenceRequirement, LockableCurrency}, - BoundedBTreeMap, BoundedBTreeSet, + BoundedBTreeSet, }; use frame_system::pallet_prelude::*; pub use pallet::*; @@ -98,7 +98,7 @@ pub mod pallet { type Currency: LockableCurrency; - type CustomerCharger: CustomerCharger; + type CustomerCharger: ICustomerCharger; type ClusterVisitor: ClusterVisitor; } @@ -254,14 +254,18 @@ pub mod pallet { ); ensure!( - ActiveBillingReports::::try_get(cluster_id.clone(), era).is_ok() == false, + ActiveBillingReports::::try_get(cluster_id, era).is_err(), Error::::NotExpectedState ); - let mut billing_report = BillingReport::default(); - billing_report.vault = Self::sub_account_id(cluster_id.clone(), era); + let mut billing_report = BillingReport:: { + vault: Self::sub_account_id(cluster_id, era), + state: State::Initialized, + ..Default::default() + }; + billing_report.vault = Self::sub_account_id(cluster_id, era); billing_report.state = State::Initialized; - ActiveBillingReports::::insert(cluster_id.clone(), era, billing_report); + ActiveBillingReports::::insert(cluster_id, era, billing_report); Self::deposit_event(Event::::BillingReportInitialized { cluster_id, era }); @@ -286,14 +290,14 @@ pub mod pallet { Error::::BatchIndexOverflow ); - let mut billing_report = ActiveBillingReports::::try_get(cluster_id.clone(), era) + let mut billing_report = ActiveBillingReports::::try_get(cluster_id, era) .map_err(|_| Error::::BillingReportDoesNotExist)?; ensure!(billing_report.state == State::Initialized, Error::::NotExpectedState); billing_report.charging_max_batch_index = max_batch_index; billing_report.state = State::ChargingCustomers; - ActiveBillingReports::::insert(cluster_id.clone(), era, billing_report); + ActiveBillingReports::::insert(cluster_id, era, billing_report); Self::deposit_event(Event::::ChargingStarted { cluster_id, era }); @@ -314,7 +318,7 @@ pub mod pallet { Error::::Unauthorised ); - let billing_report = ActiveBillingReports::::try_get(cluster_id.clone(), era) + let billing_report = ActiveBillingReports::::try_get(cluster_id, era) .map_err(|_| Error::::BillingReportDoesNotExist)?; ensure!(billing_report.state == State::ChargingCustomers, Error::::NotExpectedState); @@ -327,7 +331,7 @@ pub mod pallet { Error::::BatchIndexAlreadyProcessed ); - let mut updated_billing_report = billing_report.clone(); + let mut updated_billing_report = billing_report; for payer in payers { let customer_charge = get_customer_charge::(cluster_id, &payer.1)?; let total_customer_charge = (|| -> Option { @@ -386,16 +390,10 @@ pub mod pallet { amount: total_customer_charge, }); }, - Err(e) => { - let customer_debt = BillingReportDebt { - cluster_id, - era, - batch_index, - amount: total_customer_charge, - }; + Err(_e) => { let mut customer_dept = DebtorCustomers::::try_get(cluster_id, customer_id.clone()) - .unwrap_or(Zero::zero()); + .unwrap_or_else(|_| Zero::zero()); customer_dept = customer_dept .checked_add(total_customer_charge) @@ -438,7 +436,7 @@ pub mod pallet { Error::::Unauthorised ); - let mut billing_report = ActiveBillingReports::::try_get(cluster_id.clone(), era) + let mut billing_report = ActiveBillingReports::::try_get(cluster_id, era) .map_err(|_| Error::::BillingReportDoesNotExist)?; ensure!(billing_report.state == State::ChargingCustomers, Error::::NotExpectedState); @@ -448,7 +446,7 @@ pub mod pallet { )?; billing_report.state = State::CustomersCharged; - ActiveBillingReports::::insert(cluster_id.clone(), era, billing_report); + ActiveBillingReports::::insert(cluster_id, era, billing_report); Self::deposit_event(Event::::ChargingFinished { cluster_id, era }); @@ -474,7 +472,7 @@ pub mod pallet { Error::::BatchIndexOverflow ); - let mut billing_report = ActiveBillingReports::::try_get(cluster_id.clone(), era) + let mut billing_report = ActiveBillingReports::::try_get(cluster_id, era) .map_err(|_| Error::::BillingReportDoesNotExist)?; ensure!(billing_report.state == State::CustomersCharged, Error::::NotExpectedState); @@ -482,7 +480,7 @@ pub mod pallet { billing_report.total_node_usage = total_node_usage; billing_report.rewarding_max_batch_index = max_batch_index; billing_report.state = State::RewardingProviders; - ActiveBillingReports::::insert(cluster_id.clone(), era, billing_report); + ActiveBillingReports::::insert(cluster_id, era, billing_report); Self::deposit_event(Event::::RewardingStarted { cluster_id, era }); @@ -503,7 +501,7 @@ pub mod pallet { Error::::Unauthorised ); - let billing_report = ActiveBillingReports::::try_get(cluster_id.clone(), era) + let billing_report = ActiveBillingReports::::try_get(cluster_id, era) .map_err(|_| Error::::BillingReportDoesNotExist)?; ensure!( @@ -581,7 +579,7 @@ pub mod pallet { Error::::Unauthorised ); - let mut billing_report = ActiveBillingReports::::try_get(cluster_id.clone(), era) + let mut billing_report = ActiveBillingReports::::try_get(cluster_id, era) .map_err(|_| Error::::BillingReportDoesNotExist)?; ensure!( @@ -595,7 +593,7 @@ pub mod pallet { )?; billing_report.state = State::ProvidersRewarded; - ActiveBillingReports::::insert(cluster_id.clone(), era, billing_report); + ActiveBillingReports::::insert(cluster_id, era, billing_report); Self::deposit_event(Event::::RewardingFinished { cluster_id, era }); @@ -614,7 +612,7 @@ pub mod pallet { Error::::Unauthorised ); - let billing_report = ActiveBillingReports::::try_get(cluster_id.clone(), era) + let billing_report = ActiveBillingReports::::try_get(cluster_id, era) .map_err(|_| Error::::BillingReportDoesNotExist)?; ensure!(billing_report.state == State::ProvidersRewarded, Error::::NotExpectedState); @@ -633,7 +631,7 @@ pub mod pallet { Error::::NotDistributedBalance ); - ActiveBillingReports::::remove(cluster_id.clone(), era); + ActiveBillingReports::::remove(cluster_id, era); Self::deposit_event(Event::::BillingReportFinalized { cluster_id, era }); Ok(()) @@ -651,16 +649,16 @@ pub mod pallet { node_usage.transferred_bytes, total_nodes_usage.transferred_bytes, ); - node_reward.transfer = (ratio * total_customer_charge.transfer) as u128; + node_reward.transfer = ratio * total_customer_charge.transfer; ratio = Perbill::from_rational(node_usage.stored_bytes, total_nodes_usage.stored_bytes); - node_reward.storage = (ratio * total_customer_charge.storage) as u128; + node_reward.storage = ratio * total_customer_charge.storage; ratio = Perbill::from_rational(node_usage.number_of_puts, total_nodes_usage.number_of_puts); - node_reward.puts = (ratio * total_customer_charge.puts) as u128; + node_reward.puts = ratio * total_customer_charge.puts; ratio = Perbill::from_rational(node_usage.number_of_gets, total_nodes_usage.number_of_gets); - node_reward.gets = (ratio * total_customer_charge.gets) as u128; + node_reward.gets = ratio * total_customer_charge.gets; Some(node_reward) } @@ -720,10 +718,6 @@ pub mod pallet { } impl Pallet { - fn account_id() -> T::AccountId { - T::PalletId::get().into_account_truncating() - } - fn sub_account_id(cluster_id: ClusterId, era: DdcEra) -> T::AccountId { let mut bytes = Vec::new(); bytes.extend_from_slice(&cluster_id[..]); diff --git a/pallets/ddc-staking/src/mock.rs b/pallets/ddc-staking/src/mock.rs index 549653b92..a047f30c1 100644 --- a/pallets/ddc-staking/src/mock.rs +++ b/pallets/ddc-staking/src/mock.rs @@ -3,7 +3,7 @@ #![allow(dead_code)] use crate::{self as pallet_ddc_staking, *}; -use ddc_primitives::{CDNNodePubKey, StorageNodePubKey}; +use ddc_primitives::{CDNNodePubKey, ClusterPricingParams, StorageNodePubKey}; use ddc_traits::{ cluster::{ClusterVisitor, ClusterVisitorError}, node::{NodeVisitor, NodeVisitorError}, @@ -131,6 +131,17 @@ impl ClusterVisitor for TestClusterVisitor { ) -> Result { Ok(T::BlockNumber::from(10u32)) } + + fn get_pricing_params( + _cluster_id: &ClusterId, + ) -> Result { + Ok(ClusterPricingParams { + unit_per_mb_stored: 2, + unit_per_mb_streamed: 3, + unit_per_put_request: 4, + unit_per_get_request: 5, + }) + } } pub struct TestNodeVisitor; From fbe764a696747651d453fd8126c7f366769c2521 Mon Sep 17 00:00:00 2001 From: Victor Genin Date: Tue, 14 Nov 2023 19:30:24 +0200 Subject: [PATCH 09/17] cluster payment refactoring --- pallets/ddc-clusters/src/cluster.rs | 7 +++++-- pallets/ddc-clusters/src/lib.rs | 7 ++++++- pallets/ddc-customers/src/lib.rs | 2 +- pallets/ddc-payouts/src/lib.rs | 1 + 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/pallets/ddc-clusters/src/cluster.rs b/pallets/ddc-clusters/src/cluster.rs index 7fc6e07e4..4be19d73f 100644 --- a/pallets/ddc-clusters/src/cluster.rs +++ b/pallets/ddc-clusters/src/cluster.rs @@ -1,6 +1,6 @@ use crate::pallet::Error; use codec::{Decode, Encode}; -use ddc_primitives::{ClusterId, ClusterPricingParams}; +use ddc_primitives::ClusterId; use frame_support::{pallet_prelude::*, parameter_types}; use scale_info::TypeInfo; use sp_runtime::Perbill; @@ -41,7 +41,10 @@ pub struct ClusterGovParams { pub storage_bond_size: Balance, pub storage_chill_delay: BlockNumber, pub storage_unbonding_delay: BlockNumber, - pub pricing: ClusterPricingParams, + pub unit_per_mb_stored: u128, + pub unit_per_mb_streamed: u128, + pub unit_per_put_request: u128, + pub unit_per_get_request: u128, } impl Cluster { diff --git a/pallets/ddc-clusters/src/lib.rs b/pallets/ddc-clusters/src/lib.rs index 121640d84..a8cbf3535 100644 --- a/pallets/ddc-clusters/src/lib.rs +++ b/pallets/ddc-clusters/src/lib.rs @@ -271,7 +271,12 @@ pub mod pallet { ) -> Result { let cluster_gov_params = ClustersGovParams::::try_get(cluster_id) .map_err(|_| ClusterVisitorError::ClusterGovParamsNotSet)?; - Ok(cluster_gov_params.pricing) + Ok(ClusterPricingParams { + unit_per_mb_stored: cluster_gov_params.unit_per_mb_stored, + unit_per_mb_streamed: cluster_gov_params.unit_per_mb_streamed, + unit_per_put_request: cluster_gov_params.unit_per_put_request, + unit_per_get_request: cluster_gov_params.unit_per_get_request, + }) } fn get_chill_delay( diff --git a/pallets/ddc-customers/src/lib.rs b/pallets/ddc-customers/src/lib.rs index 2454eae19..30a2b9d36 100644 --- a/pallets/ddc-customers/src/lib.rs +++ b/pallets/ddc-customers/src/lib.rs @@ -200,7 +200,7 @@ pub mod pallet { /// An account has called `withdraw_unlocked_deposit` and removed unlocking chunks worth /// `Balance` from the unlocking queue. \[owner, amount\] Withdrawn(T::AccountId, BalanceOf), - /// The acconut has been charged for the usage + /// The account has been charged for the usage Charged(T::AccountId, BalanceOf), /// Bucket with specific id created BucketCreated(BucketId), diff --git a/pallets/ddc-payouts/src/lib.rs b/pallets/ddc-payouts/src/lib.rs index 60cc3ab75..bc8aa5d50 100644 --- a/pallets/ddc-payouts/src/lib.rs +++ b/pallets/ddc-payouts/src/lib.rs @@ -234,6 +234,7 @@ pub mod pallet { Initialized, ChargingCustomers, CustomersCharged, + DeductingFees, RewardingProviders, ProvidersRewarded, Finalized, From 94ff242d1ecd00ee7270715113c21405d99facf4 Mon Sep 17 00:00:00 2001 From: yahortsaryk Date: Tue, 14 Nov 2023 19:25:21 +0100 Subject: [PATCH 10/17] chore: runtime version for 'cere_dev' is upgraded --- runtime/cere-dev/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/cere-dev/src/lib.rs b/runtime/cere-dev/src/lib.rs index 2e4d8e1a0..2aeb530df 100644 --- a/runtime/cere-dev/src/lib.rs +++ b/runtime/cere-dev/src/lib.rs @@ -130,7 +130,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 48014, + spec_version: 48015, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 5, From b176f405adae334846bbc56d921c63d98bc0b097 Mon Sep 17 00:00:00 2001 From: Victor Genin Date: Wed, 15 Nov 2023 11:07:45 +0200 Subject: [PATCH 11/17] authorise account change --- pallets/ddc-customers/src/lib.rs | 4 --- pallets/ddc-payouts/src/lib.rs | 57 ++++++++++++-------------------- 2 files changed, 21 insertions(+), 40 deletions(-) diff --git a/pallets/ddc-customers/src/lib.rs b/pallets/ddc-customers/src/lib.rs index 30a2b9d36..058799a9f 100644 --- a/pallets/ddc-customers/src/lib.rs +++ b/pallets/ddc-customers/src/lib.rs @@ -172,10 +172,6 @@ pub mod pallet { 0 } - #[pallet::storage] - #[pallet::getter(fn dac_account)] - pub type DACAccount = StorageValue<_, T::AccountId>; - #[pallet::storage] #[pallet::getter(fn buckets_count)] pub type BucketsCount = diff --git a/pallets/ddc-payouts/src/lib.rs b/pallets/ddc-payouts/src/lib.rs index bc8aa5d50..c3365fcc4 100644 --- a/pallets/ddc-payouts/src/lib.rs +++ b/pallets/ddc-payouts/src/lib.rs @@ -179,7 +179,7 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn authorised_caller)] - pub type DACAccount = StorageValue<_, T::AccountId>; + pub type AuthorisedCaller = StorageValue<_, T::AccountId>; #[pallet::storage] #[pallet::getter(fn debtor_customers)] @@ -198,7 +198,6 @@ pub mod pallet { pub struct BillingReport { state: State, vault: T::AccountId, - authorised_caller: Option, total_customer_charge: CustomerCharge, total_distributed_reward: u128, total_node_usage: NodeUsage, @@ -215,7 +214,6 @@ pub mod pallet { Self { state: State::default(), vault: T::PalletId::get().into_account_truncating(), - authorised_caller: Option::None, total_customer_charge: CustomerCharge::default(), total_distributed_reward: Zero::zero(), total_node_usage: NodeUsage::default(), @@ -242,6 +240,18 @@ pub mod pallet { #[pallet::call] impl Pallet { + #[pallet::weight(10_000)] + pub fn set_authorised_caller( + origin: OriginFor, + authorised_caller: T::AccountId, + ) -> DispatchResult { + ensure_root(origin)?; // requires Governance approval + + AuthorisedCaller::::put(authorised_caller); + + Ok(()) + } + #[pallet::weight(10_000)] pub fn begin_billing_report( origin: OriginFor, @@ -249,10 +259,7 @@ pub mod pallet { era: DdcEra, ) -> DispatchResult { let caller = ensure_signed(origin)?; - ensure!( - Self::authorised_caller().ok_or(Error::::Unauthorised)? == caller, - Error::::Unauthorised - ); + ensure!(Self::authorised_caller() == Some(caller), Error::::Unauthorised); ensure!( ActiveBillingReports::::try_get(cluster_id, era).is_err(), @@ -281,10 +288,7 @@ pub mod pallet { max_batch_index: BatchIndex, ) -> DispatchResult { let caller = ensure_signed(origin)?; - ensure!( - Self::authorised_caller().ok_or(Error::::Unauthorised)? == caller, - Error::::Unauthorised - ); + ensure!(Self::authorised_caller() == Some(caller), Error::::Unauthorised); ensure!( max_batch_index > 0 && max_batch_index < MaxBatchesCount::get(), @@ -314,10 +318,7 @@ pub mod pallet { payers: Vec<(T::AccountId, CustomerUsage)>, ) -> DispatchResult { let caller = ensure_signed(origin)?; - ensure!( - Self::authorised_caller().ok_or(Error::::Unauthorised)? == caller, - Error::::Unauthorised - ); + ensure!(Self::authorised_caller() == Some(caller), Error::::Unauthorised); let billing_report = ActiveBillingReports::::try_get(cluster_id, era) .map_err(|_| Error::::BillingReportDoesNotExist)?; @@ -432,10 +433,7 @@ pub mod pallet { era: DdcEra, ) -> DispatchResult { let caller = ensure_signed(origin)?; - ensure!( - Self::authorised_caller().ok_or(Error::::Unauthorised)? == caller, - Error::::Unauthorised - ); + ensure!(Self::authorised_caller() == Some(caller), Error::::Unauthorised); let mut billing_report = ActiveBillingReports::::try_get(cluster_id, era) .map_err(|_| Error::::BillingReportDoesNotExist)?; @@ -463,10 +461,7 @@ pub mod pallet { total_node_usage: NodeUsage, ) -> DispatchResult { let caller = ensure_signed(origin)?; - ensure!( - Self::authorised_caller().ok_or(Error::::Unauthorised)? == caller, - Error::::Unauthorised - ); + ensure!(Self::authorised_caller() == Some(caller), Error::::Unauthorised); ensure!( max_batch_index > 0 && max_batch_index < MaxBatchesCount::get(), @@ -497,10 +492,7 @@ pub mod pallet { payees: Vec<(T::AccountId, NodeUsage)>, ) -> DispatchResult { let caller = ensure_signed(origin)?; - ensure!( - Self::authorised_caller().ok_or(Error::::Unauthorised)? == caller, - Error::::Unauthorised - ); + ensure!(Self::authorised_caller() == Some(caller), Error::::Unauthorised); let billing_report = ActiveBillingReports::::try_get(cluster_id, era) .map_err(|_| Error::::BillingReportDoesNotExist)?; @@ -575,10 +567,7 @@ pub mod pallet { era: DdcEra, ) -> DispatchResult { let caller = ensure_signed(origin)?; - ensure!( - Self::authorised_caller().ok_or(Error::::Unauthorised)? == caller, - Error::::Unauthorised - ); + ensure!(Self::authorised_caller() == Some(caller), Error::::Unauthorised); let mut billing_report = ActiveBillingReports::::try_get(cluster_id, era) .map_err(|_| Error::::BillingReportDoesNotExist)?; @@ -608,10 +597,7 @@ pub mod pallet { era: DdcEra, ) -> DispatchResult { let caller = ensure_signed(origin)?; - ensure!( - Self::authorised_caller().ok_or(Error::::Unauthorised)? == caller, - Error::::Unauthorised - ); + ensure!(Self::authorised_caller() == Some(caller), Error::::Unauthorised); let billing_report = ActiveBillingReports::::try_get(cluster_id, era) .map_err(|_| Error::::BillingReportDoesNotExist)?; @@ -724,7 +710,6 @@ pub mod pallet { bytes.extend_from_slice(&cluster_id[..]); bytes.extend_from_slice(&era.encode()); let hash = blake2_128(&bytes); - // todo: assumes AccountId is 32 bytes, which is not ideal -> rewrite it // "modl" + "payouts_" + hash is 28 bytes, the T::AccountId is 32 bytes, so we should be // safe from the truncation and possible collisions caused by it. The rest 4 bytes will From a476914cd2f32962cdcba7327fc088e339a33c03 Mon Sep 17 00:00:00 2001 From: Victor Genin Date: Wed, 15 Nov 2023 17:04:33 +0200 Subject: [PATCH 12/17] code cleanup --- pallets/ddc-customers/src/lib.rs | 73 ++++++++++++++++++++++---------- pallets/ddc-payouts/src/lib.rs | 25 ++++++----- pallets/ddc-staking/src/lib.rs | 17 ++++++-- 3 files changed, 79 insertions(+), 36 deletions(-) diff --git a/pallets/ddc-customers/src/lib.rs b/pallets/ddc-customers/src/lib.rs index 058799a9f..fb4353f35 100644 --- a/pallets/ddc-customers/src/lib.rs +++ b/pallets/ddc-customers/src/lib.rs @@ -12,7 +12,7 @@ use frame_support::{ }; use scale_info::TypeInfo; use sp_runtime::{ - traits::{AccountIdConversion, AtLeast32BitUnsigned, Saturating, Zero}, + traits::{AccountIdConversion, AtLeast32BitUnsigned, CheckedSub, Saturating, Zero, CheckedAdd}, RuntimeDebug, SaturatedConversion, }; use sp_std::prelude::*; @@ -112,20 +112,28 @@ impl< /// Charge funds that were scheduled for unlocking. /// /// Returns the updated ledger, and the amount actually charged. - fn charge_unlocking(mut self, value: Balance) -> (Self, Balance) { + fn charge_unlocking(mut self, value: Balance) -> Result<(Self, Balance), Error> { let mut unlocking_balance = Balance::zero(); while let Some(last) = self.unlocking.last_mut() { - if unlocking_balance + last.value <= value { - unlocking_balance += last.value; - self.active -= last.value; + let temp = unlocking_balance + .checked_add(&last.value) + .ok_or(Error::::ArithmeticOverflow)?; + if temp <= value { + unlocking_balance = temp; + self.active = + self.active.checked_sub(&last.value).ok_or(Error::::ArithmeticUnderflow)?; self.unlocking.pop(); } else { - let diff = value - unlocking_balance; - - unlocking_balance += diff; - self.active -= diff; - last.value -= diff; + let diff = + value.checked_sub(&unlocking_balance).ok_or(Error::::ArithmeticUnderflow)?; + + unlocking_balance = + unlocking_balance.checked_add(&diff).ok_or(Error::::ArithmeticOverflow)?; + self.active = + self.active.checked_sub(&diff).ok_or(Error::::ArithmeticUnderflow)?; + last.value = + last.value.checked_sub(&diff).ok_or(Error::::ArithmeticUnderflow)?; } if unlocking_balance >= value { @@ -133,7 +141,7 @@ impl< } } - (self, unlocking_balance) + Ok((self, unlocking_balance)) } } @@ -224,6 +232,8 @@ pub mod pallet { ClusterDoesNotExist, // unauthorised operation Unauthorised, + // Arithmetic overflow + ArithmeticOverflow, // Arithmetic underflow ArithmeticUnderflow, } @@ -257,7 +267,8 @@ pub mod pallet { #[pallet::weight(10_000)] pub fn create_bucket(origin: OriginFor, cluster_id: ClusterId) -> DispatchResult { let bucket_owner = ensure_signed(origin)?; - let cur_bucket_id = Self::buckets_count() + 1; + let cur_bucket_id = + Self::buckets_count().checked_add(1).ok_or(Error::::ArithmeticOverflow)?; ::ClusterVisitor::ensure_cluster(&cluster_id) .map_err(|_| Error::::ClusterDoesNotExist)?; @@ -328,8 +339,11 @@ pub mod pallet { let owner_balance = ::Currency::free_balance(&owner); let extra = owner_balance.min(max_additional); - ledger.total += extra; - ledger.active += extra; + ledger.total = + ledger.total.checked_add(&extra).ok_or(Error::::ArithmeticOverflow)?; + ledger.active = + ledger.active.checked_add(&extra).ok_or(Error::::ArithmeticOverflow)?; + // Last check: the new active amount of ledger must be more than ED. ensure!( ledger.active >= ::Currency::minimum_balance(), @@ -374,16 +388,19 @@ pub mod pallet { let mut value = value.min(ledger.active); if !value.is_zero() { - ledger.active -= value; + ledger.active = + ledger.active.checked_sub(&value).ok_or(Error::::ArithmeticUnderflow)?; // Avoid there being a dust balance left in the accounts system. if ledger.active < ::Currency::minimum_balance() { - value += ledger.active; + value = + value.checked_add(&ledger.active).ok_or(Error::::ArithmeticOverflow)?; ledger.active = Zero::zero(); } let current_block = >::block_number(); // Note: locking for extra block to allow for accounting + // block + configurable value - shouldn't overflow let block = current_block + ::UnlockingDelay::get(); if let Some(chunk) = @@ -448,7 +465,8 @@ pub mod pallet { if ledger.total < old_total { log::debug!("Preparing for transfer"); // Already checked that this won't overflow by entry condition. - let value = old_total - ledger.total; + let value = + old_total.checked_sub(&ledger.total).ok_or(Error::::ArithmeticUnderflow)?; let account_id = Self::account_id(); @@ -523,15 +541,26 @@ pub mod pallet { ensure!(ledger.total >= ledger.active, Error::::ArithmeticUnderflow); if ledger.active >= amount_to_deduct { - ledger.active -= amount_to_deduct; - ledger.total -= amount_to_deduct; + ledger.active = ledger + .active + .checked_sub(&amount_to_deduct) + .ok_or(Error::::ArithmeticUnderflow)?; + ledger.total = ledger + .total + .checked_sub(&amount_to_deduct) + .ok_or(Error::::ArithmeticUnderflow)?; Self::update_ledger(&content_owner, &ledger); } else { - let diff = amount_to_deduct - ledger.active; - ledger.total -= ledger.active; + let diff = amount_to_deduct + .checked_sub(&ledger.active) + .ok_or(Error::::ArithmeticUnderflow)?; + ledger.total = ledger + .total + .checked_sub(&ledger.active) + .ok_or(Error::::ArithmeticUnderflow)?; amount_to_deduct = ledger.active; ledger.active = BalanceOf::::zero(); - let (ledger, _charged) = ledger.charge_unlocking(diff); + let (ledger, _charged) = ledger.charge_unlocking(diff)?; Self::update_ledger(&content_owner, &ledger); }; diff --git a/pallets/ddc-payouts/src/lib.rs b/pallets/ddc-payouts/src/lib.rs index c3365fcc4..8143622bb 100644 --- a/pallets/ddc-payouts/src/lib.rs +++ b/pallets/ddc-payouts/src/lib.rs @@ -15,7 +15,7 @@ #![recursion_limit = "256"] use ddc_primitives::{ClusterId, DdcEra}; -use ddc_traits::{cluster::ClusterVisitor, customer::CustomerCharger as ICustomerCharger}; +use ddc_traits::{cluster::ClusterVisitor, customer::CustomerCharger as CustomerChargerType}; use frame_support::{ pallet_prelude::*, parameter_types, @@ -30,6 +30,7 @@ use sp_std::prelude::*; type BatchIndex = u16; +/// Stores usage of customers #[derive(PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Default, Clone)] pub struct CustomerUsage { pub transferred_bytes: u128, @@ -38,6 +39,7 @@ pub struct CustomerUsage { pub number_of_gets: u128, } +/// Stores usage of node provider #[derive(PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Default, Clone)] pub struct NodeUsage { pub transferred_bytes: u128, @@ -46,12 +48,13 @@ pub struct NodeUsage { pub number_of_gets: u128, } +/// Stores reward in tokens(units) of node provider as per NodeUsage #[derive(PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Default, Clone)] pub struct NodeReward { - pub transfer: u128, - pub storage: u128, - pub puts: u128, - pub gets: u128, + pub transfer: u128, // for transferred_bytes + pub storage: u128, // for stored_bytes + pub puts: u128, // for number_of_puts + pub gets: u128, // for number_of_gets } #[derive(PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Default, Clone)] @@ -62,12 +65,13 @@ pub struct BillingReportDebt { pub amount: u128, } +/// Stores charge in tokens(units) of customer as per CustomerUsage #[derive(PartialEq, Encode, Decode, RuntimeDebug, TypeInfo, Default, Clone)] pub struct CustomerCharge { - pub transfer: u128, - pub storage: u128, - pub puts: u128, - pub gets: u128, + pub transfer: u128, // for transferred_bytes + pub storage: u128, // for stored_bytes + pub puts: u128, // for number_of_puts + pub gets: u128, // for number_of_gets } /// The balance type of this pallet. @@ -98,7 +102,7 @@ pub mod pallet { type Currency: LockableCurrency; - type CustomerCharger: ICustomerCharger; + type CustomerCharger: CustomerChargerType; type ClusterVisitor: ClusterVisitor; } @@ -636,6 +640,7 @@ pub mod pallet { node_usage.transferred_bytes, total_nodes_usage.transferred_bytes, ); + // ratio multiplied by X will be > 0, < X no overflow node_reward.transfer = ratio * total_customer_charge.transfer; ratio = Perbill::from_rational(node_usage.stored_bytes, total_nodes_usage.stored_bytes); diff --git a/pallets/ddc-staking/src/lib.rs b/pallets/ddc-staking/src/lib.rs index 005b39c8d..2e977dd1d 100644 --- a/pallets/ddc-staking/src/lib.rs +++ b/pallets/ddc-staking/src/lib.rs @@ -46,7 +46,7 @@ use frame_support::{ use frame_system::pallet_prelude::*; use scale_info::TypeInfo; use sp_runtime::{ - traits::{AtLeast32BitUnsigned, Saturating, StaticLookup, Zero}, + traits::{AtLeast32BitUnsigned, CheckedAdd, CheckedSub, Saturating, StaticLookup, Zero}, RuntimeDebug, SaturatedConversion, }; use sp_std::prelude::*; @@ -310,6 +310,10 @@ pub mod pallet { ServingProhibited, /// Storing operation is called for non-Storage node StoringProhibited, + /// Arithmetic overflow occurred + ArithmeticOverflow, + /// Arithmetic underflow occurred + ArithmeticUnderflow, } #[pallet::call] @@ -408,11 +412,13 @@ pub mod pallet { let mut value = value.min(ledger.active); if !value.is_zero() { - ledger.active -= value; + ledger.active = + ledger.active.checked_sub(&value).ok_or(Error::::ArithmeticUnderflow)?; // Avoid there being a dust balance left in the staking system. if ledger.active < T::Currency::minimum_balance() { - value += ledger.active; + value = + value.checked_add(&ledger.active).ok_or(Error::::ArithmeticOverflow)?; ledger.active = Zero::zero(); } @@ -461,6 +467,7 @@ pub mod pallet { } }; + // block number + configuration -> no overflow let block = >::block_number() + unbonding_delay_in_blocks; if let Some(chunk) = ledger.unlocking.last_mut().filter(|chunk| chunk.block == block) @@ -517,7 +524,8 @@ pub mod pallet { // `consolidate_unlocked` strictly subtracts balance. if ledger.total < old_total { // Already checked that this won't overflow by entry condition. - let value = old_total - ledger.total; + let value = + old_total.checked_sub(&ledger.total).ok_or(Error::::ArithmeticUnderflow)?; Self::deposit_event(Event::::Withdrawn(stash, value)); } @@ -753,6 +761,7 @@ pub mod pallet { let is_cluster_node = T::ClusterVisitor::cluster_has_node(&cluster_id, &node_pub_key); ensure!(!is_cluster_node, Error::::FastChillProhibited); + // block number + 1 => no overflow let can_chill_from = >::block_number() + T::BlockNumber::from(1u32); Self::chill_stash_soon(&stash, &controller, cluster_id, can_chill_from); From c78667cff26033f8c00c75fd2acd7a9960a72c7f Mon Sep 17 00:00:00 2001 From: Victor Genin Date: Wed, 15 Nov 2023 17:10:55 +0200 Subject: [PATCH 13/17] formattign --- pallets/ddc-customers/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/ddc-customers/src/lib.rs b/pallets/ddc-customers/src/lib.rs index fb4353f35..8c06fbef9 100644 --- a/pallets/ddc-customers/src/lib.rs +++ b/pallets/ddc-customers/src/lib.rs @@ -12,7 +12,7 @@ use frame_support::{ }; use scale_info::TypeInfo; use sp_runtime::{ - traits::{AccountIdConversion, AtLeast32BitUnsigned, CheckedSub, Saturating, Zero, CheckedAdd}, + traits::{AccountIdConversion, AtLeast32BitUnsigned, CheckedAdd, CheckedSub, Saturating, Zero}, RuntimeDebug, SaturatedConversion, }; use sp_std::prelude::*; From a109f38c85134dd1f98c2eb6447f612d7481a9ca Mon Sep 17 00:00:00 2001 From: Victor Genin Date: Thu, 16 Nov 2023 13:45:09 +0200 Subject: [PATCH 14/17] add missing mocks --- pallets/ddc-customers/src/mock.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pallets/ddc-customers/src/mock.rs b/pallets/ddc-customers/src/mock.rs index ae07269b8..025f76fa4 100644 --- a/pallets/ddc-customers/src/mock.rs +++ b/pallets/ddc-customers/src/mock.rs @@ -128,6 +128,17 @@ impl ClusterVisitor for TestClusterVisitor { ) -> Result { Ok(T::BlockNumber::from(10u32)) } + + fn get_pricing_params( + cluster_id: &ClusterId, + ) -> Result { + Ok(ClusterPricingParams { + unit_per_mb_stored: 1, + unit_per_mb_streamed: 2, + unit_per_put_request: 3, + unit_per_get_request: 4, + }) + } } pub struct ExtBuilder; From 3ba8265caf172648bd9b4246d1a945fefc8bf4fa Mon Sep 17 00:00:00 2001 From: Victor Genin Date: Thu, 16 Nov 2023 14:53:36 +0200 Subject: [PATCH 15/17] some CI fixes --- pallets/ddc-customers/src/mock.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pallets/ddc-customers/src/mock.rs b/pallets/ddc-customers/src/mock.rs index 025f76fa4..0ff1957d5 100644 --- a/pallets/ddc-customers/src/mock.rs +++ b/pallets/ddc-customers/src/mock.rs @@ -1,7 +1,7 @@ //! Test utilities use crate::{self as pallet_ddc_customers, *}; -use ddc_primitives::{NodePubKey, NodeType}; +use ddc_primitives::{NodePubKey, NodeType, ClusterPricingParams}; use ddc_traits::cluster::{ClusterVisitor, ClusterVisitorError}; use frame_support::{ @@ -130,7 +130,7 @@ impl ClusterVisitor for TestClusterVisitor { } fn get_pricing_params( - cluster_id: &ClusterId, + _cluster_id: &ClusterId, ) -> Result { Ok(ClusterPricingParams { unit_per_mb_stored: 1, From 96a2212cbfb3df26fc067b7be267b28306ca0843 Mon Sep 17 00:00:00 2001 From: Victor Genin Date: Thu, 16 Nov 2023 15:00:50 +0200 Subject: [PATCH 16/17] CI fixes --- pallets/ddc-customers/src/mock.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/ddc-customers/src/mock.rs b/pallets/ddc-customers/src/mock.rs index 0ff1957d5..5113b1e69 100644 --- a/pallets/ddc-customers/src/mock.rs +++ b/pallets/ddc-customers/src/mock.rs @@ -1,7 +1,7 @@ //! Test utilities use crate::{self as pallet_ddc_customers, *}; -use ddc_primitives::{NodePubKey, NodeType, ClusterPricingParams}; +use ddc_primitives::{ClusterPricingParams, NodePubKey, NodeType}; use ddc_traits::cluster::{ClusterVisitor, ClusterVisitorError}; use frame_support::{ From 91c16e2d2332c19a2e832d8d9c8be918e2a13fcd Mon Sep 17 00:00:00 2001 From: yahortsaryk Date: Fri, 17 Nov 2023 15:51:39 +0100 Subject: [PATCH 17/17] fix(pallet_ddc_customers): 'StorageHasher' type for Ledger map is changed to a more secure one --- pallets/ddc-customers/src/lib.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pallets/ddc-customers/src/lib.rs b/pallets/ddc-customers/src/lib.rs index e010065dc..1263db707 100644 --- a/pallets/ddc-customers/src/lib.rs +++ b/pallets/ddc-customers/src/lib.rs @@ -177,8 +177,12 @@ pub mod pallet { /// Map from all (unlocked) "owner" accounts to the info regarding the staking. #[pallet::storage] #[pallet::getter(fn ledger)] - pub type Ledger = - StorageMap<_, Identity, T::AccountId, AccountsLedger, T>>; + pub type Ledger = StorageMap< + _, + Blake2_128Concat, + T::AccountId, + AccountsLedger, T>, + >; #[pallet::type_value] pub fn DefaultBucketCount() -> BucketId {