103 lines
2.1 KiB
Go
103 lines
2.1 KiB
Go
package ledger
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strconv"
|
|
|
|
"github.com/meshplus/bitxhub-kit/storage"
|
|
"github.com/meshplus/bitxhub-kit/types"
|
|
)
|
|
|
|
var (
|
|
minHeightStr = "minHeight"
|
|
maxHeightStr = "maxHeight"
|
|
)
|
|
|
|
type journal struct {
|
|
Address *types.Address
|
|
PrevAccount *innerAccount
|
|
AccountChanged bool
|
|
PrevStates map[string][]byte
|
|
PrevCode []byte
|
|
CodeChanged bool
|
|
}
|
|
|
|
type BlockJournal struct {
|
|
Journals []*journal
|
|
ChangedHash *types.Hash
|
|
}
|
|
|
|
func (journal *journal) revert(batch storage.Batch) {
|
|
if journal.AccountChanged {
|
|
if journal.PrevAccount != nil {
|
|
data, err := journal.PrevAccount.Marshal()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
batch.Put(compositeKey(accountKey, journal.Address), data)
|
|
} else {
|
|
batch.Delete(compositeKey(accountKey, journal.Address))
|
|
}
|
|
}
|
|
|
|
for key, val := range journal.PrevStates {
|
|
if val != nil {
|
|
batch.Put(composeStateKey(journal.Address, []byte(key)), val)
|
|
} else {
|
|
batch.Delete(composeStateKey(journal.Address, []byte(key)))
|
|
}
|
|
}
|
|
|
|
if journal.CodeChanged {
|
|
if journal.PrevCode != nil {
|
|
batch.Put(compositeKey(codeKey, journal.Address), journal.PrevCode)
|
|
} else {
|
|
batch.Delete(compositeKey(codeKey, journal.Address))
|
|
}
|
|
}
|
|
}
|
|
|
|
func getJournalRange(ldb storage.Storage) (uint64, uint64) {
|
|
minHeight := uint64(0)
|
|
maxHeight := uint64(0)
|
|
|
|
data := ldb.Get(compositeKey(journalKey, minHeightStr))
|
|
if data != nil {
|
|
minHeight = unmarshalHeight(data)
|
|
}
|
|
|
|
data = ldb.Get(compositeKey(journalKey, maxHeightStr))
|
|
if data != nil {
|
|
maxHeight = unmarshalHeight(data)
|
|
}
|
|
|
|
return minHeight, maxHeight
|
|
}
|
|
|
|
func getBlockJournal(height uint64, ldb storage.Storage) *BlockJournal {
|
|
data := ldb.Get(compositeKey(journalKey, height))
|
|
if data == nil {
|
|
return nil
|
|
}
|
|
|
|
journal := &BlockJournal{}
|
|
if err := json.Unmarshal(data, journal); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return journal
|
|
}
|
|
|
|
func marshalHeight(height uint64) []byte {
|
|
return []byte(strconv.FormatUint(height, 10))
|
|
}
|
|
|
|
func unmarshalHeight(data []byte) uint64 {
|
|
height, err := strconv.ParseUint(string(data), 10, 64)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return height
|
|
}
|