Implement PDP schedule execution path and config wiring#621
Conversation
|
based on test failure let's park this momentarily while I push up the work related to wallet extraction from db, early next week |
|
see #622 and data-preservation-programs/go-synapse#4 both need work but I need to sign off for the week |
c93e4e2 to
1641a4e
Compare
|
a few changes needed here to cleanly separate the Actor and Wallet concepts:
these are basically the changes from #621 (comment) that I mentioned as critical |
1641a4e to
c03ce04
Compare
|
I'll do a basic rebase fixup here with obvious changes that don't require deliberation then leave it in your hands |
…tor semantics (#622) ## Problem Singularity used go-filsigner for Filecoin message signing, with key material stored inline in the database (wallets.private_key column). The Wallet model was actually an on-chain actor identity (f0 address) with an embedded private key -- confusing naming that also coupled key management to database access and left a big security hole/private keys exposed in any db backup or access violation For PDP deals, we need EVM transaction signing (secp256k1 ECDSA), which go-filsigner doesn't support. The existing model also couldn't represent the real relationship: a wallet (private key) exists before any on-chain actor, and PDP deals don't need an actor at all. ## Solution ### New keystore abstraction (util/keystore/): - KeyStore interface with Put/Get/List/Delete/Has — filesystem-backed, keys stored as lotus-export-format files named by address (for now) - Signer(ks, wallet) / EVMSigner(ks, wallet) — loads key from keystore, returns go-synapse Signer or EVMSigner - Replaces direct database reads for key material ### Model rename — old Wallet becomes Actor: - The old Wallet struct (f0 actor ID + address + private key) is renamed to Actor — that's what it always was - Actor.PrivateKey column is orphaned (will be dropped by a future export-keys migration command) - GORM TableName() renames wallets → actors on auto-migrate ### New Wallet model (model/wallet.go): - Represents a private key in an external keystore: KeyPath, KeyStore, Address - Optional ActorID foreign key — links to on-chain actor when one exists - Invariant: any deal we make requires a Wallet. Market deals also require an Actor (for ClientID). PDP deals need only a Wallet. Imported/tracked deals may have neither. ### Preparation associates with Wallet, not Actor: - Preparation.Actors []Actor → Preparation.Wallets []Wallet (many2many wallet_assignments) - All handlers updated: attach/detach/listattached operate on Wallets - WalletChooser picks from []model.Wallet, DatacapWalletChooser dereferences wallet.ActorID for datacap lookup - Dealpusher market deal path: choose wallet → require ActorID → load actor → sign with wallet → pass actor to MakeDeal - Association to Actor can be loaded on demand, see below ### MakeDeal takes ProposalSigner instead of db + keystore: - type ProposalSigner func([]byte) (*crypto.Signature, error) - Caller constructs the signer, MakeDeal just calls it — cleaner separation ### Lazy actor resolution (handler/wallet/sign.go): - GetOrCreateActor() — on first market deal, queries Lotus for the wallet's on-chain actor, creates Actor record, links it - Supports the workflow: import wallet offline → fund externally → first deal auto-discovers actor ### DealPusher options pattern (service/dealpusher/options.go): - WithPDPProofSetManager, WithPDPTransactionConfirmer, WithPDPSchedulingConfig, WithScheduleDealTypeResolver - Replaces growing constructor parameter list ### Dependency changes - Added: go-synapse updated (b27d67ac9095) — provides signer.FromLotusExport, signer.Signer, signer.EVMSigner, signer.AsEVM - Removed: go-filsigner and its transitive deps (dchest/blake2b, drand/kyber, drand/kyber-bls12381) ### What's NOT in this PR - Key export/migration command (exporting actors.private_key → keystore files) — separate PR - Dropping the private_key column — blocked on export command - PDP deal-making wiring (this PR provides the signing infra, actual PDP scheduling is #621)
|
actually rebase/force push over your code is rude, redoing as merge commit so you can review it clearly |
resolve conflicts in dealpusher: adapt PDP scheduling to new Wallet/Actor model and keystore-based EVMSigner from #622
| return model.ScheduleCompleted, nil | ||
| } | ||
|
|
||
| walletObj, err := d.walletChooser.Choose(ctx, schedule.Preparation.Wallets) |
There was a problem hiding this comment.
hmm I think we should remove random wallet chooser or parametrize it such that specific properties are met (e.g. non-BLS key) -- I don't really see the utility here; if we want to round-robin across wallets for some reason we can make the parameter multivalued and let the user choose, but that seems like a bonus not core
| if err := baseQuery().Find(&cars).Error; err != nil { | ||
| return nil, errors.Wrap(err, "failed to find PDP cars") | ||
| } | ||
| filtered := make([]model.Car, 0, limit) |
There was a problem hiding this comment.
why not limit during db read?
| } | ||
|
|
||
| if err := database.DoRetry(ctx, func() error { return db.Create(dealModel).Error }); err != nil { | ||
| return model.ScheduleError, errors.Wrap(err, "failed to create PDP deal") |
There was a problem hiding this comment.
we will likely want to do something more sophisticated if deal lands on chain but DB write fails or we crash etc; right now this is recoverable if noticed using --full-sync so not a blocker but I would add a TODO for more resilient lifecycle management
|
I would move the filter limit into DB scan unless you have conflicting plans, the other two are just TODOs for later approved so you can merge (if you disagree about DB add a comment explaining why) |
Summary
Validation