From 8bf8e6c802993653d21b5399a705dfb366947910 Mon Sep 17 00:00:00 2001 From: Nate Maninger Date: Mon, 21 Oct 2024 13:21:52 -0700 Subject: [PATCH 1/6] deps: update core --- go.mod | 2 +- go.sum | 4 ++-- wallet/wallet_test.go | 4 +--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 2348802..615ca38 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ toolchain go1.23.2 require ( go.etcd.io/bbolt v1.3.11 - go.sia.tech/core v0.4.8-0.20241010202802-e48286dc47bf + go.sia.tech/core v0.4.8-0.20241021201948-dfdf69e37844 go.sia.tech/mux v1.3.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.28.0 diff --git a/go.sum b/go.sum index 84dae1e..961800b 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,8 @@ github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKs github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= -go.sia.tech/core v0.4.8-0.20241010202802-e48286dc47bf h1:kTIodJvCiCgr87QURm/9NS5JJw9Mr6mgKs9sBSFUzqA= -go.sia.tech/core v0.4.8-0.20241010202802-e48286dc47bf/go.mod h1:CpiFY0jL5OlU6sm/6fwd6/LQe6Ao8G6OtHtq21ggIoA= +go.sia.tech/core v0.4.8-0.20241021201948-dfdf69e37844 h1:rzFVA7X7QLKhmHSOnjQ0hAqPj/6f4Y5wItKhfngyBYo= +go.sia.tech/core v0.4.8-0.20241021201948-dfdf69e37844/go.mod h1:P3C1BWa/7J4XgdzWuaYHBvLo2RzZ0UBaJM4TG1GWB2g= go.sia.tech/mux v1.3.0 h1:hgR34IEkqvfBKUJkAzGi31OADeW2y7D6Bmy/Jcbop9c= go.sia.tech/mux v1.3.0/go.mod h1:I46++RD4beqA3cW9Xm9SwXbezwPqLvHhVs9HLpDtt58= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= diff --git a/wallet/wallet_test.go b/wallet/wallet_test.go index 392d2b1..24b3aa8 100644 --- a/wallet/wallet_test.go +++ b/wallet/wallet_test.go @@ -1860,10 +1860,8 @@ func TestSingleAddressWalletEventTypes(t *testing.T) { finalRevision := fce.V2FileContract finalRevision.RevisionNumber = math.MaxUint64 finalRevisionSigHash := cm.TipState().ContractSigHash(finalRevision) - finalRevision.RenterSignature = pk.SignHash(finalRevisionSigHash) - finalRevision.HostSignature = pk.SignHash(finalRevisionSigHash) // create a renewal - finalization := types.V2FileContractFinalization(finalRevision) + finalization := types.V2FileContractFinalization(pk.SignHash(finalRevisionSigHash)) // create the renewal transaction resolutionTxn := types.V2Transaction{ From c8966b742d517eaf196b4357e4544b240e6dfb19 Mon Sep 17 00:00:00 2001 From: Nate Maninger Date: Mon, 21 Oct 2024 13:24:14 -0700 Subject: [PATCH 2/6] rhp4: implement RPC remove --- rhp/v4/rpc.go | 46 +++++++++++++------------- rhp/v4/rpc_test.go | 77 +++++++++++++++++-------------------------- rhp/v4/server.go | 81 ++++++++++++++++++++++------------------------ 3 files changed, 90 insertions(+), 114 deletions(-) diff --git a/rhp/v4/rpc.go b/rhp/v4/rpc.go index 17da549..d16c578 100644 --- a/rhp/v4/rpc.go +++ b/rhp/v4/rpc.go @@ -124,8 +124,8 @@ type ( Cost types.Currency `json:"cost"` } - // RPCModifySectorsResult contains the result of executing the modify sectors RPC. - RPCModifySectorsResult struct { + // RPCRemoveSectorsResult contains the result of executing the remove sectors RPC. + RPCRemoveSectorsResult struct { Revision types.V2FileContract `json:"revision"` Cost types.Currency `json:"cost"` } @@ -309,55 +309,55 @@ func RPCVerifySector(ctx context.Context, t TransportClient, prices rhp4.HostPri }, nil } -// RPCModifySectors modifies sectors on the host. -func RPCModifySectors(ctx context.Context, t TransportClient, cs consensus.State, prices rhp4.HostPrices, sk types.PrivateKey, contract ContractRevision, actions []rhp4.ModifyAction) (RPCModifySectorsResult, error) { - req := rhp4.RPCModifySectorsRequest{ +// RPCRemoveSectors modifies sectors on the host. +func RPCRemoveSectors(ctx context.Context, t TransportClient, cs consensus.State, prices rhp4.HostPrices, sk types.PrivateKey, contract ContractRevision, indices []uint64) (RPCRemoveSectorsResult, error) { + req := rhp4.RPCRemoveSectorsRequest{ ContractID: contract.ID, Prices: prices, - Actions: actions, + Indices: indices, } req.ChallengeSignature = sk.SignHash(req.ChallengeSigHash(contract.Revision.RevisionNumber + 1)) s := t.DialStream(ctx) defer s.Close() - if err := rhp4.WriteRequest(s, rhp4.RPCModifySectorsID, &req); err != nil { - return RPCModifySectorsResult{}, fmt.Errorf("failed to write request: %w", err) + if err := rhp4.WriteRequest(s, rhp4.RPCRemoveSectorsID, &req); err != nil { + return RPCRemoveSectorsResult{}, fmt.Errorf("failed to write request: %w", err) } - numSectors := (contract.Revision.Filesize + rhp4.SectorSize - 1) / rhp4.SectorSize - var resp rhp4.RPCModifySectorsResponse + // numSectors := (contract.Revision.Filesize + rhp4.SectorSize - 1) / rhp4.SectorSize + var resp rhp4.RPCRemoveSectorsResponse if err := rhp4.ReadResponse(s, &resp); err != nil { - return RPCModifySectorsResult{}, fmt.Errorf("failed to read response: %w", err) - } else if !rhp4.VerifyModifySectorsProof(actions, numSectors, resp.OldSubtreeHashes, resp.OldLeafHashes, contract.Revision.FileMerkleRoot, resp.NewMerkleRoot) { - return RPCModifySectorsResult{}, ErrInvalidProof - } + return RPCRemoveSectorsResult{}, fmt.Errorf("failed to read response: %w", err) + } /*else if !rhp4.VerifyModifySectorsProof(actions, numSectors, resp.OldSubtreeHashes, resp.OldLeafHashes, contract.Revision.FileMerkleRoot, resp.NewMerkleRoot) { + return RPCRemoveSectorsResult{}, ErrInvalidProof + }*/ // TODO: verify proof - revision, err := rhp4.ReviseForModifySectors(contract.Revision, prices, resp.NewMerkleRoot, actions) + revision, err := rhp4.ReviseForRemoveSectors(contract.Revision, prices, resp.NewMerkleRoot, len(indices)) if err != nil { - return RPCModifySectorsResult{}, fmt.Errorf("failed to revise contract: %w", err) + return RPCRemoveSectorsResult{}, fmt.Errorf("failed to revise contract: %w", err) } sigHash := cs.ContractSigHash(revision) revision.RenterSignature = sk.SignHash(sigHash) - signatureResp := rhp4.RPCModifySectorsSecondResponse{ + signatureResp := rhp4.RPCRemoveSectorsSecondResponse{ RenterSignature: revision.RenterSignature, } if err := rhp4.WriteResponse(s, &signatureResp); err != nil { - return RPCModifySectorsResult{}, fmt.Errorf("failed to write signature response: %w", err) + return RPCRemoveSectorsResult{}, fmt.Errorf("failed to write signature response: %w", err) } - var hostSignature rhp4.RPCModifySectorsThirdResponse + var hostSignature rhp4.RPCRemoveSectorsThirdResponse if err := rhp4.ReadResponse(s, &hostSignature); err != nil { - return RPCModifySectorsResult{}, fmt.Errorf("failed to read host signatures: %w", err) + return RPCRemoveSectorsResult{}, fmt.Errorf("failed to read host signatures: %w", err) } // validate the host signature if !contract.Revision.HostPublicKey.VerifyHash(sigHash, hostSignature.HostSignature) { - return RPCModifySectorsResult{}, rhp4.ErrInvalidSignature + return RPCRemoveSectorsResult{}, rhp4.ErrInvalidSignature } // return the signed revision - return RPCModifySectorsResult{ + return RPCRemoveSectorsResult{ Revision: revision, Cost: contract.Revision.RenterOutput.Value.Sub(revision.RenterOutput.Value), }, nil @@ -495,7 +495,7 @@ func RPCSectorRoots(ctx context.Context, t TransportClient, cs consensus.State, RenterSignature: revision.RenterSignature, } - if err := req.Validate(contract.Revision.HostPublicKey, revision); err != nil { + if err := req.Validate(contract.Revision.HostPublicKey, revision, length); err != nil { return RPCSectorRootsResult{}, fmt.Errorf("invalid request: %w", err) } diff --git a/rhp/v4/rpc_test.go b/rhp/v4/rpc_test.go index b126fc8..220fd2c 100644 --- a/rhp/v4/rpc_test.go +++ b/rhp/v4/rpc_test.go @@ -4,8 +4,10 @@ import ( "bytes" "context" "io" + "maps" "net" "reflect" + "slices" "strings" "sync" "testing" @@ -177,7 +179,7 @@ func TestSettings(t *testing.T) { MaxCollateral: types.Siacoins(10000), MaxContractDuration: 1000, MaxSectorDuration: 3 * 144, - MaxModifyActions: 100, + MaxSectorBatchSize: 100, RemainingStorage: 100 * proto4.SectorSize, TotalStorage: 100 * proto4.SectorSize, Prices: proto4.HostPrices{ @@ -238,7 +240,7 @@ func TestFormContract(t *testing.T) { MaxCollateral: types.Siacoins(10000), MaxContractDuration: 1000, MaxSectorDuration: 3 * 144, - MaxModifyActions: 100, + MaxSectorBatchSize: 100, RemainingStorage: 100 * proto4.SectorSize, TotalStorage: 100 * proto4.SectorSize, Prices: proto4.HostPrices{ @@ -298,7 +300,7 @@ func TestFormContractBasis(t *testing.T) { MaxCollateral: types.Siacoins(10000), MaxContractDuration: 1000, MaxSectorDuration: 3 * 144, - MaxModifyActions: 100, + MaxSectorBatchSize: 100, RemainingStorage: 100 * proto4.SectorSize, TotalStorage: 100 * proto4.SectorSize, Prices: proto4.HostPrices{ @@ -356,7 +358,7 @@ func TestRPCRefresh(t *testing.T) { MaxCollateral: types.Siacoins(10000), MaxContractDuration: 1000, MaxSectorDuration: 3 * 144, - MaxModifyActions: 100, + MaxSectorBatchSize: 100, RemainingStorage: 100 * proto4.SectorSize, TotalStorage: 100 * proto4.SectorSize, Prices: proto4.HostPrices{ @@ -469,7 +471,7 @@ func TestRPCRenew(t *testing.T) { MaxCollateral: types.Siacoins(10000), MaxContractDuration: 1000, MaxSectorDuration: 3 * 144, - MaxModifyActions: 100, + MaxSectorBatchSize: 100, RemainingStorage: 100 * proto4.SectorSize, TotalStorage: 100 * proto4.SectorSize, Prices: proto4.HostPrices{ @@ -631,7 +633,7 @@ func TestAccounts(t *testing.T) { MaxCollateral: types.Siacoins(10000), MaxContractDuration: 1000, MaxSectorDuration: 3 * 144, - MaxModifyActions: 100, + MaxSectorBatchSize: 100, RemainingStorage: 100 * proto4.SectorSize, TotalStorage: 100 * proto4.SectorSize, Prices: proto4.HostPrices{ @@ -733,7 +735,7 @@ func TestReadWriteSector(t *testing.T) { MaxCollateral: types.Siacoins(10000), MaxContractDuration: 1000, MaxSectorDuration: 3 * 144, - MaxModifyActions: 100, + MaxSectorBatchSize: 100, RemainingStorage: 100 * proto4.SectorSize, TotalStorage: 100 * proto4.SectorSize, Prices: proto4.HostPrices{ @@ -830,7 +832,7 @@ func TestAppendSectors(t *testing.T) { MaxCollateral: types.Siacoins(10000), MaxContractDuration: 1000, MaxSectorDuration: 3 * 144, - MaxModifyActions: 100, + MaxSectorBatchSize: 100, RemainingStorage: 100 * proto4.SectorSize, TotalStorage: 100 * proto4.SectorSize, Prices: proto4.HostPrices{ @@ -948,7 +950,7 @@ func TestVerifySector(t *testing.T) { MaxCollateral: types.Siacoins(10000), MaxContractDuration: 1000, MaxSectorDuration: 3 * 144, - MaxModifyActions: 100, + MaxSectorBatchSize: 100, RemainingStorage: 100 * proto4.SectorSize, TotalStorage: 100 * proto4.SectorSize, Prices: proto4.HostPrices{ @@ -1024,7 +1026,7 @@ func TestVerifySector(t *testing.T) { } } -func TestRPCModifySectors(t *testing.T) { +func TestRPCRemoveSectors(t *testing.T) { log := zaptest.NewLogger(t) n, genesis := testutil.V2Network() hostKey, renterKey := types.GeneratePrivateKey(), types.GeneratePrivateKey() @@ -1042,7 +1044,7 @@ func TestRPCModifySectors(t *testing.T) { MaxCollateral: types.Siacoins(10000), MaxContractDuration: 1000, MaxSectorDuration: 3 * 144, - MaxModifyActions: 100, + MaxSectorBatchSize: 100, RemainingStorage: 100 * proto4.SectorSize, TotalStorage: 100 * proto4.SectorSize, Prices: proto4.HostPrices{ @@ -1130,44 +1132,23 @@ func TestRPCModifySectors(t *testing.T) { assertRevision(t, appendResult.Revision, roots) revision.Revision = appendResult.Revision - // swap two random sectors - swapA, swapB := frand.Uint64n(uint64(len(roots)/2)), frand.Uint64n(uint64(len(roots)/2))+uint64(len(roots)/2) - actions := []proto4.ModifyAction{ - {Type: proto4.ActionSwap, A: swapA, B: swapB}, + // randomly remove half the sectors + indices := make(map[uint64]bool) + var newRoots []types.Hash256 + for len(indices) < len(roots)/2 { + i := frand.Uint64n(uint64(len(roots))) + indices[i] = true } - modifyResult, err := rhp4.RPCModifySectors(context.Background(), transport, cs, settings.Prices, renterKey, revision, actions) - if err != nil { - t.Fatal(err) - } - roots[swapA], roots[swapB] = roots[swapB], roots[swapA] - assertRevision(t, modifyResult.Revision, roots) - revision.Revision = modifyResult.Revision - - // delete the last 10 sectors - actions = []proto4.ModifyAction{ - {Type: proto4.ActionTrim, N: uint64(len(roots) / 2)}, - } - modifyResult, err = rhp4.RPCModifySectors(context.Background(), transport, cs, settings.Prices, renterKey, revision, actions) - if err != nil { - t.Fatal(err) - } - trimmed, roots := roots[len(roots)/2:], roots[:len(roots)/2] - assertRevision(t, modifyResult.Revision, roots) - revision.Revision = modifyResult.Revision - - // update a random sector with one of the trimmed sectors - updateIdx := frand.Intn(len(roots)) - trimmedIdx := frand.Intn(len(trimmed)) - actions = []proto4.ModifyAction{ - {Type: proto4.ActionUpdate, Root: trimmed[trimmedIdx], A: uint64(updateIdx)}, + for i, root := range roots { + if !indices[uint64(i)] { + newRoots = append(newRoots, root) + } } - - modifyResult, err = rhp4.RPCModifySectors(context.Background(), transport, cs, settings.Prices, renterKey, revision, actions) + removeResult, err := rhp4.RPCRemoveSectors(context.Background(), transport, cs, settings.Prices, renterKey, revision, slices.Collect(maps.Keys(indices))) if err != nil { t.Fatal(err) } - roots[updateIdx] = trimmed[trimmedIdx] - assertRevision(t, modifyResult.Revision, roots) + assertRevision(t, removeResult.Revision, newRoots) } func TestRPCSectorRoots(t *testing.T) { @@ -1188,7 +1169,7 @@ func TestRPCSectorRoots(t *testing.T) { MaxCollateral: types.Siacoins(10000), MaxContractDuration: 1000, MaxSectorDuration: 3 * 144, - MaxModifyActions: 100, + MaxSectorBatchSize: 100, RemainingStorage: 100 * proto4.SectorSize, TotalStorage: 100 * proto4.SectorSize, Prices: proto4.HostPrices{ @@ -1298,7 +1279,7 @@ func BenchmarkWrite(b *testing.B) { MaxCollateral: types.Siacoins(10000), MaxContractDuration: 1000, MaxSectorDuration: 3 * 144, - MaxModifyActions: 100, + MaxSectorBatchSize: 100, RemainingStorage: 100 * proto4.SectorSize, TotalStorage: 100 * proto4.SectorSize, Prices: proto4.HostPrices{ @@ -1388,7 +1369,7 @@ func BenchmarkRead(b *testing.B) { MaxCollateral: types.Siacoins(10000), MaxContractDuration: 1000, MaxSectorDuration: 3 * 144, - MaxModifyActions: 100, + MaxSectorBatchSize: 100, RemainingStorage: 100 * proto4.SectorSize, TotalStorage: 100 * proto4.SectorSize, Prices: proto4.HostPrices{ @@ -1490,7 +1471,7 @@ func BenchmarkContractUpload(b *testing.B) { MaxCollateral: types.Siacoins(10000), MaxContractDuration: 1000, MaxSectorDuration: 3 * 144, - MaxModifyActions: 100, + MaxSectorBatchSize: 100, RemainingStorage: 100 * proto4.SectorSize, TotalStorage: 100 * proto4.SectorSize, Prices: proto4.HostPrices{ diff --git a/rhp/v4/server.go b/rhp/v4/server.go index 9958840..adf7132 100644 --- a/rhp/v4/server.go +++ b/rhp/v4/server.go @@ -250,20 +250,12 @@ func (s *Server) handleRPCWriteSector(stream net.Conn) error { }) } -func (s *Server) handleRPCModifySectors(stream net.Conn) error { - var req rhp4.RPCModifySectorsRequest +func (s *Server) handleRPCRemoveSectors(stream net.Conn) error { + var req rhp4.RPCRemoveSectorsRequest if err := rhp4.ReadRequest(stream, &req); err != nil { return errorDecodingError("failed to read request: %v", err) } - settings := s.settings.RHP4Settings() - if err := req.Validate(s.hostKey.PublicKey(), settings.MaxModifyActions); err != nil { - return errorBadRequest("request invalid: %v", err) - } - prices := req.Prices - - cs := s.chain.TipState() - state, unlock, err := s.lockContractForRevision(req.ContractID) if err != nil { return fmt.Errorf("failed to lock contract: %w", err) @@ -275,53 +267,55 @@ func (s *Server) handleRPCModifySectors(stream net.Conn) error { } fc := state.Revision - cost := prices.RPCModifySectorsCost(req.Actions) + + settings := s.settings.RHP4Settings() + if err := req.Validate(s.hostKey.PublicKey(), fc, settings.MaxSectorBatchSize); err != nil { + return errorBadRequest("request invalid: %v", err) + } + prices := req.Prices + + cost := prices.RPCRemoveSectorsCost(len(req.Indices)) // validate the payment without modifying the contract if fc.RenterOutput.Value.Cmp(cost) < 0 { return rhp4.NewRPCError(rhp4.ErrorCodePayment, fmt.Sprintf("renter output value %v is less than cost %v", fc.RenterOutput.Value, cost)) } - roots := state.Roots - for _, action := range req.Actions { - switch action.Type { - case rhp4.ActionTrim: - if action.N > uint64(len(roots)) { - return errorBadRequest("trim count %v exceeds sector count %v", action.N, len(roots)) - } - roots = roots[:len(roots)-int(action.N)] - case rhp4.ActionUpdate: - if action.N >= uint64(len(roots)) { - return errorBadRequest("update index %v exceeds sector count %v", action.A, len(roots)) - } - roots[action.N] = action.Root - case rhp4.ActionSwap: - if action.A >= uint64(len(roots)) || action.B >= uint64(len(roots)) { - return errorBadRequest("swap indices %v and %v exceed sector count %v", action.A, action.B, len(roots)) - } - roots[action.A], roots[action.B] = roots[action.B], roots[action.A] - default: - return errorBadRequest("unknown action type %v", action.Type) + // validate that all indices are within the expected range + indices := make(map[uint64]bool) + for _, i := range req.Indices { + if i >= uint64(len(state.Roots)) { + return errorBadRequest("index %v exceeds sector count %v", i, len(state.Roots)) + } + indices[i] = true + } + + roots := state.Roots[:0] + for i, root := range state.Roots { + if indices[uint64(i)] { + continue } + roots = append(roots, root) } - treeHashes, leafHashes := rhp4.BuildModifySectorsProof(req.Actions, state.Roots) - resp := rhp4.RPCModifySectorsResponse{ - OldSubtreeHashes: treeHashes, - OldLeafHashes: leafHashes, - NewMerkleRoot: rhp4.MetaRoot(roots), + // treeHashes, leafHashes := rhp4.BuildModifySectorsProof(req.Actions, state.Roots) // TODO: build proof + resp := rhp4.RPCRemoveSectorsResponse{ + // OldSubtreeHashes: treeHashes, + // OldLeafHashes: leafHashes, + NewMerkleRoot: rhp4.MetaRoot(roots), } if err := rhp4.WriteResponse(stream, &resp); err != nil { return fmt.Errorf("failed to write response: %w", err) } - var renterSigResponse rhp4.RPCModifySectorsSecondResponse + var renterSigResponse rhp4.RPCRemoveSectorsSecondResponse if err := rhp4.ReadResponse(stream, &renterSigResponse); err != nil { return errorDecodingError("failed to read renter signature response: %v", err) } - revision, err := rhp4.ReviseForModifySectors(fc, prices, resp.NewMerkleRoot, req.Actions) + revision, err := rhp4.ReviseForRemoveSectors(fc, prices, resp.NewMerkleRoot, len(req.Indices)) if err != nil { return fmt.Errorf("failed to revise contract: %w", err) } + cs := s.chain.TipState() sigHash := cs.ContractSigHash(revision) if !fc.RenterPublicKey.VerifyHash(sigHash, renterSigResponse.RenterSignature) { @@ -336,7 +330,7 @@ func (s *Server) handleRPCModifySectors(stream net.Conn) error { if err != nil { return fmt.Errorf("failed to revise contract: %w", err) } - return rhp4.WriteResponse(stream, &rhp4.RPCModifySectorsThirdResponse{ + return rhp4.WriteResponse(stream, &rhp4.RPCRemoveSectorsThirdResponse{ HostSignature: revision.HostSignature, }) } @@ -348,7 +342,7 @@ func (s *Server) handleRPCAppendSectors(stream net.Conn) error { } settings := s.settings.RHP4Settings() - if err := req.Validate(s.hostKey.PublicKey(), settings.MaxModifyActions); err != nil { + if err := req.Validate(s.hostKey.PublicKey(), settings.MaxSectorBatchSize); err != nil { return errorBadRequest("request invalid: %v", err) } prices := req.Prices @@ -489,7 +483,8 @@ func (s *Server) handleRPCSectorRoots(stream net.Conn) error { defer unlock() // validate the request fields - if err := req.Validate(s.hostKey.PublicKey(), state.Revision); err != nil { + settings := s.settings.RHP4Settings() + if err := req.Validate(s.hostKey.PublicKey(), state.Revision, settings.MaxSectorBatchSize); err != nil { return rhp4.NewRPCError(rhp4.ErrorCodeBadRequest, err.Error()) } prices := req.Prices @@ -1055,8 +1050,8 @@ func (s *Server) handleHostStream(stream net.Conn, log *zap.Logger) { err = s.handleRPCRenewContract(stream) case rhp4.RPCLatestRevisionID: err = s.handleRPCLatestRevision(stream) - case rhp4.RPCModifySectorsID: - err = s.handleRPCModifySectors(stream) + case rhp4.RPCRemoveSectorsID: + err = s.handleRPCRemoveSectors(stream) case rhp4.RPCSectorRootsID: err = s.handleRPCSectorRoots(stream) // account From b81a3e55c474d55a4d36020bd813b99b1cb0df57 Mon Sep 17 00:00:00 2001 From: Nate Maninger Date: Mon, 21 Oct 2024 14:15:01 -0700 Subject: [PATCH 3/6] deps: upgrade core --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 615ca38..0cf957d 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ toolchain go1.23.2 require ( go.etcd.io/bbolt v1.3.11 - go.sia.tech/core v0.4.8-0.20241021201948-dfdf69e37844 + go.sia.tech/core v0.4.8-0.20241021210901-4715717758b8 go.sia.tech/mux v1.3.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.28.0 diff --git a/go.sum b/go.sum index 961800b..e6b9fe9 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,8 @@ github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKs github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= -go.sia.tech/core v0.4.8-0.20241021201948-dfdf69e37844 h1:rzFVA7X7QLKhmHSOnjQ0hAqPj/6f4Y5wItKhfngyBYo= -go.sia.tech/core v0.4.8-0.20241021201948-dfdf69e37844/go.mod h1:P3C1BWa/7J4XgdzWuaYHBvLo2RzZ0UBaJM4TG1GWB2g= +go.sia.tech/core v0.4.8-0.20241021210901-4715717758b8 h1:tC7Hikf/PdZNhX2tG5IOPkRCxpopV1FKfB49Rl7C8p8= +go.sia.tech/core v0.4.8-0.20241021210901-4715717758b8/go.mod h1:P3C1BWa/7J4XgdzWuaYHBvLo2RzZ0UBaJM4TG1GWB2g= go.sia.tech/mux v1.3.0 h1:hgR34IEkqvfBKUJkAzGi31OADeW2y7D6Bmy/Jcbop9c= go.sia.tech/mux v1.3.0/go.mod h1:I46++RD4beqA3cW9Xm9SwXbezwPqLvHhVs9HLpDtt58= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= From c14ef5197f7405f08f72d14d2b13c6644efbfc0b Mon Sep 17 00:00:00 2001 From: Nate Maninger Date: Mon, 21 Oct 2024 15:06:06 -0700 Subject: [PATCH 4/6] rhp4: use core usage --- go.mod | 2 +- go.sum | 6 ++- rhp/v4/rpc.go | 50 ++++++++++++------------- rhp/v4/rpc_test.go | 4 +- rhp/v4/server.go | 93 +++++++++++++++------------------------------- testutil/host.go | 14 +++---- 6 files changed, 68 insertions(+), 101 deletions(-) diff --git a/go.mod b/go.mod index 0cf957d..bf0e707 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ toolchain go1.23.2 require ( go.etcd.io/bbolt v1.3.11 - go.sia.tech/core v0.4.8-0.20241021210901-4715717758b8 + go.sia.tech/core v0.4.8-0.20241021215909-db1d712112bc go.sia.tech/mux v1.3.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.28.0 diff --git a/go.sum b/go.sum index e6b9fe9..91ba184 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,10 @@ github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKs github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= -go.sia.tech/core v0.4.8-0.20241021210901-4715717758b8 h1:tC7Hikf/PdZNhX2tG5IOPkRCxpopV1FKfB49Rl7C8p8= -go.sia.tech/core v0.4.8-0.20241021210901-4715717758b8/go.mod h1:P3C1BWa/7J4XgdzWuaYHBvLo2RzZ0UBaJM4TG1GWB2g= +go.sia.tech/core v0.4.8-0.20241021215433-54b5123bf569 h1:l8bExeZFNmH+fENB9F5buIeDRHJZSves1dfmFPOiFAM= +go.sia.tech/core v0.4.8-0.20241021215433-54b5123bf569/go.mod h1:P3C1BWa/7J4XgdzWuaYHBvLo2RzZ0UBaJM4TG1GWB2g= +go.sia.tech/core v0.4.8-0.20241021215909-db1d712112bc h1:SDqV2W2HWzlC/DcbWuBzo5Ro12s5az0L/g3otq/ItK4= +go.sia.tech/core v0.4.8-0.20241021215909-db1d712112bc/go.mod h1:P3C1BWa/7J4XgdzWuaYHBvLo2RzZ0UBaJM4TG1GWB2g= go.sia.tech/mux v1.3.0 h1:hgR34IEkqvfBKUJkAzGi31OADeW2y7D6Bmy/Jcbop9c= go.sia.tech/mux v1.3.0/go.mod h1:I46++RD4beqA3cW9Xm9SwXbezwPqLvHhVs9HLpDtt58= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= diff --git a/rhp/v4/rpc.go b/rhp/v4/rpc.go index d16c578..472a547 100644 --- a/rhp/v4/rpc.go +++ b/rhp/v4/rpc.go @@ -110,31 +110,31 @@ type ( // RPCWriteSectorResult contains the result of executing the write sector RPC. RPCWriteSectorResult struct { - Root types.Hash256 `json:"root"` - Cost types.Currency `json:"cost"` + Root types.Hash256 `json:"root"` + Usage rhp4.Usage `json:"usage"` } // RPCReadSectorResult contains the result of executing the read sector RPC. RPCReadSectorResult struct { - Cost types.Currency `json:"cost"` + Usage rhp4.Usage `json:"usage"` } // RPCVerifySectorResult contains the result of executing the verify sector RPC. RPCVerifySectorResult struct { - Cost types.Currency `json:"cost"` + Usage rhp4.Usage `json:"usage"` } // RPCRemoveSectorsResult contains the result of executing the remove sectors RPC. RPCRemoveSectorsResult struct { Revision types.V2FileContract `json:"revision"` - Cost types.Currency `json:"cost"` + Usage rhp4.Usage `json:"usage"` } // RPCAppendSectorsResult contains the result of executing the append sectors // RPC. RPCAppendSectorsResult struct { Revision types.V2FileContract `json:"revision"` - Cost types.Currency `json:"cost"` + Usage rhp4.Usage `json:"usage"` Sectors []types.Hash256 `json:"sectors"` } @@ -142,35 +142,35 @@ type ( RPCFundAccountResult struct { Revision types.V2FileContract `json:"revision"` Balances []AccountBalance `json:"balances"` - Cost types.Currency `json:"cost"` + Usage rhp4.Usage `json:"usage"` } // RPCSectorRootsResult contains the result of executing the sector roots RPC. RPCSectorRootsResult struct { Revision types.V2FileContract `json:"revision"` Roots []types.Hash256 `json:"roots"` - Cost types.Currency `json:"cost"` + Usage rhp4.Usage `json:"usage"` } // RPCFormContractResult contains the result of executing the form contract RPC. RPCFormContractResult struct { Contract ContractRevision `json:"contract"` FormationSet TransactionSet `json:"formationSet"` - Cost types.Currency `json:"cost"` + Cost types.Currency `json:"usage"` } // RPCRenewContractResult contains the result of executing the renew contract RPC. RPCRenewContractResult struct { Contract ContractRevision `json:"contract"` RenewalSet TransactionSet `json:"renewalSet"` - Cost types.Currency `json:"cost"` + Cost types.Currency `json:"usage"` } // RPCRefreshContractResult contains the result of executing the refresh contract RPC. RPCRefreshContractResult struct { Contract ContractRevision `json:"contract"` RenewalSet TransactionSet `json:"renewalSet"` - Cost types.Currency `json:"cost"` + Cost types.Currency `json:"usage"` } ) @@ -227,7 +227,7 @@ func RPCReadSector(ctx context.Context, t TransportClient, prices rhp4.HostPrice return RPCReadSectorResult{}, ErrInvalidProof } return RPCReadSectorResult{ - Cost: prices.RPCReadSectorCost(length), + Usage: prices.RPCReadSectorCost(length), }, nil } @@ -283,8 +283,8 @@ func RPCWriteSector(ctx context.Context, t TransportClient, prices rhp4.HostPric } return RPCWriteSectorResult{ - Root: resp.Root, - Cost: prices.RPCWriteSectorCost(uint64(length), duration), + Root: resp.Root, + Usage: prices.RPCWriteSectorCost(uint64(length), duration), }, nil } @@ -305,7 +305,7 @@ func RPCVerifySector(ctx context.Context, t TransportClient, prices rhp4.HostPri } return RPCVerifySectorResult{ - Cost: prices.RPCVerifySectorCost(), + Usage: prices.RPCVerifySectorCost(), }, nil } @@ -333,7 +333,7 @@ func RPCRemoveSectors(ctx context.Context, t TransportClient, cs consensus.State return RPCRemoveSectorsResult{}, ErrInvalidProof }*/ // TODO: verify proof - revision, err := rhp4.ReviseForRemoveSectors(contract.Revision, prices, resp.NewMerkleRoot, len(indices)) + revision, usage, err := rhp4.ReviseForRemoveSectors(contract.Revision, prices, resp.NewMerkleRoot, len(indices)) if err != nil { return RPCRemoveSectorsResult{}, fmt.Errorf("failed to revise contract: %w", err) } @@ -359,7 +359,7 @@ func RPCRemoveSectors(ctx context.Context, t TransportClient, cs consensus.State // return the signed revision return RPCRemoveSectorsResult{ Revision: revision, - Cost: contract.Revision.RenterOutput.Value.Sub(revision.RenterOutput.Value), + Usage: usage, }, nil } @@ -396,7 +396,7 @@ func RPCAppendSectors(ctx context.Context, t TransportClient, cs consensus.State return RPCAppendSectorsResult{}, ErrInvalidProof } - revision, err := rhp4.ReviseForAppendSectors(contract.Revision, prices, resp.NewMerkleRoot, uint64(len(appended))) + revision, usage, err := rhp4.ReviseForAppendSectors(contract.Revision, prices, resp.NewMerkleRoot, uint64(len(appended))) if err != nil { return RPCAppendSectorsResult{}, fmt.Errorf("failed to revise contract: %w", err) } @@ -418,7 +418,7 @@ func RPCAppendSectors(ctx context.Context, t TransportClient, cs consensus.State } return RPCAppendSectorsResult{ Revision: revision, - Cost: contract.Revision.RenterOutput.Value.Sub(revision.RenterOutput.Value), + Usage: usage, Sectors: appended, }, nil } @@ -429,7 +429,7 @@ func RPCFundAccounts(ctx context.Context, t TransportClient, cs consensus.State, for _, deposit := range deposits { total = total.Add(deposit.Amount) } - revision, err := rhp4.ReviseForFundAccount(contract.Revision, total) + revision, usage, err := rhp4.ReviseForFundAccounts(contract.Revision, total) if err != nil { return RPCFundAccountResult{}, fmt.Errorf("failed to revise contract: %w", err) } @@ -466,7 +466,7 @@ func RPCFundAccounts(ctx context.Context, t TransportClient, cs consensus.State, return RPCFundAccountResult{ Revision: revision, Balances: balances, - Cost: contract.Revision.RenterOutput.Value.Sub(revision.RenterOutput.Value), + Usage: usage, }, nil } @@ -480,7 +480,7 @@ func RPCLatestRevision(ctx context.Context, t TransportClient, contractID types. // RPCSectorRoots returns the sector roots for a contract. func RPCSectorRoots(ctx context.Context, t TransportClient, cs consensus.State, prices rhp4.HostPrices, signer ContractSigner, contract ContractRevision, offset, length uint64) (RPCSectorRootsResult, error) { - revision, err := rhp4.ReviseForSectorRoots(contract.Revision, prices, length) + revision, usage, err := rhp4.ReviseForSectorRoots(contract.Revision, prices, length) if err != nil { return RPCSectorRootsResult{}, fmt.Errorf("failed to revise contract: %w", err) } @@ -516,7 +516,7 @@ func RPCSectorRoots(ctx context.Context, t TransportClient, cs consensus.State, return RPCSectorRootsResult{ Revision: revision, Roots: resp.Roots, - Cost: contract.Revision.RenterOutput.Value.Sub(revision.RenterOutput.Value), + Usage: usage, }, nil } @@ -649,7 +649,7 @@ 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 := rhp4.RenewContract(existing, p, params) + renewal, _ := rhp4.RenewContract(existing, p, params) renewalTxn := types.V2Transaction{ MinerFee: tp.RecommendedFee().Mul64(1000), FileContractResolutions: []types.V2FileContractResolution{ @@ -776,7 +776,7 @@ func RPCRenewContract(ctx context.Context, t TransportClient, tp TxPool, signer // RPCRefreshContract refreshes a contract with a host. func RPCRefreshContract(ctx context.Context, t TransportClient, tp TxPool, signer FormContractSigner, cs consensus.State, p rhp4.HostPrices, existing types.V2FileContract, params rhp4.RPCRefreshContractParams) (RPCRefreshContractResult, error) { - renewal := rhp4.RefreshContract(existing, p, params) + renewal, _ := rhp4.RefreshContract(existing, p, params) renewalTxn := types.V2Transaction{ MinerFee: tp.RecommendedFee().Mul64(1000), FileContractResolutions: []types.V2FileContractResolution{ diff --git a/rhp/v4/rpc_test.go b/rhp/v4/rpc_test.go index 220fd2c..99ccead 100644 --- a/rhp/v4/rpc_test.go +++ b/rhp/v4/rpc_test.go @@ -689,8 +689,8 @@ func TestAccounts(t *testing.T) { t.Fatalf("expected %v, got %v", account, fundResult.Balances[0].Account) case fundResult.Balances[0].Balance != accountFundAmount: t.Fatalf("expected %v, got %v", accountFundAmount, fundResult.Balances[0].Balance) - case !fundResult.Cost.Equals(accountFundAmount): - t.Fatalf("expected %v, got %v", accountFundAmount, fundResult.Cost) + case !fundResult.Usage.RenterCost().Equals(accountFundAmount): + t.Fatalf("expected %v, got %v", accountFundAmount, fundResult.Usage.RenterCost()) case !revised.HostOutput.Value.Equals(hostOutputValue): t.Fatalf("expected %v, got %v", hostOutputValue, revised.HostOutput.Value) case !revised.RenterOutput.Value.Equals(renterOutputValue): diff --git a/rhp/v4/server.go b/rhp/v4/server.go index adf7132..35f8240 100644 --- a/rhp/v4/server.go +++ b/rhp/v4/server.go @@ -19,18 +19,6 @@ import ( var protocolVersion = [3]byte{4, 0, 0} -type ( - // Usage contains the revenue and risked collateral for a contract. - Usage struct { - RPCRevenue types.Currency `json:"rpc"` - StorageRevenue types.Currency `json:"storage"` - EgressRevenue types.Currency `json:"egress"` - IngressRevenue types.Currency `json:"ingress"` - AccountFunding types.Currency `json:"accountFunding"` - RiskedCollateral types.Currency `json:"riskedCollateral"` - } -) - type ( // A TransportMux is a generic multiplexer for incoming streams. TransportMux interface { @@ -110,12 +98,12 @@ type ( // The returned function must be called to release the lock. LockV2Contract(types.FileContractID) (RevisionState, func(), error) // AddV2Contract adds a new contract to the host. - AddV2Contract(TransactionSet, Usage) error + AddV2Contract(TransactionSet, rhp4.Usage) error // RenewV2Contract finalizes an existing contract and adds its renewal. - RenewV2Contract(TransactionSet, Usage) error + RenewV2Contract(TransactionSet, rhp4.Usage) error // ReviseV2Contract atomically revises a contract and updates its sector // roots and usage. - ReviseV2Contract(contractID types.FileContractID, revision types.V2FileContract, roots []types.Hash256, usage Usage) error + ReviseV2Contract(contractID types.FileContractID, revision types.V2FileContract, roots []types.Hash256, usage rhp4.Usage) error // V2FileContractElement returns the contract state element for the given // contract ID. V2FileContractElement(types.FileContractID) (types.ChainIndex, types.V2FileContractElement, error) @@ -123,9 +111,9 @@ type ( // AccountBalance returns the balance of an account. AccountBalance(rhp4.Account) (types.Currency, error) // CreditAccountsWithContract atomically revises a contract and credits the account. - CreditAccountsWithContract([]rhp4.AccountDeposit, types.FileContractID, types.V2FileContract) ([]types.Currency, error) + CreditAccountsWithContract([]rhp4.AccountDeposit, types.FileContractID, types.V2FileContract, rhp4.Usage) ([]types.Currency, error) // DebitAccount debits an account. - DebitAccount(rhp4.Account, types.Currency) error + DebitAccount(rhp4.Account, rhp4.Usage) error } // Settings reports the host's current settings. @@ -192,7 +180,8 @@ func (s *Server) handleRPCReadSector(stream net.Conn) error { return rhp4.ErrSectorNotFound } - if err := s.contractor.DebitAccount(token.Account, prices.RPCReadSectorCost(req.Length)); err != nil { + err := s.contractor.DebitAccount(token.Account, prices.RPCReadSectorCost(req.Length)) + if err != nil { return fmt.Errorf("failed to debit account: %w", err) } @@ -237,8 +226,8 @@ func (s *Server) handleRPCWriteSector(stream net.Conn) error { return errorDecodingError("failed to read sector data: %v", err) } - cost := prices.RPCWriteSectorCost(req.DataLength, req.Duration) - if err := s.contractor.DebitAccount(req.Token.Account, cost); err != nil { + usage := prices.RPCWriteSectorCost(req.DataLength, req.Duration) + if err = s.contractor.DebitAccount(req.Token.Account, usage); err != nil { return fmt.Errorf("failed to debit account: %w", err) } @@ -274,12 +263,6 @@ func (s *Server) handleRPCRemoveSectors(stream net.Conn) error { } prices := req.Prices - cost := prices.RPCRemoveSectorsCost(len(req.Indices)) - // validate the payment without modifying the contract - if fc.RenterOutput.Value.Cmp(cost) < 0 { - return rhp4.NewRPCError(rhp4.ErrorCodePayment, fmt.Sprintf("renter output value %v is less than cost %v", fc.RenterOutput.Value, cost)) - } - // validate that all indices are within the expected range indices := make(map[uint64]bool) for _, i := range req.Indices { @@ -311,7 +294,7 @@ func (s *Server) handleRPCRemoveSectors(stream net.Conn) error { return errorDecodingError("failed to read renter signature response: %v", err) } - revision, err := rhp4.ReviseForRemoveSectors(fc, prices, resp.NewMerkleRoot, len(req.Indices)) + revision, usage, err := rhp4.ReviseForRemoveSectors(fc, prices, resp.NewMerkleRoot, len(req.Indices)) if err != nil { return fmt.Errorf("failed to revise contract: %w", err) } @@ -324,9 +307,7 @@ func (s *Server) handleRPCRemoveSectors(stream net.Conn) error { revision.RenterSignature = renterSigResponse.RenterSignature revision.HostSignature = s.hostKey.SignHash(sigHash) - err = s.contractor.ReviseV2Contract(req.ContractID, revision, roots, Usage{ - StorageRevenue: cost, - }) + err = s.contractor.ReviseV2Contract(req.ContractID, revision, roots, usage) if err != nil { return fmt.Errorf("failed to revise contract: %w", err) } @@ -345,7 +326,6 @@ func (s *Server) handleRPCAppendSectors(stream net.Conn) error { if err := req.Validate(s.hostKey.PublicKey(), settings.MaxSectorBatchSize); err != nil { return errorBadRequest("request invalid: %v", err) } - prices := req.Prices cs := s.chain.TipState() @@ -384,7 +364,7 @@ func (s *Server) handleRPCAppendSectors(stream net.Conn) error { return fmt.Errorf("failed to write response: %w", err) } - revision, err := rhp4.ReviseForAppendSectors(fc, req.Prices, newRoot, appended) + revision, usage, err := rhp4.ReviseForAppendSectors(fc, req.Prices, newRoot, appended) if err != nil { return fmt.Errorf("failed to revise contract: %w", err) } @@ -400,11 +380,7 @@ func (s *Server) handleRPCAppendSectors(stream net.Conn) error { revision.RenterSignature = renterSigResponse.RenterSignature revision.HostSignature = s.hostKey.SignHash(sigHash) - cost, collateral := req.Prices.RPCAppendSectorsCost(appended, fc.ExpirationHeight-prices.TipHeight) - err = s.contractor.ReviseV2Contract(req.ContractID, revision, roots, Usage{ - StorageRevenue: cost, - RiskedCollateral: collateral, - }) + err = s.contractor.ReviseV2Contract(req.ContractID, revision, roots, usage) if err != nil { return fmt.Errorf("failed to revise contract: %w", err) } @@ -430,26 +406,25 @@ func (s *Server) handleRPCFundAccounts(stream net.Conn) error { totalDeposits = totalDeposits.Add(deposit.Amount) } - fc := state.Revision - if err := rhp4.PayWithContract(&fc, totalDeposits, types.ZeroCurrency); err != nil { - return fmt.Errorf("failed to pay with contract: %w", err) + revision, usage, err := rhp4.ReviseForFundAccounts(state.Revision, totalDeposits) + if err != nil { + return fmt.Errorf("failed to revise contract: %w", err) } - sigHash := s.chain.TipState().ContractSigHash(fc) - if !fc.RenterPublicKey.VerifyHash(sigHash, req.RenterSignature) { + sigHash := s.chain.TipState().ContractSigHash(revision) + if !revision.RenterPublicKey.VerifyHash(sigHash, req.RenterSignature) { return rhp4.ErrInvalidSignature } + revision.HostSignature = s.hostKey.SignHash(sigHash) - fc.HostSignature = s.hostKey.SignHash(sigHash) - - balances, err := s.contractor.CreditAccountsWithContract(req.Deposits, req.ContractID, fc) + balances, err := s.contractor.CreditAccountsWithContract(req.Deposits, req.ContractID, revision, usage) if err != nil { return fmt.Errorf("failed to credit account: %w", err) } return rhp4.WriteResponse(stream, &rhp4.RPCFundAccountsResponse{ Balances: balances, - HostSignature: fc.HostSignature, + HostSignature: revision.HostSignature, }) } @@ -490,7 +465,7 @@ func (s *Server) handleRPCSectorRoots(stream net.Conn) error { prices := req.Prices // update the revision - revision, err := rhp4.ReviseForSectorRoots(state.Revision, prices, req.Length) + revision, usage, err := rhp4.ReviseForSectorRoots(state.Revision, prices, req.Length) if err != nil { return fmt.Errorf("failed to revise contract: %w", err) } @@ -506,9 +481,7 @@ func (s *Server) handleRPCSectorRoots(stream net.Conn) error { revision.HostSignature = s.hostKey.SignHash(sigHash) // update the contract - err = s.contractor.ReviseV2Contract(req.ContractID, revision, state.Roots, Usage{ - EgressRevenue: prices.RPCSectorRootsCost(req.Length), - }) + err = s.contractor.ReviseV2Contract(req.ContractID, revision, state.Roots, usage) if err != nil { return fmt.Errorf("failed to revise contract: %w", err) } @@ -656,8 +629,8 @@ func (s *Server) handleRPCFormContract(stream net.Conn) error { err = s.contractor.AddV2Contract(TransactionSet{ Transactions: formationSet, Basis: basis, - }, Usage{ - RPCRevenue: settings.Prices.ContractPrice, + }, rhp4.Usage{ + RPC: settings.Prices.ContractPrice, }) if err != nil { return fmt.Errorf("failed to add contract: %w", err) @@ -702,7 +675,7 @@ func (s *Server) handleRPCRefreshContract(stream net.Conn) error { } cs := s.chain.TipState() - renewal := rhp4.RefreshContract(existing, prices, req.Refresh) + renewal, usage := rhp4.RefreshContract(existing, prices, req.Refresh) renterCost, hostCost := rhp4.RefreshCost(cs, prices, renewal, req.MinerFee) renewalTxn := types.V2Transaction{ MinerFee: req.MinerFee, @@ -818,11 +791,7 @@ func (s *Server) handleRPCRefreshContract(stream net.Conn) error { err = s.contractor.RenewV2Contract(TransactionSet{ Transactions: renewalSet, Basis: basis, - }, Usage{ - RPCRevenue: prices.ContractPrice, - StorageRevenue: renewal.NewContract.HostOutput.Value.Sub(renewal.NewContract.TotalCollateral).Sub(prices.ContractPrice), - RiskedCollateral: renewal.NewContract.TotalCollateral.Sub(renewal.NewContract.MissedHostValue), - }) + }, usage) if err != nil { return fmt.Errorf("failed to add contract: %w", err) } @@ -868,7 +837,7 @@ func (s *Server) handleRPCRenewContract(stream net.Conn) error { } cs := s.chain.TipState() - renewal := rhp4.RenewContract(existing, prices, req.Renewal) + renewal, usage := rhp4.RenewContract(existing, prices, req.Renewal) renterCost, hostCost := rhp4.RenewalCost(cs, prices, renewal, req.MinerFee) renewalTxn := types.V2Transaction{ MinerFee: req.MinerFee, @@ -984,11 +953,7 @@ func (s *Server) handleRPCRenewContract(stream net.Conn) error { err = s.contractor.RenewV2Contract(TransactionSet{ Transactions: renewalSet, Basis: basis, - }, Usage{ - RPCRevenue: prices.ContractPrice, - StorageRevenue: renewal.NewContract.HostOutput.Value.Sub(renewal.NewContract.TotalCollateral).Sub(prices.ContractPrice), - RiskedCollateral: renewal.NewContract.TotalCollateral.Sub(renewal.NewContract.MissedHostValue), - }) + }, usage) if err != nil { return fmt.Errorf("failed to add contract: %w", err) } diff --git a/testutil/host.go b/testutil/host.go index 249c384..5e9c6d3 100644 --- a/testutil/host.go +++ b/testutil/host.go @@ -106,7 +106,7 @@ func (ec *EphemeralContractor) LockV2Contract(contractID types.FileContractID) ( } // AddV2Contract adds a new contract to the host. -func (ec *EphemeralContractor) AddV2Contract(formationSet rhp4.TransactionSet, _ rhp4.Usage) error { +func (ec *EphemeralContractor) AddV2Contract(formationSet rhp4.TransactionSet, _ proto4.Usage) error { ec.mu.Lock() defer ec.mu.Unlock() @@ -130,7 +130,7 @@ func (ec *EphemeralContractor) AddV2Contract(formationSet rhp4.TransactionSet, _ // RenewV2Contract finalizes an existing contract and adds the renewed contract // to the host. The existing contract must be locked before calling this method. -func (ec *EphemeralContractor) RenewV2Contract(renewalSet rhp4.TransactionSet, _ rhp4.Usage) error { +func (ec *EphemeralContractor) RenewV2Contract(renewalSet rhp4.TransactionSet, _ proto4.Usage) error { ec.mu.Lock() defer ec.mu.Unlock() @@ -168,7 +168,7 @@ func (ec *EphemeralContractor) RenewV2Contract(renewalSet rhp4.TransactionSet, _ // ReviseV2Contract atomically revises a contract and updates its sector roots // and usage. -func (ec *EphemeralContractor) ReviseV2Contract(contractID types.FileContractID, revision types.V2FileContract, roots []types.Hash256, _ rhp4.Usage) error { +func (ec *EphemeralContractor) ReviseV2Contract(contractID types.FileContractID, revision types.V2FileContract, roots []types.Hash256, _ proto4.Usage) error { ec.mu.Lock() defer ec.mu.Unlock() @@ -198,7 +198,7 @@ func (ec *EphemeralContractor) AccountBalance(account proto4.Account) (types.Cur // CreditAccountsWithContract credits accounts with the given deposits and // revises the contract revision. The contract must be locked before calling // this method. -func (ec *EphemeralContractor) CreditAccountsWithContract(deposits []proto4.AccountDeposit, contractID types.FileContractID, revision types.V2FileContract) ([]types.Currency, error) { +func (ec *EphemeralContractor) CreditAccountsWithContract(deposits []proto4.AccountDeposit, contractID types.FileContractID, revision types.V2FileContract, _ proto4.Usage) ([]types.Currency, error) { ec.mu.Lock() defer ec.mu.Unlock() @@ -212,17 +212,17 @@ func (ec *EphemeralContractor) CreditAccountsWithContract(deposits []proto4.Acco } // DebitAccount debits an account by the given amount. -func (ec *EphemeralContractor) DebitAccount(account proto4.Account, amount types.Currency) error { +func (ec *EphemeralContractor) DebitAccount(account proto4.Account, usage proto4.Usage) error { ec.mu.Lock() defer ec.mu.Unlock() balance, ok := ec.accounts[account] if !ok { return errors.New("account not found") - } else if balance.Cmp(amount) < 0 { + } else if balance.Cmp(usage.RenterCost()) < 0 { return errors.New("insufficient funds") } - ec.accounts[account] = balance.Sub(amount) + ec.accounts[account] = balance.Sub(usage.RenterCost()) return nil } From 37ab2f53d9b146990bd41b886eccf265ac33982c Mon Sep 17 00:00:00 2001 From: Nate Maninger Date: Mon, 21 Oct 2024 15:09:20 -0700 Subject: [PATCH 5/6] rhp4: add usage to form contract --- go.mod | 2 +- go.sum | 2 ++ rhp/v4/rpc.go | 24 +++++++++++++++--------- rhp/v4/server.go | 7 +++---- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index bf0e707..c0c2851 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ toolchain go1.23.2 require ( go.etcd.io/bbolt v1.3.11 - go.sia.tech/core v0.4.8-0.20241021215909-db1d712112bc + go.sia.tech/core v0.4.8-0.20241021220756-063922806c77 go.sia.tech/mux v1.3.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.28.0 diff --git a/go.sum b/go.sum index 91ba184..d57cb04 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,8 @@ go.sia.tech/core v0.4.8-0.20241021215433-54b5123bf569 h1:l8bExeZFNmH+fENB9F5buIe go.sia.tech/core v0.4.8-0.20241021215433-54b5123bf569/go.mod h1:P3C1BWa/7J4XgdzWuaYHBvLo2RzZ0UBaJM4TG1GWB2g= go.sia.tech/core v0.4.8-0.20241021215909-db1d712112bc h1:SDqV2W2HWzlC/DcbWuBzo5Ro12s5az0L/g3otq/ItK4= go.sia.tech/core v0.4.8-0.20241021215909-db1d712112bc/go.mod h1:P3C1BWa/7J4XgdzWuaYHBvLo2RzZ0UBaJM4TG1GWB2g= +go.sia.tech/core v0.4.8-0.20241021220756-063922806c77 h1:8Ynvew8X7nBxByE+/S/yxyPj+77urhvWCUQUgThvZ+0= +go.sia.tech/core v0.4.8-0.20241021220756-063922806c77/go.mod h1:P3C1BWa/7J4XgdzWuaYHBvLo2RzZ0UBaJM4TG1GWB2g= go.sia.tech/mux v1.3.0 h1:hgR34IEkqvfBKUJkAzGi31OADeW2y7D6Bmy/Jcbop9c= go.sia.tech/mux v1.3.0/go.mod h1:I46++RD4beqA3cW9Xm9SwXbezwPqLvHhVs9HLpDtt58= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= diff --git a/rhp/v4/rpc.go b/rhp/v4/rpc.go index 472a547..cc51658 100644 --- a/rhp/v4/rpc.go +++ b/rhp/v4/rpc.go @@ -156,21 +156,24 @@ type ( RPCFormContractResult struct { Contract ContractRevision `json:"contract"` FormationSet TransactionSet `json:"formationSet"` - Cost types.Currency `json:"usage"` + Cost types.Currency `json:"cost"` + Usage rhp4.Usage `json:"usage"` } // RPCRenewContractResult contains the result of executing the renew contract RPC. RPCRenewContractResult struct { Contract ContractRevision `json:"contract"` RenewalSet TransactionSet `json:"renewalSet"` - Cost types.Currency `json:"usage"` + Cost types.Currency `json:"cost"` + Usage rhp4.Usage `json:"usage"` } // RPCRefreshContractResult contains the result of executing the refresh contract RPC. RPCRefreshContractResult struct { Contract ContractRevision `json:"contract"` RenewalSet TransactionSet `json:"renewalSet"` - Cost types.Currency `json:"usage"` + Cost types.Currency `json:"cost"` + Usage rhp4.Usage `json:"usage"` } ) @@ -530,7 +533,7 @@ func RPCAccountBalance(ctx context.Context, t TransportClient, account rhp4.Acco // RPCFormContract forms a contract with a host func RPCFormContract(ctx context.Context, t TransportClient, tp TxPool, signer FormContractSigner, cs consensus.State, p rhp4.HostPrices, hostKey types.PublicKey, hostAddress types.Address, params rhp4.RPCFormContractParams) (RPCFormContractResult, error) { - fc := rhp4.NewContract(p, params, hostKey, hostAddress) + fc, usage := rhp4.NewContract(p, params, hostKey, hostAddress) formationTxn := types.V2Transaction{ MinerFee: tp.RecommendedFee().Mul64(1000), FileContracts: []types.V2FileContract{fc}, @@ -643,13 +646,14 @@ func RPCFormContract(ctx context.Context, t TransportClient, tp TxPool, signer F Basis: hostTransactionSetResp.Basis, Transactions: hostTransactionSetResp.TransactionSet, }, - Cost: renterCost, + Cost: renterCost, + Usage: usage, }, nil } // 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, _ := rhp4.RenewContract(existing, p, params) + renewal, usage := rhp4.RenewContract(existing, p, params) renewalTxn := types.V2Transaction{ MinerFee: tp.RecommendedFee().Mul64(1000), FileContractResolutions: []types.V2FileContractResolution{ @@ -770,13 +774,14 @@ func RPCRenewContract(ctx context.Context, t TransportClient, tp TxPool, signer Basis: hostTransactionSetResp.Basis, Transactions: hostTransactionSetResp.TransactionSet, }, - Cost: renterCost, + Cost: renterCost, + Usage: usage, }, nil } // RPCRefreshContract refreshes a contract with a host. func RPCRefreshContract(ctx context.Context, t TransportClient, tp TxPool, signer FormContractSigner, cs consensus.State, p rhp4.HostPrices, existing types.V2FileContract, params rhp4.RPCRefreshContractParams) (RPCRefreshContractResult, error) { - renewal, _ := rhp4.RefreshContract(existing, p, params) + renewal, usage := rhp4.RefreshContract(existing, p, params) renewalTxn := types.V2Transaction{ MinerFee: tp.RecommendedFee().Mul64(1000), FileContractResolutions: []types.V2FileContractResolution{ @@ -898,6 +903,7 @@ func RPCRefreshContract(ctx context.Context, t TransportClient, tp TxPool, signe Basis: hostTransactionSetResp.Basis, Transactions: hostTransactionSetResp.TransactionSet, }, - Cost: renterCost, + Cost: renterCost, + Usage: usage, }, nil } diff --git a/rhp/v4/server.go b/rhp/v4/server.go index 35f8240..d693131 100644 --- a/rhp/v4/server.go +++ b/rhp/v4/server.go @@ -527,9 +527,10 @@ func (s *Server) handleRPCFormContract(stream net.Conn) error { } prices := req.Prices + fc, usage := rhp4.NewContract(prices, req.Contract, ourKey, settings.WalletAddress) formationTxn := types.V2Transaction{ MinerFee: req.MinerFee, - FileContracts: []types.V2FileContract{rhp4.NewContract(prices, req.Contract, ourKey, settings.WalletAddress)}, + FileContracts: []types.V2FileContract{fc}, } // calculate the renter inputs @@ -629,9 +630,7 @@ func (s *Server) handleRPCFormContract(stream net.Conn) error { err = s.contractor.AddV2Contract(TransactionSet{ Transactions: formationSet, Basis: basis, - }, rhp4.Usage{ - RPC: settings.Prices.ContractPrice, - }) + }, usage) if err != nil { return fmt.Errorf("failed to add contract: %w", err) } From d816b0aa7f0459a2c8868afe91434da52718fbfc Mon Sep 17 00:00:00 2001 From: Nate Maninger Date: Tue, 22 Oct 2024 09:08:18 -0700 Subject: [PATCH 6/6] rhp4: RPC remove -> RPC free --- go.mod | 2 +- go.sum | 8 ++------ rhp/v4/rpc.go | 44 +++++++++++++++++++++----------------------- rhp/v4/rpc_test.go | 4 ++-- rhp/v4/server.go | 20 +++++++++----------- 5 files changed, 35 insertions(+), 43 deletions(-) diff --git a/go.mod b/go.mod index c0c2851..d1b30ea 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ toolchain go1.23.2 require ( go.etcd.io/bbolt v1.3.11 - go.sia.tech/core v0.4.8-0.20241021220756-063922806c77 + go.sia.tech/core v0.4.8-0.20241022155418-2652ab2ba1cf go.sia.tech/mux v1.3.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.28.0 diff --git a/go.sum b/go.sum index d57cb04..24dd4fd 100644 --- a/go.sum +++ b/go.sum @@ -6,12 +6,8 @@ github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKs github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= -go.sia.tech/core v0.4.8-0.20241021215433-54b5123bf569 h1:l8bExeZFNmH+fENB9F5buIeDRHJZSves1dfmFPOiFAM= -go.sia.tech/core v0.4.8-0.20241021215433-54b5123bf569/go.mod h1:P3C1BWa/7J4XgdzWuaYHBvLo2RzZ0UBaJM4TG1GWB2g= -go.sia.tech/core v0.4.8-0.20241021215909-db1d712112bc h1:SDqV2W2HWzlC/DcbWuBzo5Ro12s5az0L/g3otq/ItK4= -go.sia.tech/core v0.4.8-0.20241021215909-db1d712112bc/go.mod h1:P3C1BWa/7J4XgdzWuaYHBvLo2RzZ0UBaJM4TG1GWB2g= -go.sia.tech/core v0.4.8-0.20241021220756-063922806c77 h1:8Ynvew8X7nBxByE+/S/yxyPj+77urhvWCUQUgThvZ+0= -go.sia.tech/core v0.4.8-0.20241021220756-063922806c77/go.mod h1:P3C1BWa/7J4XgdzWuaYHBvLo2RzZ0UBaJM4TG1GWB2g= +go.sia.tech/core v0.4.8-0.20241022155418-2652ab2ba1cf h1:JxSZc/0Ij4zfrTAzjO5BGPExXs4z8QgOXZpgPyi95l8= +go.sia.tech/core v0.4.8-0.20241022155418-2652ab2ba1cf/go.mod h1:P3C1BWa/7J4XgdzWuaYHBvLo2RzZ0UBaJM4TG1GWB2g= go.sia.tech/mux v1.3.0 h1:hgR34IEkqvfBKUJkAzGi31OADeW2y7D6Bmy/Jcbop9c= go.sia.tech/mux v1.3.0/go.mod h1:I46++RD4beqA3cW9Xm9SwXbezwPqLvHhVs9HLpDtt58= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= diff --git a/rhp/v4/rpc.go b/rhp/v4/rpc.go index cc51658..e3ec8d0 100644 --- a/rhp/v4/rpc.go +++ b/rhp/v4/rpc.go @@ -124,8 +124,8 @@ type ( Usage rhp4.Usage `json:"usage"` } - // RPCRemoveSectorsResult contains the result of executing the remove sectors RPC. - RPCRemoveSectorsResult struct { + // RPCFreeSectorsResult contains the result of executing the remove sectors RPC. + RPCFreeSectorsResult struct { Revision types.V2FileContract `json:"revision"` Usage rhp4.Usage `json:"usage"` } @@ -224,10 +224,10 @@ func RPCReadSector(ctx context.Context, t TransportClient, prices rhp4.HostPrice rpv := rhp4.NewRangeProofVerifier(offset, length) if n, err := rpv.ReadFrom(io.TeeReader(io.LimitReader(s, int64(resp.DataLength)), w)); err != nil { return RPCReadSectorResult{}, fmt.Errorf("failed to read data: %w", err) - } else if n != int64(resp.DataLength) { - return RPCReadSectorResult{}, io.ErrUnexpectedEOF } else if !rpv.Verify(resp.Proof, root) { return RPCReadSectorResult{}, ErrInvalidProof + } else if n != int64(resp.DataLength) { + return RPCReadSectorResult{}, io.ErrUnexpectedEOF } return RPCReadSectorResult{ Usage: prices.RPCReadSectorCost(length), @@ -312,9 +312,9 @@ func RPCVerifySector(ctx context.Context, t TransportClient, prices rhp4.HostPri }, nil } -// RPCRemoveSectors modifies sectors on the host. -func RPCRemoveSectors(ctx context.Context, t TransportClient, cs consensus.State, prices rhp4.HostPrices, sk types.PrivateKey, contract ContractRevision, indices []uint64) (RPCRemoveSectorsResult, error) { - req := rhp4.RPCRemoveSectorsRequest{ +// RPCFreeSectors removes sectors from a contract. +func RPCFreeSectors(ctx context.Context, t TransportClient, cs consensus.State, prices rhp4.HostPrices, sk types.PrivateKey, contract ContractRevision, indices []uint64) (RPCFreeSectorsResult, error) { + req := rhp4.RPCFreeSectorsRequest{ ContractID: contract.ID, Prices: prices, Indices: indices, @@ -324,43 +324,41 @@ func RPCRemoveSectors(ctx context.Context, t TransportClient, cs consensus.State s := t.DialStream(ctx) defer s.Close() - if err := rhp4.WriteRequest(s, rhp4.RPCRemoveSectorsID, &req); err != nil { - return RPCRemoveSectorsResult{}, fmt.Errorf("failed to write request: %w", err) + if err := rhp4.WriteRequest(s, rhp4.RPCFreeSectorsID, &req); err != nil { + return RPCFreeSectorsResult{}, fmt.Errorf("failed to write request: %w", err) } - // numSectors := (contract.Revision.Filesize + rhp4.SectorSize - 1) / rhp4.SectorSize - var resp rhp4.RPCRemoveSectorsResponse + var resp rhp4.RPCFreeSectorsResponse if err := rhp4.ReadResponse(s, &resp); err != nil { - return RPCRemoveSectorsResult{}, fmt.Errorf("failed to read response: %w", err) - } /*else if !rhp4.VerifyModifySectorsProof(actions, numSectors, resp.OldSubtreeHashes, resp.OldLeafHashes, contract.Revision.FileMerkleRoot, resp.NewMerkleRoot) { - return RPCRemoveSectorsResult{}, ErrInvalidProof - }*/ // TODO: verify proof + return RPCFreeSectorsResult{}, fmt.Errorf("failed to read response: %w", err) + } + // TODO: verify proof - revision, usage, err := rhp4.ReviseForRemoveSectors(contract.Revision, prices, resp.NewMerkleRoot, len(indices)) + revision, usage, err := rhp4.ReviseForFreeSectors(contract.Revision, prices, resp.NewMerkleRoot, len(indices)) if err != nil { - return RPCRemoveSectorsResult{}, fmt.Errorf("failed to revise contract: %w", err) + return RPCFreeSectorsResult{}, fmt.Errorf("failed to revise contract: %w", err) } sigHash := cs.ContractSigHash(revision) revision.RenterSignature = sk.SignHash(sigHash) - signatureResp := rhp4.RPCRemoveSectorsSecondResponse{ + signatureResp := rhp4.RPCFreeSectorsSecondResponse{ RenterSignature: revision.RenterSignature, } if err := rhp4.WriteResponse(s, &signatureResp); err != nil { - return RPCRemoveSectorsResult{}, fmt.Errorf("failed to write signature response: %w", err) + return RPCFreeSectorsResult{}, fmt.Errorf("failed to write signature response: %w", err) } - var hostSignature rhp4.RPCRemoveSectorsThirdResponse + var hostSignature rhp4.RPCFreeSectorsThirdResponse if err := rhp4.ReadResponse(s, &hostSignature); err != nil { - return RPCRemoveSectorsResult{}, fmt.Errorf("failed to read host signatures: %w", err) + return RPCFreeSectorsResult{}, fmt.Errorf("failed to read host signatures: %w", err) } // validate the host signature if !contract.Revision.HostPublicKey.VerifyHash(sigHash, hostSignature.HostSignature) { - return RPCRemoveSectorsResult{}, rhp4.ErrInvalidSignature + return RPCFreeSectorsResult{}, rhp4.ErrInvalidSignature } // return the signed revision - return RPCRemoveSectorsResult{ + return RPCFreeSectorsResult{ Revision: revision, Usage: usage, }, nil diff --git a/rhp/v4/rpc_test.go b/rhp/v4/rpc_test.go index 99ccead..acf9e27 100644 --- a/rhp/v4/rpc_test.go +++ b/rhp/v4/rpc_test.go @@ -1026,7 +1026,7 @@ func TestVerifySector(t *testing.T) { } } -func TestRPCRemoveSectors(t *testing.T) { +func TestRPCFreeSectors(t *testing.T) { log := zaptest.NewLogger(t) n, genesis := testutil.V2Network() hostKey, renterKey := types.GeneratePrivateKey(), types.GeneratePrivateKey() @@ -1144,7 +1144,7 @@ func TestRPCRemoveSectors(t *testing.T) { newRoots = append(newRoots, root) } } - removeResult, err := rhp4.RPCRemoveSectors(context.Background(), transport, cs, settings.Prices, renterKey, revision, slices.Collect(maps.Keys(indices))) + removeResult, err := rhp4.RPCFreeSectors(context.Background(), transport, cs, settings.Prices, renterKey, revision, slices.Collect(maps.Keys(indices))) if err != nil { t.Fatal(err) } diff --git a/rhp/v4/server.go b/rhp/v4/server.go index d693131..dc4ac26 100644 --- a/rhp/v4/server.go +++ b/rhp/v4/server.go @@ -239,8 +239,8 @@ func (s *Server) handleRPCWriteSector(stream net.Conn) error { }) } -func (s *Server) handleRPCRemoveSectors(stream net.Conn) error { - var req rhp4.RPCRemoveSectorsRequest +func (s *Server) handleRPCFreeSectors(stream net.Conn) error { + var req rhp4.RPCFreeSectorsRequest if err := rhp4.ReadRequest(stream, &req); err != nil { return errorDecodingError("failed to read request: %v", err) } @@ -280,21 +280,19 @@ func (s *Server) handleRPCRemoveSectors(stream net.Conn) error { roots = append(roots, root) } - // treeHashes, leafHashes := rhp4.BuildModifySectorsProof(req.Actions, state.Roots) // TODO: build proof - resp := rhp4.RPCRemoveSectorsResponse{ - // OldSubtreeHashes: treeHashes, - // OldLeafHashes: leafHashes, + // TODO: build proof + resp := rhp4.RPCFreeSectorsResponse{ NewMerkleRoot: rhp4.MetaRoot(roots), } if err := rhp4.WriteResponse(stream, &resp); err != nil { return fmt.Errorf("failed to write response: %w", err) } - var renterSigResponse rhp4.RPCRemoveSectorsSecondResponse + var renterSigResponse rhp4.RPCFreeSectorsSecondResponse if err := rhp4.ReadResponse(stream, &renterSigResponse); err != nil { return errorDecodingError("failed to read renter signature response: %v", err) } - revision, usage, err := rhp4.ReviseForRemoveSectors(fc, prices, resp.NewMerkleRoot, len(req.Indices)) + revision, usage, err := rhp4.ReviseForFreeSectors(fc, prices, resp.NewMerkleRoot, len(req.Indices)) if err != nil { return fmt.Errorf("failed to revise contract: %w", err) } @@ -311,7 +309,7 @@ func (s *Server) handleRPCRemoveSectors(stream net.Conn) error { if err != nil { return fmt.Errorf("failed to revise contract: %w", err) } - return rhp4.WriteResponse(stream, &rhp4.RPCRemoveSectorsThirdResponse{ + return rhp4.WriteResponse(stream, &rhp4.RPCFreeSectorsThirdResponse{ HostSignature: revision.HostSignature, }) } @@ -1014,8 +1012,8 @@ func (s *Server) handleHostStream(stream net.Conn, log *zap.Logger) { err = s.handleRPCRenewContract(stream) case rhp4.RPCLatestRevisionID: err = s.handleRPCLatestRevision(stream) - case rhp4.RPCRemoveSectorsID: - err = s.handleRPCRemoveSectors(stream) + case rhp4.RPCFreeSectorsID: + err = s.handleRPCFreeSectors(stream) case rhp4.RPCSectorRootsID: err = s.handleRPCSectorRoots(stream) // account