Skip to content
This repository has been archived by the owner on Nov 2, 2018. It is now read-only.

migrate hostdb to the from weightedlist to the new hosttree package #1525

Merged
merged 13 commits into from Jan 10, 2017

Conversation

avahowell
Copy link
Contributor

This PR removes weightedlist from the hostdb and replaces it with the new hosttree package. Hosts are still stored in the activeHosts map by the NetAddress, since changing fully to public keys requires changing the HostDB interface, which is a much larger change. A subsequent PR will be opened, likely after the renter pools branch is merged, which removes activeHosts and changes the HostDB to use public keys.

@avahowell
Copy link
Contributor Author

Some contractor testing had to change because of these changes, since the hostTree stores hosts by publicKey it is no longer sufficient to simply re-announce the same host on a different netaddress. I've changed newTestingTrio to take a number of hosts to create, nhosts, and return a slice of hosts (with unique keypairs, obviously.)

@@ -141,6 +141,8 @@ type HostDBEntry struct {
// ScanHistory is the set of scans performed on the host. It should always
// be ordered according to the scan's Timestamp, oldest to newest.
ScanHistory HostDBScans
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know that this is not from this PR, but I think here is bad form, should just be []hdbs

The hdbss type is purely for sorting.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, my bad. Typically the pattern is to name the sorting type ByX. So we'd write:

sort.Sort(modules.ByTimestamp(entry.ScanHistory))

The name becomes pretty ugly though, since ByTimestamp is ambiguous -- it ought to be HostDBScansByTimestamp or something. Alternatively you could define the byTimestamp type locally, but then you'd need to redefine it in multiple modules.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, in Go 1.8 we can do:

sort.Slice(entry.ScanHistory, func(i, j int) bool {
    return entry.ScanHistory[i].Timestamp.Before(entry.ScanHistory[j].Timestamp)
})

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah that's what we should probably end up doing.

func newTestingTrio(name string) (modules.Host, *Contractor, modules.TestMiner, error) {
// newTestingTrio a Contractor, TestMiner, and a slice of hosts that can be
// used for testing host/renter interactions.
func newTestingTrio(name string, nhosts int) ([]modules.Host, *Contractor, modules.TestMiner, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lukechampine what are your thoughts on this change?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really like it; it's not a trio if there's multiple hosts. AFAICT, the only place we create multiple hosts is TestIntegrationSetAllowance, where we create 2 instead of 1. So I would prefer to revert the change, and instead either create the extra host manually or add a new helper function for creating multiple hosts.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that this change is ugly, I'll revert it and create an extra host in TestIntegrationSetAllowance.

if len(hdb.activeHosts) != 2 {
t.Error("host was not added:", hdb.activeHosts)
}
hdb.hostTree.Insert(h2)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^_^ very nice

siafundFee := adjustedContractPrice.Add(adjustedUploadPrice).Add(adjustedDownloadPrice).Add(entry.Collateral).MulTax()
totalPrice := entry.StoragePrice.Add(adjustedContractPrice).Add(adjustedUploadPrice).Add(adjustedDownloadPrice).Add(siafundFee)
func (hdb *HostDB) calculateHostWeight() hosttree.WeightFunc {
return func(entry modules.HostDBEntry) types.Currency {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the tabbing here, would prefer to see the weight func defined separately, then return weightFunc or whatever. I don't think it makes sense to be inline here, it's a massive amount of code.

}
} else {
// Shouldn't happen, but the usecase is covered anyway.
weight = weight.Div64(1000) // Because something weird is happening, don't trust this host very much.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably be 10e3, not 1e3. Should definitely use e notation since it's got >= three zeros

weight = weight.Div64(10) // 5,700x total penalty
}
if entry.RemainingStorage < requiredStorage {
weight = weight.Div64(100) // 570,000 total penalty
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing an x lol

allHosts: make(map[modules.NetAddress]*hostEntry),
scanPool: make(chan *hostEntry, scanPoolSize),
}

hdb.hostTree = hosttree.New(hdb.calculateHostWeight())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't you be able to just specify hdb.calculateHostWeight, instead of having a function that returns a function? You can just define the function and then specify it here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason for this is that the host weight function needs access to the hostdb's state.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DavidVorick is right -- you can just pass hdb.calculateHostWeight if you modify it to satisfy the weightFunc type. It should be:

func (hdb *HostDB) calculateHostWeight(entry modules.HostDBEntry) types.Currency {
    // use hdb.blockheight internally
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yeah, that's a lot cleaner.

for _, node := range hdb.activeHosts {
data.ActiveHosts = append(data.ActiveHosts, *node.hostEntry)
for _, entry := range hdb.activeHosts {
data.ActiveHosts = append(data.ActiveHosts, *entry)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just want to confirm that this saves everything important.

Can you verify that there is a test for saving and loading hosts, including things like the scan history?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I've confirmed that TestSaveLoad fails after modifying these lines.

@@ -107,10 +107,10 @@ func (hdb *HostDB) decrementReliability(addr modules.NetAddress, penalty types.C

// If the entry is in the active database, remove it from the active
// database.
node, exists := hdb.activeHosts[addr]
existingEntry, exists := hdb.activeHosts[addr]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so the entries still have the reliability cruft, instead of using the scan data?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, ideally activeHosts would not exist but that requires a much larger change.

@avahowell avahowell force-pushed the hosttree-implementation branch 2 times, most recently from f4415c3 to f3ab380 Compare January 10, 2017 04:52
@DavidVorick DavidVorick merged commit 9423a61 into master Jan 10, 2017
@lukechampine lukechampine deleted the hosttree-implementation branch January 10, 2017 23:49
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants