Internal server error when decoding result (RESOLVED)

Hey, I have an internal server error that’s coming from the compiler and I can’t identify. I’m using the JS SDK version 7.1.1

I’m broadcasting a transaction that makes a call to a contract on the testnet. The transaction is mined successfully, however the error is there.

Error: Http request for https://latest.compiler.aepps.com/decode-call-result failed with status code 500. Status: Internal Server Error. 
Error data: ""

Axios config:

config: {
      url: 'https://latest.compiler.aepps.com/decode-call-result',
      method: 'post',
      data: '{"function":"new_contract","source":"include \\"List.aes\\"\\n\\ncontract HashTimeLock = \\n\\n  record state = { contracts : map(hash, lock_contract) }\\n\\n  datatype status = INVALID | ACTIVE | REFUNDED | WITHDRAWN | EXPIRED \\n\\n  record lock_contract = {\\n    input_amount : int,\\n    output_amount : int,\\n    expiration : int,\\n    hash_lock : hash,\\n    status: status,\\n    sender : address,\\n    receiver : address,\\n    output_network : string,\\n    output_address : string}\\n\\n  datatype event =\\n    Withdraw(indexed hash, indexed address, indexed address, string)\\n    | Refund(indexed hash, indexed address, indexed address, string)\\n    | New_contract(indexed 
hash, indexed address, indexed address, string)\\n\\n  function withdrawable(_contract : lock_contract, secret : hash) =\\n    require(is_active(_contract.status), \\"SWAP_NOT_ACTIVE\\")\\n    require(_contract.expiration > Chain.timestamp, \\"INVALID_TIME\\")\\n    require(_contract.hash_lock == Crypto.sha256(secret), \\"INVALID_SECRET\\")\\n\\n  function refundable(_contract: lock_contract) =\\n    require(is_active(_contract.status), \\"SWAP_NOT_ACTIVE\\")\\n    require(Chain.timestamp >= _contract.expiration, \\"INVALID_TIME\\")\\n    require(_contract.sender == Call.caller, \\"INVALID_SENDER\\")\\n\\n  payable stateful entrypoint new_contract(\\n      output_amount : int,\\n      expiration : int, \\n      hash_lock : hash, \\n      receiver : address, \\n      output_network : string, \\n      output_address : string) : lock_contract =\\n    \\n    let sender : 
address = Call.caller\\n    \\n    let input_amount : int = Call.value\\n    \\n    let id : hash = generate_id(sender, receiver, input_amount, hash_lock, expiration)\\n    \\n    let new_contract : lock_contract = { \\n      input_amount = input_amount,\\n      output_amount = output_amount,\\n      expiration = expiration,\\n      hash_lock = hash_lock,\\n      status = ACTIVE,\\n      sender = sender,\\n      receiver = receiver,\\n      output_network = output_network,\\n      output_address = output_address }\\n\\n   
 require(expiration > Chain.timestamp, \\"INVALID_TIME\\")\\n    require(input_amount > 0, \\"INVALID_AMOUNT\\")\\n\\n    put(state{ contracts[id] = new_contract })\\n\\n    let swap_message : string = generate_swap_message(new_contract)\\n    \\n    Chain.event(New_contract(id, sender, receiver, swap_message))\\n    \\n    state.contracts[id]\\n\\n 
 stateful entrypoint withdraw(id : hash, secret : hash) =\\n    let _contract: lock_contract = state.contracts[id]\\n    withdrawable(_contract, secret)\\n\\n    Chain.spend(_contract.receiver, _contract.input_amount)\\n\\n    put(state{contracts[id].status = WITHDRAWN})\\n\\n    Chain.event(Withdraw(id, _contract.sender, _contract.receiver, generate_withdraw_message(secret, _contract.hash_lock) ))\\n\\n  stateful entrypoint refund(id : hash) =\\n    let _contract : lock_contract = state.contracts[id]\\n    refundable(_contract)\\n    \\n    Chain.spend(_contract.sender, _contract.input_amount)\\n\\n    put(state{ contracts[id].status = REFUNDED })\\n\\n    Chain.event(Refund(id, _contract.sender, _contract.receiver, Bytes.to_str(_contract.hash_lock)))\\n\\n  entrypoint get_one_status(id : hash) : status =\\n    let _contract : lock_contract = state.contracts[id]\\n\\n    if(_contract.status == ACTIVE &&\\n        _contract.expiration < Chain.timestamp)\\n      EXPIRED\\n    else\\n      _contract.status\\n\\n  entrypoint get_many_status(ids : list(hash)) : list(status) =\\n    List.map((id) => get_one_status(id), ids)\\n\\n  function generate_id(sender : address, receiver : address,\\n   input_amount : int, hash_lock : hash, expiration : int) : hash =\\n    let packed_string : string = String.concat(String.concat(String.concat(Address.to_str(sender), \\n      Address.to_str(receiver)), String.concat(Int.to_str(input_amount),\\n       Bytes.to_str(hash_lock))), Int.to_str(expiration))\\n    Crypto.sha256(packed_string)\\n    \\n  function generate_withdraw_message(secret : hash, hash_lock : hash) : string =\\n    concat(Bytes.to_str(secret), Bytes.to_str(hash_lock))\\n\\n  function generate_swap_message(new_contract : lock_contract) : string =\\n    concat(concat(new_contract.output_network, new_contract.output_address),\\n     concat(concat(Int.to_str(new_contract.input_amount), Int.to_str(new_contract.output_amount)),\\n     concat(Int.to_str(new_contract.expiration), Bytes.to_str(new_contract.hash_lock))))\\n  \\n  function is_active(x : status) : bool =\\n    x == ACTIVE\\n\\n  function concat(a : string, b : string) =\\n    String.concat(String.concat(a, \\",\\"),b)\\n\\n  entrypoint  init() = { contracts = {} }\\n","call-result":"ok","call-value":"cb_q58BgUFsUQgA37pD+/b+7SyBTPjsmp5mKp47Akx0c4yLS635b4gbwW1nTsf/wG+IG8FtZ07H/8BvhgFxEO8ARp8BgYcZ2AhdUzRj15KZWrT0vIXnJEq1gEZLA1zDge3Qam24r4UAAAAAAAE/nwCgBwwURA4zMENRZdpeBEtaqcNdLL4wyRwyFFVJN19SUmSfAKBrs4jtfFRU9fsXJtVRgxnm+6MvasbSWpfv9LbvZBN72A1BRVPRYWtfNDcxZFlVclE4RUF0bXp3dUtEdzRWQkdRZG5FY1A1WUY1NjNXRzR5UjlXdmZwNXRScCV612Q=","options":{"backend":"fate","clientTtl":84600,"nameTtl":50000,"nameFee":0,"deposit":0,"gasPrice":1000000000,"amount":"2000000000000000000","gas":1579000,"options":"","dryRunAccount":{"pub":"ak_11111111111111111111111111111111273Yts","amount":"100000000000000000000000000000000000"},"queryFee":30000,"oracleTtl":{"type":"delta","value":500},"queryTtl":{"type":"delta","value":10},"responseTtl":{"type":"delta","value":10},"skipArgsConvert":false,"skipTransformDecoded":false,"callStatic":false,"top":null,"waitMined":true,"verify":false,"filesystem":{},"file_system":{}}}'

Response:

response: {
      status: 500,
      statusText: 'Internal Server Error',
      headers: [Object],
      config: [Object],
      request: [ClientRequest],
      data: ''
    }

I’m not sure why it crashes, but the call-value is not of the same type (lock_contract) as the function new_contract returns…

The value has an extra hash as the first value, like the type was:

record not_exactly_a_lock_contract = {
  extra_hash : hash, 
  input_amount : int,
  output_amount : int,
  expiration : int,
  hash_lock : hash,
  status: status,
  sender : address,
  receiver : address,
  output_network : string,
  output_address : string
}

Yeah, that’s what I also found out :frowning:

It seems I’ve updated the contract and used an old deployed one, so deploying a new contract with the updated interface fixed it. Thanks for checking that for me @hanssv.chain <3

No problem! I suspect the crash is from trying to give you an error message about the mismatching types… 500 isn’t the most helpful error :slight_smile:

Yeah, 500 without any error message was a bit confusing.

Running it through the command line compiler helped:

./aesophia_cli /tmp/foo.aes -b fate --call_result cb_q58BgUFsUQgA37pD+/b+7SyBTPjsmp5mKp47Akx0c4yLS635b4gbwW1nTsf/wG+IG8FtZ07H/8BvhgFxEO8ARp8BgYcZ2AhdUzRj15KZWrT0vIXnJEq1gEZLA1zDge3Qam24r4UAAAAAAAE/nwCgBwwURA4zMENRZdpeBEtaqcNdLL4wyRwyFFVJN19SUmSfAKBrs4jtfFRU9fsXJtVRgxnm+6MvasbSWpfv9LbvZBN72A1BRVPRYWtfNDcxZFlVclE4RUF0bXp3dUtEdzRWQkdRZG5FY1A1WUY1NjNXRzR5UjlXdmZwNXRScCV612Q= --call_result_fun new_contract 
escript: exception error: no function clause matching 
                 aeso_pretty:type({variant_t,
                                   [{constr_t,
                                     [{file,no_file},{line,2},{col,21}],
                                     {con,
                                      [{file,no_file},{line,2},{col,21}],
                                      "INVALID"},
                                     []},
                                    {constr_t,
                                     [{file,no_file},{line,2},{col,31}],
                                     {con,
                                      [{file,no_file},{line,2},{col,31}],
                                      "ACTIVE"},
                                     []},
                                    {constr_t,
                                     [{file,no_file},{line,2},{col,40}],
                                     {con,
                                      [{file,no_file},{line,2},{col,40}],
                                      "REFUNDED"},
                                     []},
                                    {constr_t,
                                     [{file,no_file},{line,2},{col,51}],
                                     {con,
                                      [{file,no_file},{line,2},{col,51}],
                                      "WITHDRAWN"},
                                     []},
                                    {constr_t,
                                     [{file,no_file},{line,2},{col,63}],
                                     {con,
                                      [{file,no_file},{line,2},{col,63}],
                                      "EXPIRED"},
                                     []}]}) (/Users/hans/Quviq/Aeternity/aesophia_cli/_checkouts/aesophia/src/aeso_pretty.erl, line 245)
  in function  aeso_pretty:typed/2 (/Users/hans/Quviq/Aeternity/aesophia_cli/_checkouts/aesophia/src/aeso_pretty.erl, line 131)
  in call from lists:map/2 (lists.erl, line 1239)
  in call from lists:map/2 (lists.erl, line 1239)
  in call from aeso_pretty:typedef/1 (/Users/hans/Quviq/Aeternity/aesophia_cli/_checkouts/aesophia/src/aeso_pretty.erl, line 228)
  in call from aeso_compiler:to_sophia_value/5 (/Users/hans/Quviq/Aeternity/aesophia_cli/_checkouts/aesophia/src/aeso_compiler.erl, line 339)
  in call from aesophia_cli:decode_call_res/5 (/Users/hans/Quviq/Aeternity/aesophia_cli/src/aesophia_cli.erl, line 269)
  in call from aesophia_cli:main/1 (/Users/hans/Quviq/Aeternity/aesophia_cli/src/aesophia_cli.erl, line 62)

I’ll write an issue…

2 Likes

Yeah, I should start using the command line tools more often as they seem less error prone.

1 Like

It is one (or two or three) less layers, so it often tells you more.

1 Like