forked from FuelLabs/sway
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: add new bare u256 module to std * feat: Add base type + from,into traits * test: setup testing for U256 * cleanup * feat: add impl U256 max, min, bits, new * test: add new test assertions * style: fmt * test: generate oracle file * Update sway-lib-std/src/u256.sw Co-authored-by: John Adler <[email protected]> * fix: remove * import * fix: improve error handling * test: better test coverage * style: fmt * docs: add test comments * test: add more test cases for to_u64() * fix: remove #r prefix from storage lib * test: remove redundant test * refactor: rename to_u64 to as_u64 * Revert "fix: remove #r prefix from storage lib" This reverts commit 8dd0738. Co-authored-by: John Adler <[email protected]>
- Loading branch information
Showing
8 changed files
with
235 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,7 @@ dep reentrancy; | |
dep vm/mod; | ||
dep flags; | ||
dep u128; | ||
dep u256; | ||
dep vec; | ||
|
||
use core::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
library u256; | ||
|
||
use core::num::*; | ||
use ::result::Result; | ||
|
||
/// The 256-bit unsigned integer type. | ||
/// Represented as four 64-bit components: `(a, b, c, d)`, where `value = (a << 192) + (b << 128) + (c << 64) + d`. | ||
pub struct U256 { | ||
a: u64, | ||
b: u64, | ||
c: u64, | ||
d: u64, | ||
} | ||
|
||
pub enum U256Error { | ||
LossOfPrecision: (), | ||
} | ||
|
||
pub trait From { | ||
/// Function for creating a U256 from its u64 components. | ||
pub fn from(a: u64, b: u64, c: u64, d: u64) -> Self; | ||
} { | ||
/// Function for extracting 4 u64s from a U256. | ||
fn into(val: U256) -> (u64, u64, u64, u64) { | ||
(val.a, val.b, val.c, val.d) | ||
} | ||
} | ||
|
||
impl From for U256 { | ||
pub fn from(a: u64, b: u64, c: u64, d: u64) -> U256 { | ||
U256 { | ||
a, b, c, d, | ||
} | ||
} | ||
} | ||
|
||
impl core::ops::Eq for U256 { | ||
/// Function for comparing 2 U256s for equality | ||
pub fn eq(self, other: Self) -> bool { | ||
self.a == other.a && self.b == other.b && self.c == other.c && self.d == other.d | ||
} | ||
} | ||
|
||
impl U256 { | ||
/// Initializes a new, zeroed U256. | ||
pub fn new() -> U256 { | ||
U256 { | ||
a: 0, | ||
b: 0, | ||
c: 0, | ||
d: 0, | ||
} | ||
} | ||
|
||
/// Safely downcast to `u64` without loss of precision. | ||
/// Returns Err if the number > ~u64::max() | ||
pub fn as_u64(self) -> Result<u64, U256Error> { | ||
if self.a == 0 && self.b == 0 && self.c == 0 { | ||
Result::Ok(self.d) | ||
} else { | ||
Result::Err(U256Error::LossOfPrecision) | ||
} | ||
} | ||
|
||
/// The smallest value that can be represented by this integer type. | ||
pub fn min() -> U256 { | ||
U256 { | ||
a: 0, | ||
b: 0, | ||
c: 0, | ||
d: 0, | ||
} | ||
} | ||
|
||
/// The largest value that can be represented by this type, | ||
/// 2<sup>256</sup> - 1. | ||
pub fn max() -> U256 { | ||
U256 { | ||
a: ~u64::max(), | ||
b: ~u64::max(), | ||
c: ~u64::max(), | ||
d: ~u64::max(), | ||
} | ||
} | ||
|
||
/// The size of this type in bits. | ||
pub fn bits() -> u32 { | ||
256 | ||
} | ||
} |
2 changes: 2 additions & 0 deletions
2
test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u256_test/.gitignore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
out | ||
target |
14 changes: 14 additions & 0 deletions
14
test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u256_test/Forc.lock
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
[[package]] | ||
name = 'core' | ||
source = 'path+from-root-31E9CFD36AA5AC17' | ||
dependencies = [] | ||
|
||
[[package]] | ||
name = 'std' | ||
source = 'path+from-root-31E9CFD36AA5AC17' | ||
dependencies = ['core'] | ||
|
||
[[package]] | ||
name = 'u256_test' | ||
source = 'root' | ||
dependencies = ['std'] |
8 changes: 8 additions & 0 deletions
8
test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u256_test/Forc.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
[project] | ||
authors = ["Fuel Labs <[email protected]>"] | ||
entry = "main.sw" | ||
license = "Apache-2.0" | ||
name = "u256_test" | ||
|
||
[dependencies] | ||
std = { path = "../../../../../../../sway-lib-std" } |
14 changes: 14 additions & 0 deletions
14
test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u256_test/json_abi_oracle.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
[ | ||
{ | ||
"inputs": [], | ||
"name": "main", | ||
"outputs": [ | ||
{ | ||
"components": null, | ||
"name": "", | ||
"type": "bool" | ||
} | ||
], | ||
"type": "function" | ||
} | ||
] |
103 changes: 103 additions & 0 deletions
103
test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u256_test/src/main.sw
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
script; | ||
|
||
use core::num::*; | ||
use std::{assert::assert, result::Result, u256::{U256, U256Error}}; | ||
|
||
fn main() -> bool { | ||
// test new() | ||
let new = ~U256::new(); | ||
let empty = U256 { | ||
a: 0, | ||
b: 0, | ||
c: 0, | ||
d: 0, | ||
}; | ||
assert(new == empty); | ||
|
||
// test from() & into() | ||
let(l, m, n, o) = new.into(); | ||
assert(l == 0); | ||
assert(m == 0); | ||
assert(n == 0); | ||
assert(o == 0); | ||
|
||
let a = 11; | ||
let b = 42; | ||
let c = 101; | ||
let d = 69; | ||
let x = ~U256::from(a, b, c, d); | ||
let y = ~U256::from(a, b, c, d); | ||
|
||
assert(x.a == a); | ||
assert(x.a != b); | ||
assert(x.b == b); | ||
assert(x.b != c); | ||
assert(x.c == c); | ||
assert(x.c != d); | ||
assert(x.d == d); | ||
assert(x.d != a); | ||
|
||
let(e, f, g, h) = x.into(); | ||
assert(e == a); | ||
assert(f == b); | ||
assert(g == c); | ||
assert(h == d); | ||
|
||
assert(x == y); | ||
|
||
// test min() & max() | ||
let max = ~U256::max(); | ||
let min = ~U256::min(); | ||
let(one, two, three, four) = max.into(); | ||
assert(one == ~u64::max()); | ||
assert(two == ~u64::max()); | ||
assert(three == ~u64::max()); | ||
assert(four == ~u64::max()); | ||
|
||
let(min_1, min_2, min_3, min_4) = min.into(); | ||
assert(min_1 == ~u64::min()); | ||
assert(min_2 == ~u64::min()); | ||
assert(min_3 == ~u64::min()); | ||
assert(min_4 == ~u64::min()); | ||
|
||
// test as_u64() | ||
let err_1 = ~U256::from(42, 0, 0, 11).as_u64(); | ||
assert(match err_1 { | ||
Result::Err(U256Error::LossOfPrecision) => { | ||
true | ||
}, | ||
_ => { | ||
false | ||
}, | ||
}); | ||
|
||
let err_2 = ~U256::from(0, 42, 0, 11).as_u64(); | ||
assert(match err_2 { | ||
Result::Err(U256Error::LossOfPrecision) => { | ||
true | ||
}, | ||
_ => { | ||
false | ||
}, | ||
}); | ||
|
||
let err_3 = ~U256::from(0, 0, 42, 11).as_u64(); | ||
assert(match err_3 { | ||
Result::Err(U256Error::LossOfPrecision) => { | ||
true | ||
}, | ||
_ => { | ||
false | ||
}, | ||
}); | ||
|
||
|
||
let eleven = ~U256::from(0, 0, 0, 11); | ||
let unwrapped = eleven.as_u64().unwrap(); | ||
assert(unwrapped == 11); | ||
|
||
// test bits() | ||
assert(~U256::bits() == 256u32); | ||
|
||
true | ||
} |
3 changes: 3 additions & 0 deletions
3
test/src/e2e_vm_tests/test_programs/should_pass/stdlib/u256_test/test.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
category = "run" | ||
expected_result = { action = "return", value = 1 } | ||
validate_abi = true |