Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Strip metadata fix #1774

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open

Strip metadata fix #1774

wants to merge 15 commits into from

Conversation

pkhry
Copy link
Contributor

@pkhry pkhry commented Sep 18, 2024

Description:

See #1659

This fixes the error described inside the issue, however it will strip types in a bit different way which will result in slightly less savings on average.

Biggest difference between the new and old approaches is that:

  • we always keep full outerenum enums, unless there are some variants that do not reference any types we intend to retain.
  • we dont immediately drop pallets that the user is not interested in, instead we strip them to contain only types that are relevant and if it ends up empty -> it is being dropped.
  • outer enums and pallet types are now traversed fully to collect all the types and their deps.

Size comparison with the previous stripping approach:

size reduction Comparison:

  • using `./artifacts/polkadot_metadata_full.scale"
Comparison for old and new stripping methods. be warned, it's 1K lines
[
    DebugInfo {
        pallets_list: "System",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 502,
            num_pallets: 7,
            encoded_size: 133756,
            codegen_size: 598771,
        },
        old_retaining_algo: Info {
            num_types: 418,
            num_pallets: 1,
            encoded_size: 80216,
            codegen_size: 461382,
        },
    },
    DebugInfo {
        pallets_list: "Babe",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 411,
            num_pallets: 11,
            encoded_size: 80680,
            codegen_size: 442897,
        },
        old_retaining_algo: Info {
            num_types: 411,
            num_pallets: 1,
            encoded_size: 78437,
            codegen_size: 429077,
        },
    },
    DebugInfo {
        pallets_list: "Timestamp",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 395,
            num_pallets: 13,
            encoded_size: 75779,
            codegen_size: 416354,
        },
        old_retaining_algo: Info {
            num_types: 395,
            num_pallets: 1,
            encoded_size: 73003,
            codegen_size: 398718,
        },
    },
    DebugInfo {
        pallets_list: "Indices",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 398,
            num_pallets: 9,
            encoded_size: 76784,
            codegen_size: 428982,
        },
        old_retaining_algo: Info {
            num_types: 398,
            num_pallets: 1,
            encoded_size: 74575,
            codegen_size: 415427,
        },
    },
    DebugInfo {
        pallets_list: "Balances",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 419,
            num_pallets: 9,
            encoded_size: 84407,
            codegen_size: 487783,
        },
        old_retaining_algo: Info {
            num_types: 419,
            num_pallets: 1,
            encoded_size: 82198,
            codegen_size: 474216,
        },
    },
    DebugInfo {
        pallets_list: "Parameters",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 413,
            num_pallets: 12,
            encoded_size: 76925,
            codegen_size: 426018,
        },
        old_retaining_algo: Info {
            num_types: 413,
            num_pallets: 1,
            encoded_size: 74168,
            codegen_size: 408409,
        },
    },
    DebugInfo {
        pallets_list: "TransactionPayment",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 397,
            num_pallets: 11,
            encoded_size: 75533,
            codegen_size: 414861,
        },
        old_retaining_algo: Info {
            num_types: 397,
            num_pallets: 1,
            encoded_size: 72801,
            codegen_size: 397551,
        },
    },
    DebugInfo {
        pallets_list: "Authorship",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 394,
            num_pallets: 12,
            encoded_size: 74160,
            codegen_size: 408939,
        },
        old_retaining_algo: Info {
            num_types: 394,
            num_pallets: 1,
            encoded_size: 71342,
            codegen_size: 390790,
        },
    },
    DebugInfo {
        pallets_list: "Offences",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 399,
            num_pallets: 10,
            encoded_size: 74334,
            codegen_size: 414022,
        },
        old_retaining_algo: Info {
            num_types: 399,
            num_pallets: 1,
            encoded_size: 71984,
            codegen_size: 398824,
        },
    },
    DebugInfo {
        pallets_list: "Historical",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 396,
            num_pallets: 13,
            encoded_size: 74258,
            codegen_size: 410475,
        },
        old_retaining_algo: Info {
            num_types: 396,
            num_pallets: 1,
            encoded_size: 71516,
            codegen_size: 392805,
        },
    },
    DebugInfo {
        pallets_list: "Session",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 402,
            num_pallets: 10,
            encoded_size: 76815,
            codegen_size: 425948,
        },
        old_retaining_algo: Info {
            num_types: 402,
            num_pallets: 1,
            encoded_size: 74456,
            codegen_size: 411628,
        },
    },
    DebugInfo {
        pallets_list: "Grandpa",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 402,
            num_pallets: 11,
            encoded_size: 78756,
            codegen_size: 436131,
        },
        old_retaining_algo: Info {
            num_types: 402,
            num_pallets: 1,
            encoded_size: 76444,
            codegen_size: 421462,
        },
    },
    DebugInfo {
        pallets_list: "AuthorityDiscovery",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 395,
            num_pallets: 13,
            encoded_size: 74382,
            codegen_size: 411048,
        },
        old_retaining_algo: Info {
            num_types: 395,
            num_pallets: 1,
            encoded_size: 71495,
            codegen_size: 391843,
        },
    },
    DebugInfo {
        pallets_list: "Treasury",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 404,
            num_pallets: 7,
            encoded_size: 81164,
            codegen_size: 459627,
        },
        old_retaining_algo: Info {
            num_types: 404,
            num_pallets: 1,
            encoded_size: 79538,
            codegen_size: 448852,
        },
    },
    DebugInfo {
        pallets_list: "ConvictionVoting",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 414,
            num_pallets: 9,
            encoded_size: 82661,
            codegen_size: 455934,
        },
        old_retaining_algo: Info {
            num_types: 414,
            num_pallets: 1,
            encoded_size: 80387,
            codegen_size: 441568,
        },
    },
    DebugInfo {
        pallets_list: "Referenda",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 423,
            num_pallets: 9,
            encoded_size: 86419,
            codegen_size: 476546,
        },
        old_retaining_algo: Info {
            num_types: 423,
            num_pallets: 1,
            encoded_size: 84335,
            codegen_size: 464801,
        },
    },
    DebugInfo {
        pallets_list: "FellowshipCollective",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 405,
            num_pallets: 10,
            encoded_size: 78791,
            codegen_size: 452499,
        },
        old_retaining_algo: Info {
            num_types: 405,
            num_pallets: 1,
            encoded_size: 76496,
            codegen_size: 438100,
        },
    },
    DebugInfo {
        pallets_list: "FellowshipReferenda",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 422,
            num_pallets: 9,
            encoded_size: 85893,
            codegen_size: 476641,
        },
        old_retaining_algo: Info {
            num_types: 422,
            num_pallets: 1,
            encoded_size: 83809,
            codegen_size: 464909,
        },
    },
    DebugInfo {
        pallets_list: "Origins",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 394,
            num_pallets: 13,
            encoded_size: 74175,
            codegen_size: 409028,
        },
        old_retaining_algo: Info {
            num_types: 394,
            num_pallets: 1,
            encoded_size: 71288,
            codegen_size: 389811,
        },
    },
    DebugInfo {
        pallets_list: "Whitelist",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 563,
            num_pallets: 7,
            encoded_size: 232060,
            codegen_size: 699070,
        },
        old_retaining_algo: Info {
            num_types: 397,
            num_pallets: 1,
            encoded_size: 72631,
            codegen_size: 406658,
        },
    },
    DebugInfo {
        pallets_list: "Claims",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 404,
            num_pallets: 10,
            encoded_size: 78848,
            codegen_size: 442670,
        },
        old_retaining_algo: Info {
            num_types: 404,
            num_pallets: 1,
            encoded_size: 76238,
            codegen_size: 426953,
        },
    },
    DebugInfo {
        pallets_list: "Utility",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 563,
            num_pallets: 7,
            encoded_size: 232114,
            codegen_size: 710366,
        },
        old_retaining_algo: Info {
            num_types: 399,
            num_pallets: 1,
            encoded_size: 75701,
            codegen_size: 422136,
        },
    },
    DebugInfo {
        pallets_list: "Identity",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 451,
            num_pallets: 9,
            encoded_size: 90133,
            codegen_size: 523383,
        },
        old_retaining_algo: Info {
            num_types: 451,
            num_pallets: 1,
            encoded_size: 87985,
            codegen_size: 510544,
        },
    },
    DebugInfo {
        pallets_list: "Society",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 419,
            num_pallets: 9,
            encoded_size: 88999,
            codegen_size: 526480,
        },
        old_retaining_algo: Info {
            num_types: 419,
            num_pallets: 1,
            encoded_size: 86875,
            codegen_size: 513932,
        },
    },
    DebugInfo {
        pallets_list: "Recovery",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 567,
            num_pallets: 7,
            encoded_size: 235321,
            codegen_size: 733453,
        },
        old_retaining_algo: Info {
            num_types: 403,
            num_pallets: 1,
            encoded_size: 80171,
            codegen_size: 447311,
        },
    },
    DebugInfo {
        pallets_list: "Vesting",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 401,
            num_pallets: 9,
            encoded_size: 78445,
            codegen_size: 438034,
        },
        old_retaining_algo: Info {
            num_types: 401,
            num_pallets: 1,
            encoded_size: 76171,
            codegen_size: 423657,
        },
    },
    DebugInfo {
        pallets_list: "Scheduler",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 568,
            num_pallets: 6,
            encoded_size: 233977,
            codegen_size: 731145,
        },
        old_retaining_algo: Info {
            num_types: 407,
            num_pallets: 1,
            encoded_size: 77612,
            codegen_size: 445470,
        },
    },
    DebugInfo {
        pallets_list: "Proxy",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 571,
            num_pallets: 7,
            encoded_size: 234609,
            codegen_size: 734882,
        },
        old_retaining_algo: Info {
            num_types: 408,
            num_pallets: 1,
            encoded_size: 80803,
            codegen_size: 451419,
        },
    },
    DebugInfo {
        pallets_list: "Multisig",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 566,
            num_pallets: 7,
            encoded_size: 234170,
            codegen_size: 721871,
        },
        old_retaining_algo: Info {
            num_types: 404,
            num_pallets: 1,
            encoded_size: 80096,
            codegen_size: 437136,
        },
    },
    DebugInfo {
        pallets_list: "Preimage",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 406,
            num_pallets: 9,
            encoded_size: 76746,
            codegen_size: 431555,
        },
        old_retaining_algo: Info {
            num_types: 406,
            num_pallets: 1,
            encoded_size: 74544,
            codegen_size: 418020,
        },
    },
    DebugInfo {
        pallets_list: "AssetRate",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 399,
            num_pallets: 12,
            encoded_size: 75807,
            codegen_size: 425186,
        },
        old_retaining_algo: Info {
            num_types: 399,
            num_pallets: 1,
            encoded_size: 73118,
            codegen_size: 408334,
        },
    },
    DebugInfo {
        pallets_list: "Bounties",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 403,
            num_pallets: 8,
            encoded_size: 80792,
            codegen_size: 460794,
        },
        old_retaining_algo: Info {
            num_types: 403,
            num_pallets: 1,
            encoded_size: 78790,
            codegen_size: 447849,
        },
    },
    DebugInfo {
        pallets_list: "ChildBounties",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 401,
            num_pallets: 9,
            encoded_size: 81941,
            codegen_size: 461812,
        },
        old_retaining_algo: Info {
            num_types: 401,
            num_pallets: 1,
            encoded_size: 79667,
            codegen_size: 447431,
        },
    },
    DebugInfo {
        pallets_list: "Nis",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 411,
            num_pallets: 10,
            encoded_size: 87484,
            codegen_size: 452193,
        },
        old_retaining_algo: Info {
            num_types: 411,
            num_pallets: 1,
            encoded_size: 85056,
            codegen_size: 438127,
        },
    },
    DebugInfo {
        pallets_list: "NisCounterpartBalances",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 419,
            num_pallets: 9,
            encoded_size: 84547,
            codegen_size: 488784,
        },
        old_retaining_algo: Info {
            num_types: 419,
            num_pallets: 1,
            encoded_size: 82338,
            codegen_size: 475221,
        },
    },
    DebugInfo {
        pallets_list: "ParachainsOrigin",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 394,
            num_pallets: 13,
            encoded_size: 74389,
            codegen_size: 409047,
        },
        old_retaining_algo: Info {
            num_types: 394,
            num_pallets: 1,
            encoded_size: 71502,
            codegen_size: 389830,
        },
    },
    DebugInfo {
        pallets_list: "Configuration",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 401,
            num_pallets: 11,
            encoded_size: 82178,
            codegen_size: 507561,
        },
        old_retaining_algo: Info {
            num_types: 401,
            num_pallets: 1,
            encoded_size: 79884,
            codegen_size: 492936,
        },
    },
    DebugInfo {
        pallets_list: "ParasShared",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 398,
            num_pallets: 12,
            encoded_size: 74569,
            codegen_size: 411275,
        },
        old_retaining_algo: Info {
            num_types: 398,
            num_pallets: 1,
            encoded_size: 72189,
            codegen_size: 396041,
        },
    },
    DebugInfo {
        pallets_list: "ParaInclusion",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 399,
            num_pallets: 12,
            encoded_size: 77253,
            codegen_size: 422753,
        },
        old_retaining_algo: Info {
            num_types: 399,
            num_pallets: 1,
            encoded_size: 74565,
            codegen_size: 405916,
        },
    },
    DebugInfo {
        pallets_list: "ParaInherent",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 403,
            num_pallets: 11,
            encoded_size: 75833,
            codegen_size: 416278,
        },
        old_retaining_algo: Info {
            num_types: 403,
            num_pallets: 1,
            encoded_size: 73481,
            codegen_size: 400791,
        },
    },
    DebugInfo {
        pallets_list: "ParaScheduler",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 402,
            num_pallets: 13,
            encoded_size: 76002,
            codegen_size: 415314,
        },
        old_retaining_algo: Info {
            num_types: 402,
            num_pallets: 1,
            encoded_size: 73326,
            codegen_size: 397895,
        },
    },
    DebugInfo {
        pallets_list: "Paras",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 409,
            num_pallets: 10,
            encoded_size: 84043,
            codegen_size: 489674,
        },
        old_retaining_algo: Info {
            num_types: 409,
            num_pallets: 1,
            encoded_size: 81928,
            codegen_size: 477328,
        },
    },
    DebugInfo {
        pallets_list: "Initializer",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 397,
            num_pallets: 12,
            encoded_size: 75143,
            codegen_size: 413268,
        },
        old_retaining_algo: Info {
            num_types: 397,
            num_pallets: 1,
            encoded_size: 72846,
            codegen_size: 397237,
        },
    },
    DebugInfo {
        pallets_list: "Dmp",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 395,
            num_pallets: 11,
            encoded_size: 74519,
            codegen_size: 413520,
        },
        old_retaining_algo: Info {
            num_types: 395,
            num_pallets: 1,
            encoded_size: 71919,
            codegen_size: 397515,
        },
    },
    DebugInfo {
        pallets_list: "Hrmp",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 404,
            num_pallets: 10,
            encoded_size: 84211,
            codegen_size: 484166,
        },
        old_retaining_algo: Info {
            num_types: 404,
            num_pallets: 1,
            encoded_size: 82019,
            codegen_size: 470555,
        },
    },
    DebugInfo {
        pallets_list: "ParaSessionInfo",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 395,
            num_pallets: 11,
            encoded_size: 74404,
            codegen_size: 412193,
        },
        old_retaining_algo: Info {
            num_types: 395,
            num_pallets: 1,
            encoded_size: 72062,
            codegen_size: 397981,
        },
    },
    DebugInfo {
        pallets_list: "ParasDisputes",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 401,
            num_pallets: 12,
            encoded_size: 76379,
            codegen_size: 428147,
        },
        old_retaining_algo: Info {
            num_types: 401,
            num_pallets: 1,
            encoded_size: 74108,
            codegen_size: 412914,
        },
    },
    DebugInfo {
        pallets_list: "ParasSlashing",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 398,
            num_pallets: 12,
            encoded_size: 75264,
            codegen_size: 418095,
        },
        old_retaining_algo: Info {
            num_types: 398,
            num_pallets: 1,
            encoded_size: 72576,
            codegen_size: 401262,
        },
    },
    DebugInfo {
        pallets_list: "MessageQueue",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 406,
            num_pallets: 11,
            encoded_size: 79786,
            codegen_size: 435568,
        },
        old_retaining_algo: Info {
            num_types: 406,
            num_pallets: 1,
            encoded_size: 77343,
            codegen_size: 421441,
        },
    },
    DebugInfo {
        pallets_list: "OnDemandAssignmentProvider",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 410,
            num_pallets: 11,
            encoded_size: 78015,
            codegen_size: 435642,
        },
        old_retaining_algo: Info {
            num_types: 410,
            num_pallets: 1,
            encoded_size: 75350,
            codegen_size: 419089,
        },
    },
    DebugInfo {
        pallets_list: "CoretimeAssignmentProvider",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 410,
            num_pallets: 12,
            encoded_size: 75833,
            codegen_size: 419616,
        },
        old_retaining_algo: Info {
            num_types: 410,
            num_pallets: 1,
            encoded_size: 73340,
            codegen_size: 402579,
        },
    },
    DebugInfo {
        pallets_list: "Registrar",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 399,
            num_pallets: 10,
            encoded_size: 80476,
            codegen_size: 451649,
        },
        old_retaining_algo: Info {
            num_types: 399,
            num_pallets: 1,
            encoded_size: 77931,
            codegen_size: 436736,
        },
    },
    DebugInfo {
        pallets_list: "Slots",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 400,
            num_pallets: 11,
            encoded_size: 76992,
            codegen_size: 426605,
        },
        old_retaining_algo: Info {
            num_types: 400,
            num_pallets: 1,
            encoded_size: 74327,
            codegen_size: 410057,
        },
    },
    DebugInfo {
        pallets_list: "Auctions",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 403,
            num_pallets: 11,
            encoded_size: 78797,
            codegen_size: 441003,
        },
        old_retaining_algo: Info {
            num_types: 403,
            num_pallets: 1,
            encoded_size: 76132,
            codegen_size: 424453,
        },
    },
    DebugInfo {
        pallets_list: "Crowdloan",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 404,
            num_pallets: 9,
            encoded_size: 80930,
            codegen_size: 457966,
        },
        old_retaining_algo: Info {
            num_types: 404,
            num_pallets: 1,
            encoded_size: 78656,
            codegen_size: 443593,
        },
    },
    DebugInfo {
        pallets_list: "Coretime",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 402,
            num_pallets: 11,
            encoded_size: 76251,
            codegen_size: 423311,
        },
        old_retaining_algo: Info {
            num_types: 402,
            num_pallets: 1,
            encoded_size: 73892,
            codegen_size: 407866,
        },
    },
    DebugInfo {
        pallets_list: "XcmPallet",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 417,
            num_pallets: 7,
            encoded_size: 98939,
            codegen_size: 559130,
        },
        old_retaining_algo: Info {
            num_types: 417,
            num_pallets: 1,
            encoded_size: 97317,
            codegen_size: 549670,
        },
    },
    DebugInfo {
        pallets_list: "Beefy",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 402,
            num_pallets: 11,
            encoded_size: 79859,
            codegen_size: 443341,
        },
        old_retaining_algo: Info {
            num_types: 402,
            num_pallets: 1,
            encoded_size: 77547,
            codegen_size: 428671,
        },
    },
    DebugInfo {
        pallets_list: "Mmr",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 394,
            num_pallets: 13,
            encoded_size: 74369,
            codegen_size: 411191,
        },
        old_retaining_algo: Info {
            num_types: 394,
            num_pallets: 1,
            encoded_size: 71605,
            codegen_size: 393515,
        },
    },
    DebugInfo {
        pallets_list: "MmrLeaf",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 394,
            num_pallets: 12,
            encoded_size: 74165,
            codegen_size: 407670,
        },
        old_retaining_algo: Info {
            num_types: 394,
            num_pallets: 1,
            encoded_size: 71601,
            codegen_size: 391981,
        },
    },
    DebugInfo {
        pallets_list: "IdentityMigrator",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 396,
            num_pallets: 11,
            encoded_size: 75128,
            codegen_size: 416436,
        },
        old_retaining_algo: Info {
            num_types: 396,
            num_pallets: 1,
            encoded_size: 72396,
            codegen_size: 399132,
        },
    },
    DebugInfo {
        pallets_list: "ParasSudoWrapper",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 397,
            num_pallets: 10,
            encoded_size: 76190,
            codegen_size: 423531,
        },
        old_retaining_algo: Info {
            num_types: 397,
            num_pallets: 1,
            encoded_size: 73740,
            codegen_size: 409225,
        },
    },
    DebugInfo {
        pallets_list: "AssignedSlots",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 400,
            num_pallets: 11,
            encoded_size: 77104,
            codegen_size: 436959,
        },
        old_retaining_algo: Info {
            num_types: 400,
            num_pallets: 1,
            encoded_size: 74683,
            codegen_size: 420984,
        },
    },
    DebugInfo {
        pallets_list: "ValidatorManager",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 397,
            num_pallets: 12,
            encoded_size: 75227,
            codegen_size: 419450,
        },
        old_retaining_algo: Info {
            num_types: 397,
            num_pallets: 1,
            encoded_size: 72408,
            codegen_size: 401297,
        },
    },
    DebugInfo {
        pallets_list: "StateTrieMigration",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 403,
            num_pallets: 10,
            encoded_size: 80409,
            codegen_size: 443344,
        },
        old_retaining_algo: Info {
            num_types: 403,
            num_pallets: 1,
            encoded_size: 77799,
            codegen_size: 427618,
        },
    },
    DebugInfo {
        pallets_list: "RootTesting",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 397,
            num_pallets: 13,
            encoded_size: 74767,
            codegen_size: 415329,
        },
        old_retaining_algo: Info {
            num_types: 397,
            num_pallets: 1,
            encoded_size: 71947,
            codegen_size: 396895,
        },
    },
    DebugInfo {
        pallets_list: "Sudo",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 563,
            num_pallets: 7,
            encoded_size: 231999,
            codegen_size: 700755,
        },
        old_retaining_algo: Info {
            num_types: 398,
            num_pallets: 1,
            encoded_size: 73263,
            codegen_size: 409387,
        },
    },
    DebugInfo {
        pallets_list: "System,Balances,Configuration,XcmPallet,Timestamp",
        default: Info {
            num_types: 942,
            num_pallets: 67,
            encoded_size: 420397,
            codegen_size: 2812530,
        },
        new_retaining_algo: Info {
            num_types: 552,
            num_pallets: 10,
            encoded_size: 172372,
            codegen_size: 936371,
        },
        old_retaining_algo: Info {
            num_types: 472,
            num_pallets: 5,
            encoded_size: 127358,
            codegen_size: 816513,
        },
    },
]

@pkhry pkhry requested a review from a team as a code owner September 18, 2024 16:28
@pkhry pkhry marked this pull request as draft September 18, 2024 16:29
@pkhry pkhry marked this pull request as ready for review September 24, 2024 11:49
@pkhry pkhry changed the title WIP: Strip metadata fix Strip metadata fix Sep 24, 2024
}
}

fn collect_types(&mut self, metadata: &Metadata, t: &PortableType) {
Copy link
Collaborator

@jsdw jsdw Oct 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this logic is basically recursing through all of the types linked from some type and adding them to the set. But this is the same thing that we do in PortableRegistry::retain here https://github.com/paritytech/scale-info/blob/master/src/portable.rs#L104; is it necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, retain is called dead last before updating types, but we need to collect types ourselves to determine which outer type variants are safe to drop/which pallets can be stripped or dropped completetely.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how I feel about this function, because it duplicates the logic in scale_info's retain.

a) On the one hand, we could also remove this function entirely (ie no longer recurse and building this type Ids map when we collect up our pallet/runtime etc types), and instead have a function which has the specific goal of searching through the metadata to look for the runtime types (and in that way, it doesn't need to allocate/collect anything).

b) On the other hand, keeping this function is "easier" because you need to recurse anyway to do the above searching, so maybe you end up with fewer lines of code by just keeping it around.

Personally I'd try (a) and see whether doing so makes things easier to follow or not, but not sure!

Comment on lines 437 to 446
|| !matches!(
pallet,
PalletMetadataInner {
storage: None,
call_ty: None,
event_ty: None,
error_ty: None,
constants: map,
..
} if map.is_empty()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this make any difference? I can't see why a pallet would exist that had nothing meaningful in it, but even if it did, is there any harm in leaving it there?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I am starting to see why this is kept but not understanding it yet; you are turning things to None above in some cases

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

codegen size

@@ -588,7 +584,7 @@ impl<'a> MetadataHasher<'a> {

// Get the hashes of outer enums, considering only `specific_pallets` (if any are set).
// If any of the typed that represent outer enums are encountered later, hashes from `top_level_enum_hashes` can be substituted.
let outer_enum_hashes = OuterEnumHashes::new(metadata, self.specific_pallets.as_deref());
let outer_enum_hashes = OuterEnumHashes::new(metadata);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So here we no logner care about the possibility of the enums like RuntimeCall etc being changed, but how can we avoid caring about this?

(either the variants and all of their types still exist, so the hashes are the same, or we have stripped some types and/or variants and then the hashes owuld be different unless we ignore them, wouldn't they?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

list of pallets/variants types is completely dependant on the given set of pallets for a particular pallet or unpredictable

Copy link
Member

@niklasad1 niklasad1 Oct 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand,

So what happens if Call::Balances(pallet_system::AccountData) variant exist and I only want retain the system pallet, does the Call::Balances get filtered out?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aight, I think this was opinionated and removed variants without checking that it was actually referenced by pallets, runtime apis?

We now only rely on TypeSet::retain_metadata(..) to achieve this

metadata/src/utils/retain.rs Outdated Show resolved Hide resolved
Comment on lines 94 to 119
fn collect_extrinsic_types(&mut self, extrinsic: &ExtrinsicMetadata) {
let mut ids = Vec::from([
extrinsic.address_ty,
extrinsic.call_ty,
extrinsic.signature_ty,
extrinsic.extra_ty,
]);

for signed in &extrinsic.signed_extensions {
ids.push(signed.extra_ty);
ids.push(signed.additional_ty);
}
for id in ids {
self.seen_ids.insert(id);
}
}

if let Some(ty) = pallet.event_ty {
type_ids.insert(ty);
/// Collect all type IDs needed to represent the runtime APIs.
fn collect_runtime_api_types(&mut self, api: &RuntimeApiMetadataInner) {
for method in api.methods.values() {
for input in &method.inputs {
self.seen_ids.insert(input.ty);
}
self.seen_ids.insert(method.output_ty);
}
}
Copy link
Collaborator

@jsdw jsdw Oct 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two functions don't recurse through any sub types. While I don't think anything should, if we did decide we wanted to recurse here then I guess these should, too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pushed a change that does traverse, a few more types added to retained set on average.

Comment on lines 420 to 426
let mut retained_set = TypeSet {
seen_ids: type_set
.seen_ids
.difference(&retained_set.seen_ids)
.copied()
.collect(),
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it looks like you are:

  • building a set of types to keep based on the pallets we want to keep (retained_set)
  • cloning that set and then adding all of the other types we want to keep (runtime APIs etc) too (type_set)
  • taking the difference between those (ie type_set - retained_set? So just the other types without the pallet ones, which we could get by just not cloning above?). This difference is now retained_set.
  • for pallets we want to filter, run update_filtered_pallet, which roughly seems to keep things in the pallet if they reference types we've collected outside of the pallet stuff, and remove things if not. We then only discard pallets if no types that they directly reference are used elsewhere outside of pallets.

I might be wrong, but I don't really understand the reason for doing this? since you collected the outer enums, I can see that the first pallet we see that references those would actually be kept (which I guess has the effect of keeping the variant too?), but it feels like quite a long winded way to go about avoiding getting rid of variants if the outer enums are used somewhere, and I don't know if there is any other benefit :D

I also see that update_filtered_pallet calls retained_set.remove() each time it checks, so only the first pallet referencing eg RuntimeCall would end up having bits kept I think, and other pallets that reference RuntimeCall would be removed. Is that intentional?

Overall, I feel like we can remove a lot of this logic and rely on scale_info::PortableRegistry::retain for the recursive retaining of IDs we care about (because either that works ok already, or doesn't work and should be fixed). Then the logic can be something like:

  • Add all of the type IDs from the pallets etc that we want to keep to a set
  • For any return types or storage types in these things we are keeping, do a deep scan to see if we find the RuntimeCall, RutimeEvent or RuntimeError outer enums. If we find one, we can't strip any variants out of it
  • Now, call PortableRegistry::retain to keep all of the type Ids we need (which will vary depending on whether those enums had variants stripped out of them or not and thus fewer IDs to recurse through).

All of that said though, if there is some value I'm not understanding in the way that we are keeping pallets etc here, then probably I'd need to be walked through it and we'd want to add a comment or two somewhere here to explain the approach and reasoning for it for our future selves :)

Copy link
Contributor Author

@pkhry pkhry Oct 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

taking the difference between those (ie type_set - retained_set? So just the other types without the pallet ones, which we could get by just not cloning above?). This difference is now retained_set.

The difference is the types present in the type_set and absent in retained_set. retained_set is not interesting in this case as types were already present in retained pallet. But i feel like we are talking about the same thing

but it feels like quite a long winded way to go about avoiding getting rid of variants if the outer enums are used somewhere, and I don't know if there is any other benefit :D

Its more about getting rid of pallets and outer enums, but only if they are not referenced anywhere. Its about stripping types that are not interesting to user without accidentally removing something that is required.

I also see that update_filtered_pallet calls retained_set.remove() each time it checks, so only the first pallet referencing eg RuntimeCall would end up having bits kept I think, and other pallets that reference RuntimeCall would be removed. Is that intentional?

I guess i'm misunderstanding something, shouldn't only one pallet with the type be enough or we can safely ignore those refs to runtime call/runtime error/runtime event and remove pallet based purely on storage/constant types? My intuition was to keep them as they might be referencing inner types inside outerenum variant, ie pallet.event_ty = 365 and metadata.outer_enum.event_ty = 22

All of that said though, if there is some value I'm not understanding in the way that we are keeping pallets etc here, then probably I'd need to be walked through it and we'd want to add a comment or two somewhere here to explain the approach and reasoning for it for our future selves :)

as above: My intuition was to keep them as they might be referencing inner types inside outerenum variant, ie pallet.event_ty = 365 and metadata.outer_enum.event_ty = 22

@jsdw
Copy link
Collaborator

jsdw commented Oct 3, 2024

I had a look over and think I'm starting to understand the code more, though I still think that it's more complex than we need (but let's chat tomorrow and look at the code more to confirm).

Essentially, scale_info::PortableRegistry::retain() should already do the recursive retaining stuff, and then the one thing that we do that can cause issues is that we dumbly strip variants from the outer enums without checking if they are returned anywhere. The goal then is to work out whether we can strip the outer enums in this way or whether we need to leave them as is.

So, the approach I'd lean towards with this is more like:

  1. Traverse all of the type IDs we see in the pallets and runtime APIs that we want to keep (not recursively), adding them to a set of IDs we want to keep.
  2. While doing this or as a separate step, do a recursive search over this pallets and runtime APIs — on the pallet errors, events, and storage, and the runtime API return type IDs (hope I'm not missing something!) — to see if we find any of the outer enum IDs. See the example function below for a way to search for outer enum IDs given some starting ID.
  3. For any outer enum IDs still in the set (ie not found), strip them to only contain the pallet variants we are keeping. Add the outer enum IDs to the set of IDs we want to keep.
  4. Call scale_info::PortableReigstry::retain() passing all of the IDs we want to keep. This will handle recursively keeping Ids etc, and will get rid of any now-unneeded IDs if we stripped any enum variants too.
  5. Filter all of the pallets and runtime APIs that we don't want to keep from the metadata (we could do this right at the beginning if we want; we always filter them).

For working out whether some type contains an outer enum, you might end up with a recursive check which is a simplified version of yours, and doesn't need to allocate anything like:

fn find_tys_in_id(id: u32, types: &PortableRegistry, unseen: &mut BTreeSet<u32>) {
    unseen.remove(id)

    let ty = types.resolve(id);
    match ty.type_def {
        TypeDef::Composite(TypeDefComposite { fields }) => {
            for field in fields {
                find_tys_in_id(field.ty.id, types, unseen)
            }
        }
        TypeDef::Variant(TypeDefVariant { variants }) => {
            for variant in variants {
                for field in &variant.fields {
                    find_tys_in_id(field.ty.id, types, unseen)
                }
            }
        }
        TypeDef::Array(TypeDefArray { len: _, type_param })
        | TypeDef::Sequence(TypeDefSequence { type_param })
        | TypeDef::Compact(TypeDefCompact { type_param }) => {
            find_tys_in_id(type_param.id, types, unseen)
        }
        TypeDef::Tuple(TypeDefTuple { fields }) => {
            for field in fields {
                find_tys_in_id(field.id, types, unseen)
            }
        }
        TypeDef::Primitive(_) | TypeDef::BitSequence(_) => {
            // End of recursion.
        }
    }
}

I def think that the existing code can be made clearer w.r.t what steps it takes, and hopefully this extra check to see if we can strip outer enum types handles the edge case we've faced where we strip variants even though we need the fully types to decode something in Subxt.

Note: If the outer enum types are inputs to some runtime API etc, we can still strip them I think. All this means is that users won't be able to express things about pallets that have been stripped when constructing such inputs. Everything should still encode ok.

@pkhry
Copy link
Contributor Author

pkhry commented Oct 9, 2024

I had a look over and think I'm starting to understand the code more, though I still think that it's more complex than we need (but let's chat tomorrow and look at the code more to confirm).

Essentially, scale_info::PortableRegistry::retain() should already do the recursive retaining stuff, and then the one thing that we do that can cause issues is that we dumbly strip variants from the outer enums without checking if they are returned anywhere. The goal then is to work out whether we can strip the outer enums in this way or whether we need to leave them as is.

So, the approach I'd lean towards with this is more like:

  1. Traverse all of the type IDs we see in the pallets and runtime APIs that we want to keep (not recursively), adding them to a set of IDs we want to keep.
  2. While doing this or as a separate step, do a recursive search over this pallets and runtime APIs — on the pallet errors, events, and storage, and the runtime API return type IDs (hope I'm not missing something!) — to see if we find any of the outer enum IDs. See the example function below for a way to search for outer enum IDs given some starting ID.
  3. For any outer enum IDs still in the set (ie not found), strip them to only contain the pallet variants we are keeping. Add the outer enum IDs to the set of IDs we want to keep.
  4. Call scale_info::PortableReigstry::retain() passing all of the IDs we want to keep. This will handle recursively keeping Ids etc, and will get rid of any now-unneeded IDs if we stripped any enum variants too.
  5. Filter all of the pallets and runtime APIs that we don't want to keep from the metadata (we could do this right at the beginning if we want; we always filter them).

For working out whether some type contains an outer enum, you might end up with a recursive check which is a simplified version of yours, and doesn't need to allocate anything like:

fn find_tys_in_id(id: u32, types: &PortableRegistry, unseen: &mut BTreeSet<u32>) {
    unseen.remove(id)

    let ty = types.resolve(id);
    match ty.type_def {
        TypeDef::Composite(TypeDefComposite { fields }) => {
            for field in fields {
                find_tys_in_id(field.ty.id, types, unseen)
            }
        }
        TypeDef::Variant(TypeDefVariant { variants }) => {
            for variant in variants {
                for field in &variant.fields {
                    find_tys_in_id(field.ty.id, types, unseen)
                }
            }
        }
        TypeDef::Array(TypeDefArray { len: _, type_param })
        | TypeDef::Sequence(TypeDefSequence { type_param })
        | TypeDef::Compact(TypeDefCompact { type_param }) => {
            find_tys_in_id(type_param.id, types, unseen)
        }
        TypeDef::Tuple(TypeDefTuple { fields }) => {
            for field in fields {
                find_tys_in_id(field.id, types, unseen)
            }
        }
        TypeDef::Primitive(_) | TypeDef::BitSequence(_) => {
            // End of recursion.
        }
    }
}

I def think that the existing code can be made clearer w.r.t what steps it takes, and hopefully this extra check to see if we can strip outer enum types handles the edge case we've faced where we strip variants even though we need the fully types to decode something in Subxt.

Note: If the outer enum types are inputs to some runtime API etc, we can still strip them I think. All this means is that users won't be able to express things about pallets that have been stripped when constructing such inputs. Everything should still encode ok.

ok, so after fiddling this a bit more i think this suggested approach is the way to go.
With the conditional outerenum variant removal the biggest factor in the amount of types retained is always the runtime_api

click me, wall of text `pallet_filter` - the pallet we want to keep. `name` - approach to traversal that was taken. `count` - amount of types retained in the registry after stripping.

as visible from set below its the runtime_api that plays the biggest whether or not the outer_enums would be stripped down.

Note however that amount of types on average will increase compared to the old approach, e.g. for a dataset of 943 types it will be 644 instead of the 411 in the past.

[
    Collected {
        pallets_filter: "System",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 581,
            },
            Info {
                name: "traverse pallets",
                count: 644,
            },
            Info {
                name: "traverse extrinsics",
                count: 581,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 644,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 644,
            },
        ],
    },
    Collected {
        pallets_filter: "Babe",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 575,
            },
            Info {
                name: "traverse pallets",
                count: 575,
            },
            Info {
                name: "traverse extrinsics",
                count: 575,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 575,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 640,
            },
        ],
    },
    Collected {
        pallets_filter: "Timestamp",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 562,
            },
            Info {
                name: "traverse pallets",
                count: 562,
            },
            Info {
                name: "traverse extrinsics",
                count: 562,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 562,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 627,
            },
        ],
    },
    Collected {
        pallets_filter: "Indices",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 565,
            },
            Info {
                name: "traverse pallets",
                count: 565,
            },
            Info {
                name: "traverse extrinsics",
                count: 565,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 565,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 629,
            },
        ],
    },
    Collected {
        pallets_filter: "Balances",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 584,
            },
            Info {
                name: "traverse pallets",
                count: 584,
            },
            Info {
                name: "traverse extrinsics",
                count: 584,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 584,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 647,
            },
        ],
    },
    Collected {
        pallets_filter: "Parameters",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 570,
            },
            Info {
                name: "traverse pallets",
                count: 570,
            },
            Info {
                name: "traverse extrinsics",
                count: 570,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 570,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 627,
            },
        ],
    },
    Collected {
        pallets_filter: "TransactionPayment",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 564,
            },
            Info {
                name: "traverse pallets",
                count: 564,
            },
            Info {
                name: "traverse extrinsics",
                count: 564,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 564,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 628,
            },
        ],
    },
    Collected {
        pallets_filter: "Authorship",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 562,
            },
            Info {
                name: "traverse pallets",
                count: 562,
            },
            Info {
                name: "traverse extrinsics",
                count: 562,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 562,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 627,
            },
        ],
    },
    Collected {
        pallets_filter: "Offences",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 566,
            },
            Info {
                name: "traverse pallets",
                count: 566,
            },
            Info {
                name: "traverse extrinsics",
                count: 566,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 566,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 630,
            },
        ],
    },
    Collected {
        pallets_filter: "Historical",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 563,
            },
            Info {
                name: "traverse pallets",
                count: 563,
            },
            Info {
                name: "traverse extrinsics",
                count: 563,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 563,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 628,
            },
        ],
    },
    Collected {
        pallets_filter: "Session",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 567,
            },
            Info {
                name: "traverse pallets",
                count: 567,
            },
            Info {
                name: "traverse extrinsics",
                count: 567,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 567,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 631,
            },
        ],
    },
    Collected {
        pallets_filter: "Grandpa",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 567,
            },
            Info {
                name: "traverse pallets",
                count: 567,
            },
            Info {
                name: "traverse extrinsics",
                count: 567,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 567,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 631,
            },
        ],
    },
    Collected {
        pallets_filter: "AuthorityDiscovery",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 563,
            },
            Info {
                name: "traverse pallets",
                count: 563,
            },
            Info {
                name: "traverse extrinsics",
                count: 563,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 563,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 628,
            },
        ],
    },
    Collected {
        pallets_filter: "Treasury",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 570,
            },
            Info {
                name: "traverse pallets",
                count: 570,
            },
            Info {
                name: "traverse extrinsics",
                count: 570,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 570,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 634,
            },
        ],
    },
    Collected {
        pallets_filter: "ConvictionVoting",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 576,
            },
            Info {
                name: "traverse pallets",
                count: 576,
            },
            Info {
                name: "traverse extrinsics",
                count: 576,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 576,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 640,
            },
        ],
    },
    Collected {
        pallets_filter: "Referenda",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 582,
            },
            Info {
                name: "traverse pallets",
                count: 582,
            },
            Info {
                name: "traverse extrinsics",
                count: 582,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 582,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 645,
            },
        ],
    },
    Collected {
        pallets_filter: "FellowshipCollective",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 571,
            },
            Info {
                name: "traverse pallets",
                count: 571,
            },
            Info {
                name: "traverse extrinsics",
                count: 571,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 571,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 633,
            },
        ],
    },
    Collected {
        pallets_filter: "FellowshipReferenda",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 581,
            },
            Info {
                name: "traverse pallets",
                count: 581,
            },
            Info {
                name: "traverse extrinsics",
                count: 581,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 581,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 644,
            },
        ],
    },
    Collected {
        pallets_filter: "Origins",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 562,
            },
            Info {
                name: "traverse pallets",
                count: 562,
            },
            Info {
                name: "traverse extrinsics",
                count: 562,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 562,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 627,
            },
        ],
    },
    Collected {
        pallets_filter: "Whitelist",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 564,
            },
            Info {
                name: "traverse pallets",
                count: 564,
            },
            Info {
                name: "traverse extrinsics",
                count: 564,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 564,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 628,
            },
        ],
    },
    Collected {
        pallets_filter: "Claims",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 564,
            },
            Info {
                name: "traverse pallets",
                count: 564,
            },
            Info {
                name: "traverse extrinsics",
                count: 564,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 564,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 628,
            },
        ],
    },
    Collected {
        pallets_filter: "Utility",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 564,
            },
            Info {
                name: "traverse pallets",
                count: 564,
            },
            Info {
                name: "traverse extrinsics",
                count: 564,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 564,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 628,
            },
        ],
    },
    Collected {
        pallets_filter: "Identity",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 579,
            },
            Info {
                name: "traverse pallets",
                count: 579,
            },
            Info {
                name: "traverse extrinsics",
                count: 579,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 579,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 643,
            },
        ],
    },
    Collected {
        pallets_filter: "Society",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 585,
            },
            Info {
                name: "traverse pallets",
                count: 585,
            },
            Info {
                name: "traverse extrinsics",
                count: 585,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 585,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 648,
            },
        ],
    },
    Collected {
        pallets_filter: "Recovery",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 568,
            },
            Info {
                name: "traverse pallets",
                count: 568,
            },
            Info {
                name: "traverse extrinsics",
                count: 568,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 568,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 632,
            },
        ],
    },
    Collected {
        pallets_filter: "Vesting",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 567,
            },
            Info {
                name: "traverse pallets",
                count: 567,
            },
            Info {
                name: "traverse extrinsics",
                count: 567,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 567,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 631,
            },
        ],
    },
    Collected {
        pallets_filter: "Scheduler",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 569,
            },
            Info {
                name: "traverse pallets",
                count: 569,
            },
            Info {
                name: "traverse extrinsics",
                count: 569,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 569,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 633,
            },
        ],
    },
    Collected {
        pallets_filter: "Proxy",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 572,
            },
            Info {
                name: "traverse pallets",
                count: 572,
            },
            Info {
                name: "traverse extrinsics",
                count: 572,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 572,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 636,
            },
        ],
    },
    Collected {
        pallets_filter: "Multisig",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 567,
            },
            Info {
                name: "traverse pallets",
                count: 567,
            },
            Info {
                name: "traverse extrinsics",
                count: 567,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 567,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 631,
            },
        ],
    },
    Collected {
        pallets_filter: "Preimage",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 573,
            },
            Info {
                name: "traverse pallets",
                count: 573,
            },
            Info {
                name: "traverse extrinsics",
                count: 573,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 573,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 637,
            },
        ],
    },
    Collected {
        pallets_filter: "AssetRate",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 564,
            },
            Info {
                name: "traverse pallets",
                count: 564,
            },
            Info {
                name: "traverse extrinsics",
                count: 564,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 564,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 628,
            },
        ],
    },
    Collected {
        pallets_filter: "Bounties",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 569,
            },
            Info {
                name: "traverse pallets",
                count: 569,
            },
            Info {
                name: "traverse extrinsics",
                count: 569,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 569,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 633,
            },
        ],
    },
    Collected {
        pallets_filter: "ChildBounties",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 567,
            },
            Info {
                name: "traverse pallets",
                count: 567,
            },
            Info {
                name: "traverse extrinsics",
                count: 567,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 567,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 631,
            },
        ],
    },
    Collected {
        pallets_filter: "Nis",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 576,
            },
            Info {
                name: "traverse pallets",
                count: 576,
            },
            Info {
                name: "traverse extrinsics",
                count: 576,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 576,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 640,
            },
        ],
    },
    Collected {
        pallets_filter: "NisCounterpartBalances",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 584,
            },
            Info {
                name: "traverse pallets",
                count: 584,
            },
            Info {
                name: "traverse extrinsics",
                count: 584,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 584,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 647,
            },
        ],
    },
    Collected {
        pallets_filter: "ParachainsOrigin",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 562,
            },
            Info {
                name: "traverse pallets",
                count: 562,
            },
            Info {
                name: "traverse extrinsics",
                count: 562,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 562,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 627,
            },
        ],
    },
    Collected {
        pallets_filter: "Configuration",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 566,
            },
            Info {
                name: "traverse pallets",
                count: 566,
            },
            Info {
                name: "traverse extrinsics",
                count: 566,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 566,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 631,
            },
        ],
    },
    Collected {
        pallets_filter: "ParasShared",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 565,
            },
            Info {
                name: "traverse pallets",
                count: 565,
            },
            Info {
                name: "traverse extrinsics",
                count: 565,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 565,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 630,
            },
        ],
    },
    Collected {
        pallets_filter: "ParaInclusion",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 566,
            },
            Info {
                name: "traverse pallets",
                count: 566,
            },
            Info {
                name: "traverse extrinsics",
                count: 566,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 566,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 630,
            },
        ],
    },
    Collected {
        pallets_filter: "ParaInherent",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 563,
            },
            Info {
                name: "traverse pallets",
                count: 563,
            },
            Info {
                name: "traverse extrinsics",
                count: 563,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 563,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 628,
            },
        ],
    },
    Collected {
        pallets_filter: "ParaScheduler",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 570,
            },
            Info {
                name: "traverse pallets",
                count: 570,
            },
            Info {
                name: "traverse extrinsics",
                count: 570,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 570,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 635,
            },
        ],
    },
    Collected {
        pallets_filter: "Paras",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 575,
            },
            Info {
                name: "traverse pallets",
                count: 575,
            },
            Info {
                name: "traverse extrinsics",
                count: 575,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 575,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 639,
            },
        ],
    },
    Collected {
        pallets_filter: "Initializer",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 564,
            },
            Info {
                name: "traverse pallets",
                count: 564,
            },
            Info {
                name: "traverse extrinsics",
                count: 564,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 564,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 629,
            },
        ],
    },
    Collected {
        pallets_filter: "Dmp",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 562,
            },
            Info {
                name: "traverse pallets",
                count: 562,
            },
            Info {
                name: "traverse extrinsics",
                count: 562,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 562,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 627,
            },
        ],
    },
    Collected {
        pallets_filter: "Hrmp",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 569,
            },
            Info {
                name: "traverse pallets",
                count: 569,
            },
            Info {
                name: "traverse extrinsics",
                count: 569,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 569,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 633,
            },
        ],
    },
    Collected {
        pallets_filter: "ParaSessionInfo",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 562,
            },
            Info {
                name: "traverse pallets",
                count: 562,
            },
            Info {
                name: "traverse extrinsics",
                count: 562,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 562,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 627,
            },
        ],
    },
    Collected {
        pallets_filter: "ParasDisputes",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 568,
            },
            Info {
                name: "traverse pallets",
                count: 568,
            },
            Info {
                name: "traverse extrinsics",
                count: 568,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 568,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 630,
            },
        ],
    },
    Collected {
        pallets_filter: "ParasSlashing",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 564,
            },
            Info {
                name: "traverse pallets",
                count: 564,
            },
            Info {
                name: "traverse extrinsics",
                count: 564,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 564,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 629,
            },
        ],
    },
    Collected {
        pallets_filter: "MessageQueue",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 571,
            },
            Info {
                name: "traverse pallets",
                count: 571,
            },
            Info {
                name: "traverse extrinsics",
                count: 571,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 571,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 634,
            },
        ],
    },
    Collected {
        pallets_filter: "OnDemandAssignmentProvider",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 576,
            },
            Info {
                name: "traverse pallets",
                count: 576,
            },
            Info {
                name: "traverse extrinsics",
                count: 576,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 576,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 640,
            },
        ],
    },
    Collected {
        pallets_filter: "CoretimeAssignmentProvider",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 573,
            },
            Info {
                name: "traverse pallets",
                count: 573,
            },
            Info {
                name: "traverse extrinsics",
                count: 573,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 573,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 638,
            },
        ],
    },
    Collected {
        pallets_filter: "Registrar",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 566,
            },
            Info {
                name: "traverse pallets",
                count: 566,
            },
            Info {
                name: "traverse extrinsics",
                count: 566,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 566,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 630,
            },
        ],
    },
    Collected {
        pallets_filter: "Slots",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 567,
            },
            Info {
                name: "traverse pallets",
                count: 567,
            },
            Info {
                name: "traverse extrinsics",
                count: 567,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 567,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 631,
            },
        ],
    },
    Collected {
        pallets_filter: "Auctions",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 568,
            },
            Info {
                name: "traverse pallets",
                count: 568,
            },
            Info {
                name: "traverse extrinsics",
                count: 568,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 568,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 632,
            },
        ],
    },
    Collected {
        pallets_filter: "Crowdloan",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 567,
            },
            Info {
                name: "traverse pallets",
                count: 567,
            },
            Info {
                name: "traverse extrinsics",
                count: 567,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 567,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 631,
            },
        ],
    },
    Collected {
        pallets_filter: "Coretime",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 564,
            },
            Info {
                name: "traverse pallets",
                count: 564,
            },
            Info {
                name: "traverse extrinsics",
                count: 564,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 564,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 628,
            },
        ],
    },
    Collected {
        pallets_filter: "XcmPallet",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 583,
            },
            Info {
                name: "traverse pallets",
                count: 583,
            },
            Info {
                name: "traverse extrinsics",
                count: 583,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 583,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 647,
            },
        ],
    },
    Collected {
        pallets_filter: "Beefy",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 564,
            },
            Info {
                name: "traverse pallets",
                count: 564,
            },
            Info {
                name: "traverse extrinsics",
                count: 564,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 564,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 629,
            },
        ],
    },
    Collected {
        pallets_filter: "Mmr",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 562,
            },
            Info {
                name: "traverse pallets",
                count: 562,
            },
            Info {
                name: "traverse extrinsics",
                count: 562,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 562,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 627,
            },
        ],
    },
    Collected {
        pallets_filter: "MmrLeaf",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 562,
            },
            Info {
                name: "traverse pallets",
                count: 562,
            },
            Info {
                name: "traverse extrinsics",
                count: 562,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 562,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 627,
            },
        ],
    },
    Collected {
        pallets_filter: "IdentityMigrator",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 563,
            },
            Info {
                name: "traverse pallets",
                count: 563,
            },
            Info {
                name: "traverse extrinsics",
                count: 563,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 563,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 627,
            },
        ],
    },
    Collected {
        pallets_filter: "ParasSudoWrapper",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 563,
            },
            Info {
                name: "traverse pallets",
                count: 563,
            },
            Info {
                name: "traverse extrinsics",
                count: 563,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 563,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 628,
            },
        ],
    },
    Collected {
        pallets_filter: "AssignedSlots",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 565,
            },
            Info {
                name: "traverse pallets",
                count: 565,
            },
            Info {
                name: "traverse extrinsics",
                count: 565,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 565,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 629,
            },
        ],
    },
    Collected {
        pallets_filter: "ValidatorManager",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 563,
            },
            Info {
                name: "traverse pallets",
                count: 563,
            },
            Info {
                name: "traverse extrinsics",
                count: 563,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 563,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 627,
            },
        ],
    },
    Collected {
        pallets_filter: "StateTrieMigration",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 565,
            },
            Info {
                name: "traverse pallets",
                count: 565,
            },
            Info {
                name: "traverse extrinsics",
                count: 565,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 565,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 627,
            },
        ],
    },
    Collected {
        pallets_filter: "RootTesting",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 563,
            },
            Info {
                name: "traverse pallets",
                count: 563,
            },
            Info {
                name: "traverse extrinsics",
                count: 563,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 563,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 627,
            },
        ],
    },
    Collected {
        pallets_filter: "Sudo",
        results: [
            Info {
                name: "no stripping",
                count: 943,
            },
            Info {
                name: "no deep traversal",
                count: 564,
            },
            Info {
                name: "traverse pallets",
                count: 564,
            },
            Info {
                name: "traverse extrinsics",
                count: 564,
            },
            Info {
                name: "traverse pallets & extrinsics",
                count: 564,
            },
            Info {
                name: "traverse pallets, extrinsics & runtime",
                count: 628,
            },
        ],
    },
]

@@ -214,7 +214,10 @@ impl Metadata {
MetadataHasher::new(self)
}

/// Filter out any pallets that we don't want to keep, retaining only those that we do.
/// Filter out any pallets and/or runtime_apis that we don't want to keep, retaining only those that we do.
/// Note:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather create a dev-note using // to avoid this to end-up in the API docs

/// Filter out any pallets that we don't want to keep, retaining only those that we do.
/// Filter out any pallets and/or runtime_apis that we don't want to keep, retaining only those that we do.
/// Note:
/// without also filtering out irrelevant runtime_api's in addition to pallets one should not expect significant metadata size reduction.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// without also filtering out irrelevant runtime_api's in addition to pallets one should not expect significant metadata size reduction.
/// runtime api filtering will not lead to significant metadata size reduction because the return types are kept to ensure that those can be decoded.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

runtimeApi filtering will lead to significant metadata size reductions.
If a runtimeApi returns an outerEnum type we no longer can strip the enum, because we don't know which variants are used.

/// Filter out any pallets and/or runtime_apis that we don't want to keep, retaining only those that we do.
/// Note:
/// without also filtering out irrelevant runtime_api's in addition to pallets one should not expect significant metadata size reduction.
/// This happens because we will keep the types returned by runtime_api methods to guarantee that we can safely decode them.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need to keep the return types if those are not used/trimmed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can never know if they are used fully or partially, therefore we always keep the full type

metadata/src/lib.rs Outdated Show resolved Hide resolved
match entry.entry_type {
StorageEntryType::Plain(ty) => {
type_ids.insert(ty);
use alloc::collections::{BTreeMap, BTreeSet, VecDeque};
Copy link
Member

@niklasad1 niklasad1 Oct 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mind document the algorithm we use to filter out pallets/runtime APIs as top-level docs in this module?
Such as the tree/types, outer enums etc are traversed and in which order...

};

// If the type was not referenced earlier we can safely strip some of the variants
if self.seen_ids.insert(id) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if self.seen_ids.insert(id) {
if self.seen_ids.contains(id) {

Inserting makes the result of calling collect_variants_in_type depend on the order in which you call it. So I wonder whether there is a need to insert here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure i'm following, we still need to add the enum type to the set and we don't do a deep traversal for outerenums anyways so insertion order shouldn't matter

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this is one of the things I find harder to follow; I guess I want to separate the funciton that "determines whether to keep all of the variants" from functions that mutate and add type IDs to some set.

metadata/src/utils/retain.rs Outdated Show resolved Hide resolved
metadata/src/utils/retain.rs Outdated Show resolved Hide resolved
};

#[derive(Clone)]
struct TypeSet {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I'd likely make the functions impl'd on this free standing and just have a. BTreeSet passed about, primarily for the reason that despite this TypeSet struct, there are still places where you manually do type_set.seen_ids.insert(foo) or whatever, so the internal details are leaking anyway :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed those parts to use defined method on the struct. i moved those functions an impl block to not carry the set around :D

@@ -281,7 +358,6 @@ pub fn retain_metadata<F, G>(
mod tests {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any test that we can add which ensures we don't strip outer enum variants when it would lead to breakage (ie they are used somewhere)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added a test that references initial issue

@pkhry pkhry requested review from jsdw and niklasad1 October 14, 2024 18:57
metadata/src/utils/retain.rs Outdated Show resolved Hide resolved
// test that the hashes are the same:
let hash = MetadataHasher::new(&metadata)
.only_these_pallets(&["First"])
.only_these_pallets(&name_set)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we can revert this to "First" now to simplify?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed the test completetely as the behaviour in OuterEnumHashes relied on the fact that some of the variants in outernums are removed unconditionally.

Comment on lines +440 to +445
{
let set = "Balances,Timestamp,Contracts,ContractsEvm,System"
.split(",")
.collect::<BTreeSet<&str>>();
move |s| set.contains(&s)
},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd simplify this to just |s| ["Balances","Timestamp","Contracts","ContractsEVM","System"].contains(s); no need for the set etc really (and with so few items it's prob not even slower anyways, but being a test it's not a big deal)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i written it like this only because repro command is a string and i was lazy to type


#[test]
fn issue_1659() {
let metadata_cache = load_metadata("../artifacts/regressions/1659.scale");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: rename to full_metadata?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which full_metadata? maybe we can name it 1659.full_metadata.scale?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I wasn't clear at all! I meant to rename metadata_cache to full_metadata :)

}
}

#[test]
fn retain_one_runtime_api() {
let metadata_cache = load_metadata();
let metadata_cache = load_metadata_polkadot();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I'd call this just metadata too (not really this PR but hey :))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renamed load_metadata_polkadot to load_metadata and introduced load_metadata_custom to load different files

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I wasn't clear at all there! I was referring to the variable metadata_cache; it's not really a cache or anything ,it is just the metadata :)

@pkhry pkhry requested a review from jsdw October 15, 2024 09:50
@jsdw
Copy link
Collaborator

jsdw commented Oct 15, 2024

One of the things that was bugging me a bit in this code prior to this PR is that we have separate collect_x and update_x functions, and we need to ensure that the logic for finding each type Id is identical across them.

Something that I find a bit hard to do still in this PR is following exactly the steps that we take to strip types. I think this was also a bit messy before the PR too.

Anyway, I got to wondering whether something like the following would be ultimately much clearer and easier to follow, while avoiding duplicating the logc around collect vs update:

pub fn retain_metadata<F, G>(
    metadata: &mut Metadata,
    mut pallets_filter: F,
    mut runtime_apis_filter: G,
) where
    F: FnMut(&str) -> bool,
    G: FnMut(&str) -> bool,
{
    // 1. Delete pallets we don't want to keep.
    metadata.pallets.retain(|pallet| pallets_filter(&pallet.name));
    metadata.pallets_by_index = metadata
        .pallets
        .values()
        .iter()
        .enumerate()
        .map(|(pos, p)| (p.index, pos))
        .collect();

    // 2. Delete runtime APIs we don't want to keep.
    metadata.apis.retain(|api| runtime_apis_filter(&api.name));

    // 3. For each outer enum type, strip it if possible, ie if it is not returned by any
    // of the things we're keeping (because if it is, we need to keep all of it so that we
    // can still decode values into it).
    let outer_enums = metadata.outer_enums();
    for outer_enum_ty_id in [outer_enums.call_enum_ty(), outer_enums.error_enum_ty(), outer_enums.event_enum_ty()] {
        if !find_type_id_in_return_pos(metadata, outer_enum_ty_id) {
            retain_variants_in_enum_type(metadata, &pallets_filter); 
            // ^ prob clearer renamed to "strip_variants_in_enum_type"
        }
    }

    // 4. Collect all of the type IDs we still want to keep after deleting.
    let mut keep_these_type_ids: BTreeSet<u32> = iterate_metadata_types(metadata).map(|id| *id).collect();

    // 5. Additionally, subxt depends on the `DispatchError` type existing; we use the same
    // logic here that is used when building our `Metadata` to ensure we keep it too.
    let dispatch_error_ty = metadata
        .types
        .types
        .iter()
        .find(|ty| ty.ty.path.segments == ["sp_runtime", "DispatchError"])
        .expect("Metadata must contain sp_runtime::DispatchError");
    keep_these_type_ids.insert(dispatch_error_ty.id);

    // 5. Strip all of the type IDs we no longer need, based on the above set.
    let map_ids = metadata.types.retain(|id| keep_these_type_ids.contains(&id));

    // 6. Now, update the type IDs referenced in our metadata to reflect this.
    for id in iterate_metadata_types(metadata) {
        if let Some(new_id) = map_ids.get(id) {
            *id = *new_id;
        } else {
            panic!("Type id {id} was not retained. This is a bug");
        }
    }
}

/// return an iterator handing back a mutable reference to each type ID seen in the metadata (not recursively).
/// This will iterate over every type referenced in the metadata outside of `metadata.types`.
fn iterate_metadata_types(metadata: &mut Metadata) -> impl Iterator<Item = &mut u32> {
    unimplemented!()
}

/// Look for a type ID anywhere that we can be given back, ie in constants, storage or runtime API return types.
/// This will recurse deeply into those type IDs to find them (but doesn't need to allocate).
fn find_type_id_in_return_pos(metadata: &mut Metadata, type_id: u32) -> bool {
    unimplemented!()
}

I think this would be something like my "north star" for a readable and hopefullyfairly easy to follow implementation of stripping pallets/runtime APIs.

That all said, I think we can aim to get this PR merged and havea go as a follow up step to do something like this.

metadata/src/lib.rs Outdated Show resolved Hide resolved
@pkhry pkhry requested a review from jsdw October 15, 2024 10:45
Comment on lines 582 to 584
// If any of the typed that represent outer enums are encountered later, hashes from `top_level_enum_hashes` can be substituted.
let outer_enum_hashes = OuterEnumHashes::new(metadata, self.specific_pallets.as_deref());
let outer_enum_hashes = OuterEnumHashes::new(metadata);

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still a bit confused by this.

Basically, the case I am thinking about is if we want to compare some "full" metadata with some "stripped down" metadata. We want to ensure that the remaining parts of the stripped metadata are in line with this full metadata (which would come form a node at runtime most probably).

To generate the same hash as the stripped metadata, we need to hash only the pallets that were kept around when hashing the full metadata.

To do this, we would previously generate outer_enum_hashes which hashed only the variants for those specific pallets (because we always stripped them). Now, it looks like we always hash every pallet in the full metadata, and so the hash would sometimes be different from the stripped metadata (ie whenever the stripped metadata actually removes variants, it will be different).

I guess this isn't tested yet, since I don't think it should work as it stands (but maybe I'm missing something?)

I think this hashing function would have to also work out whether the variants would be stripped or not based on what we pass to only_these_runtime_apis and only_these_pallets? This would be a good reason to have a separate find_type_id_in_return_pos type function, so that we can lean on it in both places.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dq: but isn't this testing the stripping logic by using said stripping logic? maybe its more logical to remove validation that uses specific_pallets?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is essentially using the striping logic (without actually having to do the heavyweight stuff of removing types/pallets etc) in order that we can compare some stripped metadata that a user might have passed to the Subxt macro with some "full" metadata that you get from a node, to check that the two are compatible.

And so my concern with this bit of code is that it looks like the hash generated for some stripped metadata would be different from the hash gernerated from the same "full" metadata (assuming that the stripped metadata was able to strip variants from one or more outer enums).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(happy to jump on a call or chat more about this if it doesn't make sense, and maybe I'm missing something too :))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants