ethereum / ethereum/populus

mapping's used gas changes based on index used as static value or a variable. Probably usedGas returns transaction instead of execution cost.

Open
#276 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
No language data
Stars
319
Forks
110
PR merge metrics
No merged PRs in 30d

Description

- platform darwin -- Python 2.7.12, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
- plugins: populus-1.1.0
- OS: Mac OS X

You could see my question on the following link: http://ethereum.stackexchange.com/questions/13433/mappings-used-gas-changes-based-on-index-used-as-static-value-or-a-variable

Other people tried my code and observed that used gas is same for both two codes on solidity environment. But on the populus environment the usedGas differs. I have used `usedGas` parameter to obtain the tx gas value.

[Q] What may be the reason of the problem?

Here is my code:
**Used gas = 86658** (Probably usedGas returns Transaction Cost!)

self.list_[selfSize] = Interval( { num: e - 1, core: c, next: self.head });
self.list_[selfSize + 1] = Interval( { num: 10, core: 10, next: 10 });

//self.list_[selfSize] = Interval( { num: e - 1, core: c, next: self.head });//commented out!!
//self.list_[3] = Interval( { num: 10, core: 10, next: 10 });//commented out!!

-- or
**Used gas = 65220** (Probably usedGas returns Execution Cost!)

//self.list_[selfSize] = Interval( { num: e - 1, core: c, next: self.head });//commented out!!
//self.list_[selfSize + 1] = Interval( { num: 10, core: 10, next: 10 });//commented out!!

self.list_[selfSize] = Interval( { num: e - 1, core: c, next: self.head });//used GAS = 65220
self.list_[3] = Interval( { num: 10, core: 10, next: 10 });

--As you can see both code accessing to index value 2 and 3.

Contract: **Array.sol**

pragma solidity ^0.4.8;
library ReceiptLib {
struct Interval {
uint32 num;
int32 core;
uint32 next;
}

struct intervalNode {
uint32 den;
mapping(uint32 => Interval) list_;
uint32 len;
uint32 head;
int32 coreLimit;
}
function constructReceipt(intervalNode storage self){
self.head = 1; //self.listSize - 1;
self.coreLimit = 128;

self.list_[0] = Interval( { num: 0, core: 0, next: 0 });
self.list_[1] = Interval( { num: 0, core: 0, next: 0 });
self.len = 2;
}
function number(intervalNode storage self, uint32 s, uint32 e, int32 c){
uint32 selfSize = self.len;
//self.list_[selfSize] = Interval( { num: e - 1, core: c, next: self.head });
//self.list_[selfSize + 1] = Interval( { num: 10, core: 10, next: 10 });

self.list_[selfSize] = Interval( { num: e - 1, core: c, next: self.head });
self.list_[3] = Interval( { num: 10, core: 10, next: 10 });
}
}

contract Array{
using ReceiptLib for ReceiptLib.intervalNode;
ReceiptLib.intervalNode receiptList;

function Array(){
receiptList.constructReceipt();
}
function test(uint32 s, uint32 e, int32 c) {
receiptList.number(s, e, c);
}
}

**test.py:**
```
def test_receipt(web3, accounts, chain, unmigrated_chain):
my_contract = unmigrated_chain.get_contract('Array');
set_txn_hash = my_contract_1.transact().test(10, 20, 2);
contract_address = unmigrated_chain.wait.for_receipt(set_txn_hash)
print(contract_address["gasUsed"]);
```

screen shot 2017-03-25 at 05 48 43

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with test.py, the Array contract, and the unmigrated_chain.get_contract and wait.for_receipt entry points. Reproduce both mapping-index variants and compare the reported gasUsed values; done means the discrepancy between transaction cost and execution cost is explained and the expected behavior is documented or corrected.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, solidity
Domain
blockchain, testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.