-
Notifications
You must be signed in to change notification settings - Fork 43
/
validate.go
50 lines (42 loc) 路 1.71 KB
/
validate.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// 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
}