diff --git a/rhp/v2/merkle.go b/rhp/v2/merkle.go index a676295d..ba026283 100644 --- a/rhp/v2/merkle.go +++ b/rhp/v2/merkle.go @@ -435,29 +435,6 @@ func VerifyAppendProof(numLeaves uint64, treeHashes []types.Hash256, sectorRoot, return acc.root() == newRoot } -// DiffProofSize returns the size of a Merkle diff proof for the specified -// actions within a tree containing numLeaves leaves. -func DiffProofSize(actions []RPCWriteAction, numLeaves uint64) (numHashes int) { - indices := sectorsChanged(actions, numLeaves) - numHashes += len(indices) - - buildRange := func(i, j uint64) { - for i < j { - subtreeSize := nextSubtreeSize(i, j) - numHashes++ - i += subtreeSize - } - } - - var start uint64 - for _, end := range indices { - buildRange(start, end) - start = end + 1 - } - buildRange(start, numLeaves) - return -} - // BuildDiffProof constructs a diff proof for the specified actions. // ActionUpdate is not supported. func BuildDiffProof(actions []RPCWriteAction, sectorRoots []types.Hash256) (treeHashes, leafHashes []types.Hash256) { diff --git a/rhp/v2/rhp.go b/rhp/v2/rhp.go index 5cbd9a4f..92df35b3 100644 --- a/rhp/v2/rhp.go +++ b/rhp/v2/rhp.go @@ -281,10 +281,12 @@ type ( ) // RPCSectorRootsCost returns the price of a SectorRoots RPC. -func RPCSectorRootsCost(settings HostSettings, n uint64) types.Currency { +func RPCSectorRootsCost(settings HostSettings, rootOffset, numRoots uint64) types.Currency { + proofSize := RangeProofSize(LeavesPerSector, rootOffset, rootOffset+numRoots) return settings.BaseRPCPrice. - Add(settings.DownloadBandwidthPrice.Mul64(n * 32)). // roots - Add(settings.DownloadBandwidthPrice.Mul64(128 * 32)) // proof + Add(settings.DownloadBandwidthPrice.Mul64(64)). // signature + Add(settings.DownloadBandwidthPrice.Mul64(numRoots * 32)). // roots + Add(settings.DownloadBandwidthPrice.Mul64(proofSize * 32)) // proof } // RPCReadCost returns the price of a Read RPC. @@ -304,11 +306,12 @@ func RPCReadCost(settings HostSettings, sections []RPCReadRequestSection) types. // RPCAppendCost returns the price and collateral of a Write RPC with a single // append operation. -func RPCAppendCost(settings HostSettings, storageDuration uint64) (price, collateral types.Currency) { +func RPCAppendCost(settings HostSettings, storageDuration, numLeaves uint64) (price, collateral types.Currency) { + proofSize := uint64(bits.Len64(numLeaves)) + 1 // hashes + new root price = settings.BaseRPCPrice. Add(settings.StoragePrice.Mul64(SectorSize).Mul64(storageDuration)). Add(settings.UploadBandwidthPrice.Mul64(SectorSize)). - Add(settings.DownloadBandwidthPrice.Mul64(128 * 32)) // proof + Add(settings.DownloadBandwidthPrice.Mul64(proofSize * 32)) // proof collateral = settings.Collateral.Mul64(SectorSize).Mul64(storageDuration) // add some leeway to reduce chance of host rejecting price = price.Mul64(125).Div64(100) @@ -317,8 +320,8 @@ func RPCAppendCost(settings HostSettings, storageDuration uint64) (price, collat } // RPCDeleteCost returns the price of a Write RPC that deletes n sectors. -func RPCDeleteCost(settings HostSettings, n int) types.Currency { - price := settings.BaseRPCPrice. - Add(settings.DownloadBandwidthPrice.Mul64(128 * 32)) // proof - return price.Mul64(105).Div64(100) +func RPCDeleteCost(settings HostSettings, numSectors, numLeaves uint64) types.Currency { + proofSize := 2*uint64(bits.Len64(numLeaves))*numSectors + 1 // hashes + new root + return settings.BaseRPCPrice. + Add(settings.DownloadBandwidthPrice.Mul64(proofSize * 32)) // proof } diff --git a/v2/net/rhp/merkle.go b/v2/net/rhp/merkle.go index 5067ac5e..3547acb7 100644 --- a/v2/net/rhp/merkle.go +++ b/v2/net/rhp/merkle.go @@ -6,7 +6,6 @@ import ( "io" "math" "math/bits" - "sort" "unsafe" "go.sia.tech/core/v2/internal/blake2b" @@ -245,61 +244,8 @@ func RangeProofSize(n, start, end uint64) uint64 { // DiffProofSize returns the size of a Merkle diff proof for the specified // actions within a tree containing n leaves. -func DiffProofSize(n uint64, actions []RPCWriteAction) (numHashes int) { - indices := sectorsChanged(actions, uint64(n)) - numHashes += len(indices) - - buildRange := func(i, j uint64) { - for i < j { - subtreeSize := nextSubtreeSize(i, j) - numHashes++ - i += subtreeSize - } - } - - var start uint64 - for _, end := range indices { - buildRange(start, end) - start = end + 1 - } - buildRange(start, n) - return -} - -func sectorsChanged(actions []RPCWriteAction, numSectors uint64) []uint64 { - newNumSectors := numSectors - sectorsChanged := make(map[uint64]struct{}) - for _, action := range actions { - switch action.Type { - case RPCWriteActionAppend: - sectorsChanged[newNumSectors] = struct{}{} - newNumSectors++ - - case RPCWriteActionTrim: - for i := uint64(0); i < action.A; i++ { - newNumSectors-- - sectorsChanged[newNumSectors] = struct{}{} - } - - case RPCWriteActionSwap: - sectorsChanged[action.A] = struct{}{} - sectorsChanged[action.B] = struct{}{} - - default: - panic("unknown or unsupported action type: " + action.Type.String()) - } - } - - var sectorIndices []uint64 - for index := range sectorsChanged { - if index < numSectors { - sectorIndices = append(sectorIndices, index) - } - } - sort.Slice(sectorIndices, func(i, j int) bool { - return sectorIndices[i] < sectorIndices[j] - }) - return sectorIndices +func DiffProofSize(n int, actions []RPCWriteAction) int { + return 128 // TODO } // nextSubtreeSize returns the size of the subtree adjacent to start that does diff --git a/v2/net/rhp/rpc.go b/v2/net/rhp/rpc.go index c8e7745a..38fe376c 100644 --- a/v2/net/rhp/rpc.go +++ b/v2/net/rhp/rpc.go @@ -231,7 +231,7 @@ func RPCWriteRenterCost(settings HostSettings, fc types.FileContract, actions [] sectorStoragePrice := settings.StoragePrice.Mul64(SectorSize).Mul64(storageDuration) storageCost = sectorStoragePrice.Mul64(sectorsAdded - sectorsRemoved) } - proofSize := DiffProofSize(fc.Filesize/SectorSize, actions) + proofSize := DiffProofSize(int(fc.Filesize/SectorSize), actions) downloadBandwidth := uint64(proofSize) * 32 return settings.InstrWriteBaseCost. Add(settings.UploadBandwidthPrice.Mul64(sectorsAdded * SectorSize)).