dominant-strategies / quais-5.js

MIT License
1 stars 6 forks source link

JsonRpcProvider and WebSocketProvider not working as intended #8

Closed Juuddi closed 10 months ago

Juuddi commented 1 year ago

Quais Version

0.1.14

Search Terms

JsonRpcProvider, WebSocketProvider

Describe the Problem

Ethers v5.7.1 has event listeners available for contract events that allow you to listen for events emitted by a specific contract. These event listeners require a deployed smart contract and a provider to listen for events through. Both of Ethers' JsonRpcProvider and WebSocketProvider are feasible options to use when listening for smart contract events.

After some testing with Quais and a deployed contract on a local network, I've noticed that the Quais v0.1.14 JsonRpcProvider when used for listening to smart contract events never returns any event data. I've gone ahead and tested both the JsonRpcProvider and WebSocketProvider and only the WebSocketProvider gives a response when an event is emitted. This functionality of the JsonRpcProvider is also not returning any response in Quais v0.1.11, so it looks like this may be a longer standing issue. This issue prevents applications from listening for smart contract events from the blockscout RPC endpoints as they do not have public Websocket functionality.

In an effort to determine the root cause of the issue, I tested the functionality of pure provider event listeners (e.g. print the block number of each block that is mined). In v0.1.14, the JsonRpcProvider returns no data for any new blocks, but in v0.1.11 returns the number of each mined block correctly. Seems as though some change between v0.1.11 and v0.1.14 is causing this issue.

The WebSocketProvider immediately returns an error which I've provided in the error section below. Seems as though when the go-quai API moved away from returning block numbers as hex arrays, the WebsocketProvider was not updated to reflect that. This occurs in both v0.1.11 and v0.1.14.

Code Snippet

// Http listener for block number
const provider = new quais.providers.JsonRpcProvider('http://0.0.0.0:8610')
provider.on('block', (blockNumber) => {
    console.log('Block Number: ', blockNumber)
})

// WS event listener for block number
const provider = new quais.providers.WebSocketProvider('http://0.0.0.0:8611')
provider.on('block', (blockNumber) => {
    console.log('Block Number: ', blockNumber)
})

// Http listener for contract events
const provider = new quais.providers.JsonRpcProvider('http://0.0.0.0:8610')
const wallet = new quais.Wallet(
    'priv-key-omitted-here',
    provider
 )
const contract = new quais.Contract('0x04a2a0B920466781a0057c8E84b01f413A9b267d', ABI.abi, wallet)

contract.on('Status', (message, player, prize, winner, heads) => {
    const prizeString = quais.utils.formatEther(prize.toNumber())
    const newGameResult = {
        message: message,
        player: player,
        prize: prizeString,
        winner: winner,
        heads: heads,
    }
    console.log('GameResult: ', newGameResult)
 })

Contract ABI

[
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "previousOwner",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "newOwner",
          "type": "address"
        }
      ],
      "name": "OwnershipTransferred",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": false,
          "internalType": "string",
          "name": "_msg",
          "type": "string"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "player",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "bool",
          "name": "winner",
          "type": "bool"
        },
        {
          "indexed": false,
          "internalType": "bool",
          "name": "heads",
          "type": "bool"
        }
      ],
      "name": "Status",
      "type": "event"
    },
    {
      "inputs": [
        {
          "internalType": "bool",
          "name": "_playerChoice",
          "type": "bool"
        }
      ],
      "name": "Play",
      "outputs": [],
      "stateMutability": "payable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "getContractBalance",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "maxBet",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "minBet",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "owner",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "payPercentage",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "renounceOwnership",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "_maxBet",
          "type": "uint256"
        },
        {
          "internalType": "uint256",
          "name": "_minBet",
          "type": "uint256"
        },
        {
          "internalType": "uint32",
          "name": "_payPercentage",
          "type": "uint32"
        }
      ],
      "name": "setBetLimits",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "totalFlips",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "newOwner",
          "type": "address"
        }
      ],
      "name": "transferOwnership",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "stateMutability": "payable",
      "type": "receive"
    }
  ],

Errors

/Users/multi-chain-deploy/node_modules/@quais/logger/lib/index.js:247
        throw this.makeError(message, code, params);
        ^

Error: invalid BigNumber value (argument="value", value=["0x2a","0x2f5","0x53b6"], code=INVALID_ARGUMENT, version=bignumber/5.7.0)
    at Logger.makeError (/Users/multi-chain-deploy/node_modules/@quais/logger/lib/index.js:238:21)
    at Logger.throwError (/Users/multi-chain-deploy/node_modules/@quais/logger/lib/index.js:247:20)
    at Logger.throwArgumentError (/Users/multi-chain-deploy/node_modules/@quais/logger/lib/index.js:250:21)
    at BigNumber.from (/Users/multi-chain-deploy/node_modules/@quais/bignumber/lib/bignumber.js:239:23)
    at Object.processFunc (/Users/multi-chain-deploy/node_modules/@quais/providers/lib/websocket-provider.js:276:61)
    at WebSocketProvider._this.websocket.onmessage (/Users/multi-chain-deploy/node_modules/@quais/providers/lib/websocket-provider.js:154:25)
    at WebSocket.onMessage (/Users/multi-chain-deploy/node_modules/@quais/providers/node_modules/ws/lib/event-target.js:132:16)
    at WebSocket.emit (node:events:514:28)
    at Receiver.receiverOnMessage (/Users/multi-chain-deploy/node_modules/@quais/providers/node_modules/ws/lib/websocket.js:834:20)
    at Receiver.emit (node:events:514:28) {
  reason: 'invalid BigNumber value',
  code: 'INVALID_ARGUMENT',
  argument: 'value',
  value: [ '0x2a', '0x2f5', '0x53b6' ]
}

Environment

Hardhat

Environment (Other)

Running a local go-quai instance, using quai-hardhat, Next.js frontend

Juuddi commented 10 months ago

No longer relevant with the removal of polling, some of the provider types, and the addition of the shim package quais-polling