mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-25 09:19:28 +00:00
beacon/engine, rpc: use json.Marshaler for direct result encoding
This commit is contained in:
parent
ca18d7e655
commit
bdaa6d6f94
4 changed files with 12 additions and 49 deletions
|
|
@ -12,31 +12,6 @@ import (
|
|||
|
||||
var _ = (*executionPayloadEnvelopeMarshaling)(nil)
|
||||
|
||||
// MarshalJSON marshals as JSON.
|
||||
func (e ExecutionPayloadEnvelope) MarshalJSON() ([]byte, error) {
|
||||
type ExecutionPayloadEnvelope struct {
|
||||
ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"`
|
||||
BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"`
|
||||
BlobsBundle *BlobsBundle `json:"blobsBundle"`
|
||||
Requests []hexutil.Bytes `json:"executionRequests"`
|
||||
Override bool `json:"shouldOverrideBuilder"`
|
||||
Witness *hexutil.Bytes `json:"witness,omitempty"`
|
||||
}
|
||||
var enc ExecutionPayloadEnvelope
|
||||
enc.ExecutionPayload = e.ExecutionPayload
|
||||
enc.BlockValue = (*hexutil.Big)(e.BlockValue)
|
||||
enc.BlobsBundle = e.BlobsBundle
|
||||
if e.Requests != nil {
|
||||
enc.Requests = make([]hexutil.Bytes, len(e.Requests))
|
||||
for k, v := range e.Requests {
|
||||
enc.Requests[k] = v
|
||||
}
|
||||
}
|
||||
enc.Override = e.Override
|
||||
enc.Witness = e.Witness
|
||||
return json.Marshal(&enc)
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals from JSON.
|
||||
func (e *ExecutionPayloadEnvelope) UnmarshalJSON(input []byte) error {
|
||||
type ExecutionPayloadEnvelope struct {
|
||||
|
|
|
|||
|
|
@ -68,9 +68,6 @@ func marshalHexBytesArray(buf []byte, items []hexutil.Bytes) []byte {
|
|||
}
|
||||
|
||||
// writeHexBytes writes a hex-encoded byte slice as a JSON string ("0x...") to buf.
|
||||
// NOTE: This function avoids allocations by pre-allocating the buffer space needed;
|
||||
// otherwise, we would use hexutil.Encode() and append the result to the buffer.
|
||||
// hexutil.Encode() uses 64% more memory than writing to buffer directly.
|
||||
func writeHexBytes(buf []byte, data []byte) []byte {
|
||||
buf = append(buf, '"', '0', 'x')
|
||||
buf = slices.Grow(buf, len(data)*2+1)
|
||||
|
|
@ -81,10 +78,8 @@ func writeHexBytes(buf []byte, data []byte) []byte {
|
|||
return buf
|
||||
}
|
||||
|
||||
// PremarshaledJSON implements rpc.JSONPremarshaled. It returns pre-serialized
|
||||
// JSON by delegating small fields to their existing MarshalJSON methods and
|
||||
// hand-rolling only the BlobsBundle.
|
||||
func (e ExecutionPayloadEnvelope) PremarshaledJSON() ([]byte, error) {
|
||||
// MarshalJSON implements json.Marshaler.
|
||||
func (e ExecutionPayloadEnvelope) MarshalJSON() ([]byte, error) {
|
||||
// Marshal the execution payload using its gencodec MarshalJSON.
|
||||
payload, err := e.ExecutionPayload.MarshalJSON()
|
||||
if err != nil {
|
||||
|
|
@ -47,7 +47,7 @@ type encodingType int
|
|||
const (
|
||||
encNone encodingType = iota
|
||||
encJSON
|
||||
encJSONPremarshaled
|
||||
encJSONCustom
|
||||
encRLP
|
||||
)
|
||||
|
||||
|
|
@ -57,8 +57,8 @@ func (e encodingType) String() string {
|
|||
return "none"
|
||||
case encJSON:
|
||||
return "json"
|
||||
case encJSONPremarshaled:
|
||||
return "json_premarshaled"
|
||||
case encJSONCustom:
|
||||
return "json_custom"
|
||||
case encRLP:
|
||||
return "rlp"
|
||||
default:
|
||||
|
|
@ -66,7 +66,7 @@ func (e encodingType) String() string {
|
|||
}
|
||||
}
|
||||
|
||||
var encodingTypes = []encodingType{encNone, encJSON, encJSONPremarshaled, encRLP}
|
||||
var encodingTypes = []encodingType{encNone, encJSON, encJSONCustom, encRLP}
|
||||
|
||||
// benchEncode encodes the value using the specified encoding type.
|
||||
// It fails the benchmark if encoding fails.
|
||||
|
|
@ -78,14 +78,14 @@ func benchEncode(b *testing.B, enc encodingType, v any) {
|
|||
if err != nil {
|
||||
b.Fatalf("JSON marshal failed: %v", err)
|
||||
}
|
||||
case encJSONPremarshaled:
|
||||
if pm, ok := v.(rpc.JSONPremarshaled); ok {
|
||||
_, err = pm.PremarshaledJSON()
|
||||
case encJSONCustom:
|
||||
if m, ok := v.(json.Marshaler); ok {
|
||||
_, err = m.MarshalJSON()
|
||||
} else {
|
||||
_, err = json.Marshal(v)
|
||||
}
|
||||
if err != nil {
|
||||
b.Fatalf("JSON premarshaled marshal failed: %v", err)
|
||||
b.Fatalf("JSON MarshalJSON failed: %v", err)
|
||||
}
|
||||
case encRLP:
|
||||
_, err = rlp.EncodeToBytes(v)
|
||||
|
|
|
|||
11
rpc/json.go
11
rpc/json.go
|
|
@ -113,20 +113,13 @@ func (msg *jsonrpcMessage) errorResponse(err error) *jsonrpcMessage {
|
|||
return resp
|
||||
}
|
||||
|
||||
// JSONPremarshaled may be implemented by RPC return types that provide
|
||||
// pre-serialized JSON. This bypasses json.Marshal and its re-validation
|
||||
// pass. Implementors must ensure the returned bytes are valid JSON.
|
||||
type JSONPremarshaled interface {
|
||||
PremarshaledJSON() ([]byte, error)
|
||||
}
|
||||
|
||||
func (msg *jsonrpcMessage) response(result interface{}) *jsonrpcMessage {
|
||||
var (
|
||||
enc []byte
|
||||
err error
|
||||
)
|
||||
if pm, ok := result.(JSONPremarshaled); ok {
|
||||
enc, err = pm.PremarshaledJSON()
|
||||
if m, ok := result.(json.Marshaler); ok {
|
||||
enc, err = m.MarshalJSON()
|
||||
} else {
|
||||
enc, err = json.Marshal(result)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue