Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core/state: fix bug in copy of copy State #16485

Merged
merged 1 commit into from
Apr 11, 2018

Conversation

holiman
Copy link
Contributor

@holiman holiman commented Apr 10, 2018

Fixes #15225 (comment) . The copied state did not contain the full journal, and when that was copied, the dirty tracking was lost.

@wuestholz
Copy link
Contributor

@holiman @karalabe Thanks again for proposing a fix for the reported issue this quickly. I just applied the patch to check if this fixes the tests that started failing in my automated smart contract analysis tool after I had updated go-ethereum. It seems like this did the trick and the tests pass again.

state.stateObjects[addr] = self.stateObjects[addr].deepCopy(state)
state.stateObjectsDirty[addr] = struct{}{}
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you are iterating over all the state objects, even non dirty ones and set them to dirty in lower layers. Are you sure this is what you intended? Am I missing something?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that is most likely wrong

@karalabe
Copy link
Member

How the heck did this PR succeed building?

# github.com/ethereum/go-ethereum/core/state
core/state/statedb.go:486:63: not enough arguments in call to self.stateObjects[addr].deepCopy
	have (*StateDB)
	want (*StateDB, func(common.Address))

@karalabe
Copy link
Member

karalabe commented Apr 11, 2018

Apparently @holiman you based this PR on your own master branch (which was stale) and not upstream master. Or not sure what funky issue happened, but this branch is 28 commits behind master. Will force push.

EDIT: Done.

Copy link
Member

@karalabe karalabe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please modify the code so it only copies the actually dirty objects, but not the clean ones:

diff --git a/core/state/statedb.go b/core/state/statedb.go
index 3b8faa287..f18e0a47d 100644
--- a/core/state/statedb.go
+++ b/core/state/statedb.go
@@ -477,13 +477,12 @@ func (self *StateDB) Copy() *StateDB {
        // Above, we don't copy the actual journal. This means that if the copy is copied, the
        // loop above will be a no-op, since the copy:s journal is empty.
        // Thus, here we iterate over stateObjects, to enable copies of copies
-       for addr := range self.stateObjects {
+       for addr := range self.stateObjectsDirty {
                if _, exist := state.stateObjects[addr]; !exist {
                        state.stateObjects[addr] = self.stateObjects[addr].deepCopy(state)
                        state.stateObjectsDirty[addr] = struct{}{}
                }
        }
-
        for hash, logs := range self.logs {
                state.logs[hash] = make([]*types.Log, len(logs))
                copy(state.logs[hash], logs)

@karalabe
Copy link
Member

Oh, and pls also fix copy:s.

@karalabe karalabe added this to the 1.8.4 milestone Apr 11, 2018
@holiman
Copy link
Contributor Author

holiman commented Apr 11, 2018

Done, ptal

Copy link
Member

@karalabe karalabe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@karalabe karalabe merged commit 5a79aca into ethereum:master Apr 11, 2018
@wuestholz
Copy link
Contributor

wuestholz commented Apr 11, 2018

@holiman @karalabe I just pulled these changes and encountered a crash that seems to be related. Unfortunately, I can't easily reproduce it. However, here is parts of the stack trace:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x75f517]

goroutine 18 [running]:
github.com/ethereum/go-ethereum/core/state.(*stateObject).deepCopy(0x0, 0xc42037   cfc0, 0xc420459740)
        /go/src/github.com/ethereum/go-ethereum/core/state/state_object.go:279 +   0x37
github.com/ethereum/go-ethereum/core/state.(*StateDB).Copy(0xc42016bc00, 0x0)
        /go/src/github.com/ethereum/go-ethereum/core/state/statedb.go:474 +0x477

Any idea what might be going wrong here?

This might be completely unrelated, but while looking at the code for deepCopy I was wondering if the following line is actually correct:

stateObject.cachedStorage = self.dirtyStorage.Copy()

@holiman
Copy link
Contributor Author

holiman commented Apr 11, 2018

Interesting. so there is an addr in the journal which is not in the stateObjects. What were you doing -- and on what chain, and around what block?

@holiman
Copy link
Contributor Author

holiman commented Apr 11, 2018

Regarding the second question, I believe that is correct. It copies over all modified storage entries to the copy, but does not bother copying non-modified data.

@holiman
Copy link
Contributor Author

holiman commented Apr 11, 2018

Oh, btw @wuestholz , did you use the original PR or the fixed/squashed one? What's the commit hash?

@wuestholz
Copy link
Contributor

@holiman I see. Thanks for looking into it! In case that helps, I'm using a local in-memory chain (with the chain config for mainnet) to run sequences of transactions to detect issues in smart contracts. I might be able to get the sequence of transactions in case that helps.

Yes, I'm using the fixed one (5a79aca).

@holiman
Copy link
Contributor Author

holiman commented Apr 11, 2018

If you are using pre-byzantium rules, it may be the that you run into the case documented here: https://github.com/ethereum/go-ethereum/blob/master/core/state/statedb.go#L532 . If that's the case, that would be good news. Otherwise, you may have found some other cornercase, which I would be very grateful if you were able to reproduce/diagnose.

@wuestholz
Copy link
Contributor

@holiman Hm. I'm using the same chain config as mainnet and it seems that the block numbers are around 4007428. I assume that would be pre-byzantium, right?

@holiman
Copy link
Contributor Author

holiman commented Apr 11, 2018

Yes, byzantium is at 4370000. You would typically trigger this if a transaction touches upon 0000...003, which is the ripeMD precompile, and the goes OOG.
The fix is trivial (we can just add a nil-check). It would be nice to know that it's not some other strangeness going on, though.

@wuestholz
Copy link
Contributor

@holiman Yes, that's what seems to be happening. The non-existing address is indeed 0000000000000000000000000000000000000003 for my run. Below you can see the sequence of transactions (as json) that seem to trigger the behavior in case you want to try to reproduce it:

{
    "steps": [
        {
            "address": "0x0000000000000000000000000000000000000000",
            "input": "0x60606040526000806000640aaaaaaaaa92508273ffffffffffffffffffffffffffffffffffffffff166108fc6801158e460913d000009081150290604051600060405180830381858888f19350505050151561005a57600080fd5b640bbbbbbbbb91508173ffffffffffffffffffffffffffffffffffffffff166108fc6801158e460913d000009081150290604051600060405180830381858888f1935050505015156100ab57600080fd5b640ccccccccc90508073ffffffffffffffffffffffffffffffffffffffff166108fc60649081150290604051600060405180830381858888f1935050505015156100f457600080fd5b6100fc610256565b604051809103906000f080151561011257600080fd5b6000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc670de0b6b3a76400009081150290604051600060405180830381858888f1935050505015156101ba57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663912b1e246040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401600060405180830381600087803b151561023e57600080fd5b5af1151561024b57600080fd5b505050505050610266565b604051610313806102a683390190565b6032806102746000396000f30060606040520000a165627a7a7230582058bb7fed9f76b9f6a49a9ce2e0402a048ea0188f4e9849c6fe15e0f145952e8a00296060604052336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550341561004f57600080fd5b6102b58061005e6000396000f300606060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680631ac9f70d146100645780633ccfd60b14610092578063912b1e241461009c578063b4a99a4e146100b1575b005b610090600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610106565b005b61009a61018d565b005b34156100a757600080fd5b6100af610262565b005b34156100bc57600080fd5b6100c4610264565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3073ffffffffffffffffffffffffffffffffffffffff16313410151561018a578073ffffffffffffffffffffffffffffffffffffffff166108fc343073ffffffffffffffffffffffffffffffffffffffff1631019081150290604051600060405180830381858888f19350505050151561017f57600080fd5b6000151561018957fe5b5b50565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156101e857600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f19350505050151561026057600080fd5b565b565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16815600a165627a7a72305820d291800b9d4f604152c7f64c5cdcaa0a6da68420bf1f39161f66745c066248bf0029",
            "origin": "0xcccccccccccccccccccccccccccccccccccccccc",
            "value": "0xffffffffffffffffffffffffffffffffff",
            "gasLimit": "0xfffffffffffffff",
            "gasPrice": "0xee6b2800",
            "number": "0x3d2604",
            "coinbase": "0xcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb",
            "difficulty": "0x44c0218784c10",
            "time": "0x5964babf"
        },
        {
            "address": "0x76566b860970d0dab6cdb9e3f95bb32409d9f739",
            "input": "0x3ccfd60b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
            "origin": "0x8af6a7af30d840ba137e8f3f34d54cfb8beba6e2",
            "value": "0x0",
            "gasLimit": "0x80000",
            "gasPrice": "0xee6b6394",
            "number": "0x3d26c3",
            "coinbase": "0xcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb",
            "difficulty": "0x44c0218785ff8",
            "time": "0x5964babf"
        },
        {
            "address": "0x76566b860970d0dab6cdb9e3f95bb32409d9f739",
            "input": "0x1ac9f70d00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cc00000000000000000000000000000000000000000000000000030000000000000000000000000000000000f60000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000000000000000000000000000ea0000000000000000000000000000000000000000000000d20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004900ff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fb000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fe0000000000000000000000000000000000000000000000000000000000000000f200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d300000000000000000000000000000000000000003d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
            "origin": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
            "value": "0x0",
            "gasLimit": "0x10096",
            "gasPrice": "0xee6bf6ca",
            "number": "0x3d390e",
            "coinbase": "0xcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb",
            "difficulty": "0x44c0218779394",
            "time": "0x5964c4b2"
        }
    ]
}

@holiman
Copy link
Contributor Author

holiman commented Apr 11, 2018

Thanks for confirming! I'll follow up with a nil-check

@wuestholz
Copy link
Contributor

Great! Thank you very much for fixing this so quickly!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants