Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Function_Call results in AssertionError/Unexpected Upcast #428

Open
ALuhning opened this issue Mar 1, 2021 · 2 comments
Open

Function_Call results in AssertionError/Unexpected Upcast #428

ALuhning opened this issue Mar 1, 2021 · 2 comments
Labels
bug Something isn't working T-dev-tools

Comments

@ALuhning
Copy link
Contributor

ALuhning commented Mar 1, 2021

Describe the bug
Having a hard time getting function_call to work with AS. Trying to call from contract results in an assertion failed and unexpected upcast errors regardless of how the arguments are passed in.

To Reproduce
Steps to reproduce the behavior:
1. Create a function_call in a contract such as:

promise.function_call(
'init',
args,
u128.Zero,
env.prepaid_gas() - CREATE_CALL_GAS
)

2. Pass in some args either from frontend like:
`const argsList =

{ "purpose": purpose.value, "council": council.value.split('\n'), "bond": utils.format.parseNearAmount(bond.value), "vote_period": (parseFloat(votePeriod.value) * 3600 * 1000000000).toFixed().toString(), "grace_period": (parseFloat(gracePeriod.value) * 3600 * 1000000000).toFixed().toString() }

`

or just add some args in the contract such as:

` ContractPromiseBatch.create(context.contractName).function_call(
"tick",
"

{"counter":"10"}

",
u128.Zero,
context.prepaidGas - context.usedGas - RESERVE_GAS
)`

3. Will fail with AssertionError and unexpected upcast error

Expected behavior
Expecting the function call to work.

Additional context
Additional information from Discord - user: theophoric

`import

{ ContractPromiseBatch, context, logging, u128 }

from 'near-sdk-as';
const RESERVE_GAS = 10_000_000_000_000;
@nearBindgen
export class Timer {

tick(counter: u32 = 1): void

{ // return if there is not enough gas to process -- instead of running out logging.log("tick: " + counter.toString()); this.tock(counter + 1); }

private tock(counter: u32): void {
// return if
logging.log("tock: " + counter.toString());
counter++;
ContractPromiseBatch.create(context.contractName).function_call<

{counter: u32}>(

"tick",

{counter}

,
u128.Zero,
context.prepaidGas - context.usedGas - RESERVE_GAS
)
}
}`

compiling that outputs pages of minified JS and then:
`...

Error [AssertionError]: assertion failed
at i.assert (/Users/theophoric/Development/NEAR/theophoric/near-boilerplate-as/contract/node_modules/assemblyscript/dist/assemblyscript.js:7:701252)
at h.resolveFunction (/Users/theophoric/Development/NEAR/theophoric/near-boilerplate-as/contract/node_modules/assemblyscript/dist/assemblyscript.js:7:635274)
at T.compilePropertyAccessExpression (/Users/theophoric/Development/NEAR/theophoric/near-boilerplate-as/contract/node_modules/assemblyscript/dist/assemblyscript.js:7:326466)
at T.compileExpression (/Users/theophoric/Development/NEAR/theophoric/near-boilerplate-as/contract/node_modules/assemblyscript/dist/assemblyscript.js:7:238203)
at T.compileBinaryExpression (/Users/theophoric/Development/NEAR/theophoric/near-boilerplate-as/contract/node_modules/assemblyscript/dist/assemblyscript.js:7:242966)
at T.compileExpression (/Users/theophoric/Development/NEAR/theophoric/near-boilerplate-as/contract/node_modules/assemblyscript/dist/assemblyscript.js:7:237442)
at T.compileBinaryExpression (/Users/theophoric/Development/NEAR/theophoric/near-boilerplate-as/contract/node_modules/assemblyscript/dist/assemblyscript.js:7:243584)
at T.compileExpression (/Users/theophoric/Development/NEAR/theophoric/near-boilerplate-as/contract/node_modules/assemblyscript/dist/assemblyscript.js:7:237442)
at T.compileExpressionStatement (/Users/theophoric/Development/NEAR/theophoric/near-boilerplate-as/contract/node_modules/assemblyscript/dist/assemblyscript.js:7:224985)
at T.compileStatement (/Users/theophoric/Development/NEAR/theophoric/near-boilerplate-as/contract/node_modules/assemblyscript/dist/assemblyscript.js:7:220824)`

[message.txt](https://github.com/near/near-sdk-as/files/6061093/message.txt)

Changing the function call in tock to the following:

ContractPromiseBatch.create(context.contractName).function_call<u32>( "tick", 0, u128.Zero, context.prepaidGas - context.usedGas - RESERVE_GAS )

allows it to compile but throws the following error on contract execution:

Log <span class="error">[dev-1614111710072-2942979]</span>: ABORT: unexpected upcast, filename: "~lib/near-sdk-bindgen/index.ts" line: 71 col: 20 Failure <span class="error">[dev-1614111710072-2942979]</span>: Error: Smart contract panicked: unexpected upcast, filename: "~lib/near-sdk-bindgen/index.ts" line: 71 col: 20

using a json encoding of the arguments has the same effect:

`private tock(counter: u32): void {
// return if
logging.log("tock: " + counter.toString());
counter++;
ContractPromiseBatch.create(context.contractName).function_call(
"tick",
"

{"counter":"10"}

",
u128.Zero,
context.prepaidGas - context.usedGas - RESERVE_GAS
)
}`

@ALuhning ALuhning added the bug Something isn't working label Mar 1, 2021
@mehtaphysical
Copy link
Contributor

hey, I get the same sort of thing if I don't fill in the function_calls generic type parameter. I no longer get that error if i fill in the generic type parameter function_call<SomeType>. Code here

One other thing, I think the type that you pass has to be encodable. This means you should decorate the type with @nearBindgen . For example:

import { ContractPromiseBatch, context, logging, u128 } from 'near-sdk-as';

const RESERVE_GAS = 10_000_000_000_000;

@nearBindgen
class Counter {
  counter: u32
}

export function tick(counter: u32): void {
  // return if there is not enough gas to process -- instead of running out
  logging.log("tick: " + counter.toString());
  tock(counter + 1);
}

function tock(counter: u32): void {
  // return if 
  logging.log("tock: " + counter.toString());
  counter++;
  ContractPromiseBatch.create(context.contractName).function_call<Counter>(
    "tick",
    { counter }, 
    u128.Zero,
    context.prepaidGas - context.usedGas - RESERVE_GAS
  )
}

See code here

@ryancwalsh
Copy link

@mehtaphysical Thanks for the hint!
Using

@nearBindgen
class RecipientMatcherAmount {
...
...
.function_call<RecipientMatcherAmount>('setMatcherAmount', { recipient, matcher, amount: matchedAmount }, u128.Zero, XCC_GAS);

instead of defining RecipientMatcherAmount as a TypeScript type seems to work, as your comment hinted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working T-dev-tools
Projects
None yet
Development

No branches or pull requests

3 participants