aboutsummaryrefslogtreecommitdiffstats
path: root/core/state/journal.go
blob: 540ade6fb77e919aeab5f3edddaec54eda8c80bd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// Copyright 2016 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

package state

import (
    "math/big"

    "github.com/ethereum/go-ethereum/common"
)

type journalEntry interface {
    undo(*StateDB)
}

type journal []journalEntry

type (
    // Changes to the account trie.
    createObjectChange struct {
        account *common.Address
    }
    resetObjectChange struct {
        prev *StateObject
    }
    deleteAccountChange struct {
        account     *common.Address
        prev        bool // whether account had already suicided
        prevbalance *big.Int
    }

    // Changes to individual accounts.
    balanceChange struct {
        account *common.Address
        prev    *big.Int
    }
    nonceChange struct {
        account *common.Address
        prev    uint64
    }
    storageChange struct {
        account       *common.Address
        key, prevalue common.Hash
    }
    codeChange struct {
        account            *common.Address
        prevcode, prevhash []byte
    }

    // Changes to other state values.
    refundChange struct {
        prev *big.Int
    }
    addLogChange struct {
        txhash common.Hash
    }
)

func (ch createObjectChange) undo(s *StateDB) {
    s.GetStateObject(*ch.account).deleted = true
    delete(s.stateObjects, *ch.account)
    delete(s.stateObjectsDirty, *ch.account)
}

func (ch resetObjectChange) undo(s *StateDB) {
    s.setStateObject(ch.prev)
}

func (ch deleteAccountChange) undo(s *StateDB) {
    obj := s.GetStateObject(*ch.account)
    if obj != nil {
        obj.remove = ch.prev
        obj.setBalance(ch.prevbalance)
    }
}

func (ch balanceChange) undo(s *StateDB) {
    s.GetStateObject(*ch.account).setBalance(ch.prev)
}

func (ch nonceChange) undo(s *StateDB) {
    s.GetStateObject(*ch.account).setNonce(ch.prev)
}

func (ch codeChange) undo(s *StateDB) {
    s.GetStateObject(*ch.account).setCode(common.BytesToHash(ch.prevhash), ch.prevcode)
}

func (ch storageChange) undo(s *StateDB) {
    s.GetStateObject(*ch.account).setState(ch.key, ch.prevalue)
}

func (ch refundChange) undo(s *StateDB) {
    s.refund = ch.prev
}

func (ch addLogChange) undo(s *StateDB) {
    logs := s.logs[ch.txhash]
    if len(logs) == 1 {
        delete(s.logs, ch.txhash)
    } else {
        s.logs[ch.txhash] = logs[:len(logs)-1]
    }
}