Skip to content

Commit

Permalink
feat: role proposal confirmation logic
Browse files Browse the repository at this point in the history
  • Loading branch information
tkxkd0159 committed May 2, 2024
1 parent e30a99d commit 1693f60
Show file tree
Hide file tree
Showing 11 changed files with 568 additions and 119 deletions.
18 changes: 18 additions & 0 deletions docs/core/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,7 @@
- [ProvisionData](#lbm.fbridge.v1.ProvisionData)
- [ProvisionStatus](#lbm.fbridge.v1.ProvisionStatus)
- [RoleMetadata](#lbm.fbridge.v1.RoleMetadata)
- [RolePair](#lbm.fbridge.v1.RolePair)
- [RoleProposal](#lbm.fbridge.v1.RoleProposal)
- [Vote](#lbm.fbridge.v1.Vote)

Expand Down Expand Up @@ -11482,6 +11483,22 @@ RoleMetadata defines the metadata of the role.



<a name="lbm.fbridge.v1.RolePair"></a>

### RolePair



| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `address` | [string](#string) | | |
| `role` | [Role](#lbm.fbridge.v1.Role) | | |






<a name="lbm.fbridge.v1.RoleProposal"></a>

### RoleProposal
Expand Down Expand Up @@ -11743,6 +11760,7 @@ GenesisState defines the fbridge module's genesis state.
| `role_proposals` | [RoleProposal](#lbm.fbridge.v1.RoleProposal) | repeated | role_proposals defines all the role proposals present at genesis. |
| `votes` | [Vote](#lbm.fbridge.v1.Vote) | repeated | votes defines all the votes present for role proposals at genesis. |
| `role_metadata` | [RoleMetadata](#lbm.fbridge.v1.RoleMetadata) | | role_metadata defines all the role metadata present at genesis. |
| `roles` | [RolePair](#lbm.fbridge.v1.RolePair) | repeated | roles defines all addresses assigned roles at genesis. |



Expand Down
7 changes: 6 additions & 1 deletion proto/lbm/fbridge/v1/fbridge.proto
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ enum Role {
JUDGE = 3 [(gogoproto.enumvalue_customname) = "RoleJudge"];
}

message RolePair {
string address = 1;
Role role = 2;
}

message RoleProposal {
uint64 id = 1;
// the proposer address
Expand Down Expand Up @@ -106,4 +111,4 @@ message RoleMetadata {
uint32 operator = 2;
// the number of the judges
uint32 judge = 3;
}
}
2 changes: 2 additions & 0 deletions proto/lbm/fbridge/v1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ message GenesisState {
repeated Vote votes = 6 [(gogoproto.nullable) = false];
// role_metadata defines all the role metadata present at genesis.
RoleMetadata role_metadata = 7 [(gogoproto.nullable) = false];
// roles defines all addresses assigned roles at genesis.
repeated RolePair roles = 8 [(gogoproto.nullable) = false];
}

message SendingState {
Expand Down
37 changes: 35 additions & 2 deletions x/fbridge/keeper/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,21 @@ func (k Keeper) GetVote(ctx sdk.Context, proposalID uint64, voter sdk.AccAddress
return types.VoteOption(binary.BigEndian.Uint32(bz)), nil

Check warning on line 157 in x/fbridge/keeper/auth.go

View check run for this annotation

Codecov / codecov/patch

x/fbridge/keeper/auth.go#L157

Added line #L157 was not covered by tests
}

func (k Keeper) setRole(ctx sdk.Context, role types.Role, addr sdk.AccAddress) {
func (k Keeper) GetVotes(ctx sdk.Context, proposalID uint64) []types.VoteOption {
store := ctx.KVStore(k.storeKey)

Check warning on line 161 in x/fbridge/keeper/auth.go

View check run for this annotation

Codecov / codecov/patch

x/fbridge/keeper/auth.go#L160-L161

Added lines #L160 - L161 were not covered by tests

votes := make([]types.VoteOption, 0)
iterator := sdk.KVStorePrefixIterator(store, types.VotesKey(proposalID))
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
v := types.VoteOption(binary.BigEndian.Uint32(iterator.Value()))
votes = append(votes, v)

Check warning on line 168 in x/fbridge/keeper/auth.go

View check run for this annotation

Codecov / codecov/patch

x/fbridge/keeper/auth.go#L163-L168

Added lines #L163 - L168 were not covered by tests
}

return votes

Check warning on line 171 in x/fbridge/keeper/auth.go

View check run for this annotation

Codecov / codecov/patch

x/fbridge/keeper/auth.go#L171

Added line #L171 was not covered by tests
}

func (k Keeper) SetRole(ctx sdk.Context, role types.Role, addr sdk.AccAddress) {
store := ctx.KVStore(k.storeKey)
bz := make([]byte, 4)
binary.BigEndian.PutUint32(bz, uint32(role))
Expand All @@ -174,7 +188,26 @@ func (k Keeper) GetRole(ctx sdk.Context, addr sdk.AccAddress) types.Role {
return types.Role(binary.BigEndian.Uint32(bz))

Check warning on line 188 in x/fbridge/keeper/auth.go

View check run for this annotation

Codecov / codecov/patch

x/fbridge/keeper/auth.go#L188

Added line #L188 was not covered by tests
}

func (k Keeper) setRoleMetadata(ctx sdk.Context, data types.RoleMetadata) {
func (k Keeper) GetRolePairs(ctx sdk.Context) []types.RolePair {
store := ctx.KVStore(k.storeKey)

Check warning on line 192 in x/fbridge/keeper/auth.go

View check run for this annotation

Codecov / codecov/patch

x/fbridge/keeper/auth.go#L191-L192

Added lines #L191 - L192 were not covered by tests

pairs := make([]types.RolePair, 0)
iterator := sdk.KVStorePrefixIterator(store, types.KeyRolePrefix)
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
assignee := types.SplitRoleKey(iterator.Key())
pairs = append(pairs, types.RolePair{Address: assignee.String(), Role: types.Role(binary.BigEndian.Uint32(iterator.Value()))})

Check warning on line 199 in x/fbridge/keeper/auth.go

View check run for this annotation

Codecov / codecov/patch

x/fbridge/keeper/auth.go#L194-L199

Added lines #L194 - L199 were not covered by tests
}

return pairs

Check warning on line 202 in x/fbridge/keeper/auth.go

View check run for this annotation

Codecov / codecov/patch

x/fbridge/keeper/auth.go#L202

Added line #L202 was not covered by tests
}

func (k Keeper) DeleteRole(ctx sdk.Context, addr sdk.AccAddress) {
store := ctx.KVStore(k.storeKey)
store.Delete(types.RoleKey(addr))

Check warning on line 207 in x/fbridge/keeper/auth.go

View check run for this annotation

Codecov / codecov/patch

x/fbridge/keeper/auth.go#L205-L207

Added lines #L205 - L207 were not covered by tests
}

func (k Keeper) SetRoleMetadata(ctx sdk.Context, data types.RoleMetadata) {
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshal(&data)
store.Set(types.KeyRoleMetadata, bz)

Check warning on line 213 in x/fbridge/keeper/auth.go

View check run for this annotation

Codecov / codecov/patch

x/fbridge/keeper/auth.go#L210-L213

Added lines #L210 - L213 were not covered by tests
Expand Down
17 changes: 13 additions & 4 deletions x/fbridge/keeper/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,21 @@ import (
func (k Keeper) InitGenesis(ctx sdk.Context, gs *types.GenesisState) error {
k.SetParams(ctx, gs.Params)

Check warning on line 10 in x/fbridge/keeper/genesis.go

View check run for this annotation

Codecov / codecov/patch

x/fbridge/keeper/genesis.go#L10

Added line #L10 was not covered by tests
k.setNextSequence(ctx, gs.SendingState.NextSeq)
k.setNextProposalID(ctx, gs.NextRoleProposalId)
k.setRoleMetadata(ctx, gs.RoleMetadata)

k.setNextProposalID(ctx, gs.NextRoleProposalId)
for _, proposal := range gs.RoleProposals {
k.setRoleProposal(ctx, proposal)

Check warning on line 15 in x/fbridge/keeper/genesis.go

View check run for this annotation

Codecov / codecov/patch

x/fbridge/keeper/genesis.go#L13-L15

Added lines #L13 - L15 were not covered by tests
}

for _, vote := range gs.Votes {
k.setVote(ctx, vote.ProposalId, sdk.MustAccAddressFromBech32(vote.Voter), vote.Option)

Check warning on line 19 in x/fbridge/keeper/genesis.go

View check run for this annotation

Codecov / codecov/patch

x/fbridge/keeper/genesis.go#L18-L19

Added lines #L18 - L19 were not covered by tests
}

k.SetRoleMetadata(ctx, gs.RoleMetadata)
for _, pair := range gs.Roles {
k.SetRole(ctx, pair.Role, sdk.MustAccAddressFromBech32(pair.Address))

Check warning on line 24 in x/fbridge/keeper/genesis.go

View check run for this annotation

Codecov / codecov/patch

x/fbridge/keeper/genesis.go#L22-L24

Added lines #L22 - L24 were not covered by tests
}

// TODO: we initialize the appropriate genesis parameters whenever the feature is added

return nil
Expand All @@ -27,9 +36,10 @@ func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState {
NextSeq: k.GetNextSequence(ctx),
},
NextRoleProposalId: k.GetNextProposalID(ctx),
RoleMetadata: k.GetRoleMetadata(ctx),
RoleProposals: k.GetProposals(ctx),
Votes: k.GetAllVotes(ctx),
RoleMetadata: k.GetRoleMetadata(ctx),
Roles: k.GetRolePairs(ctx),

Check warning on line 42 in x/fbridge/keeper/genesis.go

View check run for this annotation

Codecov / codecov/patch

x/fbridge/keeper/genesis.go#L38-L42

Added lines #L38 - L42 were not covered by tests
}
}

Expand All @@ -43,7 +53,6 @@ func (k Keeper) IterateVotes(ctx sdk.Context, cb func(proposal types.Vote) (stop
id, voter := types.SplitVoterVoteKey(iterator.Key())
opt := types.VoteOption(binary.BigEndian.Uint32(iterator.Value()))
v := types.Vote{ProposalId: id, Voter: voter.String(), Option: opt}
k.cdc.MustUnmarshal(iterator.Value(), &v)
if cb(v) {
break

Check warning on line 57 in x/fbridge/keeper/genesis.go

View check run for this annotation

Codecov / codecov/patch

x/fbridge/keeper/genesis.go#L50-L57

Added lines #L50 - L57 were not covered by tests
}
Expand Down
70 changes: 70 additions & 0 deletions x/fbridge/module/abci.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package module

import (
"fmt"

Check failure on line 4 in x/fbridge/module/abci.go

View workflow job for this annotation

GitHub Actions / golangci-lint

File is not `gci`-ed with --skip-generated -s standard -s default -s prefix(github.com/Finschia/finschia-sdk) --custom-order (gci)
sdk "github.com/Finschia/finschia-sdk/types"
"github.com/Finschia/finschia-sdk/x/fbridge/keeper"
"github.com/Finschia/finschia-sdk/x/fbridge/types"
)

func EndBlocker(ctx sdk.Context, k keeper.Keeper) {
guardianTrustLevel := k.GetParams(ctx).GuardianTrustLevel
proposals := k.GetProposals(ctx)
for _, proposal := range proposals {
if ctx.BlockTime().After(proposal.ExpiredAt) {
k.DeleteRoleProposal(ctx, proposal.Id)
continue
}

votes := k.GetVotes(ctx, proposal.Id)

voteYes := 0
for _, vote := range votes {
if vote == types.OptionYes {
voteYes++
}
}

var total uint32 = 0
roleMeta := k.GetRoleMetadata(ctx)
previousRole := k.GetRole(ctx, sdk.MustAccAddressFromBech32(proposal.Target))
switch proposal.Role {
case types.RoleGuardian:
total = roleMeta.Guardian
case types.RoleOperator:
total = roleMeta.Operator
case types.RoleJudge:
total = roleMeta.Judge
default:
panic(fmt.Sprintf("invalid role: %s\n", proposal.Role))
}

if types.CheckTrustLevelThreshold(uint64(total), uint64(voteYes), guardianTrustLevel) {
if proposal.Role == types.RoleEmpty {
k.DeleteRole(ctx, sdk.MustAccAddressFromBech32(proposal.Target))
} else {
k.SetRole(ctx, proposal.Role, sdk.MustAccAddressFromBech32(proposal.Target))
}

switch proposal.Role {
case types.RoleGuardian:
roleMeta.Guardian++
case types.RoleOperator:
roleMeta.Operator++
case types.RoleJudge:
roleMeta.Judge++
}
switch previousRole {
case types.RoleGuardian:
roleMeta.Guardian--
case types.RoleOperator:
roleMeta.Operator--
case types.RoleJudge:
roleMeta.Judge--
}
k.SetRoleMetadata(ctx, roleMeta)

k.DeleteRoleProposal(ctx, proposal.Id)
}
}
}
14 changes: 11 additions & 3 deletions x/fbridge/module/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ const (
)

var (
_ module.AppModuleBasic = AppModuleBasic{}
_ module.AppModuleGenesis = AppModule{}
_ module.AppModule = AppModule{}
_ module.AppModuleBasic = AppModuleBasic{}
_ module.AppModuleGenesis = AppModule{}
_ module.AppModule = AppModule{}
_ module.EndBlockAppModule = AppModule{}
)

// AppModuleBasic defines the basic application module used by the fbridge module.
Expand Down Expand Up @@ -121,6 +122,13 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw
// ConsensusVersion implements AppModule/ConsensusVersion.
func (AppModule) ConsensusVersion() uint64 { return consensusVersion }

// EndBlock returns the end blocker for the fbridge module.
// It returns no validator updates.
func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
EndBlocker(ctx, am.keeper)
return []abci.ValidatorUpdate{}
}

// RegisterInvariants does nothing, there are no invariants to enforce
func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {
_ = ir
Expand Down
Loading

0 comments on commit 1693f60

Please sign in to comment.