From a872dd10c23f3beac2dd76aa49fc69d598b559a7 Mon Sep 17 00:00:00 2001 From: Peter Fox Date: Thu, 21 Feb 2019 14:57:43 +0000 Subject: [PATCH 1/2] Compare intrinsic gas of public transaction versus the private version that contains the PTM hash instead. If there is a difference, add it on to the execution cost. --- internal/ethapi/api.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 7f56c3eee..4800a588c 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -55,6 +55,9 @@ import ( const ( defaultGasPrice = 50 * params.Shannon + + //Hex-encoded 64 byte array of "17" values + maxPrivateIntrinsicDataHex = "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" ) // PublicEthereumAPI provides an API to access Ethereum related information. @@ -771,6 +774,37 @@ func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (h return 0, fmt.Errorf("gas required exceeds allowance or always failing transaction") } } + + //QUORUM + + //We don't know if this is going to be a private or public transaction + //It is possible to have a data field that has a lower intrinsic value than the PTM hash + //so this checks that if we were to place a PTM hash (with all non-zero values) here then the transaction would + //still run + //This makes the return value a potential over-estimate of gas, rather than the exact cost to run right now + + //There is still one edge case: if the transaction has a low intrinsic gas cost, but a high execution cost, then + //it the addition of the extra gas needed to make it private may push it over the maximum gas allowed, but this + //wouldn't matter since we weren't planning to make it private + + //if the transaction has a value then it cannot be private, so we can skip this check + if args.Value.ToInt().Cmp(big.NewInt(0)) == 0 { + + isHomestead := s.b.ChainConfig().IsHomestead(new(big.Int).SetInt64(int64(rpc.PendingBlockNumber))) + intrinsicGasPublic, _ := core.IntrinsicGas(args.Data, args.To == nil, isHomestead) + intrinsicGasPrivate, _ := core.IntrinsicGas(common.Hex2Bytes(maxPrivateIntrinsicDataHex), args.To == nil, isHomestead) + + if intrinsicGasPrivate > intrinsicGasPublic { + if math.MaxUint64 - hi < intrinsicGasPrivate - intrinsicGasPublic { + return 0, fmt.Errorf("gas required exceeds allowance or always failing transaction") + } + return hexutil.Uint64(hi + (intrinsicGasPrivate - intrinsicGasPublic)), nil + } + + } + + //END QUORUM + return hexutil.Uint64(hi), nil } From e1e5fa0e8f25816e46b5b2813950b2425e59915a Mon Sep 17 00:00:00 2001 From: Peter Fox Date: Thu, 21 Feb 2019 17:00:28 +0000 Subject: [PATCH 2/2] Require the addition of the extra intrinsic gas cost to remain under the user input gas limit. --- internal/ethapi/api.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 4800a588c..cd68df138 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -783,10 +783,6 @@ func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (h //still run //This makes the return value a potential over-estimate of gas, rather than the exact cost to run right now - //There is still one edge case: if the transaction has a low intrinsic gas cost, but a high execution cost, then - //it the addition of the extra gas needed to make it private may push it over the maximum gas allowed, but this - //wouldn't matter since we weren't planning to make it private - //if the transaction has a value then it cannot be private, so we can skip this check if args.Value.ToInt().Cmp(big.NewInt(0)) == 0 { @@ -796,7 +792,7 @@ func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (h if intrinsicGasPrivate > intrinsicGasPublic { if math.MaxUint64 - hi < intrinsicGasPrivate - intrinsicGasPublic { - return 0, fmt.Errorf("gas required exceeds allowance or always failing transaction") + return 0, fmt.Errorf("private intrinsic gas addition exceeds allowance") } return hexutil.Uint64(hi + (intrinsicGasPrivate - intrinsicGasPublic)), nil }