forked from TrueCloudLab/neoneo-go
core: save application logs for native persist
This commit is contained in:
parent
3894b6db9f
commit
295d8fc70e
3 changed files with 55 additions and 5 deletions
|
@ -363,7 +363,20 @@ func (bc *Blockchain) notificationDispatcher() {
|
||||||
// We don't want to waste time looping through transactions when there are no
|
// We don't want to waste time looping through transactions when there are no
|
||||||
// subscribers.
|
// subscribers.
|
||||||
if len(txFeed) != 0 || len(notificationFeed) != 0 || len(executionFeed) != 0 {
|
if len(txFeed) != 0 || len(notificationFeed) != 0 || len(executionFeed) != 0 {
|
||||||
var aerIdx int
|
aer := event.appExecResults[0]
|
||||||
|
if !aer.TxHash.Equals(event.block.Hash()) {
|
||||||
|
panic("inconsistent application execution results")
|
||||||
|
}
|
||||||
|
for ch := range executionFeed {
|
||||||
|
ch <- aer
|
||||||
|
}
|
||||||
|
for i := range aer.Events {
|
||||||
|
for ch := range notificationFeed {
|
||||||
|
ch <- &aer.Events[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aerIdx := 1
|
||||||
for _, tx := range event.block.Transactions {
|
for _, tx := range event.block.Transactions {
|
||||||
aer := event.appExecResults[aerIdx]
|
aer := event.appExecResults[aerIdx]
|
||||||
if !aer.TxHash.Equals(tx.Hash()) {
|
if !aer.TxHash.Equals(tx.Hash()) {
|
||||||
|
@ -547,7 +560,7 @@ func (bc *Blockchain) processHeader(h *block.Header, batch storage.Batch, header
|
||||||
// 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.Block) error {
|
func (bc *Blockchain) storeBlock(block *block.Block) error {
|
||||||
cache := dao.NewCached(bc.dao)
|
cache := dao.NewCached(bc.dao)
|
||||||
appExecResults := make([]*state.AppExecResult, 0, len(block.Transactions))
|
appExecResults := make([]*state.AppExecResult, 0, 1+len(block.Transactions))
|
||||||
if err := cache.StoreAsBlock(block); err != nil {
|
if err := cache.StoreAsBlock(block); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -565,6 +578,19 @@ func (bc *Blockchain) storeBlock(block *block.Block) error {
|
||||||
} else if _, err := systemInterop.DAO.Persist(); err != nil {
|
} else if _, err := systemInterop.DAO.Persist(); err != nil {
|
||||||
return errors.Wrap(err, "can't persist `onPersist` changes")
|
return errors.Wrap(err, "can't persist `onPersist` changes")
|
||||||
}
|
}
|
||||||
|
aer := &state.AppExecResult{
|
||||||
|
TxHash: block.Hash(), // application logs can be retrieved by block hash
|
||||||
|
Trigger: trigger.System,
|
||||||
|
VMState: v.State(),
|
||||||
|
GasConsumed: v.GasConsumed(),
|
||||||
|
Stack: v.Estack().ToContractParameters(),
|
||||||
|
Events: systemInterop.Notifications,
|
||||||
|
}
|
||||||
|
appExecResults = append(appExecResults, aer)
|
||||||
|
err := cache.PutAppExecResult(aer)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to Store notifications")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tx := range block.Transactions {
|
for _, tx := range block.Transactions {
|
||||||
|
|
|
@ -257,13 +257,16 @@ func TestSubscriptions(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Eventually(t, func() bool { return len(blockCh) != 0 }, time.Second, 10*time.Millisecond)
|
require.Eventually(t, func() bool { return len(blockCh) != 0 }, time.Second, 10*time.Millisecond)
|
||||||
assert.Empty(t, notificationCh)
|
assert.Empty(t, notificationCh)
|
||||||
assert.Empty(t, executionCh)
|
assert.Len(t, executionCh, 1)
|
||||||
assert.Empty(t, txCh)
|
assert.Empty(t, txCh)
|
||||||
|
|
||||||
b := <-blockCh
|
b := <-blockCh
|
||||||
assert.Equal(t, blocks[0], b)
|
assert.Equal(t, blocks[0], b)
|
||||||
assert.Empty(t, blockCh)
|
assert.Empty(t, blockCh)
|
||||||
|
|
||||||
|
aer := <-executionCh
|
||||||
|
assert.Equal(t, b.Hash(), aer.TxHash)
|
||||||
|
|
||||||
script := io.NewBufBinWriter()
|
script := io.NewBufBinWriter()
|
||||||
emit.Bytes(script.BinWriter, []byte("yay!"))
|
emit.Bytes(script.BinWriter, []byte("yay!"))
|
||||||
emit.Syscall(script.BinWriter, "System.Runtime.Notify")
|
emit.Syscall(script.BinWriter, "System.Runtime.Notify")
|
||||||
|
@ -308,6 +311,17 @@ func TestSubscriptions(t *testing.T) {
|
||||||
require.Equal(t, invBlock, b)
|
require.Equal(t, invBlock, b)
|
||||||
assert.Empty(t, blockCh)
|
assert.Empty(t, blockCh)
|
||||||
|
|
||||||
|
exec := <-executionCh
|
||||||
|
require.Equal(t, b.Hash(), exec.TxHash)
|
||||||
|
require.Equal(t, exec.VMState, "HALT")
|
||||||
|
|
||||||
|
// 3 burn events for every tx and 1 mint for primary node
|
||||||
|
require.True(t, len(notificationCh) >= 4)
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
notif := <-notificationCh
|
||||||
|
require.Equal(t, bc.contracts.GAS.Hash, notif.ScriptHash)
|
||||||
|
}
|
||||||
|
|
||||||
// Follow in-block transaction order.
|
// Follow in-block transaction order.
|
||||||
for _, txExpected := range invBlock.Transactions {
|
for _, txExpected := range invBlock.Transactions {
|
||||||
tx := <-txCh
|
tx := <-txCh
|
||||||
|
|
|
@ -97,9 +97,19 @@ func TestSubscriptions(t *testing.T) {
|
||||||
|
|
||||||
for _, b := range getTestBlocks(t) {
|
for _, b := range getTestBlocks(t) {
|
||||||
require.NoError(t, chain.AddBlock(b))
|
require.NoError(t, chain.AddBlock(b))
|
||||||
for range b.Transactions {
|
|
||||||
resp := getNotification(t, respMsgs)
|
resp := getNotification(t, respMsgs)
|
||||||
require.Equal(t, response.ExecutionEventID, resp.Event)
|
require.Equal(t, response.ExecutionEventID, resp.Event)
|
||||||
|
for {
|
||||||
|
resp := getNotification(t, respMsgs)
|
||||||
|
if resp.Event != response.NotificationEventID {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := 0; i < len(b.Transactions); i++ {
|
||||||
|
if i > 0 {
|
||||||
|
resp = getNotification(t, respMsgs)
|
||||||
|
}
|
||||||
|
require.Equal(t, response.ExecutionEventID, resp.Event)
|
||||||
for {
|
for {
|
||||||
resp := getNotification(t, respMsgs)
|
resp := getNotification(t, respMsgs)
|
||||||
if resp.Event == response.NotificationEventID {
|
if resp.Event == response.NotificationEventID {
|
||||||
|
@ -109,7 +119,7 @@ func TestSubscriptions(t *testing.T) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resp := getNotification(t, respMsgs)
|
resp = getNotification(t, respMsgs)
|
||||||
require.Equal(t, response.BlockEventID, resp.Event)
|
require.Equal(t, response.BlockEventID, resp.Event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue