Skip to content

Commit

Permalink
redux
Browse files Browse the repository at this point in the history
resolve intermediary tests

test updates
  • Loading branch information
andrewkmin committed Jun 20, 2022
1 parent bbfa980 commit c123dfe
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 35 deletions.
53 changes: 41 additions & 12 deletions services/construction/construction_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"context"
"encoding/hex"
"encoding/json"
"fmt"
"math/big"
"testing"

Expand Down Expand Up @@ -58,8 +59,9 @@ var (
transferGasLimitERC20 = uint64(65000)
transferNonce = uint64(67)
transferData = "0xa9059cbb000000000000000000000000efd3dc58d60af3295b92ecd484caeb3a2f30b3e7000000000000000000000000000000000000000000000000000000000134653c" //nolint
transferGasCap = uint64(1001000000)
transferGasTip = uint64(1000000000)
transferGasCap = uint64(60000000000) // 60 gwei
transferGasTip = uint64(1500000000) // 1.5 gwei
transferGasCapWithTip = transferGasCap + transferGasTip

transferValueHex = hexutil.EncodeUint64(transferValue)
transferGasLimitHex = hexutil.EncodeUint64(transferGasLimit)
Expand All @@ -68,6 +70,10 @@ var (
transferNonceHex2 = "0x22"
transferGasCapHex = hexutil.EncodeUint64(transferGasCap)
transferGasTipHex = hexutil.EncodeUint64(transferGasTip)
transferGasCapWithTipHex = hexutil.EncodeUint64(transferGasCapWithTip)

minGasCap = big.NewInt(30000000000)
minGasCapHex = hexutil.EncodeUint64(minGasCap.Uint64())

header = EthTypes.Header{
ParentHash: common.Hash{},
Expand All @@ -83,7 +89,24 @@ var (
GasUsed: 0,
Time: 0,
Extra: hexutil.Bytes{},
BaseFee: big.NewInt(30000000000), // equivalent to 30 gwei
BaseFee: minGasCap, // equivalent to 30 gwei, previously 500000
}

headerWithLowBaseFee = EthTypes.Header{
ParentHash: common.Hash{},
UncleHash: common.Hash{},
Coinbase: common.Address{},
Root: common.Hash{},
TxHash: common.Hash{},
ReceiptHash: common.Hash{},
Bloom: EthTypes.Bloom{},
Difficulty: nil,
Number: nil,
GasLimit: 0,
GasUsed: 0,
Time: 0,
Extra: hexutil.Bytes{},
BaseFee: big.NewInt(10000000000), // equivalent to 10 gwei
}
)

Expand Down Expand Up @@ -158,15 +181,14 @@ func TestConstructionFlowWithPendingNonce(t *testing.T) {
// Test Metadata
metadata := &metadata{
GasLimit: 21000,
GasTip: big.NewInt(1500000000),
GasCap: big.NewInt(1501000000),
GasTip: big.NewInt(int64(transferGasTip)),
GasCap: big.NewInt(int64(transferGasCapWithTip)), // math: gasCap = new(big.Int).Add(gasTip, new(big.Int).Mul(baseFee, multiplier))
Nonce: 0,
To: constructionToAddress,
Value: big.NewInt(1000),
}

var blockNum *big.Int = nil

mockClient.On(
"BlockHeader",
ctx,
Expand All @@ -179,7 +201,7 @@ func TestConstructionFlowWithPendingNonce(t *testing.T) {
"SuggestGasTipCap",
ctx,
).Return(
big.NewInt(1500000000),
big.NewInt(int64(transferGasTip)),
nil,
).Once()
mockClient.On(
Expand All @@ -199,23 +221,27 @@ func TestConstructionFlowWithPendingNonce(t *testing.T) {
Metadata: forceMarshalMap(t, metadata),
SuggestedFee: []*types.Amount{
{
Value: "661500000000000",
Value: "1291500000000000",
Currency: polygon.Currency,
},
},
}, metadataResponse)

// Test Payloads
unsignedRaw := `{"from":"0x5aCB42b3cfCD734a57AFF800139ba1354b549159","to":"0x3Fa177c2E87Cb24148EC403921dB577d140CC07c","value":"0x3e8","data":"0x","nonce":"0x0","max_fee_per_gas":"0x59682f00","max_priority_fee_per_gas":"0x59682f00","gas":"0x5208","chain_id":"0x13881"}`
unsignedRaw := `{"from":"0x5aCB42b3cfCD734a57AFF800139ba1354b549159","to":"0x3Fa177c2E87Cb24148EC403921dB577d140CC07c","value":"0x3e8","data":"0x","nonce":"0x0","max_fee_per_gas":"0xe51af8700","max_priority_fee_per_gas":"0x59682f00","gas":"0x5208","chain_id":"0x13881"}`
payloadsResponse, err := servicer.ConstructionPayloads(ctx, &types.ConstructionPayloadsRequest{
NetworkIdentifier: networkIdentifier,
Operations: ops,
Metadata: forceMarshalMap(t, metadata),
})
assert.Nil(t, err)
payloadsRaw := `[{"address":"0x5aCB42b3cfCD734a57AFF800139ba1354b549159","hex_bytes":"9df2732e3102b2de6c837eb1055292b1f0472b6ae898dff7ba917afc61719120","account_identifier":{"address":"0x5aCB42b3cfCD734a57AFF800139ba1354b549159"},"signature_type":"ecdsa_recovery"}]`

payloadsRaw := `[{"address":"0x5aCB42b3cfCD734a57AFF800139ba1354b549159","hex_bytes":"0206e22e9bded068a76f89a86e0849b7e6ff8f6e8a22e1b679fd87a08635a9f2","account_identifier":{"address":"0x5aCB42b3cfCD734a57AFF800139ba1354b549159"},"signature_type":"ecdsa_recovery"}]`
var payloads []*types.SigningPayload
assert.NoError(t, json.Unmarshal([]byte(payloadsRaw), &payloads))

hexString := hexutil.Encode(payloadsResponse.Payloads[0].Bytes)
fmt.Printf("hexstring %s", hexString)
assert.Equal(t, &types.ConstructionPayloadsResponse{
UnsignedTransaction: unsignedRaw,
Payloads: payloads,
Expand Down Expand Up @@ -245,15 +271,18 @@ func TestConstructionFlowWithPendingNonce(t *testing.T) {
}, parseUnsignedResponse)

// Test Combine
signaturesRaw := `[{"hex_bytes":"9f2f61a9a90f6695b10ed04102dca3e0aa50a10263afd861761226e3e61903a62fb42a9e8d96af626e64fd20573338f41d4f90ea9834ce6aa4ff79869181699700","public_key":{"hex_bytes":"0405e82ac561143aafc13ba109677a597c8f797b07417d0addd7a346ad35882b3c4a006620e02127b9a32e90979ff93ecad0a2f577db238163a50023e393e354ff","curve_type":"secp256k1"},"signing_payload":{"hex_bytes":"9df2732e3102b2de6c837eb1055292b1f0472b6ae898dff7ba917afc61719120","address":"0x5aCB42b3cfCD734a57AFF800139ba1354b549159"},"signature_type":"ecdsa_recovery"}]`
signaturesRaw := `[{"hex_bytes":"9f2f61a9a90f6695b10ed04102dca3e0aa50a10263afd861761226e3e61903a62fb42a9e8d96af626e64fd20573338f41d4f90ea9834ce6aa4ff79869181699700","public_key":{"hex_bytes":"0405e82ac561143aafc13ba109677a597c8f797b07417d0addd7a346ad35882b3c4a006620e02127b9a32e90979ff93ecad0a2f577db238163a50023e393e354ff","curve_type":"secp256k1"},"signing_payload":{"hex_bytes":"0206e22e9bded068a76f89a86e0849b7e6ff8f6e8a22e1b679fd87a08635a9f2","address":"0x5aCB42b3cfCD734a57AFF800139ba1354b549159"},"signature_type":"ecdsa_recovery"}]`
var signatures []*types.Signature
assert.NoError(t, json.Unmarshal([]byte(signaturesRaw), &signatures))
signedRaw := `{"type":"0x2","nonce":"0x0","gasPrice":null,"maxPriorityFeePerGas":"0x59682f00","maxFeePerGas":"0xe51af8700","gas":"0x5208","value":"0x3e8","input":"0x","v":"0x0","r":"0x9f2f61a9a90f6695b10ed04102dca3e0aa50a10263afd861761226e3e61903a6","s":"0x2fb42a9e8d96af626e64fd20573338f41d4f90ea9834ce6aa4ff798691816997","to":"0x3fa177c2e87cb24148ec403921db577d140cc07c","chainId":"0x13881","accessList":[],"hash":"0xfacf81ceb293b34292ea428c64a4a550fd5702432908a952aa9d1db455c22c72"}` //nolint
signedRaw := `{"type":"0x2","nonce":"0x0","gasPrice":null,"maxPriorityFeePerGas":"0x59682f00","maxFeePerGas":"0xe51af8700","gas":"0x5208","value":"0x3e8","input":"0x","v":"0x0","r":"0x9f2f61a9a90f6695b10ed04102dca3e0aa50a10263afd861761226e3e61903a6","s":"0x2fb42a9e8d96af626e64fd20573338f41d4f90ea9834ce6aa4ff798691816997","to":"0x3fa177c2e87cb24148ec403921db577d140cc07c","chainId":"0x13881","accessList":[],"hash":"0xa7c55d7deafc3a717c36162b1dad13b7738ff5898dce3c946dd879e2e73ce840"}` //nolint
combineResponse, err := servicer.ConstructionCombine(ctx, &types.ConstructionCombineRequest{
NetworkIdentifier: networkIdentifier,
UnsignedTransaction: unsignedRaw,
Signatures: signatures,
})

fmt.Printf("resulting payload: %v\n", combineResponse.SignedTransaction)

assert.Nil(t, err)
assert.Equal(t, &types.ConstructionCombineResponse{
SignedTransaction: signedRaw,
Expand Down
25 changes: 12 additions & 13 deletions services/construction/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,25 +117,23 @@ func (a *APIService) ConstructionMetadata(
return nil, svcErrors.WrapErr(svcErrors.ErrGeth, err)
}

// Initially set baseFee to 30 gwei, the minimum gas price that the node will accept on mainnet.
// See https://forum.polygon.technology/t/recommended-min-gas-price-setting/7604 for additional context.
baseFee := big.NewInt(30000000000)

// get the maximum of header.BaseFee and 30 gwei
if header.BaseFee.Cmp(baseFee) == 1 {
baseFee = header.BaseFee
}

var gasCap *big.Int
if input.GasCap == nil {
// Set default max fee to double the last base fee plus priority tip
// to ensure tx is highly likely to go out in the next block
// to ensure tx is highly likely to go out in the next block.
multiplier := big.NewInt(2)
gasCap = new(big.Int).Add(gasTip, new(big.Int).Mul(baseFee, multiplier))
gasCap = new(big.Int).Add(gasTip, new(big.Int).Mul(header.BaseFee, multiplier))
} else {
gasCap = input.GasCap
}

// Ensure the gas cap is at least 30 gwei, the minimum gas price that the node will accept on mainnet.
// See https://forum.polygon.technology/t/recommended-min-gas-price-setting/7604 for additional context.
minFee := big.NewInt(30000000000) // 30 gwei
if minFee.Cmp(gasCap) == 1 {
gasCap = minFee
}

metadata := &metadata{
Nonce: nonce,
GasLimit: gasLimit,
Expand All @@ -153,8 +151,9 @@ func (a *APIService) ConstructionMetadata(
return nil, svcErrors.WrapErr(svcErrors.ErrUnableToParseIntermediateResult, err)
}

// Find suggested gas usage
suggestedFee := (baseFee.Int64() + metadata.GasTip.Int64()) * int64(gasLimit)
// Find suggested gas usage. Note that this figure accounts for the minimum (30 gwei), and
// is potentially doubled the block base fee.
suggestedFee := gasCap.Int64() * int64(gasLimit)

return &types.ConstructionMetadataResponse{
Metadata: metadataMap,
Expand Down
54 changes: 44 additions & 10 deletions services/construction/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,12 @@ func TestMetadata(t *testing.T) {
"value": transferValueHex,
"nonce": transferNonceHex2,
"gas_limit": transferGasLimitHex,
"gas_cap": transferGasCapHex,
"gas_cap": transferGasCapWithTipHex,
"gas_tip": transferGasTipHex,
},
SuggestedFee: []*types.Amount{
{
Value: fmt.Sprintf("%d", (header.BaseFee.Uint64()+transferGasTip)*transferGasLimit),
Value: fmt.Sprintf("%d", transferGasCapWithTip*transferGasLimit),
Currency: polygon.Currency,
},
},
Expand Down Expand Up @@ -123,17 +123,51 @@ func TestMetadata(t *testing.T) {
"value": transferValueHex,
"nonce": transferNonceHex,
"gas_limit": transferGasLimitHex,
"gas_cap": transferGasCapHex,
"gas_cap": transferGasCapWithTipHex,
"gas_tip": transferGasTipHex,
},
SuggestedFee: []*types.Amount{
{
Value: fmt.Sprintf("%d", (header.BaseFee.Uint64()+transferGasTip)*transferGasLimit),
Value: fmt.Sprintf("%d", transferGasCapWithTip*transferGasLimit),
Currency: polygon.Currency,
},
},
},
},
"happy path: native currency with gas tip set to 30 gwei floor": {
options: map[string]interface{}{
"from": metadataFrom,
"to": metadataTo,
"value": transferValueHex,
"nonce": transferNonceHex2,
},
expectedResponse: &types.ConstructionMetadataResponse{
Metadata: map[string]interface{}{
"to": metadataTo,
"value": transferValueHex,
"nonce": transferNonceHex2,
"gas_limit": transferGasLimitHex,
"gas_cap": minGasCapHex,
"gas_tip": transferGasTipHex,
},
SuggestedFee: []*types.Amount{
{
Value: fmt.Sprintf("%d", (minGasCap.Uint64())*transferGasLimit),
Currency: polygon.Currency,
},
},
},
mocks: func(ctx context.Context, client *mocks.Client) {
var blockNum *big.Int = nil

client.On("BlockHeader", ctx, blockNum).
Return(&headerWithLowBaseFee, nil)

client.On("SuggestGasTipCap", ctx).
Return(big.NewInt(int64(transferGasTip)), nil)

},
},
"happy path: ERC20 currency with nonce": {
options: map[string]interface{}{
"from": metadataFrom,
Expand Down Expand Up @@ -168,13 +202,13 @@ func TestMetadata(t *testing.T) {
"value": "0x0",
"nonce": transferNonceHex2,
"gas_limit": transferGasLimitERC20Hex,
"gas_cap": transferGasCapHex,
"gas_cap": transferGasCapWithTipHex,
"gas_tip": transferGasTipHex,
"data": metadataData,
},
SuggestedFee: []*types.Amount{
{
Value: fmt.Sprintf("%d", (header.BaseFee.Uint64()+transferGasTip)*transferGasLimitERC20),
Value: fmt.Sprintf("%d", transferGasCapWithTip*transferGasLimitERC20),
Currency: polygon.Currency,
},
},
Expand Down Expand Up @@ -216,15 +250,15 @@ func TestMetadata(t *testing.T) {
"value": "0x0",
"nonce": transferNonceHex2,
"gas_limit": transferGasLimitERC20Hex,
"gas_cap": transferGasCapHex,
"gas_cap": transferGasCapWithTipHex,
"gas_tip": transferGasTipHex,
"data": metadataGenericData,
"method_signature": "approve(address,uint256)",
"method_args": []interface{}{"0xD10a72Cf054650931365Cc44D912a4FD75257058", "1000"},
},
SuggestedFee: []*types.Amount{
{
Value: fmt.Sprintf("%d", (header.BaseFee.Uint64()+transferGasTip)*transferGasLimitERC20),
Value: fmt.Sprintf("%d", transferGasCapWithTip*transferGasLimitERC20),
Currency: polygon.Currency,
},
},
Expand Down Expand Up @@ -266,15 +300,15 @@ func TestMetadata(t *testing.T) {
"value": "0x5f5e100",
"nonce": transferNonceHex2,
"gas_limit": transferGasLimitERC20Hex,
"gas_cap": transferGasCapHex,
"gas_cap": transferGasCapWithTipHex,
"gas_tip": transferGasTipHex,
"data": metadataMaticWithdrawData,
"method_signature": "withdraw(uint256)",
"method_args": []interface{}{"100000000"},
},
SuggestedFee: []*types.Amount{
{
Value: fmt.Sprintf("%d", (header.BaseFee.Uint64()+transferGasTip)*transferGasLimitERC20),
Value: fmt.Sprintf("%d", transferGasCapWithTip*transferGasLimitERC20),
Currency: polygon.Currency,
},
},
Expand Down

0 comments on commit c123dfe

Please sign in to comment.