Skip to content

Commit

Permalink
dev/fork-state-bash-script (#77)
Browse files Browse the repository at this point in the history
* add bash script for local forked testing

* fix: clarify docs

* fix: reorder docs

* Update README.md

* change getopt -> getopts

* derive blocktimestamp from forked block

* flag to disable expiration checks

* add tmux flag

* fix

* change sleep input

* add option to run everything locally

* add bundle bulker

* remove blocking code

* deploy contracts in local mode instead of overwriting account code

* finalize deploy script

* remove sub module edits

* fix parsing error
  • Loading branch information
mouseless0x authored Feb 7, 2024
1 parent 2809708 commit 90b5e11
Show file tree
Hide file tree
Showing 9 changed files with 308 additions and 6 deletions.
1 change: 1 addition & 0 deletions packages/cli/src/config/bundler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export const bundlerArgsSchema = z.object({

flushStuckTransactionsDuringStartup: z.boolean(),
safeMode: z.boolean(),
disableExpirationCheck: z.boolean(),

tenderlyEnabled: z.boolean().optional(),
minimumGasPricePercent: z.number().int().min(0),
Expand Down
6 changes: 6 additions & 0 deletions packages/cli/src/config/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,12 @@ export const bundlerOptions: CliCommandOptions<IBundlerArgsInput> = {
description: "Custom gas limit for estimation",
type: "string"
},
disableExpirationCheck: {
description: "Should the node make expiration checks",
type: "boolean",
require: false,
default: false
},
bundleMode: {
description:
"Set if the bundler should run in auto bundle mode or not.",
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/src/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ export const bundlerHandler = async (
parsedArgs.utilityPrivateKey,
parsedArgs.apiVersion,
parsedArgs.tenderlyEnabled,
parsedArgs.balanceOverrideEnabled
parsedArgs.balanceOverrideEnabled,
parsedArgs.disableExpirationCheck,
)
}

Expand Down
12 changes: 7 additions & 5 deletions packages/rpc/src/validation/UnsafeValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,7 @@ async function getSimulationResult(
(err) => err instanceof ContractFunctionExecutionError
)
throw new RpcError(
`UserOperation reverted during simulation with reason: ${
(revertError?.cause as any)?.reason
`UserOperation reverted during simulation with reason: ${(revertError?.cause as any)?.reason
}`,
ValidationErrors.SimulateValidation
)
Expand Down Expand Up @@ -133,6 +132,7 @@ export class UnsafeValidator implements IValidator {
utilityWallet: Account
usingTenderly: boolean
balanceOverrideEnabled: boolean
disableExpirationCheck: boolean
apiVersion: ApiVersion
chainId: number

Expand All @@ -144,7 +144,8 @@ export class UnsafeValidator implements IValidator {
utilityWallet: Account,
apiVersion: ApiVersion,
usingTenderly = false,
balanceOverrideEnabled = false
balanceOverrideEnabled = false,
disableExpirationCheck = false,
) {
this.publicClient = publicClient
this.entryPoint = entryPoint
Expand All @@ -153,6 +154,7 @@ export class UnsafeValidator implements IValidator {
this.utilityWallet = utilityWallet
this.usingTenderly = usingTenderly
this.balanceOverrideEnabled = balanceOverrideEnabled
this.disableExpirationCheck = disableExpirationCheck
this.apiVersion = apiVersion
this.chainId = publicClient.chain.id
}
Expand Down Expand Up @@ -361,14 +363,14 @@ export class UnsafeValidator implements IValidator {
now
})

if (validationResult.returnInfo.validAfter > now - 5) {
if (validationResult.returnInfo.validAfter > now - 5 && !this.disableExpirationCheck) {
throw new RpcError(
"User operation is not valid yet",
ValidationErrors.ExpiresShortly
)
}

if (validationResult.returnInfo.validUntil < now + 30) {
if (validationResult.returnInfo.validUntil < now + 30 && !this.disableExpirationCheck) {
throw new RpcError(
"expires too soon",
ValidationErrors.ExpiresShortly
Expand Down
1 change: 1 addition & 0 deletions scripts/.bundle-bulker.bytecode
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
608060405234801561001057600080fd5b50610b6a806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c806303a353bd146100d35780633e652e30146100fd57806345c706581461011057806394430fa514610151578063e5f7e72f1461016c575b6000806100656000366101a7565b6040516307eb652360e21b81529193509150735ff137d4b0fdcd49dca30c7cf57e578a026d278990631fad948c906100a390859085906004016105b2565b600060405180830381600087803b1580156100bd57600080fd5b505af11580156100d1573d6000803e3d6000fd5b005b6100e66100e13660046106dc565b6101a7565b6040516100f49291906105b2565b60405180910390f35b6100d161010b36600461077f565b6102bd565b61013961011e3660046107b6565b6000602081905290815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020016100f4565b610139735ff137d4b0fdcd49dca30c7cf57e578a026d278981565b61019261017a3660046107d8565b60016020526000908152604090205463ffffffff1681565b60405163ffffffff90911681526020016100f4565b60606000806101b960048286886107f5565b6101c29161081f565b60e01c6000818152602081905260409020549091506001600160a01b0316806102325760405162461bcd60e51b815260206004820152601760248201527f496e666c61746f72206e6f74207265676973746572656400000000000000000060448201526064015b60405180910390fd5b6001600160a01b0381166303a353bd61024e876004818b6107f5565b6040518363ffffffff1660e01b815260040161026b92919061084f565b600060405180830381865afa158015610288573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526102b09190810190610966565b9350935050509250929050565b8163ffffffff166000036103135760405162461bcd60e51b815260206004820152601760248201527f496e666c61746f722049442063616e6e6f7420626520300000000000000000006044820152606401610229565b60e082901b6001600160e01b0319166303e652e360e41b1480159061034d575060e082901b6001600160e01b0319166303a353bd60e01b14155b6103af5760405162461bcd60e51b815260206004820152602d60248201527f496e666c61746f722049442063616e6e6f7420636c6173682077697468206f7460448201526c6865722066756e6374696f6e7360981b6064820152608401610229565b6001600160a01b0381166104055760405162461bcd60e51b815260206004820152601c60248201527f496e666c61746f7220616464726573732063616e6e6f742062652030000000006044820152606401610229565b63ffffffff82166000908152602081905260409020546001600160a01b0316156104715760405162461bcd60e51b815260206004820152601b60248201527f496e666c61746f7220616c7265616479207265676973746572656400000000006044820152606401610229565b6001600160a01b03811660009081526001602052604090205463ffffffff16156104dd5760405162461bcd60e51b815260206004820152601b60248201527f496e666c61746f7220616c7265616479207265676973746572656400000000006044820152606401610229565b63ffffffff821660008181526020818152604080832080546001600160a01b0319166001600160a01b0387169081179091558084526001835292819020805463ffffffff1916851790558051938452908301919091527f0d97c40f054b84805413cf34bed1603e769ee682b2b8a85fe26e032e237bd6a3910160405180910390a15050565b60005b8381101561057d578181015183820152602001610565565b50506000910152565b6000815180845261059e816020860160208601610562565b601f01601f19169290920160200192915050565b60006040808301818452808651808352606092508286019150828160051b8701016020808a0160005b848110156106b657898403605f19018652815180516001600160a01b03168552610160848201518587015289820151818b88015261061b82880182610586565b915050888201518682038a8801526106338282610586565b6080848101519089015260a0808501519089015260c0808501519089015260e08085015190890152610100808501519089015261012080850151898303828b015291935091506106838382610586565b9250505061014080830151925086820381880152506106a28183610586565b9785019795505050908201906001016105db565b50508196506106cf8189018a6001600160a01b03169052565b5050505050509392505050565b600080602083850312156106ef57600080fd5b823567ffffffffffffffff8082111561070757600080fd5b818501915085601f83011261071b57600080fd5b81358181111561072a57600080fd5b86602082850101111561073c57600080fd5b60209290920196919550909350505050565b803563ffffffff8116811461076257600080fd5b919050565b6001600160a01b038116811461077c57600080fd5b50565b6000806040838503121561079257600080fd5b61079b8361074e565b915060208301356107ab81610767565b809150509250929050565b6000602082840312156107c857600080fd5b6107d18261074e565b9392505050565b6000602082840312156107ea57600080fd5b81356107d181610767565b6000808585111561080557600080fd5b8386111561081257600080fd5b5050820193919092039150565b6001600160e01b031981358181169160048510156108475780818660040360031b1b83161692505b505092915050565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b634e487b7160e01b600052604160045260246000fd5b604051610160810167ffffffffffffffff811182821017156108b8576108b861087e565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156108e7576108e761087e565b604052919050565b805161076281610767565b600082601f83011261090b57600080fd5b815167ffffffffffffffff8111156109255761092561087e565b610938601f8201601f19166020016108be565b81815284602083860101111561094d57600080fd5b61095e826020830160208701610562565b949350505050565b6000806040838503121561097957600080fd5b825167ffffffffffffffff8082111561099157600080fd5b818501915085601f8301126109a557600080fd5b81516020828211156109b9576109b961087e565b8160051b6109c88282016108be565b928352848101820192828101908a8511156109e257600080fd5b83870192505b84831015610b17578251868111156109ff57600080fd5b8701610160818d03601f19011215610a1657600080fd5b610a1e610894565b610a298683016108ef565b8152604082015186820152606082015188811115610a4657600080fd5b610a548e88838601016108fa565b604083015250608082015188811115610a6c57600080fd5b610a7a8e88838601016108fa565b60608301525060a0820151608082015260c082015160a082015260e082015160c082015261010082015160e08201526101208201516101008201526101408083015189811115610ac957600080fd5b610ad78f89838701016108fa565b6101208401525061016083015189811115610af157600080fd5b610aff8f89838701016108fa565b918301919091525083525091830191908301906109e8565b9750610b279150508782016108ef565b945050505050925092905056fea26469706673582212207ed838f4b7adb68a66fb680398aedaf7834714915afe01319096aa23e89e76a164736f6c63430008150033
1 change: 1 addition & 0 deletions scripts/.entrypoint.bytecode

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions scripts/.simple-account-factory.bytecode

Large diffs are not rendered by default.

55 changes: 55 additions & 0 deletions scripts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Scripts For Local Testing

Simple bash script to deploy and run a local alto + anvil instance in forked mode (uses state from mainnet).

### Running

The environment must be run in either **forked** or **local** mode.

#### Running in forked mode

Fork mode runs alto tied to a forked anvil instance. And is specified with the `-f` flag.

```
./run-local-instance.sh -f -r <rpc-url> -b <fork-block>
```

both flags `-r` (rpc url) and `-b` (block number) are required for forked mode.

#### Running in local mode

Local mode runs alto tied to a standard anvil instance. And is specified with the `-l` flag.
Local mode will deploy the following contracts:
- [EntryPoint](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/core/EntryPoint.sol) to address `0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789`
- [SimpleAccountFactory](https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/samples/SimpleAccount.sol) to address `0x9406Cc6185a346906296840746125a0E44976454`
- [BundleBulker](https://github.com/daimo-eth/bulk/blob/master/src/BundleBulker.sol) to address `0x000000000091A1F34f51CE866bEd8983dB51a97E`

```console
./run-local-instance.sh -l
```

> [!NOTE]
> Make sure you don't rename the repo when cloning. The script searches up for a directory named `alto` and treats it as the project root.
### Cli Flags + Options

```console
Usage: ./run-local-fork.sh [OPTIONS]
Utility to spawn a local alto instances linked to an anvil node.
*Must* be ran with either -l or -f flags.

Alto Options
-e EntryPoint contract address, 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789 (DEFAULT)
-l Local mode
-f Fork mode (used for debugging)

Anvil Options
-r <rpc-url> RPC url to fork from
-b <block-num> Fork block number
-p <port>
-h <host>
-c <address>,<bytecode-file>

Misc Options
-t Launch anvil + alto in a tmux split
```
234 changes: 234 additions & 0 deletions scripts/run-local-instance.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
#!/usr/bin/env bash
set -euo pipefail

bundleBulker=0x3Fde2701a9a5FC30b1F1916ec465A2F04BC7c05d
simpleAccountFactory=0x9406Cc6185a346906296840746125a0E44976454
entryPoint=0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789
rpcUrl=
blockNum=
tmux=
forkMode=
localMode=
signerKey=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 # anvil default acc 0
utilityKey=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d # anvil default acc 1
anvilPort=8545
anvilHost=127.0.0.1
patchBytecode=()

projectRoot=`pwd | sed 's%\(.*/alto\)/.*%\1%'`

# helper functions.
usage(){
>&2 cat << EOF
Usage: $0 [OPTIONS]
Utility to quickly spawn a local alto instance linked to an anvil node.
*Must* be ran with either -l or -f flags.
Alto Options
-e EntryPoint contract address, 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789 (DEFAULT)
-l Local mode
-f Fork mode (used for debugging)
Anvil Options
-r <rpc-url> RPC url to fork from
-b <block-num> Fork block number
-p <port>
-h <host>
-c <address>,<bytecode-file>
Misc Options
-t Launch anvil + alto in a tmux split
EOF
exit 1
}
apply_bytecode_patches() {
for patch in "${patchBytecode[@]}"; do
IFS=',' read -r contractAddr bytecodeFile <<< "$patch"

if [[ -z "$contractAddr" || -z "$bytecodeFile" ]]; then
echo "ERR: wrong usage, failed to parse. correct usage: -c <address>,<bytecode-file>"
exit 1
fi

patchedBytecode=$(cat $bytecodeFile | tr -d '\n')

curl -H "Content-Type: application/json" \
-X POST --data "{\"id\": \"4337\", \"jsonrpc\":\"2.0\", \"method\":\"anvil_setCode\", \"params\": [\"$contractAddr\", \"$patchedBytecode\"]}" \
$anvilHost:$anvilPort

done
}
deploy_contracts() {
entryPointCall=0x0000000000000000000000000000000000000000000000000000000000000000$(cat $projectRoot/scripts/.entrypoint.bytecode | tr -d '\n')
cast send 0x4e59b44847b379578588920ca78fbf26c0b4956c $entryPointCall \
--private-key $utilityKey \
--rpc-url http://$anvilHost:$anvilPort

simpleAccountFactoryCall=0x0000000000000000000000000000000000000000000000000000000000000000$(cat $projectRoot/scripts/.simple-account-factory.bytecode | tr -d '\n')
cast send 0x4e59b44847b379578588920ca78fbf26c0b4956c $simpleAccountFactoryCall \
--private-key $utilityKey \
--rpc-url http://$anvilHost:$anvilPort

bundleBulkerCall=0x7cf7a0f0060e1519d0ee3e12e0ee57890f69d7aa693404299a3a779e90cd7921$(cat $projectRoot/scripts/.bundle-bulker.bytecode | tr -d '\n')
cast send 0x4e59b44847b379578588920ca78fbf26c0b4956c $bundleBulkerCall \
--private-key $utilityKey \
--rpc-url http://$anvilHost:$anvilPort
}

while getopts "e:r:b:h:p:c:tfl" opt;
do
case ${opt} in
e)
entryPoint=$OPTARG
;;
r)
rpcUrl=$OPTARG
;;
b)
blockNum=$OPTARG
;;
p)
anvilPort=$OPTARG
;;
h)
anvilHost=$OPTARG
;;
c)
patchBytecode+=($OPTARG)
;;
t)
tmux=1
;;
f)
forkMode=1
;;
l)
localMode=1
;;
esac
done

# check for required flags.
if [ -n "$localMode" ] && [ -n "$forkMode" ]; then
echo "[Err] Must be ran in either fork or local mode. Run again with either flag -f or -l." && exit 1
fi

if [ -z "$localMode" ] && [ -z "$forkMode" ]; then
echo "[Err] Must be ran in either fork or local mode. Run again with either flag -f or -l." && exit 1
fi

if [ -n "$localMode" ]; then
[ -n "$rpcUrl" ] && echo "[NOTE] Flag -r cannot be used in local mode" && exit 1
[ -n "$blockNum" ] && echo "[NOTE] Flag -b cannot be used in local mode" && exit 1
elif [ -n "$forkMode" ]; then
[ -z "$rpcUrl" ] && echo "[NOTE] Flag -r is missing, required in forking mode" && exit 1
[ -z "$blockNum" ] && echo "[NOTE] Flag -b is missing, required in forking mode" && exit 1
fi

if [ -n "$localMode" ] && [ -z "$forkMode" ]; then
# build alto intance.
pnpm build

if [ -z "$tmux" ]; then
# launch both instances in same terminal.
anvil &

sleep 2
deploy_contracts
apply_bytecode_patches

$projectRoot/alto --entryPoint $entryPoint \
--signerPrivateKeys $signerKey \
--utilityPrivateKey $utilityKey \
--rpcUrl http://$anvilHost:$anvilPort \
--minBalance 0 \
--networkName local \
--disableExpirationCheck true

else
# launch both instances in a tmux split.
SESSION="anvil_alto_session"
if tmux has-session -t $SESSION 2>/dev/null; then
tmux kill-session -t $SESSION
fi

# create tmux session
tmux new-session -d -s $SESSION
tmux split-window -h -t $SESSION

# setup anvil on pane 0
tmux send-keys -t ${SESSION}.0 "anvil" C-m

sleep 2
deploy_contracts
apply_bytecode_patches

# setup alto on pane 1
tmux send-keys -t ${SESSION}.1 "$projectRoot/alto --rpcUrl http://$anvilHost:$anvilPort \
--entryPoint $entryPoint \
--signerPrivateKeys $signerKey \
--utilityPrivateKey $utilityKey \
--minBalance 0 \
--networkName local \
--disableExpirationCheck true" C-m

tmux attach-session -t $SESSION
fi
fi

if [ -n $forkMode ] && [ -z "$localMode" ]; then
forkTimestamp=$(cast block $blockNum --rpc-url $rpcUrl | grep time | awk '{print $2}' | tr -d '\n')

# build alto intance.
pnpm build

if [ -z "$tmux" ]; then
# launch both instances in same terminal.
anvil --fork-url $rpcUrl \
--fork-block-number $blockNum \
--timestamp $forkTimestamp &

sleep 2
apply_bytecode_patches

$projectRoot/alto --entryPoint $entryPoint \
--signerPrivateKeys $signerKey \
--utilityPrivateKey $utilityKey \
--rpcUrl http://$anvilHost:$anvilPort \
--minBalance 0 \
--networkName local \
--disableExpirationCheck true
else
# launch both instances in a tmux split.
SESSION="anvil_alto_session"
if tmux has-session -t $SESSION 2>/dev/null; then
tmux kill-session -t $SESSION
fi

# create tmux session
tmux new-session -d -s $SESSION
tmux split-window -h -t $SESSION

# setup anvil on pane 0
tmux send-keys -t ${SESSION}.0 "anvil --fork-url $rpcUrl \
--fork-block-number $blockNum \
--timestamp $forkTimestamp" C-m

sleep 2
apply_bytecode_patches

# setup alto on pane 1
tmux send-keys -t ${SESSION}.1 "$projectRoot/alto --rpcUrl http://$anvilHost:$anvilPort \
--entryPoint $entryPoint \
--signerPrivateKeys $signerKey \
--utilityPrivateKey $utilityKey \
--minBalance 0 \
--networkName local \
--disableExpirationCheck true" C-m

tmux attach-session -t $SESSION
fi
fi

exit 0

0 comments on commit 90b5e11

Please sign in to comment.