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] AddressStateTx and tests refactoring #372

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 genesis/camino_genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ func buildPGenesis(config *Config, hrp string, xGenesisBytes []byte, xGenesisDat
for _, allocation := range config.Camino.Allocations {
var addrState as.AddressState
if allocation.AddressStates.ConsortiumMember {
addrState |= as.AddressStateConsortiumMember
addrState |= as.AddressStateConsortium
}
if allocation.AddressStates.KYCVerified {
addrState |= as.AddressStateKYCVerified
Expand Down
45 changes: 26 additions & 19 deletions vms/platformvm/addrstate/camino_address_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const (

AddressStateBitRoleAdmin AddressStateBit = 0 // super role

AddressStateBitRoleKYC AddressStateBit = 1 // allows to set KYCVerified and KYCExpired
AddressStateBitRoleKYCAdmin AddressStateBit = 1 // allows to set KYCVerified and KYCExpired
AddressStateBitRoleOffersAdmin AddressStateBit = 2 // allows to set OffersCreator
AddressStateBitRoleConsortiumAdminProposer AddressStateBit = 3 // allows to create admin add/exclude member proposals

Expand All @@ -28,30 +28,33 @@ const (

AddressStateEmpty AddressState = 0

AddressStateRoleAdmin AddressState = AddressState(1) << AddressStateBitRoleAdmin // 0b1
AddressStateRoleKYC AddressState = AddressState(1) << AddressStateBitRoleKYC // 0b10
AddressStateRoleOffersAdmin AddressState = AddressState(1) << AddressStateBitRoleOffersAdmin // 0b100
AddressStateRoleConsortiumAdminProposer AddressState = AddressState(1) << AddressStateBitRoleConsortiumAdminProposer // 0b1000
AddressStateRoleAll AddressState = AddressStateRoleAdmin | AddressStateRoleKYC | // 0b1111
AddressStateRoleOffersAdmin | AddressStateRoleConsortiumAdminProposer
AddressStateRoleAdmin = AddressState(1) << AddressStateBitRoleAdmin // 0b1
AddressStateRoleKYCAdmin = AddressState(1) << AddressStateBitRoleKYCAdmin // 0b10
AddressStateRoleOffersAdmin = AddressState(1) << AddressStateBitRoleOffersAdmin // 0b100
AddressStateRoleConsortiumAdminProposer = AddressState(1) << AddressStateBitRoleConsortiumAdminProposer // 0b1000

AddressStateKYCVerified AddressState = AddressState(1) << AddressStateBitKYCVerified // 0b0100000000000000000000000000000000
AddressStateKYCExpired AddressState = AddressState(1) << AddressStateBitKYCExpired // 0b1000000000000000000000000000000000
AddressStateKYCAll AddressState = AddressStateKYCVerified | AddressStateKYCExpired // 0b1100000000000000000000000000000000
AddressStateKYCVerified = AddressState(1) << AddressStateBitKYCVerified // 0b0100000000000000000000000000000000
AddressStateKYCExpired = AddressState(1) << AddressStateBitKYCExpired // 0b1000000000000000000000000000000000

AddressStateConsortiumMember AddressState = AddressState(1) << AddressStateBitConsortium // 0b0100000000000000000000000000000000000000
AddressStateNodeDeferred AddressState = AddressState(1) << AddressStateBitNodeDeferred // 0b1000000000000000000000000000000000000000
AddressStateVotableBits AddressState = AddressStateConsortiumMember | AddressStateNodeDeferred // 0b1100000000000000000000000000000000000000
AddressStateConsortium = AddressState(1) << AddressStateBitConsortium // 0b0100000000000000000000000000000000000000
AddressStateNodeDeferred = AddressState(1) << AddressStateBitNodeDeferred // 0b1000000000000000000000000000000000000000

AddressStateOffersCreator AddressState = AddressState(1) << AddressStateBitOffersCreator // 0b00100000000000000000000000000000000000000000000000000
AddressStateCaminoProposer AddressState = AddressState(1) << AddressStateBitCaminoProposer // 0b01000000000000000000000000000000000000000000000000000
AddressStateOffersCreator = AddressState(1) << AddressStateBitOffersCreator // 0b0100000000000000000000000000000000000000000000000000
AddressStateCaminoProposer = AddressState(1) << AddressStateBitCaminoProposer // 0b1000000000000000000000000000000000000000000000000000

AddressStateAthensPhaseBits = AddressStateRoleOffersAdmin | AddressStateOffersCreator
AddressStateBerlinPhaseBits = AddressStateCaminoProposer | AddressStateRoleOffersAdmin
// Bit groups (as AddressState)

AddressStateValidBits = AddressStateRoleAll | AddressStateKYCAll | AddressStateVotableBits |
AddressStateSunrisePhaseBits = AddressStateRoleAdmin | AddressStateRoleKYCAdmin | // 0b1100001100000000000000000000000000000011
AddressStateKYCVerified | AddressStateKYCExpired | AddressStateConsortium |
AddressStateNodeDeferred

AddressStateAthensPhaseBits = AddressStateRoleOffersAdmin | AddressStateOffersCreator // 0b0100000000000000000000000000000000000000000000000100

AddressStateBerlinPhaseBits = AddressStateCaminoProposer | AddressStateRoleConsortiumAdminProposer // 0b1000000000000000000000000000000000000000000000001000

AddressStateValidBits = AddressStateSunrisePhaseBits | // 0b1100000000001100001100000000000000000000000000001111
AddressStateAthensPhaseBits |
AddressStateBerlinPhaseBits // 0b1100000000001100001100000000000000000000000000001111
AddressStateBerlinPhaseBits
)

func (as AddressState) Is(state AddressState) bool {
Expand All @@ -61,3 +64,7 @@ func (as AddressState) Is(state AddressState) bool {
func (as AddressState) IsNot(state AddressState) bool {
return as&state != state
}

func (asb AddressStateBit) ToAddressState() AddressState {
return AddressState(1) << asb
}
2 changes: 1 addition & 1 deletion vms/platformvm/camino_helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ func newCaminoGenesisWithUTXOs(caminoGenesisConfig api.Camino, genesisUTXOs []ap
caminoGenesisConfig.ValidatorConsortiumMembers[i] = key.Address()
caminoGenesisConfig.AddressStates = append(caminoGenesisConfig.AddressStates, genesis.AddressState{
Address: key.Address(),
State: as.AddressStateConsortiumMember,
State: as.AddressStateConsortium,
})
}

Expand Down
9 changes: 5 additions & 4 deletions vms/platformvm/camino_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,10 +280,11 @@ func (s *CaminoService) SetAddressState(_ *http.Request, args *SetAddressStateAr

// Create the transaction
tx, err := s.vm.txBuilder.NewAddressStateTx(
targetAddr, // Address to change state
args.Remove, // Add or remove State
args.State, // The state to change
privKeys, // Keys providing the staked tokens
targetAddr, // Address to change state
args.Remove, // Add or remove State
args.State, // The state to change
ids.ShortEmpty, // executor address
privKeys, // Keys providing the staked tokens
change,
)
if err != nil {
Expand Down
24 changes: 18 additions & 6 deletions vms/platformvm/camino_vm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ func TestRemoveDeferredValidator(t *testing.T) {
adminProposerKey.Address(),
false,
as.AddressStateBitRoleConsortiumAdminProposer,
rootAdminKey.Address(),
[]*secp256k1.PrivateKey{rootAdminKey},
outputOwners,
)
Expand All @@ -95,6 +96,7 @@ func TestRemoveDeferredValidator(t *testing.T) {
consortiumMemberKey.Address(),
false,
as.AddressStateBitKYCVerified,
caminoPreFundedKeys[0].Address(),
[]*secp256k1.PrivateKey{caminoPreFundedKeys[0]},
nil,
)
Expand Down Expand Up @@ -153,6 +155,7 @@ func TestRemoveDeferredValidator(t *testing.T) {
consortiumMemberKey.Address(),
false,
as.AddressStateBitNodeDeferred,
caminoPreFundedKeys[0].Address(),
[]*secp256k1.PrivateKey{caminoPreFundedKeys[0]},
outputOwners,
)
Expand All @@ -167,7 +170,7 @@ func TestRemoveDeferredValidator(t *testing.T) {

// Verify that the validator's owner's deferred state and consortium member is true
ownerState, _ := vm.state.GetAddressStates(consortiumMemberKey.Address())
require.Equal(ownerState, as.AddressStateNodeDeferred|as.AddressStateConsortiumMember|as.AddressStateKYCVerified)
require.Equal(ownerState, as.AddressStateNodeDeferred|as.AddressStateConsortium|as.AddressStateKYCVerified)

// Fast-forward clock to time for validator to be rewarded
vm.clock.Set(endTime)
Expand Down Expand Up @@ -218,7 +221,7 @@ func TestRemoveDeferredValidator(t *testing.T) {

// Verify that the validator's owner's deferred state is false
ownerState, _ = vm.state.GetAddressStates(consortiumMemberKey.Address())
require.Equal(ownerState, as.AddressStateConsortiumMember|as.AddressStateKYCVerified)
require.Equal(ownerState, as.AddressStateConsortium|as.AddressStateKYCVerified)

timestamp := vm.state.GetTimestamp()
require.Equal(endTime.Unix(), timestamp.Unix())
Expand Down Expand Up @@ -272,6 +275,7 @@ func TestRemoveReactivatedValidator(t *testing.T) {
adminProposerKey.Address(),
false,
as.AddressStateBitRoleConsortiumAdminProposer,
rootAdminKey.Address(),
[]*secp256k1.PrivateKey{rootAdminKey},
outputOwners,
)
Expand All @@ -281,6 +285,7 @@ func TestRemoveReactivatedValidator(t *testing.T) {
consortiumMemberKey.Address(),
false,
as.AddressStateBitKYCVerified,
caminoPreFundedKeys[0].Address(),
[]*secp256k1.PrivateKey{caminoPreFundedKeys[0]},
nil,
)
Expand Down Expand Up @@ -340,6 +345,7 @@ func TestRemoveReactivatedValidator(t *testing.T) {
consortiumMemberKey.Address(),
false,
as.AddressStateBitNodeDeferred,
caminoPreFundedKeys[0].Address(),
[]*secp256k1.PrivateKey{caminoPreFundedKeys[0]},
outputOwners,
)
Expand All @@ -357,6 +363,7 @@ func TestRemoveReactivatedValidator(t *testing.T) {
consortiumMemberKey.Address(),
true,
as.AddressStateBitNodeDeferred,
caminoPreFundedKeys[0].Address(),
[]*secp256k1.PrivateKey{caminoPreFundedKeys[0]},
outputOwners,
)
Expand Down Expand Up @@ -600,6 +607,7 @@ func TestProposals(t *testing.T) {
proposerAddr,
false,
as.AddressStateBitCaminoProposer,
caminoPreFundedKeys[0].Address(),
[]*secp256k1.PrivateKey{caminoPreFundedKeys[0]},
nil,
)
Expand Down Expand Up @@ -741,6 +749,7 @@ func TestAdminProposals(t *testing.T) {
proposerAddr,
false,
as.AddressStateBitRoleConsortiumAdminProposer,
caminoPreFundedKeys[0].Address(),
[]*secp256k1.PrivateKey{caminoPreFundedKeys[0]},
nil,
)
Expand All @@ -750,13 +759,14 @@ func TestAdminProposals(t *testing.T) {
checkTx(t, vm, blk.ID(), addrStateTx.ID())
applicantAddrState, err := vm.state.GetAddressStates(applicantAddr)
require.NoError(err)
require.True(applicantAddrState.IsNot(as.AddressStateConsortiumMember))
require.True(applicantAddrState.IsNot(as.AddressStateConsortium))

// Make applicant (see admin proposal below) kyc-verified
addrStateTx, err = vm.txBuilder.NewAddressStateTx(
applicantAddr,
false,
as.AddressStateBitKYCVerified,
caminoPreFundedKeys[0].Address(),
[]*secp256k1.PrivateKey{caminoPreFundedKeys[0]},
nil,
)
Expand Down Expand Up @@ -805,7 +815,7 @@ func TestAdminProposals(t *testing.T) {
// check that applicant became c-member
applicantAddrState, err = vm.state.GetAddressStates(applicantAddr)
require.NoError(err)
require.True(applicantAddrState.Is(as.AddressStateConsortiumMember))
require.True(applicantAddrState.Is(as.AddressStateConsortium))
}

func TestExcludeMemberProposals(t *testing.T) {
Expand Down Expand Up @@ -933,6 +943,7 @@ func TestExcludeMemberProposals(t *testing.T) {
consortiumAdminKey.Address(),
false,
as.AddressStateBitRoleConsortiumAdminProposer,
rootAdminKey.Address(),
[]*secp256k1.PrivateKey{rootAdminKey, fundsKey},
nil,
)
Expand All @@ -959,6 +970,7 @@ func TestExcludeMemberProposals(t *testing.T) {
memberToExcludeAddr,
false,
as.AddressStateBitKYCVerified,
rootAdminKey.Address(),
[]*secp256k1.PrivateKey{rootAdminKey},
nil,
)
Expand Down Expand Up @@ -997,7 +1009,7 @@ func TestExcludeMemberProposals(t *testing.T) {
require.Equal(expectedHeight, height)
memberAddrState, err = vm.state.GetAddressStates(memberToExcludeAddr)
require.NoError(err)
require.Equal(as.AddressStateConsortiumMember|as.AddressStateKYCVerified, memberAddrState)
require.Equal(as.AddressStateConsortium|as.AddressStateKYCVerified, memberAddrState)
bondedAmt -= proposalBondAmount
checkBalance(t, vm.state, fundsAddr,
balance-burnedAmt, // total
Expand Down Expand Up @@ -1226,7 +1238,7 @@ func TestExcludeMemberProposals(t *testing.T) {
0, 0, balance-burnedAmt-bondedAmt, // unlocked
)
} else {
require.Equal(as.AddressStateConsortiumMember|as.AddressStateKYCVerified, memberAddrState)
require.Equal(as.AddressStateConsortium|as.AddressStateKYCVerified, memberAddrState)
if tt.pendingValidator {
require.NoError(pendingValidatorErr)
} else {
Expand Down
6 changes: 3 additions & 3 deletions vms/platformvm/state/camino.go
Original file line number Diff line number Diff line change
Expand Up @@ -386,9 +386,9 @@ func (cs *caminoState) syncGenesis(s *state, g *genesis.State) error {
initalAdminAddressState|as.AddressStateRoleAdmin)

addrStateTx, err := txs.NewSigned(&txs.AddressStateTx{
Address: g.Camino.InitialAdmin,
State: as.AddressStateBitRoleAdmin,
Remove: false,
Address: g.Camino.InitialAdmin,
StateBit: as.AddressStateBitRoleAdmin,
Remove: false,
}, txs.Codec, nil)
if err != nil {
return err
Expand Down
4 changes: 2 additions & 2 deletions vms/platformvm/state/camino_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,13 +253,13 @@ func TestSyncGenesis(t *testing.T) {
},
{
Address: shortID,
State: as.AddressStateRoleKYC,
State: as.AddressStateRoleKYCAdmin,
},
}, depositTxs, initialAdmin),
},
cs: *wrappers.IgnoreError(newCaminoState(baseDB, validatorsDB, prometheus.NewRegistry())).(*caminoState),
want: caminoDiff{
modifiedAddressStates: map[ids.ShortID]as.AddressState{initialAdmin: as.AddressStateRoleAdmin, shortID: as.AddressStateRoleKYC},
modifiedAddressStates: map[ids.ShortID]as.AddressState{initialAdmin: as.AddressStateRoleAdmin, shortID: as.AddressStateRoleKYCAdmin},
modifiedDepositOffers: map[ids.ID]*deposit.Offer{
depositOffers[0].ID: depositOffers[0],
depositOffers[1].ID: depositOffers[1],
Expand Down
72 changes: 55 additions & 17 deletions vms/platformvm/txs/builder/camino_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"fmt"

"github.com/ava-labs/avalanchego/chains/atomic"
"github.com/ava-labs/avalanchego/codec"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/snow"
"github.com/ava-labs/avalanchego/utils"
Expand All @@ -32,12 +33,14 @@ var (
fakeTreasuryKey = secp256k1.FakePrivateKey(treasury.Addr)
fakeTreasuryKeychain = secp256k1fx.NewKeychain(fakeTreasuryKey)

errKeyMissing = errors.New("couldn't find key matching address")
errWrongNodeKeyType = errors.New("node key type isn't *secp256k1.PrivateKey")
errNotSECPOwner = errors.New("owner is not *secp256k1fx.OutputOwners")
errWrongLockMode = errors.New("this tx can't be used with this caminoGenesis.LockModeBondDeposit")
errNoUTXOsForImport = errors.New("no utxos for import")
errWrongOutType = errors.New("wrong output type")
errKeyMissing = errors.New("couldn't find key matching address")
errWrongNodeKeyType = errors.New("node key type isn't *secp256k1.PrivateKey")
errNotSECPOwner = errors.New("owner is not *secp256k1fx.OutputOwners")
errWrongLockMode = errors.New("this tx can't be used with this caminoGenesis.LockModeBondDeposit")
errNoUTXOsForImport = errors.New("no utxos for import")
errWrongOutType = errors.New("wrong output type")
errEmptyAddress = errors.New("address is empty")
errEmptyExecutorAddress = errors.New("executor address is empty")
)

type CaminoBuilder interface {
Expand All @@ -63,6 +66,7 @@ type CaminoTxBuilder interface {
address ids.ShortID,
remove bool,
state as.AddressStateBit,
executor ids.ShortID,
keys []*secp256k1.PrivateKey,
change *secp256k1fx.OutputOwners,
) (*txs.Tx, error)
Expand Down Expand Up @@ -302,6 +306,7 @@ func (b *caminoBuilder) NewAddressStateTx(
address ids.ShortID,
remove bool,
state as.AddressStateBit,
executor ids.ShortID,
keys []*secp256k1.PrivateKey,
change *secp256k1fx.OutputOwners,
) (*txs.Tx, error) {
Expand All @@ -310,18 +315,51 @@ func (b *caminoBuilder) NewAddressStateTx(
return nil, fmt.Errorf("couldn't generate tx inputs/outputs: %w", err)
}

// Create the tx
utx := &txs.AddressStateTx{
BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{
NetworkID: b.ctx.NetworkID,
BlockchainID: b.ctx.ChainID,
Ins: ins,
Outs: outs,
}},
Address: address,
Remove: remove,
State: state,
isBerlin := b.cfg.IsBerlinPhaseActivated(b.state.GetTimestamp())

switch {
case address == ids.ShortEmpty:
return nil, errEmptyAddress
case isBerlin && executor == ids.ShortEmpty:
return nil, errEmptyExecutorAddress
}

executorSigner, err := getSigner(keys, executor)
if err != nil {
return nil, err
}

var utx *txs.AddressStateTx
if isBerlin {
utx = &txs.AddressStateTx{
UpgradeVersionID: codec.UpgradeVersion1,
BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{
NetworkID: b.ctx.NetworkID,
BlockchainID: b.ctx.ChainID,
Ins: ins,
Outs: outs,
}},
Address: address,
Remove: remove,
StateBit: state,
Executor: executor,
ExecutorAuth: &secp256k1fx.Input{SigIndices: []uint32{0}},
}
signers = append(signers, executorSigner)
} else {
utx = &txs.AddressStateTx{
BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{
NetworkID: b.ctx.NetworkID,
BlockchainID: b.ctx.ChainID,
Ins: ins,
Outs: outs,
}},
Address: address,
Remove: remove,
StateBit: state,
}
}

tx, err := txs.NewSigned(utx, txs.Codec, signers)
if err != nil {
return nil, err
Expand Down
Loading