Git Product home page Git Product logo

diamond-3's People

Contributors

evert0x avatar mudgen avatar wighawag avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

diamond-3's Issues

Upgrading structure in library

Hi, Nick!
Brilliant conception, awesome ideas!
Did you tested next case:

  1. we deploy LibDiamond.sol as separate library
  2. we linking this to Diamond.sol
  3. add some datas
  4. NEXT - adding or changing structure in LibDiamond.sol (adding new variables, changing old)
  5. deploying this again and link to existing Diamond.sol.
    Question 1 is it possible?)
    Question2 - have it backward compatibility? So can "old" stored data form p.3 be accessed/modified through new, changed in p.4 structure?

Tests are exceeding block gas limit

Hi, love the project :).

I'm using the latest version from Master. And the default tests are exceeding the block limit.

`evert@EvertX1:/piedao/Diamond$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
evert@EvertX1:
/piedao/Diamond$ truffle test
Using network 'development'.

Compiling your contracts...

Everything is up to date, there is nothing to compile.

Contract: Cache bug test
✓ should not exhibit the cache bug

Contract: DiamondTest
✓ should have three facets -- call to facetAddresses function
✓ facets should have the right function selectors -- call to facetFunctionSelectors function (51ms)
✓ selectors should be associated to facets correctly -- multiple calls to facetAddress function (42ms)
✓ should get all the facets and function selectors of the diamond -- call to facets function
✓ should add test1 functions (139ms)
✓ should add test2 functions (171ms)
✓ should remove some test2 functions (90ms)
1) should remove some test1 functions
> No events were emitted
2) remove all functions and facets accept diamondCut and facets
> No events were emitted
3) add most functions and facets
> No events were emitted

8 passing (3s)
3 failing

  1. Contract: DiamondTest
    should remove some test1 functions:
    Error: Returned error: Exceeds block gas limit
    at Object.ErrorResponse (/home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/node_modules/web3-core-helpers/src/errors.js:29:1)
    at /home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/node_modules/web3-core-requestmanager/src/index.js:140:1
    at /home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/packages/provider/wrapper.js:112:1
    at XMLHttpRequest.request.onreadystatechange (/home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/node_modules/web3-providers-http/src/index.js:96:1)
    at XMLHttpRequestEventTarget.dispatchEvent (/home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request-event-target.js:34:1)
    at XMLHttpRequest._setReadyState (/home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:208:1)
    at XMLHttpRequest._onHttpResponseEnd (/home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:318:1)
    at IncomingMessage. (/home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:289:47)
    at endReadableNT (_stream_readable.js:1145:12)
    at process._tickCallback (internal/process/next_tick.js:63:19)

  2. Contract: DiamondTest
    remove all functions and facets accept diamondCut and facets:
    Error: Returned error: Exceeds block gas limit
    at Object.ErrorResponse (/home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/node_modules/web3-core-helpers/src/errors.js:29:1)
    at /home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/node_modules/web3-core-requestmanager/src/index.js:140:1
    at /home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/packages/provider/wrapper.js:112:1
    at XMLHttpRequest.request.onreadystatechange (/home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/node_modules/web3-providers-http/src/index.js:96:1)
    at XMLHttpRequestEventTarget.dispatchEvent (/home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request-event-target.js:34:1)
    at XMLHttpRequest._setReadyState (/home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:208:1)
    at XMLHttpRequest._onHttpResponseEnd (/home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:318:1)
    at IncomingMessage. (/home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:289:47)
    at endReadableNT (_stream_readable.js:1145:12)
    at process._tickCallback (internal/process/next_tick.js:63:19)

  3. Contract: DiamondTest
    add most functions and facets:
    Error: Returned error: Exceeds block gas limit
    at Object.ErrorResponse (/home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/node_modules/web3-core-helpers/src/errors.js:29:1)
    at /home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/node_modules/web3-core-requestmanager/src/index.js:140:1
    at /home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/packages/provider/wrapper.js:112:1
    at XMLHttpRequest.request.onreadystatechange (/home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/node_modules/web3-providers-http/src/index.js:96:1)
    at XMLHttpRequestEventTarget.dispatchEvent (/home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request-event-target.js:34:1)
    at XMLHttpRequest._setReadyState (/home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:208:1)
    at XMLHttpRequest._onHttpResponseEnd (/home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:318:1)
    at IncomingMessage. (/home/evert/.npm-global/lib/node_modules/truffle/build/webpack:/node_modules/xhr2-cookies/dist/xml-http-request.js:289:47)
    at endReadableNT (_stream_readable.js:1145:12)
    at process._tickCallback (internal/process/next_tick.js:63:19)

`

Data corruption in memory slots

Hi Nick!
Thanks for your idea - Brilliant Proxy :)

Do you know are there any ways to avoid problems with carruption of data?

For example, we have two structs with one pointer:

bytes32 constant POINTER = keccak256("any.pointer");

struct DataStruct {
    uint32 value;
    mapping(address => uint256) authsIndex;
    address[] auths;
}

struct DataStructV2 {
    uint256 value;
}

function getDataStruct() internal pure returns (DataStruct storage ds) {
    bytes32 position = POINTER;
    assembly {
        ds.slot := position
    }
}

