-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
throw an error if the registry contract hasn't been deployed #22
Conversation
waitForReady, | ||
} from "./util.js"; | ||
|
||
const spawnSync = spawn.sync; | ||
|
||
// TODO: maybe this can be parsed out of the deploy process? | ||
// Since it's always the same address just hardcoding for now. | ||
const registryAddress = "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This used to reside in the validator.ts file, but we need access to it here now so it's been moved. If we can find a way to get this value from the deploy process, that would be ideal. Until then this works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't just get this from the underlying client package?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
by the client you mean @tableland/evm
?
@@ -62,7 +67,7 @@ class LocalTableland { | |||
typeof config.registryDir === "string" && | |||
config.registryDir.trim() !== "" | |||
) { | |||
this.registryDir = config.registryDir; | |||
this.registryDir = config.registryDir.trim(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trimming before setting the instance value, which means all later access doesn't need to trim
@@ -80,19 +85,15 @@ class LocalTableland { | |||
} | |||
|
|||
async #_start(config: Config = {}): Promise<void> { | |||
if ( | |||
typeof this.registryDir !== "string" || | |||
this.registryDir.trim() === "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above... This has already been trimmed.
this.#_cleanup(); | ||
|
||
// Check if the hardhat port is in use (defaults to 5 retries, 300ms b/w each try) | ||
const registryPortIsTaken = await probePortInUse(this.registryPort); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An old PR attempted to fix the CI issues by retrying the same hardhat node port in hopes it will become available. The issue comes from a crashing contract deploy process, not a failure to start the hardhat node. We no longer need this retry logic. I've left the logic that ensures the port is available, since this is a nice mechanism to fail fast and loud if the port was already taken.
@@ -101,14 +102,18 @@ class LocalTableland { | |||
// Else, notify the user only if it's a not the default and is custom. | |||
if (registryPortIsTaken) { | |||
throw new Error(`port ${this.registryPort} already in use`); | |||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some cleanup here. We don't need an else clause because throwing breaks out of this function.
this.registryPort | ||
}` | ||
); | ||
this.silent !== true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was getting logged even if the dev had set silent: true
|
||
const deployed = await this.#_ensureRegistry(); | ||
if (!deployed) { | ||
throw new Error( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This ensures we fail fast and loud if the deploy failed. At the moment you have to look through the CI logs and see if the failing tests are becaseue the registry wasn't deployed, or for some legitimate reason.
const code = await provider.getCode(registryAddress); | ||
|
||
// if the contract exists, and is not empty, code will not be equal to 0x | ||
return code !== "0x"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To check if the registry was deployed, we can use the ethers.js getCode
method. If the contract exists it will have a long string corresponding to the contract code. If not it will equal "0x".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Smart
@@ -1,220 +1,17 @@ | |||
import { type Server } from "node:net"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes in this file are the result of moving the network startup and shutdown tests to their own file.
test("fails to start due to registry deploy failure", async function () { | ||
const lt = new LocalTableland({ silent: true }); | ||
// note: need to cast as `any` since the method is private | ||
const deployStub = stub(lt, "_deployRegistry" as any); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I created a noop stub so the registry isn't deployed. This must result in an error instead of successful startup.
All the other tests in this file were moved from the e2e file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really nice work here @joewagner!
waitForReady, | ||
} from "./util.js"; | ||
|
||
const spawnSync = spawn.sync; | ||
|
||
// TODO: maybe this can be parsed out of the deploy process? | ||
// Since it's always the same address just hardcoding for now. | ||
const registryAddress = "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't just get this from the underlying client package?
@@ -220,6 +222,33 @@ class LocalTableland { | |||
console.log("\n\n*************************************\n"); | |||
} | |||
|
|||
// note: Tests are using sinon to stub this method. Because typescript compiles ecmascript | |||
// private features, i.e. hash syntax, in a way that does not work with sinon we must |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, really? Huh, there are apparently other libs that have a problem with this. Do you have a reference for the issue? Just for interest sake?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great question, I couldn't find an issue in Sinon. Maybe I should open one? Here's the Sinon source https://github.com/sinonjs/sinon/blob/main/lib/sinon/util/core/is-non-existent-property.js#L10
When you have a class the uses the js private class feature, you'll always get false
when you do something like:
class Derp {
#_foo() {
return "foo";
}
}
const instance = new Derp();
console.log("#_foo" in instance); // => false
console.log(instance.#_foo); // => type error
Maybe it's impossible to spy on private fields?
const code = await provider.getCode(registryAddress); | ||
|
||
// if the contract exists, and is not empty, code will not be equal to 0x | ||
return code !== "0x"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Smart
@carsonfarmer This was automatically changed to point at main after merging tablelandnetwork/local-tableland#21, can you give another ✅ ? [EDIT]: almost forgot to bump the patch version, gtg now. |
@asutula I added the fix for the SDK regression here since without the changes in this PR the CI fails constantly. |
Overview
As an improvement working toward fixing #40 this PR introduces behavior that check if the registry has been deployed before starting the Validator. If the contract is not deployed an error is thrown. This will make CI tests fail immediately and obviously, which will make the reason for failure more obvious.
Details
Along with requiring the existence of the registry on chain for successful startup, there are a few other changes:
NOTE: this is based off the
publish
branch. Once that's merged this will be pointed at main.