Skip to content

Commit

Permalink
Merge pull request #35 from gballet/execute-block-in-engine-api
Browse files Browse the repository at this point in the history
execute block in engine api
  • Loading branch information
jsign authored Aug 29, 2024
2 parents d08750d + 8b5f446 commit f25bb63
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 29 deletions.
4 changes: 2 additions & 2 deletions build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
.hash = "1220c0cf921a5311489bdd6eaf2f2b82bc9245ba39c2da346039aa311e28db633828",
},
.httpz = .{
.url = "https://github.com/karlseguin/http.zig/archive/c8b04e3.tar.gz",
.hash = "1220f998896588d034c3027f2dae37b751b55cd0f12a6abaafc800b3f6954e93f97b",
.url = "https://github.com/karlseguin/http.zig/archive/c224ebb.tar.gz",
.hash = "12206297df84406cd4eed306acef30eb2a1a6a18b6771ebb4920391a3a7299b2e6a7",
},
.zigcli = .{
.url = "https://github.com/jiacai2050/zigcli/archive/54d095c.tar.gz",
Expand Down
2 changes: 1 addition & 1 deletion src/blockchain/blockchain.zig
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const AddressKeySet = common.AddressKeySet;
const LogsBloom = types.LogsBloom;
const Block = types.Block;
const Tx = types.Tx;
const BlockHeader = types.BlockHeader;
pub const BlockHeader = types.BlockHeader;
const Environment = blockchain_types.Environment;
const Message = blockchain_types.Message;
const StateDB = @import("../state/state.zig").StateDB;
Expand Down
3 changes: 2 additions & 1 deletion src/config/config.zig
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ pub const ChainId = enum(u64) {
SpecTest = 0,
Mainnet = 1,
Goerli = 5,
Testing = 1337,
Holesky = 17000,
Kaustinen = 69420,
Sepolia = 11155111,
};

pub const ChainConfig = struct {
ChainName: []const u8,
chainId: u64 = @intFromEnum(ChainId.Mainnet),
chainId: ChainId = ChainId.Mainnet,
homesteadBlock: ?u64 = null,
daoForkBlock: ?u64 = null,
eip150Block: ?u64 = null,
Expand Down
39 changes: 35 additions & 4 deletions src/engine_api/engine_api.zig
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,46 @@ pub const EngineAPIRequest = struct {
test "deserialize sample engine_newPayloadV2" {
const json = std.json;
const expect = std.testing.expect;
const lib = @import("./../lib.zig");
const StateDB = lib.state.StateDB;
const Blockchain = lib.blockchain.Blockchain;
const AccountState = lib.state.AccountState;
const BlockHeader = lib.blockchain.BlockHeader;
const Hash32 = lib.types.Hash32;
var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
defer arena.deinit();

const fileContent = @embedFile("./test_req.json");

const payload = try json.parseFromSlice(EngineAPIRequest, std.testing.allocator, fileContent, .{ .ignore_unknown_fields = true });
const payload = try json.parseFromSlice(EngineAPIRequest, arena.allocator(), fileContent, .{ .ignore_unknown_fields = true });
defer payload.deinit();

var statedb = try StateDB.init(arena.allocator(), &[0]AccountState{});
defer statedb.deinit();
const parent_header = BlockHeader{
.parent_hash = [_]u8{0} ** 32,
.uncle_hash = types.empty_uncle_hash,
.fee_recipient = [_]u8{0} ** 20,
.state_root = [_]u8{0} ** 32,
.transactions_root = [_]u8{0} ** 32,
.receipts_root = [_]u8{0} ** 32,
.logs_bloom = [_]u8{0} ** 256,
.difficulty = 0,
.block_number = 0,
.gas_limit = 0x1c9c380,
.gas_used = 0,
.timestamp = 0,
.extra_data = &[_]u8{},
.prev_randao = [_]u8{0} ** 32,
.nonce = [_]u8{0} ** 8,
.base_fee_per_gas = 7,
.withdrawals_root = [_]u8{0} ** 32,
};
var blockchain = try Blockchain.init(arena.allocator(), .Testing, &statedb, parent_header, [_]Hash32{[_]u8{0} ** 32} ** 256);

try expect(std.mem.eql(u8, payload.value.method, "engine_newPayloadV2"));
const execution_payload_json = payload.value.params[0];
var ep = try execution_payload_json.to_execution_payload(std.testing.allocator);
defer ep.deinit(std.testing.allocator);
try execution_payload.newPayloadV2Handler(&ep);
var ep = try execution_payload_json.to_execution_payload(arena.allocator());
defer ep.deinit(arena.allocator());
try execution_payload.newPayloadV2Handler(&blockchain, &ep);
}
36 changes: 23 additions & 13 deletions src/engine_api/execution_payload.zig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const std = @import("std");
const types = @import("../types/types.zig");
const lib = @import("../lib.zig");
const blockchain = lib.blockchain;
const Blockchain = lib.blockchain.Blockchain;
const state = lib.state;
const Allocator = std.mem.Allocator;
const BlockHeader = types.BlockHeader;
Expand Down Expand Up @@ -31,7 +31,21 @@ pub const ExecutionPayload = struct {

allocator: Allocator,

pub fn toBlock(self: *const ExecutionPayload) types.Block {
pub fn toBlock(self: *const ExecutionPayload) !types.Block {
var withdrawals = std.ArrayList(lib.mpt.KeyVal).init(self.allocator);
defer withdrawals.deinit();
for (self.withdrawals, 0..) |w, index| {
var key = [_]u8{0} ** 32;
std.mem.writeInt(usize, key[24..], index, .big);
try withdrawals.append(try lib.mpt.KeyVal.init(self.allocator, &key, try w.encode(self.allocator)));
}
var transactions = std.ArrayList(lib.mpt.KeyVal).init(self.allocator);
defer transactions.deinit();
for (self.transactions, 0..) |tx, index| {
var key = [_]u8{0} ** 32;
std.mem.writeInt(usize, key[24..], index, .big);
try transactions.append(try lib.mpt.KeyVal.init(self.allocator, &key, try tx.encode(self.allocator)));
}
return types.Block{
.header = types.BlockHeader{
.parent_hash = self.parentHash,
Expand All @@ -48,9 +62,9 @@ pub const ExecutionPayload = struct {
.timestamp = @intCast(self.timestamp),
.extra_data = self.extraData,
.base_fee_per_gas = self.baseFeePerGas,
.transactions_root = [_]u8{0} ** 32,
.transactions_root = try lib.mpt.mptize(self.allocator, transactions.items[0..]),
.nonce = [_]u8{0} ** 8,
.withdrawals_root = [_]u8{0} ** 32,
.withdrawals_root = try lib.mpt.mptize(self.allocator, withdrawals.items[0..]),
},
.transactions = self.transactions,
.withdrawals = self.withdrawals,
Expand All @@ -65,15 +79,11 @@ pub const ExecutionPayload = struct {
}
};

pub fn newPayloadV2Handler(params: *ExecutionPayload) !void {
const block = params.toBlock();
_ = block;
pub fn newPayloadV2Handler(blockchain: *Blockchain, params: *ExecutionPayload) !void {
const block = try params.toBlock();
// TODO reconstruct the proof from the (currently undefined) execution witness
// and verify it. Then execute the block and return the result.
// bc.run_block(block, params.transactions);

// But so far, just print the content of the payload
// std.log.info("newPayloadV2Handler: {any}", .{params});
// and verify it.

// std.debug.print("block number={}\n", .{block.header.block_number});
// Then execute the block and return the result.
return blockchain.runBlock(block);
}
4 changes: 2 additions & 2 deletions src/engine_api/test_req.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
"method": "engine_newPayloadV2",
"params": [
{
"parentHash": "0x522930864dc2f6569f4d4b92f40001fe6752727ff53db5cb5c5ffd51d3cc53e4",
"parentHash": "0xf725aca23ac424e82c9e75b78915bc533a4d4be2ced7c57f0f5885c5ac8e03d5",
"feeRecipient": "0xf97e180c050e5ab072211ad2c213eb5aee4df134",
"stateRoot": "0x27bb13dc19c41288dd29236b27baac49338c466b8c0eb44fb4c0c0083dfb214a",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"prevRandao": "0x8ad449de1358704350f28598677be5c4cd609b42d31653b967f615b47ad1e63e",
"blockNumber": "0x112b8",
"blockNumber": "0x1",
"gasLimit": "0x1c9c380",
"gasUsed": "0x0",
"timestamp": "0x65361030",
Expand Down
34 changes: 30 additions & 4 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,24 @@ const Address = types.Address;
const VM = @import("blockchain/vm.zig").VM;
const StateDB = @import("state/state.zig").StateDB;
const Block = types.Block;
const BlockHeader = types.BlockHeader;
const Tx = types.Tx;
const TxSigner = @import("signer/signer.zig").TxSigner;
const Hash32 = types.Hash32;
const httpz = @import("httpz");
const engine_api = @import("engine_api/engine_api.zig");
const json = std.json;
const simargs = @import("simargs");
const version = @import("version.zig").version;
const Blockchain = lib.blockchain.Blockchain;

fn engineAPIHandler(req: *httpz.Request, res: *httpz.Response) !void {
fn engineAPIHandler(blockchain: *Blockchain, req: *httpz.Request, res: *httpz.Response) !void {
if (try req.json(engine_api.EngineAPIRequest)) |payload| {
if (std.mem.eql(u8, payload.method, "engine_newPayloadV2")) {
const execution_payload_json = payload.params[0];
var execution_payload = try execution_payload_json.to_execution_payload(res.arena);
defer execution_payload.deinit(res.arena);
try engine_api.execution_payload.newPayloadV2Handler(&execution_payload);
try engine_api.execution_payload.newPayloadV2Handler(blockchain, &execution_payload);
} else {
res.status = 500;
}
Expand Down Expand Up @@ -74,9 +77,32 @@ pub fn main() !void {
std.log.info("version: {s}", .{version});
try config.dump(allocator);

var engine_api_server = try httpz.Server().init(allocator, .{
var statedb = try StateDB.init(allocator, &[0]AccountState{});
defer statedb.deinit();
const parent_header = BlockHeader{
.parent_hash = [_]u8{0} ** 32,
.uncle_hash = types.empty_uncle_hash,
.fee_recipient = [_]u8{0} ** 20,
.state_root = [_]u8{0} ** 32,
.transactions_root = [_]u8{0} ** 32,
.receipts_root = [_]u8{0} ** 32,
.logs_bloom = [_]u8{0} ** 256,
.difficulty = 0,
.block_number = 0,
.gas_limit = 0,
.gas_used = 0,
.timestamp = 0,
.extra_data = &[_]u8{},
.prev_randao = [_]u8{0} ** 32,
.nonce = [_]u8{0} ** 8,
.base_fee_per_gas = 0,
.withdrawals_root = [_]u8{0} ** 32,
};
var blockchain = try Blockchain.init(allocator, config.chainId, &statedb, parent_header, [_]Hash32{[_]u8{0} ** 32} ** 256);

var engine_api_server = try httpz.ServerApp(*Blockchain).init(allocator, .{
.port = port,
});
}, &blockchain);
var router = engine_api_server.router();
router.post("/", engineAPIHandler);
std.log.info("Listening on {}", .{port});
Expand Down
2 changes: 1 addition & 1 deletion src/mpt/mpt.zig
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const common = @import("../common/common.zig");
const Allocator = std.mem.Allocator;
const Hash32 = types.Hash32;

const empty_mpt_root = common.comptimeHexToBytes("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421");
pub const empty_mpt_root = common.comptimeHexToBytes("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421");

// KeyVal represents an element in the Merkle Patricia Trie.
pub const KeyVal = struct {
Expand Down
2 changes: 1 addition & 1 deletion src/types/transaction.zig
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub const Tx = union(TxTypes) {
}

// encode encodes a transaction to RLP. The caller is responsible for freeing the returned bytes.
pub fn encode(self: *Tx, arena: Allocator) ![]const u8 {
pub fn encode(self: *const Tx, arena: Allocator) ![]const u8 {
var list = ArrayList(u8).init(arena);
defer list.deinit();
switch (self.*) {
Expand Down

0 comments on commit f25bb63

Please sign in to comment.