-
Notifications
You must be signed in to change notification settings - Fork 442
Expand file tree
/
Copy pathfeature_gate.go
More file actions
116 lines (101 loc) · 3.82 KB
/
Copy pathfeature_gate.go
File metadata and controls
116 lines (101 loc) · 3.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// Copyright 2026 github.com/gagliardetto
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package solana
// Ported from solana-sdk feature-gate-interface (state.rs).
import (
"fmt"
bin "github.com/gagliardetto/binary"
)
// SIMD-0525 slot-time reduction feature gates, in activation order.
// Each takes effect one epoch after its activation epoch (see sysvar.MsPerSlotAt).
var (
FeatureReduceSlotTimeTo350ms = MustPublicKeyFromBase58("iBRL5RuWhw4yqaAZu96RUULHckHTZAoe2b77qaV38JZ")
FeatureReduceSlotTimeTo300ms = MustPublicKeyFromBase58("iBRLL3k18HST852F1Mf3Lv83waTNQmmqvKDxvYGwQFL")
FeatureReduceSlotTimeTo250ms = MustPublicKeyFromBase58("iBRLMc81UjRa8fn8A6eE8bJTnRbgQoPTynM51akENCV")
FeatureReduceSlotTimeTo200ms = MustPublicKeyFromBase58("iBRLjhJnkmDZgNoZRDMW11d8ZV7HvsL3vAyRjZB5npW")
)
// FeatureSizeOf is the serialized size of a Feature account (1-byte option tag + u64).
const FeatureSizeOf = 9
// Feature is the state of a feature-gate account (owner FeatureProgramID).
type Feature struct {
// Slot at which the feature was activated; nil while pending.
ActivatedAt *uint64
}
// IsActive reports whether the feature has been activated.
func (f Feature) IsActive() bool {
return f.ActivatedAt != nil
}
func (f Feature) MarshalWithEncoder(encoder *bin.Encoder) error {
if f.ActivatedAt == nil {
return encoder.WriteByte(0)
}
if err := encoder.WriteByte(1); err != nil {
return err
}
return encoder.WriteUint64(*f.ActivatedAt, bin.LE)
}
func (f *Feature) UnmarshalWithDecoder(decoder *bin.Decoder) error {
// Bincode Option<u64>: strict 0/1 tag, lenient about trailing bytes.
tag, err := decoder.ReadByte()
if err != nil {
return fmt.Errorf("unable to read feature option tag: %w", err)
}
switch tag {
case 0:
f.ActivatedAt = nil
return nil
case 1:
v, err := decoder.ReadUint64(bin.LE)
if err != nil {
return fmt.Errorf("unable to read feature activation slot: %w", err)
}
f.ActivatedAt = &v
return nil
default:
return fmt.Errorf("invalid feature option tag: %d", tag)
}
}
// DecodeFeature decodes a bincode-encoded Feature (Option<u64>).
func DecodeFeature(data []byte) (Feature, error) {
var f Feature
err := f.UnmarshalWithDecoder(bin.NewBinDecoder(data))
return f, err
}
// FeatureFromAccount decodes a Feature after checking the account owner,
// mirroring feature-gate-interface from_account.
func FeatureFromAccount(owner PublicKey, data []byte) (Feature, error) {
if !owner.Equals(FeatureProgramID) {
return Feature{}, fmt.Errorf("invalid feature account owner: %s", owner)
}
// Upstream from_account enforces the minimum account size even for
// pending features, beyond what the lenient bincode decode requires.
if len(data) < FeatureSizeOf {
return Feature{}, fmt.Errorf("feature account data too short: %d bytes, need %d", len(data), FeatureSizeOf)
}
return DecodeFeature(data)
}
// FeatureSet maps feature gate IDs to their activation slot,
// a minimal counterpart of the Rust FeatureSet's active map.
// The zero value (nil) is a valid, empty set.
type FeatureSet map[PublicKey]uint64
// ActivatedSlot returns the activation slot of the feature, if activated.
func (fs FeatureSet) ActivatedSlot(id PublicKey) (uint64, bool) {
slot, ok := fs[id]
return slot, ok
}
// IsActive reports whether the feature is activated.
func (fs FeatureSet) IsActive(id PublicKey) bool {
_, ok := fs[id]
return ok
}