aboutsummaryrefslogtreecommitdiffstats
path: root/dex/recovery.go
diff options
context:
space:
mode:
authorWei-Ning Huang <w@dexon.org>2019-03-21 16:54:37 +0800
committerWei-Ning Huang <w@byzantine-lab.io>2019-06-13 18:11:44 +0800
commit22631478cadc0f6a21a219af4399b86619240606 (patch)
tree327ec5b9ab71f67e667e32dbbb6db3c09cbc7665 /dex/recovery.go
parent33f98f535d3f79d9d915ac57255aeee5d83ef81d (diff)
downloadgo-tangerine-22631478cadc0f6a21a219af4399b86619240606.tar
go-tangerine-22631478cadc0f6a21a219af4399b86619240606.tar.gz
go-tangerine-22631478cadc0f6a21a219af4399b86619240606.tar.bz2
go-tangerine-22631478cadc0f6a21a219af4399b86619240606.tar.lz
go-tangerine-22631478cadc0f6a21a219af4399b86619240606.tar.xz
go-tangerine-22631478cadc0f6a21a219af4399b86619240606.tar.zst
go-tangerine-22631478cadc0f6a21a219af4399b86619240606.zip
dex: skip duplicate vote to reduce gas used (#293)
Diffstat (limited to 'dex/recovery.go')
-rw-r--r--dex/recovery.go72
1 files changed, 45 insertions, 27 deletions
diff --git a/dex/recovery.go b/dex/recovery.go
index 0e5c60e1a..4c3da7d5a 100644
--- a/dex/recovery.go
+++ b/dex/recovery.go
@@ -20,6 +20,7 @@ package dex
import (
"crypto/ecdsa"
"encoding/hex"
+ "errors"
"fmt"
"math/big"
"strconv"
@@ -29,6 +30,7 @@ import (
"github.com/dexon-foundation/dexon/common"
"github.com/dexon-foundation/dexon/core/types"
"github.com/dexon-foundation/dexon/crypto"
+ "github.com/dexon-foundation/dexon/log"
"github.com/dexon-foundation/dexon/params"
"github.com/dexon-foundation/dexon/rlp"
"github.com/onrik/ethrpc"
@@ -296,6 +298,8 @@ const recoveryABI = `
]
`
+var errAlreadyVoted = errors.New("already voted for recovery")
+
var abiObject abi.ABI
func init() {
@@ -328,6 +332,23 @@ func NewRecovery(config *params.RecoveryConfig, networkRPC string,
}
}
+func (r *Recovery) callRPC(data []byte, tag string) ([]byte, error) {
+ res, err := r.client.EthCall(ethrpc.T{
+ From: r.nodeAddress.String(),
+ To: r.contract.String(),
+ Data: "0x" + hex.EncodeToString(data),
+ }, tag)
+ if err != nil {
+ return nil, err
+ }
+
+ resBytes, err := hex.DecodeString(res[2:])
+ if err != nil {
+ return nil, err
+ }
+ return resBytes, nil
+}
+
func (r *Recovery) genVoteForSkipBlockTx(height uint64) (*types.Transaction, error) {
netVersion, err := r.client.NetVersion()
if err != nil {
@@ -339,21 +360,33 @@ func (r *Recovery) genVoteForSkipBlockTx(height uint64) (*types.Transaction, err
return nil, err
}
- data, err := abiObject.Pack("depositValue")
+ data, err := abiObject.Pack("voted", big.NewInt(int64(height)), r.nodeAddress)
if err != nil {
return nil, err
}
- res, err := r.client.EthCall(ethrpc.T{
- From: r.nodeAddress.String(),
- To: r.contract.String(),
- Data: "0x" + hex.EncodeToString(data),
- }, "latest")
+ resBytes, err := r.callRPC(data, "latest")
if err != nil {
return nil, err
}
- resBytes, err := hex.DecodeString(res[2:])
+ var voted bool
+ err = abiObject.Unpack(&voted, "voted", resBytes)
+ if err != nil {
+ return nil, err
+ }
+
+ if voted {
+ log.Info("Already voted for skip block", "height", height)
+ return nil, errAlreadyVoted
+ }
+
+ data, err = abiObject.Pack("depositValue")
+ if err != nil {
+ return nil, err
+ }
+
+ resBytes, err = r.callRPC(data, "latest")
if err != nil {
return nil, err
}
@@ -397,6 +430,9 @@ func (r *Recovery) genVoteForSkipBlockTx(height uint64) (*types.Transaction, err
func (r *Recovery) ProposeSkipBlock(height uint64) error {
tx, err := r.genVoteForSkipBlockTx(height)
+ if err == errAlreadyVoted {
+ return nil
+ }
if err != nil {
return err
}
@@ -422,16 +458,7 @@ func (r *Recovery) Votes(height uint64) (uint64, error) {
snapshotHeight := bn - numConfirmation
- res, err := r.client.EthCall(ethrpc.T{
- From: r.nodeAddress.String(),
- To: r.contract.String(),
- Data: "0x" + hex.EncodeToString(data),
- }, fmt.Sprintf("0x%x", snapshotHeight))
- if err != nil {
- return 0, err
- }
-
- resBytes, err := hex.DecodeString(res[2:])
+ resBytes, err := r.callRPC(data, fmt.Sprintf("0x%x", snapshotHeight))
if err != nil {
return 0, err
}
@@ -456,16 +483,7 @@ func (r *Recovery) Votes(height uint64) (uint64, error) {
return 0, err
}
- res, err = r.client.EthCall(ethrpc.T{
- From: r.nodeAddress.String(),
- To: r.contract.String(),
- Data: "0x" + hex.EncodeToString(data),
- }, fmt.Sprintf("0x%x", snapshotHeight))
- if err != nil {
- return 0, err
- }
-
- resBytes, err := hex.DecodeString(res[2:])
+ resBytes, err := r.callRPC(data, fmt.Sprintf("0x%x", snapshotHeight))
if err != nil {
return 0, err
}