Open KORuL opened 5 years ago
Hydrabadger
is already generic in the type of contribution C
. The idea is that C
is a list of transactions, but it can be anything!
So I'm not sure I understand the issue: Which kinds of transactions does the application need?
I mean to make an API for hydrabadger that allows you to send a transaction. Now it is implemented in the form of a lambda function, which is very inconvenient when you need to make a transaction from the outside. I work at the java level, and hydrabadger is a dll. Therefore, I would like an accessible API to send a transaction.
The Hydrabadger::propose_user_contribution
method is what you want. You might want to add an ffi layer which includes a function roughly like the following:
#[no_mangle]
pub extern "C" fn send_transaction<C: Contribution, N: NodeId>(
hdb: &Hydrabadger<C, N>,
txn: Transaction)
-> i32
{
hdb.propose_user_contribution(vec![txn]).{convert_error_code_to_i32_etc};
}
Please let me know if that will work or if I'm not understanding you correctly.
At first glance it looks like what you need. How to save an object on hdb, so that after the run_node method, you can call this method after some time interval? Will this method work correctly if it is called when the status of the validator belongs to another?
How to save an object on hdb, so that after the run_node method, you can call this method after some time interval?
Clone your Hydrabadger instance before calling node
or run_node
e.g.: hdb.clone().run_node(...)
. A Hydrabadger
object is internally Arc
-wrapped.
Will this method work correctly if it is called when the status of the validator belongs to another?
What do you mean by "the status of the validator belongs to another?"
This method does not take into account that during a call, its user may have non-validator status.
/// Handles a incoming batch of user transactions.
pub fn propose_user_contribution(&self, txn: C) -> Result<(), Error> {
if self.is_validator() {
self.send_internal(InternalMessage::hb_contribution(
self.inner.nid.clone(),
OutAddr(*self.inner.addr),
txn,
));
Ok(())
} else {
Err(Error::ProposeUserContributionNotValidator)
}
}
In order not to request the status of a validator or not after a certain period of time,
pub fn is_validator(&self) -> bool {
self.state_dsct_stale() == StateDsct::Validator
}
can you create a callback function to get the status of the event as a validator?
I'm not sure I completely understand what you're asking for. If you attempt to call propose_user_contribution
when the node is not a validator, an Err(Error::ProposeUserContributionNotValidator)
is returned.
Can you please clarify what do you mean by "create a callback function to get the status of the event as a validator?"
I work with Hydrabadger as a dll through certain methods. And it would be convenient for me to have a method to send a message, which then resolved the situation itself when the validator and when not. At the application level, I call the method to send a message, the corresponding method is called in hydrabadger. What is the most convenient way to resolve the situation when I am not a validator at the moment? to start a stream and wait when I become a validator, asking again after a certain time interval? Or maybe there is a way to implement something like a callback function that I am now a validator and at this point to send a message? Help please understand how better and some sort of listing
I would recommend simply checking the result of the call to propose_user_contribution
for an Err(Error::ProposeUserContributionNotValidator)
return value, then returning an error value (perhaps as an integer, -1
for example) from send_transaction
.
In your application code, simply check for a returned error (check for -1
etc.) then take the appropriate action, perhaps queueing your message for retry.
An even more robust solution is to use some notion of state (connected/disconnected/etc.) in your application so that it knows when it can and cannot send messages. You will want to check this state before attempting to send any message. How you want to design it is up to you but I would recommend simply queuing all messages in one step, then attempting to flush the queue (by sending all queued messages as a contribution) in a separate step.
As an additional layer of robustness you could add a verification / acknowledgement mechanism which ensures that each message was received before completely removing it from the queue (where each queued message has an unsent / sent / ackd
state for example).
An even more robust solution is to use some notion of state (connected/disconnected/etc.) in your application so that it knows when it can and cannot send messages. You will want to check this state before attempting to send any message.
Is there a way to find out if hydrabadger can send it or not?
I do not fully understand if we now take hydrabadger and on top of it make a function similar to this:
pub fn send_transaction(&self, txn: String) {
let mut txn_: Option<Transaction> = None;
txn_ = Some(Transaction(txn.to_string()));
while self.hydrabadger.lock().clone().unwrap().is_validator() {
let ten_millis = time::Duration::from_millis(10);
thread::sleep(ten_millis);
}
match self.hydrabadger.lock().clone().unwrap().propose_user_contribution(vec![txn_])
{
Err(e) => {
warn!("send_transaction Error: {}", e.to_string());
}
_ => {
warn!("send_transaction success");
}
};
}
then the application will crash because it did not send an empty transaction when it was a validator. Can you help me write a universal method for me? So that I called the method and it waited for the status of the validator and sent the transaction, and I returned the code successful. if there is no transaction, then sent it itself empty.
Help write a universal method for sending transactions. If I enter a transaction from the outside, the method must wait for the status of the validator and then send. If there is no transaction from outside, then when the status of the validator comes, an empty transaction is sent. Now we have to use the workaround that allows it, but it is wrong
If you can give me a link to your code I might be able to help advise you more, though I can't promise how soon. Let me just say though that there are a many different ways to implement what you want. Ideally your Java code has some notion of the state of the Hydrabadger connection. I think it would take me quite a bit of time to properly tell you how to do this but I'll take a look.
Hi! We use this repo for creating crypto-based messenger app. The are some issues and improvements suggestoins we want to introduce. It would be cool if you add the following capablities we need:
pub fn send_transaction (tr: Transaction)