We need to extend
threadedContractMaintenance so that it checks our existing list of hosts and makes sure that none of them are violating the new IP address rules that we've put in place when selecting from random hosts. There are two stages of implementation, one for v1.3.4, and the other for v1.4.x.
For v1.3.4, we should take the
addressFilter in the hostTree and move it to a separate package so that it can be imported by both the hostdb and the hosttree. If there's a relatively clean way to modify this issue without moving the
addressFilter interface+implementation to a new package, that's fine. I suggest the package
NebulousLabs/Sia/utils/addressfilter, and then in v1.4.x we'd move a bunch of our other top level packages to
utils (encoding, persist, crypto, sync, compatibility).
In the hostdb itself, we would create the function
checkForIPViolations, which would take in a list of host pubkeys as input, and return a list of host pubkeys as output that indicate which hosts are bad and should not be used anymore. The implementation will create an
addressFilter (from the
hostdb, which is the only reason I suggest moving the
addressFilter implementation), then resolve IPs for all the pubkeys provided, and then return a list of all the IPs that fail. In the event of a conflict (meaning we have two hosts that are valid), it'll randomly select one of the hosts to be bad, the other will remain good. This is the implementation for v1.3.4.
In v1.4.x, the implementation gets more involved. The hostdb will start to store a new field for each host: a block height indicating the last time that the host changed it's IP address /24. So small changes to the IP (where it keeps the same leading 24 bits) won't cause this value to update. But if they do change, the host loses its age. Then, we update the implementation of
checkForIPViolations to prefer the host that has had the least recent IP address change (according to this value) rather than to choose one randomly. This means that the hostdb is responsible for watching the hosts for changes like their IP address, keeping that complexity out of the contractor. I think the hostdb is the correct place to put this complexity. The hostdb will check what address a host resolves to every time it scans that host.
The v1.3.4 implementation is a quick stopgap to prevent attacks like the ones that some people have predeclared on our forums. The v1.4.x is to sew up all the remaining loose ends with IP resolving, but is chosen to be v1.4.x because it modifies the state, persistence, and logic of the hostdb, which is too much of a change to fit into v1.3.4 without more extensive testing.