Ingress should use a set
The `AdminList`, `AccountRulesList`, and `NodeRulesList` contracts have been recently rewritten to use a set. `Ingress` has the semantics of a set but has not been written the same way.\\nThis leads to some inefficiencies. In particular, `Ingress.removeContract` is an O(n) operation:\\n```\\nfor (uint i = 0; i < contractKeys.length; i++) {\\n    // Delete the key from the array + mapping if it is present\\n    if (contractKeys[i] == name) {\\n        delete registry[contractKeys[i]];\\n        contractKeys[i] = contractKeys[contractKeys.length - 1];\\n        delete contractKeys[contractKeys.length - 1];\\n        contractKeys.length--;\\n```\\n
Use the same set implementation for Ingress: an array of `ContractDetails` and a mapping of names to indexes in that array.
```\\nfor (uint i = 0; i < contractKeys.length; i++) {\\n    // Delete the key from the array + mapping if it is present\\n    if (contractKeys[i] == name) {\\n        delete registry[contractKeys[i]];\\n        contractKeys[i] = contractKeys[contractKeys.length - 1];\\n        delete contractKeys[contractKeys.length - 1];\\n        contractKeys.length--;\\n```\\n