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
|
||||
// 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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue