Golang implemented sidechain for Bytom
Revision | af122f09a85f9325539467dc921561e1b26864f3 (tree) |
---|---|
Zeit | 2019-11-27 16:19:42 |
Autor | shenao78 <shenao.78@163....> |
Commiter | shenao78 |
fix conflict
@@ -222,19 +222,21 @@ func addMatchTxOutput(txData *types.TxData, txInput *types.TxInput, order *commo | ||
222 | 222 | } |
223 | 223 | |
224 | 224 | func CalcRequestAmount(fromAmount uint64, contractArg *vmutil.MagneticContractArgs) uint64 { |
225 | - bigFromAmount := big.NewInt(0).SetUint64(fromAmount) | |
226 | - bigRatioNum := big.NewInt(0).SetInt64(contractArg.RatioNumerator) | |
227 | - bigRatioDen := big.NewInt(0).SetInt64(contractArg.RatioDenominator) | |
228 | - product := big.NewInt(0).Mul(bigFromAmount, bigRatioNum) | |
229 | - return big.NewInt(0).Quo(product, bigRatioDen).Uint64() | |
225 | + res := big.NewInt(0).SetUint64(fromAmount) | |
226 | + res.Mul(res, big.NewInt(contractArg.RatioNumerator)).Quo(res, big.NewInt(contractArg.RatioDenominator)) | |
227 | + if !res.IsUint64() { | |
228 | + return 0 | |
229 | + } | |
230 | + return res.Uint64() | |
230 | 231 | } |
231 | 232 | |
232 | 233 | func calcShouldPayAmount(receiveAmount uint64, contractArg *vmutil.MagneticContractArgs) uint64 { |
233 | - bigReceiveAmount := big.NewInt(0).SetUint64(receiveAmount) | |
234 | - bigRatioNum := big.NewInt(0).SetInt64(contractArg.RatioNumerator) | |
235 | - bigRatioDen := big.NewInt(0).SetInt64(contractArg.RatioDenominator) | |
236 | - product := big.NewInt(0).Mul(bigReceiveAmount, bigRatioDen) | |
237 | - return big.NewInt(0).Quo(product, bigRatioNum).Uint64() | |
234 | + res := big.NewInt(0).SetUint64(receiveAmount) | |
235 | + res.Mul(res, big.NewInt(contractArg.RatioDenominator)).Quo(res, big.NewInt(contractArg.RatioNumerator)) | |
236 | + if !res.IsUint64() { | |
237 | + return 0 | |
238 | + } | |
239 | + return res.Uint64() | |
238 | 240 | } |
239 | 241 | |
240 | 242 | func calcMaxFeeAmount(shouldPayAmount uint64, maxFeeRate float64) int64 { |
@@ -247,7 +249,7 @@ func calcOppositeIndex(size int, selfIdx int) int { | ||
247 | 249 | |
248 | 250 | func isMatched(orders []*common.Order) bool { |
249 | 251 | for i, order := range orders { |
250 | - if opposisteOrder := orders[calcOppositeIndex(len(orders), i)]; 1/order.Rate < opposisteOrder.Rate { | |
252 | + if oppositeOrder := orders[calcOppositeIndex(len(orders), i)]; 1/order.Rate < oppositeOrder.Rate { | |
251 | 253 | return false |
252 | 254 | } |
253 | 255 | } |
@@ -8,7 +8,6 @@ import ( | ||
8 | 8 | "github.com/vapor/consensus/segwit" |
9 | 9 | dbm "github.com/vapor/database/leveldb" |
10 | 10 | "github.com/vapor/errors" |
11 | - "github.com/vapor/math/checked" | |
12 | 11 | "github.com/vapor/protocol/bc" |
13 | 12 | "github.com/vapor/protocol/bc/types" |
14 | 13 | ) |
@@ -27,7 +26,7 @@ var ( | ||
27 | 26 | errNumeratorOfRatioIsOverflow = errors.New("ratio numerator of contract args product input amount is overflow") |
28 | 27 | errLengthOfInputIsIncorrect = errors.New("length of matched tx input is not equals to actual matched tx input") |
29 | 28 | errSpendOutputIDIsIncorrect = errors.New("spend output id of matched tx is not equals to actual matched tx") |
30 | - errRequestAmountLessThenOne = errors.New("request amount of order less than one") | |
29 | + errRequestAmountMath = errors.New("request amount of order less than one or big than max of int64") | |
31 | 30 | ) |
32 | 31 | |
33 | 32 | // MovCore represent the core logic of the match module, which include generate match transactions before packing the block, |
@@ -233,12 +232,8 @@ func validateMagneticContractArgs(fromAmount uint64, program []byte) error { | ||
233 | 232 | return errRatioOfTradeLessThanZero |
234 | 233 | } |
235 | 234 | |
236 | - if _, ok := checked.MulInt64(int64(fromAmount), contractArgs.RatioNumerator); !ok { | |
237 | - return errNumeratorOfRatioIsOverflow | |
238 | - } | |
239 | - | |
240 | 235 | if match.CalcRequestAmount(fromAmount, contractArgs) < 1 { |
241 | - return errRequestAmountLessThenOne | |
236 | + return errRequestAmountMath | |
242 | 237 | } |
243 | 238 | return nil |
244 | 239 | } |
@@ -389,17 +389,17 @@ func TestValidateBlock(t *testing.T) { | ||
389 | 389 | wantError: errRatioOfTradeLessThanZero, |
390 | 390 | }, |
391 | 391 | { |
392 | - desc: "ratio numerator product input amount is overflow", | |
392 | + desc: "want amount is overflow", | |
393 | 393 | block: &types.Block{ |
394 | 394 | Transactions: []*types.Tx{ |
395 | 395 | types.NewTx(types.TxData{ |
396 | 396 | Inputs: []*types.TxInput{types.NewSpendInput(nil, *mock.Btc2EthOrders[0].Utxo.SourceID, *mock.Btc2EthOrders[0].FromAssetID, mock.Btc2EthOrders[0].Utxo.Amount, mock.Btc2EthOrders[0].Utxo.SourcePos, []byte{0x51})}, |
397 | - Outputs: []*types.TxOutput{types.NewIntraChainOutput(*mock.Btc2EthOrders[0].FromAssetID, mock.Btc2EthOrders[0].Utxo.Amount, mock.MustCreateP2WMCProgram(mock.ETH, testutil.MustDecodeHexString("51"), math.MaxInt64, 10))}, | |
397 | + Outputs: []*types.TxOutput{types.NewIntraChainOutput(*mock.Btc2EthOrders[0].FromAssetID, mock.Btc2EthOrders[0].Utxo.Amount, mock.MustCreateP2WMCProgram(mock.ETH, testutil.MustDecodeHexString("51"), math.MaxInt64, 1))}, | |
398 | 398 | }), |
399 | 399 | }, |
400 | 400 | }, |
401 | 401 | verifyResults: []*bc.TxVerifyResult{{StatusFail: false}}, |
402 | - wantError: errNumeratorOfRatioIsOverflow, | |
402 | + wantError: errRequestAmountMath, | |
403 | 403 | }, |
404 | 404 | } |
405 | 405 |
@@ -2,6 +2,7 @@ package vm | ||
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "math" |
5 | + "math/big" | |
5 | 6 | |
6 | 7 | "github.com/vapor/math/checked" |
7 | 8 | ) |
@@ -457,3 +458,36 @@ func opWithin(vm *virtualMachine) error { | ||
457 | 458 | } |
458 | 459 | return vm.pushBool(x >= min && x < max, true) |
459 | 460 | } |
461 | + | |
462 | +func opMulFraction(vm *virtualMachine) error { | |
463 | + if err := vm.applyCost(8); err != nil { | |
464 | + return err | |
465 | + } | |
466 | + | |
467 | + z, err := vm.popInt64(true) | |
468 | + if err != nil { | |
469 | + return err | |
470 | + } | |
471 | + | |
472 | + if z == 0 { | |
473 | + return ErrDivZero | |
474 | + } | |
475 | + | |
476 | + y, err := vm.popInt64(true) | |
477 | + if err != nil { | |
478 | + return err | |
479 | + } | |
480 | + | |
481 | + x, err := vm.popInt64(true) | |
482 | + if err != nil { | |
483 | + return err | |
484 | + } | |
485 | + | |
486 | + res := big.NewInt(x) | |
487 | + res.Mul(res, big.NewInt(y)).Quo(res, big.NewInt(z)) | |
488 | + if !res.IsInt64() { | |
489 | + return ErrRange | |
490 | + } | |
491 | + | |
492 | + return vm.pushInt64(res.Int64(), true) | |
493 | +} |
@@ -446,6 +446,40 @@ func TestNumericOps(t *testing.T) { | ||
446 | 446 | deferredCost: -18, |
447 | 447 | dataStack: [][]byte{{1}}, |
448 | 448 | }, |
449 | + }, { | |
450 | + op: OP_MULFRACTION, | |
451 | + startVM: &virtualMachine{ | |
452 | + runLimit: 50000, | |
453 | + dataStack: [][]byte{{15}, {2}, {3}}, | |
454 | + }, | |
455 | + wantVM: &virtualMachine{ | |
456 | + runLimit: 49992, | |
457 | + deferredCost: -18, | |
458 | + dataStack: [][]byte{{10}}, | |
459 | + }, | |
460 | + }, { | |
461 | + op: OP_MULFRACTION, | |
462 | + startVM: &virtualMachine{ | |
463 | + runLimit: 50000, | |
464 | + dataStack: [][]byte{Int64Bytes(-654), {3}, {2}}, | |
465 | + }, | |
466 | + wantVM: &virtualMachine{ | |
467 | + runLimit: 49992, | |
468 | + deferredCost: -18, | |
469 | + dataStack: [][]byte{Int64Bytes(-981)}, | |
470 | + }, | |
471 | + }, { | |
472 | + op: OP_MULFRACTION, | |
473 | + startVM: &virtualMachine{ | |
474 | + runLimit: 50000, | |
475 | + dataStack: [][]byte{Int64Bytes(-654), {3}, {}}, | |
476 | + }, | |
477 | + wantVM: &virtualMachine{ | |
478 | + runLimit: 49992, | |
479 | + deferredCost: -18, | |
480 | + dataStack: [][]byte{}, | |
481 | + }, | |
482 | + wantErr: ErrDivZero, | |
449 | 483 | }} |
450 | 484 | |
451 | 485 | numops := []Op{ |
@@ -453,6 +487,7 @@ func TestNumericOps(t *testing.T) { | ||
453 | 487 | OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_MOD, OP_LSHIFT, OP_RSHIFT, OP_BOOLAND, |
454 | 488 | OP_BOOLOR, OP_NUMEQUAL, OP_NUMEQUALVERIFY, OP_NUMNOTEQUAL, OP_LESSTHAN, |
455 | 489 | OP_LESSTHANOREQUAL, OP_GREATERTHAN, OP_GREATERTHANOREQUAL, OP_MIN, OP_MAX, OP_WITHIN, |
490 | + OP_MULFRACTION, | |
456 | 491 | } |
457 | 492 | |
458 | 493 | for _, op := range numops { |
@@ -536,6 +571,14 @@ func TestRangeErrs(t *testing.T) { | ||
536 | 571 | {fmt.Sprintf("%d 1 LSHIFT", int64(math.MinInt64)), true}, |
537 | 572 | {fmt.Sprintf("%d 1 LSHIFT", int64(math.MinInt64)/2), false}, |
538 | 573 | {fmt.Sprintf("%d 2 LSHIFT", int64(math.MinInt64)/2), true}, |
574 | + {fmt.Sprintf("%d %d %d MULFRACTION", int64(math.MaxInt64)/2-1, 2, 1), false}, | |
575 | + {fmt.Sprintf("%d %d %d MULFRACTION", int64(math.MaxInt64)/2+1, 2, 1), true}, | |
576 | + {fmt.Sprintf("%d %d %d MULFRACTION", int64(math.MinInt64)/2+1, 2, 1), false}, | |
577 | + {fmt.Sprintf("%d %d %d MULFRACTION", int64(math.MinInt64)/2-1, 2, 1), true}, | |
578 | + {fmt.Sprintf("%d %d %d MULFRACTION", int64(math.MaxInt64), 3, 2), true}, | |
579 | + {fmt.Sprintf("%d %d %d MULFRACTION", int64(math.MaxInt64), 2, 3), false}, | |
580 | + {fmt.Sprintf("%d %d %d MULFRACTION", int64(math.MinInt64), 3, 2), true}, | |
581 | + {fmt.Sprintf("%d %d %d MULFRACTION", int64(math.MinInt64), 2, 3), false}, | |
539 | 582 | } |
540 | 583 | |
541 | 584 | for i, c := range cases { |
@@ -194,6 +194,7 @@ const ( | ||
194 | 194 | OP_MIN Op = 0xa3 |
195 | 195 | OP_MAX Op = 0xa4 |
196 | 196 | OP_WITHIN Op = 0xa5 |
197 | + OP_MULFRACTION Op = 0xa6 | |
197 | 198 | |
198 | 199 | OP_SHA256 Op = 0xa8 |
199 | 200 | OP_SHA3 Op = 0xaa |
@@ -300,6 +301,7 @@ var ( | ||
300 | 301 | OP_MIN: {OP_MIN, "MIN", opMin}, |
301 | 302 | OP_MAX: {OP_MAX, "MAX", opMax}, |
302 | 303 | OP_WITHIN: {OP_WITHIN, "WITHIN", opWithin}, |
304 | + OP_MULFRACTION: {OP_MULFRACTION, "MULFRACTION", opMulFraction}, | |
303 | 305 | |
304 | 306 | OP_SHA256: {OP_SHA256, "SHA256", opSha256}, |
305 | 307 | OP_SHA3: {OP_SHA3, "SHA3", opSha3}, |
@@ -200,10 +200,9 @@ func P2WMCProgram(magneticContractArgs MagneticContractArgs) ([]byte, error) { | ||
200 | 200 | // PICK [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset exchangeAmount] |
201 | 201 | // 3 [... exchangeAmount sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset exchangeAmount 3] |
202 | 202 | // ROLL [... exchangeAmount sellerKey standardProgram sellerProgram ratioNumerator requestedAsset exchangeAmount ratioDenominator] |
203 | -// MUL [... exchangeAmount sellerKey standardProgram sellerProgram ratioNumerator requestedAsset (exchangeAmount * ratioDenominator)] | |
204 | -// 2 [... exchangeAmount sellerKey standardProgram sellerProgram ratioNumerator requestedAsset (exchangeAmount * ratioDenominator) 2] | |
205 | -// ROLL [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset (exchangeAmount * ratioDenominator) ratioNumerator] | |
206 | -// DIV [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount] | |
203 | +// 3 [... exchangeAmount sellerKey standardProgram sellerProgram ratioNumerator requestedAsset exchangeAmount ratioDenominator 3] | |
204 | +// ROLL [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset exchangeAmount ratioDenominator ratioNumerator] | |
205 | +// MULFRACTION [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount] | |
207 | 206 | // AMOUNT [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount valueAmount] |
208 | 207 | // OVER [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount valueAmount actualAmount] |
209 | 208 | // 0 [... exchangeAmount sellerKey standardProgram sellerProgram requestedAsset actualAmount valueAmount actualAmount 0] |
@@ -244,10 +243,9 @@ func P2WMCProgram(magneticContractArgs MagneticContractArgs) ([]byte, error) { | ||
244 | 243 | // AMOUNT [... sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset valueAmount] |
245 | 244 | // 2 [... sellerKey standardProgram sellerProgram ratioDenominator ratioNumerator requestedAsset valueAmount 2] |
246 | 245 | // ROLL [... sellerKey standardProgram sellerProgram ratioDenominator requestedAsset valueAmount ratioNumerator] |
247 | -// MUL [... sellerKey standardProgram sellerProgram ratioDenominator requestedAsset (valueAmount * ratioNumerator)] | |
248 | -// 2 [... sellerKey standardProgram sellerProgram ratioDenominator requestedAsset (valueAmount * ratioNumerator) 2] | |
249 | -// ROLL [... sellerKey standardProgram sellerProgram requestedAsset (valueAmount * ratioNumerator) ratioDenominator] | |
250 | -// DIV [... sellerKey standardProgram sellerProgram requestedAsset requestedAmount] | |
246 | +// 3 [... sellerKey standardProgram sellerProgram ratioDenominator requestedAsset valueAmount ratioNumerator 3] | |
247 | +// ROLL [... sellerKey standardProgram sellerProgram requestedAsset valueAmount ratioNumerator ratioDenominator] | |
248 | +// MULFRACTION [... sellerKey standardProgram sellerProgram requestedAsset requestedAmount] | |
251 | 249 | // DUP [... sellerKey standardProgram sellerProgram requestedAsset requestedAmount requestedAmount] |
252 | 250 | // 0 [... sellerKey standardProgram sellerProgram requestedAsset requestedAmount requestedAmount 0] |
253 | 251 | // GREATERTHAN [... sellerKey standardProgram sellerProgram requestedAsset requestedAmount (requestedAmount > 0)] |
@@ -299,9 +297,9 @@ func P2MCProgram(magneticContractArgs MagneticContractArgs) ([]byte, error) { | ||
299 | 297 | builder.AddOp(vm.OP_PICK) |
300 | 298 | builder.AddOp(vm.OP_3) |
301 | 299 | builder.AddOp(vm.OP_ROLL) |
302 | - builder.AddOp(vm.OP_MUL) | |
303 | - builder.AddOp(vm.OP_ROT) | |
304 | - builder.AddOp(vm.OP_DIV) | |
300 | + builder.AddOp(vm.OP_3) | |
301 | + builder.AddOp(vm.OP_ROLL) | |
302 | + builder.AddOp(vm.OP_MULFRACTION) | |
305 | 303 | builder.AddOp(vm.OP_AMOUNT) |
306 | 304 | builder.AddOp(vm.OP_OVER) |
307 | 305 | builder.AddOp(vm.OP_0) |
@@ -339,9 +337,9 @@ func P2MCProgram(magneticContractArgs MagneticContractArgs) ([]byte, error) { | ||
339 | 337 | builder.SetJumpTarget(1) |
340 | 338 | builder.AddOp(vm.OP_AMOUNT) |
341 | 339 | builder.AddOp(vm.OP_ROT) |
342 | - builder.AddOp(vm.OP_MUL) | |
343 | - builder.AddOp(vm.OP_ROT) | |
344 | - builder.AddOp(vm.OP_DIV) | |
340 | + builder.AddOp(vm.OP_3) | |
341 | + builder.AddOp(vm.OP_ROLL) | |
342 | + builder.AddOp(vm.OP_MULFRACTION) | |
345 | 343 | builder.AddOp(vm.OP_DUP) |
346 | 344 | builder.AddOp(vm.OP_0) |
347 | 345 | builder.AddOp(vm.OP_GREATERTHAN) |