Skip to content

Commit 6a0f4a5

Browse files
authored
Merge pull request #187 from pushchain/release/v1.1.23-donut
Release/v1.1.23 donut
2 parents c0d515c + 6ffa725 commit 6a0f4a5

File tree

5 files changed

+270
-11
lines changed

5 files changed

+270
-11
lines changed

api/uexecutor/v1/types.pulsar.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/upgrades.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/pushchain/push-chain-node/app/upgrades"
99
aiauditfixes "github.com/pushchain/push-chain-node/app/upgrades/ai-audit-fixes"
10+
aiauditfixes2 "github.com/pushchain/push-chain-node/app/upgrades/ai-audit-fixes-2"
1011
ceagasandpayload "github.com/pushchain/push-chain-node/app/upgrades/cea-gas-and-payload"
1112
ceapayloadverificationfix "github.com/pushchain/push-chain-node/app/upgrades/cea-payload-verification-fix"
1213
chainmeta "github.com/pushchain/push-chain-node/app/upgrades/chain-meta"
@@ -28,7 +29,6 @@ import (
2829
tsscorefix "github.com/pushchain/push-chain-node/app/upgrades/tss-core-fix"
2930
tssvotegasless "github.com/pushchain/push-chain-node/app/upgrades/tss-vote-gasless"
3031
universaltxv1 "github.com/pushchain/push-chain-node/app/upgrades/universal-tx-v1"
31-
aiauditfixes "github.com/pushchain/push-chain-node/app/upgrades/ai-audit-fixes"
3232
)
3333

3434
// Upgrades list of chain upgrades
@@ -54,6 +54,7 @@ var Upgrades = []upgrades.Upgrade{
5454
ceagasandpayload.NewUpgrade(),
5555
ceapayloadverificationfix.NewUpgrade(),
5656
aiauditfixes.NewUpgrade(),
57+
aiauditfixes2.NewUpgrade(),
5758
}
5859

