/
utils.go
137 lines (117 loc) · 3.96 KB
/
utils.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
package app
import (
"bytes"
"encoding/json"
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
ethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
abciTypes "github.com/tendermint/tendermint/abci/types"
"github.com/CyberMiles/travis/errors"
"github.com/CyberMiles/travis/utils"
)
// format of query data
type jsonRequest struct {
Method string `json:"method"`
ID json.RawMessage `json:"id,omitempty"`
Params []interface{} `json:"params,omitempty"`
}
// rlp decode an etherum transaction
func decodeTx(txBytes []byte) (*types.Transaction, error) {
tx := new(types.Transaction)
rlpStream := rlp.NewStream(bytes.NewBuffer(txBytes), 0)
if err := tx.DecodeRLP(rlpStream); err != nil {
return nil, err
}
return tx, nil
}
//-------------------------------------------------------
// convenience methods for validators
// Receiver returns the receiving address based on the selected strategy
// #unstable
func (app *EthermintApplication) Receiver() common.Address {
if app.strategy != nil {
return app.strategy.Receiver()
}
return utils.HoldAccount
}
// SetValidators sets new validators on the strategy
// #unstable
func (app *EthermintApplication) SetValidators(validators []abciTypes.Validator) {
if app.strategy != nil {
app.strategy.SetValidators(validators)
}
}
// GetUpdatedValidators returns an updated validator set from the strategy
// #unstable
func (app *EthermintApplication) GetUpdatedValidators() abciTypes.ResponseEndBlock {
if app.strategy != nil {
return abciTypes.ResponseEndBlock{ValidatorUpdates: app.strategy.GetUpdatedValidators()}
}
return abciTypes.ResponseEndBlock{}
}
// CollectTx invokes CollectTx on the strategy
// #unstable
func (app *EthermintApplication) CollectTx(tx *types.Transaction) {
if app.strategy != nil {
app.strategy.CollectTx(tx)
}
}
func (app *EthermintApplication) basicCheck(tx *ethTypes.Transaction) (*state.StateDB, common.Address, uint64, abciTypes.ResponseCheckTx) {
// Heuristic limit, reject transactions over 32KB to prevent DOS attacks
if tx.Size() > maxTransactionSize {
return nil, common.Address{}, 0,
abciTypes.ResponseCheckTx{
Code: errors.CodeTypeInternalErr,
Log: core.ErrOversizedData.Error()}
}
// tx.ChainID() must > 0
if tx.ChainId().Cmp(big.NewInt(0)) <= 0 {
return nil, common.Address{}, 0,
abciTypes.ResponseCheckTx{
Code: errors.CodeTypeInternalErr,
Log: types.ErrInvalidChainId.Error()}
}
networkId := big.NewInt(int64(app.backend.Ethereum().NetVersion()))
signer := ethTypes.NewEIP155Signer(networkId)
// Make sure the transaction is signed properly
from, err := ethTypes.Sender(signer, tx)
if err != nil {
// TODO: Add errors.CodeTypeInvalidSignature ?
return nil, common.Address{}, 0,
abciTypes.ResponseCheckTx{
Code: errors.CodeTypeInternalErr,
Log: err.Error()}
}
// Transactions can't be negative. This may never happen using RLP decoded
// transactions but may occur if you create a transaction using the RPC.
if tx.Value().Sign() < 0 {
return nil, common.Address{}, 0,
abciTypes.ResponseCheckTx{
Code: errors.CodeTypeBaseInvalidInput,
Log: core.ErrNegativeValue.Error()}
}
currentState := app.checkTxState
// Check the transaction doesn't exceed the current block limit gas.
gasLimit := app.backend.GasLimit()
if gasLimit < tx.Gas() {
return nil, common.Address{}, 0,
abciTypes.ResponseCheckTx{
Code: errors.CodeTypeInternalErr,
Log: core.ErrGasLimitReached.Error()}
}
nonce := currentState.GetNonce(from)
if nonce != tx.Nonce() {
return nil, common.Address{}, 0,
abciTypes.ResponseCheckTx{
Code: errors.CodeTypeBadNonce,
Log: fmt.Sprintf(
"Nonce not strictly increasing. Expected %d Got %d",
nonce, tx.Nonce())}
}
return currentState, from, nonce, abciTypes.ResponseCheckTx{Code: abciTypes.CodeTypeOK}
}