radiance/pkg/shred/legacy.go

184 lines
4.0 KiB
Go

package shred
import (
"encoding/base64"
bin "github.com/gagliardetto/binary"
"github.com/gagliardetto/solana-go"
)
type LegacyCode struct {
Common CommonHeader
Payload []byte
}
const (
LegacyDataHeaderSize = 86
LegacyDataV2HeaderSize = 88
LegacyPayloadSize = 1057 // TODO where does this number come from?
LegacyV2PayloadSize = 1051 // TODO idk???
)
func LegacyCodeFromPayload(shred []byte) *LegacyCode {
panic("legacy shred code unimplemented")
}
func (s *LegacyCode) CommonHeader() *CommonHeader {
return &s.Common
}
func (s *LegacyCode) DataHeader() *DataHeader {
return nil
}
func (s *LegacyCode) Data() ([]byte, bool) {
return nil, false
}
func (s *LegacyCode) DataComplete() bool {
return false
}
// LegacyData is genesis-era shred data.
type LegacyData struct {
Common CommonHeader
Header DataHeader
Payload []byte
}
func LegacyDataFromPayload(shred []byte) *LegacyData {
data := new(LegacyData)
dec := bin.NewBinDecoder(shred)
if err := dec.Decode(&data.Common); err != nil {
return nil
}
if err := dec.Decode(&data.Header); err != nil {
return nil
}
if data.Common.Variant != LegacyDataID {
return nil
}
if len(shred) < LegacyDataHeaderSize {
return nil
}
// TODO Sanitize
data.Payload = make([]byte, LegacyDataHeaderSize+LegacyPayloadSize)
copy(data.Payload, shred)
return data
}
func (s *LegacyData) CommonHeader() *CommonHeader {
return &s.Common
}
func (s *LegacyData) DataHeader() *DataHeader {
return &s.Header
}
func (s *LegacyData) Data() ([]byte, bool) {
return s.Payload[LegacyDataHeaderSize : LegacyDataHeaderSize+LegacyPayloadSize], true
}
func (s *LegacyData) DataComplete() bool {
return s.Header.Flags&FlagDataCompleteShred == 1
}
func (s *LegacyData) ReferenceTick() uint8 {
return s.Header.Flags & FlagShredTickReferenceMask
}
func (s *LegacyData) MarshalYAML() (any, error) {
item := struct {
Signature solana.Signature
Variant uint8
Slot uint64
Index uint32
Version uint16
FECSetIndex uint32
Payload string
}{
Signature: s.Common.Signature,
Variant: s.Common.Variant,
Slot: s.Common.Slot,
Index: s.Common.Index,
Version: s.Common.Version,
FECSetIndex: s.Common.FECSetIndex,
Payload: base64.StdEncoding.EncodeToString(s.Payload),
}
return item, nil
}
// LegacyDataV2 is Q2 2020-era shred data.
type LegacyDataV2 struct {
Common CommonHeader
Header DataV2Header
Payload []byte
}
func LegacyDataV2FromPayload(shred []byte) *LegacyDataV2 {
data := new(LegacyDataV2)
dec := bin.NewBinDecoder(shred)
if err := dec.Decode(&data.Common); err != nil {
return nil
}
if err := dec.Decode(&data.Header); err != nil {
return nil
}
if data.Common.Variant != LegacyDataID {
return nil
}
if len(shred) < LegacyDataV2HeaderSize {
return nil
}
// TODO Sanitize
data.Payload = make([]byte, LegacyDataV2HeaderSize+LegacyV2PayloadSize)
copy(data.Payload, shred)
return data
}
func (s *LegacyDataV2) CommonHeader() *CommonHeader {
return &s.Common
}
func (s *LegacyDataV2) DataHeader() *DataV2Header {
return &s.Header
}
func (s *LegacyDataV2) Data() ([]byte, bool) {
if int(s.Header.Size) > len(s.Payload) {
return nil, false
}
return s.Payload[LegacyDataV2HeaderSize:s.Header.Size], true
}
func (s *LegacyDataV2) DataComplete() bool {
return s.Header.Flags&FlagDataCompleteShred == 1
}
func (s *LegacyDataV2) ReferenceTick() uint8 {
return s.Header.Flags & FlagShredTickReferenceMask
}
func (s *LegacyDataV2) MarshalYAML() (any, error) {
item := struct {
Signature solana.Signature
Variant uint8
Slot uint64
Index uint32
Version uint16
FECSetIndex uint32
Size uint16
Payload string
}{
Signature: s.Common.Signature,
Variant: s.Common.Variant,
Slot: s.Common.Slot,
Index: s.Common.Index,
Version: s.Common.Version,
FECSetIndex: s.Common.FECSetIndex,
Size: s.Header.Size,
Payload: base64.StdEncoding.EncodeToString(s.Payload),
}
return item, nil
}