Skip to content

Commit

Permalink
P-chain - Memo field zeroed post Durango (#2607)
Browse files Browse the repository at this point in the history
Signed-off-by: Stephen Buttolph <stephen@avalabs.org>
Co-authored-by: Stephen Buttolph <stephen@avalabs.org>
Co-authored-by: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com>
  • Loading branch information
3 people authored Jan 19, 2024
1 parent a054afd commit 3d4feed
Show file tree
Hide file tree
Showing 5 changed files with 761 additions and 57 deletions.
18 changes: 18 additions & 0 deletions vms/components/avax/base_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,21 @@ func (t *BaseTx) Verify(ctx *snow.Context) error {
return nil
}
}

func VerifyMemoFieldLength(memo types.JSONByteSlice, isDurangoActive bool) error {
if !isDurangoActive {
// SyntacticVerify validates this field pre-Durango
return nil
}

if len(memo) != 0 {
return fmt.Errorf(
"%w: %d > %d",
ErrMemoTooLarge,
len(memo),
0,
)
}

return nil
}
63 changes: 50 additions & 13 deletions vms/platformvm/txs/executor/staker_tx_verification.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,16 @@ func verifyAddValidatorTx(
var (
currentTimestamp = chainState.GetTimestamp()
isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp)
startTime = currentTimestamp
)
if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil {
return nil, err
}

startTime := currentTimestamp
if !isDurangoActive {
startTime = tx.StartTime()
}

duration := tx.EndTime().Sub(startTime)
switch {
case tx.Validator.Wght < backend.Config.MinValidatorStake:
Expand Down Expand Up @@ -194,8 +199,12 @@ func verifyAddSubnetValidatorTx(
var (
currentTimestamp = chainState.GetTimestamp()
isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp)
startTime = currentTimestamp
)
if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil {
return err
}

startTime := currentTimestamp
if !isDurangoActive {
startTime = tx.StartTime()
}
Expand Down Expand Up @@ -283,6 +292,14 @@ func verifyRemoveSubnetValidatorTx(
return nil, false, err
}

var (
currentTimestamp = chainState.GetTimestamp()
isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp)
)
if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil {
return nil, false, err
}

isCurrentValidator := true
vdr, err := chainState.GetCurrentValidator(tx.Subnet, tx.NodeID)
if err == database.ErrNotFound {
Expand Down Expand Up @@ -351,8 +368,14 @@ func verifyAddDelegatorTx(
var (
currentTimestamp = chainState.GetTimestamp()
isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp)
endTime = tx.EndTime()
startTime = currentTimestamp
)
if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil {
return nil, err
}

var (
endTime = tx.EndTime()
startTime = currentTimestamp
)
if !isDurangoActive {
startTime = tx.StartTime()
Expand Down Expand Up @@ -458,15 +481,19 @@ func verifyAddPermissionlessValidatorTx(
return err
}

if !backend.Bootstrapped.Get() {
return nil
}

var (
currentTimestamp = chainState.GetTimestamp()
isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp)
startTime = currentTimestamp
)
if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil {
return err
}

if !backend.Bootstrapped.Get() {
return nil
}

startTime := currentTimestamp
if !isDurangoActive {
startTime = tx.StartTime()
}
Expand Down Expand Up @@ -578,15 +605,21 @@ func verifyAddPermissionlessDelegatorTx(
return err
}

var (
currentTimestamp = chainState.GetTimestamp()
isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp)
)
if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil {
return err
}

if !backend.Bootstrapped.Get() {
return nil
}

var (
currentTimestamp = chainState.GetTimestamp()
isDurangoActive = backend.Config.IsDurangoActivated(currentTimestamp)
endTime = tx.EndTime()
startTime = currentTimestamp
endTime = tx.EndTime()
startTime = currentTimestamp
)
if !isDurangoActive {
startTime = tx.StartTime()
Expand Down Expand Up @@ -728,6 +761,10 @@ func verifyTransferSubnetOwnershipTx(
return err
}

if err := avax.VerifyMemoFieldLength(tx.Memo, true /*=isDurangoActive*/); err != nil {
return err
}

if !backend.Bootstrapped.Get() {
// Not bootstrapped yet -- don't need to do full verification.
return nil
Expand Down
6 changes: 4 additions & 2 deletions vms/platformvm/txs/executor/staker_tx_verification_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,15 @@ func TestVerifyAddPermissionlessValidatorTx(t *testing.T) {
}
},
stateF: func(ctrl *gomock.Controller) state.Chain {
return nil
mockState := state.NewMockChain(ctrl)
mockState.EXPECT().GetTimestamp().Return(now) // chain time is after Durango fork activation since now.After(activeForkTime)
return mockState
},
sTxF: func() *txs.Tx {
return &verifiedSignedTx
},
txF: func() *txs.AddPermissionlessValidatorTx {
return nil
return &txs.AddPermissionlessValidatorTx{}
},
expectedErr: nil,
},
Expand Down
50 changes: 46 additions & 4 deletions vms/platformvm/txs/executor/standard_tx_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,21 @@ func (e *StandardTxExecutor) CreateChainTx(tx *txs.CreateChainTx) error {
return err
}

