Given the state:
Account X, nonce: 0
Account X sends a valid TX
Account X new nonce: 1
Account X sends an invalid TX that doesn't pass a validateTx() check in mempool (msg too large, more than 32kb for example)
Account X new nonce in the global state: 2 or 1 ?
If an account sends in invalid TX should the nonce of the next transaction be the same as of the invalid one or does it have to increase after every attept to submit a TX?
Related
I am trying to swap some USDC(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48) token for USDT(0xdAC17F958D2ee523a2206206994597C13D831ec7) token using UniswapV2Router02 at address 0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F(this is the Sushiswap's router on Ethereum mainnet)
Since I both USDC and USDT have 6 digits precision as amountIn to the swapExactTokensForTokens method I am passing number 3000 * 10 ** 6(must be equal to $3000). As amountOutMin I am passing 2850 * 10 ** 6(must be equal to $2850, which is -5% from the amountIn. In my opinion this is prety enough slippage tolerance)
Everything looks right? Yes but no! Everythime I ma trying to run this code:
UniswapV2Router(0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F) // Sushiswap router on ETH mainnet
.swapExactTokensForTokens(3000 * 10 ** 6, // 3000 USDC
2850 * 10 ** 6, // 2850 USDT
[
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC address on ETH mainnet
"0xdAC17F958D2ee523a2206206994597C13D831ec7" // USDT address on ETH mainnet
],
msg.sender,
<some deadline>);
I am getting the following error:
Revert message: UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT
Please help what I am missing?
EDIT: I am using truffle and I have forked ETH mainnet
EDIT 2: The amount UniswapV2Router is trying to return is 1327704386 ~ 1327 USDT which is ~60% slippage but in the liquidity pair there are assets for $2,036,392,078,752.44
It happened so thath the Sushiswap's USDC/USDT pool has only 5k in liquidity and everything with my code is right.
In the process of studying Ethereum smart contracts, the question arose of how to store large structures inside a contract (array or map). There is a contract
pragma solidity ^ 0.8.6;
contract UselessWorker {
uint32 public successfullyExecutedIterations = 0;
mapping (uint32 => uint32 [6]) items;
event ItemAdded (uint32 result);
function doWork (int _iterations) public {
for (int32 i = 0; i <_iterations; i ++) {
items [successfullyExecutedIterations] = [uint32 (block.timestamp), successfullyExecutedIterations, 10, 10, 10, 10];
successfullyExecutedIterations ++;
}
emit ItemAdded (successfullyExecutedIterations);
}
}
The doWork method fills the map items with arrays of numbers, called by an external script. At the same time, the more records appear in items, the faster disk space is consumed (for 1,000,000 the blockchain size is about 350 MB, for 2,000,000 about 1.1 GB, for 19,000,000 about 22 GB.This is the size of the .ethereum/net/geth/chaindata/ folder).
I am testing it on a private network, so the price of gas does not bother me. I run it with the command
geth --mine --networkid 999 --datadir ~ / .ethereum / net
--rpccorsdomain "" --allow-insecure-unlock --miner.gastarget 900000000 --rpc --ws --ws.port 8546 --ws.addr "127.0.0.1" --ws.origins
"" --ws.api "web3, eth" --rpc.gascap 800000000
According to estimates, one record in the map should take about 224 bytes (7 * 32 bytes) and for 19M records it should be about 4.2 GB.
It feels like a memory leak is taking place. Or I don't understand well how memory is allocated for storing map.
Can anyone suggest why blockchain is consuming so much disk space?
I am trying to make a mesh network using ESP32 module. The WiFi.h softAPConfig() can be used to set the starting address for leasing, but it progress upwards without reusing the already leased addresses which are no more in use. So I want to limit the leasing range between two addresses.
I found this piece of code from dhcpserver.h
/* Defined in esp_misc.h */
typedef struct {
bool enable;
ip4_addr_t start_ip;
ip4_addr_t end_ip;
} dhcps_lease_t;
This is the code I compiled and uploaded into the ESP32 module
#include "WiFi.h"
char *ssid = "AirMesh";
IPAddress local_IP(192,168,1,0);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);
void setup()
{
Serial.begin(9600);
Serial.println();
Serial.print("Setting soft-AP configuration ... ");
Serial.println(WiFi.softAPConfig(local_IP, gateway, subnet) ? "Ready" : "Failed!");
Serial.print("Setting soft-AP ... ");
Serial.println(WiFi.softAP("ESPsoftAP_01") ? "Ready" : "Failed!");
Serial.print("Soft-AP IP address = ");
Serial.println(WiFi.softAPIP());
WiFi.softAP(ssid);
}
void loop() {}
The first device when connected gives an IP 192.168.1.1, the second device an IP 192.168.1.2, when I disconnect the first device and reconnected it and it gives an IP 192.168.1.3 (every connection use different physical addresses)
This progression keeps going
EDIT:
After digging it up, I think I found the code responsible for ranging IP leasing, but couldn't figure out what it means.
lease.start_ip.addr = static_cast<uint32_t>(local_ip) + (1 << 24);
lease.end_ip.addr = static_cast<uint32_t>(local_ip) + (11 << 24);
After trial and error methord, I managed to find the answer
Change the code in WiFiAP.cpp file (i have forked and requested a pull replacing 11 with 10 since the maximum number of connections possible for ESP32 is 10)
lease.start_ip.addr = static_cast<uint32_t>(local_ip) + (1 << 24);
lease.end_ip.addr = static_cast<uint32_t>(local_ip) + (n << 24);
Where n is number of IP addresses that must be allocated to external devices.
For ex:-
lease.end_ip.addr = static_cast<uint32_t>(local_ip) + (20 << 24);
means if the starting IP is 192.168.1.0 the DHCP will assign address starting from 192.168.1.1 to 192.168.1.20, while 192.168.1.0 (starting IP will be the address of the ESP32 module)
Doesn't the access point use the first ip of 192.168.1.1 not 1.0?
So 2-11 is 10 connections.
I want to use global variable for several kernel method, but when I use the flowing code to init __device__ variable, I got a [access violation on store (global memory)] error when I init the second var.
__device__ short* blockTmp[4];
//init blockTmp
template<int BS>
__global__ void InitQuarterBuf_kernel(
)
{
int iBufSize = 2000000;
for (int i = 0; i < 4; i++){
blockTmp[[i] = new short[iBufSize];
blockTmp[[i][iBufSize-1]=1;
printf("blockTmp[[%d][%d] is %d.\n",i,iBufSize-1,blockTmp[[i][iBufSize-1]);
}
}
The error message:
Memory Checker detected 1 access violations.
error = access violation on store (global memory)
gridid = 94
blockIdx = {0,0,0}
threadIdx = {0,0,0}
address = 0x003d08fe
accessSize = 2
CUDA grid launch failed: CUcontext: 1014297073536 CUmodule: 1013915337344 Function: _Z21InitBuf_kernelILi8EEvii
CUDA context created : 67e557f3e0
CUDA module loaded: 67cdc7ed80
CUDA module loaded: 67cdc7e180
================================================================================
CUDA Memory Checker detected 1 threads caused an access violation:
Launch Parameters
CUcontext = 67e557f3e0
CUstream = 67cdc7f580
CUmodule = 67cdc7e180
CUfunction = 67eb64b2f0
FunctionName = _Z21InitBuf_kernelILi8EEvii
GridId = 94
gridDim = {1,1,1}
blockDim = {1,1,1}
sharedSize = 256
Parameters (raw):
0x00000780 0x00000440
GPU State:
Address Size Type Mem Block Thread blockIdx threadIdx PC Source
----------------------------------------------------------------------------------------------------------------------------------
003d08fe 2 adr st g 0 0 {0,0,0} {0,0,0} _Z21InitBuf_kernelILi8EEvii+0004c8
Summary of access violations:
xxxx_launcher.cu(481): error MemoryChecker: #misaligned=0 #invalidAddress=1
================================================================================
Memory Checker detected 1 access violations.
error = access violation on store (global memory)
gridid = 94
blockIdx = {0,0,0}
threadIdx = {0,0,0}
address = 0x003d08fe
accessSize = 2
CUDA grid launch failed: CUcontext: 446229378016 CUmodule: 445834060160 Function: _Z21InitBuf_kernelILi8EEvii
Is there some limit for __device__ variable? How can I init the __device__ variable?
And if I change the buffer size to 1000, it is OK.
Your posted kernel doesn't really make sense, as your __device__ variable is named blockTmp but you are initializing m_filteredBlockTmp variables in your kernel, which don't appear to be defined anywhere.
Anyway, supposing these are intended to be the same, the issue is probably not related to your usage of __device__ variables (pointers, in this case) but your use of in-kernel new which definitely has allocation limits.
These limits and behavior are the same as what is described in the programming guide for in-kernel malloc. In particular, the default limit is 8MB and if you need more (in the "device heap") you must explicitly raise the limit with a CUDA runtime API call.
A useful error check in these situations is to check whether the pointer returned by new or malloc is NULL, which would indicate an allocation failure. If you fail to do that check, but then attempt to use the pointer anyway, you are going to run into trouble as described in your post.
I am curious to understand the divide by zero exception handling in linux. When divide by zero operation is performed, a trap is generated i.e. INT0 is sent to the processor and ultimately SIGFPE signal is sent to the process that performed the operation.
As I see, the divide by zero exception is registered in trap_init() function as
set_trap_gate(0, ÷_error);
I want to know in detail, what all happens in between the INT0 being generated and before the SIGFPE being sent to the process?
Trap handler is registered in the trap_init function from arch/x86/kernel/traps.c
void __init trap_init(void)
..
set_intr_gate(X86_TRAP_DE, ÷_error);
set_intr_gate writes the address of the handler function into idt_table x86/include/asm/desc.h.
How is the divide_error function defined? As a macro in traps.c
DO_ERROR_INFO(X86_TRAP_DE, SIGFPE, "divide error", divide_error, FPE_INTDIV,
regs->ip)
And the macro DO_ERROR_INFO is defined a bit above in the same traps.c:
193 #define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
194 dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \
195 { \
196 siginfo_t info; \
197 enum ctx_state prev_state; \
198 \
199 info.si_signo = signr; \
200 info.si_errno = 0; \
201 info.si_code = sicode; \
202 info.si_addr = (void __user *)siaddr; \
203 prev_state = exception_enter(); \
204 if (notify_die(DIE_TRAP, str, regs, error_code, \
205 trapnr, signr) == NOTIFY_STOP) { \
206 exception_exit(prev_state); \
207 return; \
208 } \
209 conditional_sti(regs); \
210 do_trap(trapnr, signr, str, regs, error_code, &info); \
211 exception_exit(prev_state); \
212 }
(Actually it defines the do_divide_error function which is called by the small asm-coded stub "entry point" with prepared arguments. The macro is defined in entry_32.S as ENTRY(divide_error) and entry_64.S as macro zeroentry: 1303 zeroentry divide_error do_divide_error)
So, when a user divides by zero (and this operation reaches the retirement buffer in OoO), hardware generates a trap, sets %eip to divide_error stub, it sets up the frame and calls the C function do_divide_error. The function do_divide_error will create the siginfo_t struct describing the error (signo=SIGFPE, addr= address of failed instruction,etc), then it will try to inform all notifiers, registered with register_die_notifier (actually it is a hook, sometimes used by the in-kernel debugger "kgdb"; kprobe's kprobe_exceptions_notify - only for int3 or gpf; uprobe's arch_uprobe_exception_notify - again only int3, etc).
Because DIE_TRAP is usually not blocked by the notifier, the do_trap function will be called. It has a short code of do_trap:
139 static void __kprobes
140 do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
141 long error_code, siginfo_t *info)
142 {
143 struct task_struct *tsk = current;
...
157 tsk->thread.error_code = error_code;
158 tsk->thread.trap_nr = trapnr;
170
171 if (info)
172 force_sig_info(signr, info, tsk);
...
175 }
do_trap will send a signal to the current process with force_sig_info, which will "Force a signal that the process can't ignore".. If there is an active debugger for the process (our current process is ptrace-ed by gdb or strace), then send_signal will translate the signal SIGFPE to the current process from do_trap into SIGTRAP to debugger. If no debugger - the signal SIGFPE should kill our process while saving the core file, because that is the default action for SIGFPE (check man 7 signal in the section "Standard signals", search for SIGFPE in the table).
The process can't set SIGFPE to ignore it (I'm not sure here: 1), but it can define its own signal handler to handle the signal (example of handing SIGFPE another). This handler may just print %eip from siginfo, run backtrace() and die; or it even may try to recover the situation and return to the failed instruction. This may be useful for example in some JITs like qemu, java, or valgrind; or in high-level languages like java or ghc, which can turn SIGFPE into a language exception and programs in these languages can handle the exception (for example, spaghetti from openjdk is in hotspot/src/os/linux/vm/os_linux.cpp).
There is a list of SIGFPE handlers in debian via codesearch for siagaction SIGFPE or for signal SIGFPE