Skip to content

Commit ead8ce7

Browse files
authored
Merge acd391d into 418fd81
2 parents 418fd81 + acd391d commit ead8ce7

File tree

5 files changed

+200
-5
lines changed

5 files changed

+200
-5
lines changed

libs/cosmos-sdk/baseapp/gasuseddb.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,13 @@ func (h *HistoryGasUsedRecordDB) FlushHgu() {
7676
return
7777
}
7878
latestGasKeys := make([]gasKey, len(h.latestGu))
79+
index := 0
7980
for key, gas := range h.latestGu {
80-
latestGasKeys = append(latestGasKeys, gasKey{
81+
latestGasKeys[index] = gasKey{
8182
gas: gas,
8283
key: key,
83-
})
84+
}
85+
index++
8486
delete(h.latestGu, key)
8587
}
8688
h.jobQueue <- func() { h.flushHgu(latestGasKeys...) } // closure
@@ -103,8 +105,8 @@ func (h *HistoryGasUsedRecordDB) getHgu(key []byte) (hgu int64, fromCache bool)
103105
func (h *HistoryGasUsedRecordDB) flushHgu(gks ...gasKey) {
104106
for _, gk := range gks {
105107
hgu, cacheHit := h.getHgu([]byte(gk.key))
106-
// avgGas = 0.4 * newGas + 0.6 * oldGas
107-
avgGas := int64(GasUsedFactor*float64(gk.gas) + (1.0-GasUsedFactor)*float64(hgu))
108+
// avgGas = 0.4 * newGas + 0.6 * oldGas.The value of wasm store contract is too small and need to be rounded up.
109+
avgGas := int64(GasUsedFactor*float64(gk.gas) + (1.0-GasUsedFactor)*float64(hgu) + 0.6)
108110
// add to cache if hit
109111
if cacheHit {
110112
h.cache.Add(gk.key, avgGas)

libs/cosmos-sdk/x/auth/types/stdtx.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,33 @@ func (tx *StdTx) GetGasPrice() *big.Int {
268268
return tx.Fee.GasPrices()[0].Amount.BigInt()
269269
}
270270

271+
type WasmMsgChecker interface {
272+
FnSignatureInfo() (string, int, error)
273+
}
274+
271275
func (tx *StdTx) GetTxFnSignatureInfo() ([]byte, int) {
272-
return nil, 0
276+
// hgu can't be right simulated with many Msgs.
277+
if len(tx.Msgs) != 1 {
278+
return nil, 0
279+
}
280+
281+
fnSign := ""
282+
deploySize := 0
283+
for _, msg := range tx.Msgs {
284+
v, ok := msg.(WasmMsgChecker)
285+
if !ok {
286+
break
287+
}
288+
fn, size, err := v.FnSignatureInfo()
289+
if err != nil || len(fn) <= 0 {
290+
break
291+
}
292+
293+
deploySize = size
294+
fnSign = fn
295+
break
296+
}
297+
return []byte(fnSign), deploySize
273298
}
274299

275300
func (tx *StdTx) GetFrom() string {

x/wasm/handler.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ import (
44
"fmt"
55

66
"github.com/gogo/protobuf/proto"
7+
bam "github.com/okx/okbchain/libs/cosmos-sdk/baseapp"
78
sdk "github.com/okx/okbchain/libs/cosmos-sdk/types"
89
sdkerrors "github.com/okx/okbchain/libs/cosmos-sdk/types/errors"
10+
sdktypes "github.com/okx/okbchain/libs/cosmos-sdk/x/auth/types"
11+
cfg "github.com/okx/okbchain/libs/tendermint/config"
912
"github.com/okx/okbchain/libs/tendermint/libs/kv"
1013
types2 "github.com/okx/okbchain/libs/tendermint/types"
1114
"github.com/okx/okbchain/x/wasm/keeper"
@@ -35,6 +38,10 @@ func NewHandler(k types.ContractOpsKeeper) sdk.Handler {
3538
if ctx.IsDeliver() || ctx.ParaMsg() != nil {
3639
watcher.Save(err)
3740
}
41+
42+
if err == nil && !ctx.IsCheckTx() {
43+
updateHGU(ctx, msg)
44+
}
3845
}()
3946

4047
switch msg := msg.(type) {
@@ -60,6 +67,30 @@ func NewHandler(k types.ContractOpsKeeper) sdk.Handler {
6067
}
6168
}
6269

70+
func updateHGU(ctx sdk.Context, msg sdk.Msg) {
71+
if cfg.DynamicConfig.GetMaxGasUsedPerBlock() <= 0 {
72+
return
73+
}
74+
75+
v, ok := msg.(sdktypes.WasmMsgChecker)
76+
if !ok {
77+
return
78+
}
79+
80+
fnSign, deploySize, err := v.FnSignatureInfo()
81+
if err != nil || len(fnSign) <= 0 {
82+
return
83+
}
84+
85+
gc := int64(ctx.GasMeter().GasConsumed())
86+
if deploySize > 0 {
87+
// calculate average gas consume for deploy contract case, The value is too small and need to +1
88+
gc = gc/int64(deploySize) + 1
89+
}
90+
91+
bam.InstanceOfHistoryGasUsedRecordDB().UpdateGasUsed([]byte(fnSign), gc)
92+
}
93+
6394
// filterMessageEvents returns the same events with all of type == EventTypeMessage removed except
6495
// for wasm message types.
6596
// this is so only our top-level message event comes through

x/wasm/types/tx.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package types
33
import (
44
"encoding/json"
55
"errors"
6+
"fmt"
67
"strings"
78

89
sdk "github.com/okx/okbchain/libs/cosmos-sdk/types"
@@ -78,6 +79,16 @@ func (msg MsgStoreCode) GetSigners() []sdk.AccAddress {
7879
return []sdk.AccAddress{sdk.WasmToAccAddress(senderAddr)}
7980
}
8081

82+
func (msg MsgStoreCode) FnSignatureInfo() (string, int, error) {
83+
codeLen := len(msg.WASMByteCode)
84+
var err error
85+
if codeLen <= 0 {
86+
err = fmt.Errorf("wasm byte code length is 0")
87+
}
88+
89+
return msg.Type(), codeLen, err
90+
}
91+
8192
func (msg MsgInstantiateContract) Route() string {
8293
return RouterKey
8394
}
@@ -163,6 +174,35 @@ func (msg MsgExecuteContract) GetSigners() []sdk.AccAddress {
163174
return []sdk.AccAddress{sdk.WasmToAccAddress(senderAddr)}
164175
}
165176

177+
func (msg MsgExecuteContract) FnSignatureInfo() (string, int, error) {
178+
if err := msg.Msg.ValidateBasic(); err != nil {
179+
return "", 0, fmt.Errorf("failed to validate msg:%v", err)
180+
}
181+
182+
var v interface{}
183+
json.Unmarshal(msg.Msg, &v)
184+
data := v.(map[string]interface{})
185+
if len(data) != 1 {
186+
return "", 0, fmt.Errorf("failed to check msg method:%s", string(msg.Msg.Bytes()))
187+
}
188+
189+
method := ""
190+
for k, _ := range data {
191+
method = k
192+
break
193+
}
194+
195+
if len(method) <= 0 {
196+
return "", 0, fmt.Errorf("msg has not method:%s", string(msg.Msg.Bytes()))
197+
}
198+
199+
var builder strings.Builder
200+
builder.WriteString(msg.Contract)
201+
builder.WriteString(method)
202+
203+
return builder.String(), 0, nil
204+
}
205+
166206
func (msg MsgMigrateContract) Route() string {
167207
return RouterKey
168208
}

x/wasm/types/tx_test.go

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,3 +545,100 @@ func TestMsgJsonSignBytes(t *testing.T) {
545545
})
546546
}
547547
}
548+
549+
func TestMsgStoreCodeFnSignatureInfo(t *testing.T) {
550+
cases := map[string]struct {
551+
msg MsgStoreCode
552+
len int
553+
err error
554+
}{
555+
"normal": {
556+
msg: MsgStoreCode{
557+
Sender: sdk.WasmAddress(make([]byte, 20)).String(),
558+
WASMByteCode: []byte("foo"),
559+
},
560+
len: 3,
561+
err: nil,
562+
},
563+
"empty": {
564+
msg: MsgStoreCode{
565+
Sender: sdk.WasmAddress(make([]byte, 20)).String(),
566+
WASMByteCode: []byte(""),
567+
},
568+
len: 0,
569+
err: fmt.Errorf("wasm byte code length is 0"),
570+
},
571+
}
572+
573+
for name, tc := range cases {
574+
t.Run(name, func(t *testing.T) {
575+
name, lenFn, err := tc.msg.FnSignatureInfo()
576+
require.Equal(t, name, "store-code")
577+
require.Equal(t, lenFn, tc.len)
578+
require.Equal(t, err, tc.err)
579+
})
580+
}
581+
}
582+
583+
func TestMsgExecuteContractFnSignatureInfo(t *testing.T) {
584+
cases := map[string]struct {
585+
msg MsgExecuteContract
586+
name string
587+
err error
588+
}{
589+
"normal": {
590+
msg: MsgExecuteContract{
591+
Sender: sdk.WasmAddress(make([]byte, 20)).String(),
592+
Contract: sdk.WasmAddress(make([]byte, 20)).String(),
593+
Msg: []byte("{\"press\":{\"ascending\":true}}"),
594+
},
595+
name: "0x0000000000000000000000000000000000000000press",
596+
err: nil,
597+
},
598+
"empty msg name": {
599+
msg: MsgExecuteContract{
600+
Sender: sdk.WasmAddress(make([]byte, 20)).String(),
601+
Contract: sdk.WasmAddress(make([]byte, 20)).String(),
602+
Msg: []byte("{\"\":{\"ascending\":true}}"),
603+
},
604+
name: "",
605+
err: fmt.Errorf("msg has not method:{\"\":{\"ascending\":true}}"),
606+
},
607+
"validate msg": {
608+
msg: MsgExecuteContract{
609+
Sender: sdk.WasmAddress(make([]byte, 20)).String(),
610+
Contract: sdk.WasmAddress(make([]byte, 20)).String(),
611+
Msg: []byte("sdfasdf"),
612+
},
613+
name: "",
614+
err: fmt.Errorf("failed to validate msg:invalid"),
615+
},
616+
"check msg method, 0": {
617+
msg: MsgExecuteContract{
618+
Sender: sdk.WasmAddress(make([]byte, 20)).String(),
619+
Contract: sdk.WasmAddress(make([]byte, 20)).String(),
620+
Msg: []byte("{}"),
621+
},
622+
name: "",
623+
err: fmt.Errorf("failed to check msg method:{}"),
624+
},
625+
"check msg method, 1": {
626+
msg: MsgExecuteContract{
627+
Sender: sdk.WasmAddress(make([]byte, 20)).String(),
628+
Contract: sdk.WasmAddress(make([]byte, 20)).String(),
629+
Msg: []byte("{\"press\":{\"ascending\":true},\"hello\":{\"ascending\":true}}"),
630+
},
631+
name: "",
632+
err: fmt.Errorf("failed to check msg method:{\"press\":{\"ascending\":true},\"hello\":{\"ascending\":true}}"),
633+
},
634+
}
635+
636+
for name, tc := range cases {
637+
t.Run(name, func(t *testing.T) {
638+
name, lenFn, err := tc.msg.FnSignatureInfo()
639+
require.Equal(t, tc.name, name)
640+
require.Equal(t, lenFn, 0)
641+
require.Equal(t, tc.err, err)
642+
})
643+
}
644+
}

0 commit comments

Comments
 (0)