var (
currentTimestamp = e.State.GetTimestamp()
isDurangoActive = e.Config.IsDurangoActivated(currentTimestamp)
)
if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil {
return err
}

baseTxCreds, err := verifyPoASubnetAuthorization(e.Backend, e.State, e.Tx, tx.SubnetID, tx.SubnetAuth)
if err != nil {
return err
}

// Verify the flowcheck
timestamp := e.State.GetTimestamp()
createBlockchainTxFee := e.Config.GetCreateBlockchainTxFee(timestamp)
createBlockchainTxFee := e.Config.GetCreateBlockchainTxFee(currentTimestamp)
if err := e.FlowChecker.VerifySpend(
tx,
e.State,
Expand Down Expand Up @@ -98,9 +105,16 @@ func (e *StandardTxExecutor) CreateSubnetTx(tx *txs.CreateSubnetTx) error {
return err
}

var (
currentTimestamp = e.State.GetTimestamp()
isDurangoActive = e.Config.IsDurangoActivated(currentTimestamp)
)
if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil {
return err
}

// Verify the flowcheck
timestamp := e.State.GetTimestamp()
createSubnetTxFee := e.Config.GetCreateSubnetTxFee(timestamp)
createSubnetTxFee := e.Config.GetCreateSubnetTxFee(currentTimestamp)
if err := e.FlowChecker.VerifySpend(
tx,
e.State,
Expand Down Expand Up @@ -131,6 +145,14 @@ func (e *StandardTxExecutor) ImportTx(tx *txs.ImportTx) error {
return err
}

var (
currentTimestamp = e.State.GetTimestamp()
isDurangoActive = e.Config.IsDurangoActivated(currentTimestamp)
)
if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil {
return err
}

e.Inputs = set.NewSet[ids.ID](len(tx.ImportedInputs))
utxoIDs := make([][]byte, len(tx.ImportedInputs))
for i, in := range tx.ImportedInputs {
Expand Down Expand Up @@ -209,6 +231,14 @@ func (e *StandardTxExecutor) ExportTx(tx *txs.ExportTx) error {
return err
}

var (
currentTimestamp = e.State.GetTimestamp()
isDurangoActive = e.Config.IsDurangoActivated(currentTimestamp)
)
if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil {
return err
}

outs := make([]*avax.TransferableOutput, len(tx.Outs)+len(tx.ExportedOutputs))
copy(outs, tx.Outs)
copy(outs[len(tx.Outs):], tx.ExportedOutputs)
Expand Down Expand Up @@ -386,6 +416,14 @@ func (e *StandardTxExecutor) TransformSubnetTx(tx *txs.TransformSubnetTx) error
return err
}

var (
currentTimestamp = e.State.GetTimestamp()
isDurangoActive = e.Config.IsDurangoActivated(currentTimestamp)
)
if err := avax.VerifyMemoFieldLength(tx.Memo, isDurangoActive); err != nil {
return err
}

// Note: math.MaxInt32 * time.Second < math.MaxInt64 - so this can never
// overflow.
if time.Duration(tx.MaxStakeDuration)*time.Second > e.Backend.Config.MaxStakeDuration {
Expand Down Expand Up @@ -512,6 +550,10 @@ func (e *StandardTxExecutor) BaseTx(tx *txs.BaseTx) error {
return err
}

if err := avax.VerifyMemoFieldLength(tx.Memo, true /*=isDurangoActive*/); err != nil {
return err
}

// Verify the flowcheck
if err := e.FlowChecker.VerifySpend(
tx,
Expand Down
Loading

0 comments on commit 3d4feed

Please sign in to comment.