Assembly code for a multi-proxy smart contract implementation - solidity

Need some help modifying the proxy assembly code to work with multiple (n) implementation contracts.
I need the function to revert if the implementation contract reverted, but keep on going if the implementation contract doesn't have the requested function
for (uint256 i = 0; i < implementations.length; ++i) {
address implementation = implementations[i];
assembly {
// Copy msg.data. We take full control of memory in this inline assembly
// block because it will not return to Solidity code. We overwrite the
// Solidity scratch pad at memory position 0.
calldatacopy(0, 0, calldatasize())
// Call the implementation.
// out and outsize are 0 because we don't know the size yet.
let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
// Copy the returned data.
returndatacopy(0, 0, returndatasize())
switch result
// delegatecall returns 0 on error.
case 0 {
// revert(0, returndatasize())
//TODO: Revert only if the function was indeed found on the Target Contract
}
default {
return(0, returndatasize())
}
}
}
//If Nothing Found
revert("NO_SUCH_FUNCTION");

Related

Solidity: I need to reference bytes constants efficiently

I am implementing an on-chain font in Solidity. It works great, but I am not able to eliminate unnessary copies of bytes from code space (bytes constants) to the storage.
Here is the current implementation.
contract LondrinaSolid is IFontProvider {
uint constant fixed_height = 1024;
uint constant fixed_baseline = 805;
bytes constant font_0 = "\x4d\x60\xd1\x74\x05\x43\x8a\x56\x1f\x29\x56\x0b\xd2\x55\x21\x63\x50\x00\x00\x45\x62\x2e\x45\x4a\xc5\x45\xf4\x19\x45\xf5\x4b\x45\xf3\xb0\x45\xff\x65\x45\xfe\xeb\x55\x39\x2e\x56\x3b\x44\x55\x8b\x73\x65\x0c\x4c\x05\x73\xc0\x45\x02\xc5\x35\x97\x63\x50\x05\x95\x44\xfe\x21\x44\xb7\xcd\x03\x5a\x6d\x40\x75\x54\x06\x63\xfc\x54\x83\xe6\x54\x99\xc7\x54\x9a\xe0\x54\x01\xe3\x44\xf5\xd2\x44\xc9\xef\x44\xd5\xef\x44\x66\xef\x44\x66\x0b\x45\x72\x0b\x45\x3e\x40\x45\x40\x73\x50\x3d\x73\x55\x39\xf7\x05\x5a";
bytes constant font_1 = "\x4d\x50\xbc\x27\x06\x73\xf7\x54\xf4\xf5\x64\x27\xfe\x54\xc6\xfe\x54\xc6\x63\x50\x00\x00\x55\x4e\x0d\x55\x7c\x0c\x05\x73\x4e\x45\xfb\x4f\x45\xea\x05\x35\x8a\x08\x35\x61\x04\x35\xbd\xfe\x34\xaf\x63\x50\x00\x00\x45\xa1\xfa\x44\x7e\xfb\x04\x73\x9d\x54\x02\x99\x54\x01\x63\x50\x00\x00\x45\xbd\x64\x45\xac\x80\x05\x53\x09\x55\xfb\x0a\x65\x0d\x63\x50\x00\x00\x55\x1b\x14\x55\x4b\x1f\x05\x73\x46\x55\x0f\x4b\x55\x0f\x18\x45\xf9\x1c\x45\xed\x5a\x00";
bytes constant font_2 = "\x4d\x50\xd3\x57\x06\x73\x0a\x45\xa6\x18\x45\x93\x39\x45\xd6\x4b\x55\x0d\xfe\x54\x66\xcc\x54\x81\xb4\x54\x33\x7f\x54\x53\xb6\x54\x3b\xb2\x54\x41\xe8\x54\x24\xe3\x54\x4f\xf6\x54\xbb\xf5\x54\xc3\x63\x50\x00\x00\x55\x0f\x04\x55\x1e\x05\x05\x73\xbd\x45\xfb\xd4\x45\xfb\xee\x45\xfd\xf6\x45\xfd\x08\x45\xfa\x08\x45\xf7\xfd\x44\xb7\xff\x44\xab\xfd\x44\xcc\xf6\x44\xbc\x63\x50\x00\x00\x45\x04\x06\x35\xe9\x02\x55\x00\x00\x55\x23\xb5\x54\x48\x9f\x04\x73\x99\x45\xb4\xb9\x45\x90\x31\x45\xc5\x31\x45\x7f\xfc\x44\x56\xa4\x44\x14\xf2\x43\xe0\xc0\x53\x02\x53\x40\xf6\xbb\x55\x15\x58\x06\x63\x00\x55\x00\x39\x55\x15\xbe\x45\xff\x5a\x00";
...
bytes constant font_X = "\x4d\x50\x09\x35\x05\x73\x40\x55\x93\x4f\x55\xc7\x2f\x55\x94\x2e\x55\xad\xce\x54\xaa\xc8\x54\xbe\xcd\x54\xa5\xc9\x54\xad\x63\x50\x00\x00\x55\x28\x10\x55\x60\x0e\x05\x73\x50\x45\xfd\x50\x45\xfd\x63\x50\x00\x00\x55\x1e\xaf\x54\x25\x98\x04\x73\x1f\x45\x96\x1f\x45\x96\x63\x50\x00\x00\x55\x1c\x6a\x55\x20\x7a\x05\x73\x13\x55\x48\x19\x55\x51\x63\x50\x00\x00\x55\x30\x0e\x55\x5d\x09\x05\x73\x52\x55\x01\x57\x55\x02\x63\x50\x00\x00\x45\xe5\x9f\x44\xd8\x6e\x04\x73\xc5\x44\x3a\xc2\x44\x1d\x63\x50\x00\x00\x55\x34\x52\x54\x41\x29\x04\x73\x34\x45\x51\x34\x45\x51\x63\x50\x00\x00\x45\xb3\x01\x45\xa2\x01\x05\x73\xa1\x54\x03\x99\x54\x04\x63\x50\x00\x00\x45\xca\xc9\x45\xc5\xd0\x55\x00\x00\x45\xe3\xa5\x44\xe0\x93\x04\x73\xe8\x44\xa0\xe8\x44\xa0\x63\x50\x00\x00\x45\x76\xff\x44\x3b\x05\x05\x5a";
bytes constant font_Y = "\x4d\x50\x17\x30\x05\x73\x19\x55\x59\x30\x55\x8d\x57\x55\xdc\x57\x55\xe8\x63\x50\x00\x00\x45\xc5\x9e\x45\xbd\xb1\x05\x53\x12\x85\x1d\x10\x85\x22\x63\x50\x00\x00\x55\x42\x04\x55\x64\x03\x05\x73\x4a\x45\xfd\x58\x55\x01\x63\x50\x00\x00\x55\x3f\x56\x54\x55\x2e\x04\x53\xb6\x66\x15\xcb\x56\xe0\x73\x50\x39\x5f\x54\x3a\x51\x04\x63\x00\x55\x00\xb2\x44\xf2\x4c\x54\x07\x00\x55\x00\xbb\x54\xc7\xb9\x54\xcc\x00\x55\x00\xbe\x44\x48\xbc\x44\x34\x00\x55\x00\xeb\x44\xee\xab\x44\xf3\x73\x40\xc0\x08\x45\xa5\x07\x05\x5a";
bytes constant font_Z = "\x4d\x50\x0b\x33\x05\x73\x0a\x55\x33\x09\x55\x4f\x03\x55\x4b\x0d\x55\x54\x63\x50\x00\x00\x55\xeb\x06\x55\xfc\x0c\x55\x00\x00\x45\x8a\xa5\x45\x7a\xb9\x05\x53\x26\x75\x4a\x19\x75\x73\x63\x50\x00\x00\x55\x01\x44\x55\x01\x5c\x05\x73\x04\x55\x4e\x0c\x55\x58\x63\x50\x00\x00\x55\xab\xf8\x54\xcf\xf9\x04\x73\xdb\x55\x03\x06\x56\x07\x63\x50\x00\x00\x55\x0e\x6b\x54\x02\x46\x54\x00\x00\x45\x0c\xff\x34\xf6\x08\x55\x00\x00\x55\x92\x2d\x54\xa4\x14\x04\x73\x6a\x45\x64\x6d\x45\x59\x01\x45\xad\x02\x45\x9d\xff\x44\xb5\xfc\x44\xb0\x63\x50\x00\x00\x45\x35\xfd\x44\x12\xfc\x04\x73\x3f\x54\x01\xf7\x53\x09\x5a\x00";
mapping(uint => bytes) fontData;
mapping(uint => uint) widths;
constructor() {
registerAll();
}
function _register(string memory _char, bytes memory _bytecode, uint _width) internal {
uint key = uint(uint8(bytes(_char)[0]));
if (_bytecode.length > 0) {
fontData[key] = _bytecode;
}
widths[key] = _width;
}
function registerAll() external onlyOwner {
_register("0", font_0, 554);
_register("1", font_1, 414);
_register("2", font_2, 540);
...
_register("X", font_X, 531);
_register("Y", font_Y, 531);
_register("Z", font_Z, 531);
}
function height() external pure override returns(uint) {
return fixed_height;
}
function baseline() external pure override returns(uint) {
return fixed_baseline;
}
function widthOf(string memory _char) external view override returns(uint) {
uint key = uint(uint8(bytes(_char)[0]));
return widths[key];
}
function pathOf(string memory _char) external view override returns(bytes memory) {
uint key = uint(uint8(bytes(_char)[0]));
return fontData[key];
}
}
The problem is in the _register method, which stores the mapping between the charactor and the vector data in the "fontData". Even thought the font data itself is already in this smart contract, it copies it to the "memory" space when calling this method and copies it into the "storage", which is quite expensive (12M units of gas).
One possible work around is to eliminate the _register method, and implement a binary search in pathOf method to directly return font_X, but that code is ugly and not scalable.
Ideally, I just want to store the references to those font data in "fontData" and return them in pathOf method.
I'd appreciate any suggestions, including writing some assembly solution (which I am comfortable with).
I was able to solve this problem by creating a function for each font, and having a mapping from character codes to those functions in the storage.
With this change, I was able to reduce the deployment cost of one particular font from 0.13ETH to 0.027ETH (assuming 30gwei gas price).

Invalid pointer operation when freeing TStreamAdapter

Can anyone clarify why do I get "Invalid pointer operation" when I attempt to delete TStreamAdapter? Or... how to properly free the memory from TStreamAdapter? It works, if I remove the delete but that causes a memory leak. Even if I use boost::scoped_ptr it also fails with the same error.
Note: I also tried initializing TStreamAdapter with soOwned value, same error.
The code:
HRESULT LoadFromStr(TWebBrowser* WB, const UnicodeString& HTML)
{
if (!WB->Document)
{
WB->Navigate("about:blank");
while (!WB->Document) { Application->ProcessMessages(); }
}
DelphiInterface<IHTMLDocument2> diDoc = WB->Document;
if (diDoc)
{
boost::scoped_ptr<TMemoryStream> ms(new TMemoryStream);
{
boost::scoped_ptr<TStringList> sl(new TStringList);
sl->Text = HTML;
sl->SaveToStream(ms.get(), TEncoding::Unicode);
ms->Position = 0;
}
DelphiInterface<IPersistStreamInit> diPSI;
if (SUCCEEDED(diDoc->QueryInterface(IID_IPersistStreamInit, (void**)&diPSI)) && diPSI)
{
TStreamAdapter* sa = new TStreamAdapter(ms.get(), soReference);
diPSI->Load(*sa);
delete sa; // <-- invalid pointer operation here???
// UPDATED (solution) - instead of the above!!!
// DelphiInterface<IStream> sa(*(new TStreamAdapter(ms.get(), soReference)));
// diPSI->Load(sa);
// DelphiInterface is automatically freed on function end
return S_OK;
}
}
return E_FAIL;
}
Update: I found the solution here - http://www.cyberforum.ru/cpp-builder/thread743255.html
The solution is to use
_di_IStream sa(*(new TStreamAdapter(ms.get(), soReference)));
or...
DelphiInterface<IStream> sa(*(new TStreamAdapter(ms.get(), soReference)));
As it will automatically free the IStream once it is out of scope. At least it should - is there a possible memory leak here? (CodeGuard did not detect any memory leaks).
TStreamAdapter is a TInterfacedObject descendant, which implements reference counting semantics. You are not supposed to delete it at all, you need to let reference counting free the object when it is no longer being referenced by anyone.
Using _di_IStream (which is just an alias for DelphiInterface<IStream>) is the correct way to automate that with a smart pointer. TComInterface<IStream> and CComPtr<IStream> would also work, too.

Can we use constant and returns keyword and a;change the state of the variables in solidity?

the warnings say that the function is declared as view and those lines are changing the state. i want a return statement but also want to do the addition and subtraction in the function body(ie., change the state). is it possible in solidity?
(this code is a part of the ERC20 token
function _transferToken(address _from, address _to, uint _value) constant public returns (string)
{
// Prevent transfer to 0x0 address. Use burn() instead
if(_to == 0x0)
{
return "Invalid address";
}
// Check if the sender has enough
else if(balanceOf[_from] < _value)
{
return "insufficient tokens";
}
// Check for overflows
else if(balanceOf[_to] + _value < balanceOf[_to])
{
return "Transaction failed";
}
else
{
// Subtract from the sender
balanceOf[_from] = balanceOf[_from] - _value; ***warning***
// Add the same to the recipient
balanceOf[_to]=balanceOf[_to] + _value; *****warning*****
return("Successful");
}
}
If you declare a function as view, you must not modify the state. This is not enforced yet, the compiler only raises a warning. But what you are planning on doing is not possible with a view function.
Calling a view function from off chain doesn't cost you any ether because you don't change the state or run any computations on the actual blockchain.
Besides, you shouldn't use the constant modifier for functions anymore. It is an alias for view and is deprecated.
It will be dropped in version 0.5.0 as stated in the official documentation here.

C++/CLI pin_ptr's usage in proper way

I am newbie of C++/CLI.
I already know that the pin_ptr's functionality is making GC not to learn to specified object.
now let me show you msdn's example.
https://msdn.microsoft.com/en-us//library/1dz8byfh.aspx
// pin_ptr_1.cpp
// compile with: /clr
using namespace System;
#define SIZE 10
#pragma unmanaged
// native function that initializes an array
void native_function(int* p) {
for(int i = 0 ; i < 10 ; i++)
p[i] = i;
}
#pragma managed
public ref class A {
private:
array<int>^ arr; // CLR integer array
public:
A() {
arr = gcnew array<int>(SIZE);
}
void load() {
pin_ptr<int> p = &arr[0]; // pin pointer to first element in arr
int* np = p; // pointer to the first element in arr
native_function(np); // pass pointer to native function
}
int sum() {
int total = 0;
for (int i = 0 ; i < SIZE ; i++)
total += arr[i];
return total;
}
};
int main() {
A^ a = gcnew A;
a->load(); // initialize managed array using the native function
Console::WriteLine(a->sum());
}
hear is the question.
Isn't it okay, the passed object(arr) not pinned ?
because the unmanaged code(native_function) is sync operation and finished before the C++/CLI code (load)
is there any chance the gc destory arr, even though the main logic is running?
(I think A is main's stack variable and arr is A's member variable, so while running main, it should visible)
if so, how can we guarantee that the A is there before invoking load?
(only while not running in native-code?)
int main() {
A^ a = gcnew A;
// I Think A or arr can be destroyed in here, if it is able to be destroyed in native_function.
a->load();
...
}
Thanks, in advance.
The problem that is solved by pinning a pointer is not a normal concurrency issue. It might be true that no other thread will preempt the execution of your native function. However, you have to count in the garbage collector, which might kick in whenever the .NET runtime sees fit. For instance, the system might run low on memory, so the runtime decides to collect disposed objects. This might happen while your native function executes, and the garbage collector might relocate the array it is using, so the pointer you passed in isn't valid anymore.
The golden rule of thumb is to pin ALL array pointers and ALL string pointers before passing them to a native function. ALWAYS. Don't think about it, just do it as a rule. Your code might work fine for a long time without pinning, but one day bad luck will strike you just when it's most annoying.

Safely detect, if function is called from an ISR?

I'm developing software for an ARM Cortex M3 (NXP LPC1769) microncontroller. At the moment I'm searching for a mechansim to detect if my function is called within an ISR. I asume that I have to check a register. Based on this information I would like to call difficult functions.
I already checked the reference manual, if there is a register containing the necessary information.
For example I tried to detect if I'm called from an ISR (I used SysTick-ISR) based on the "Interrupt Active Bit Register" (IABR) register. This register should be != 0 if an ISR is active. But the value was 0x00000000. This implies that no interrupt is active. Besides this test I checked the NVIC and SC register in the reference manual searching for a register containing the necessary flag but I didn't found one.
Does anybody know a suitable register / mechanism for my problem?
You need to test the VECTACTIVE field of the Interrupt Control State Register.
I use the following:
//! Test if in interrupt mode
inline bool isInterrupt()
{
return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0 ;
}
SCM and SCB_ICSR_VECTACTIVE_Msk are defined in the CMSIS (core_cm3.h), which I imagine would be included indirectly by your part specific header (lpc17xx.h or similar I guess). I am using C++, including stdbool.h in C will get you a bool type, or change to an int or typedef of your own.
It is then used thus for example:
void somefunction( char ch )
{
if( isInterrupt() )
{
// Do not block if ISR
send( ch, NO_WAIT ) ;
}
else
{
send( ch, TIMEOUT ) ;
}
}
If a solution is required that assumes no knowledge of the architecture consider the following:
volatile int interrupt_nest_count = 0 ;
#define ENTER_ISR() interrupt_nest_count++
#define EXIT_ISR() interrupt_nest_count--
#define IN_ISR() (interrupt_nest_count != 0)
void isrA()
{
ENTER_ISR() ;
somefunction( 'a' ) ;
EXIT_ISR() ;
}
void isrB()
{
ENTER_ISR() ;
somefunction( 'b' ) ;
EXIT_ISR() ;
}
void somefunction( char ch )
{
if( IN_ISR() )
{
// Do not block if ISR
send( ch, NO_WAIT ) ;
}
else
{
send( ch, TIMEOUT ) ;
}
}
However the question refers to safely detecting the interrupt context, and this relies on the enter/exit macros being added to all ISRs.
After some discussion and more searching I found the right register:
Interrupt Program Status Register: The IPSR contains the exception type number of
the current Interrupt Service Routine (ISR). See the register summary in Table 626 for
its attributes.
If a function isn't called from an isr the value of the register is IPSR == 0
The simplest method is to pass the context as a parameter to the function. It is also platform independent.
typedef enum _context {
normal_context = 0,
isr_context = 1
} context;
Call to the function from ISR:
func(param1, param2, isr_context);
Call to the function from normal code:
func(param1, param2, normal_context);
If the ISR code is not under your control and you are just passing a function pointer, then just use two different wrapper functions. One that passes isr_context and another that passes normal_context as a parameter to the function.
The best way is probably to make two different functions: one that is called from the ISR and another that is called from the rest of the program.
If that isn't an option, then you could determine the caller with pure standard C, no registers needed:
inline void my_func (const char* caller);
static void isr (void)
{
my_func(__func__);
}
inline void my_func (const char* caller)
{
if(strcmp(caller, "isr")==0)
{
// was called from isr
}
else
{
// called from elsewhere
}
}
If you give your ISRs smart names, the above code will be quick enough to run from an isr.