txscript/scriptnum: add maxscriptnum and maxcltvlength
This commit is contained in:
parent
81b80328bd
commit
6ec9b73a53
3 changed files with 81 additions and 69 deletions
|
@ -12,9 +12,21 @@ const (
|
||||||
maxInt32 = 1<<31 - 1
|
maxInt32 = 1<<31 - 1
|
||||||
minInt32 = -1 << 31
|
minInt32 = -1 << 31
|
||||||
|
|
||||||
// defaultScriptNumLen is the default number of bytes
|
// maxScriptNumLen is the maximum number of bytes data being interpreted
|
||||||
// data being interpreted as an integer may be.
|
// as an integer may be for the majority of op codes.
|
||||||
defaultScriptNumLen = 4
|
maxScriptNumLen = 4
|
||||||
|
|
||||||
|
// cltvMaxScriptNumLen is the maximum number of bytes data being interpreted
|
||||||
|
// as an integer may be for by-time and by-height locks as interpreted by
|
||||||
|
// CHECKLOCKTIMEVERIFY.
|
||||||
|
//
|
||||||
|
// The value comes from the fact that the current transaction locktime
|
||||||
|
// is a uint32 resulting in a maximum locktime of 2^32-1 (the year
|
||||||
|
// 2106). However, scriptNums are signed and therefore a standard
|
||||||
|
// 4-byte scriptNum would only support up to a maximum of 2^31-1 (the
|
||||||
|
// year 2038). Thus, a 5-byte scriptNum is needed since it will support
|
||||||
|
// up to 2^39-1 which allows dates beyond the current locktime limit.
|
||||||
|
cltvMaxScriptNumLen = 5
|
||||||
)
|
)
|
||||||
|
|
||||||
// scriptNum represents a numeric value used in the scripting engine with
|
// scriptNum represents a numeric value used in the scripting engine with
|
||||||
|
@ -178,7 +190,7 @@ func (n scriptNum) Int32() int32 {
|
||||||
// before an ErrStackNumberTooBig is returned. This effectively limits the
|
// before an ErrStackNumberTooBig is returned. This effectively limits the
|
||||||
// range of allowed values.
|
// range of allowed values.
|
||||||
// WARNING: Great care should be taken if passing a value larger than
|
// WARNING: Great care should be taken if passing a value larger than
|
||||||
// defaultScriptNumLen, which could lead to addition and multiplication
|
// maxScriptNumLen, which could lead to addition and multiplication
|
||||||
// overflows.
|
// overflows.
|
||||||
//
|
//
|
||||||
// See the Bytes function documentation for example encodings.
|
// See the Bytes function documentation for example encodings.
|
||||||
|
|
|
@ -104,35 +104,35 @@ func TestMakeScriptNum(t *testing.T) {
|
||||||
err error
|
err error
|
||||||
}{
|
}{
|
||||||
// Minimal encoding must reject negative 0.
|
// Minimal encoding must reject negative 0.
|
||||||
{hexToBytes("80"), 0, defaultScriptNumLen, true, errMinimalData},
|
{hexToBytes("80"), 0, maxScriptNumLen, true, errMinimalData},
|
||||||
|
|
||||||
// Minimally encoded valid values with minimal encoding flag.
|
// Minimally encoded valid values with minimal encoding flag.
|
||||||
// Should not error and return expected integral number.
|
// Should not error and return expected integral number.
|
||||||
{nil, 0, defaultScriptNumLen, true, nil},
|
{nil, 0, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("01"), 1, defaultScriptNumLen, true, nil},
|
{hexToBytes("01"), 1, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("81"), -1, defaultScriptNumLen, true, nil},
|
{hexToBytes("81"), -1, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("7f"), 127, defaultScriptNumLen, true, nil},
|
{hexToBytes("7f"), 127, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("ff"), -127, defaultScriptNumLen, true, nil},
|
{hexToBytes("ff"), -127, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("8000"), 128, defaultScriptNumLen, true, nil},
|
{hexToBytes("8000"), 128, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("8080"), -128, defaultScriptNumLen, true, nil},
|
{hexToBytes("8080"), -128, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("8100"), 129, defaultScriptNumLen, true, nil},
|
{hexToBytes("8100"), 129, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("8180"), -129, defaultScriptNumLen, true, nil},
|
{hexToBytes("8180"), -129, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("0001"), 256, defaultScriptNumLen, true, nil},
|
{hexToBytes("0001"), 256, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("0081"), -256, defaultScriptNumLen, true, nil},
|
{hexToBytes("0081"), -256, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("ff7f"), 32767, defaultScriptNumLen, true, nil},
|
{hexToBytes("ff7f"), 32767, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("ffff"), -32767, defaultScriptNumLen, true, nil},
|
{hexToBytes("ffff"), -32767, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("008000"), 32768, defaultScriptNumLen, true, nil},
|
{hexToBytes("008000"), 32768, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("008080"), -32768, defaultScriptNumLen, true, nil},
|
{hexToBytes("008080"), -32768, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("ffff00"), 65535, defaultScriptNumLen, true, nil},
|
{hexToBytes("ffff00"), 65535, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("ffff80"), -65535, defaultScriptNumLen, true, nil},
|
{hexToBytes("ffff80"), -65535, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("000008"), 524288, defaultScriptNumLen, true, nil},
|
{hexToBytes("000008"), 524288, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("000088"), -524288, defaultScriptNumLen, true, nil},
|
{hexToBytes("000088"), -524288, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("000070"), 7340032, defaultScriptNumLen, true, nil},
|
{hexToBytes("000070"), 7340032, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("0000f0"), -7340032, defaultScriptNumLen, true, nil},
|
{hexToBytes("0000f0"), -7340032, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("00008000"), 8388608, defaultScriptNumLen, true, nil},
|
{hexToBytes("00008000"), 8388608, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("00008080"), -8388608, defaultScriptNumLen, true, nil},
|
{hexToBytes("00008080"), -8388608, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("ffffff7f"), 2147483647, defaultScriptNumLen, true, nil},
|
{hexToBytes("ffffff7f"), 2147483647, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("ffffffff"), -2147483647, defaultScriptNumLen, true, nil},
|
{hexToBytes("ffffffff"), -2147483647, maxScriptNumLen, true, nil},
|
||||||
{hexToBytes("ffffffff7f"), 549755813887, 5, true, nil},
|
{hexToBytes("ffffffff7f"), 549755813887, 5, true, nil},
|
||||||
{hexToBytes("ffffffffff"), -549755813887, 5, true, nil},
|
{hexToBytes("ffffffffff"), -549755813887, 5, true, nil},
|
||||||
{hexToBytes("ffffffffffffff7f"), 9223372036854775807, 8, true, nil},
|
{hexToBytes("ffffffffffffff7f"), 9223372036854775807, 8, true, nil},
|
||||||
|
@ -145,50 +145,50 @@ func TestMakeScriptNum(t *testing.T) {
|
||||||
// Minimally encoded values that are out of range for data that
|
// Minimally encoded values that are out of range for data that
|
||||||
// is interpreted as script numbers with the minimal encoding
|
// is interpreted as script numbers with the minimal encoding
|
||||||
// flag set. Should error and return 0.
|
// flag set. Should error and return 0.
|
||||||
{hexToBytes("0000008000"), 0, defaultScriptNumLen, true, errNumTooBig},
|
{hexToBytes("0000008000"), 0, maxScriptNumLen, true, errNumTooBig},
|
||||||
{hexToBytes("0000008080"), 0, defaultScriptNumLen, true, errNumTooBig},
|
{hexToBytes("0000008080"), 0, maxScriptNumLen, true, errNumTooBig},
|
||||||
{hexToBytes("0000009000"), 0, defaultScriptNumLen, true, errNumTooBig},
|
{hexToBytes("0000009000"), 0, maxScriptNumLen, true, errNumTooBig},
|
||||||
{hexToBytes("0000009080"), 0, defaultScriptNumLen, true, errNumTooBig},
|
{hexToBytes("0000009080"), 0, maxScriptNumLen, true, errNumTooBig},
|
||||||
{hexToBytes("ffffffff00"), 0, defaultScriptNumLen, true, errNumTooBig},
|
{hexToBytes("ffffffff00"), 0, maxScriptNumLen, true, errNumTooBig},
|
||||||
{hexToBytes("ffffffff80"), 0, defaultScriptNumLen, true, errNumTooBig},
|
{hexToBytes("ffffffff80"), 0, maxScriptNumLen, true, errNumTooBig},
|
||||||
{hexToBytes("0000000001"), 0, defaultScriptNumLen, true, errNumTooBig},
|
{hexToBytes("0000000001"), 0, maxScriptNumLen, true, errNumTooBig},
|
||||||
{hexToBytes("0000000081"), 0, defaultScriptNumLen, true, errNumTooBig},
|
{hexToBytes("0000000081"), 0, maxScriptNumLen, true, errNumTooBig},
|
||||||
{hexToBytes("ffffffffffff00"), 0, defaultScriptNumLen, true, errNumTooBig},
|
{hexToBytes("ffffffffffff00"), 0, maxScriptNumLen, true, errNumTooBig},
|
||||||
{hexToBytes("ffffffffffff80"), 0, defaultScriptNumLen, true, errNumTooBig},
|
{hexToBytes("ffffffffffff80"), 0, maxScriptNumLen, true, errNumTooBig},
|
||||||
{hexToBytes("ffffffffffffff00"), 0, defaultScriptNumLen, true, errNumTooBig},
|
{hexToBytes("ffffffffffffff00"), 0, maxScriptNumLen, true, errNumTooBig},
|
||||||
{hexToBytes("ffffffffffffff80"), 0, defaultScriptNumLen, true, errNumTooBig},
|
{hexToBytes("ffffffffffffff80"), 0, maxScriptNumLen, true, errNumTooBig},
|
||||||
{hexToBytes("ffffffffffffff7f"), 0, defaultScriptNumLen, true, errNumTooBig},
|
{hexToBytes("ffffffffffffff7f"), 0, maxScriptNumLen, true, errNumTooBig},
|
||||||
{hexToBytes("ffffffffffffffff"), 0, defaultScriptNumLen, true, errNumTooBig},
|
{hexToBytes("ffffffffffffffff"), 0, maxScriptNumLen, true, errNumTooBig},
|
||||||
|
|
||||||
// Non-minimally encoded, but otherwise valid values with
|
// Non-minimally encoded, but otherwise valid values with
|
||||||
// minimal encoding flag. Should error and return 0.
|
// minimal encoding flag. Should error and return 0.
|
||||||
{hexToBytes("00"), 0, defaultScriptNumLen, true, errMinimalData}, // 0
|
{hexToBytes("00"), 0, maxScriptNumLen, true, errMinimalData}, // 0
|
||||||
{hexToBytes("0100"), 0, defaultScriptNumLen, true, errMinimalData}, // 1
|
{hexToBytes("0100"), 0, maxScriptNumLen, true, errMinimalData}, // 1
|
||||||
{hexToBytes("7f00"), 0, defaultScriptNumLen, true, errMinimalData}, // 127
|
{hexToBytes("7f00"), 0, maxScriptNumLen, true, errMinimalData}, // 127
|
||||||
{hexToBytes("800000"), 0, defaultScriptNumLen, true, errMinimalData}, // 128
|
{hexToBytes("800000"), 0, maxScriptNumLen, true, errMinimalData}, // 128
|
||||||
{hexToBytes("810000"), 0, defaultScriptNumLen, true, errMinimalData}, // 129
|
{hexToBytes("810000"), 0, maxScriptNumLen, true, errMinimalData}, // 129
|
||||||
{hexToBytes("000100"), 0, defaultScriptNumLen, true, errMinimalData}, // 256
|
{hexToBytes("000100"), 0, maxScriptNumLen, true, errMinimalData}, // 256
|
||||||
{hexToBytes("ff7f00"), 0, defaultScriptNumLen, true, errMinimalData}, // 32767
|
{hexToBytes("ff7f00"), 0, maxScriptNumLen, true, errMinimalData}, // 32767
|
||||||
{hexToBytes("00800000"), 0, defaultScriptNumLen, true, errMinimalData}, // 32768
|
{hexToBytes("00800000"), 0, maxScriptNumLen, true, errMinimalData}, // 32768
|
||||||
{hexToBytes("ffff0000"), 0, defaultScriptNumLen, true, errMinimalData}, // 65535
|
{hexToBytes("ffff0000"), 0, maxScriptNumLen, true, errMinimalData}, // 65535
|
||||||
{hexToBytes("00000800"), 0, defaultScriptNumLen, true, errMinimalData}, // 524288
|
{hexToBytes("00000800"), 0, maxScriptNumLen, true, errMinimalData}, // 524288
|
||||||
{hexToBytes("00007000"), 0, defaultScriptNumLen, true, errMinimalData}, // 7340032
|
{hexToBytes("00007000"), 0, maxScriptNumLen, true, errMinimalData}, // 7340032
|
||||||
{hexToBytes("0009000100"), 0, 5, true, errMinimalData}, // 16779520
|
{hexToBytes("0009000100"), 0, 5, true, errMinimalData}, // 16779520
|
||||||
|
|
||||||
// Non-minimally encoded, but otherwise valid values without
|
// Non-minimally encoded, but otherwise valid values without
|
||||||
// minimal encoding flag. Should not error and return expected
|
// minimal encoding flag. Should not error and return expected
|
||||||
// integral number.
|
// integral number.
|
||||||
{hexToBytes("00"), 0, defaultScriptNumLen, false, nil},
|
{hexToBytes("00"), 0, maxScriptNumLen, false, nil},
|
||||||
{hexToBytes("0100"), 1, defaultScriptNumLen, false, nil},
|
{hexToBytes("0100"), 1, maxScriptNumLen, false, nil},
|
||||||
{hexToBytes("7f00"), 127, defaultScriptNumLen, false, nil},
|
{hexToBytes("7f00"), 127, maxScriptNumLen, false, nil},
|
||||||
{hexToBytes("800000"), 128, defaultScriptNumLen, false, nil},
|
{hexToBytes("800000"), 128, maxScriptNumLen, false, nil},
|
||||||
{hexToBytes("810000"), 129, defaultScriptNumLen, false, nil},
|
{hexToBytes("810000"), 129, maxScriptNumLen, false, nil},
|
||||||
{hexToBytes("000100"), 256, defaultScriptNumLen, false, nil},
|
{hexToBytes("000100"), 256, maxScriptNumLen, false, nil},
|
||||||
{hexToBytes("ff7f00"), 32767, defaultScriptNumLen, false, nil},
|
{hexToBytes("ff7f00"), 32767, maxScriptNumLen, false, nil},
|
||||||
{hexToBytes("00800000"), 32768, defaultScriptNumLen, false, nil},
|
{hexToBytes("00800000"), 32768, maxScriptNumLen, false, nil},
|
||||||
{hexToBytes("ffff0000"), 65535, defaultScriptNumLen, false, nil},
|
{hexToBytes("ffff0000"), 65535, maxScriptNumLen, false, nil},
|
||||||
{hexToBytes("00000800"), 524288, defaultScriptNumLen, false, nil},
|
{hexToBytes("00000800"), 524288, maxScriptNumLen, false, nil},
|
||||||
{hexToBytes("00007000"), 7340032, defaultScriptNumLen, false, nil},
|
{hexToBytes("00007000"), 7340032, maxScriptNumLen, false, nil},
|
||||||
{hexToBytes("0009000100"), 16779520, 5, false, nil},
|
{hexToBytes("0009000100"), 16779520, 5, false, nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ func (s *stack) PopInt() (scriptNum, error) {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return makeScriptNum(so, s.verifyMinimalData, defaultScriptNumLen)
|
return makeScriptNum(so, s.verifyMinimalData, maxScriptNumLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PopBool pops the value off the top of the stack, converts it into a bool, and
|
// PopBool pops the value off the top of the stack, converts it into a bool, and
|
||||||
|
@ -123,7 +123,7 @@ func (s *stack) PeekInt(idx int32) (scriptNum, error) {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return makeScriptNum(so, s.verifyMinimalData, defaultScriptNumLen)
|
return makeScriptNum(so, s.verifyMinimalData, maxScriptNumLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PeekBool returns the Nth item on the stack as a bool without removing it.
|
// PeekBool returns the Nth item on the stack as a bool without removing it.
|
||||||
|
|
Loading…
Reference in a new issue