Update text

This commit is contained in:
iteye 2026-07-06 16:07:01 +08:00
parent 971409030b
commit 9db15e21f4
3 changed files with 146 additions and 74 deletions

View file

@ -1,86 +1,89 @@
// Copyright 2026-2027, QuarkChain. // Copyright 2026-2027, QuarkChain.
// Package wire: serializable message structs for every cluster RPC opcode. // Package wire defines the Go-side wire-compatible message structs for all
// Cluster RPC and P2P opcodes.
// //
// Each struct mirrors a pyquarkchain Serializable from // These structs are a strict binary-compatible representation of the Python
// quarkchain/cluster/rpc.py (ClusterOp messages) or // QuarkChain Serializable definitions in:
// quarkchain/cluster/p2p_commands.py (CommandOp messages). // - quarkchain/cluster/rpc.py
// - quarkchain/cluster/p2p_commands.py
// //
// Field layout MUST stay byte-compatible with the Python wire format. Every // -----------------------------------------------------------------------------
// field name matches the Python FIELDS order and the wire encoding is enforced // Protocol Contract
// by qkc/serialize/ struct tags (see typecache.go): // -----------------------------------------------------------------------------
// //
// bytesizeofslicelen:"4" 4-byte big-endian length prefix for slices // This package defines a BYTE-LEVEL WIRE CONTRACT.
// (Python PrependedSizeBytesSerializer(4) and
// PrependedSizeListSerializer(4, T))
// ser:"nil" nullable pointer — 1-byte presence marker
// (Python Optional(T))
// ser:"-" ignored field (not serialised)
// //
// Primitive type mapping (Python → Go): // The following invariants MUST always hold:
// - Struct field order MUST match Python FIELDS order exactly
// - Encoding MUST be byte-identical to Python Serializable output
// - Optional fields MUST preserve presence markers
// - Slice encoding MUST use 4-byte big-endian length prefixes
// //
// uint8 → uint8 1 byte // Any deviation from these rules is considered a protocol-breaking change.
// uint16 → uint16 2 bytes big-endian
// uint32 → uint32 4 bytes big-endian
// uint64 → uint64 8 bytes big-endian
// uint128 → [16]byte 16 bytes big-endian
// uint256 → *big.Int 1-byte length prefix + big-endian bytes
// biguint → *big.Int same as uint256
// hash256 → [32]byte 32 bytes
// Branch → uint32 4 bytes
// Address → [20]byte 20 bytes
// signature65 → [65]byte 65 bytes
// boolean → bool 1 byte (0x00 / 0x01)
// //
// ============================================================================= // -----------------------------------------------------------------------------
// Placeholder: RawBytes // Serialization Tags (qkc/serialize)
// ============================================================================= // -----------------------------------------------------------------------------
// //
// pyquarkchain defines many complex Serializable types (RootBlock, // The wire format is enforced via struct tags:
// MinorBlockHeader, TypedTransaction, CrossShardTransactionList,
// TokenBalanceMap, TransactionReceipt, Log, MinorBlock, RootBlockHeader)
// that are NOT yet ported to Go. They all have a Python FIELDS list, so
// the Go wire length for any given field is well-defined — it just depends
// on the future Go type's encoding.
// //
// To keep this PR self-contained and the wire layout pinned down NOW, each // bytesizeofslicelen:"4"
// not-yet-ported type is referenced as *RawBytes. RawBytes is a transparent // - 4-byte big-endian length prefix for slices
// Serializable that round-trips arbitrary bytes, matching the wire length // - Compatible with Python PrependedSizeBytesSerializer(4)
// of the future Go struct once the fields are filled in. When the real Go
// type lands, only the field type needs to change — the wire encoding stays
// byte-identical.
// //
// SAFETY: RawBytes.Deserialize consumes ALL remaining bytes in the buffer. // ser:"nil"
// It is only safe when the *RawBytes field is the LAST field of its parent // - Nullable pointer field with 1-byte presence marker
// struct. Fields that are not last are annotated with a WARNING and cannot be // - Compatible with Python Optional(T)
// correctly deserialized until the real Go type is ported.
// //
// ============================================================================= // ser:"-"
// Layout // - Field is excluded from serialization
// =============================================================================
// //
// Grouped to match the wire opcode sections in opcode.go: // -----------------------------------------------------------------------------
// Primitive Type Mapping (Python → Go)
// -----------------------------------------------------------------------------
// //
// §1 Cluster initialisation (PING, CONNECT_TO_SLAVES, MINE, GEN_TX) // uint8 → uint8 (1 byte)
// §2 Virtual connection mgmt (CREATE/DESTROY_CLUSTER_PEER) // uint16 → uint16 (2 bytes BE)
// §3 Block updates (ADD_ROOT_BLOCK, ADD_MINOR_BLOCK, // uint32 → uint32 (4 bytes BE)
// SYNC_MINOR_BLOCK_LIST, CHECK_MINOR_BLOCK, // uint64 → uint64 (8 bytes BE)
// GET_UNCONFIRMED_HEADERS, ADD_MINOR_BLOCK_HEADER) // uint128 → [16]byte (16 bytes BE)
// §4 Block queries (GET_ECO_INFO_LIST, GET_NEXT_BLOCK_TO_MINE, // uint256 → *big.Int (1-byte length + big-endian bytes)
// GET_MINOR_BLOCK, GET_TRANSACTION, EXECUTE_TX, // biguint → *big.Int (same as uint256)
// GET_TX_RECEIPT, GET_TX_LIST_BY_ADDRESS, // hash256 → [32]byte (32 bytes)
// GET_ALL_TX, GET_LOG, ESTIMATE_GAS, GET_STORAGE, // Branch → uint32 (4 bytes)
// GET_CODE, GAS_PRICE, GET_WORK, SUBMIT_WORK) // Address → [20]byte (20 bytes)
// §5 Account / staking (GET_ACCOUNT_DATA, GET_ROOT_CHAIN_STAKES, // signature65 → [65]byte (65 bytes)
// GET_TOTAL_BALANCE) // boolean → bool (0x00 / 0x01)
// §6 Cross-shard (Slave↔Slave) (ADD_XSHARD_TX_LIST, BATCH_ADD_XSHARD_TX_LIST)
// §7 P2P commands (HELLO, NEW_MINOR_BLOCK_HEADER_LIST,
// NEW_TRANSACTION_LIST, NEW_BLOCK_MINOR,
// PING_PONG, NEW_ROOT_BLOCK)
// §8 P2P queries (GET_ROOT_BLOCK_*, GET_MINOR_BLOCK_*)
// //
// Every struct is defined in one place to keep the opcode-to-struct mapping // -----------------------------------------------------------------------------
// in protocol.go complete and avoid scattering definitions across PRs. // Layout Organization
// -----------------------------------------------------------------------------
//
// Structs are grouped by opcode domain (see opcode.go):
//
// §1 Cluster initialization
// §2 Virtual connection management
// §3 Block updates
// §4 Block queries
// §5 Account / staking
// §6 Cross-shard communication
// §7 P2P commands
// §8 P2P queries
//
// This grouping is purely organizational and does NOT affect wire format.
//
// -----------------------------------------------------------------------------
// Design Principle
// -----------------------------------------------------------------------------
//
// This package is the SINGLE SOURCE OF TRUTH for wire-level compatibility
// between Go and Python implementations.
//
// It is NOT allowed to:
// - introduce semantic deviations from Python FIELDS
// - change serialization rules locally per struct
// - diverge from opcode mapping defined in protocol.go
package wire package wire
import ( import (

View file

@ -151,7 +151,7 @@ func TestPrependedSizeHashList4_Deserialize_InvalidLength(t *testing.T) {
// //
// Only structs with *RawBytes as the LAST field (or no RawBytes at all) can // Only structs with *RawBytes as the LAST field (or no RawBytes at all) can
// safely round-trip. Structs with non-last RawBytes are only verified via the // safely round-trip. Structs with non-last RawBytes are only verified via the
// factory completeness test (§7) — they serialize correctly but cannot be // factory completeness test (§6) — they serialize correctly but cannot be
// deserialized until the real Go type replaces RawBytes. // deserialized until the real Go type replaces RawBytes.
func TestMessageRoundTrip(t *testing.T) { func TestMessageRoundTrip(t *testing.T) {

View file

@ -1,14 +1,83 @@
// Copyright 2026-2027, QuarkChain. // Copyright 2026-2027, QuarkChain.
// ============================================================================= // =============================================================================
// TEMPORARY PLACEHOLDER FILE — DELETE after real types merge // WIRE MIGRATION SHIM (NOT PART OF PROTOCOL SPEC)
// ============================================================================= // =============================================================================
// //
// RawBytes is a placeholder used during pyquarkchain → Go migration. // This file exists solely to support incremental migration from Python
// Delete this file once real types (RootBlock, MinorBlockHeader, etc.) are ported. // QuarkChain Serializable types to Go native structs.
// Replace `*RawBytes` fields in messages.go with real typed pointers.
// //
// DO NOT REVIEW AS PRODUCTION CODE. // It is an IMPLEMENTATION-ONLY COMPATIBILITY LAYER.
//
// -----------------------------------------------------------------------------
// IMPORTANT DISTINCTION
// -----------------------------------------------------------------------------
//
// This file is NOT part of the wire protocol specification.
//
// The actual protocol contract is defined in package wire message structs.
// RawBytes is only a temporary bridge for unported complex types.
//
// -----------------------------------------------------------------------------
// Migration Strategy
// -----------------------------------------------------------------------------
//
// Many Python-side Serializable types (e.g. RootBlock, MinorBlockHeader,
// TypedTransaction, CrossShardTransactionList, TokenBalanceMap, etc.)
// have not yet been ported to Go.
//
// During migration, these types are represented as:
//
// *RawBytes
//
// This allows:
// - wire format to remain stable
// - incremental type replacement
// - independent migration of each message type
//
// -----------------------------------------------------------------------------
// RawBytes Semantics
// -----------------------------------------------------------------------------
//
// RawBytes is a terminal wire sink type.
//
// It represents an opaque byte segment whose internal structure is defined
// by the Python FIELDS schema but is not yet implemented in Go.
//
// Wire behavior:
// - Serialize: writes raw bytes unchanged
// - Deserialize: consumes ALL remaining bytes in buffer
//
// -----------------------------------------------------------------------------
// SAFETY CONSTRAINTS
// -----------------------------------------------------------------------------
//
// RawBytes MUST obey the following rules:
//
// 1. MUST only appear as the LAST field in a struct
// 2. MUST NOT be partially decoded or inspected
// 3. MUST NOT be used in stable protocol definitions
// 4. MUST be removed once real Go types are introduced
//
// Any violation of these rules results in undefined wire behavior.
//
// -----------------------------------------------------------------------------
// Lifecycle
// -----------------------------------------------------------------------------
//
// This file is TEMPORARY and will be removed after full migration.
//
// Migration completion steps:
// 1. Replace all *RawBytes fields with concrete types
// 2. Verify wire compatibility via round-trip tests
// 3. Delete this file entirely
//
// -----------------------------------------------------------------------------
// WARNING
// -----------------------------------------------------------------------------
//
// This file is NOT production protocol logic.
// It is a migration tool and must be treated as unstable internal code.
package wire package wire
import ( import (