Official Go implementation of the Bytom protocol
Revision | 5460f4e62e3552829dc1f1a82a5e909ca744e6b8 (tree) |
---|---|
Time | 2019-01-11 16:13:02 |
Author | oysheng <oysheng@byto...> |
Commiter | oysheng |
optimise contract check for validate transaction
@@ -51,6 +51,31 @@ func IsP2WSHScript(prog []byte) bool { | ||
51 | 51 | return insts[1].Op == vm.OP_DATA_32 && len(insts[1].Data) == consensus.PayToWitnessScriptHashDataSize |
52 | 52 | } |
53 | 53 | |
54 | +func IsContainCheckOutput(prog []byte) bool { | |
55 | + insts, err := vm.ParseProgram(prog) | |
56 | + if err != nil { | |
57 | + return false | |
58 | + } | |
59 | + | |
60 | + for pos, inst := range insts { | |
61 | + if inst.Op == vm.OP_CHECKOUTPUT { | |
62 | + return true | |
63 | + } else if inst.Op == vm.OP_CHECKPREDICATE && (pos-2) >= 0 { | |
64 | + instructions, err := vm.ParseProgram(insts[pos-2].Data) | |
65 | + if err != nil { | |
66 | + return false | |
67 | + } | |
68 | + | |
69 | + for _, instruction := range instructions { | |
70 | + if instruction.Op == vm.OP_CHECKOUTPUT { | |
71 | + return true | |
72 | + } | |
73 | + } | |
74 | + } | |
75 | + } | |
76 | + return false | |
77 | +} | |
78 | + | |
54 | 79 | func ConvertP2PKHSigProgram(prog []byte) ([]byte, error) { |
55 | 80 | insts, err := vm.ParseProgram(prog) |
56 | 81 | if err != nil { |
@@ -184,6 +184,12 @@ func checkValid(vs *validationState, e bc.Entry) (err error) { | ||
184 | 184 | return errors.Wrapf(bc.ErrMissingEntry, "entry for bytom input %x not found", BTMInputID) |
185 | 185 | } |
186 | 186 | |
187 | + vs2 := *vs | |
188 | + vs2.entryID = BTMInputID | |
189 | + if err := checkValid(&vs2, e); err != nil { | |
190 | + return errors.Wrap(err, "checking gas input") | |
191 | + } | |
192 | + | |
187 | 193 | // check contract program |
188 | 194 | if res, ok := e.(*bc.Spend); ok { |
189 | 195 | if res.SpentOutputId == nil { |
@@ -195,15 +201,16 @@ func checkValid(vs *validationState, e bc.Entry) (err error) { | ||
195 | 201 | return errors.Wrap(err, "getting spend prevout") |
196 | 202 | } |
197 | 203 | |
204 | + var prog []byte | |
198 | 205 | if !segwit.IsP2WScript(spentOutput.ControlProgram.Code) { |
199 | - contractFalg = true | |
206 | + prog = spentOutput.ControlProgram.Code | |
207 | + } else if segwit.IsP2WSHScript(spentOutput.ControlProgram.Code) && len(res.WitnessArguments) != 0 { | |
208 | + prog = res.WitnessArguments[len(res.WitnessArguments)-1] | |
200 | 209 | } |
201 | - } | |
202 | 210 | |
203 | - vs2 := *vs | |
204 | - vs2.entryID = BTMInputID | |
205 | - if err := checkValid(&vs2, e); err != nil { | |
206 | - return errors.Wrap(err, "checking gas input") | |
211 | + if prog != nil && segwit.IsContainCheckOutput(prog) { | |
212 | + contractFalg = true | |
213 | + } | |
207 | 214 | } |
208 | 215 | } |
209 | 216 |