Borrowed from Osmosis's contribution guidelines
Any contribution that you make to this repository will be under the Apache 2 License, as dictated by that license:
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
Contributors must sign-off each commit by adding a Signed-off-by: ...
line to commit messages to certify that they have the right to submit
the code they are contributing to the project according to the
Developer Certificate of Origin (DCO).
When updating global parameters, you must update the following files:
For x/emissions
:
x/emissions/types/params.go
- Set the default values for the new params
- Add a new function to return the default values
- Add validation for the new params
x/emissions/proto/emissions/v1/params.proto
- Add to the
Params
proto, tracking all global params
- Add to the
x/emissions/proto/emissions/v1/tx.proto
- Add to the proto of the tx that allows us to set new params
x/emissions/keeper/msgserver/msg_server_params.go
- Add code to the tx that allows us to set new params
- Update any tests where all params need to be specified
- Update any external docs here:
For x/mint
:
TBD
x/emissions|mint/keeper/events.go
- Add a new
New...Event
function- May not always be needed
- Add a new
Emit...Event
function
- Add a new
x/emissions|mint/metrics/labels.go
- Add a new label to identify the new event
- May not always be needed
- Add a new label to identify the new event
x/emissions|mint/proto/emissions|mint/vX/events.proto
- Update/Create the proto for the new event
x/emissions|mint/types/events_test.go
- Test the new event
x/emissions|mint/...
- Emit the new event where desired
vX
should refer to the latest version of the respective module (the version of the highest X
).
When updating the state store in x/emissions
, you must update the following files:
x/emissions/keeper/keeper.go
x/emissions/keeper/keeper_test.go
as neededx/emissions/types/keys.go
x/emissions/keeper/genesis.go
x/emissions/keeper/genesis_test.go
x/emissions/proto/emissions/v1/genesis.proto
At time of writing, we use a simple, incrementing versioning system per module e.g.
x/emissions
v6
that is incremented upon every breaking change independently of chain or other module versioning.Meanwhile, the chain abides by SemVer.
Upgrades will typically involve changing something about at least one of the chain's constituent modules, which in turn requires an upgrade of the chain itself. We first discuss what to do in a PR to "upgrade a module," then discuss how to "upgrade the chain."
- Update
ConsensusVersion
var at top ofx/MODULE/module/module.go
- Register the migration below ^that, in the same file
- Add the protobuf types as a new folder in
x/MODULE/module/vX/EXAMPLE.proto
- Update the paths of all endpoints at
x/MODULE/proto/MODULE/vX/query.proto
- Add the updated service to the query and/or message servers of
x/MODULE/module/autocli.go
(Query.Service
and/orMsg.Service
) - If changes to state or to logic that eventually affects state are involved, be sure to write a heavily-logged migration in
x/MODULE/migrations/vX/migrate.go
- You will likely need to add the previous version's types to the adjacent
oldtypes
folder in order to manipulate preexisting state.
- You will likely need to add the previous version's types to the adjacent
- Create the upgrade handler for the chain at
app/upgrades/vA_B_C/upgrades.go
- Add the upgrade handler you created above to
app/upgrades.go
It is critical to avoid performing network requests to external services since it is common for services to be unavailable or rate-limit.
Imagine a service that returns exchange rates when clients query its HTTP endpoint. This service might experience downtime or be restricted in some geographical areas.
As a result, nodes may get diverging responses where some get successful responses while others errors, leading to state breakage.
Randomness cannot be used in the state machine, as the state machine by definition must be deterministic. Any time you'd consider using it, instead seed a CSPRNG off of some seed.
One thing to note is that in golang, iteration order over maps is non-deterministic, so to be deterministic you must gather the keys, and sort them all prior to iterating over all values.
Threads and Goroutines might preempt differently in different hardware. Therefore, they should be avoided for the sake of determinism. Additionally, it is hard to predict when the multi-threaded state can be updated.
This is out of the developer's control but is mentioned for completeness.