Skip to content

Commit

Permalink
rhp: add DiffProofSize
Browse files Browse the repository at this point in the history
  • Loading branch information
peterjan committed Aug 28, 2023
1 parent ad76cac commit b554d55
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 3 deletions.
23 changes: 23 additions & 0 deletions rhp/v2/merkle.go
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,29 @@ 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) {
Expand Down
58 changes: 56 additions & 2 deletions v2/net/rhp/merkle.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"io"
"math"
"math/bits"
"sort"
"unsafe"

"go.sia.tech/core/v2/internal/blake2b"
Expand Down Expand Up @@ -244,8 +245,61 @@ 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 int, actions []RPCWriteAction) int {
return 128 // TODO
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
}

// nextSubtreeSize returns the size of the subtree adjacent to start that does
Expand Down
2 changes: 1 addition & 1 deletion v2/net/rhp/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(int(fc.Filesize/SectorSize), actions)
proofSize := DiffProofSize(fc.Filesize/SectorSize, actions)
downloadBandwidth := uint64(proofSize) * 32
return settings.InstrWriteBaseCost.
Add(settings.UploadBandwidthPrice.Mul64(sectorsAdded * SectorSize)).
Expand Down

0 comments on commit b554d55

Please sign in to comment.