ethereum / py-evm

A Python implementation of the Ethereum Virtual Machine
https://py-evm.readthedocs.io/en/latest/
MIT License
2.27k stars 655 forks source link

Gas cost discrepancy between py-evm and ethereumjs/geth #2162

Closed Alleysira closed 7 months ago

Alleysira commented 8 months ago

What happened

Hey, I'm interested in the EVM implementations, so I'm fuzzing py-evm 0.8.0b1 along with other EVMs. And I found that when executing the same bytecodes with same gas, py-evm runs out of gas while EthereumJS and Geth are still fine.

How to reproduce

I build a docker image to make it easier for you to analyze why it happened. The image can be accessed using the following commands:

docker pull alleysira/pyevm-poc:1.0.0 

The following commands will directly give the results.

docker run alleysira/pyevm-poc:1.0.0

Or you can do that step by step by

. ./env/bin/activate
cd poc/
solc --evm-version shanghai --bin-runtime TrustGarant/seed/PreProcess_0x2339E3bDF79894b4EE72c951911713F917385925.sol -o contract/ --overwrite
python3 fool.py --code ./contract/TrustGarant_V1.bin-runtime --sig 0xb585375f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000d50d4c16ea00ae00f0f87fd3ae9dfd67cb70d7b0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000022ea81a6481fb45b2d9e42cc5826fc9547e75263142074844c53d53ab73c76695a885dea0d405bf5b4c0105e39c493b5217e37ad0000000000000000000000000000000000000000000000000000000000000097
tail -n 1 output/gethout.json ; tail -n 1 output/pyout.json ; tail -n 1 output/jsout.json

You can see that the gas cost of EthereumJS and Geth are 0x445d2 and returnd normally, but the pyevm run ou of gas.

{"output":"0000000000000000000000000000000000000000000000000000000000000001","gasUsed":"0x445d2"} //Geth
{"output": "", "gasUsed": "0x3da9b"} //pyevm
{"output":"0000000000000000000000000000000000000000000000000000000000000001","gasUsed":"0x445d2"} //Ethereumjs

I'm using /poc/runBytecode.py to run the contract, the runBytecode.py looks like

from eth import constants
from eth.db.atomic import AtomicDB
from eth import constants
from eth.chains.base import MiningChain
from eth_utils import (to_wei, decode_hex,  to_canonical_address,)
from eth.vm.forks.shanghai import ShanghaiVM
from eth_typing import Address
from eth_keys import keys
from eth.tools.transaction import new_transaction
from cytoolz import assoc
import argparse

def parse_args():
    """
    Parse input arguments
    """
    parser = argparse.ArgumentParser(description='Test a transaction')

    # contract runtime bytecode  $ solc xxx.sol --bin-runtime
    parser.add_argument('--data', dest='data', default='', type=str)
    # function signature bytecode
    parser.add_argument('--sig', dest='signature', default='', type=str)

    args = parser.parse_args()
    return args

def funded_address_initial_balance():
    return to_wei(0xffff, 'ether')

def base_genesis_state(funded_address, funded_address_initial_balance):
    return {
        funded_address: {
            'balance': funded_address_initial_balance,
            'nonce': 0,
            'code': b'',
            'storage': {},
        }
    }

def funded_address_private_key():
    return keys.PrivateKey(
        decode_hex('0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8')
    )

def genesis_state(base_genesis_state,simple_contract_address, bytecode):
    # base_genesis_state is a dict, simple_contract_address is key, {b,n,c,s} is value :)
    result = assoc(
        base_genesis_state,
        simple_contract_address,
        {
            'balance': 0,
            'nonce': 0,
            'code': decode_hex(bytecode),  # contract bytecode
            'storage': {},
        },
    )
    return result

GENESIS_PARAMS = {
    #  'coinbase': constants.ZERO_ADDRESS,
    # change coinbase to skip 2500 gas gap
     'coinbase': Address(0x000000000000000000000000000000000000abcd.to_bytes(20,'big')),
     'transaction_root': constants.BLANK_ROOT_HASH,
     'receipt_root': constants.BLANK_ROOT_HASH,
     'difficulty': 0,
     'gas_limit': 0xffffff,
     'timestamp': 0,
     'extra_data': constants.GENESIS_EXTRA_DATA,
     'nonce': b'\x00' * 8
}

def main():
    args = parse_args()

    init_address = to_canonical_address("8888f1f195afa192cfee860698584c030f4c9db1")

    base_state = base_genesis_state(init_address, funded_address_initial_balance())

    # with chain code
    simple_contract_address = to_canonical_address("0x692a70d2e424a56d2c6c27aa97d1a86395877b3a")

    klass = MiningChain.configure(
        __name__='MyTestChain',
        vm_configuration=(
            (constants.GENESIS_BLOCK_NUMBER,ShanghaiVM),
        )
    )

    SENDER = to_canonical_address("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b")
    SENDER_PRIVATE_KEY = funded_address_private_key()

    # RECEIVER = to_canonical_address("0x692a70d2e424a56d2c6c27aa97d1a86395877b3a")
    GENESIS_STATE = genesis_state(base_state, simple_contract_address,args.data)
    chain = klass.from_genesis(AtomicDB(), GENESIS_PARAMS, GENESIS_STATE)

    call_txn = new_transaction(
        vm = chain.get_vm(),
        from_ = to_canonical_address("0x1c7cd2d37ffd63856a5bd56a9af1643f2bcf545f"),
        to = simple_contract_address,
        # private_key=SENDER_PRIVATE_KEY,
        gas=0x48000,
        # data=function_selector,
        data=decode_hex(args.signature),
    )
    result_bytes = chain.get_transaction_result(call_txn, chain.get_canonical_head())

