mirror of
https://github.com/AthanorLabs/atomic-swap.git
synced 2026-01-08 21:58:07 -05:00
51 lines
1.7 KiB
Go
51 lines
1.7 KiB
Go
// Copyright 2023 The AthanorLabs/atomic-swap Authors
|
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
|
|
package coins
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/cockroachdb/apd/v3"
|
|
)
|
|
|
|
// ValidatePositive is for doing additional input validation on apd.Decimal values
|
|
// that should only contain positive values (like min, max and provided amounts).
|
|
func ValidatePositive(jsonFieldName string, maxDecimals uint8, value *apd.Decimal) error {
|
|
if value == nil {
|
|
return fmt.Errorf("%q is not set", jsonFieldName)
|
|
}
|
|
if value.IsZero() {
|
|
return fmt.Errorf("%q must be non-zero", jsonFieldName)
|
|
}
|
|
if value.Negative {
|
|
return fmt.Errorf("%q cannot be negative", jsonFieldName)
|
|
}
|
|
if value.Form != apd.Finite {
|
|
return fmt.Errorf("%q must be finite", jsonFieldName)
|
|
}
|
|
|
|
// In most cases, this line won't do anything. If the coefficient is divisible
|
|
// by one or more multiples of 10, the zeros are chopped off and added to the
|
|
// exponent (same external value, but different internal representation).
|
|
_, _ = value.Reduce(value)
|
|
|
|
// We could probably go lower, but something is definitely suspicious if
|
|
// someone is sending us amounts with more than 100 digits. The check
|
|
// below does not differentiate between digits before/after the Decimal
|
|
// point.
|
|
numDigits := value.NumDigits() // number of digits in the coefficient
|
|
if numDigits > MaxCoinPrecision {
|
|
return fmt.Errorf("%q has too many digits", jsonFieldName)
|
|
}
|
|
|
|
// We are calling digits after the decimal point "decimals". Since we reduced
|
|
// the value above, each negative exponent value represents a decimal point.
|
|
if value.Exponent < -int32(maxDecimals) {
|
|
return fmt.Errorf("%q has too many decimal points; found=%d max=%d", jsonFieldName,
|
|
-value.Exponent, maxDecimals)
|
|
}
|
|
|
|
return nil
|
|
}
|