Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validate ChainId on non-legacy transactions #3061

Merged
merged 1 commit into from
May 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -176,5 +176,27 @@ public bool Before_eip_1559_has_to_be_legacy_or_access_list_tx(TxType txType, bo
IReleaseSpec releaseSpec = new ReleaseSpec() {IsEip2930Enabled = eip2930, IsEip1559Enabled = eip1559};
return txValidator.IsWellFormed(tx, releaseSpec);
}


[TestCase(TxType.Legacy, ExpectedResult = true)]
[TestCase(TxType.AccessList, ExpectedResult = false)]
[TestCase(TxType.EIP1559, ExpectedResult = false)]
public bool Chain_Id_required_for_non_legacy_transactions_after_Berlin(TxType txType)
{
byte[] sigData = new byte[65];
sigData[31] = 1; // correct r
sigData[63] = 1; // correct s
sigData[64] = 38;
Signature signature = new Signature(sigData);
Transaction tx = Build.A.Transaction
.WithType(txType > TxType.AccessList ? TxType.Legacy : txType)
.WithAccessList(txType == TxType.AccessList ? new AccessList(new Dictionary<Address, IReadOnlySet<UInt256>>()) : null)
.WithSignature(signature).TestObject;

tx.Type = txType;

TxValidator txValidator = new TxValidator(ChainId.Mainnet);
return txValidator.IsWellFormed(tx, Berlin.Instance);
}
}
}
34 changes: 29 additions & 5 deletions src/Nethermind/Nethermind.Blockchain/Validators/TxValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the Nethermind. If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Numerics;
using Nethermind.Core;
using Nethermind.Core.Crypto;
Expand Down Expand Up @@ -49,16 +50,39 @@ public bool IsWellFormed(Transaction transaction, IReleaseSpec releaseSpec)
transaction.GasLimit >= IntrinsicGasCalculator.Calculate(transaction, releaseSpec) &&
/* if it is a call or a transfer then we require the 'To' field to have a value
while for an init it will be empty */
ValidateSignature(transaction.Signature, releaseSpec);
ValidateSignature(transaction.Signature, releaseSpec) &&
ValidateChainId(transaction);
}

private bool ValidateTxType(Transaction transaction, IReleaseSpec releaseSpec)
{
return transaction.Type == TxType.Legacy ||
(transaction.Type == TxType.AccessList && releaseSpec.UseTxAccessLists) ||
(transaction.Type == TxType.EIP1559 && releaseSpec.IsEip1559Enabled);
switch (transaction.Type)
{
case TxType.Legacy:
return true;
case TxType.AccessList:
return releaseSpec.UseTxAccessLists;
case TxType.EIP1559:
return releaseSpec.IsEip1559Enabled;
default:
return false;
}
}


private bool ValidateChainId(Transaction transaction)
{
switch (transaction.Type)
{
case TxType.Legacy:
return true;
case TxType.AccessList:
case TxType.EIP1559:
return transaction.ChainId == _chainIdValue;
default:
return false;
}
}

private bool ValidateSignature(Signature signature, IReleaseSpec spec)
{
BigInteger sValue = signature.SAsSpan.ToUnsignedBigInteger();
Expand Down