if __name__ == '__main__':
    main()

Why this happened?

I'm curious about why this situation happened, as I have already made great efforts to ensure that the testing environments of all three evms are as similar as possible. If this issue is due to testing environment, please tell me how to correct this one. I appreciate your guidance in this matter. Thank you in advance.

pacrob commented 8 months ago

Thanks for the issue, @Alleysira ! We won't have time this week, but will take a look and let you know what we find.

Alleysira commented 8 months ago

Thanks for your attention, just take your time. And if you need anything else, please let me know :)

Alleysira commented 7 months ago

Thanks for the issue, @Alleysira ! We won't have time this week, but will take a look and let you know what we find.

Hello, @pacrob. Could you please provide an update on the status of the discrepancy I raised earlier? I'm curious to know why this happened, thanks.

pacrob commented 7 months ago

Hello, @pacrob. Could you please provide an update on the status of the discrepancy I raised earlier? I'm curious to know why this happened, thanks.

Hi @Alleysira - sorry, I haven't been able to work on this - we're pushing to get web3.py v7 ready to go. I will definitely let you know when I have more info.

fselmo commented 7 months ago

@Alleysira can you please test this with the latest version of the library? Also I can't reproduce the code snippet you provided. I get:

ModuleNotFoundError: No module named 'eth.tools.transaction'
fselmo commented 7 months ago

Your SENDER and SENDER_PRIVATE_KEY are not being used. result_bytes is not being used. I'm not sure what the test case is supposed to be when I look at this code snippet. Can you make it more concise and clear what the test is actually testing? Who is the sender if not SENDER? py-evm is passing all of the thousands of ethereum tests so if you are seeing a discrepancy this would be good to try to capture as an ethereum test. Therefore it would be good to have a clearer picture here. Thanks.

Alleysira commented 7 months ago

@Alleysira can you please test this with the latest version of the library? Also I can't reproduce the code snippet you provided. I get:

ModuleNotFoundError: No module named 'eth.tools.transaction'

Thanks for your time @fselmo. I'm working on pyevm 0.8.0b1 because I manually added logging instructions to output a pyout.json file like Geth/Besu provided to help me find difference, later I'll try to move to a newer version of pyevm, or maybe you guys have already done that to output a same format json file? If so, could you please tell me how to do that with your implementation.

I believe it's reproducible in the docker images I provided above. Since I have to call Geth/evm, Py-evm and Ethereum/JS at the same time, the environment is hard to setup in short time, I build docker image to assist your analysis.

Alleysira commented 7 months ago

Your SENDER and SENDER_PRIVATE_KEY are not being used. result_bytes is not being used. I'm not sure what the test case is supposed to be when I look at this code snippet. Can you make it more concise and clear what the test is actually testing? Who is the sender if not SENDER? py-evm is passing all of the thousands of ethereum tests so if you are seeing a discrepancy this would be good to try to capture as an ethereum test. Therefore it would be good to have a clearer picture here. Thanks.

Sorry for my unclear desscription. I'll illustrate the script and the docker I provided. The not used variables like SENDER was introduced by the template I used before, but I didn't delete those unused variables, sorry about the mass here. Actually, 0x1c7cd2d37ffd63856a5bd56a9af1643f2bcf545f is my SENDER in new_transaction and result_bytes is indeed not necessarily to be used as I already logged the information I need during the opcodes' execution.

As you can see in the docker /home/alleysira/EVMFuzzer/poc/fool.py, I gave same bytecodes to Geth/evm, Py-evm and Ethereum/JS with same calldata. fool.py is a script to get bytecodes and input (test case) and call 3 evms. The bytecodes is from./contract/TrustGarant_V1.bin-runtime and the calldata is 0xb585375f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000d50d4c16ea00ae00f0f87fd3ae9dfd67cb70d7b0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000022ea81a6481fb45b2d9e42cc5826fc9547e75263142074844c53d53ab73c76695a885dea0d405bf5b4c0105e39c493b5217e37ad0000000000000000000000000000000000000000000000000000000000000097. To execute bytecodes in py-evm, I used /home/alleysira/EVMFuzzer/poc/runBytecode.py below.

    call_txn = new_transaction(
        vm = chain.get_vm(),
        from_ = to_canonical_address("0x1c7cd2d37ffd63856a5bd56a9af1643f2bcf545f"),
        to = simple_contract_address,
        # private_key=SENDER_PRIVATE_KEY,
        gas=0xffffff,
        # data=function_selector,
        data=decode_hex(args.signature),
    )
    result_bytes = chain.get_transaction_result(call_txn, chain.get_canonical_head())

To get tracing information about the opcodes, I added some logging instructions in original /home/alleysira/EVMFuzzer/env/lib/python3.8/site-packages/eth/vm.computaion.py to trace the opcodes execution, so I can get pyout.json like gethout.json to find discrepancy.

