-
Notifications
You must be signed in to change notification settings - Fork 302
/
abci.go
144 lines (122 loc) · 3.91 KB
/
abci.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package app
import (
"bytes"
"errors"
"fmt"
"sort"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/lazyledger/lazyledger-app/x/lazyledgerapp/types"
abci "github.com/lazyledger/lazyledger-core/abci/types"
core "github.com/lazyledger/lazyledger-core/proto/tendermint/types"
)
// This file should contain all of the altered ABCI methods
// PreprocessTxs fullfills the lazyledger-core version of the ACBI interface, by
// performing basic validation for the incoming txs, and by cleanly separating
// share messages from transactions
func (app *App) PreprocessTxs(txs abci.RequestPreprocessTxs) abci.ResponsePreprocessTxs {
squareSize := app.SquareSize()
shareCounter := uint64(0)
var shareMsgs []*core.Message
var processedTxs [][]byte
for _, rawTx := range txs.Txs {
// decode the Tx
tx, err := app.txConfig.TxDecoder()(rawTx)
if err != nil {
continue
}
// don't process the tx if the transaction doesn't contain a
// PayForMessage sdk.Msg
if !hasWirePayForMessage(tx) {
processedTxs = append(processedTxs, rawTx)
continue
}
// only support transactions that contain a single sdk.Msg
if len(tx.GetMsgs()) != 1 {
continue
}
msg := tx.GetMsgs()[0]
// run basic validation on the transaction
err = tx.ValidateBasic()
if err != nil {
continue
}
// process the message
coreMsg, signedTx, err := app.processMsg(msg)
if err != nil {
continue
}
// increment the share counter by the number of shares taken by the message
sharesTaken := uint64(len(coreMsg.Data) / types.ShareSize)
shareCounter += sharesTaken
// if there are too many shares stop processing and return the transactions
if shareCounter > squareSize*squareSize {
break
}
// encode the processed tx
rawProcessedTx, err := app.appCodec.MarshalBinaryBare(signedTx)
if err != nil {
continue
}
// add the message and tx to the output
shareMsgs = append(shareMsgs, &coreMsg)
processedTxs = append(processedTxs, rawProcessedTx)
}
// sort messages lexigraphically
sort.Slice(shareMsgs, func(i, j int) bool {
return bytes.Compare(shareMsgs[i].NamespaceId, shareMsgs[j].NamespaceId) < 0
})
return abci.ResponsePreprocessTxs{
Txs: processedTxs,
Messages: &core.Messages{MessagesList: shareMsgs},
}
}
func hasWirePayForMessage(tx sdk.Tx) bool {
for _, msg := range tx.GetMsgs() {
if msg.Type() == types.TypeMsgPayforMessage {
return true
}
}
return false
}
// processMsgs will perform the processing required by PreProcessTxs for a set
// of sdk.Msg's from a single sdk.Tx
func (app *App) processMsg(msg sdk.Msg) (core.Message, *types.TxSignedTransactionDataPayForMessage, error) {
squareSize := app.SquareSize()
// reject all msgs in tx if a single included msg is not correct type
wireMsg, ok := msg.(*types.MsgWirePayForMessage)
if !ok {
return core.Message{},
nil,
errors.New("transaction contained a message type other than types.MsgWirePayForMessage")
}
// make sure that a ShareCommitAndSignature of the correct size is
// included in the message
var shareCommit types.ShareCommitAndSignature
for _, commit := range wireMsg.MessageShareCommitment {
if commit.K == squareSize {
shareCommit = commit
}
}
// K == 0 means there was no share commit with the desired current square size
if shareCommit.K == 0 {
return core.Message{},
nil,
fmt.Errorf("No share commit for correct square size. Current square size: %d", squareSize)
}
// add the message to the list of core message to be returned to ll-core
coreMsg := core.Message{
NamespaceId: wireMsg.GetMessageNameSpaceId(),
Data: wireMsg.GetMessage(),
}
// wrap the signed transaction data
sTxData, err := wireMsg.SignedTransactionDataPayForMessage(squareSize)
if err != nil {
return core.Message{}, nil, err
}
signedData := &types.TxSignedTransactionDataPayForMessage{
Message: sTxData,
Signature: shareCommit.Signature,
PublicKey: wireMsg.PublicKey,
}
return coreMsg, signedData, nil
}