3box-js icon indicating copy to clipboard operation
3box-js copied to clipboard

Error "Could not append entry, key "did..."" @ openBox w/ older account

Open oznekenzo opened this issue 6 years ago • 16 comments

I'm getting the following error when attempting to openBox with an old(er) account w/ lib version 1.10.5:

Uncaught (in promise) Error: Could not append entry, key "did:3:zdpuAupxYZEMM2PmieSNRUQLk7Cn1s36fbc9LwLBnGuUdAvvC" is not allowed to write to the log
    at permitted (log.js:363)

This is happens regardles off # of loads and is preventing a successful openBox.

oznekenzo avatar Aug 09 '19 16:08 oznekenzo

Same thing happening to me with an old account and 3box v13.1.0

brunobar79 avatar Oct 29 '19 01:10 brunobar79

Thanks for reporting @brunobar79 this seems to be happening randomly and I've been unable to recreate it consistently. Does this happen for you every time you call Box.openBox? Does this block the openBox promise from resolving?

oed avatar Oct 30 '19 10:10 oed

I can reproduce 100% of the time with an account that I've used with 3box a long time ago. It works fine with newly created eth accounts.

It happens every time I call Box.openBox and it doesn't block, it rejects the promise because the error is thrown. For better understanding take a look at the img below.

Screen Shot 2019-10-30 at 2 18 06 PM

brunobar79 avatar Oct 30 '19 18:10 brunobar79

Ok, that's good that it's replicatible. Would you mind sending me the address this is happening with so that I can investigate?

oed avatar Oct 30 '19 18:10 oed

This one gives problems: 0xE46aBAf75cFbFF815c0b7FfeD6F02B0760eA27f1

brunobar79 avatar Oct 30 '19 18:10 brunobar79

Thanks @brunobar79 I've tried to replicate the error by syncing the data of your address but have not been able to. If you run the example dapp in this repo (latest develop) do you still see this issue?

oed avatar Oct 31 '19 11:10 oed

This is happening with me as well, 100% of the time: 0xfD77Ee24B43F3Aa0f7389dF2B43d3eF5BF0d41DC

ps2-controller avatar Oct 31 '19 22:10 ps2-controller

Here's a sample code which will succeed with address and privKey for: 0x32684523CfA7F9CFEBBc954Ad40E4f3521BA9bBc

but fail for 0xfD77Ee24B43F3Aa0f7389dF2B43d3eF5BF0d41DC

I have also used the failing address in the past for 3box, but the succeeding address is new. Hope this helps!

async function makeA3Box(address, privateKey) {
    let ethereum = {
        sendAsync: function (data, callback) {
            let messageHash = EthCrypto.hash.keccak256(data.params[0]);
            let signature = EthCrypto.sign(privateKey, messageHash)
            callback(null, {result: signature})
            return signature
        }
    }
    const box = await Box.openBox(address, ethereum)
    return box
}

ps2-controller avatar Nov 01 '19 02:11 ps2-controller

Apparently I was signing the messages differently that I did in the past when I used 3box via MetaMask. The signatures are not matching at that's why old accounts like this one were not matching and new ones don't have that problem (because there's nothing to match against (?)

I've fixed that on my end and now I'm able to open the box and the space 🎉 but I'm still getting the same error while trying to write in a private space (reading works fine).

I'll investigate more and update this thread if there's any find.

brunobar79 avatar Nov 01 '19 02:11 brunobar79

I've deployed the latest example from develop branch to https://3box-example.netlify.com Here's a video where you can see that using MetaMask (not a custom provider) I can open the box and the space but it breaks with the same error (Could not append entry, key ... ) while trying to write any date to the space (public or private) with the same error.

http://recordit.co/i4rHwO6uyT

BTW: Writing to the private store (not in the space!) works fine.

brunobar79 avatar Nov 01 '19 02:11 brunobar79

Thanks @ps2-controller Can you confirm what version of 3box you are using? Your code example is slightly helpful but it's hard for me to replicate without access to the private key that is causing the issue unfortunately. I was able to sync the data locally without any problem, but it might be an issue with trying to append an entry to the 3box "rootstore" (internal datastructure) while openBox is being executed. Not yet sure why this would be happening.

@brunobar79

Apparently I was signing the messages differently that I did in the past when I used 3box via MetaMask.

Ok what was the difference exactly? Is this something that has changed in MM? Could the problem be something similar when trying to write to the space since you have to sign a separate message to access the space?

Looking deeper it seems like it's some kind of error similar to above? Perhaps you created the space with the other way of signing the message?

The data in your 3Box says that the InstaPay space is using the DID did:3:bafyreibgku5cltbdylwtoymkkw7popm2xevr3eegha52ouhwsoexfurdvu, while in your video the DID ends in ...hayrqq. So somehow you are getting a different set of keys for the space.

oed avatar Nov 01 '19 11:11 oed

@oed I was (temporarily) generating an invalid signature (or at least different to what MetaMask has been doing forever). Is it possible that the first time I opened the space "InstaPay" I did it with the wrong signature and now MetaMask is trying to match the correct expected one?

That theory makes sense because I can open and write into other spaces with that account.

"Maybe" you guys can prevent scenarios like this by trying to recover the signing account from the signature like this (https://github.com/danfinlay/js-eth-personal-sign-examples/blob/master/index.js#L66) before writing anything at the storage level. Making sure the recovered account matches the account used for signing is a good way to ensure the signature has been signed correctly with personalSign

EDIT: apparently you are already doing it so you can ignore my comment.

brunobar79 avatar Nov 01 '19 17:11 brunobar79

Hi @oed Here's a throwaway keypair which seems to produce the issue: code:

        let ethereum = {
            sendAsync: function (data, callback) {
                let messageHash = EthCrypto.hash.keccak256(data.params[0]);
                let signature = EthCrypto.sign(account.privateKey, messageHash)
                callback(null, {result: signature})
                return signature
            }
        }

        let box = await Box.openBox(account.address, ethereum)
        let space = await box.openSpace(SPACE_NAME)
        let checkPrivate = await space.private.get(PRIVATE_INFO)

Public Key: 0x706e1fbD182827Aa41a507510a31f392610B695c Private Key: 0x6404e68b4473c1f9406cb6cfa09cfccc4ce897930319132eeb00166b9a70ff6d Result: looks like it is spotting the data.params parameter 3Box is sending as undefined

{jsonrpc: "2.0", id: 1, method: "3id_getLink", params: undefined}

It looks like it's spotting the param property of the data object passed as an argument to the sendAsync function as undefined which is resulting in an invalid signature.

ps2-controller avatar Nov 01 '19 20:11 ps2-controller

Actually, I'm fairly certain that's a separate issue - I'll make a separate issue for it

ps2-controller avatar Nov 01 '19 20:11 ps2-controller

@brunobar79

Is it possible that the first time I opened the space "InstaPay" I did it with the wrong signature and now MetaMask is trying to match the correct expected one?

Yes, this is most likely it. A workaround of this issue is to remove the entry for this space from the rootstore and reopen it with the correct key. Something like:

const entries = box.replicator.rootstore.all
const entryId = // get the CID (hash) of the entry for the broken space
box.replicator.rootstore.remove(entryId)

And yes, we should definitely have better checks in place. The code that you link doesn't really check for the part of the code that generated this issue. Oh, would you mind explaining how you where signing differently?

oed avatar Nov 04 '19 08:11 oed

I'm getting the same error while I'm using Trezor with metamask. The problem is still here after I've cleaned local storage. But I find that if I just connect the address generated by metamask instead of trezor, the login function works well.

SilasZhr avatar Apr 13 '21 02:04 SilasZhr