Skip to content

Commit

Permalink
Update new contract formation endpoint to broadcast event for formed …
Browse files Browse the repository at this point in the history
…contracts (#1471)
  • Loading branch information
ChrisSchinnerl committed Aug 22, 2024
2 parents 6c61aa9 + 49d7f66 commit e0d618f
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 63 deletions.
65 changes: 65 additions & 0 deletions bus/bus.go
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,71 @@ func (b *Bus) Shutdown(ctx context.Context) error {
)
}

func (b *Bus) addContract(ctx context.Context, rev rhpv2.ContractRevision, contractPrice, totalCost types.Currency, startHeight uint64, state string) (api.ContractMetadata, error) {
c, err := b.ms.AddContract(ctx, rev, contractPrice, totalCost, startHeight, state)
if err != nil {
return api.ContractMetadata{}, err
}

b.broadcastAction(webhooks.Event{
Module: api.ModuleContract,
Event: api.EventAdd,
Payload: api.EventContractAdd{
Added: c,
Timestamp: time.Now().UTC(),
},
})
return c, nil
}

func (b *Bus) isPassedV2AllowHeight() bool {
cs := b.cm.TipState()
return cs.Index.Height >= cs.Network.HardforkV2.AllowHeight
}

func (b *Bus) formContract(ctx context.Context, hostSettings rhpv2.HostSettings, renterAddress types.Address, renterFunds, hostCollateral types.Currency, hostKey types.PublicKey, hostIP string, endHeight uint64) (rhpv2.ContractRevision, error) {
// derive the renter key
renterKey := b.deriveRenterKey(hostKey)

// prepare the transaction
cs := b.cm.TipState()
fc := rhpv2.PrepareContractFormation(renterKey.PublicKey(), hostKey, renterFunds, hostCollateral, endHeight, hostSettings, renterAddress)
txn := types.Transaction{FileContracts: []types.FileContract{fc}}

// calculate the miner fee
fee := b.cm.RecommendedFee().Mul64(cs.TransactionWeight(txn))
txn.MinerFees = []types.Currency{fee}

// fund the transaction
cost := rhpv2.ContractFormationCost(cs, fc, hostSettings.ContractPrice).Add(fee)
toSign, err := b.w.FundTransaction(&txn, cost, true)
if err != nil {
return rhpv2.ContractRevision{}, fmt.Errorf("couldn't fund transaction: %w", err)
}

// sign the transaction
b.w.SignTransaction(&txn, toSign, wallet.ExplicitCoveredFields(txn))

// form the contract
contract, txnSet, err := b.rhp2.FormContract(ctx, hostKey, hostIP, renterKey, append(b.cm.UnconfirmedParents(txn), txn))
if err != nil {
b.w.ReleaseInputs([]types.Transaction{txn}, nil)
return rhpv2.ContractRevision{}, err
}

// add transaction set to the pool
_, err = b.cm.AddPoolTransactions(txnSet)
if err != nil {
b.w.ReleaseInputs([]types.Transaction{txn}, nil)
return rhpv2.ContractRevision{}, fmt.Errorf("couldn't add transaction set to the pool: %w", err)
}

// broadcast the transaction set
go b.s.BroadcastTransactionSet(txnSet)

return contract, nil
}

// initSettings loads the default settings if the setting is not already set and
// ensures the settings are valid
func (b *Bus) initSettings(ctx context.Context) error {
Expand Down
62 changes: 2 additions & 60 deletions bus/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -948,20 +948,10 @@ func (b *Bus) contractIDHandlerPOST(jc jape.Context) {
return
}

a, err := b.ms.AddContract(jc.Request.Context(), req.Contract, req.ContractPrice, req.TotalCost, req.StartHeight, req.State)
a, err := b.addContract(jc.Request.Context(), req.Contract, req.ContractPrice, req.TotalCost, req.StartHeight, req.State)
if jc.Check("couldn't store contract", err) != nil {
return
}

b.broadcastAction(webhooks.Event{
Module: api.ModuleContract,
Event: api.EventAdd,
Payload: api.EventContractAdd{
Added: a,
Timestamp: time.Now().UTC(),
},
})

jc.Encode(a)
}

Expand Down Expand Up @@ -2357,7 +2347,7 @@ func (b *Bus) contractsFormHandler(jc jape.Context) {
}

// store the contract
metadata, err := b.ms.AddContract(
metadata, err := b.addContract(
ctx,
contract,
contract.Revision.MissedHostPayout().Sub(rfr.HostCollateral),
Expand All @@ -2372,51 +2362,3 @@ func (b *Bus) contractsFormHandler(jc jape.Context) {
// return the contract
jc.Encode(metadata)
}

func (b *Bus) formContract(ctx context.Context, hostSettings rhpv2.HostSettings, renterAddress types.Address, renterFunds, hostCollateral types.Currency, hostKey types.PublicKey, hostIP string, endHeight uint64) (rhpv2.ContractRevision, error) {
// derive the renter key
renterKey := b.deriveRenterKey(hostKey)

// prepare the transaction
cs := b.cm.TipState()
fc := rhpv2.PrepareContractFormation(renterKey.PublicKey(), hostKey, renterFunds, hostCollateral, endHeight, hostSettings, renterAddress)
txn := types.Transaction{FileContracts: []types.FileContract{fc}}

// calculate the miner fee
fee := b.cm.RecommendedFee().Mul64(cs.TransactionWeight(txn))
txn.MinerFees = []types.Currency{fee}

// fund the transaction
cost := rhpv2.ContractFormationCost(cs, fc, hostSettings.ContractPrice).Add(fee)
toSign, err := b.w.FundTransaction(&txn, cost, true)
if err != nil {
return rhpv2.ContractRevision{}, fmt.Errorf("couldn't fund transaction: %w", err)
}

// sign the transaction
b.w.SignTransaction(&txn, toSign, wallet.ExplicitCoveredFields(txn))

// form the contract
contract, txnSet, err := b.rhp2.FormContract(ctx, hostKey, hostIP, renterKey, append(b.cm.UnconfirmedParents(txn), txn))
if err != nil {
b.w.ReleaseInputs([]types.Transaction{txn}, nil)
return rhpv2.ContractRevision{}, err
}

// add transaction set to the pool
_, err = b.cm.AddPoolTransactions(txnSet)
if err != nil {
b.w.ReleaseInputs([]types.Transaction{txn}, nil)
return rhpv2.ContractRevision{}, fmt.Errorf("couldn't add transaction set to the pool: %w", err)
}

// broadcast the transaction set
go b.s.BroadcastTransactionSet(txnSet)

return contract, nil
}

func (b *Bus) isPassedV2AllowHeight() bool {
cs := b.cm.TipState()
return cs.Index.Height >= cs.Network.HardforkV2.AllowHeight
}
6 changes: 3 additions & 3 deletions internal/test/e2e/contracts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ func TestFormContract(t *testing.T) {
tt.OK(err)

// form a contract using the bus
cs, _ := b.ConsensusState(context.Background())
wallet, _ := b.Wallet(context.Background())
endHeight := cs.BlockHeight + test.AutopilotConfig.Contracts.Period + test.AutopilotConfig.Contracts.RenewWindow
contract, err := b.FormContract(context.Background(), wallet.Address, types.Siacoins(1), h.PublicKey, h.NetAddress, types.Siacoins(1), endHeight)
ap, err := b.Autopilot(context.Background(), api.DefaultAutopilotID)
tt.OK(err)
contract, err := b.FormContract(context.Background(), wallet.Address, types.Siacoins(1), h.PublicKey, h.NetAddress, types.Siacoins(1), ap.EndHeight())
tt.OK(err)

// assert the contract was added to the bus
Expand Down

0 comments on commit e0d618f

Please sign in to comment.