Skip to main content
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
Bumped by Community user
added 260 characters in body
Source Link
LampShade
  • 640
  • 9
  • 22

Edit: I'm thinking it makes sense to make a websocket connection to each node to listen for a new block number. Then go with that block number for option 2 and not bothering with the +1, +2 future block thingy since it will result it lots of extra calls.

Edit: I'm thinking it makes sense to make a websocket connection to each node to listen for a new block number. Then go with that block number for option 2 and not bothering with the +1, +2 future block thingy since it will result it lots of extra calls.

Source Link
LampShade
  • 640
  • 9
  • 22

Getting the latest eth_call result from a cluster of nodes

What's the best way to know the block number associated with the result of an eth_call? Assume I have several nodes that i'm running and i'm making calls to all of them (for redundancy). My goal is to get the latest result of an eth_call and maximize the likelyhood that it's accurate.

Option 1.) I can make a call for eth_blockNumber with the 'latest' parameter and then a separate call for my eth_call also with the 'latest' parameter, but there I have no guarantee that the block number didn't change by the time the eth_call was made.

payload = {
        "id": randint(0, 99999999999999),
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "data": <DataGoesHere>,
                "to": <ContractAddressGoeshere>
            },
            "latest"
        ]
    }

Option 2.) Or I can specify the specific block number in my eth_call but that seems a little silly because i'm having to guess what the latest block number is. Silly because a node can be a few blocks behind and can catch up at any moment. I can get the current block number and then also in parallel make calls for current + 1 and current + 2 just incase another block or two got quickly mined in.

payload = {
        "id": randint(0, 99999999999999),
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "data": <DataGoesHere>,
                "to": <ContractAddressGoeshere>
            },
            currentBlockNumber_hex
        ]
    }

I could also (just to be careful) make a call for currentBlockNumber_hex + 1

payload = {
        "id": randint(0, 99999999999999),
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "data": <DataGoesHere>,
                "to": <ContractAddressGoeshere>
            },
            currentBlockNumber_hex + 1
        ]
    }

And while i'm at it, may as well do currentBlockNumber_hex + 2

payload = {
        "id": randint(0, 99999999999999),
        "jsonrpc": "2.0",
        "method": "eth_call",
        "params": [
            {
                "data": <DataGoesHere>,
                "to": <ContractAddressGoeshere>
            },
            currentBlockNumber_hex + 2
        ]
    }

But this seems silly. Is there a better way? I have a lot of nodes for redundancy purposes. And I've noticed that they aren't always perfectly agreeing on the latest data. One or two may get a few blocks behind for various reasons.

For example, I may make an eth_call to all 3 nodes and here are the results:

{
  'node1': {
    'jsonrpc': '2.0',
    'result': '0x14ef054e8f9ef79',
    'id': 38577622847874
  },
  'node2': {
    'jsonrpc': '2.0',
    'result': '0x14ef054e8f9ef79',
    'id': 38577622847874
  },
  'node3': {
    'jsonrpc': '2.0',
    'result': '0x14ef054e8f9ef79',
    'id': 50123622847874
  }
}

And here are the latest block numbers:

node1: 6262258
node2: 6262257
node3: 6262259

Notice that Node 3 is ahead and just so happened to have the latest value, while nodes 1 and 2 are behind and don't yet have the latest state.

If I go with Option 1.) from above, I have no way of knowing if node3's result of 0x14ef054e8f9ef79 is actually from block 6262259 because it was called separately with the 'latest' parameter.

if I go with Option 2.) from above i'm having to make an insane amount of calls just to verify that this is the latest value. I'll be making 9 calls. Node1 on block 6262258, Node1 on block (6262258 + 1), Node1 on block (6262258 + 2). Then Node2 on block 6262257, Node2 on block (6262257 + 1), Node2 on block (6262257 + 2). Then Node3 on block 6262259, Node3 on block (6262259 + 1), Node3 on block (6262259 + 2). So that's 9 calls just to get one value. Granted it's going to increase the likely hood that I have the absolute latest value (compared to Option 1.) so it may be worth it.