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

deal with unfinalized blocks #120

Closed
shunjizhan opened this issue Nov 15, 2021 · 2 comments
Closed

deal with unfinalized blocks #120

shunjizhan opened this issue Nov 15, 2021 · 2 comments
Assignees

Comments

@shunjizhan
Copy link
Collaborator

as discussed here #73 (comment), we need a helper JS class to listen to recent/finalized block change, and index these unfinalized block data.

@xlc
Copy link
Member

xlc commented Nov 16, 2021

Something like this. This allow constant time add and purge block data and usually identify tx data in 1 or 2 lookup.

interface BlockData {
  blockNumber: number
  block: Block
}

interface BucketData {
  bucket: number
  blocks: BlockData[]
  transactions: Record<string, Tranasction> // txhash => tx
}

const BUCKET_SIZE = 5

export class UnfinalizedBlockCache {
  buckets: BucketData[] = []
  txpool: Record<string, Tranasction> = {}

  addBlock(block: Block) {
    const bucket = Math.floor(block.number / BUCKET_SIZE)
    const startBucket = this.buckets[0]?.bucket
    const idx = bucket - startBucket
    this.buckets[idx] = this.buckets[idx] ?? { bucket, blocks: [], transactions: {} }
    const bucketData = {
     bucket
     // other fields
    }
    this.buckets[idx].blocks[block.number % BUCKET_SIZE] = bucketData
    // update this.buckets[idx].transactions
  }

  updateFinalizedHead(blockNumber: number) {
    const bucket = Math.floor(blockNumber / BUCKET_SIZE)
    const startBucket = this.buckets[0]?.bucket
    if (startBucket != null && bucket > startBucket) {
      const idx = bucket - startBucket
      this.buckets.splice(0, idx + 1) // make sure this can handle holes
    }
  }

  queryTransactionByHash(hash: string) {
    for (const i = this.buckets.length - 1; i >= 0; --i ) {
      const bucketData = this.buckets[i]  // search from latest bucket
      const tx = bucketData.transactions[hash]
      if (tx) {
        return tx
      }
    }
    if (this.txpool[hash]) {
      return this.txpool[hash]
    }
    // not found
    // update txpool and search it again
  }
}

function createUnfinalizedBlockCache(api: ApiPromise) {
  const cache = new UnfinalizedBlockCache()
  let lastProcessedBlock = undefined

  // subscribe to new head
  // retry on error
    // while lastProcessedBlock !== undefiled && lastProcessedBlock < latestBlockNumber
      // let block = getBlock(lastProcessedBlock + 1)
      // cache.addBlock(block)
      // lastProcessedBlock = block.number

  // subscribe to finalized haed
  // retry on error
    // lastProcessedBlock = max(lastProcessedBlock, blockNumber)
    // cache.updateFinalizedHead(blockNumber)
  return cache
}

@shunjizhan
Copy link
Collaborator Author

closes with #131

@shunjizhan shunjizhan self-assigned this Nov 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants