Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
default: patch
---

# Fix a bug where a changed host wallet address leads to failed renewals.
Comment thread
ChrisSchinnerl marked this conversation as resolved.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require (
github.com/quic-go/quic-go v0.59.0
github.com/quic-go/webtransport-go v0.10.0
go.etcd.io/bbolt v1.4.3
go.sia.tech/core v0.19.1
go.sia.tech/core v0.19.2-0.20260421131916-3a5d3f254fd9
go.sia.tech/mux v1.5.0
go.uber.org/zap v1.27.1
golang.org/x/crypto v0.50.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
go.etcd.io/bbolt v1.4.3 h1:dEadXpI6G79deX5prL3QRNP6JB8UxVkqo4UPnHaNXJo=
go.etcd.io/bbolt v1.4.3/go.mod h1:tKQlpPaYCVFctUIgFKFnAlvbmB3tpy1vkTnDWohtc0E=
go.sia.tech/core v0.19.1 h1:rinLh0vuB4eBMVIVZ+Fmaym7B1nxw43I/v/SxYYPVeI=
go.sia.tech/core v0.19.1/go.mod h1:UYT4fwCjNx2wsY1cvGTjXVQPjCEa2LNEgFF3lbHjUVs=
go.sia.tech/core v0.19.2-0.20260421131916-3a5d3f254fd9 h1:SHUyAU/iO9ltIqkBEkUjqwoKxbdK7/aUcpcAElIXSpw=
go.sia.tech/core v0.19.2-0.20260421131916-3a5d3f254fd9/go.mod h1:FhSj+8PZLGQZSjujkAkvjhLvzuy9hRZuoBFFJoH2mto=
go.sia.tech/mux v1.5.0 h1:6bQeO5y4AQPcf+UYHjhxpaNX+2V2wI5LIl0BbAg2YDA=
go.sia.tech/mux v1.5.0/go.mod h1:1/SlgVsLOUsca5tXxAEEwl+Ohm4B8te2YdRhpRGaUZw=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
Expand Down
22 changes: 11 additions & 11 deletions rhp/v4/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,15 +276,15 @@ func callSingleRoundtripRPC(ctx context.Context, t TransportClient, rpcID types.
return nil
}

func rpcRefreshContract(ctx context.Context, t TransportClient, tp TxPool, signer FormContractSigner, cs consensus.State, p rhp4.HostPrices, existing types.V2FileContract, params rhp4.RPCRefreshContractParams, partialRollover bool) (RPCRefreshContractResult, error) {
func rpcRefreshContract(ctx context.Context, t TransportClient, tp TxPool, signer FormContractSigner, cs consensus.State, p rhp4.HostPrices, hostAddress types.Address, existing types.V2FileContract, params rhp4.RPCRefreshContractParams, partialRollover bool) (RPCRefreshContractResult, error) {
var renewal types.V2FileContractRenewal
var usage rhp4.Usage
var id types.Specifier
if partialRollover {
renewal, usage = rhp4.RefreshContractPartialRollover(existing, p, params)
renewal, usage = rhp4.RefreshContractPartialRollover(existing, p, hostAddress, params)
id = rhp4.RPCRefreshPartialID
} else {
renewal, usage = rhp4.RefreshContractFullRollover(existing, p, params)
renewal, usage = rhp4.RefreshContractFullRollover(existing, p, hostAddress, params)
id = rhp4.RPCRefreshContractID
}

Expand Down Expand Up @@ -348,7 +348,7 @@ func rpcRefreshContract(ctx context.Context, t TransportClient, tp TxPool, signe
} else if n > 0 {
// add change output
renewalTxn.SiacoinOutputs = append(renewalTxn.SiacoinOutputs, types.SiacoinOutput{
Address: existing.HostOutput.Address,
Address: renewal.NewContract.HostOutput.Address,
Value: hostInputSum.Sub(hostCost),
})
}
Expand Down Expand Up @@ -1006,8 +1006,8 @@ func RPCFormContract(ctx context.Context, t TransportClient, tp TxPool, signer F
}

// RPCRenewContract renews a contract with a host.
func RPCRenewContract(ctx context.Context, t TransportClient, tp TxPool, signer FormContractSigner, cs consensus.State, p rhp4.HostPrices, existing types.V2FileContract, params rhp4.RPCRenewContractParams) (RPCRenewContractResult, error) {
renewal, usage := rhp4.RenewContract(existing, p, params)
func RPCRenewContract(ctx context.Context, t TransportClient, tp TxPool, signer FormContractSigner, cs consensus.State, p rhp4.HostPrices, hostAddress types.Address, existing types.V2FileContract, params rhp4.RPCRenewContractParams) (RPCRenewContractResult, error) {
renewal, usage := rhp4.RenewContract(existing, p, hostAddress, params)
Comment thread
ChrisSchinnerl marked this conversation as resolved.
renewalTxn := types.V2Transaction{
MinerFee: signer.RecommendedFee().Mul64(1000),
}
Expand Down Expand Up @@ -1067,7 +1067,7 @@ func RPCRenewContract(ctx context.Context, t TransportClient, tp TxPool, signer
} else if n > 0 {
// add change output
renewalTxn.SiacoinOutputs = append(renewalTxn.SiacoinOutputs, types.SiacoinOutput{
Address: existing.HostOutput.Address,
Address: renewal.NewContract.HostOutput.Address,
Value: hostInputSum.Sub(hostCost),
})
}
Expand Down Expand Up @@ -1148,13 +1148,13 @@ func RPCRenewContract(ctx context.Context, t TransportClient, tp TxPool, signer
// RPCRefreshContractFullRollover refreshes a contract with a host.
//
// Deprecated: use RPCRefreshContractPartialRollover instead.
func RPCRefreshContractFullRollover(ctx context.Context, t TransportClient, tp TxPool, signer FormContractSigner, cs consensus.State, p rhp4.HostPrices, existing types.V2FileContract, params rhp4.RPCRefreshContractParams) (RPCRefreshContractResult, error) {
return rpcRefreshContract(ctx, t, tp, signer, cs, p, existing, params, false)
func RPCRefreshContractFullRollover(ctx context.Context, t TransportClient, tp TxPool, signer FormContractSigner, cs consensus.State, p rhp4.HostPrices, hostAddress types.Address, existing types.V2FileContract, params rhp4.RPCRefreshContractParams) (RPCRefreshContractResult, error) {
return rpcRefreshContract(ctx, t, tp, signer, cs, p, hostAddress, existing, params, false)
}

// RPCRefreshContractPartialRollover refreshes a contract with a host.
//
// Only supported on hosts using protocol 5.0.0 or later.
func RPCRefreshContractPartialRollover(ctx context.Context, t TransportClient, tp TxPool, signer FormContractSigner, cs consensus.State, p rhp4.HostPrices, existing types.V2FileContract, params rhp4.RPCRefreshContractParams) (RPCRefreshContractResult, error) {
return rpcRefreshContract(ctx, t, tp, signer, cs, p, existing, params, true)
func RPCRefreshContractPartialRollover(ctx context.Context, t TransportClient, tp TxPool, signer FormContractSigner, cs consensus.State, p rhp4.HostPrices, hostAddress types.Address, existing types.V2FileContract, params rhp4.RPCRefreshContractParams) (RPCRefreshContractResult, error) {
return rpcRefreshContract(ctx, t, tp, signer, cs, p, hostAddress, existing, params, true)
}
30 changes: 15 additions & 15 deletions rhp/v4/rpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,7 @@ func TestRPCRefreshPartialRollover(t *testing.T) {
revision := formContractUploadSector(t, types.Siacoins(100), types.Siacoins(200), types.Siacoins(25))

// refresh the contract
_, err = rhp4.RPCRefreshContractPartialRollover(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, revision.Revision, proto4.RPCRefreshContractParams{
_, err = rhp4.RPCRefreshContractPartialRollover(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, settings.WalletAddress, revision.Revision, proto4.RPCRefreshContractParams{
ContractID: revision.ID,
Allowance: types.ZeroCurrency,
Collateral: types.ZeroCurrency,
Expand All @@ -729,7 +729,7 @@ func TestRPCRefreshPartialRollover(t *testing.T) {
// refresh the contract with 1H over max collateral
collateral := settings.MaxCollateral.Sub(revision.Revision.RiskedCollateral()).Add(types.NewCurrency64(1))
allowance := proto4.MinRenterAllowance(settings.Prices, collateral)
_, err = rhp4.RPCRefreshContractPartialRollover(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, revision.Revision, proto4.RPCRefreshContractParams{
_, err = rhp4.RPCRefreshContractPartialRollover(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, settings.WalletAddress, revision.Revision, proto4.RPCRefreshContractParams{
ContractID: revision.ID,
Allowance: allowance,
Collateral: collateral,
Expand All @@ -743,7 +743,7 @@ func TestRPCRefreshPartialRollover(t *testing.T) {
// try again with exactly max collateral
collateral = settings.MaxCollateral.Sub(revision.Revision.RiskedCollateral())
allowance = proto4.MinRenterAllowance(settings.Prices, collateral)
_, err = rhp4.RPCRefreshContractPartialRollover(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, revision.Revision, proto4.RPCRefreshContractParams{
_, err = rhp4.RPCRefreshContractPartialRollover(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, settings.WalletAddress, revision.Revision, proto4.RPCRefreshContractParams{
ContractID: revision.ID,
Allowance: allowance,
Collateral: collateral,
Expand All @@ -759,7 +759,7 @@ func TestRPCRefreshPartialRollover(t *testing.T) {
newAllowance := types.Siacoins(10)
newCollateral := types.Siacoins(20)
// refresh the contract
refreshResult, err := rhp4.RPCRefreshContractPartialRollover(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, revision.Revision, proto4.RPCRefreshContractParams{
refreshResult, err := rhp4.RPCRefreshContractPartialRollover(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, settings.WalletAddress, revision.Revision, proto4.RPCRefreshContractParams{
ContractID: revision.ID,
Allowance: newAllowance,
Collateral: newCollateral,
Expand Down Expand Up @@ -800,7 +800,7 @@ func TestRPCRefreshPartialRollover(t *testing.T) {
newAllowance := types.Siacoins(20)
newCollateral := types.Siacoins(40)
// refresh the contract
refreshResult, err := rhp4.RPCRefreshContractPartialRollover(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, revision.Revision, proto4.RPCRefreshContractParams{
refreshResult, err := rhp4.RPCRefreshContractPartialRollover(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, settings.WalletAddress, revision.Revision, proto4.RPCRefreshContractParams{
ContractID: revision.ID,
Allowance: newAllowance,
Collateral: newCollateral,
Expand Down Expand Up @@ -844,7 +844,7 @@ func TestRPCRefreshPartialRollover(t *testing.T) {
newAllowance := types.Siacoins(10)
newCollateral := types.Siacoins(20)
// refresh the contract
refreshResult, err := rhp4.RPCRefreshContractPartialRollover(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, revision.Revision, proto4.RPCRefreshContractParams{
refreshResult, err := rhp4.RPCRefreshContractPartialRollover(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, settings.WalletAddress, revision.Revision, proto4.RPCRefreshContractParams{
ContractID: revision.ID,
Allowance: newAllowance,
Collateral: newCollateral,
Expand Down Expand Up @@ -931,7 +931,7 @@ func TestRPCRefreshPartialRollover(t *testing.T) {
newAllowance := types.Siacoins(10)
newCollateral := types.Siacoins(20)
// refresh the contract
refreshResult, err := rhp4.RPCRefreshContractPartialRollover(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, revision.Revision, proto4.RPCRefreshContractParams{
refreshResult, err := rhp4.RPCRefreshContractPartialRollover(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, settings.WalletAddress, revision.Revision, proto4.RPCRefreshContractParams{
ContractID: revision.ID,
Allowance: newAllowance,
Collateral: newCollateral,
Expand Down Expand Up @@ -1066,7 +1066,7 @@ func TestRPCRefreshFullRollover(t *testing.T) {
revision := formContractUploadSector(t, types.Siacoins(100), types.Siacoins(200), types.Siacoins(25))

// refresh the contract
_, err = rhp4.RPCRefreshContractFullRollover(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, revision.Revision, proto4.RPCRefreshContractParams{
_, err = rhp4.RPCRefreshContractFullRollover(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, settings.WalletAddress, revision.Revision, proto4.RPCRefreshContractParams{
ContractID: revision.ID,
Allowance: types.ZeroCurrency,
Collateral: types.ZeroCurrency,
Expand All @@ -1084,7 +1084,7 @@ func TestRPCRefreshFullRollover(t *testing.T) {
// refresh the contract with 1H over max collateral
collateral := settings.MaxCollateral.Sub(revision.Revision.TotalCollateral).Add(types.NewCurrency64(1))
allowance := proto4.MinRenterAllowance(settings.Prices, collateral)
_, err = rhp4.RPCRefreshContractFullRollover(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, revision.Revision, proto4.RPCRefreshContractParams{
_, err = rhp4.RPCRefreshContractFullRollover(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, settings.WalletAddress, revision.Revision, proto4.RPCRefreshContractParams{
ContractID: revision.ID,
Allowance: allowance,
Collateral: collateral,
Expand All @@ -1098,7 +1098,7 @@ func TestRPCRefreshFullRollover(t *testing.T) {
// try again with exactly max collateral
collateral = settings.MaxCollateral.Sub(revision.Revision.TotalCollateral)
allowance = proto4.MinRenterAllowance(settings.Prices, collateral)
_, err = rhp4.RPCRefreshContractFullRollover(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, revision.Revision, proto4.RPCRefreshContractParams{
_, err = rhp4.RPCRefreshContractFullRollover(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, settings.WalletAddress, revision.Revision, proto4.RPCRefreshContractParams{
ContractID: revision.ID,
Allowance: allowance,
Collateral: collateral,
Expand All @@ -1111,7 +1111,7 @@ func TestRPCRefreshFullRollover(t *testing.T) {
t.Run("valid refresh", func(t *testing.T) {
revision := formContractUploadSector(t, types.Siacoins(100), types.Siacoins(200), types.Siacoins(25))
// refresh the contract
refreshResult, err := rhp4.RPCRefreshContractFullRollover(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, revision.Revision, proto4.RPCRefreshContractParams{
refreshResult, err := rhp4.RPCRefreshContractFullRollover(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, settings.WalletAddress, revision.Revision, proto4.RPCRefreshContractParams{
ContractID: revision.ID,
Allowance: types.Siacoins(10),
Collateral: types.Siacoins(20),
Expand Down Expand Up @@ -1241,7 +1241,7 @@ func TestRPCRenew(t *testing.T) {
revision := formContractUploadSector(t, types.Siacoins(100), types.Siacoins(200), types.Siacoins(25))

// renew the contract
_, err = rhp4.RPCRenewContract(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, revision.Revision, proto4.RPCRenewContractParams{
_, err = rhp4.RPCRenewContract(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, settings.WalletAddress, revision.Revision, proto4.RPCRenewContractParams{
ContractID: revision.ID,
Allowance: types.Siacoins(150),
Comment thread
ChrisSchinnerl marked this conversation as resolved.
Collateral: types.Siacoins(300),
Expand All @@ -1258,7 +1258,7 @@ func TestRPCRenew(t *testing.T) {
revision := formContractUploadSector(t, types.Siacoins(100), types.Siacoins(200), types.Siacoins(25))

// renew the contract
renewResult, err := rhp4.RPCRenewContract(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, revision.Revision, proto4.RPCRenewContractParams{
renewResult, err := rhp4.RPCRenewContract(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, settings.WalletAddress, revision.Revision, proto4.RPCRenewContractParams{
ContractID: revision.ID,
Allowance: types.Siacoins(150),
Collateral: types.Siacoins(300),
Expand Down Expand Up @@ -1296,7 +1296,7 @@ func TestRPCRenew(t *testing.T) {
revision := formContractUploadSector(t, types.Siacoins(100), types.Siacoins(200), types.Siacoins(25))

// renew the contract
renewResult, err := rhp4.RPCRenewContract(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, revision.Revision, proto4.RPCRenewContractParams{
renewResult, err := rhp4.RPCRenewContract(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, settings.WalletAddress, revision.Revision, proto4.RPCRenewContractParams{
ContractID: revision.ID,
Allowance: types.Siacoins(50),
Collateral: types.Siacoins(100),
Expand Down Expand Up @@ -1334,7 +1334,7 @@ func TestRPCRenew(t *testing.T) {
revision := formContractUploadSector(t, types.Siacoins(100), types.Siacoins(200), types.Siacoins(25))

// renew the contract
renewResult, err := rhp4.RPCRenewContract(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, revision.Revision, proto4.RPCRenewContractParams{
renewResult, err := rhp4.RPCRenewContract(context.Background(), transport, cm, fundAndSign, cm.TipState(), settings.Prices, settings.WalletAddress, revision.Revision, proto4.RPCRenewContractParams{
ContractID: revision.ID,
Allowance: types.Siacoins(150),
Collateral: types.Siacoins(300),
Expand Down
6 changes: 3 additions & 3 deletions rhp/v4/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -782,9 +782,9 @@ func (s *Server) handleRPCRefreshContract(stream net.Conn, partial bool) error {
var renewal types.V2FileContractRenewal
var usage rhp4.Usage
if partial {
renewal, usage = rhp4.RefreshContractPartialRollover(existing, prices, req.Refresh)
renewal, usage = rhp4.RefreshContractPartialRollover(existing, prices, settings.WalletAddress, req.Refresh)
} else {
renewal, usage = rhp4.RefreshContractFullRollover(existing, prices, req.Refresh)
renewal, usage = rhp4.RefreshContractFullRollover(existing, prices, settings.WalletAddress, req.Refresh)
}
renterCost, hostCost := rhp4.RefreshCost(cs, prices, renewal, req.MinerFee)
renewalTxn := types.V2Transaction{
Expand Down Expand Up @@ -966,7 +966,7 @@ func (s *Server) handleRPCRenewContract(stream net.Conn) error {
}

cs := s.chain.TipState()
renewal, usage := rhp4.RenewContract(existing, prices, req.Renewal)
renewal, usage := rhp4.RenewContract(existing, prices, settings.WalletAddress, req.Renewal)
renterCost, hostCost := rhp4.RenewalCost(cs, renewal, req.MinerFee)
renewalTxn := types.V2Transaction{
MinerFee: req.MinerFee,
Expand Down
Loading