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

[PVM] Add kyb verified state, allow kyb verified to propose add member #355

Merged
merged 1 commit into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -161,4 +161,4 @@ require (

replace github.com/ava-labs/avalanche-ledger-go => github.com/chain4travel/camino-ledger-go v0.0.13-c4t

replace github.com/ava-labs/coreth => github.com/chain4travel/caminoethvm v1.1.15-rc1.0.20240721114155-ee5dce4e9868
replace github.com/ava-labs/coreth => github.com/chain4travel/caminoethvm v1.1.15-rc1.0.20240721114647-ffc063541f3f
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chain4travel/caminoethvm v1.1.15-rc1.0.20240721114155-ee5dce4e9868 h1:32bIll72axJXTU3hSYPxY3hxYZ5TqgJpJVE9IubyBZo=
github.com/chain4travel/caminoethvm v1.1.15-rc1.0.20240721114155-ee5dce4e9868/go.mod h1:aXs2X5y4BVp+fGUk4sR1rk1qHmrtTl6NxTJPhUVw3P0=
github.com/chain4travel/caminoethvm v1.1.15-rc1.0.20240721114647-ffc063541f3f h1:UXaMNZQQBLT8Fu3l6p8Fktr3NhYBHfjs5ZRi4UauP4I=
github.com/chain4travel/caminoethvm v1.1.15-rc1.0.20240721114647-ffc063541f3f/go.mod h1:aXs2X5y4BVp+fGUk4sR1rk1qHmrtTl6NxTJPhUVw3P0=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
Expand Down
11 changes: 8 additions & 3 deletions vms/platformvm/addrstate/camino_address_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ const (
AddressStateBitKYCVerified AddressStateBit = 32
// Indicates that address KYC verification is expired. (not yet implemented)
AddressStateBitKYCExpired AddressStateBit = 33
// Indicates that address passed KYB verification
AddressStateBitKYBVerified AddressStateBit = 34
// Indicates that address is member of consortium
AddressStateBitConsortium AddressStateBit = 38
// Indicates that a node owned by this address (as consortium member) is deferred
Expand Down Expand Up @@ -58,6 +60,9 @@ const (
AddressStateKYCVerified = AddressState(1) << AddressStateBitKYCVerified
// 0b0000000000000000000000000000001000000000000000000000000000000000
AddressStateKYCExpired = AddressState(1) << AddressStateBitKYCExpired
// 0b0000000000000000000000000000010000000000000000000000000000000000
AddressStateKYBVerified = AddressState(1) << AddressStateBitKYBVerified

// 0b0000000000000000000000000100000000000000000000000000000000000000
AddressStateConsortium = AddressState(1) << AddressStateBitConsortium
// 0b0000000000000000000000001000000000000000000000000000000000000000
Expand All @@ -75,10 +80,10 @@ const (
AddressStateNodeDeferred
// 0b0000000000000100000000000000000000000000000000000000000000000100
AddressStateAthensPhaseBits = AddressStateRoleOffersAdmin | AddressStateOffersCreator
// 0b0000000000001000000000000000000000000000000000000000000000001000
// 0b0000000000001000000000000000010000000000000000000000000000001000
AddressStateBerlinPhaseBits = AddressStateFoundationAdmin | AddressStateRoleConsortiumSecretary |
AddressStateRoleValidatorAdmin
// 0b0000000000001100000000001100001100000000000000000000000000011111
AddressStateRoleValidatorAdmin | AddressStateKYBVerified
// 0b0000000000001100000000001100011100000000000000000000000000011111
AddressStateValidBits = AddressStateSunrisePhaseBits |
AddressStateAthensPhaseBits |
AddressStateBerlinPhaseBits
Expand Down
4 changes: 2 additions & 2 deletions vms/platformvm/txs/executor/camino_tx_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -2323,7 +2323,7 @@ func (e *CaminoStandardTxExecutor) AddressStateTx(tx *txs.AddressStateTx) error
}

const (
addressStateKYCAll = as.AddressStateKYCVerified | as.AddressStateKYCExpired
addressStateKYCAll = as.AddressStateKYCVerified | as.AddressStateKYCExpired | as.AddressStateKYBVerified
addressStateRoleBits = as.AddressStateRoleAdmin | as.AddressStateRoleKYCAdmin |
as.AddressStateRoleConsortiumSecretary | as.AddressStateRoleOffersAdmin |
as.AddressStateRoleValidatorAdmin | as.AddressStateFoundationAdmin
Expand All @@ -2334,7 +2334,7 @@ func isPermittedToModifyAddrStateBit(isBerlinPhase bool, roles, state as.Address
switch {
// admin can do anything before BerlinPhase, after that admin can only modify other roles
case roles.Is(as.AddressStateRoleAdmin) && (!isBerlinPhase || addressStateRoleBits&state != 0):
// kyc role can change kyc status
// kyc role can change kyc/kyb bits
case addressStateKYCAll&state != 0 && roles.Is(as.AddressStateRoleKYCAdmin):
// offers admin can assign offers creator role
case state == as.AddressStateOffersCreator && roles.Is(as.AddressStateRoleOffersAdmin):
Expand Down
1 change: 1 addition & 0 deletions vms/platformvm/txs/executor/camino_tx_executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2079,6 +2079,7 @@ func TestCaminoStandardTxExecutorAddressStateTx(t *testing.T) {
for _, permissionsMatrix := range permissionsMatrix {
permissionsMatrix[as.AddressStateBitRoleKYCAdmin][as.AddressStateBitKYCVerified] = nil
permissionsMatrix[as.AddressStateBitRoleKYCAdmin][as.AddressStateBitKYCExpired] = nil
permissionsMatrix[as.AddressStateBitRoleKYCAdmin][as.AddressStateBitKYBVerified] = nil
permissionsMatrix[as.AddressStateBitRoleOffersAdmin][as.AddressStateBitOffersCreator] = nil
permissionsMatrix[as.AddressStateBitRoleValidatorAdmin][as.AddressStateBitNodeDeferred] = nil
}
Expand Down
16 changes: 11 additions & 5 deletions vms/platformvm/txs/executor/dac/camino_dac.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ var (
_ dac.Executor = (*proposalExecutor)(nil)
_ dac.BondTxIDsGetter = (*proposalBondTxIDsGetter)(nil)

errNotKYCVerified = errors.New("address is not KYC verified")
errNotVerifiedAddress = errors.New("address is not KYC or KYB verified")
errNotConsortiumMember = errors.New("address isn't consortium member")
errConsortiumMember = errors.New("address is consortium member")
errNotPermittedToCreateProposal = errors.New("don't have permission to create proposal of this type")
Expand Down Expand Up @@ -144,14 +144,14 @@ func (*proposalBondTxIDsGetter) BaseFeeProposal(*dac.BaseFeeProposalState) ([]id

func (e *proposalVerifier) AddMemberProposal(proposal *dac.AddMemberProposal) error {
// verify that address isn't consortium member and is KYC verified
applicantAddress, err := e.state.GetAddressStates(proposal.ApplicantAddress)
applicantAddrState, err := e.state.GetAddressStates(proposal.ApplicantAddress)
switch {
case err != nil:
return err
case applicantAddress.Is(as.AddressStateConsortium):
case applicantAddrState.Is(as.AddressStateConsortium):
return fmt.Errorf("%w (applicant)", errConsortiumMember)
case applicantAddress.IsNot(as.AddressStateKYCVerified):
return fmt.Errorf("%w (applicant)", errNotKYCVerified)
case !isVerifiedAddrState(applicantAddrState):
return fmt.Errorf("%w (applicant)", errNotVerifiedAddress)
}

// verify that there is no existing add member proposal for this address
Expand Down Expand Up @@ -428,3 +428,9 @@ func mustHaveActiveValidator(s state.Chain, address ids.ShortID) error {
}
return err
}

const addrStateVerifiedBits = as.AddressStateKYCVerified | as.AddressStateKYBVerified

func isVerifiedAddrState(addrState as.AddressState) bool {
return addrState&addrStateVerifiedBits != 0
}
30 changes: 27 additions & 3 deletions vms/platformvm/txs/executor/dac/camino_dac_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ func TestProposalVerifierAddMemberProposal(t *testing.T) {
},
expectedErr: errConsortiumMember,
},
"Applicant address is not kyc verified": {
"Applicant address is not kyc or kyb verified": {
state: func(c *gomock.Controller, utx *txs.AddProposalTx) *state.MockDiff {
s := state.NewMockDiff(c)
s.EXPECT().GetAddressStates(applicantAddress).Return(as.AddressStateEmpty, nil)
Expand All @@ -280,7 +280,7 @@ func TestProposalVerifierAddMemberProposal(t *testing.T) {
signers: [][]*secp256k1.PrivateKey{
{feeOwnerKey}, {bondOwnerKey}, {proposerKey},
},
expectedErr: errNotKYCVerified,
expectedErr: errNotVerifiedAddress,
},
"Already active AddMemberProposal for this applicant": {
state: func(c *gomock.Controller, utx *txs.AddProposalTx) *state.MockDiff {
Expand Down Expand Up @@ -308,7 +308,7 @@ func TestProposalVerifierAddMemberProposal(t *testing.T) {
},
expectedErr: errAlreadyActiveProposal,
},
"OK": {
"OK: Applicant address is kyc verified": {
state: func(c *gomock.Controller, utx *txs.AddProposalTx) *state.MockDiff {
s := state.NewMockDiff(c)
proposalsIterator := state.NewMockProposalsIterator(c)
Expand All @@ -333,6 +333,30 @@ func TestProposalVerifierAddMemberProposal(t *testing.T) {
{feeOwnerKey}, {bondOwnerKey}, {proposerKey},
},
},
"OK: Applicant address is kyb verified": {
state: func(c *gomock.Controller, utx *txs.AddProposalTx) *state.MockDiff {
s := state.NewMockDiff(c)
proposalsIterator := state.NewMockProposalsIterator(c)
proposalsIterator.EXPECT().Next().Return(false)
proposalsIterator.EXPECT().Release()
proposalsIterator.EXPECT().Error().Return(nil)

s.EXPECT().GetAddressStates(applicantAddress).Return(as.AddressStateKYBVerified, nil)
s.EXPECT().GetProposalIterator().Return(proposalsIterator, nil)
return s
},
utx: func() *txs.AddProposalTx {
return &txs.AddProposalTx{
BaseTx: baseTx,
ProposalPayload: proposalBytes,
ProposerAddress: proposerAddr,
ProposerAuth: &secp256k1fx.Input{SigIndices: []uint32{0}},
}
},
signers: [][]*secp256k1.PrivateKey{
{feeOwnerKey}, {bondOwnerKey}, {proposerKey},
},
},
}
for name, tt := range tests {
t.Run(name, func(t *testing.T) {
Expand Down
Loading