integerinteger-overflowmotokointernet-computer

What is the meaning of "trap" in relation to integer underflow/overflow?


Reading through the docs for Internet Computer's Motoko:

https://sdk.dfinity.org/docs/languages/motoko-at-a-glance.html#_bounded_numbers_trapping

I realised I don't have a good model for what the word "trapping" means here:

Bounded numbers (trapping) Nat8, Nat16, Nat32, Nat64, Int8, Int16, Int32, Int64

trap on over- and underflow

need type annotations specified

literals: 13, 0xf4, -20, 1_000_000

Does it mean that the integer will stay fixed at the maximum/minimum if an attempt to write a number that would cause an overflow/underflow?

What is the origin of the word "trap" in this context? And what is its precise meaning here?


Solution

  • A trap in this context causes the execution to abort. The canister will still be fine but the call being made to the canister will fail. See this part of the manual.

    As a demo, I set up a counter canister with type Nat8 from one of these templates, so it should support values 0..255 inclusive, and initialized it to 250:

    $ cat counter-canister/main.mo 
    actor {
        stable var currentValue: Nat8 = 250;
    
        public func increment(): async () {
            currentValue += 1;
        };
    
        public query func getValue(): async Nat8 {
            currentValue;
        };
    };
    

    I then clicked the "increment" button. It increased from 250 until 255 as expected, then on the next click, this showed up in the browser console:

    vendor.e49a5b15.js:831 Uncaught (in promise) Error: Call was rejected:
      Request ID: 0f549a49b80b31831e423196d086e36c12df51896ffaaa59e99bae7fa66047aa
      Reject code: 5
      Reject text: Canister ryjl3-tyaaa-aaaaa-aaaba-cai trapped explicitly: arithmetic overflow
    
        at pollForResponse (vendor.e49a5b15.js:831)
        at async n (vendor.e49a5b15.js:838)
        at async HTMLButtonElement.n (index.4a11dcea.js:5)
    

    Reloading the page showed that the value was still at the maximum, 255.

    The canister is still perfectly functional. If I had bothered to put a decrement button there as well I could have counted down a bit and then increased the value until I hit the limit again.