gun icon indicating copy to clipboard operation
gun copied to clipboard

How to validate user data?

Open Osiris-Team opened this issue 2 years ago • 8 comments

Couldn't find this in the docs or issues. Is there something like this built in gun?

I thought this could be done somewhat like this: User A says 1+1=3 and adds 3 to an intermediate database. Other users then get assigned to perform the same operation user A did and see if the result is correct. This means that we need a majority to say yes the value is correct and determine a user that adds the value to the main database. In this case, the majority says no and thus the value doesn't get added to the main database.

Since it's all client-side code anyways, if the user knows a bit of javascript he/she could skip the intermediate database part and update directly the main database. So we need users to listen to changes on the main database directly and correct the data if it's wrong?

This would mean that the majority of the users must be "good" users that have not removed the correction of wrong values part from their javascript code. So I need some sort of bot-protection too when the user first installs my app. Like recaptcha.

Osiris-Team avatar Apr 02 '22 22:04 Osiris-Team

moderation like stuff?

atordvairn avatar Apr 03 '22 10:04 atordvairn

you can't control public data in decentralised systems what you can do is to not to render them. ex: a post has more dislikes than likes, hide it.

atordvairn avatar Apr 03 '22 10:04 atordvairn

Example for clarification: If I wanted to create a multiplayer game, where the coordinates x, y, z of each player are shared among each other, then each player would have to check if the new position of the other player is valid, based on the position the player had before and the maximum allowed movement. Otherwise, people just could fly around or run faster than others and teleport to different places.

Of course the majority of the players would have had to agree on the maximum allowed movement speed before starting the game.

Osiris-Team avatar Apr 03 '22 11:04 Osiris-Team

hmmm, that's hard to take care of

the only thing that comes in my mind is to compare the before and after coordinates to validate..

atordvairn avatar Apr 03 '22 11:04 atordvairn

Yeah then the question would be if all players have the latest last coordinates of one another. If one player has the last coordinate of another player, that actually is the last coordinate of 3 seconds ago, the validation will fail and the player thinks that the person teleported and will try to fix the value which would throw the other player back. So I would have to trust gun that the data is synchronized correctly.

Or add a limit of how often one player tries to change the other players' position. Idk. thats why Im asking ^^

Osiris-Team avatar Apr 03 '22 11:04 Osiris-Team

You are discovering why smart contracts were created @Osiris-Team :)

Gun can only take you so far in terms of decentralized use cases. Eventually you do need something like smart contracts to coordinate.

But I don't think there is a smart contract system that works at speeds needed to run a real online game.

So what people would do most of the time is have the "contract" handled by a closed source game app and only let the game app update the Gun db (don't let the users update their own position)

trosel avatar May 01 '22 04:05 trosel

Ok I hoped there would be something like that implemented in gun. Since data validation is kind of an important topic in a decentralized database I think. It would be cool to have to simply enable a validation method, and all the complicated stuff happens under the hood. Just throwing ideas around, have no clue how any of this works. @amark are there any plans in implementing something like this?

Osiris-Team avatar May 01 '22 09:05 Osiris-Team

Since data validation is kind of an important topic in a decentralized database I think.

It's a question of use case more than capability. You can moderate content in Gun through various patterns. You can have different levels of permissions as well (contributor, editor, owner).

But the use case you described... I don't think that is possible in any decentralized system today. If you're open to hearing other possible solutions, there may be a different way of looking at the problem.

trosel avatar May 01 '22 16:05 trosel

@Osiris-Team Do you have any solution to this? Here's something I'm trying, let me know if you have a come to a better solution.

var Gun = require('gun');

function extractUserPayload(msg) {
    let payload = {};
    let fullPath = '';

    Object.keys(msg.put).forEach((key) => {
        fullPath = key;
    });

    payload = msg.put[fullPath];
    delete payload['_']

    console.log({ fullPath, payload });

    return { fullPath, payload };
}

Gun.on('opt', function (ctx) {
    if (ctx.once) {
        return
    }

    ctx.on('in', function (msg) {
        const to = this.to
        if (msg.put) {

            /* Get the user payload and do some validation.
               The validate() function below hasn't been implemented.
               You can use your own validation function that validates the extracted payload */
            const validated = validate(extractUserPayload(msg));

            /* call next() if its valid or ignore if not validated */
            if (validated) to.next(msg)
        }

    })
})

var gun = Gun({ web: config.server.listen(config.port), peers: config.peers });

console.log('Relay peer started on port ' + config.port + ' with /gun');

JohnYepthomi avatar Oct 13 '22 02:10 JohnYepthomi

@JohnYepthomi thanks for sharing your code! No I didn't find any solution, but that's mostly because I didn't start the project I would require this in.

Osiris-Team avatar Oct 13 '22 18:10 Osiris-Team

@Osiris-Team you're correct. @trosel is correct that performance matters, but even then, you'd never want this on a smart contract (see later).

The way you described doing it is how to do it. GUN.state.is(node, key) will return the vector/timestamp of the update, so you use this when calculating time differentials. If state_a is at posX and then state_b is at posX+100000 then clearly it violates.

You do NOT want every peer in a network enforcing this logic, which is what smart contracts do, this is a terrible idea that does not scale. Your application is the p2p "smart contract", as only the peers running your app are the ones enforcing your app. So when your app logic sees an invalid update, don't render it!

Honest peers will see each other. Dishonest peers will vanish. Bonus mode: Show cheaters to only other cheaters, so they compete on cheating - a whole new meta game.

amark avatar Oct 19 '22 06:10 amark

I believe the fix for this is to implement consensus protocol. The app must have a key that validates the consensus mechanism implementation and version, then when a new data a peer arrives, that consensus will validate the data, if the format and content is valid, it does persist and propagate. When invalid it discard, creating a “fork” in the network and isolating bad actors and old versions.

pretty much same as smart contracts and IPFS.

To control that the new DB should have authorship public key(s) that will be used to match consensus implementation. Therefore every consensus script needs to be serialized and signed, and the public key to validate that signature goes with the DB constructor options.

For example:

gun({consensus:[“xxx”]});

// where callback is a function that can be serialized and it’s code is signed by the private key that owns the public key of the consensus xxx const getRule = gun.contract(callback, signature);

const putRule = gun.contract(callback, signature);

gun.get(‘something’, getRule).put(dataObj, putRule);

Therefore let’s say that the put rule prevent data to be deleted at all, it can only be added to the dataObj. Once the peer sync this change it can validate the new dataObj and if fail the consensus execution, it ignores the change.

if a peer spam the change it can get banned from the peer, therefore removing bad actors from the network.

it doesn’t prevent bad consensus implementation, but, gives tools to devs to prevent someone to open the source code delete data and propagate the damage to the network. Or restrict who can do certain changes by requiring some kind of signature to create admin access, that kind of thing.

gartz avatar Apr 09 '23 17:04 gartz

Thanks for the extra ideas. There's about 30 different ways this could be implemented and is extremely specific to the app, so yeah the app should do this/define the rules. GUN let's you extend itself GUN.chain.contract = function(){ ... so challenge: Get 5 devs to all implement their own version of this, then test/play with each others, see which one is the best. Whoever wins we'll have it published as a gun module or if super popular, even pull it into this repo (if its not super bloated).

Gonna close, since pretty detailed answers have been provided, & trying to keep github issues relevant to current existing bugs.

amark avatar May 11 '23 10:05 amark