Skip to content
This repository has been archived by the owner on May 3, 2024. It is now read-only.

Calculate and check previous 256 block hashes #107

Open
ggkitsas opened this issue Jun 12, 2023 · 4 comments
Open

Calculate and check previous 256 block hashes #107

ggkitsas opened this issue Jun 12, 2023 · 4 comments
Assignees

Comments

@ggkitsas
Copy link

Describe the feature you would like

Calculate all previous 256 block hashes. We need that because these last 256 blockhashes are exposed directly to the smart contracts using an opcode, and so we of course need to make sure the correct data is returned when that opcode is called.

In the circuits we only have access to 2 blockhashes: the previous one and the current one. The calculation for the current blockhash is developed in #79.

Since the previous blockhash encapsulates the previous block header, we don't need to check the correctness of the previous block header values. We only need to check the consistency of the block hash chain, that is for the block i

  1. block_hash[i] = HASH(block_header[i])
  2. prev_block_hash[i+1] = block_hash[i]

All the previous block hashes will be stored in the block table with the format:
(BlockContextFieldTag::BlockHash, block_number, block_hash.expr()).

Additional context

No response

@ggkitsas
Copy link
Author

@Brechtpd The initial calculation of total number of rows needed (assuming no implications arise) is ~170k. Is that acceptable?

@Brechtpd
Copy link

Yep, fits in a 2**18 circuit which is very reasonable.

@ggkitsas ggkitsas self-assigned this Jun 22, 2023
@Brechtpd Brechtpd moved this from 📝 Todo to 🏗 In progress in Taiko Project Board Jul 15, 2023
@psix1219king
Copy link

Asynchronous hash calculation: If there's a possibility to parallelize the hash calculation process, considering an asynchronous approach to this task can be beneficial. For instance, initiating hash computations for multiple blocks simultaneously can expedite the process.

import threading
import hashlib

Function to calculate the hash of a block

def calculate_block_hash(block_header):
return hashlib.sha256(block_header.encode()).hexdigest()

Function for asynchronously calculating block hashes

def async_calculate_block_hashes(block_headers):
block_hashes = {}
threads = []

# Define a function for calculating hash and start it in a separate thread for each block
for block_number, block_header in block_headers.items():
    thread = threading.Thread(target=calculate_and_store_block_hash, args=(block_hashes, block_number, block_header))
    threads.append(thread)
    thread.start()

# Wait for all threads to complete
for thread in threads:
    thread.join()

return block_hashes

Function to calculate the hash of a block and store it in a dictionary

def calculate_and_store_block_hash(block_hashes, block_number, block_header):
block_hash = calculate_block_hash(block_header)
block_hashes[block_number] = block_hash

Example usage

block_headers = {
1: "block header 1",
2: "block header 2",
# Add other blocks here
}

block_hashes = async_calculate_block_hashes(block_headers)
print("Block Hashes:", block_hashes)

@psix1219king
Copy link

ORRRRRRR

Parallel computations: If possible, parallel computations can be utilized for calculating block hashes. For instance, the process can be divided into multiple parts and distributed among several processor cores or even across multiple computers.

import concurrent.futures
import hashlib

Function to calculate the hash of a block

def calculate_block_hash(block_header):
return hashlib.sha256(block_header.encode()).hexdigest()

Function for parallel hash calculations of blocks

def parallel_calculate_block_hashes(block_headers):
block_hashes = {}
# Determine the maximum number of threads
max_threads = min(len(block_headers), concurrent.futures.thread.ThreadPoolExecutor().max_workers)
with concurrent.futures.ThreadPoolExecutor(max_workers=max_threads) as executor:
# Create tasks for each block
future_to_block_number = {executor.submit(calculate_block_hash, block_header): block_number for block_number, block_header in block_headers.items()}
# Wait for tasks to complete and obtain results
for future in concurrent.futures.as_completed(future_to_block_number):
block_number = future_to_block_number[future]
try:
block_hash = future.result()
block_hashes[block_number] = block_hash
except Exception as exc:
print(f'Block {block_number} generated an exception: {exc}')
return block_hashes

Example usage

block_headers = {
1: "block header 1",
2: "block header 2",
# Add other blocks here
}

block_hashes = parallel_calculate_block_hashes(block_headers)
print("Block Hashes:", block_hashes)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
Status: 🏗 In progress
Development

No branches or pull requests

3 participants