function getDataStructV2() internal pure returns (DataStructV2 storage ds) {
    bytes32 position = POINTER;
    assembly {
        ds.slot := position
    }
}

If i write 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF in ds.DataStruct2.value, after writing 341234 in ds.DataStruct.value, then the second value overrides the first one. But its not ok)

Are there any ways to protect against overwriting old data with an other(new) struct in memory slot already occupied?

Help With New `diamondCut` Functions

If you want to contribute to this project, here's an opportunity to do so.

Make pull requests to implement the versions of diamondCut listed below or discuss new possible versions in the comments.

The implementations must be gas efficient.

Rational

Something that is currently missing from the Diamond Standard is a way to add/replace/remove functions and execute arbitrary code in the same transaction. This is needed for example to initialize/setup storage data after adding functions to a diamond.

It is possible to have different versions of the diamondCut function that take different arguments and work in different ways. However all versions are used to add/replace/remove functions from diamonds.

But before adding more versions of diamondCut to the Diamond Standard I want them implemented in this project. In addition, versions of diamondCut can exist and be used that are not defined in the Diamond Standard. The ones defined in the Diamond Standard are for compatibility between tools.

Just because a version of diamondCut doesn't exist in the Diamond Standard doesn't mean it can't exist and be used. I'd like this project to include a library of different versions of diamondCut that are useful in different circumstances.

What to Implement

Implement the following functions in DiamondFacet.sol or other file. All these functions can be private/internal/public/external.

  • diamondCut(bytes[] memory _diamondCut, address _initializer, bytes memory _data)

This version of diamondCut is used to execute arbitrary code after adding/replacing/removing functions and passing in _data as an argument to the arbitrary code.

_initializer is a contract with a function initialize(bytes memory _data) that is called using delegatecall. Obviously the parameter _data is passed from diamondCut to initialize.

  • diamondCut(bytes memory _diamondCut)

First 20 bytes is the facet address and the rest of the bytes are 4-byte function selectors.

  • diamondCut(address _facet, bytes memory _data)

This function is used to allow a new facet to add its functions to a diamond and execute arbitrary code, passing _data as an argument.

_facet should execute the initialize(bytes memory _data) using delegatecode. For example: _facet.delegatecall(abi.encodeWithSignature("initialize(bytes)", _data).

From within initialize(bytes memory _data) a facet should add its function selectors.

Other Versions

I am interested in suggestions and adding other versions of diamondCut to the project. Feel free to discuss ideas in the comments or in the Diamond Standard Discord: https://discord.gg/kQewPw2

Selector Aliases

For true interoperability of facets written and deployed by different authors, it would be useful if selectors could be aliased. For example, both a whitelist and a role management contract might have a function with the signature add(address).

As this would likely be a rare occurrence, the best implementation might be an AliasFacet contract, whose fallback function handles the routing of selector aliases to the target facets. The Diamond fallback would therefore remain gas-efficient.

How to Deploy Diamond contarct in README

Hi, Nick. i was going through the README and observed that the README is not showing new users how they can clone the diamond-3 repo and deploy it. Having clear steps on how to clone the repo, run tests and deploy the contracts to testnet and mainnet could help new blockchain developers explore this product.

If this can be included in the README, this would be nice. we don't assume that everyone coming to this repo is an experienced developer. Thanks

Error handling Events by facet..

Hi @mudgen ,
I have added few facets to my diamond successfully. Truffle Testing runs smooth.
But as I added this facet, here comes a problem:
I want to put all events into one Facet. The Facet code is like this:

F_events.sol:

pragma solidity ^0.6.12;
// SPDX-License-Identifier: MIT

import "./DiamondStorageContract.sol";

contract F_events is DiamondStorageContract{
  event simpleEvent(string eventNotice);
}

The testing Code is this:

...
    it('should add F_events functions', async () => {
      const selectors = getSelectors(f_events)
      addresses.push(f_events.address)
      result = await diamondFacet.methods.diamondCut([f_events.address + selectors]).send({ from: web3.eth.defaultAccount, gas: 1000000 })
      result = await diamondLoupeFacet.methods.facetFunctionSelectors(addresses[7]).call()
      assert.equal(result, '0x' + selectors)
    })

and it give this error:
image

Possible Gas Optimization in diamondCut

Currently the diamondCut implementation copies calldata to memory. What if we didn't do this and just used the calldata? I check to see if this is possible and if we get a gas savings.

FILE test/diamondTest.js not passing on node v15.2.1

TypeError: Cannot add property 3, object is not extensible
cause by line 120

addresses.push(test1Facet.address)

fix by doing line 68 (array deep copy)

addresses = [...await diamondloupefacet.methods.facetaddresses().call()]

Fallback Fallback

It is conceivable that the author of a Diamond contract might wish to implement a custom fallback function, but the current design does not allow this.

A possible implementation would allow a fallback address to be set rather than a function. This address would contain code that itself implements a fallback function.

[Feature] Implementing self-balanced tree in order to keep all facets

Hi there!

I just briefly checked the code and realized that in order to keep all facets current diamond version uses a dynamically allocated array and simple mapping for getting O(1) per getFacet() query. What if we could simply store everything in a tree in order to get O(log n) for getFacet() query without having a need to allocate an array and mapping(it looks kind of crutch in a code)?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.