-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
implement deserialization of newPayloadV2 request
- Loading branch information
Showing
8 changed files
with
265 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,11 @@ | ||
.{ | ||
.name = "zig-rlp", | ||
.version = "0.0.1-beta-0", | ||
.dependencies = .{ | ||
.@"zig-rlp" = .{ | ||
.url = "https://github.com/gballet/zig-rlp/archive/refs/tags/v0.0.1-beta-0.tar.gz", | ||
.hash = "122000e0811d6cb4758f6122b1de2d384efa32b9b2714caec2236f6b34b0529d699c", | ||
}, | ||
}, | ||
.dependencies = .{ .@"zig-rlp" = .{ | ||
.url = "https://github.com/gballet/zig-rlp/archive/refs/tags/v0.0.1-beta-0.tar.gz", | ||
.hash = "122000e0811d6cb4758f6122b1de2d384efa32b9b2714caec2236f6b34b0529d699c", | ||
}, .zap = .{ | ||
.url = "https://github.com/zigzap/zap/archive/refs/tags/v0.1.14-pre.tar.gz", | ||
.hash = "122067d12bc7abb93f7ce623f61b94cadfdb180cef12da6559d092e6b374202acda3", | ||
} }, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
const std = @import("std"); | ||
const fmt = std.fmt; | ||
const Allocator = std.mem.Allocator; | ||
pub const execution_payload = @import("./execution_payload.zig"); | ||
const ExecutionPayload = execution_payload.ExecutionPayload; | ||
|
||
fn prefixedhex2hash(dst: []u8, src: []const u8) !void { | ||
if (src.len < 2 or src.len % 2 != 0) { | ||
return error.InvalidInput; | ||
} | ||
var skip0x: usize = if (src[1] == 'X' or src[1] == 'x') 2 else 0; | ||
if (src[skip0x..].len != 2 * dst.len) { | ||
return error.InvalidOutputLength; | ||
} | ||
_ = try fmt.hexToBytes(dst[0..], src[skip0x..]); | ||
} | ||
|
||
fn prefixedhex2byteslice(allocator: Allocator, src: []const u8) ![]u8 { | ||
// TODO catch the 0x0 corner case | ||
if (src.len < 2 or src.len % 2 != 0) { | ||
return error.InvalidInput; | ||
} | ||
var skip0x: usize = if (src[1] == 'X' or src[1] == 'x') 2 else 0; | ||
var dst: []u8 = try allocator.alloc(u8, src[skip0x..].len / 2); | ||
|
||
_ = try fmt.hexToBytes(dst[0..], src[skip0x..]); | ||
|
||
return dst; | ||
} | ||
|
||
fn prefixedhex2u64(src: []const u8) !u64 { | ||
// execution engine integers can be odd-length :facepalm: | ||
if (src.len < 3) { | ||
return error.InvalidInput; | ||
} | ||
|
||
var skip0x: usize = if (src[1] == 'X' or src[1] == 'x') 2 else 0; | ||
|
||
return std.fmt.parseInt(u64, src[skip0x..], 16); | ||
} | ||
|
||
// This is an intermediate structure used to deserialize the hex strings | ||
// from the JSON request. I have seen some zig libraries that can do this | ||
// out of the box, but it seems that approach hasn't been merged into the | ||
// std yet. | ||
const ExecutionPayloadJSON = struct { | ||
parentHash: []const u8, | ||
feeRecipient: []const u8, | ||
stateRoot: []const u8, | ||
receiptsRoot: []const u8, | ||
logsBloom: []const u8, | ||
prevRandao: []const u8, | ||
blockNumber: []const u8, | ||
gasLimit: []const u8, | ||
gasUsed: []const u8, | ||
timestamp: []const u8, | ||
extraData: []const u8, | ||
baseFeePerGas: []const u8, | ||
blockHash: []const u8, | ||
transactions: [][]const u8, | ||
|
||
pub fn to_execution_payload(self: *const ExecutionPayloadJSON, allocator: Allocator) !ExecutionPayload { | ||
var parentHash: [32]u8 = undefined; | ||
var feeRecipient: [20]u8 = undefined; | ||
var stateRoot: [32]u8 = undefined; | ||
var receiptsRoot: [32]u8 = undefined; | ||
var logsBloom: [256]u8 = undefined; | ||
var prevRandao: [32]u8 = undefined; | ||
var blockHash: [32]u8 = undefined; | ||
|
||
var transactions: [][]const u8 = &[_][]const u8{}; | ||
if (self.transactions.len > 0) { | ||
transactions = try allocator.alloc([]const u8, self.transactions.len); | ||
} | ||
|
||
_ = try prefixedhex2hash(parentHash[0..], self.parentHash); | ||
_ = try prefixedhex2hash(feeRecipient[0..], self.feeRecipient); | ||
_ = try prefixedhex2hash(stateRoot[0..], self.stateRoot); | ||
_ = try prefixedhex2hash(receiptsRoot[0..], self.receiptsRoot); | ||
_ = try prefixedhex2hash(logsBloom[0..], self.logsBloom); | ||
_ = try prefixedhex2hash(prevRandao[0..], self.prevRandao); | ||
_ = try prefixedhex2hash(blockHash[0..], self.blockHash); | ||
|
||
return ExecutionPayload{ | ||
.parentHash = parentHash, | ||
.feeRecipient = feeRecipient, | ||
.stateRoot = stateRoot, | ||
.receiptsRoot = receiptsRoot, | ||
.prevRandao = prevRandao, | ||
.extraData = try prefixedhex2byteslice(allocator, self.extraData), | ||
.blockHash = blockHash, | ||
.logsBloom = logsBloom, | ||
.blockNumber = try prefixedhex2u64(self.blockNumber), | ||
.gasLimit = try prefixedhex2u64(self.gasLimit), | ||
.gasUsed = try prefixedhex2u64(self.gasUsed), | ||
.timestamp = try prefixedhex2u64(self.timestamp), | ||
.baseFeePerGas = try prefixedhex2u64(self.baseFeePerGas), | ||
.transactions = transactions, | ||
.withdrawals = null, | ||
.blobGasUsed = null, | ||
.excessBlobGas = null, | ||
}; | ||
} | ||
}; | ||
|
||
pub const EngineAPIRequest = struct { | ||
jsonrpc: []const u8, | ||
id: u64, | ||
method: []const u8, | ||
params: []const ExecutionPayloadJSON, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
const std = @import("std"); | ||
const types = @import("../types/types.zig"); | ||
|
||
pub const ExecutionPayload = struct { | ||
parentHash: types.Hash32, | ||
feeRecipient: types.Address, | ||
stateRoot: types.Hash32, | ||
receiptsRoot: types.Hash32, | ||
logsBloom: [256]u8, | ||
prevRandao: types.Hash32, | ||
blockNumber: u64, | ||
gasLimit: u64, | ||
gasUsed: u64, | ||
timestamp: u64, | ||
extraData: []const u8, | ||
baseFeePerGas: u256, | ||
blockHash: types.Hash32, | ||
transactions: [][]const u8, | ||
|
||
withdrawals: ?[]types.Withdrawal, | ||
blobGasUsed: ?u64, | ||
excessBlobGas: ?u64, | ||
// executionWitness : ?types.ExecutionWitness, | ||
|
||
pub fn to_block(self: *const ExecutionPayload) types.Block { | ||
return types.Block{ | ||
.header = types.BlockHeader{ | ||
.parent_hash = self.parentHash, | ||
.uncle_hash = types.empty_uncle_hash, | ||
.fee_recipient = self.feeRecipient, | ||
.state_root = self.stateRoot, | ||
.receipts_root = self.receiptsRoot, | ||
.logs_bloom = self.logsBloom, | ||
.prev_randao = self.prevRandao, | ||
.block_number = @intCast(self.blockNumber), | ||
.gas_limit = @intCast(self.gasLimit), | ||
.gas_used = self.gasUsed, | ||
.timestamp = @intCast(self.timestamp), | ||
.extra_data = self.extraData, | ||
.base_fee_per_gas = self.baseFeePerGas, | ||
.transactions_root = [_]u8{0} ** 32, | ||
.mix_hash = 0, | ||
.nonce = [_]u8{0} ** 8, | ||
.blob_gas_used = null, | ||
.withdrawals_root = null, | ||
.excess_blob_gas = null, | ||
}, | ||
// .blockHash = self.blockHash, | ||
// .transactions = self.transactions, | ||
// .withdrawals = self.withdrawals, | ||
}; | ||
} | ||
}; | ||
|
||
pub fn newPayloadV2Handler(params: *const ExecutionPayload) !void { | ||
// TODO reconstruct the proof from the (currently undefined) execution witness | ||
// and verify it. Then execute the block and return the result. | ||
// vm.run_block(params.to_block(), params.transactions); | ||
|
||
// But so far, just print the content of the payload | ||
std.log.info("newPayloadV2Handler: {any}", .{params}); | ||
|
||
_ = params.to_block(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
const std = @import("std"); | ||
const types = @import("types.zig"); | ||
|
||
pub const Withdrawal = struct { | ||
index: u64, | ||
validator: u64, | ||
address: types.Address, | ||
amount: u64, | ||
}; |