Solana: Check if deposit is finalized? - solana

How can we check if a deposit is finalized using solana/web3.js? I've tried using getTransaction with commitment parameter finalized and I did get a response with slot number. However, it took a few more seconds for Solana Explorer to show status Finalized. This probably means receiving slot number in a response to getTransaction doesn't necessarily mean a deposit is finalized?

Have you tried using 'confirmed' instead?
https://solana-labs.github.io/solana-web3.js/modules.html#Finality

You can use Connection.confirmTransaction with the finalized commitment to check that a transaction has landed. For example:
const signature = await connection.sendTransaction(transaction, signers);
const status = await connection.confirmTransaction(
{
signature: signature,
blockhash: transaction.recentBlockhash,
lastValidBlockHeight: transaction.lastValidBlockHeight,
},
)
).value;
if (status.err) {
throw new Error(
`Transaction ${signature} failed (${JSON.stringify(status)})`,
);
}
This was lifted from https://github.com/solana-labs/solana/blob/master/web3.js/src/util/send-and-confirm-transaction.ts

Related

method: "hardhat_impersonateAccount" - What happens when you call this method with an address that doesn't exist?

async function impersonateAccount(acctAddress) {
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [acctAddress],
});
return await ethers.getSigner(acctAddress);
}
When forking the blockchain locally on Hardhat, the function above allows developers to impersonate the address passed as argument to it.
So you can create transactions as if you're the owner of the account.
What happens when forking the mainnet, and you pass an address that does not exist on the mainnet as an argument?
Would it throw an error?
Does it create the account for you locally and give you access?
It will create the account locally with a balance of 0 ETH.
I tried this with the Ropsten address 0xFD391b604E9456c0Ec4aC13Cc881FbAF68868eB2, which currently has 210 testnet ETH and does not exist on the mainnet.
With your code example it will return a valid signer, and if you check the balance of the signer's address it will have 0 ETH.

How to check instruction in Solana on-chain program?

I am developing game, which guesses number and get reward if they success.
This is summary of my program.
First, user send amount of sol and his guessing number.
Second, Program get random number and store user's sol to vault.
Third, Program make random number, if user is right, gives him reward.
Here, how can I check if the user sent correct amount of sol in program?
This is test code for calling program.
const result = await program.rpc.play(
new anchor.BN(40),
new anchor.BN(0),
new anchor.BN(20000000),
_nonce, {
accounts: {
vault: vaultPDA,
user: provider.wallet.publicKey, // User wallet
storage: storageAccount.publicKey,
systemProgram: systemProgram
},
instructions: [
SystemProgram.transfer({
fromPubkey: provider.wallet.publicKey,
toPubkey: vaultPDA,`enter code here`
lamports: 20000000`enter code here`
})
],
signers: [storageAccount]`enter code here`
}
)
The best solution would be to directly transfer the lamports inside of your program using a cross-program invocation, like this program: Cross-program invocation with unauthorized signer or writable account
Otherwise, from within your program, you can check the lamports on the AccountInfo passed, and make sure it's the proper number, similar to this example: https://solanacookbook.com/references/programs.html#transferring-lamports
The difference there is that you don't need to move the lamports.

Code is not delievered by SendCodeRequest without error and this happens only on server-side with Heroku

Here is my situation: the same Telethon code is used on my local machine and on the server. Requesting authorization code from local machine works fine. Requesting the code from the server does not produce any error, and code is not sent. Sometimes it works even from the server without any changes in code.
I suppose there might be some ip blocks or something related to the ip, cause that is the only thing which might differ on the server side: Heroku assign ip addresses dynamically, so, there might by some subnets which are blocked by Telegram API for some reason. But there is no error and that is really strange. There are too many ip addresses to disprove the hypothesis. I need to catch at least one ip address which gives me opposite results: one time code it recieved and another time does not. So I am stuck with this situation and have no ideas how it could be fixed or clarified.
global t
t = None
async def ssssendCode(phone):
global t
try:
if os.path.isfile(phone+'.session'):
logger.debug('client file exists')
else:
logger.debug('client file does not exist')
if t is None:
t = TelegramClient(phone, settings['telegramClientAPIId'], settings['telegramClientAPIHash'])
t.phone = phone
#t.phone_code_hash = None
await t.connect()
#response = await t.send_code_request(phone=phone,force_sms=True)
s3_session.resource('s3').Bucket('telethon').upload_file(str(phone)+".session", str(phone)+".session")
logger.debug(str(requests.get('https://httpbin.org/ip').text))
response = await t.send_code_request(phone=phone)
logger.debug(str(t.is_connected()))
except Exception as e:
response = str(e)
return str(response)
example of response to the local machine request
SentCode(type=SentCodeTypeSms(length=5), phone_code_hash='b5b069a2a4122040f1', next_type=CodeTypeCall(), timeout=120)
example of reponse to the server-side request
SentCode(type=SentCodeTypeSms(length=5), phone_code_hash='0e89db0324c1af0149', next_type=CodeTypeCall(), timeout=120)
send_code_request is the from the Telethon without modifications
async def send_code_request(
self: 'TelegramClient',
phone: str,
*,
force_sms: bool = False) -> 'types.auth.SentCode':
"""
Sends the Telegram code needed to login to the given phone number.
Arguments
phone (`str` | `int`):
The phone to which the code will be sent.
force_sms (`bool`, optional):
Whether to force sending as SMS.
Returns
An instance of :tl:`SentCode`.
Example
.. code-block:: python
phone = '+34 123 123 123'
sent = await client.send_code_request(phone)
print(sent)
"""
result = None
phone = utils.parse_phone(phone) or self._phone
phone_hash = self._phone_code_hash.get(phone)
if not phone_hash:
try:
result = await self(functions.auth.SendCodeRequest(
phone, self.api_id, self.api_hash, types.CodeSettings()))
except errors.AuthRestartError:
return await self.send_code_request(phone, force_sms=force_sms)
# If we already sent a SMS, do not resend the code (hash may be empty)
if isinstance(result.type, types.auth.SentCodeTypeSms):
force_sms = False
# phone_code_hash may be empty, if it is, do not save it (#1283)
if result.phone_code_hash:
self._phone_code_hash[phone] = phone_hash = result.phone_code_hash
else:
force_sms = True
self._phone = phone
if force_sms:
result = await self(
functions.auth.ResendCodeRequest(phone, phone_hash))
self._phone_code_hash[phone] = result.phone_code_hash
return result
Just in case: I have much more than 2 minutes between attempts to get a code from the local machine and server, so it is absolutely not the timeout issue. And moreover: even when requesting the code from the local right after half a minute from the failed server-side attemp: code is coming almost immediately.

Send message only once instead of periodically

I have developed a scenario where at first the vehicles send a self messsage and upon reception of the self message vehicles send a message to RSU.
The self message code is written in the initialize() method. But during simulation the vehicles send the message to RSU every second.
I want the message to be sent only once. What should I do?
I have attached the handleSelfmessage method of my TraCIDemo11p.cc class.
if(msg->isSelfMessage()==true)
{
cModule *tmpMobility = getParentModule()->getSubmodule("veinsmobility");
mobility = dynamic_cast<Veins::TraCIMobility*>(tmpMobility);
ASSERT(mobility);
t_channel channel = dataOnSch ? type_SCH : type_CCH;
WaveShortMessage* wsm = prepareWSM("data", dataLengthBits, channel, dataPriority, -1,2);
wsm->setSenderAddress(myAddress);
wsm->setRecipientAddress(1001);
sendMessage(wsm->getWsmData());
}
Your approach seems right, but obviously you have some problem in your implementation.
Alternatively you can create a new message and send it to yourself
myOneTimeMsg = new cMessage("OneTimeMsg");
scheduleAt(simTime()+1.0, myOneTimeMsg); // this will send the message at t=currentTime+1.0 seconds
Then you can handle that message as follows:
if(msg->isSelfMessage()==true){
if (msg == myOneTimeMsg) {
// do what you need next...
Amending the answer of #user4786271:
The handleSelfMsg method of TraCIDemo11p.cc obviously is executed for every self-message which this module receives - possibly also non WSMs. So if you just added the given code there, it will send a WSM for every of those self-messages. Thus, only checking for self-message type is not enough. You need to create a new message type and check for that type as shown by #user4786271.

Windows: ReportEvent function

As far as I understood, the ReportEvent function requires Message Text Files associated through the registry to receive properly formatted messages. Is there any common Event Ids or any simple way to report an event with no Message Text Files associated?
Or may be, is there special common Event Source which I can use in my application? Something like RegisterEventSource(NULL, "Application")?
You don't have to register your messages in HKLM. (Which is a good thing, because you can't register messages if you're not an administrator).
But that doesn't stop you from writing events to the Windows Application event log. The only downside is that starting with Windows Vista you'll just get some ugly text along with it.
HRESULT LogToEventLog(String Source, String EventText, int EventType, DWORD EventID)
{
/*
EventType is one of:
EVENTLOG_ERROR_TYPE = $0001;
EVENTLOG_WARNING_TYPE = $0002;
EVENTLOG_INFORMATION_TYPE = $0004;
EVENTLOG_AUDIT_SUCCESS = $0008;
EVENTLOG_AUDIT_FAILURE = $0010;
Source is your name for your app or feature, e.g.:
"My Cool App"
"Outlook"
"ESENT"
"Chrome"
*/
HANDLE h = RegisterEventSource(null, Source); //null --> local computer
if (h == 0)
return HResultFromWin32(GetLastError);
try
{
PChar[1] ss;
ss[0] = PChar(EventText);
if (!ReportEvent(
h, // event log handle
EventType, // event type
0, // category zero
EventID, // event identifier
null, // no user security identifier
1, // one substitution string
0, // no data
#ss, // pointer to string array
null // pointer to data
))
{
return HResultFromWin32(GetLastError);
}
}
finally
{
DeregisterEventSource(h);
}
return S_OK;
}
And so now you can log events to the Application event log:
LogToEventLog("Stackoverflow", "Question 5399066 was answered by Ian Boyd",
EVENTLOG_INFORMATION_TYPE, 0x45);
Steal someone else's registration
Unfortunately, starting with Windows Vista, Windows will give ugly complaints that you didn't register the event beforehand:
The description for Event ID 69 from source Stackoverflow cannot be
found. Either the component that raises this event is not installed on
your local computer or the installation is corrupted. You can install
or repair the component on the local computer.
If the event originated on another computer, the display information
had to be saved with the event.
The following information was included with the event:
Question 5399066 was answered by Ian Boyd
But you don't have to live with it. Just because you didn't register an message source file in HKLM, doesn't mean nobody else did.
Notice, for example, a message from the Outlook source in the Event log:
Source: Outlook
EventID: 0x40000020
Event Data: D:\win32app\Exchange\Outlook2003.pst
Message: The store D:\win32app\Exchange\Outlook2003.pst has detected a catalog checkpoint.
You can check registration information for Outlook in:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application\Outlook
And see:
MessageEventFile: REG_SZ = "D:\Programs\MICROS~4\Office14\1033\MAPIR.DLL"
If you peek into the resources of MAPIR.dll binary, you'll see its Message Table:
1 MESSAGETABLE
{
0x12, "Connection stats for server (%1). Rpcs Attempted (%2), Rpcs Succeeded (%3), Rpcs Failed (%4), Rpcs Canceled (%5), Rpc UI shown (%6), Avg request time (%7) ms, Min request time (%8) ms, Max request time (%9) ms.\r\n"
0x14, "Cancelable RPC started.\r\n"
0x15, "Cancelable RPC shutdown.\r\n"
0x40000010, "Cancelable RPC dialog shown for server (%1), total wait time was (%2) ms, result was (%3).\r\n"
0x40000011, "User canceled request against server (%1) after waiting (%2) ms.\r\n"
0x40000013, "Rpc call (%1) on transport (%2) to server (%3) failed with error code (%4) after waiting (%5) ms; eeInfo (%6).\r\n"
0x40000016, "There was a problem reading one or more of your reminders. Some reminders may not appear.\r\n"
0x40000017, "Unable to update public free/busy data.\r\n"
0x4000001A, "%1\r\n"
0x4000001B, "%1\r\n"
0x4000001D, "The store %1 is being re-pushed to the indexer for the following reason: %2.\r\n"
0x4000001E, "Starting reconciliation for the store %1 for the following reason: %2.\r\n"
0x4000001F, "The store %1 has detected a catalog rebuild.\r\n"
0x40000020, "The store %1 has detected a catalog checkpoint.\r\n"
...
}
You can see that eventid 0x40000020 is assocated with a formatting string:
"The store %1 has detected a catalog checkpoint.\r\n"
You can hijack Outlook's registration:
LogToEventLog("Outlook", "Your mom", EVENTLOG_INFORMATION_TYPE, $40000020);
and you'll get your event added to the event log without all the ugly warnings:
No, you just have to follow the rules and define your message text files, build them into resources, link them to your app etc.
The example provided at MSDN leads you through everything you need to do.
Try this out, it's worked for me before..
http://www.codeproject.com/KB/system/xeventlog.aspx

Resources