Skip to content

Commit

Permalink
AA-68 bundler rpc calls (#24)
Browse files Browse the repository at this point in the history
* eth_estimateUserOp
* getUserOperationReceipt
  • Loading branch information
drortirosh authored Dec 24, 2022
1 parent 286eddb commit c36bbc4
Show file tree
Hide file tree
Showing 25 changed files with 956 additions and 278 deletions.
118 changes: 118 additions & 0 deletions aabundler-launcher
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#!/bin/bash -e
# launch bundler: also start geth, and deploy entrypoint.
cd `dirname $0`

GETH=geth
GETHPORT=8545
BUNDLERPORT=3000
GETHPID=/tmp/aabundler.geth.pid
BUNDLERPID=/tmp/aabundler.node.pid
VERSION="aabundler-js-0.1"

BUNDLERLOG=/tmp/aabundler.log

BUNDLERURL=http://localhost:$BUNDLERPORT/rpc
NODEURL=http://localhost:$GETHPORT

function fatal {
echo "$@" 1>&2
exit 1
}

function isPortFree {
port=$1
curl http://localhost:$port 2>&1 | grep -q Connection.refused
}


function waitForPort {
port=$1
while isPortFree $port; do true; done
}

function startBundler {

isPortFree $GETHPORT || fatal port $GETHPORT not free
isPortFree $BUNDLERPORT || fatal port $BUNDLERPORT not free

echo == starting geth 1>&2
$GETH version | grep ^Version: 1>&2

$GETH --dev --http.port $GETHPORT \
--http.api personal,eth,net,web3,debug \
--ignore-legacy-receipts \
--http \
--http.addr "0.0.0.0" \
--rpc.allow-unprotected-txs \
--allow-insecure-unlock \
--verbosity 1 & echo $! > $GETHPID

waitForPort $GETHPORT

cd packages/bundler
echo == Deploying entrypoint 1>&2
export TS_NODE_TRANSPILE_ONLY=1
npx hardhat deploy --network localhost
echo == Starting bundler 1>&2
ts-node -T ./src/exec.ts --config ./localconfig/bundler.config.json --port $BUNDLERPORT --network http://localhost:$GETHPORT & echo $! > $BUNDLERPID
waitForPort $BUNDLERPORT
}

function start {
isPortFree $GETPORTPORT || fatal port $GETHPORT not free
isPortFree $BUNDLERPORT || fatal port $BUNDLERPORT not free
startBundler > $BUNDLERLOG
echo == Bundler, Geth started. log to $BUNDLERLOG
}

function stop {
echo == stopping bundler
test -r $BUNDLERPID && kill -9 `cat $BUNDLERPID`
test -r $GETHPID && kill -9 `cat $GETHPID`
rm $BUNDLERPID $GETHPID
echo == bundler, geth stopped
}

function jsoncurl {
method=$1
params=$2
url=$3
data="{\"method\":\"$method\",\"params\":$params,\"id\":1,\"jsonrpc\":\"2.0\"}"
curl -s -H content-type:application/json -d $data $url
}

function info {
entrypoint=`jsoncurl eth_supportedEntryPoints [] $BUNDLERURL | jq -r .result["0"]`
echo "BUNDLER_ENTRYPOINT=$entrypoint"
status="down"; test -n "$entrypoint" && status="active"
echo "BUNDLER_URL=$BUNDLERURL"
echo "BUNDLER_NODE_URL=$NODEURL"
echo "BUNDLER_LOG=$BUNDLERLOG"
echo "BUNDLER_VERSION=$VERSION"
echo "BUNDLER_STATUS=$status"
}

case $1 in

start)
start
;;
stop)
stop
;;

restart)
echo == restarting bundler
stop
start
;;

info)
info
;;

*) echo "usage: $0 {start|stop|restart|info}"
exit 1 ;;


esac
56 changes: 0 additions & 56 deletions launcher

