tx binary with block time

This commit is contained in:
thloyi
2026-06-05 10:35:49 +08:00
parent 9f17ffce61
commit 44eecac087
2 changed files with 175 additions and 15 deletions

View File

@@ -17,7 +17,8 @@ import (
)
const (
txBinarySchemaVersionCurrent uint16 = 3
txBinarySchemaVersionV3 uint16 = 3
txBinarySchemaVersionCurrent uint16 = 4
txBinaryEnumVersionV1 uint16 = 1
txBinarySOLScale int32 = 9
@@ -27,6 +28,10 @@ const (
var txBinaryMagic = [4]byte{'P', 'T', 'X', 'B'}
var txsBinaryMagic = [4]byte{'P', 'T', 'X', 'S'}
func txBinarySchemaVersionSupported(version uint16) bool {
return version >= txBinarySchemaVersionV3 && version <= txBinarySchemaVersionCurrent
}
type TxBinary struct {
SchemaVersion uint16
EnumVersion uint16
@@ -34,6 +39,7 @@ type TxBinary struct {
Signer uint32
Block uint64
BlockIndex uint64
BlockAt int64
TxHash *[64]byte
CuFee uint64
Swaps []SwapBinary
@@ -204,6 +210,7 @@ func newTxBinaryWithAddressTable(tx *Tx, addressTable []solana.PublicKey, addres
EnumVersion: txBinaryEnumVersionV1,
Block: tx.Block,
BlockIndex: tx.BlockIndex,
BlockAt: tx.BlockAt,
CuLimit: tx.CuLimit,
ComputeUnitsConsumed: tx.ComputeUnitsConsumed,
}
@@ -411,6 +418,8 @@ func MergeTxsBinarySourcesToWriterWithOptions(sources []TxsBinaryReaderSource, w
return fmt.Errorf("source[%d].batch[%d].tx[%d]: %w", sourceIndex, batchIndex, txIndex, err)
}
tx.SchemaVersion = plan.schemaVersion
tx.EnumVersion = plan.enumVersion
bodyBytes, err := txBinaryMarshalTxBody(&tx, plan.enumTable)
if err != nil {
reader.Close()
@@ -432,7 +441,7 @@ func (tx *TxBinary) MarshalBinary() ([]byte, error) {
if tx == nil {
return nil, fmt.Errorf("tx binary is nil")
}
if tx.SchemaVersion != txBinarySchemaVersionCurrent {
if !txBinarySchemaVersionSupported(tx.SchemaVersion) {
return nil, fmt.Errorf("unsupported tx binary schema version: %d", tx.SchemaVersion)
}
@@ -460,7 +469,7 @@ func (txs *TxsBinary) MarshalBinary() ([]byte, error) {
if txs == nil {
return nil, fmt.Errorf("txs binary is nil")
}
if txs.SchemaVersion != txBinarySchemaVersionCurrent {
if !txBinarySchemaVersionSupported(txs.SchemaVersion) {
return nil, fmt.Errorf("unsupported tx binary schema version: %d", txs.SchemaVersion)
}
@@ -478,8 +487,11 @@ func (txs *TxsBinary) MarshalBinary() ([]byte, error) {
}
enc.writeUint32(uint32(len(txs.Txs)))
for i := range txs.Txs {
if err := enc.writeTxBinaryBody(&txs.Txs[i], enumTable); err != nil {
return nil, fmt.Errorf("tx[%d], %s: %w", i, base58.Encode(txs.Txs[i].TxHash[:]), err)
tx := txs.Txs[i]
tx.SchemaVersion = txs.SchemaVersion
tx.EnumVersion = txs.EnumVersion
if err := enc.writeTxBinaryBody(&tx, enumTable); err != nil {
return nil, fmt.Errorf("tx[%d], %s: %w", i, base58.Encode(tx.TxHash[:]), err)
}
}
return enc.bytes(), nil
@@ -520,7 +532,7 @@ func (tx *TxBinary) UnmarshalBinary(data []byte) error {
if err != nil {
return err
}
if tx.SchemaVersion != txBinarySchemaVersionCurrent {
if !txBinarySchemaVersionSupported(tx.SchemaVersion) {
return fmt.Errorf("unsupported tx binary schema version: %d", tx.SchemaVersion)
}
@@ -560,7 +572,7 @@ func (txs *TxsBinary) UnmarshalBinary(data []byte) error {
if err != nil {
return err
}
if txs.SchemaVersion != txBinarySchemaVersionCurrent {
if !txBinarySchemaVersionSupported(txs.SchemaVersion) {
return fmt.Errorf("unsupported tx binary schema version: %d", txs.SchemaVersion)
}
@@ -613,6 +625,7 @@ func (tx *TxBinary) ToTx() (*Tx, error) {
Signer: signer,
Block: tx.Block,
BlockIndex: tx.BlockIndex,
BlockAt: tx.BlockAt,
CuFee: decimal.NewFromUint64(tx.CuFee),
CUPrice: decimal.NewFromUint64(tx.CUPrice).Shift(-txBinaryCUPriceScale),
BeforeSolBalance: txBinaryFloat64ToDecimal(tx.BeforeSolBalance, txBinarySOLScale),
@@ -1166,6 +1179,9 @@ func (enc *txBinaryEncoder) writeTxBinaryBody(tx *TxBinary, enumTable *txBinaryE
enc.writeUint32(tx.Signer)
enc.writeUint64(tx.Block)
enc.writeUint64(tx.BlockIndex)
if tx.SchemaVersion >= txBinarySchemaVersionCurrent {
enc.writeUint64(uint64(tx.BlockAt))
}
enc.writeBool(tx.TxHash != nil)
if tx.TxHash != nil {
enc.writeBytes(tx.TxHash[:])
@@ -1474,7 +1490,7 @@ func (dec *txBinaryStreamDecoder) readTxsBinaryHeader() (*txsBinaryHeader, error
if err != nil {
return nil, err
}
if schemaVersion != txBinarySchemaVersionCurrent {
if !txBinarySchemaVersionSupported(schemaVersion) {
return nil, fmt.Errorf("unsupported tx binary schema version: %d", schemaVersion)
}
@@ -1531,7 +1547,7 @@ func (dec *txBinaryStreamDecoder) readTxsBinaryHeaderOrEOF() (*txsBinaryHeader,
if err != nil {
return nil, err
}
if schemaVersion != txBinarySchemaVersionCurrent {
if !txBinarySchemaVersionSupported(schemaVersion) {
return nil, fmt.Errorf("unsupported tx binary schema version: %d", schemaVersion)
}
@@ -1799,6 +1815,13 @@ func txBinaryReadTxBody(dec txBinaryBodyReader, tx *TxBinary, enumTable *txBinar
if tx.BlockIndex, err = dec.readUint64(); err != nil {
return err
}
if tx.SchemaVersion >= txBinarySchemaVersionCurrent {
blockAt, err := dec.readUint64()
if err != nil {
return err
}
tx.BlockAt = int64(blockAt)
}
hasTxHash, err := dec.readBool()
if err != nil {
@@ -1854,7 +1877,9 @@ func txBinaryBuildMergePlan(sources []TxsBinaryReaderSource, opts TxsBinaryMerge
builder := txBinaryAddressTableBuilder{
index: make(map[solana.PublicKey]struct{}),
}
plan := &txsBinaryMergePlan{}
plan := &txsBinaryMergePlan{
schemaVersion: txBinarySchemaVersionCurrent,
}
hasBatch := false
for sourceIndex, source := range sources {
@@ -1896,15 +1921,10 @@ func txBinaryBuildMergePlan(sources []TxsBinaryReaderSource, opts TxsBinaryMerge
}
if !hasBatch {
plan.schemaVersion = header.schemaVersion
plan.enumVersion = header.enumVersion
plan.enumTable = header.enumTable
hasBatch = true
} else {
if header.schemaVersion != plan.schemaVersion {
reader.Close()
return nil, fmt.Errorf("source[%d].batch[%d]: schema version mismatch: got %d want %d", sourceIndex, batchIndex, header.schemaVersion, plan.schemaVersion)
}
if header.enumVersion != plan.enumVersion {
reader.Close()
return nil, fmt.Errorf("source[%d].batch[%d]: enum version mismatch: got %d want %d", sourceIndex, batchIndex, header.enumVersion, plan.enumVersion)