core: deduplicate state commit methods, use interim MemCachedStore
commit methods duplicated putSmthIntoStore functions, but have MemCachedStore now that can easily substitute for a Batch, especially given that interop needs something like that for its storage purposes anyway.
This commit is contained in:
parent
fc0031e5aa
commit
2245fedbb1
9 changed files with 71 additions and 67 deletions
|
@ -48,17 +48,23 @@ func getAccountStateFromStore(s storage.Store, hash util.Uint160) (*AccountState
|
||||||
return account, err
|
return account, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// commit writes all account states to the given Batch.
|
// putAccountStateIntoStore puts given AccountState into the given store.
|
||||||
func (a Accounts) commit(b storage.Batch) error {
|
func putAccountStateIntoStore(store storage.Store, as *AccountState) error {
|
||||||
buf := io.NewBufBinWriter()
|
buf := io.NewBufBinWriter()
|
||||||
for hash, state := range a {
|
as.EncodeBinary(buf.BinWriter)
|
||||||
state.EncodeBinary(buf.BinWriter)
|
if buf.Err != nil {
|
||||||
if buf.Err != nil {
|
return buf.Err
|
||||||
return buf.Err
|
}
|
||||||
|
key := storage.AppendPrefix(storage.STAccount, as.ScriptHash.Bytes())
|
||||||
|
return store.Put(key, buf.Bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// commit writes all account states to the given Batch.
|
||||||
|
func (a Accounts) commit(store storage.Store) error {
|
||||||
|
for _, state := range a {
|
||||||
|
if err := putAccountStateIntoStore(store, state); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
key := storage.AppendPrefix(storage.STAccount, hash.Bytes())
|
|
||||||
b.Put(key, buf.Bytes())
|
|
||||||
buf.Reset()
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,16 +13,11 @@ const feeMode = 0x0
|
||||||
// Assets is mapping between AssetID and the AssetState.
|
// Assets is mapping between AssetID and the AssetState.
|
||||||
type Assets map[util.Uint256]*AssetState
|
type Assets map[util.Uint256]*AssetState
|
||||||
|
|
||||||
func (a Assets) commit(b storage.Batch) error {
|
func (a Assets) commit(store storage.Store) error {
|
||||||
buf := io.NewBufBinWriter()
|
for _, state := range a {
|
||||||
for hash, state := range a {
|
if err := putAssetStateIntoStore(store, state); err != nil {
|
||||||
state.EncodeBinary(buf.BinWriter)
|
return err
|
||||||
if buf.Err != nil {
|
|
||||||
return buf.Err
|
|
||||||
}
|
}
|
||||||
key := storage.AppendPrefix(storage.STAsset, hash.Bytes())
|
|
||||||
b.Put(key, buf.Bytes())
|
|
||||||
buf.Reset()
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -306,7 +306,7 @@ func (bc *Blockchain) processHeader(h *Header, batch storage.Batch, headerList *
|
||||||
// and all tests are in place, we can make a more optimized and cleaner implementation.
|
// and all tests are in place, we can make a more optimized and cleaner implementation.
|
||||||
func (bc *Blockchain) storeBlock(block *Block) error {
|
func (bc *Blockchain) storeBlock(block *Block) error {
|
||||||
var (
|
var (
|
||||||
batch = bc.store.Batch()
|
tmpStore = storage.NewMemCachedStore(bc.store)
|
||||||
unspentCoins = make(UnspentCoins)
|
unspentCoins = make(UnspentCoins)
|
||||||
spentCoins = make(SpentCoins)
|
spentCoins = make(SpentCoins)
|
||||||
accounts = make(Accounts)
|
accounts = make(Accounts)
|
||||||
|
@ -314,14 +314,16 @@ func (bc *Blockchain) storeBlock(block *Block) error {
|
||||||
contracts = make(Contracts)
|
contracts = make(Contracts)
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := storeAsBlock(batch, block, 0); err != nil {
|
if err := storeAsBlock(tmpStore, block, 0); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
storeAsCurrentBlock(batch, block)
|
if err := storeAsCurrentBlock(tmpStore, block); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
for _, tx := range block.Transactions {
|
for _, tx := range block.Transactions {
|
||||||
if err := storeAsTransaction(batch, tx, block.Index); err != nil {
|
if err := storeAsTransaction(tmpStore, tx, block.Index); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,7 +417,7 @@ func (bc *Blockchain) storeBlock(block *Block) error {
|
||||||
|
|
||||||
return cs.Script
|
return cs.Script
|
||||||
})
|
})
|
||||||
systemInterop := newInteropContext(0x10, bc, bc.store, block, tx)
|
systemInterop := newInteropContext(0x10, bc, tmpStore, block, tx)
|
||||||
vm.RegisterInteropFuncs(systemInterop.getSystemInteropMap())
|
vm.RegisterInteropFuncs(systemInterop.getSystemInteropMap())
|
||||||
vm.RegisterInteropFuncs(systemInterop.getNeoInteropMap())
|
vm.RegisterInteropFuncs(systemInterop.getNeoInteropMap())
|
||||||
vm.LoadScript(t.Script)
|
vm.LoadScript(t.Script)
|
||||||
|
@ -435,22 +437,22 @@ func (bc *Blockchain) storeBlock(block *Block) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Persist all to storage.
|
// Persist all to storage.
|
||||||
if err := accounts.commit(batch); err != nil {
|
if err := accounts.commit(tmpStore); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := unspentCoins.commit(batch); err != nil {
|
if err := unspentCoins.commit(tmpStore); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := spentCoins.commit(batch); err != nil {
|
if err := spentCoins.commit(tmpStore); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := assets.commit(batch); err != nil {
|
if err := assets.commit(tmpStore); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := contracts.commit(batch); err != nil {
|
if err := contracts.commit(tmpStore); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := bc.store.PutBatch(batch); err != nil {
|
if _, err := tmpStore.Persist(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,16 +27,11 @@ type ContractState struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// commit flushes all contracts to the given storage.Batch.
|
// commit flushes all contracts to the given storage.Batch.
|
||||||
func (a Contracts) commit(b storage.Batch) error {
|
func (a Contracts) commit(store storage.Store) error {
|
||||||
buf := io.NewBufBinWriter()
|
for _, contract := range a {
|
||||||
for hash, contract := range a {
|
if err := putContractStateIntoStore(store, contract); err != nil {
|
||||||
contract.EncodeBinary(buf.BinWriter)
|
return err
|
||||||
if buf.Err != nil {
|
|
||||||
return buf.Err
|
|
||||||
}
|
}
|
||||||
key := storage.AppendPrefix(storage.STContract, hash.Bytes())
|
|
||||||
b.Put(key, buf.Bytes())
|
|
||||||
buf.Reset()
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,16 +35,22 @@ func (s SpentCoins) getAndUpdate(store storage.Store, hash util.Uint256) (*Spent
|
||||||
return spent, nil
|
return spent, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s SpentCoins) commit(b storage.Batch) error {
|
// putSpentCoinStateIntoStore puts given SpentCoinState into the given store.
|
||||||
|
func putSpentCoinStateIntoStore(store storage.Store, hash util.Uint256, scs *SpentCoinState) error {
|
||||||
buf := io.NewBufBinWriter()
|
buf := io.NewBufBinWriter()
|
||||||
|
scs.EncodeBinary(buf.BinWriter)
|
||||||
|
if buf.Err != nil {
|
||||||
|
return buf.Err
|
||||||
|
}
|
||||||
|
key := storage.AppendPrefix(storage.STSpentCoin, hash.BytesReverse())
|
||||||
|
return store.Put(key, buf.Bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SpentCoins) commit(store storage.Store) error {
|
||||||
for hash, state := range s {
|
for hash, state := range s {
|
||||||
state.EncodeBinary(buf.BinWriter)
|
if err := putSpentCoinStateIntoStore(store, hash, state); err != nil {
|
||||||
if buf.Err != nil {
|
return err
|
||||||
return buf.Err
|
|
||||||
}
|
}
|
||||||
key := storage.AppendPrefix(storage.STSpentCoin, hash.BytesReverse())
|
|
||||||
b.Put(key, buf.Bytes())
|
|
||||||
buf.Reset()
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,6 @@ func TestEncodeDecodeSpentCoinState(t *testing.T) {
|
||||||
func TestCommitSpentCoins(t *testing.T) {
|
func TestCommitSpentCoins(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
store = storage.NewMemoryStore()
|
store = storage.NewMemoryStore()
|
||||||
batch = store.Batch()
|
|
||||||
spentCoins = make(SpentCoins)
|
spentCoins = make(SpentCoins)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -49,6 +48,5 @@ func TestCommitSpentCoins(t *testing.T) {
|
||||||
txHeight: 1,
|
txHeight: 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert.Nil(t, spentCoins.commit(batch))
|
assert.Nil(t, spentCoins.commit(store))
|
||||||
assert.Nil(t, store.PutBatch(batch))
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,17 @@ func getUnspentCoinStateFromStore(s storage.Store, hash util.Uint256) (*UnspentC
|
||||||
return unspent, nil
|
return unspent, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// putUnspentCoinStateIntoStore puts given UnspentCoinState into the given store.
|
||||||
|
func putUnspentCoinStateIntoStore(store storage.Store, hash util.Uint256, ucs *UnspentCoinState) error {
|
||||||
|
buf := io.NewBufBinWriter()
|
||||||
|
ucs.EncodeBinary(buf.BinWriter)
|
||||||
|
if buf.Err != nil {
|
||||||
|
return buf.Err
|
||||||
|
}
|
||||||
|
key := storage.AppendPrefix(storage.STCoin, hash.BytesReverse())
|
||||||
|
return store.Put(key, buf.Bytes())
|
||||||
|
}
|
||||||
|
|
||||||
// UnspentCoinState hold the state of a unspent coin.
|
// UnspentCoinState hold the state of a unspent coin.
|
||||||
type UnspentCoinState struct {
|
type UnspentCoinState struct {
|
||||||
states []CoinState
|
states []CoinState
|
||||||
|
@ -68,16 +79,11 @@ func NewUnspentCoinState(n int) *UnspentCoinState {
|
||||||
}
|
}
|
||||||
|
|
||||||
// commit writes all unspent coin states to the given Batch.
|
// commit writes all unspent coin states to the given Batch.
|
||||||
func (u UnspentCoins) commit(b storage.Batch) error {
|
func (u UnspentCoins) commit(store storage.Store) error {
|
||||||
buf := io.NewBufBinWriter()
|
|
||||||
for hash, state := range u {
|
for hash, state := range u {
|
||||||
state.EncodeBinary(buf.BinWriter)
|
if err := putUnspentCoinStateIntoStore(store, hash, state); err != nil {
|
||||||
if buf.Err != nil {
|
return err
|
||||||
return buf.Err
|
|
||||||
}
|
}
|
||||||
key := storage.AppendPrefix(storage.STCoin, hash.BytesReverse())
|
|
||||||
b.Put(key, buf.Bytes())
|
|
||||||
buf.Reset()
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,6 @@ func TestDecodeEncodeUnspentCoinState(t *testing.T) {
|
||||||
func TestCommitUnspentCoins(t *testing.T) {
|
func TestCommitUnspentCoins(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
store = storage.NewMemoryStore()
|
store = storage.NewMemoryStore()
|
||||||
batch = store.Batch()
|
|
||||||
unspentCoins = make(UnspentCoins)
|
unspentCoins = make(UnspentCoins)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -56,6 +55,5 @@ func TestCommitUnspentCoins(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Nil(t, unspentCoins.commit(batch))
|
assert.Nil(t, unspentCoins.commit(store))
|
||||||
assert.Nil(t, store.PutBatch(batch))
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,15 +179,15 @@ func headerSliceReverse(dest []*Header) {
|
||||||
|
|
||||||
// storeAsCurrentBlock stores the given block witch prefix
|
// storeAsCurrentBlock stores the given block witch prefix
|
||||||
// SYSCurrentBlock.
|
// SYSCurrentBlock.
|
||||||
func storeAsCurrentBlock(batch storage.Batch, block *Block) {
|
func storeAsCurrentBlock(store storage.Store, block *Block) error {
|
||||||
buf := io.NewBufBinWriter()
|
buf := io.NewBufBinWriter()
|
||||||
buf.WriteLE(block.Hash().BytesReverse())
|
buf.WriteLE(block.Hash().BytesReverse())
|
||||||
buf.WriteLE(block.Index)
|
buf.WriteLE(block.Index)
|
||||||
batch.Put(storage.SYSCurrentBlock.Bytes(), buf.Bytes())
|
return store.Put(storage.SYSCurrentBlock.Bytes(), buf.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
// storeAsBlock stores the given block as DataBlock.
|
// storeAsBlock stores the given block as DataBlock.
|
||||||
func storeAsBlock(batch storage.Batch, block *Block, sysFee uint32) error {
|
func storeAsBlock(store storage.Store, block *Block, sysFee uint32) error {
|
||||||
var (
|
var (
|
||||||
key = storage.AppendPrefix(storage.DataBlock, block.Hash().BytesReverse())
|
key = storage.AppendPrefix(storage.DataBlock, block.Hash().BytesReverse())
|
||||||
buf = io.NewBufBinWriter()
|
buf = io.NewBufBinWriter()
|
||||||
|
@ -202,12 +202,11 @@ func storeAsBlock(batch storage.Batch, block *Block, sysFee uint32) error {
|
||||||
if buf.Err != nil {
|
if buf.Err != nil {
|
||||||
return buf.Err
|
return buf.Err
|
||||||
}
|
}
|
||||||
batch.Put(key, buf.Bytes())
|
return store.Put(key, buf.Bytes())
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// storeAsTransaction stores the given TX as DataTransaction.
|
// storeAsTransaction stores the given TX as DataTransaction.
|
||||||
func storeAsTransaction(batch storage.Batch, tx *transaction.Transaction, index uint32) error {
|
func storeAsTransaction(store storage.Store, tx *transaction.Transaction, index uint32) error {
|
||||||
key := storage.AppendPrefix(storage.DataTransaction, tx.Hash().BytesReverse())
|
key := storage.AppendPrefix(storage.DataTransaction, tx.Hash().BytesReverse())
|
||||||
buf := io.NewBufBinWriter()
|
buf := io.NewBufBinWriter()
|
||||||
buf.WriteLE(index)
|
buf.WriteLE(index)
|
||||||
|
@ -215,6 +214,5 @@ func storeAsTransaction(batch storage.Batch, tx *transaction.Transaction, index
|
||||||
if buf.Err != nil {
|
if buf.Err != nil {
|
||||||
return buf.Err
|
return buf.Err
|
||||||
}
|
}
|
||||||
batch.Put(key, buf.Bytes())
|
return store.Put(key, buf.Bytes())
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue