Skip to content

Commit

Permalink
[PVM] AddressStateTx and tests refactoring (#348)
Browse files Browse the repository at this point in the history
(cherry picked from commit 8d23dfe)
  • Loading branch information
evlekht committed Aug 1, 2024
1 parent 2f09c73 commit 671d075
Show file tree
Hide file tree
Showing 17 changed files with 1,134 additions and 899 deletions.
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

0 comments on commit 671d075

Please sign in to comment.