diff --git a/packages/evm/src/opcodes/functions.ts b/packages/evm/src/opcodes/functions.ts index 049046a29f..d6bdfc423d 100644 --- a/packages/evm/src/opcodes/functions.ts +++ b/packages/evm/src/opcodes/functions.ts @@ -20,8 +20,8 @@ import { MAX_INTEGER_BIGINT, SECP256K1_ORDER_DIV_2, TWO_POW256, + bigIntToAddressBytes, bigIntToBytes, - bigIntToHex, bytesToBigInt, bytesToHex, concatBytes, @@ -622,8 +622,8 @@ export const handlers: Map = new Map([ return } - const historyAddress = Address.fromString( - bigIntToHex(common.param('vm', 'historyStorageAddress')) + const historyAddress = new Address( + bigIntToAddressBytes(common.param('vm', 'historyStorageAddress')) ) const key = setLengthLeft(bigIntToBytes(number % historyServeWindow), 32) @@ -1156,7 +1156,8 @@ export const handlers: Map = new Map([ return } - const expectedAddress = new Address(setLengthLeft(bigIntToBytes(authority), 20).slice(-20)) + // we don't want strick check here on authority being in address range just last 20 bytes + const expectedAddress = new Address(bigIntToAddressBytes(authority, false)) const account = (await runState.stateManager.getAccount(expectedAddress)) ?? new Account() if (account.isContract()) { diff --git a/packages/util/src/address.ts b/packages/util/src/address.ts index 5fdf192df4..2cb37d498e 100644 --- a/packages/util/src/address.ts +++ b/packages/util/src/address.ts @@ -43,7 +43,7 @@ export class Address { */ static fromString(str: string): Address { if (!isValidAddress(str)) { - throw new Error('Invalid address') + throw new Error(`Invalid address input=${str}`) } return new Address(hexToBytes(str)) } diff --git a/packages/util/src/bytes.ts b/packages/util/src/bytes.ts index c67950c251..907bf2ad3d 100644 --- a/packages/util/src/bytes.ts +++ b/packages/util/src/bytes.ts @@ -430,6 +430,16 @@ export const bigIntToUnpaddedBytes = (value: bigint): Uint8Array => { return unpadBytes(bigIntToBytes(value)) } +export const bigIntToAddressBytes = (value: bigint, strict: boolean = true): Uint8Array => { + const addressBytes = bigIntToBytes(value) + if (strict && addressBytes.length > 20) { + throw Error(`Invalid address bytes length=${addressBytes.length} strict=${strict}`) + } + + // setLength already slices if more than requisite length + return setLengthLeft(addressBytes, 20) +} + /** * Convert value from number to an unpadded Uint8Array * (useful for RLP transport) diff --git a/packages/util/test/bytes.spec.ts b/packages/util/test/bytes.spec.ts index fa636fe43d..3d6954b2b6 100644 --- a/packages/util/test/bytes.spec.ts +++ b/packages/util/test/bytes.spec.ts @@ -3,6 +3,7 @@ import { assert, describe, it } from 'vitest' import { Address, addHexPrefix, + bigIntToAddressBytes, bigIntToBytes, bigIntToHex, bigIntToUnpaddedBytes, @@ -401,6 +402,36 @@ describe('bigIntToUnpaddedBytes', () => { }) }) +describe('bigIntToAddressBytes', () => { + const testCases = [ + [ + '0x0aae40965e6800cd9b1f4b05ff21581047e3f91e', + BigInt('0x0aae40965e6800cd9b1f4b05ff21581047e3f91e'), + true, + ], + [ + '0xe473f7e92ba2490e9fcbbe8bb9c3be3adbb74efc', + BigInt('0xe473f7e92ba2490e9fcbbe8bb9c3be3adbb74efc'), + true, + ], + [ + '0xae40965e6800cd9b1f4b05ff21581047e3f91e00', + BigInt('0x0aae40965e6800cd9b1f4b05ff21581047e3f91e00'), + false, + ], + ] + + for (const [addressHex, addressBigInt, isSafe] of testCases) { + it('should correctly convert', () => { + const addressHexFromBigInt = bytesToHex(bigIntToAddressBytes(addressBigInt, false)) + assert.equal(addressHex, addressHexFromBigInt, `should correctly convert ${addressBigInt}`) + if (isSafe === false) { + assert.throw(() => bigIntToAddressBytes(addressBigInt)) + } + }) + } +}) + describe('intToUnpaddedBytes', () => { it('should equal unpadded buffer value', () => { assert.deepEqual(intToUnpaddedBytes(0), Uint8Array.from([])) diff --git a/packages/vm/src/runBlock.ts b/packages/vm/src/runBlock.ts index e38f6035f7..2a9f190d2d 100644 --- a/packages/vm/src/runBlock.ts +++ b/packages/vm/src/runBlock.ts @@ -12,8 +12,8 @@ import { BIGINT_8, GWEI_TO_WEI, KECCAK256_RLP, + bigIntToAddressBytes, bigIntToBytes, - bigIntToHex, bytesToHex, concatBytes, equalsBytes, @@ -488,8 +488,8 @@ export async function accumulateParentBlockHash( if (!this.common.isActivatedEIP(2935)) { throw new Error('Cannot call `accumulateParentBlockHash`: EIP 2935 is not active') } - const historyAddress = Address.fromString( - bigIntToHex(this.common.param('vm', 'historyStorageAddress')) + const historyAddress = new Address( + bigIntToAddressBytes(this.common.param('vm', 'historyStorageAddress')) ) const historyServeWindow = this.common.param('vm', 'historyServeWindow') diff --git a/packages/vm/test/api/EIPs/eip-2935-historical-block-hashes.spec.ts b/packages/vm/test/api/EIPs/eip-2935-historical-block-hashes.spec.ts index a29ae9c4f6..ecec388476 100644 --- a/packages/vm/test/api/EIPs/eip-2935-historical-block-hashes.spec.ts +++ b/packages/vm/test/api/EIPs/eip-2935-historical-block-hashes.spec.ts @@ -101,16 +101,16 @@ const deploymentConfigs = [ // may 25 configuration with set on the lines of 4788 [ // contract code - '0x3373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35600143035500', + '0x3373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35611fff60014303165500', // deployment tx input - '0x60608060095f395ff33373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35600143035500', + '0x60648060095f395ff33373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35611fff60014303165500', // v r s ['0x1b', '0x539', '0x1b9b6eb1f0'], // sender, hash, deployed address [ - '0x72eed28860ac985f1ec32306564b5926ea7c0b70', - '0xe43ec833884324f31c2e8314534d5b15233d84f32f05a05ea2a45649b587a9df', - '0xcc766763fcc59487cdab9f21487174417b1fa282', + '0xe473f7e92ba2490e9fcbbe8bb9c3be3adbb74efc', + '0x3c769a03d6e2212f1d26ab59ba797dce0900df29ffd23c1dd391fd6b217973ad', + '0x0aae40965e6800cd9b1f4b05ff21581047e3f91e', ], ], ]