This file was deleted.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"clear": "lerna run clear",
"hardhat-compile": "lerna run hardhat-compile",
"preprocess": "yarn lerna-clear && yarn hardhat-compile && yarn lerna-tsc",
"runop-self": "yarn runop --deployDeployer --selfBundler"
"runop-self": "ts-node ./packages/bundler/src/runner/runop.ts --deployDeployer --selfBundler"
},
"dependencies": {
"@typescript-eslint/eslint-plugin": "^5.33.0",
Expand Down
118 changes: 118 additions & 0 deletions packages/bundler/contracts/tests/TestRulesAccount.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.15;

import "@account-abstraction/contracts/interfaces/IAccount.sol";
import "@account-abstraction/contracts/interfaces/IPaymaster.sol";
import "@account-abstraction/contracts/interfaces/IEntryPoint.sol";

contract Dummy {
uint public value = 1;
}

contract TestCoin {
mapping(address => uint) balances;

function balanceOf(address addr) public returns (uint) {
return balances[addr];
}

function mint(address addr) public returns (uint) {
return balances[addr] += 100;
}

//unrelated to token: testing inner object revert
function reverting() public returns (uint) {
revert("inner-revert");
}

function wasteGas() public returns (uint) {
string memory buffer = "string to be duplicated";
while (true) {
buffer = string.concat(buffer, buffer);
}
return 0;
}
}

contract TestRulesAccount is IAccount, IPaymaster {

uint state;
TestCoin public coin;

event State(uint oldState, uint newState);

function setState(uint _state) external {
emit State(state, _state);
state = _state;
}

function setCoin(TestCoin _coin) public returns (uint){
coin = _coin;
return 0;
}

function eq(string memory a, string memory b) internal returns (bool) {
return keccak256(bytes(a)) == keccak256(bytes(b));
}

event TestMessage(address eventSender);

function runRule(string memory rule) public returns (uint) {
if (eq(rule, "")) return 0;
else if (eq(rule, "number")) return block.number;
else if (eq(rule, "coinbase")) return uint160(address(block.coinbase));
else if (eq(rule, "blockhash")) return uint(blockhash(0));
else if (eq(rule, "create2")) return new Dummy{salt : bytes32(uint(0x1))}().value();
else if (eq(rule, "balance-self")) return coin.balanceOf(address(this));
else if (eq(rule, "mint-self")) return coin.mint(address(this));
else if (eq(rule, "balance-1")) return coin.balanceOf(address(1));
else if (eq(rule, "mint-1")) return coin.mint(address(1));

else if (eq(rule, "inner-revert")) return coin.reverting();
else if (eq(rule, "oog")) return coin.wasteGas();
else if (eq(rule, "emit-msg")) {
emit TestMessage(address(this));
return 0;}

revert(string.concat("unknown rule: ", rule));
}

function addStake(IEntryPoint entryPoint) public payable {
entryPoint.addStake{value : msg.value}(1);
}

function validateUserOp(UserOperation calldata userOp, bytes32, address, uint256 missingAccountFunds)
external override returns (uint256 ) {
if (missingAccountFunds > 0) {
/* solhint-disable-next-line avoid-low-level-calls */
(bool success,) = msg.sender.call{value : missingAccountFunds}("");
success;
}
if (userOp.signature.length == 4) {
uint32 deadline = uint32(bytes4(userOp.signature));
return deadline;
}
runRule(string(userOp.signature));
return 0;
}

function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)
external returns (bytes memory context, uint256 deadline) {
string memory rule = string(userOp.paymasterAndData[20 :]);
runRule(rule);
return ("", 0);
}

function postOp(PostOpMode, bytes calldata, uint256) external {}

}

contract TestRulesAccountDeployer {
function create(string memory rule, TestCoin coin) public returns (TestRulesAccount) {
TestRulesAccount a = new TestRulesAccount{salt : bytes32(uint(0))}();
a.setCoin(coin);
a.runRule(rule);
return a;
}

}
23 changes: 0 additions & 23 deletions packages/bundler/deploy/1-deploy-helper.ts

This file was deleted.

5 changes: 0 additions & 5 deletions packages/bundler/deploy/2-deploy-entrypoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,13 @@ import { HardhatRuntimeEnvironment } from 'hardhat/types'
import { DeployFunction } from 'hardhat-deploy/types'
import { ethers } from 'hardhat'

const UNSTAKE_DELAY_SEC = 100
const PAYMASTER_STAKE = ethers.utils.parseEther('1')

// deploy entrypoint - but only on debug network..
const deployEP: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
// first verify if already deployed:
try {
await hre.deployments.deploy(
'EntryPoint', {
from: ethers.constants.AddressZero,
args: [PAYMASTER_STAKE, UNSTAKE_DELAY_SEC],
deterministicDeployment: true,
log: true
})
Expand All @@ -35,7 +31,6 @@ const deployEP: DeployFunction = async function (hre: HardhatRuntimeEnvironment)
'EntryPoint', {
// from: ethers.constants.AddressZero,
from: deployer,
// args: [PAYMASTER_STAKE, UNSTAKE_DELAY_SEC],
gasLimit: 4e6,
deterministicDeployment: true,
log: true
Expand Down
1 change: 0 additions & 1 deletion packages/bundler/deploy/3-fund-signer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { HardhatRuntimeEnvironment } from 'hardhat/types'
import { DeployFunction } from 'hardhat-deploy/types'
import { parseEther } from 'ethers/lib/utils'

// deploy entrypoint - but only on debug network..
const fundsigner: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
// on geth, fund the default "hardhat node" account.

Expand Down
3 changes: 1 addition & 2 deletions packages/bundler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@
"ethers": "^5.7.0",
"express": "^4.18.1",
"hardhat-gas-reporter": "^1.0.8",
"ow": "^0.28.1",
"source-map-support": "^0.5.21"
"ow": "^0.28.1"
},
"devDependencies": {
"@nomicfoundation/hardhat-chai-matchers": "^1.0.3",
Expand Down
Loading

0 comments on commit c36bbc4

Please sign in to comment.