Skip to content

Commit 810d0e4

Browse files
committed
import timelock utility
1 parent b236d1a commit 810d0e4

File tree

6 files changed

+164
-27
lines changed

6 files changed

+164
-27
lines changed

applications/util/tx.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"hyperledger.abchain.org/core/crypto"
99
txutil "hyperledger.abchain.org/core/tx"
1010
"net/http"
11+
"time"
1112
)
1213

1314
type FabricRPCCore struct {
@@ -36,6 +37,23 @@ func (s *FabricRPCCore) PrehandlePost(rw web.ResponseWriter,
3637
s.TxGenerator.BeginTx(nil)
3738
}
3839

40+
if tl := req.PostFormValue("timelock"); tl != "" {
41+
td, err := time.ParseDuration(tl)
42+
if err != nil {
43+
http.Error(rw, err.Error(), http.StatusBadRequest)
44+
return
45+
}
46+
s.TxGenerator.Timelock = time.Now().Add(td)
47+
48+
} else if tlT := req.PostFormValue("timelockat"); tlT != "" {
49+
t, err := time.Parse(time.Stamp, tlT)
50+
if err != nil {
51+
http.Error(rw, err.Error(), http.StatusBadRequest)
52+
return
53+
}
54+
s.TxGenerator.Timelock = t
55+
}
56+
3957
s.rwForOutput = rw
4058
}
4159

chaincode/lib/txgen/tx.go

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"github.com/golang/protobuf/proto"
66
"hyperledger.abchain.org/chaincode/lib/caller"
77
txutil "hyperledger.abchain.org/core/tx"
8+
"time"
89
)
910

