2018-04-06 14:52:10 +00:00
|
|
|
# Nimbus
|
|
|
|
# Copyright (c) 2018 Status Research & Development GmbH
|
|
|
|
# Licensed under either of
|
|
|
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
|
|
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
|
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
|
2018-05-07 12:41:54 +00:00
|
|
|
import stint, constants, strformat, strutils, sequtils, endians, macros, utils / padding, rlp
|
2018-01-16 17:05:20 +00:00
|
|
|
|
2018-03-13 14:30:38 +00:00
|
|
|
# some methods based on py-evm utils/numeric
|
|
|
|
|
2018-02-20 17:27:43 +00:00
|
|
|
# TODO improve
|
2018-01-15 18:42:40 +00:00
|
|
|
|
2018-02-20 17:27:43 +00:00
|
|
|
proc intToBigEndian*(value: UInt256): Bytes =
|
2018-05-07 12:41:54 +00:00
|
|
|
result = newSeq[byte](32)
|
|
|
|
let v_ptr = cast[ptr array[32, byte]](value.unsafeAddr)
|
|
|
|
|
|
|
|
for idx, val in result.mpairs:
|
|
|
|
when system.cpuEndian == littleEndian:
|
|
|
|
val = v_ptr[32 - 1 - idx]
|
|
|
|
else:
|
|
|
|
val = v_ptr[idx]
|
2018-04-06 14:52:10 +00:00
|
|
|
|
2018-02-20 17:27:43 +00:00
|
|
|
proc bigEndianToInt*(value: Bytes): UInt256 =
|
|
|
|
var bytes = value.padLeft(32, 0.byte)
|
2018-05-07 12:41:54 +00:00
|
|
|
let v_ptr = cast[ptr array[32, byte]](result.addr)
|
|
|
|
|
|
|
|
for idx, val in bytes:
|
|
|
|
when system.cpuEndian == littleEndian:
|
|
|
|
v_ptr[32 - 1 - idx] = val
|
|
|
|
else:
|
|
|
|
v_ptr[idx] = val
|
2018-01-16 17:05:20 +00:00
|
|
|
|
2018-02-20 17:27:43 +00:00
|
|
|
#echo intToBigEndian("32482610168005790164680892356840817100452003984372336767666156211029086934369".u256)
|
2018-01-16 17:05:20 +00:00
|
|
|
|
2018-05-16 08:41:34 +00:00
|
|
|
# proc bitLength*(value: UInt256): int =
|
|
|
|
# 255 - value.countLeadingZeroBits
|
|
|
|
|
2018-05-25 10:25:19 +00:00
|
|
|
proc log256*(value: UInt256): Natural =
|
|
|
|
(255 - value.countLeadingZeroBits) div 8 # Compilers optimize to `shr 3`
|
2018-05-16 08:41:34 +00:00
|
|
|
|
|
|
|
# proc ceil8*(value: int): int =
|
|
|
|
# let remainder = value mod 8
|
|
|
|
# if remainder == 0:
|
|
|
|
# value
|
|
|
|
# else:
|
|
|
|
# value + 8 - remainder
|
2018-02-28 15:06:05 +00:00
|
|
|
|
2018-02-20 17:27:43 +00:00
|
|
|
proc unsignedToSigned*(value: UInt256): Int256 =
|
|
|
|
0.i256
|
2018-05-17 08:08:28 +00:00
|
|
|
# TODO Remove stub (used in quasiBoolean for signed comparison)
|
2018-02-20 17:27:43 +00:00
|
|
|
|
|
|
|
proc signedToUnsigned*(value: Int256): UInt256 =
|
|
|
|
0.u256
|
2018-05-17 08:08:28 +00:00
|
|
|
# TODO Remove stub (used in quasiBoolean for signed comparison)
|
|
|
|
|
|
|
|
proc unsignedToPseudoSigned*(value: UInt256): UInt256 =
|
|
|
|
result = value
|
|
|
|
if value > INT_256_MAX_AS_UINT256:
|
|
|
|
result -= INT_256_MAX_AS_UINT256
|
|
|
|
|
|
|
|
proc pseudoSignedToUnsigned*(value: UInt256): UInt256 =
|
|
|
|
result = value
|
|
|
|
if value > INT_256_MAX_AS_UINT256:
|
|
|
|
result += INT_256_MAX_AS_UINT256
|
2018-01-16 17:05:20 +00:00
|
|
|
|
2018-03-13 14:30:38 +00:00
|
|
|
# it's deasible to map nameXX methods like that (originally decorator)
|
2018-01-16 17:05:20 +00:00
|
|
|
macro ceilXX(ceiling: static[int]): untyped =
|
2018-01-22 22:23:07 +00:00
|
|
|
var name = ident(&"ceil{ceiling}")
|
2018-01-16 17:05:20 +00:00
|
|
|
result = quote:
|
2018-05-25 10:25:19 +00:00
|
|
|
proc `name`*(value: Natural): Natural =
|
|
|
|
var remainder = value mod `ceiling`
|
2018-01-16 17:05:20 +00:00
|
|
|
if remainder == 0:
|
|
|
|
return value
|
|
|
|
else:
|
2018-05-25 10:25:19 +00:00
|
|
|
return value + `ceiling` - remainder
|
2018-01-16 18:42:38 +00:00
|
|
|
|
2018-01-16 17:05:20 +00:00
|
|
|
|
|
|
|
ceilXX(32)
|
|
|
|
ceilXX(8)
|