The testcase solidy file is located at /home/alleysira/EVMFuzzer/poc/TrustGarant/seed/PreProcess_0x2339E3bDF79894b4EE72c951911713F917385925.sol. I used solc 0.8.23 to compile the sol and put the contract bytecodes at address 0x692a70d2e424a56d2c6c27aa97d1a86395877b3a. The called function is function createDeal(bool iamBuyer, address secondPartner, bool guarantor, address, guarantAddr, uint price, bytes32 dealTerms) external returns(bool).

I believe these information can help reproduce the gas discrepancy issue. If you have any more problems please let me know and I'll be willing to offer more information. Thanks for your attention!

fselmo commented 7 months ago

Thanks @Alleysira. Can you provide the contract bytecode you are using to test?

Alleysira commented 7 months ago

Thanks @Alleysira. Can you provide the contract bytecode you are using to test?

Of course, I copied the bytecodes from container. bytecode.txt

fselmo commented 7 months ago

@Alleysira I sense something is wrong in your setup and I'm not sure where but for usage questions I would suggest you use the #py-evm channel in the Discord server for the Ethereum Python community.

I made a quick reproduction using your examples and hooking py-evm up through web3.py + eth_tester using the EthereumTesterProvider and this seems to return the same output as geth and ethereumjs. I'll post my reproducible snippet below.

import logging
from eth import constants
from eth_utils import (
    to_wei,
    DEBUG2_LEVEL_NUM,
    decode_hex,
    to_canonical_address,
)
from eth_utils.toolz import (
    assoc,
)
from eth.vm.forks.shanghai import ShanghaiVM
from eth_account import Account
from eth_typing import Address
from hexbytes import HexBytes
from web3 import Web3, EthereumTesterProvider
from eth_tester import EthereumTester, PyEVMBackend

# set log level to debug2
logging.basicConfig(level=DEBUG2_LEVEL_NUM)

def funded_address_initial_balance():
    funds = to_wei(0xFFFF, "ether")
    return funds

def base_genesis_state(funded_address, funded_address_initial_balance):
    return {
        funded_address: {
            "balance": funded_address_initial_balance,
            "nonce": 0,
            "code": b"",
            "storage": {},
        }
    }

def funded_address_private_key():
    return "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8"

def genesis_state(base_genesis_state, simple_contract_address):
    result = assoc(
        base_genesis_state,
        simple_contract_address,
        {
            "balance": 0,
            "nonce": 0,
            "code": decode_hex("0x608060405260043610610233575f3560e01c80638da5cb5b1161012d578063c64e39d3116100aa578063e7c80f171161006e578063e7c80f171461090b578063e8755d0014610947578063ea6b35851461096f578063f851a44014610999578063fc8edb52146109c35761023a565b8063c64e39d3146107fa578063ccf9e51214610836578063d1b1889514610860578063d57dc883146108a5578063db2c317b146108e15761023a565b8063a030e856116100f1578063a030e856146106e6578063a6f9dae114610725578063b585375f1461074d578063be6da18c14610789578063bff1f9e1146107d05761023a565b80638da5cb5b146105ed5780638f28397014610617578063907f58ea1461063f5780639305dd701461067b57806399b956a0146106a55761023a565b80635b9d2512116101bb5780636fb1eb0c1161017f5780636fb1eb0c146105075780637d41702e14610531578063849bb2db1461056d578063887a13b214610583578063891e6f43146105c35761023a565b80635b9d2512146104015780635f81a57c1461043d5780635f9d8efb1461046757806362fd6187146104a357806368bc531f146104cb5761023a565b8063213566b111610202578063213566b11461030857806331ea1a391461034457806341c208111461038057806346f1942914610396578063538028d0146103d75761023a565b806302a2e3fc1461023e57806317e43aa71461027a5780631c20fadd146102905780631e41a47a146102cc5761023a565b3661023a57005b5f80fd5b348015610249575f80fd5b50610264600480360381019061025f9190613674565b6109ff565b60405161027191906136ae565b60405180910390f35b348015610285575f80fd5b5061028e610b4d565b005b34801561029b575f80fd5b506102b660048036038101906102b19190613754565b610bfa565b6040516102c391906136ae565b60405180910390f35b3480156102d7575f80fd5b506102f260048036038101906102ed91906137a4565b610d2c565b6040516102ff91906136ae565b60405180910390f35b348015610313575f80fd5b5061032e600480360381019061032991906137cf565b610d7b565b60405161033b91906136ae565b60405180910390f35b34801561034f575f80fd5b5061036a600480360381019061036591906137a4565b610e10565b60405161037791906136ae565b60405180910390f35b34801561038b575f80fd5b50610394611013565b005b3480156103a1575f80fd5b506103bc60048036038101906103b791906137a4565b611070565b6040516103ce9695949392919061381c565b60405180910390f35b3480156103e2575f80fd5b506103eb6110b7565b6040516103f8919061388a565b60405180910390f35b34801561040c575f80fd5b50610427600480360381019061042291906137a4565b6110dc565b60405161043491906136ae565b60405180910390f35b348015610448575f80fd5b50610451611122565b60405161045e91906138a3565b60405180910390f35b348015610472575f80fd5b5061048d600480360381019061048891906137a4565b611128565b60405161049a91906136ae565b60405180910390f35b3480156104ae575f80fd5b506104c960048036038101906104c491906137a4565b611826565b005b3480156104d6575f80fd5b506104f160048036038101906104ec91906137cf565b6118b2565b6040516104fe91906136ae565b60405180910390f35b348015610512575f80fd5b5061051b611a03565b60405161052891906138a3565b60405180910390f35b34801561053c575f80fd5b50610557600480360381019061055291906137a4565b611a09565b60405161056491906136ae565b60405180910390f35b348015610578575f80fd5b50610581611c1e565b005b34801561058e575f80fd5b506105a960048036038101906105a491906138bc565b611c5f565b6040516105ba95949392919061399e565b60405180910390f35b3480156105ce575f80fd5b506105d7611f4a565b6040516105e4919061388a565b60405180910390f35b3480156105f8575f80fd5b50610601611f6f565b60405161060e9190613a32565b60405180910390f35b348015610622575f80fd5b5061063d600480360381019061063891906138bc565b611f92565b005b34801561064a575f80fd5b50610665600480360381019061066091906137cf565b611fd5565b60405161067291906136ae565b60405180910390f35b348015610686575f80fd5b5061068f612126565b60405161069c91906138a3565b60405180910390f35b3480156106b0575f80fd5b506106cb60048036038101906106c691906138bc565b61212c565b6040516106dd96959493929190613ad5565b60405180910390f35b3480156106f1575f80fd5b5061070c600480360381019061070791906138bc565b6121ea565b60405161071c9493929190613b3b565b60405180910390f35b348015610730575f80fd5b5061074b60048036038101906107469190613bc4565b61243f565b005b348015610758575f80fd5b50610773600480360381019061076e9190613c22565b612481565b60405161078091906136ae565b60405180910390f35b348015610794575f80fd5b506107af60048036038101906107aa91906137a4565b612a55565b6040516107c79c9b9a99989796959493929190613cba565b60405180910390f35b3480156107db575f80fd5b506107e4612b7b565b6040516107f191906138a3565b60405180910390f35b348015610805575f80fd5b50610820600480360381019061081b9190613d72565b612b81565b60405161082d91906136ae565b60405180910390f35b348015610841575f80fd5b5061084a612e44565b60405161085791906138a3565b60405180910390f35b34801561086b575f80fd5b50610886600480360381019061088191906138bc565b612e4a565b60405161089c9a99989796959493929190613db0565b60405180910390f35b3480156108b0575f80fd5b506108cb60048036038101906108c69190613f7d565b612f2c565b6040516108d891906136ae565b60405180910390f35b3480156108ec575f80fd5b506108f5612fdf565b604051610902919061388a565b60405180910390f35b348015610916575f80fd5b50610931600480360381019061092c91906137a4565b613004565b60405161093e91906136ae565b60405180910390f35b348015610952575f80fd5b5061096d600480360381019061096891906137cf565b6130c3565b005b34801561097a575f80fd5b506109836130d5565b60405161099091906136ae565b60405180910390f35b3480156109a4575f80fd5b506109ad613181565b6040516109ba919061388a565b60405180910390f35b3480156109ce575f80fd5b506109e960048036038101906109e491906137a4565b6131a6565b6040516109f691906136ae565b60405180910390f35b5f8115610aa7575f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015490505f600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010181905550610a993382613387565b610aa1575f80fd5b50610b44565b5f600e5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015490505f600e5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010181905550610b3a3382613387565b610b42575f80fd5b505b60019050919050565b610b7b3360015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff166004546134d9565b610b83575f80fd5b60045460055f828254610b969190614004565b9250508190555042600e5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f018190555060075f815480929190610bf390614037565b9190505550565b5f805f8573ffffffffffffffffffffffffffffffffffffffff168585604051602401610c2792919061407e565b6040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610cb191906140e9565b5f604051808303815f865af19150503d805f8114610cea576040519150601f19603f3d011682016040523d82523d5f602084013e610cef565b606091505b50915091505f815114158015610d16575080806020019051810190610d149190614113565b155b15610d1f575f80fd5b6001925050509392505050565b5f81600e5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206005018190555060019050919050565b5f82600e5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206006018190555081600e5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600701819055506001905092915050565b5f80600b8381548110610e2657610e2561413e565b5b905f5260205f209060070201905042600b8481548110610e4957610e4861413e565b5b905f5260205f20906007020160050181905550600d5f825f0160029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060090183908060018154018082558091505060019003905f5260205f20015f9091909190915055600d5f826001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060090183908060018154018082558091505060019003905f5260205f20015f90919091909150558060020160149054906101000a900460ff161561100957600e5f826003015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600e0183908060018154018082558091505060019003905f5260205f20015f90919091909150555b6001915050919050565b42600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f018190555060065f81548092919061106990614037565b9190505550565b600c818154811061107f575f80fd5b905f5260205f2090600602015f91509050805f0154908060010154908060020154908060030154908060040154908060050154905086565b600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f6001600b83815481106110f3576110f261413e565b5b905f5260205f20906007020160020160156101000a81548160ff02191690831515021790555060019050919050565b60085481565b5f80600b838154811061113e5761113d61413e565b5b905f5260205f20906007020190505f600c84815481106111615761116061413e565b5b905f5260205f20906006020190505f815f0154905042600b868154811061118b5761118a61413e565b5b905f5260205f209060070201600501819055508260030160149054906101000a900460ff1661131d57600d5f845f0160029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206002015f81548092919061122790614037565b9190505550600d5f846001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206002015f81548092919061129f90614037565b9190505550600e5f846003015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206002015f81548092919061131790614037565b91905055505b600d5f845f0160029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060080185908060018154018082558091505060019003905f5260205f20015f9091909190915055600d5f846001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060080185908060018154018082558091505060019003905f5260205f20015f90919091909150558260020160149054906101000a900460ff16156114ca57600e5f846003015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600d0185908060018154018082558091505060019003905f5260205f20015f90919091909150555b80600d5f855f0160029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206004015f82825461153c9190614004565b9250508190555080600d5f856001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206004015f8282546115b59190614004565b9250508190555080600e5f856003015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206004015f82825461162e9190614004565b925050819055508060085f8282546116469190614004565b925050819055505f612710836001015483611661919061416b565b61166b91906141d9565b90508060055f82825461167e9190614004565b925050819055505f8460030160149054906101000a900460ff16156116c1576127108460030154846116b0919061416b565b6116ba91906141d9565b90506116e1565b6127108460020154846116d4919061416b565b6116de91906141d9565b90505b80600e5f876003015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f8282546117539190614004565b925050819055505f8183856117689190614209565b6117729190614209565b905080600d5f886001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206001015f8282546117e69190614004565b92505081905550612710600c89815481106118045761180361413e565b5b905f5260205f2090600602016005018190555060019650505050505050919050565b5f805f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168260405161186b9061425f565b5f6040518083038185875af1925050503d805f81146118a5576040519150601f19603f3d011682016040523d82523d5f602084013e6118aa565b606091505b505090505050565b5f805f600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168585604051602401611900929190614273565b6040516020818303038152906040527f68bc531f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161198a91906140e9565b5f60405180830381855af49150503d805f81146119c2576040519150601f19603f3d011682016040523d82523d5f602084013e6119c7565b606091505b50915091505f8151141580156119ee5750808060200190518101906119ec9190614113565b155b156119f7575f80fd5b60019250505092915050565b60035481565b5f80600b8381548110611a1f57611a1e61413e565b5b905f5260205f20906007020190506001600b8481548110611a4357611a4261413e565b5b905f5260205f2090600702015f015f6101000a81548160ff021916908315150217905550600d5f825f0160029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060070183908060018154018082558091505060019003905f5260205f20015f9091909190915055600d5f826001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060070183908060018154018082558091505060019003905f5260205f20015f90919091909150558060020160149054906101000a900460ff1615611c1457600e5f826003015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600b0183908060018154018082558091505060019003905f5260205f20015f90919091909150555b6001915050919050565b5f60055490505f600581905550611c545f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682613387565b611c5c575f80fd5b50565b6060806060806060600e5f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600a01600e5f8873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600b01600e5f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600c01600e5f8a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600d01600e5f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600e0184805480602002602001604051908101604052809291908181526020018280548015611df057602002820191905f5260205f20905b815481526020019060010190808311611ddc575b5050505050945083805480602002602001604051908101604052809291908181526020018280548015611e4057602002820191905f5260205f20905b815481526020019060010190808311611e2c575b5050505050935082805480602002602001604051908101604052809291908181526020018280548015611e9057602002820191905f5260205f20905b815481526020019060010190808311611e7c575b5050505050925081805480602002602001604051908101604052809291908181526020018280548015611ee057602002820191905f5260205f20905b815481526020019060010190808311611ecc575b5050505050915080805480602002602001604051908101604052809291908181526020018280548015611f3057602002820191905f5260205f20905b815481526020019060010190808311611f1c575b505050505090509450945094509450945091939590929450565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b8060025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f805f600a5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168585604051602401612023929190614273565b6040516020818303038152906040527f907f58ea000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516120ad91906140e9565b5f60405180830381855af49150503d805f81146120e5576040519150601f19603f3d011682016040523d82523d5f602084013e6120ea565b606091505b50915091505f81511415801561211157508080602001905181019061210f9190614113565b155b1561211a575f80fd5b60019250505092915050565b60045481565b600d602052805f5260405f205f91509050805f015490806001015490806002015490806003015490806004015490806005018054612169906142c7565b80601f0160208091040260200160405190810160405280929190818152602001828054612195906142c7565b80156121e05780601f106121b7576101008083540402835291602001916121e0565b820191905f5260205f20905b8154815290600101906020018083116121c357829003601f168201915b5050505050905086565b606080606080600d5f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600601600d5f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600701600d5f8873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600801600d5f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206009018380548060200260200160405190810160405280929190818152602001828054801561233957602002820191905f5260205f20905b815481526020019060010190808311612325575b505050505093508280548060200260200160405190810160405280929190818152602001828054801561238957602002820191905f5260205f20905b815481526020019060010190808311612375575b50505050509250818054806020026020016040519081016040528092919081815260200182805480156123d957602002820191905f5260205f20905b8154815260200190600101908083116123c5575b505050505091508080548060200260200160405190810160405280929190818152602001828054801561242957602002820191905f5260205f20905b815481526020019060010190808311612415575b5050505050905093509350935093509193509193565b805f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b5f805f80600190505f60035490505f808c1561249e573395508b94505b8c6124aa578b95503394505b8a6124b457600199505b8a1561259657600e5f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600601549150600e5f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600701549050600e5f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206009015f9054906101000a900460ff16612595575f93505b5b600b6040518061018001604052805f151581526020015f151581526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018d1515815260200186151581526020018c73ffffffffffffffffffffffffffffffffffffffff1681526020015f151581526020014281526020015f81526020018a815250908060018154018082558091505060019003905f5260205f2090600702015f909190919091505f820151815f015f6101000a81548160ff0219169083151502179055506020820151815f0160016101000a81548160ff0219169083151502179055506040820151815f0160026101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506060820151816001015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506080820151816002015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060a08201518160020160146101000a81548160ff02191690831515021790555060c08201518160020160156101000a81548160ff02191690831515021790555060e0820151816003015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506101008201518160030160146101000a81548160ff0219169083151502179055506101208201518160040155610140820151816005015561016082015181600601555050600c6040518060c001604052808b81526020018581526020018481526020018381526020015f81526020015f815250908060018154018082558091505060019003905f5260205f2090600602015f909190919091505f820151815f01556020820151816001015560408201518160020155606082015181600301556080820151816004015560a082015181600501555050600d5f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206006016001600b8054905061292d9190614209565b908060018154018082558091505060019003905f5260205f20015f9091909190915055600d5f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206006016001600b805490506129a29190614209565b908060018154018082558091505060019003905f5260205f20015f90919091909150558a15612a4157600e5f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600a016001600b80549050612a1d9190614209565b908060018154018082558091505060019003905f5260205f20015f90919091909150555b600196505050505050509695505050505050565b600b8181548110612a64575f80fd5b905f5260205f2090600702015f91509050805f015f9054906101000a900460ff1690805f0160019054906101000a900460ff1690805f0160029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806002015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020160149054906101000a900460ff16908060020160159054906101000a900460ff1690806003015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060030160149054906101000a900460ff1690806004015490806005015490806006015490508c565b60065481565b5f80600b8481548110612b9757612b9661413e565b5b905f5260205f20906007020190506001600b8581548110612bbb57612bba61413e565b5b905f5260205f20906007020160020160146101000a81548160ff021916908315150217905550600e5f826003015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600e0184908060018154018082558091505060019003905f5260205f20015f90919091909150556001600b8581548110612c7e57612c7d61413e565b5b905f5260205f20906007020160030160146101000a81548160ff02191690831515021790555082600b8581548110612cb957612cb861413e565b5b905f5260205f2090600702016003015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600e5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060060154600c8581548110612d5a57612d5961413e565b5b905f5260205f20906006020160020181905550600e5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060070154600c8581548110612dc257612dc161413e565b5b905f5260205f20906006020160030181905550600e5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600c0184908060018154018082558091505060019003905f5260205f20015f9091909190915055600191505092915050565b60075481565b600e602052805f5260405f205f91509050805f015490806001015490806002015490806003015490806004015490806005015490806006015490806007015490806008018054612e99906142c7565b80601f0160208091040260200160405190810160405280929190818152602001828054612ec5906142c7565b8015612f105780601f10612ee757610100808354040283529160200191612f10565b820191905f5260205f20905b815481529060010190602001808311612ef357829003601f168201915b505050505090806009015f9054906101000a900460ff1690508a565b5f8115612f865782600d5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206005019081612f809190614494565b50612fd5565b82600e5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206008019081612fd39190614494565b505b6001905092915050565b60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f80600b838154811061301a5761301961413e565b5b905f5260205f20906007020190506130763360015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600c86815481106130625761306161413e565b5b905f5260205f2090600602015f01546134d9565b61307e575f80fd5b6001600b84815481106130945761309361413e565b5b905f5260205f2090600702015f0160016101000a81548160ff0219169083151502179055506001915050919050565b81600381905550806004819055505050565b5f600e5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206009015f9054906101000a900460ff1615600e5f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206009015f6101000a81548160ff0219169083151502179055506001905090565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f80600b83815481106131bc576131bb61413e565b5b905f5260205f20906007020190506001600b84815481106131e0576131df61413e565b5b905f5260205f20906007020160030160146101000a81548160ff021916908315150217905550600d5f825f0160029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206003015f81548092919061327990614037565b9190505550600d5f826001015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f206003015f8154809291906132f190614037565b9190505550600e5f826003015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20600c0183908060018154018082558091505060019003905f5260205f20015f90919091909150556001915050919050565b5f805f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1685856040516024016133d592919061407e565b6040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161345f91906140e9565b5f604051808303815f865af19150503d805f8114613498576040519150601f19603f3d011682016040523d82523d5f602084013e61349d565b606091505b50915091505f8151141580156134c45750808060200190518101906134c29190614113565b155b156134cd575f80fd5b60019250505092915050565b5f805f60095f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1686868660405160240161352993929190614563565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516135b391906140e9565b5f604051808303815f865af19150503d805f81146135ec576040519150601f19603f3d011682016040523d82523d5f602084013e6135f1565b606091505b50915091505f8151141580156136185750808060200190518101906136169190614113565b155b15613621575f80fd5b6001925050509392505050565b5f604051905090565b5f80fd5b5f80fd5b5f8115159050919050565b6136538161363f565b811461365d575f80fd5b50565b5f8135905061366e8161364a565b92915050565b5f6020828403121561368957613688613637565b5b5f61369684828501613660565b91505092915050565b6136a88161363f565b82525050565b5f6020820190506136c15f83018461369f565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6136f0826136c7565b9050919050565b613700816136e6565b811461370a575f80fd5b50565b5f8135905061371b816136f7565b92915050565b5f819050919050565b61373381613721565b811461373d575f80fd5b50565b5f8135905061374e8161372a565b92915050565b5f805f6060848603121561376b5761376a613637565b5b5f6137788682870161370d565b93505060206137898682870161370d565b925050604061379a86828701613740565b9150509250925092565b5f602082840312156137b9576137b8613637565b5b5f6137c684828501613740565b91505092915050565b5f80604083850312156137e5576137e4613637565b5b5f6137f285828601613740565b925050602061380385828601613740565b9150509250929050565b61381681613721565b82525050565b5f60c08201905061382f5f83018961380d565b61383c602083018861380d565b613849604083018761380d565b613856606083018661380d565b613863608083018561380d565b61387060a083018461380d565b979650505050505050565b613884816136e6565b82525050565b5f60208201905061389d5f83018461387b565b92915050565b5f6020820190506138b65f83018461380d565b92915050565b5f602082840312156138d1576138d0613637565b5b5f6138de8482850161370d565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b61391981613721565b82525050565b5f61392a8383613910565b60208301905092915050565b5f602082019050919050565b5f61394c826138e7565b61395681856138f1565b935061396183613901565b805f5b83811015613991578151613978888261391f565b975061398383613936565b925050600181019050613964565b5085935050505092915050565b5f60a0820190508181035f8301526139b68188613942565b905081810360208301526139ca8187613942565b905081810360408301526139de8186613942565b905081810360608301526139f28185613942565b90508181036080830152613a068184613942565b90509695505050505050565b5f613a1c826136c7565b9050919050565b613a2c81613a12565b82525050565b5f602082019050613a455f830184613a23565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b83811015613a82578082015181840152602081019050613a67565b5f8484015250505050565b5f601f19601f8301169050919050565b5f613aa782613a4b565b613ab18185613a55565b9350613ac1818560208601613a65565b613aca81613a8d565b840191505092915050565b5f60c082019050613ae85f83018961380d565b613af5602083018861380d565b613b02604083018761380d565b613b0f606083018661380d565b613b1c608083018561380d565b81810360a0830152613b2e8184613a9d565b9050979650505050505050565b5f6080820190508181035f830152613b538187613942565b90508181036020830152613b678186613942565b90508181036040830152613b7b8185613942565b90508181036060830152613b8f8184613942565b905095945050505050565b613ba381613a12565b8114613bad575f80fd5b50565b5f81359050613bbe81613b9a565b92915050565b5f60208284031215613bd957613bd8613637565b5b5f613be684828501613bb0565b91505092915050565b5f819050919050565b613c0181613bef565b8114613c0b575f80fd5b50565b5f81359050613c1c81613bf8565b92915050565b5f805f805f8060c08789031215613c3c57613c3b613637565b5b5f613c4989828a01613660565b9650506020613c5a89828a0161370d565b9550506040613c6b89828a01613660565b9450506060613c7c89828a0161370d565b9350506080613c8d89828a01613740565b92505060a0613c9e89828a01613c0e565b9150509295509295509295565b613cb481613bef565b82525050565b5f61018082019050613cce5f83018f61369f565b613cdb602083018e61369f565b613ce8604083018d61387b565b613cf5606083018c61387b565b613d02608083018b61387b565b613d0f60a083018a61369f565b613d1c60c083018961369f565b613d2960e083018861387b565b613d3761010083018761369f565b613d4561012083018661380d565b613d5361014083018561380d565b613d61610160830184613cab565b9d9c50505050505050505050505050565b5f8060408385031215613d8857613d87613637565b5b5f613d9585828601613740565b9250506020613da68582860161370d565b9150509250929050565b5f61014082019050613dc45f83018d61380d565b613dd1602083018c61380d565b613dde604083018b61380d565b613deb606083018a61380d565b613df8608083018961380d565b613e0560a083018861380d565b613e1260c083018761380d565b613e1f60e083018661380d565b818103610100830152613e328185613a9d565b9050613e4261012083018461369f565b9b9a5050505050505050505050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b613e8f82613a8d565b810181811067ffffffffffffffff82111715613eae57613ead613e59565b5b80604052505050565b5f613ec061362e565b9050613ecc8282613e86565b919050565b5f67ffffffffffffffff821115613eeb57613eea613e59565b5b613ef482613a8d565b9050602081019050919050565b828183375f83830152505050565b5f613f21613f1c84613ed1565b613eb7565b905082815260208101848484011115613f3d57613f3c613e55565b5b613f48848285613f01565b509392505050565b5f82601f830112613f6457613f63613e51565b5b8135613f74848260208601613f0f565b91505092915050565b5f8060408385031215613f9357613f92613637565b5b5f83013567ffffffffffffffff811115613fb057613faf61363b565b5b613fbc85828601613f50565b9250506020613fcd85828601613660565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61400e82613721565b915061401983613721565b925082820190508082111561403157614030613fd7565b5b92915050565b5f61404182613721565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361407357614072613fd7565b5b600182019050919050565b5f6040820190506140915f83018561387b565b61409e602083018461380d565b9392505050565b5f81519050919050565b5f81905092915050565b5f6140c3826140a5565b6140cd81856140af565b93506140dd818560208601613a65565b80840191505092915050565b5f6140f482846140b9565b915081905092915050565b5f8151905061410d8161364a565b92915050565b5f6020828403121561412857614127613637565b5b5f614135848285016140ff565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f61417582613721565b915061418083613721565b925082820261418e81613721565b915082820484148315176141a5576141a4613fd7565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6141e382613721565b91506141ee83613721565b9250826141fe576141fd6141ac565b5b828204905092915050565b5f61421382613721565b915061421e83613721565b925082820390508181111561423657614235613fd7565b5b92915050565b50565b5f61424a5f836140af565b91506142558261423c565b5f82019050919050565b5f6142698261423f565b9150819050919050565b5f6040820190506142865f83018561380d565b614293602083018461380d565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806142de57607f821691505b6020821081036142f1576142f061429a565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026143537fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614318565b61435d8683614318565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61439861439361438e84613721565b614375565b613721565b9050919050565b5f819050919050565b6143b18361437e565b6143c56143bd8261439f565b848454614324565b825550505050565b5f90565b6143d96143cd565b6143e48184846143a8565b505050565b5b81811015614407576143fc5f826143d1565b6001810190506143ea565b5050565b601f82111561444c5761441d816142f7565b61442684614309565b81016020851015614435578190505b61444961444185614309565b8301826143e9565b50505b505050565b5f82821c905092915050565b5f61446c5f1984600802614451565b1980831691505092915050565b5f614484838361445d565b9150826002028217905092915050565b61449d82613a4b565b67ffffffffffffffff8111156144b6576144b5613e59565b5b6144c082546142c7565b6144cb82828561440b565b5f60209050601f8311600181146144fc575f84156144ea578287015190505b6144f48582614479565b86555061455b565b601f19841661450a866142f7565b5f5b828110156145315784890151825560018201915060208501945060208101905061450c565b8683101561454e578489015161454a601f89168261445d565b8355505b6001600288020188555050505b505050505050565b5f6060820190506145765f83018661387b565b614583602083018561387b565b614590604083018461380d565b94935050505056fea2646970667358221220dce69a658be591dac418fb875190b90cf36428039ce6fec5f3464438953f1a8164736f6c63430008170033"),  # contract bytecode
            "storage": {},
        },
    )
    return result

