repositories
loading repo index
repositories
loading repo index
repository
loading code, commits, and activity
public Clawd ADK gateway launch mirror
stars
latest
clone command
git clone gitlawb://did:key:z6Mkq5mY...iFZ5/my-project-publ...git clone gitlawb://did:key:z6Mkq5mY.../my-project-publ...2fa351d6docs: add automaton and perps launch sources16d ago| #1 | // ============================================================================ |
| #2 | // BPF-Safe 128-bit Types |
| #3 | // ============================================================================ |
| #4 | // |
| #5 | // CRITICAL: Rust 1.77/1.78 changed i128/u128 alignment from 8 to 16 bytes on x86_64, |
| #6 | // but BPF/SBF still uses 8-byte alignment. This causes struct layout mismatches |
| #7 | // when reading/writing 128-bit values on-chain. |
| #8 | // |
| #9 | // These wrapper types use [u64; 2] internally to ensure consistent 8-byte alignment |
| #10 | // across all platforms. See: https://blog.rust-lang.org/2024/03/30/i128-layout-update.html |
| #11 | // |
| #12 | // KANI OPTIMIZATION: For Kani builds, we use transparent newtypes around raw |
| #13 | // primitives. This dramatically reduces SAT solver complexity since Kani doesn't |
| #14 | // have to reason about bit-shifting and array indexing for every 128-bit operation. |
| #15 | |
| #16 | // ============================================================================ |
| #17 | // I128 - Kani-optimized version (transparent newtype) |
| #18 | // ============================================================================ |
| #19 | #[cfg(kani)] |
| #20 | #[repr(transparent)] |
| #21 | #[derive(Clone, Copy, PartialEq, Eq)] |
| #22 | pub struct I128(i128); |
| #23 | |
| #24 | #[cfg(kani)] |
| #25 | impl I128 { |
| #26 | pub const ZERO: Self = Self(0); |
| #27 | pub const MIN: Self = Self(i128::MIN); |
| #28 | pub const MAX: Self = Self(i128::MAX); |
| #29 | |
| #30 | #[inline(always)] |
| #31 | pub const fn new(val: i128) -> Self { |
| #32 | Self(val) |
| #33 | } |
| #34 | |
| #35 | #[inline(always)] |
| #36 | pub const fn get(self) -> i128 { |
| #37 | self.0 |
| #38 | } |
| #39 | |
| #40 | #[inline(always)] |
| #41 | pub fn set(&mut self, val: i128) { |
| #42 | self.0 = val; |
| #43 | } |
| #44 | |
| #45 | #[inline(always)] |
| #46 | pub fn checked_add(self, rhs: i128) -> Option<Self> { |
| #47 | self.0.checked_add(rhs).map(Self) |
| #48 | } |
| #49 | |
| #50 | #[inline(always)] |
| #51 | pub fn checked_sub(self, rhs: i128) -> Option<Self> { |
| #52 | self.0.checked_sub(rhs).map(Self) |
| #53 | } |
| #54 | |
| #55 | #[inline(always)] |
| #56 | pub fn checked_mul(self, rhs: i128) -> Option<Self> { |
| #57 | self.0.checked_mul(rhs).map(Self) |
| #58 | } |
| #59 | |
| #60 | #[inline(always)] |
| #61 | pub fn checked_div(self, rhs: i128) -> Option<Self> { |
| #62 | self.0.checked_div(rhs).map(Self) |
| #63 | } |
| #64 | |
| #65 | #[inline(always)] |
| #66 | pub fn saturating_add(self, rhs: i128) -> Self { |
| #67 | Self(self.0.saturating_add(rhs)) |
| #68 | } |
| #69 | |
| #70 | #[inline(always)] |
| #71 | pub fn saturating_add_i128(self, rhs: I128) -> Self { |
| #72 | Self(self.0.saturating_add(rhs.0)) |
| #73 | } |
| #74 | |
| #75 | #[inline(always)] |
| #76 | pub fn saturating_sub(self, rhs: i128) -> Self { |
| #77 | Self(self.0.saturating_sub(rhs)) |
| #78 | } |
| #79 | |
| #80 | #[inline(always)] |
| #81 | pub fn saturating_sub_i128(self, rhs: I128) -> Self { |
| #82 | Self(self.0.saturating_sub(rhs.0)) |
| #83 | } |
| #84 | |
| #85 | #[inline(always)] |
| #86 | pub fn wrapping_add(self, rhs: i128) -> Self { |
| #87 | Self(self.0.wrapping_add(rhs)) |
| #88 | } |
| #89 | |
| #90 | #[inline(always)] |
| #91 | pub fn abs(self) -> Self { |
| #92 | Self(self.0.abs()) |
| #93 | } |
| #94 | |
| #95 | #[inline(always)] |
| #96 | pub fn unsigned_abs(self) -> u128 { |
| #97 | self.0.unsigned_abs() |
| #98 | } |
| #99 | |
| #100 | #[inline(always)] |
| #101 | pub fn is_zero(self) -> bool { |
| #102 | self.0 == 0 |
| #103 | } |
| #104 | |
| #105 | #[inline(always)] |
| #106 | pub fn is_negative(self) -> bool { |
| #107 | self.0 < 0 |
| #108 | } |
| #109 | |
| #110 | #[inline(always)] |
| #111 | pub fn is_positive(self) -> bool { |
| #112 | self.0 > 0 |
| #113 | } |
| #114 | } |
| #115 | |
| #116 | // ============================================================================ |
| #117 | // I128 - BPF version (array-based for alignment) |
| #118 | // ============================================================================ |
| #119 | /// BPF-safe signed 128-bit integer using [u64; 2] for consistent alignment. |
| #120 | /// Layout: [lo, hi] in little-endian order. |
| #121 | // Kani I128 trait implementations |
| #122 | #[cfg(kani)] |
| #123 | impl Default for I128 { |
| #124 | fn default() -> Self { |
| #125 | Self::ZERO |
| #126 | } |
| #127 | } |
| #128 | |
| #129 | #[cfg(kani)] |
| #130 | impl core::fmt::Debug for I128 { |
| #131 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { |
| #132 | write!(f, "I128({})", self.0) |
| #133 | } |
| #134 | } |
| #135 | |
| #136 | #[cfg(kani)] |
| #137 | impl core::fmt::Display for I128 { |
| #138 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { |
| #139 | write!(f, "{}", self.0) |
| #140 | } |
| #141 | } |
| #142 | |
| #143 | #[cfg(kani)] |
| #144 | impl From<i128> for I128 { |
| #145 | fn from(val: i128) -> Self { |
| #146 | Self(val) |
| #147 | } |
| #148 | } |
| #149 | |
| #150 | #[cfg(kani)] |
| #151 | impl From<i64> for I128 { |
| #152 | fn from(val: i64) -> Self { |
| #153 | Self(val as i128) |
| #154 | } |
| #155 | } |
| #156 | |
| #157 | #[cfg(kani)] |
| #158 | impl From<I128> for i128 { |
| #159 | fn from(val: I128) -> Self { |
| #160 | val.0 |
| #161 | } |
| #162 | } |
| #163 | |
| #164 | #[cfg(kani)] |
| #165 | impl PartialOrd for I128 { |
| #166 | fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { |
| #167 | Some(self.cmp(other)) |
| #168 | } |
| #169 | } |
| #170 | |
| #171 | #[cfg(kani)] |
| #172 | impl Ord for I128 { |
| #173 | fn cmp(&self, other: &Self) -> core::cmp::Ordering { |
| #174 | self.0.cmp(&other.0) |
| #175 | } |
| #176 | } |
| #177 | |
| #178 | #[cfg(kani)] |
| #179 | impl core::ops::Add<i128> for I128 { |
| #180 | type Output = Self; |
| #181 | fn add(self, rhs: i128) -> Self { |
| #182 | Self(self.0.saturating_add(rhs)) |
| #183 | } |
| #184 | } |
| #185 | |
| #186 | #[cfg(kani)] |
| #187 | impl core::ops::Add<I128> for I128 { |
| #188 | type Output = Self; |
| #189 | fn add(self, rhs: I128) -> Self { |
| #190 | Self(self.0.saturating_add(rhs.0)) |
| #191 | } |
| #192 | } |
| #193 | |
| #194 | #[cfg(kani)] |
| #195 | impl core::ops::Sub<i128> for I128 { |
| #196 | type Output = Self; |
| #197 | fn sub(self, rhs: i128) -> Self { |
| #198 | Self(self.0.saturating_sub(rhs)) |
| #199 | } |
| #200 | } |
| #201 | |
| #202 | #[cfg(kani)] |
| #203 | impl core::ops::Sub<I128> for I128 { |
| #204 | type Output = Self; |
| #205 | fn sub(self, rhs: I128) -> Self { |
| #206 | Self(self.0.saturating_sub(rhs.0)) |
| #207 | } |
| #208 | } |
| #209 | |
| #210 | #[cfg(kani)] |
| #211 | impl core::ops::Neg for I128 { |
| #212 | type Output = Self; |
| #213 | fn neg(self) -> Self { |
| #214 | Self(self.0.saturating_neg()) |
| #215 | } |
| #216 | } |
| #217 | |
| #218 | #[cfg(kani)] |
| #219 | impl core::ops::AddAssign<i128> for I128 { |
| #220 | fn add_assign(&mut self, rhs: i128) { |
| #221 | *self = *self + rhs; |
| #222 | } |
| #223 | } |
| #224 | |
| #225 | #[cfg(kani)] |
| #226 | impl core::ops::SubAssign<i128> for I128 { |
| #227 | fn sub_assign(&mut self, rhs: i128) { |
| #228 | *self = *self - rhs; |
| #229 | } |
| #230 | } |
| #231 | |
| #232 | // ============================================================================ |
| #233 | // I128 - BPF version (array-based for alignment) |
| #234 | // ============================================================================ |
| #235 | #[cfg(not(kani))] |
| #236 | #[repr(C)] |
| #237 | #[derive(Clone, Copy, PartialEq, Eq)] |
| #238 | pub struct I128([u64; 2]); |
| #239 | |
| #240 | #[cfg(not(kani))] |
| #241 | impl I128 { |
| #242 | pub const ZERO: Self = Self([0, 0]); |
| #243 | pub const MIN: Self = Self([0, 0x8000_0000_0000_0000]); // i128::MIN |
| #244 | pub const MAX: Self = Self([u64::MAX, 0x7FFF_FFFF_FFFF_FFFF]); // i128::MAX |
| #245 | |
| #246 | #[inline] |
| #247 | pub const fn new(val: i128) -> Self { |
| #248 | Self([val as u64, (val >> 64) as u64]) |
| #249 | } |
| #250 | |
| #251 | #[inline] |
| #252 | pub const fn get(self) -> i128 { |
| #253 | // Sign-extend: treat hi as signed |
| #254 | ((self.0[1] as i128) << 64) | (self.0[0] as u128 as i128) |
| #255 | } |
| #256 | |
| #257 | #[inline] |
| #258 | pub fn set(&mut self, val: i128) { |
| #259 | self.0[0] = val as u64; |
| #260 | self.0[1] = (val >> 64) as u64; |
| #261 | } |
| #262 | |
| #263 | #[inline] |
| #264 | pub fn checked_add(self, rhs: i128) -> Option<Self> { |
| #265 | self.get().checked_add(rhs).map(Self::new) |
| #266 | } |
| #267 | |
| #268 | #[inline] |
| #269 | pub fn checked_sub(self, rhs: i128) -> Option<Self> { |
| #270 | self.get().checked_sub(rhs).map(Self::new) |
| #271 | } |
| #272 | |
| #273 | #[inline] |
| #274 | pub fn checked_mul(self, rhs: i128) -> Option<Self> { |
| #275 | self.get().checked_mul(rhs).map(Self::new) |
| #276 | } |
| #277 | |
| #278 | #[inline] |
| #279 | pub fn checked_div(self, rhs: i128) -> Option<Self> { |
| #280 | self.get().checked_div(rhs).map(Self::new) |
| #281 | } |
| #282 | |
| #283 | #[inline] |
| #284 | pub fn saturating_add(self, rhs: i128) -> Self { |
| #285 | Self::new(self.get().saturating_add(rhs)) |
| #286 | } |
| #287 | |
| #288 | #[inline] |
| #289 | pub fn saturating_add_i128(self, rhs: I128) -> Self { |
| #290 | Self::new(self.get().saturating_add(rhs.get())) |
| #291 | } |
| #292 | |
| #293 | #[inline] |
| #294 | pub fn saturating_sub(self, rhs: i128) -> Self { |
| #295 | Self::new(self.get().saturating_sub(rhs)) |
| #296 | } |
| #297 | |
| #298 | #[inline] |
| #299 | pub fn saturating_sub_i128(self, rhs: I128) -> Self { |
| #300 | Self::new(self.get().saturating_sub(rhs.get())) |
| #301 | } |
| #302 | |
| #303 | #[inline] |
| #304 | pub fn wrapping_add(self, rhs: i128) -> Self { |
| #305 | Self::new(self.get().wrapping_add(rhs)) |
| #306 | } |
| #307 | |
| #308 | #[inline] |
| #309 | pub fn abs(self) -> Self { |
| #310 | Self::new(self.get().abs()) |
| #311 | } |
| #312 | |
| #313 | #[inline] |
| #314 | pub fn unsigned_abs(self) -> u128 { |
| #315 | self.get().unsigned_abs() |
| #316 | } |
| #317 | |
| #318 | #[inline] |
| #319 | pub fn is_zero(self) -> bool { |
| #320 | self.0[0] == 0 && self.0[1] == 0 |
| #321 | } |
| #322 | |
| #323 | #[inline] |
| #324 | pub fn is_negative(self) -> bool { |
| #325 | (self.0[1] as i64) < 0 |
| #326 | } |
| #327 | |
| #328 | #[inline] |
| #329 | pub fn is_positive(self) -> bool { |
| #330 | !self.is_zero() && !self.is_negative() |
| #331 | } |
| #332 | } |
| #333 | |
| #334 | #[cfg(not(kani))] |
| #335 | impl Default for I128 { |
| #336 | fn default() -> Self { |
| #337 | Self::ZERO |
| #338 | } |
| #339 | } |
| #340 | |
| #341 | #[cfg(not(kani))] |
| #342 | impl core::fmt::Debug for I128 { |
| #343 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { |
| #344 | write!(f, "I128({})", self.get()) |
| #345 | } |
| #346 | } |
| #347 | |
| #348 | #[cfg(not(kani))] |
| #349 | impl core::fmt::Display for I128 { |
| #350 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { |
| #351 | write!(f, "{}", self.get()) |
| #352 | } |
| #353 | } |
| #354 | |
| #355 | #[cfg(not(kani))] |
| #356 | impl From<i128> for I128 { |
| #357 | fn from(val: i128) -> Self { |
| #358 | Self::new(val) |
| #359 | } |
| #360 | } |
| #361 | |
| #362 | #[cfg(not(kani))] |
| #363 | impl From<i64> for I128 { |
| #364 | fn from(val: i64) -> Self { |
| #365 | Self::new(val as i128) |
| #366 | } |
| #367 | } |
| #368 | |
| #369 | #[cfg(not(kani))] |
| #370 | impl From<I128> for i128 { |
| #371 | fn from(val: I128) -> Self { |
| #372 | val.get() |
| #373 | } |
| #374 | } |
| #375 | |
| #376 | #[cfg(not(kani))] |
| #377 | impl PartialOrd for I128 { |
| #378 | fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { |
| #379 | Some(self.cmp(other)) |
| #380 | } |
| #381 | } |
| #382 | |
| #383 | #[cfg(not(kani))] |
| #384 | impl Ord for I128 { |
| #385 | fn cmp(&self, other: &Self) -> core::cmp::Ordering { |
| #386 | self.get().cmp(&other.get()) |
| #387 | } |
| #388 | } |
| #389 | |
| #390 | // ============================================================================ |
| #391 | // U128 - Kani-optimized version (transparent newtype) |
| #392 | // ============================================================================ |
| #393 | #[cfg(kani)] |
| #394 | #[repr(transparent)] |
| #395 | #[derive(Clone, Copy, PartialEq, Eq)] |
| #396 | pub struct U128(u128); |
| #397 | |
| #398 | #[cfg(kani)] |
| #399 | impl U128 { |
| #400 | pub const ZERO: Self = Self(0); |
| #401 | pub const MAX: Self = Self(u128::MAX); |
| #402 | |
| #403 | #[inline(always)] |
| #404 | pub const fn new(val: u128) -> Self { |
| #405 | Self(val) |
| #406 | } |
| #407 | |
| #408 | #[inline(always)] |
| #409 | pub const fn get(self) -> u128 { |
| #410 | self.0 |
| #411 | } |
| #412 | |
| #413 | #[inline(always)] |
| #414 | pub fn set(&mut self, val: u128) { |
| #415 | self.0 = val; |
| #416 | } |
| #417 | |
| #418 | #[inline(always)] |
| #419 | pub fn checked_add(self, rhs: u128) -> Option<Self> { |
| #420 | self.0.checked_add(rhs).map(Self) |
| #421 | } |
| #422 | |
| #423 | #[inline(always)] |
| #424 | pub fn checked_sub(self, rhs: u128) -> Option<Self> { |
| #425 | self.0.checked_sub(rhs).map(Self) |
| #426 | } |
| #427 | |
| #428 | #[inline(always)] |
| #429 | pub fn checked_mul(self, rhs: u128) -> Option<Self> { |
| #430 | self.0.checked_mul(rhs).map(Self) |
| #431 | } |
| #432 | |
| #433 | #[inline(always)] |
| #434 | pub fn checked_div(self, rhs: u128) -> Option<Self> { |
| #435 | self.0.checked_div(rhs).map(Self) |
| #436 | } |
| #437 | |
| #438 | #[inline(always)] |
| #439 | pub fn saturating_add(self, rhs: u128) -> Self { |
| #440 | Self(self.0.saturating_add(rhs)) |
| #441 | } |
| #442 | |
| #443 | #[inline(always)] |
| #444 | pub fn saturating_add_u128(self, rhs: U128) -> Self { |
| #445 | Self(self.0.saturating_add(rhs.0)) |
| #446 | } |
| #447 | |
| #448 | #[inline(always)] |
| #449 | pub fn saturating_sub(self, rhs: u128) -> Self { |
| #450 | Self(self.0.saturating_sub(rhs)) |
| #451 | } |
| #452 | |
| #453 | #[inline(always)] |
| #454 | pub fn saturating_sub_u128(self, rhs: U128) -> Self { |
| #455 | Self(self.0.saturating_sub(rhs.0)) |
| #456 | } |
| #457 | |
| #458 | #[inline(always)] |
| #459 | pub fn saturating_mul(self, rhs: u128) -> Self { |
| #460 | Self(self.0.saturating_mul(rhs)) |
| #461 | } |
| #462 | |
| #463 | #[inline(always)] |
| #464 | pub fn wrapping_add(self, rhs: u128) -> Self { |
| #465 | Self(self.0.wrapping_add(rhs)) |
| #466 | } |
| #467 | |
| #468 | #[inline(always)] |
| #469 | pub fn max(self, rhs: Self) -> Self { |
| #470 | if self.0 >= rhs.0 { |
| #471 | self |
| #472 | } else { |
| #473 | rhs |
| #474 | } |
| #475 | } |
| #476 | |
| #477 | #[inline(always)] |
| #478 | pub fn min(self, rhs: Self) -> Self { |
| #479 | if self.0 <= rhs.0 { |
| #480 | self |
| #481 | } else { |
| #482 | rhs |
| #483 | } |
| #484 | } |
| #485 | |
| #486 | #[inline(always)] |
| #487 | pub fn is_zero(self) -> bool { |
| #488 | self.0 == 0 |
| #489 | } |
| #490 | } |
| #491 | |
| #492 | #[cfg(kani)] |
| #493 | impl Default for U128 { |
| #494 | fn default() -> Self { |
| #495 | Self::ZERO |
| #496 | } |
| #497 | } |
| #498 | |
| #499 | #[cfg(kani)] |
| #500 | impl core::fmt::Debug for U128 { |
| #501 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { |
| #502 | write!(f, "U128({})", self.0) |
| #503 | } |
| #504 | } |
| #505 | |
| #506 | #[cfg(kani)] |
| #507 | impl core::fmt::Display for U128 { |
| #508 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { |
| #509 | write!(f, "{}", self.0) |
| #510 | } |
| #511 | } |
| #512 | |
| #513 | #[cfg(kani)] |
| #514 | impl From<u128> for U128 { |
| #515 | fn from(val: u128) -> Self { |
| #516 | Self(val) |
| #517 | } |
| #518 | } |
| #519 | |
| #520 | #[cfg(kani)] |
| #521 | impl From<u64> for U128 { |
| #522 | fn from(val: u64) -> Self { |
| #523 | Self(val as u128) |
| #524 | } |
| #525 | } |
| #526 | |
| #527 | #[cfg(kani)] |
| #528 | impl From<U128> for u128 { |
| #529 | fn from(val: U128) -> Self { |
| #530 | val.0 |
| #531 | } |
| #532 | } |
| #533 | |
| #534 | #[cfg(kani)] |
| #535 | impl PartialOrd for U128 { |
| #536 | fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { |
| #537 | Some(self.cmp(other)) |
| #538 | } |
| #539 | } |
| #540 | |
| #541 | #[cfg(kani)] |
| #542 | impl Ord for U128 { |
| #543 | fn cmp(&self, other: &Self) -> core::cmp::Ordering { |
| #544 | self.0.cmp(&other.0) |
| #545 | } |
| #546 | } |
| #547 | |
| #548 | #[cfg(kani)] |
| #549 | impl core::ops::Add<u128> for U128 { |
| #550 | type Output = Self; |
| #551 | fn add(self, rhs: u128) -> Self { |
| #552 | Self(self.0.saturating_add(rhs)) |
| #553 | } |
| #554 | } |
| #555 | |
| #556 | #[cfg(kani)] |
| #557 | impl core::ops::Add<U128> for U128 { |
| #558 | type Output = Self; |
| #559 | fn add(self, rhs: U128) -> Self { |
| #560 | Self(self.0.saturating_add(rhs.0)) |
| #561 | } |
| #562 | } |
| #563 | |
| #564 | #[cfg(kani)] |
| #565 | impl core::ops::Sub<u128> for U128 { |
| #566 | type Output = Self; |
| #567 | fn sub(self, rhs: u128) -> Self { |
| #568 | Self(self.0.saturating_sub(rhs)) |
| #569 | } |
| #570 | } |
| #571 | |
| #572 | #[cfg(kani)] |
| #573 | impl core::ops::Sub<U128> for U128 { |
| #574 | type Output = Self; |
| #575 | fn sub(self, rhs: U128) -> Self { |
| #576 | Self(self.0.saturating_sub(rhs.0)) |
| #577 | } |
| #578 | } |
| #579 | |
| #580 | #[cfg(kani)] |
| #581 | impl core::ops::Mul<u128> for U128 { |
| #582 | type Output = Self; |
| #583 | fn mul(self, rhs: u128) -> Self { |
| #584 | Self(self.0.saturating_mul(rhs)) |
| #585 | } |
| #586 | } |
| #587 | |
| #588 | #[cfg(kani)] |
| #589 | impl core::ops::Mul<U128> for U128 { |
| #590 | type Output = Self; |
| #591 | fn mul(self, rhs: U128) -> Self { |
| #592 | Self(self.0.saturating_mul(rhs.0)) |
| #593 | } |
| #594 | } |
| #595 | |
| #596 | #[cfg(kani)] |
| #597 | impl core::ops::Div<u128> for U128 { |
| #598 | type Output = Self; |
| #599 | fn div(self, rhs: u128) -> Self { |
| #600 | Self(self.0 / rhs) |
| #601 | } |
| #602 | } |
| #603 | |
| #604 | #[cfg(kani)] |
| #605 | impl core::ops::Div<U128> for U128 { |
| #606 | type Output = Self; |
| #607 | fn div(self, rhs: U128) -> Self { |
| #608 | Self(self.0 / rhs.0) |
| #609 | } |
| #610 | } |
| #611 | |
| #612 | #[cfg(kani)] |
| #613 | impl core::ops::AddAssign<u128> for U128 { |
| #614 | fn add_assign(&mut self, rhs: u128) { |
| #615 | *self = *self + rhs; |
| #616 | } |
| #617 | } |
| #618 | |
| #619 | #[cfg(kani)] |
| #620 | impl core::ops::SubAssign<u128> for U128 { |
| #621 | fn sub_assign(&mut self, rhs: u128) { |
| #622 | *self = *self - rhs; |
| #623 | } |
| #624 | } |
| #625 | |
| #626 | // ============================================================================ |
| #627 | // U128 - BPF version (array-based for alignment) |
| #628 | // ============================================================================ |
| #629 | /// BPF-safe unsigned 128-bit integer using [u64; 2] for consistent alignment. |
| #630 | /// Layout: [lo, hi] in little-endian order. |
| #631 | #[cfg(not(kani))] |
| #632 | #[repr(C)] |
| #633 | #[derive(Clone, Copy, PartialEq, Eq)] |
| #634 | pub struct U128([u64; 2]); |
| #635 | |
| #636 | #[cfg(not(kani))] |
| #637 | impl U128 { |
| #638 | pub const ZERO: Self = Self([0, 0]); |
| #639 | pub const MAX: Self = Self([u64::MAX, u64::MAX]); |
| #640 | |
| #641 | #[inline] |
| #642 | pub const fn new(val: u128) -> Self { |
| #643 | Self([val as u64, (val >> 64) as u64]) |
| #644 | } |
| #645 | |
| #646 | #[inline] |
| #647 | pub const fn get(self) -> u128 { |
| #648 | ((self.0[1] as u128) << 64) | (self.0[0] as u128) |
| #649 | } |
| #650 | |
| #651 | #[inline] |
| #652 | pub fn set(&mut self, val: u128) { |
| #653 | self.0[0] = val as u64; |
| #654 | self.0[1] = (val >> 64) as u64; |
| #655 | } |
| #656 | |
| #657 | #[inline] |
| #658 | pub fn checked_add(self, rhs: u128) -> Option<Self> { |
| #659 | self.get().checked_add(rhs).map(Self::new) |
| #660 | } |
| #661 | |
| #662 | #[inline] |
| #663 | pub fn checked_sub(self, rhs: u128) -> Option<Self> { |
| #664 | self.get().checked_sub(rhs).map(Self::new) |
| #665 | } |
| #666 | |
| #667 | #[inline] |
| #668 | pub fn checked_mul(self, rhs: u128) -> Option<Self> { |
| #669 | self.get().checked_mul(rhs).map(Self::new) |
| #670 | } |
| #671 | |
| #672 | #[inline] |
| #673 | pub fn checked_div(self, rhs: u128) -> Option<Self> { |
| #674 | self.get().checked_div(rhs).map(Self::new) |
| #675 | } |
| #676 | |
| #677 | #[inline] |
| #678 | pub fn saturating_add(self, rhs: u128) -> Self { |
| #679 | Self::new(self.get().saturating_add(rhs)) |
| #680 | } |
| #681 | |
| #682 | #[inline] |
| #683 | pub fn saturating_add_u128(self, rhs: U128) -> Self { |
| #684 | Self::new(self.get().saturating_add(rhs.get())) |
| #685 | } |
| #686 | |
| #687 | #[inline] |
| #688 | pub fn saturating_sub(self, rhs: u128) -> Self { |
| #689 | Self::new(self.get().saturating_sub(rhs)) |
| #690 | } |
| #691 | |
| #692 | #[inline] |
| #693 | pub fn saturating_sub_u128(self, rhs: U128) -> Self { |
| #694 | Self::new(self.get().saturating_sub(rhs.get())) |
| #695 | } |
| #696 | |
| #697 | #[inline] |
| #698 | pub fn saturating_mul(self, rhs: u128) -> Self { |
| #699 | Self::new(self.get().saturating_mul(rhs)) |
| #700 | } |
| #701 | |
| #702 | #[inline] |
| #703 | pub fn wrapping_add(self, rhs: u128) -> Self { |
| #704 | Self::new(self.get().wrapping_add(rhs)) |
| #705 | } |
| #706 | |
| #707 | #[inline] |
| #708 | pub fn max(self, rhs: Self) -> Self { |
| #709 | if self.get() >= rhs.get() { |
| #710 | self |
| #711 | } else { |
| #712 | rhs |
| #713 | } |
| #714 | } |
| #715 | |
| #716 | #[inline] |
| #717 | pub fn min(self, rhs: Self) -> Self { |
| #718 | if self.get() <= rhs.get() { |
| #719 | self |
| #720 | } else { |
| #721 | rhs |
| #722 | } |
| #723 | } |
| #724 | |
| #725 | #[inline] |
| #726 | pub fn is_zero(self) -> bool { |
| #727 | self.0[0] == 0 && self.0[1] == 0 |
| #728 | } |
| #729 | } |
| #730 | |
| #731 | #[cfg(not(kani))] |
| #732 | impl Default for U128 { |
| #733 | fn default() -> Self { |
| #734 | Self::ZERO |
| #735 | } |
| #736 | } |
| #737 | |
| #738 | #[cfg(not(kani))] |
| #739 | impl core::fmt::Debug for U128 { |
| #740 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { |
| #741 | write!(f, "U128({})", self.get()) |
| #742 | } |
| #743 | } |
| #744 | |
| #745 | #[cfg(not(kani))] |
| #746 | impl core::fmt::Display for U128 { |
| #747 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { |
| #748 | write!(f, "{}", self.get()) |
| #749 | } |
| #750 | } |
| #751 | |
| #752 | #[cfg(not(kani))] |
| #753 | impl From<u128> for U128 { |
| #754 | fn from(val: u128) -> Self { |
| #755 | Self::new(val) |
| #756 | } |
| #757 | } |
| #758 | |
| #759 | #[cfg(not(kani))] |
| #760 | impl From<u64> for U128 { |
| #761 | fn from(val: u64) -> Self { |
| #762 | Self::new(val as u128) |
| #763 | } |
| #764 | } |
| #765 | |
| #766 | #[cfg(not(kani))] |
| #767 | impl From<U128> for u128 { |
| #768 | fn from(val: U128) -> Self { |
| #769 | val.get() |
| #770 | } |
| #771 | } |
| #772 | |
| #773 | #[cfg(not(kani))] |
| #774 | impl PartialOrd for U128 { |
| #775 | fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { |
| #776 | Some(self.cmp(other)) |
| #777 | } |
| #778 | } |
| #779 | |
| #780 | #[cfg(not(kani))] |
| #781 | impl Ord for U128 { |
| #782 | fn cmp(&self, other: &Self) -> core::cmp::Ordering { |
| #783 | self.get().cmp(&other.get()) |
| #784 | } |
| #785 | } |
| #786 | |
| #787 | // Arithmetic operators for U128 (BPF version) |
| #788 | #[cfg(not(kani))] |
| #789 | impl core::ops::Add<u128> for U128 { |
| #790 | type Output = Self; |
| #791 | fn add(self, rhs: u128) -> Self { |
| #792 | Self::new(self.get().saturating_add(rhs)) |
| #793 | } |
| #794 | } |
| #795 | |
| #796 | #[cfg(not(kani))] |
| #797 | impl core::ops::Add<U128> for U128 { |
| #798 | type Output = Self; |
| #799 | fn add(self, rhs: U128) -> Self { |
| #800 | Self::new(self.get().saturating_add(rhs.get())) |
| #801 | } |
| #802 | } |
| #803 | |
| #804 | #[cfg(not(kani))] |
| #805 | impl core::ops::Sub<u128> for U128 { |
| #806 | type Output = Self; |
| #807 | fn sub(self, rhs: u128) -> Self { |
| #808 | Self::new(self.get().saturating_sub(rhs)) |
| #809 | } |
| #810 | } |
| #811 | |
| #812 | #[cfg(not(kani))] |
| #813 | impl core::ops::Sub<U128> for U128 { |
| #814 | type Output = Self; |
| #815 | fn sub(self, rhs: U128) -> Self { |
| #816 | Self::new(self.get().saturating_sub(rhs.get())) |
| #817 | } |
| #818 | } |
| #819 | |
| #820 | #[cfg(not(kani))] |
| #821 | impl core::ops::Mul<u128> for U128 { |
| #822 | type Output = Self; |
| #823 | fn mul(self, rhs: u128) -> Self { |
| #824 | Self::new(self.get().saturating_mul(rhs)) |
| #825 | } |
| #826 | } |
| #827 | |
| #828 | #[cfg(not(kani))] |
| #829 | impl core::ops::Mul<U128> for U128 { |
| #830 | type Output = Self; |
| #831 | fn mul(self, rhs: U128) -> Self { |
| #832 | Self::new(self.get().saturating_mul(rhs.get())) |
| #833 | } |
| #834 | } |
| #835 | |
| #836 | #[cfg(not(kani))] |
| #837 | impl core::ops::Div<u128> for U128 { |
| #838 | type Output = Self; |
| #839 | fn div(self, rhs: u128) -> Self { |
| #840 | Self::new(self.get() / rhs) |
| #841 | } |
| #842 | } |
| #843 | |
| #844 | #[cfg(not(kani))] |
| #845 | impl core::ops::Div<U128> for U128 { |
| #846 | type Output = Self; |
| #847 | fn div(self, rhs: U128) -> Self { |
| #848 | Self::new(self.get() / rhs.get()) |
| #849 | } |
| #850 | } |
| #851 | |
| #852 | #[cfg(not(kani))] |
| #853 | impl core::ops::AddAssign<u128> for U128 { |
| #854 | fn add_assign(&mut self, rhs: u128) { |
| #855 | *self = *self + rhs; |
| #856 | } |
| #857 | } |
| #858 | |
| #859 | #[cfg(not(kani))] |
| #860 | impl core::ops::SubAssign<u128> for U128 { |
| #861 | fn sub_assign(&mut self, rhs: u128) { |
| #862 | *self = *self - rhs; |
| #863 | } |
| #864 | } |
| #865 | |
| #866 | // Arithmetic operators for I128 (BPF version) |
| #867 | #[cfg(not(kani))] |
| #868 | impl core::ops::Add<i128> for I128 { |
| #869 | type Output = Self; |
| #870 | fn add(self, rhs: i128) -> Self { |
| #871 | Self::new(self.get().saturating_add(rhs)) |
| #872 | } |
| #873 | } |
| #874 | |
| #875 | #[cfg(not(kani))] |
| #876 | impl core::ops::Add<I128> for I128 { |
| #877 | type Output = Self; |
| #878 | fn add(self, rhs: I128) -> Self { |
| #879 | Self::new(self.get().saturating_add(rhs.get())) |
| #880 | } |
| #881 | } |
| #882 | |
| #883 | #[cfg(not(kani))] |
| #884 | impl core::ops::Sub<i128> for I128 { |
| #885 | type Output = Self; |
| #886 | fn sub(self, rhs: i128) -> Self { |
| #887 | Self::new(self.get().saturating_sub(rhs)) |
| #888 | } |
| #889 | } |
| #890 | |
| #891 | #[cfg(not(kani))] |
| #892 | impl core::ops::Sub<I128> for I128 { |
| #893 | type Output = Self; |
| #894 | fn sub(self, rhs: I128) -> Self { |
| #895 | Self::new(self.get().saturating_sub(rhs.get())) |
| #896 | } |
| #897 | } |
| #898 | |
| #899 | #[cfg(not(kani))] |
| #900 | impl core::ops::Mul<i128> for I128 { |
| #901 | type Output = Self; |
| #902 | fn mul(self, rhs: i128) -> Self { |
| #903 | Self::new(self.get().saturating_mul(rhs)) |
| #904 | } |
| #905 | } |
| #906 | |
| #907 | #[cfg(not(kani))] |
| #908 | impl core::ops::Neg for I128 { |
| #909 | type Output = Self; |
| #910 | fn neg(self) -> Self { |
| #911 | Self::new(-self.get()) |
| #912 | } |
| #913 | } |
| #914 | |
| #915 | #[cfg(not(kani))] |
| #916 | impl core::ops::AddAssign<i128> for I128 { |
| #917 | fn add_assign(&mut self, rhs: i128) { |
| #918 | *self = *self + rhs; |
| #919 | } |
| #920 | } |
| #921 | |
| #922 | #[cfg(not(kani))] |
| #923 | impl core::ops::SubAssign<i128> for I128 { |
| #924 | fn sub_assign(&mut self, rhs: i128) { |
| #925 | *self = *self - rhs; |
| #926 | } |
| #927 | } |
| #928 |