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 #378

Merged
merged 1 commit into from
Aug 7, 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 scripts/lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ fi

# The -P option is not supported by the grep version installed by
# default on macos. Since `-o errexit` is ignored in an if
# conditional, triggering the problem here ensures script failure whenTESTS
# conditional, triggering the problem here ensures script failure when
# using an unsupported version of grep.
grep -P 'lint.sh' scripts/lint.sh &> /dev/null || (\
>&2 echo "error: This script requires a recent version of gnu grep.";\
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 @@ -2306,7 +2306,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 @@ -2317,7 +2317,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 @@ -2088,6 +2088,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 @@ -262,7 +262,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 @@ -279,7 +279,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 @@ -307,7 +307,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 @@ -332,6 +332,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