5960
// RegisterUpgradeHandlers registers the chain upgrade handlers
Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
package aiauditfixes2
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"cosmossdk.io/log"
8+
storetypes "cosmossdk.io/store/types"
9+
upgradetypes "cosmossdk.io/x/upgrade/types"
10+
11+
sdk "github.com/cosmos/cosmos-sdk/types"
12+
"github.com/cosmos/cosmos-sdk/types/module"
13+
14+
"github.com/pushchain/push-chain-node/app/upgrades"
15+
uexecutortypes "github.com/pushchain/push-chain-node/x/uexecutor/types"
16+
utsstypes "github.com/pushchain/push-chain-node/x/utss/types"
17+
)
18+
19+
const UpgradeName = "ai-audit-fixes-2"
20+
21+
func NewUpgrade() upgrades.Upgrade {
22+
return upgrades.Upgrade{
23+
UpgradeName: UpgradeName,
24+
CreateUpgradeHandler: CreateUpgradeHandler,
25+
StoreUpgrades: storetypes.StoreUpgrades{
26+
Added: []string{},
27+
Deleted: []string{},
28+
},
29+
}
30+
}
31+
32+
func CreateUpgradeHandler(
33+
mm upgrades.ModuleManager,
34+
configurator module.Configurator,
35+
ak *upgrades.AppKeepers,
36+
) upgradetypes.UpgradeHandler {
37+
return func(ctx context.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
38+
sdkCtx := sdk.UnwrapSDKContext(ctx)
39+
logger := sdkCtx.Logger().With("upgrade", UpgradeName)
40+
logger.Info("Starting upgrade handler")
41+
42+
// ---------------------------------------------------------------
43+
// 1. Run module migrations FIRST (consensus version bumps)
44+
// Must run before backfills so that the new proto schema
45+
// (e.g. revert_error field on UniversalTx) is applied
46+
// before we iterate existing entries.
47+
// - uexecutor: 5 → 6 (PendingOutbounds collection)
48+
// - utss: 1 → 2 (TssEvents collections)
49+
// ---------------------------------------------------------------
50+
versionMap, err := mm.RunMigrations(ctx, configurator, fromVM)
51+
if err != nil {
52+
return nil, fmt.Errorf("RunMigrations: %w", err)
53+
}
54+
55+
// ---------------------------------------------------------------
56+
// 2. Backfill PendingOutbounds index from existing UniversalTx
57+
// (safe now — migrations have run, proto schema is current)
58+
// ---------------------------------------------------------------
59+
if err := backfillPendingOutbounds(ctx, ak, logger); err != nil {
60+
return nil, fmt.Errorf("backfillPendingOutbounds: %w", err)
61+
}
62+
63+
// ---------------------------------------------------------------
64+
// 3. Backfill TssEvents from ProcessHistory + TssKeyHistory
65+
// ---------------------------------------------------------------
66+
if err := backfillTssEvents(ctx, ak, logger); err != nil {
67+
return nil, fmt.Errorf("backfillTssEvents: %w", err)
68+
}
69+
70+
// ---------------------------------------------------------------
71+
// 4. Register usigverifier V2 precompile in EVM params
72+
// ---------------------------------------------------------------
73+
if err := registerPrecompileV2(sdkCtx, ak, logger); err != nil {
74+
return nil, fmt.Errorf("registerPrecompileV2: %w", err)
75+
}
76+
77+
logger.Info("Upgrade complete", "upgrade", UpgradeName)
78+
return versionMap, nil
79+
}
80+
}
81+
82+
// backfillPendingOutbounds iterates all UniversalTx entries and creates a
83+
// PendingOutboundEntry for every outbound that is still in PENDING status.
84+
func backfillPendingOutbounds(ctx context.Context, ak *upgrades.AppKeepers, logger log.Logger) error {
85+
keeper := ak.UExecutorKeeper
86+
logger.Info("Backfilling PendingOutbounds index")
87+
88+
count := 0
89+
iter, err := keeper.UniversalTx.Iterate(ctx, nil)
90+
if err != nil {
91+
return fmt.Errorf("failed to create UniversalTx iterator: %w", err)
92+
}
93+
defer iter.Close()
94+
95+
for ; iter.Valid(); iter.Next() {
96+
kv, err := iter.KeyValue()
97+
if err != nil {
98+
return fmt.Errorf("failed to read UniversalTx entry: %w", err)
99+
}
100+
101+
utxId := kv.Key
102+
utx := kv.Value
103+
104+
for _, ob := range utx.OutboundTx {
105+
if ob == nil {
106+
continue
107+
}
108+
if ob.OutboundStatus == uexecutortypes.Status_PENDING {
109+
entry := uexecutortypes.PendingOutboundEntry{
110+
OutboundId: ob.Id,
111+
UniversalTxId: utxId,
112+
CreatedAt: 0, // unknown historical height
113+
}
114+
if err := keeper.PendingOutbounds.Set(ctx, ob.Id, entry); err != nil {
115+
return fmt.Errorf("failed to set pending outbound %s: %w", ob.Id, err)
116+
}
117+
count++
118+
}
119+
}
120+
}
121+
122+
logger.Info("PendingOutbounds backfill complete", "total_indexed", count)
123+
return nil
124+
}
125+
126+
// backfillTssEvents creates TssEvent entries from ProcessHistory and TssKeyHistory.
127+
// Skips if events already exist (re-run guard).
128+
func backfillTssEvents(ctx context.Context, ak *upgrades.AppKeepers, logger log.Logger) error {
129+
utssKeeper := ak.UTssKeeper
130+
logger.Info("Backfilling TssEvents")
131+
132+
// Guard: skip if events already exist
133+
hasEvents := false
134+
_ = utssKeeper.TssEvents.Walk(ctx, nil, func(id uint64, event utsstypes.TssEvent) (bool, error) {
135+
hasEvents = true
136+
return true, nil
137+
})
138+
if hasEvents {
139+
logger.Info("TssEvents already exist, skipping backfill")
140+
return nil
141+
}
142+
143+
// Backfill from ProcessHistory
144+
err := utssKeeper.ProcessHistory.Walk(ctx, nil, func(processId uint64, process utsstypes.TssKeyProcess) (bool, error) {
145+
eventId, err := utssKeeper.NextTssEventId.Next(ctx)
146+
if err != nil {
147+
return true, fmt.Errorf("failed to generate tss event id: %w", err)
148+
}
149+
150+
var status utsstypes.TssEventStatus
151+
switch process.Status {
152+
case utsstypes.TssKeyProcessStatus_TSS_KEY_PROCESS_PENDING:
153+
status = utsstypes.TssEventStatus_TSS_EVENT_ACTIVE
154+
case utsstypes.TssKeyProcessStatus_TSS_KEY_PROCESS_SUCCESS:
155+
status = utsstypes.TssEventStatus_TSS_EVENT_COMPLETED
156+
case utsstypes.TssKeyProcessStatus_TSS_KEY_PROCESS_FAILED:
157+
status = utsstypes.TssEventStatus_TSS_EVENT_EXPIRED
158+
default:
159+
status = utsstypes.TssEventStatus_TSS_EVENT_ACTIVE
160+
}
161+
162+
tssEvent := utsstypes.TssEvent{
163+
Id: eventId,
164+
EventType: utsstypes.TssEventType_TSS_EVENT_PROCESS_INITIATED,
165+
Status: status,
166+
ProcessId: process.Id,
167+
ProcessType: process.ProcessType.String(),
168+
Participants: process.Participants,
169+
ExpiryHeight: process.ExpiryHeight,
170+
BlockHeight: process.BlockHeight,
171+
}
172+
173+
if err := utssKeeper.TssEvents.Set(ctx, eventId, tssEvent); err != nil {
174+
return true, fmt.Errorf("failed to store tss event: %w", err)
175+
}
176+
return false, nil
177+
})
178+
if err != nil {
179+
return fmt.Errorf("failed to backfill process history events: %w", err)
180+
}
181+
182+
// Backfill from TssKeyHistory
183+
var latestFinalizedEventId uint64
184+
var latestFinalizedBlockHeight int64
185+
hasFinalized := false
186+
187+
err = utssKeeper.TssKeyHistory.Walk(ctx, nil, func(keyId string, key utsstypes.TssKey) (bool, error) {
188+
eventId, err := utssKeeper.NextTssEventId.Next(ctx)
189+
if err != nil {
190+
return true, fmt.Errorf("failed to generate tss event id: %w", err)
191+
}
192+
193+
tssEvent := utsstypes.TssEvent{
194+
Id: eventId,
195+
EventType: utsstypes.TssEventType_TSS_EVENT_KEY_FINALIZED,
196+
Status: utsstypes.TssEventStatus_TSS_EVENT_COMPLETED,
197+
ProcessId: key.ProcessId,
198+
Participants: key.Participants,
199+
KeyId: key.KeyId,
200+
TssPubkey: key.TssPubkey,
201+
BlockHeight: key.FinalizedBlockHeight,
202+
}
203+
204+
if err := utssKeeper.TssEvents.Set(ctx, eventId, tssEvent); err != nil {
205+
return true, fmt.Errorf("failed to store tss key finalized event: %w", err)
206+
}
207+
208+
if key.FinalizedBlockHeight >= latestFinalizedBlockHeight {
209+
latestFinalizedBlockHeight = key.FinalizedBlockHeight
210+
latestFinalizedEventId = eventId
211+
hasFinalized = true
212+
}
213+
return false, nil
214+
})
215+
if err != nil {
216+
return fmt.Errorf("failed to backfill tss key history events: %w", err)
217+
}
218+
219+
// Mark the latest finalized key event as ACTIVE
220+
if hasFinalized {
221+
latestEvent, err := utssKeeper.TssEvents.Get(ctx, latestFinalizedEventId)
222+
if err != nil {
223+
return fmt.Errorf("failed to get latest finalized event: %w", err)
224+
}
225+
latestEvent.Status = utsstypes.TssEventStatus_TSS_EVENT_ACTIVE
226+
if err := utssKeeper.TssEvents.Set(ctx, latestFinalizedEventId, latestEvent); err != nil {
227+
return fmt.Errorf("failed to update latest finalized event status: %w", err)
228+
}
229+
}
230+
231+
logger.Info("TssEvents backfill complete")
232+
return nil
233+
}
234+
235+
// registerPrecompileV2 adds the usigverifier V2 address to EVM ActiveStaticPrecompiles
236+
// so the EVM recognizes it as a callable precompile.
237+
func registerPrecompileV2(sdkCtx sdk.Context, ak *upgrades.AppKeepers, logger log.Logger) error {
238+
const usigVerifierV2Addr = "0xEC00000000000000000000000000000000000001"
239+
240+
evmParams := ak.EVMKeeper.GetParams(sdkCtx)
241+
242+
// Check if already registered
243+
for _, addr := range evmParams.ActiveStaticPrecompiles {
244+
if addr == usigVerifierV2Addr {
245+
logger.Info("usigverifier V2 precompile already registered in EVM params")
246+
return nil
247+
}
248+
}
249+
250+
evmParams.ActiveStaticPrecompiles = append(evmParams.ActiveStaticPrecompiles, usigVerifierV2Addr)
251+
252+
if err := ak.EVMKeeper.SetParams(sdkCtx, evmParams); err != nil {
253+
return fmt.Errorf("failed to set EVM params with new precompile: %w", err)
254+
}
255+
256+
logger.Info("Registered usigverifier V2 precompile in EVM params", "address", usigVerifierV2Addr)
257+
return nil
258+
}

proto/uexecutor/v1/types.proto

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ message UniversalTx {
188188
Inbound inbound_tx = 2; // Full inbound tx data
189189
repeated PCTx pc_tx = 3; // Execution details on Push Chain
190190
repeated OutboundTx outbound_tx = 4; // Outbound tx triggered by this tx
191-
string revert_error = 5; // Non-empty if revert outbound attachment failed
191+
string revert_error = 6; // Non-empty if revert outbound attachment failed (field 5 reserved — ghost enum data from removed UniversalTxStatus)
192192
}
193193

194194
// LEGACY TYPES

x/uexecutor/types/types.pb.go

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)