GENESIS_PARAMS = {
    #  'coinbase': constants.ZERO_ADDRESS,
    # change coinbase to skip 2500 gas gap
    "coinbase": Address(0x000000000000000000000000000000000000ABCD.to_bytes(20, "big")),
    "transaction_root": constants.BLANK_ROOT_HASH,
    "receipt_root": constants.BLANK_ROOT_HASH,
    "difficulty": 0,
    "gas_limit": 0xFFFFFF,
    "timestamp": 0,
    "extra_data": constants.GENESIS_EXTRA_DATA,
    "nonce": b"\x00" * 8,
}

def main():
    sender_private_key = funded_address_private_key()
    acct = Account.from_key(sender_private_key)
    base_state = base_genesis_state(
        to_canonical_address(acct.address), funded_address_initial_balance()
    )

    # with chain code
    simple_contract_address = to_canonical_address(
        "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a"
    )

    GENESIS_STATE = genesis_state(base_state, simple_contract_address)
    ethereum_tester = EthereumTester(
        PyEVMBackend(
            GENESIS_PARAMS,
            GENESIS_STATE,
            ((0, ShanghaiVM),),
        )
    )
    ethereum_tester.add_account(sender_private_key)
    provider = EthereumTesterProvider(ethereum_tester)
    w3 = Web3(provider)

    params = {
        "from": acct.address,
        "to": w3.to_checksum_address("0x692a70d2e424a56d2c6c27aa97d1a86395877b3a"),
        "gas": "0xffffff",
        "data": "0xb585375f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000d50d4c16ea00ae00f0f87fd3ae9dfd67cb70d7b0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000022ea81a6481fb45b2d9e42cc5826fc9547e75263142074844c53d53ab73c76695a885dea0d405bf5b4c0105e39c493b5217e37ad0000000000000000000000000000000000000000000000000000000000000097",
        "nonce": 0,
    }
    call_result = w3.eth.call(params)
    assert call_result == HexBytes(
        '0x0000000000000000000000000000000000000000000000000000000000000001'
    )

if __name__ == "__main__":
    main()

From the debug2 logs I can see the gas used is the same in the following line:

Level 8:eth.vm.computation.BaseComputation:COMPUTATION SUCCESS: from: 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b | to: 0x692a70d2e424a56d2c6c27aa97d1a86395877b3a | value: 0 | depth: 0 | static: n | gas-used: 280018 | gas-remaining: 16474489