core: save application logs for native persist

This commit is contained in:
Evgenii Stratonikov 2020-06-18 14:19:55 +03:00
parent 3894b6db9f
commit 295d8fc70e
3 changed files with 55 additions and 5 deletions

View file

@ -363,7 +363,20 @@ func (bc *Blockchain) notificationDispatcher() {
// We don't want to waste time looping through transactions when there are no
// subscribers.
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 {
aer := event.appExecResults[aerIdx]
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.
func (bc *Blockchain) storeBlock(block *block.Block) error {
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 {
return err
}
@ -565,6 +578,19 @@ func (bc *Blockchain) storeBlock(block *block.Block) error {
} else if _, err := systemInterop.DAO.Persist(); err != nil {
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 {

View file

@ -257,13 +257,16 @@ func TestSubscriptions(t *testing.T) {
require.NoError(t, err)
require.Eventually(t, func() bool { return len(blockCh) != 0 }, time.Second, 10*time.Millisecond)
assert.Empty(t, notificationCh)
assert.Empty(t, executionCh)
assert.Len(t, executionCh, 1)
assert.Empty(t, txCh)
b := <-blockCh
assert.Equal(t, blocks[0], b)
assert.Empty(t, blockCh)
aer := <-executionCh
assert.Equal(t, b.Hash(), aer.TxHash)
script := io.NewBufBinWriter()
emit.Bytes(script.BinWriter, []byte("yay!"))
emit.Syscall(script.BinWriter, "System.Runtime.Notify")
@ -308,6 +311,17 @@ func TestSubscriptions(t *testing.T) {
require.Equal(t, invBlock, b)
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.
for _, txExpected := range invBlock.Transactions {
tx := <-txCh

View file

@ -97,8 +97,18 @@ func TestSubscriptions(t *testing.T) {
for _, b := range getTestBlocks(t) {
require.NoError(t, chain.AddBlock(b))
for range b.Transactions {
resp := getNotification(t, respMsgs)
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 {
resp := getNotification(t, respMsgs)
@ -109,7 +119,7 @@ func TestSubscriptions(t *testing.T) {
break
}
}
resp := getNotification(t, respMsgs)
resp = getNotification(t, respMsgs)
require.Equal(t, response.BlockEventID, resp.Event)
}