-
Notifications
You must be signed in to change notification settings - Fork 11.4k
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
[wallet + rest server] Remove usage of wallet context in rest server #817
Conversation
b83c108
to
c58a053
Compare
I have tried all endpoint manually and they seems to work fine, @arun-koshy can you verify it for me? |
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.
So apologies if I'm stirring the pot too much, but I have a set of overriding questions.
- Instead of using
PersistedConfig
, have we thought of using a config library such as config-rs which can deserialize from multiple formats into structs? It also has many features we might want later, like ability to merge multiple configs or from the environment. - JSON is kinda hard to read as a config format, have we thought about using TOML?
- Since you are refactoring some things could we rename "network.conf" to "sui.conf" so it can encompass things like logging/tracing config? We'll want to add much more configuration than just networking soon.
Thanks for including me, this is very interesting.
} | ||
} | ||
|
||
pub struct PersistedConfig<C> { |
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.
Can we add RustDoc here? Not clear what PersistedConfig is for just by looking here
Thanks for the review @velvia ! Any form of stirring are welcome here :)
config-rs looks interesting, we can definitely explore adopting it if we need the extra functionalities.
Personally I am ok with JSON/TOML/YAML. We should wait after GDC if we want to change it? There are lot of docs base on the JSON version already, not sure if we have enough time to change it?
I am not so sure about extending network.conf... I would imagine in a real Sui network, we will have one |
sui/src/rest_server.rs
Outdated
// and we cannot use &mut reference on the server_state object. | ||
fn take_server_state(&self) -> Result<ServerState, HttpError> { | ||
let mut state = self.server_state.lock().unwrap(); | ||
state.take().ok_or_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.
Could you also add this issue to the todo, I believe the take() I had in the code is what is causing the problem
Ok cool, we can add it later, agreed. Just didn't want to have to reinvent anything, but it looks small for now.
Oh probably not now, but can be easily changed later. We can wait for feedback from GDC/testing.
Ah I c. In that case I might create a separate authority.conf for a separate change. |
sui/src/rest_server.rs
Outdated
// Need to use a random id because rocksdb locks on current process which | ||
// means even if the directory is deleted the lock will remain causing an | ||
// IO Error when a restart is attempted. |
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 might need to update the location of this comment
}; | ||
|
||
addresses.push(address); |
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.
Could you help me understand the change here? Previously we do not include the address in genesis_conf
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 don't include address in genesis.conf previously because we don't have the key pair, we can add them now as we have decouple keys from the ClientState.
|
||
let object_id = match ObjectID::try_from(object_info_params.object_id) { | ||
Ok(object_id) => object_id, | ||
Err(error) => { | ||
*server_context.wallet_context.lock().unwrap() = Some(wallet_context); | ||
return Err(custom_http_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.
Why don't we have server_context.set_server_state(state);
here?
The fact that we need to add server_context.set_server_state(state);
before every return seems very error prone to me. I would suggest put everything in the middle into a separate function like #708 (comment) so that you only need to do it once
let state = server_context.take_server_state()?;
object_schema_helper(state,...);
server_context.set_server_state(state);
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 did thought of doing that but that will be a much bigger refactoring, @arun-koshy are you ok with that?
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.
It would actually be much appreciated :)
Done refactoring for take and set_server_state, will test for concurrency now. |
I somehow figured out how to fix @666lcz can you check if concurrent request works? |
7081070
to
fa34f1d
Compare
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.
Thanks so much for doing this Patrick! Looks great
Also incredible find on the real issue that was forcing us to use take()!!!
config: NetworkConfig, | ||
gateway: GatewayClient, | ||
keystore: Arc<RwLock<Box<dyn Keystore>>>, | ||
addresses: Vec<SuiAddress>, |
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.
nit: Just to be clear it would be good to add a note here that this field is just meant to be used for genesis/start. Maybe renaming it too genesis_addresses is enough? Once the network has been started there should be no expectation of the rest server knowing of any addresses. i.e. no one adding new endpoints should reference this field in server state.
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.
actually every field in ServerState
except GatewayClient
should be changed or removed when the rest_server -> Gateway transformation is completed
- keystore/addresses should be removed as they belongs to wallet/application
working_dir
andauthority_handles
should be removed, genesis and network startup should happen outside of Gateway, i.e. Gateway should not worry about genesis and starting up authorities, it should just connect to it assuming the network exist.network.conf
should becomegateway.conf
and only contain basic network info for connecting to the authorities, e.g. list of authorities host and port, network timeout, epoch etc...
I have added a TODO to remove these
sui/src/rest_server.rs
Outdated
// Taking state object without returning ownership | ||
let mut state = server_context.server_state.lock().await; | ||
let state = state.as_mut().ok_or_else(|| { | ||
custom_http_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.
nit: use server_state_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.
good spot! thanks!
for address in addresses.iter() { | ||
if let Err(err) = wallet_context.gateway.sync_account_state(*address).await { | ||
*server_context.wallet_context.lock().unwrap() = Some(wallet_context); | ||
let addresses = state.addresses.clone(); |
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 should aim to remove this as the Rest server should not technically have a store of addresses to return. When /addresses is hit the expectation should be that it hits the GatewayClient every time to get the list of known addresses. Can you switch this to call GatewayClient if it is already available or can you add a TODO for me to do this in a future PR?
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.
hmm get_account is not part of the GatewayAPI, and I think we shouldn't need this endpoint down the line, as the wallet/application should know which address it is managing
use crate::{create_api, ServerContext}; | ||
|
||
#[tokio::test] | ||
async fn test_concurrency() -> Result<(), anyhow::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.
Awesome! Thanks for adding a test 😄
So I did
to checkout your branch locally, and change the request from
to
The former(sequential) request works but I am seeing the same error for the latter(concurrent) one:
Feel free to address the concurrent problem as a separate PR. |
Thanks @666lcz ! Are you sure this is running against my branch? The error message |
Sorry for being an idiot! I was spoiled by the auto restarting feature of the Typescript development lately and forgot to rebuild. Indeed the concurrent requests are working after I rebuilt. Thanks for fixing this! |
No problem at all! Glad this fixes the problem! |
354ce9d
to
c4dc4d3
Compare
the response of genesis has changed and addresses are returned instead of wallet config, @arun-koshy do we need to notify whoever using the rest api? Will this break anything? |
Geniteam code is frozen so we should be good to go pushing this to main. I will update our documentation to reflect these changes. |
c4dc4d3
to
cf242e6
Compare
cf242e6
to
625cbe4
Compare
… in rest_server are now transient and won't be persisted to disk, it is already deleting the configs when stop endpoint is call prior the changes.
… take and return of server state object
added concurrent request test for rest server
625cbe4
to
2c27da9
Compare
Config
, the configs used in wallet and rest server are now in memory only by default,PersistedConfig
is added if we need to persist the config to disk.