Skip to content

Commit

Permalink
Add additional sanity checks to lockup endpoint.
Browse files Browse the repository at this point in the history
  • Loading branch information
poolcoke authored and lazynina committed Jan 24, 2024
1 parent 2f61afb commit 5c4a0d4
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 1 deletion.
25 changes: 24 additions & 1 deletion routes/lockups.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/holiman/uint256"
"io"
"net/http"
"time"
)

type LockedBalanceEntryResponse struct {
Expand Down Expand Up @@ -157,8 +158,30 @@ func (fes *APIServer) CoinLockup(ww http.ResponseWriter, req *http.Request) {
}
}

// TODO: What other validations are required?
// Sanity check that the lockup appears to occur in the future.
currentTimestampNanoSecs := time.Now().UnixNano()
if requestData.UnlockTimestampNanoSecs < currentTimestampNanoSecs {
_AddBadRequestError(ww, fmt.Sprintf("CoinLockup: The unlock timestamp cannot be in the past "+
"(unlock timestamp: %d, current timestamp: %d)\n",
requestData.UnlockTimestampNanoSecs, currentTimestampNanoSecs))
return
}

// Sanity check that the vested lockup does not go into the past.
if requestData.UnlockTimestampNanoSecs > requestData.VestingEndTimestampNanoSecs {
_AddBadRequestError(ww, fmt.Sprintf("CoinLockup: Vested lockups cannot vest into the past "+
"(unlock timestamp: %d, vesting end timestamp: %d\n",
requestData.UnlockTimestampNanoSecs, requestData.VestingEndTimestampNanoSecs))
return
}

// Sanity check that the lockup request amount is non-zero.
if requestData.LockupAmountBaseUnits.IsZero() {
_AddBadRequestError(ww, fmt.Sprintf("CoinLockup: Cannot lockup an amount of zero\n"))
return
}

// Encode the extra data.
extraData, err := EncodeExtraDataMap(requestData.ExtraData)
if err != nil {
_AddBadRequestError(ww, fmt.Sprintf("CoinLockup: Problem encoding ExtraData: %v", err))
Expand Down
39 changes: 39 additions & 0 deletions routes/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -3249,6 +3249,13 @@ type UnlockStakeLimitMapItem struct {
OpCount uint64
}

type LockupLimitMapItem struct {
ProfilePublicKeyBase58Check string
ScopeType lib.LockupLimitScopeTypeString
Operation lib.LockupLimitOperationString
OpCount uint64
}

// TransactionSpendingLimitResponse is a backend struct used to describe the TransactionSpendingLimit for a Derived key
// in a way that can be JSON encoded/decoded.
type TransactionSpendingLimitResponse struct {
Expand Down Expand Up @@ -3286,6 +3293,8 @@ type TransactionSpendingLimitResponse struct {
UnstakeLimitMap []UnstakeLimitMapItem
// UnlockStakeLimitMap is a slice of UnlockStakeLimitMapItems
UnlockStakeLimitMap []UnlockStakeLimitMapItem
// LockupLimitMap is a slice of LockupLimitMapItems
LockupLimitMap []LockupLimitMapItem

// ===== ENCODER MIGRATION lib.UnlimitedDerivedKeysMigration =====
// IsUnlimited determines whether this derived key is unlimited. An unlimited derived key can perform all transactions
Expand Down Expand Up @@ -3683,6 +3692,21 @@ func TransactionSpendingLimitToResponse(
}
}

if len(transactionSpendingLimit.LockupLimitMap) > 0 {
for lockupLimitKey, opCount := range transactionSpendingLimit.LockupLimitMap {
publicKeyBytes := utxoView.GetPublicKeyForPKID(&lockupLimitKey.ProfilePKID)
publicKeyBase58Check := lib.Base58CheckEncode(publicKeyBytes, false, params)
transactionSpendingLimitResponse.LockupLimitMap = append(
transactionSpendingLimitResponse.LockupLimitMap,
LockupLimitMapItem{
ProfilePublicKeyBase58Check: publicKeyBase58Check,
ScopeType: lockupLimitKey.ScopeType.ToScopeString(),
Operation: lockupLimitKey.Operation.ToOperationString(),
OpCount: opCount,
})
}
}

return transactionSpendingLimitResponse
}

Expand Down Expand Up @@ -3890,6 +3914,21 @@ func (fes *APIServer) TransactionSpendingLimitFromResponse(
transactionSpendingLimit.UnlockStakeLimitMap[unlockStakeLimitKey] = unlockStakeLimitMapItem.OpCount
}
}
if len(transactionSpendingLimitResponse.LockupLimitMap) > 0 {
transactionSpendingLimit.LockupLimitMap = make(map[lib.LockupLimitKey]uint64)
for _, lockupLimitMapItem := range transactionSpendingLimitResponse.LockupLimitMap {
profilePublicKey, _, err := lib.Base58CheckDecode(lockupLimitMapItem.ProfilePublicKeyBase58Check)
if err != nil {
return nil, err
}
pkidEntry := utxoView.GetPKIDForPublicKey(profilePublicKey)
transactionSpendingLimit.LockupLimitMap[lib.MakeLockupLimitKey(
*pkidEntry.PKID,
lockupLimitMapItem.ScopeType.ToScopeType(),
lockupLimitMapItem.Operation.ToOperationType(),
)] = lockupLimitMapItem.OpCount
}
}

return transactionSpendingLimit, nil
}
Expand Down

0 comments on commit 5c4a0d4

Please sign in to comment.