Closed DariuszDepta closed 10 months ago
After brainstorming about this change with @webmaster128 and @chipshort we agreed, that the simplest, safest and the closest to real-life blockchain way of handling addresses in tests will be using Bech32 encoding. It means, that all user addresses and contract addresses will be either in canonical form or Bech32 encoded.
Implementation of the trait cosmwasm_std::Api
for cosmwasm_std::testing::MockApi
will be
adjusted in the extent described below.
addr_validate
This function will probably stay untouched. The validation process checks if the input address can be canonicalized and then humanized, and the result is compared with the input.
It means, that when the user passes valid Bech32 or Bech32m address
with predefined prefix (see Bech32 prefix
section below) to this function,
it will be properly canonicalized. Canonical address can be always humanized,
so the whole validation process will always success.
In case the user passes an invalid address (not Bech32 encoded), the canonicalization will reject it with an error, and then the whole validation fails.
addr_canonicalize
Canonicalization will use Bech32 decoder with predefined prefix. If decoding fails,
it means that the provided address is invalid and an error will be returned.
After change, this function will accept only addresses in Bech32 or Bech32m encoding
having predefined prefix (see Bech32 prefix
section below).
addr_humanize
This function will use Bech32 encoder to generate humanized address
with predefined prefix (see Bech32 prefix
section below).
cosmwasm_std::testing::MockApi
during instantiation will have a predefined prefix set.
The default prefix used in Bech32 encoding/decoding will be cosmwasm, but it can be set
to any reasonable value. So the user may create addresses like these in real blockchain,
e.g. juno1v82su97skv6ucfqvuvswe0t5fph7pfsrtraxf0x33d8ylj5qnrysdvkc95
Addr
structWe will provide utility function named hashed, to be used only for testing purposes
(just like unchecked) for creating Bech32 addresses from any provided input.
The unchecked function will be deprecated, so the proper ways of creating Addr
will be:
let checked: Addr = Addr::hashed(input)
,let checked: Addr = deps.api.addr_validate(input)?
, orlet checked: Addr = deps.api.addr_humanize(canonical_addr)?
.Adding function Addr::hashed
is non-breaking change, under condition, that bech32 crate compiles to wasm32
(can be implemented immediately).
Changing the behaviour of functions addr_canonicalize
and addr_humanize
is a breaking change.
These changes have to be postponed to version 2.0. All test cases im cosmwasm
and tests for contracts (cw-plus)
have to be reviewed and adjusted.
Adding Bech32 prefix to MockApi seems to be a non-breaking change and can be implemented immediately.
I agree with the above except for one thing: Addr::hashed("cosmwasm", "foobar")
requires you to always put the prefix there and means it's easy to use the wrong prefix. Is there something wrong with adding the address maker as MockApi::addr_make(&self, input: &str) -> StdResult<Addr>
? Then you can use Addr::unchecked
internally.
I think it would be good to keep Addr encoding agnostic.
I like the idea. Let's keep Addr
encoding agnostic and move the address builder to MockApi
.
I pulled out https://github.com/CosmWasm/cosmwasm/issues/1887 as a preparation that allows users to use it instead of Addr::unchecked. This I think should go in 1.5. The rest if this ticket we can do later.
This issue and the corresponding PR is a proposal of using new algorithms in functions:
Api::addr_canonicalize
, andApi::addr_humanize
implemented in
cosmwasm_std::testing::MockApi
.The new implementation is based on Bech32 encoding format (as idescribed in BIP-0173 and Bech32m encoding format described in BIP-0350) and uses the implementation provided by crate bech32.
Proposed solution supports all currently implemented functionality, like the possibility of using short custom addresses like foobar that are not bech32 encoded. Additionaly, new functions allow users to generate humanized addresses just like real-life blockchain in bech32 format with user-defined prefix like juno, osmosis etc. Finally, this solution solves the issue #1648 and unlocks implementation of the issue #39.
Proposed solution
This solution is based on Bech32 encoding format with default or user-defined bech32 prefix. User can define Bech32 prefix during MockApi instantiation.
All input addresses represented directly as a string or wrapped with
Addr
are treated either as Bech32 encoded or as a plain text. The simplest usage scenario is following: a user provides a simple plain-text address which is then canonicalized and humanized, e.g.:When a user provides a long address, similar as in Juno chain, then the previous example would look like this:
When a user wants to generate and humanize a predictable contract address using a function
instantiate2_address
while testing contracts in Juno chain test cases, then it could be done as follows:Proposed algorithm
It is assumed, that MockApi has configured Bech32 prefix during instantiation for example: juno. The reversed version of this prefix (rev_prefix) is used internally as desribed below.
addr_canonicalize
addr_humanize