Skip to content

Instantly share code, notes, and snippets.

@laalaguer
Last active February 28, 2022 09:23
Show Gist options
  • Select an option

  • Save laalaguer/0cee317aae7892be60bbf5638911502f to your computer and use it in GitHub Desktop.

Select an option

Save laalaguer/0cee317aae7892be60bbf5638911502f to your computer and use it in GitHub Desktop.

Revisions

  1. laalaguer revised this gist Feb 28, 2022. 1 changed file with 16 additions and 17 deletions.
    33 changes: 16 additions & 17 deletions find-account-has-code.py
    Original file line number Diff line number Diff line change
    @@ -1,26 +1,24 @@
    ''' Python script to find the earliest block that an account has code.
    python3 find.py [address]
    python3 find.py [node_url] [address]
    '''
    import sys
    from typing import Union
    from thor_requests.connect import Connect

    NODE_URL = 'https://mainnet.veblocks.net'
    connector = Connect(NODE_URL)

    def account_has_code(account_address: str, block_number: int) -> bool:
    def account_has_code(connector: Connect, account_address: str, block_number: int) -> bool:
    ''' Fill your judgment function here, return True/False '''
    account = connector.get_account(account_address, str(block_number))
    return account['hasCode']

    def get_best_block_number () -> int:
    def get_best_block_number(connector: Connect) -> int:
    ''' Fill in your logic of : get "best" block, return the number of the block'''
    block = connector.get_block("best", True)
    return int(block["number"])

    def binary_search(account_address: str, start_n: int, end_n: int) -> Union[int, None]:
    def binary_search(connector: Connect, account_address: str, start_n: int, end_n: int) -> Union[int, None]:
    ''' Find the first block number, that this account DOES NOT "hasCode"
    This ensures we find it within log2(N) times, where N = end_n - start_n
    N = 1 million, find it in 19.9 times
    @@ -31,33 +29,34 @@ def binary_search(account_address: str, start_n: int, end_n: int) -> Union[int,
    if pivot == start_n or pivot == end_n:
    return pivot

    if account_has_code(account_address, pivot):
    return binary_search(account_address, start_n, pivot)
    if account_has_code(connector, account_address, pivot):
    return binary_search(connector, account_address, start_n, pivot)
    else:
    return binary_search(account_address, pivot, end_n)
    return binary_search(connector, account_address, pivot, end_n)

    def earliest_block_that_account_does_not_have_code(account_address: str):
    def earliest_block_that_account_does_not_have_code(connector: Connect, account_address: str):
    ''' Wrapper function to cover some edge cases '''
    # Set up boundary
    latest_block_n = get_best_block_number()
    latest_block_n = get_best_block_number(connector)
    first_block_n = 1

    # Anti stupid
    if not account_has_code(account_address, latest_block_n):
    if not account_has_code(connector, account_address, latest_block_n):
    raise Exception(f"Wow, this account {account_address} doesn't have code at all till now!")

    # Anti stupid
    if account_has_code(account_address, first_block_n):
    if account_has_code(connector, account_address, first_block_n):
    raise Exception(f"Wow, this account already has code before #{first_block_n} block, try go more way back!!")

    # Now we sure to find the n in the between start and end
    return binary_search(account_address, first_block_n, latest_block_n)
    return binary_search(connector, account_address, first_block_n, latest_block_n)


    if __name__ == "__main__":
    node_url = sys.argv[1]
    address = sys.argv[2]

    address = sys.argv[1]

    result = earliest_block_that_account_does_not_have_code(address)
    connector = Connect(node_url)
    result = earliest_block_that_account_does_not_have_code(connector, address)

    print(result + 1) # This is the time when the account first "HAS" code
  2. laalaguer revised this gist Feb 25, 2022. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions find-account-has-code.py
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,7 @@
    python3 find.py [address]
    '''
    import sys # command line args
    import sys
    from typing import Union
    from thor_requests.connect import Connect

    @@ -48,7 +48,7 @@ def earliest_block_that_account_does_not_have_code(account_address: str):

    # Anti stupid
    if account_has_code(account_address, first_block_n):
    raise Exception(f"Wow, this account already has code before {first_block_n} blocks before, try go more way back!!")
    raise Exception(f"Wow, this account already has code before #{first_block_n} block, try go more way back!!")

    # Now we sure to find the n in the between start and end
    return binary_search(account_address, first_block_n, latest_block_n)
  3. laalaguer revised this gist Feb 25, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion find-account-has-code.py
    Original file line number Diff line number Diff line change
    @@ -48,7 +48,7 @@ def earliest_block_that_account_does_not_have_code(account_address: str):

    # Anti stupid
    if account_has_code(account_address, first_block_n):
    raise Exception(f"Wow, this account already has code before {max_go_back_blocks} blocks before, try go more way back!!")
    raise Exception(f"Wow, this account already has code before {first_block_n} blocks before, try go more way back!!")

    # Now we sure to find the n in the between start and end
    return binary_search(account_address, first_block_n, latest_block_n)
  4. laalaguer revised this gist Feb 25, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion find-account-has-code.py
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    ''' Python script to find the earliest block that an account has code.
    python3 find.py [address] [max_go_back_blocks]
    python3 find.py [address]
    '''
    import sys # command line args
  5. laalaguer revised this gist Feb 25, 2022. 1 changed file with 3 additions and 7 deletions.
    10 changes: 3 additions & 7 deletions find-account-has-code.py
    Original file line number Diff line number Diff line change
    @@ -36,11 +36,11 @@ def binary_search(account_address: str, start_n: int, end_n: int) -> Union[int,
    else:
    return binary_search(account_address, pivot, end_n)

    def earliest_block_that_account_does_not_have_code(account_address: str, max_go_back_blocks: int):
    def earliest_block_that_account_does_not_have_code(account_address: str):
    ''' Wrapper function to cover some edge cases '''
    # Set up boundary
    latest_block_n = get_best_block_number()
    first_block_n = latest_block_n - max_go_back_blocks
    first_block_n = 1

    # Anti stupid
    if not account_has_code(account_address, latest_block_n):
    @@ -57,11 +57,7 @@ def earliest_block_that_account_does_not_have_code(account_address: str, max_go_
    if __name__ == "__main__":

    address = sys.argv[1]
    max_go_back = int(sys.argv[2])

    result = earliest_block_that_account_does_not_have_code(
    address,
    max_go_back
    )
    result = earliest_block_that_account_does_not_have_code(address)

    print(result + 1) # This is the time when the account first "HAS" code
  6. laalaguer revised this gist Feb 25, 2022. 1 changed file with 35 additions and 27 deletions.
    62 changes: 35 additions & 27 deletions find-account-has-code.py
    Original file line number Diff line number Diff line change
    @@ -1,40 +1,42 @@
    # Python
    ''' Python script to find the earliest block that an account has code.
    python3 find.py [address] [max_go_back_blocks]
    '''
    import sys # command line args
    from typing import Union
    from thor_requests.connect import Connect

    MAX_RETRACE_BLOCKS = 1000000 # 1 million blocks to retrace at most
    NODE_URL = 'https://mainnet.veblocks.net'
    connector = Connect(NODE_URL)

    def account_has_code (account_address: str, block_number: int) -> bool:
    def account_has_code(account_address: str, block_number: int) -> bool:
    ''' Fill your judgment function here, return True/False '''
    pass
    account = connector.get_account(account_address, str(block_number))
    return account['hasCode']

    def get_best_block_number () -> int:
    ''' Fill in your logic of : get "best" block, return the number of the block'''
    pass

    block = connector.get_block("best", True)
    return int(block["number"])

    def binary_search(account_address: str, start_n: int, end_n: int) -> Union[int, None]:
    ''' This ensures we find it within log2(N) times, where N = end_n - start_n
    ''' Find the first block number, that this account DOES NOT "hasCode"
    This ensures we find it within log2(N) times, where N = end_n - start_n
    N = 1 million, find it in 19.9 times
    '''
    # oops, not found!
    if not (start_n <= end_n):
    return None

    # found!
    if account_has_code(account_address, start_n):
    return start_n

    print(f'Search blocks: {start_n} till {end_n}')
    pivot = int((start_n + end_n) / 2)
    possible_1 = binary_search(account_address, start_n+1, pivot)
    if possible_1 is not None:
    return possible_1
    possible_2 = binary_search(account_address, pivot+1, end_n)
    if possible_2 is not None:
    return possible_2

    return None

    def earliest_block_that_account_has_code(account_address: str, max_go_back_blocks: int):
    if pivot == start_n or pivot == end_n:
    return pivot

    if account_has_code(account_address, pivot):
    return binary_search(account_address, start_n, pivot)
    else:
    return binary_search(account_address, pivot, end_n)

    def earliest_block_that_account_does_not_have_code(account_address: str, max_go_back_blocks: int):
    ''' Wrapper function to cover some edge cases '''
    # Set up boundary
    latest_block_n = get_best_block_number()
    @@ -54,6 +56,12 @@ def earliest_block_that_account_has_code(account_address: str, max_go_back_block

    if __name__ == "__main__":

    earliest_block_that_account_has_code(
    # Fill in your params here
    )
    address = sys.argv[1]
    max_go_back = int(sys.argv[2])

    result = earliest_block_that_account_does_not_have_code(
    address,
    max_go_back
    )

    print(result + 1) # This is the time when the account first "HAS" code
  7. laalaguer created this gist Feb 25, 2022.
    59 changes: 59 additions & 0 deletions find-account-has-code.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,59 @@
    # Python
    from typing import Union

    MAX_RETRACE_BLOCKS = 1000000 # 1 million blocks to retrace at most

    def account_has_code (account_address: str, block_number: int) -> bool:
    ''' Fill your judgment function here, return True/False '''
    pass

    def get_best_block_number () -> int:
    ''' Fill in your logic of : get "best" block, return the number of the block'''
    pass


    def binary_search(account_address: str, start_n: int, end_n: int) -> Union[int, None]:
    ''' This ensures we find it within log2(N) times, where N = end_n - start_n
    N = 1 million, find it in 19.9 times
    '''
    # oops, not found!
    if not (start_n <= end_n):
    return None

    # found!
    if account_has_code(account_address, start_n):
    return start_n

    pivot = int((start_n + end_n) / 2)
    possible_1 = binary_search(account_address, start_n+1, pivot)
    if possible_1 is not None:
    return possible_1
    possible_2 = binary_search(account_address, pivot+1, end_n)
    if possible_2 is not None:
    return possible_2

    return None

    def earliest_block_that_account_has_code(account_address: str, max_go_back_blocks: int):
    ''' Wrapper function to cover some edge cases '''
    # Set up boundary
    latest_block_n = get_best_block_number()
    first_block_n = latest_block_n - max_go_back_blocks

    # Anti stupid
    if not account_has_code(account_address, latest_block_n):
    raise Exception(f"Wow, this account {account_address} doesn't have code at all till now!")

    # Anti stupid
    if account_has_code(account_address, first_block_n):
    raise Exception(f"Wow, this account already has code before {max_go_back_blocks} blocks before, try go more way back!!")

    # Now we sure to find the n in the between start and end
    return binary_search(account_address, first_block_n, latest_block_n)


    if __name__ == "__main__":

    earliest_block_that_account_has_code(
    # Fill in your params here
    )