1011
type QueryResp struct {
@@ -41,6 +42,7 @@ type TxGenerator struct {
4142
calledError error
4243
callnotify chan struct{}
4344
call_deploy bool
45+
Timelock time.Time
4446
Credgenerator TxCredHandler
4547
Dispatcher rpc.Caller
4648
MethodMapper map[string]string
@@ -72,12 +74,28 @@ func (t *TxGenerator) txcall(method string, msg proto.Message) error {
7274

7375
method = t.methodName(method)
7476

75-
b, err := txutil.NewTxBuilder(t.Ccname, t.GetNonce(), method, msg)
76-
if err != nil {
77-
return err
78-
}
77+
if t.Timelock.IsZero() {
78+
79+
b, err := txutil.NewTxBuilder(t.Ccname, t.GetNonce(), method, msg)
80+
if err != nil {
81+
return err
82+
}
83+
t.txbuilder = b
84+
85+
} else {
86+
b, err := txutil.NewTxBuilderWithTimeLock(t.Ccname, t.GetNonce(), t.Timelock)
87+
if err != nil {
88+
return err
89+
}
7990

80-
t.txbuilder = b
91+
err = b.SetMessage(msg)
92+
if err != nil {
93+
return err
94+
}
95+
b.SetMethod(method)
96+
t.txbuilder = b
97+
98+
}
8199

82100
return nil
83101
}

chaincode/lib/txhandle/tx.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,18 @@ func (cci *ChaincodeTx) TxCall(stub shim.ChaincodeStubInterface,
4040
return nil, errors.New("Unmatched chaincode name")
4141
}
4242

43+
//check ts expired
44+
if parser.GetFlags().IsTimeLock() {
45+
expT := parser.GetTxTime()
46+
if expT.IsZero() {
47+
return nil, errors.New("Enforced timelock Tx has no valid expired time")
48+
} else if nowT, err := stub.GetTxTime(); err != nil {
49+
return nil, errors.New("Can not get exec time: " + err.Error())
50+
} else if nowT.After(expT) {
51+
return nil, errors.New("Tx is expired")
52+
}
53+
}
54+
4355
for _, h := range cci.PreHandlers {
4456
err := h.PreHandling(stub, function, parser)
4557
if err != nil {

core/tx/txParser.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,29 @@ import (
88
"time"
99
)
1010

11+
type Flags uint32
12+
13+
//indicate the expried time in header is obliged to be considered
14+
func TxFlag_Timelock() Flags {
15+
return Flags(1)
16+
}
17+
18+
func (f Flags) U() uint32 {
19+
return uint32(f)
20+
}
21+
22+
func (f Flags) And(fanother Flags) Flags {
23+
return Flags(uint32(f) | uint32(fanother))
24+
}
25+
26+
func (f Flags) IsTimeLock() bool {
27+
return (f & TxFlag_Timelock()) != 0
28+
}
29+
1130
type Parser interface {
1231
GetCCname() string
1332
GetNonce() []byte
33+
GetFlags() Flags
1434
GetTxTime() time.Time
1535
GetAddrCredential() AddrCredentials
1636
GetDataCredential() DataCredentials
@@ -35,6 +55,10 @@ func (t *txParser) GetNonce() []byte {
3555
return t.nonce
3656
}
3757

58+
func (t *txParser) GetFlags() Flags {
59+
return Flags(t.flags)
60+
}
61+
3862
func (t *txParser) GetTxTime() time.Time {
3963
return t.txts
4064
}

core/tx/tx_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func TestTx(t *testing.T) {
3838

3939
txinit(t)
4040

41-
msg := &pb.TxMsgExample{[]byte{'1', '9', '8', '4'}, 1984}
41+
msg := &pb.TxMsgExample{Param1: []byte{'1', '9', '8', '4'}, Param2: 1984}
4242

4343
builder, err := NewTxBuilder("gamepai", nil, "example", msg)
4444

core/tx/txbuilder.go

Lines changed: 86 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ type baseMaker struct {
2323
credBuilder *builder
2424
}
2525

26-
func NewTxMaker(args [][]byte) TxMaker {
26+
func NewTxMaker(args [][]byte) *baseMaker {
2727
return &baseMaker{args, newTxCredentialBuilder()}
2828
}
2929

@@ -79,18 +79,53 @@ type Builder interface {
7979

8080
type baseBuilder struct {
8181
baseMaker
82-
txHash []byte
82+
method string
8383
nonce []byte
84+
txHash []byte
8485
}
8586

8687
func (b *baseBuilder) GetHash() []byte {
88+
if b.txHash == nil {
89+
b.txHash = b.GenHash(b.method)
90+
}
8791
return b.txHash
8892
}
8993

9094
func (b *baseBuilder) GetNonce() []byte {
9195
return b.nonce
9296
}
9397

98+
func (b *baseBuilder) SetHeader(h *pb.TxHeader) error {
99+
100+
hh := msgToByte(h)
101+
if hh == nil {
102+
return errors.New("Encode header fail")
103+
}
104+
105+
b.nonce = h.GetNonce()
106+
b.txHash = nil
107+
108+
b.txArgs[0] = hh
109+
110+
return nil
111+
}
112+
113+
func (b *baseBuilder) SetMethod(m string) {
114+
b.txHash = nil
115+
b.method = m
116+
}
117+
118+
func (b *baseBuilder) SetMessage(msg proto.Message) error {
119+
120+
hm := msgToByte(msg)
121+
if hm == nil {
122+
return errors.New("No message binded")
123+
}
124+
b.txArgs[1] = hm
125+
b.txHash = nil
126+
return nil
127+
}
128+
94129
const (
95130
queryEffectInHour int = 1
96131
)
@@ -107,41 +142,71 @@ func GenerateNonce() []byte {
107142
return nonce
108143
}
109144

110-
func NewTxBuilder(ccname string, nonce []byte, method string, msg proto.Message) (Builder, error) {
145+
func newTxBuilder() *baseBuilder {
111146

112-
hm := msgToByte(msg)
113-
if hm == nil {
114-
return nil, errors.New("No message binded")
115-
}
147+
return &baseBuilder{baseMaker: baseMaker{make([][]byte, 2), newTxCredentialBuilder()}}
148+
}
149+
150+
func NewTxBuilderWithTimeLock(ccname string, nonce []byte, t time.Time) (b *baseBuilder, err error) {
116151

117152
if nonce == nil {
118153
nonce = GenerateNonce()
119154
}
120155

121-
expTime := &timestamp.Timestamp{
122-
Seconds: time.Now().Unix() + int64(queryEffectInHour*3600),
123-
Nanos: 0}
156+
header := &pb.TxHeader{
157+
Base: &pb.TxBase{
158+
Network: DefaultNetworkName(),
159+
Ccname: ccname,
160+
},
161+
ExpiredTs: &timestamp.Timestamp{
162+
Seconds: t.Unix(),
163+
Nanos: 0},
164+
Nonce: nonce,
165+
Flags: TxFlag_Timelock().U(),
166+
}
167+
168+
b = newTxBuilder()
169+
err = b.SetHeader(header)
170+
171+
return
172+
}
173+
174+
func NewTxBuilder2(ccname string, nonce []byte) (b *baseBuilder, err error) {
175+
176+
if nonce == nil {
177+
nonce = GenerateNonce()
178+
}
124179

125180
header := &pb.TxHeader{
126181
Base: &pb.TxBase{
127182
Network: DefaultNetworkName(),
128183
Ccname: ccname,
129-
Method: "",
130184
},
131-
ExpiredTs: expTime,
132-
Nonce: nonce,
185+
ExpiredTs: &timestamp.Timestamp{
186+
Seconds: time.Now().Unix() + int64(queryEffectInHour*3600),
187+
Nanos: 0},
188+
Nonce: nonce,
133189
}
134190

135-
hh := msgToByte(header)
136-
if hh == nil {
137-
return nil, errors.New("Encode header fail")
191+
b = newTxBuilder()
192+
err = b.SetHeader(header)
193+
194+
return
195+
}
196+
197+
func NewTxBuilder(ccname string, nonce []byte, method string, msg proto.Message) (*baseBuilder, error) {
198+
199+
b, err := NewTxBuilder2(ccname, nonce)
200+
if err != nil {
201+
return nil, err
202+
}
203+
204+
err = b.SetMessage(msg)
205+
if err != nil {
206+
return nil, err
138207
}
139208

140-
b := &baseBuilder{
141-
baseMaker{[][]byte{hh, hm}, newTxCredentialBuilder()},
142-
genHash(hh, hm, method),
143-
nonce}
209+
b.SetMethod(method)
144210

145211
return b, nil
146-
147212
}

0 commit comments

Comments
 (0)