Commit fe6a5919 authored by Ralph Pichler's avatar Ralph Pichler Committed by GitHub

feat: allow transaction from another sender for identity tx (#2409)

parent c2c76ced
...@@ -94,16 +94,25 @@ func (m *Matcher) Matches(ctx context.Context, tx []byte, networkID uint64, send ...@@ -94,16 +94,25 @@ func (m *Matcher) Matches(ctx context.Context, tx []byte, networkID uint64, send
return nil, ErrTransactionPending return nil, ErrTransactionPending
} }
sender, err := types.Sender(m.signer, nTx) // if transaction data is exactly one word and starts with 4 0-bytes this is a transaction data type proof
if err != nil { // we check for the starting 0-bytes so we don't mistake a 28 byte data solidity call for this
err2 := m.storage.Put(peerOverlayKey(senderOverlay, incomingTx), &overlayVerification{ // otherwise this is considered as a signer based proof. a transaction can be only one of the two.
TimeStamp: m.timeNow(), var attestedOverlay common.Address
Verified: false, txData := nTx.Data()
}) if len(txData) == 32 && bytes.Equal(txData[0:4], []byte{0, 0, 0, 0}) {
if err2 != nil { attestedOverlay = common.BytesToAddress(nTx.Data())
return nil, err2 } else {
attestedOverlay, err = types.Sender(m.signer, nTx)
if err != nil {
err2 := m.storage.Put(peerOverlayKey(senderOverlay, incomingTx), &overlayVerification{
TimeStamp: m.timeNow(),
Verified: false,
})
if err2 != nil {
return nil, err2
}
return nil, fmt.Errorf("%v: %w", err, ErrTransactionSenderInvalid)
} }
return nil, fmt.Errorf("%v: %w", err, ErrTransactionSenderInvalid)
} }
receipt, err := m.backend.TransactionReceipt(ctx, incomingTx) receipt, err := m.backend.TransactionReceipt(ctx, incomingTx)
...@@ -145,7 +154,7 @@ func (m *Matcher) Matches(ctx context.Context, tx []byte, networkID uint64, send ...@@ -145,7 +154,7 @@ func (m *Matcher) Matches(ctx context.Context, tx []byte, networkID uint64, send
return nil, fmt.Errorf("receipt hash %x does not match block's parent hash %x: %w", receiptBlockHash, nextBlockParentHash, ErrBlockHashMismatch) return nil, fmt.Errorf("receipt hash %x does not match block's parent hash %x: %w", receiptBlockHash, nextBlockParentHash, ErrBlockHashMismatch)
} }
expectedRemoteBzzAddress := crypto.NewOverlayFromEthereumAddress(sender.Bytes(), networkID, nextBlockHash) expectedRemoteBzzAddress := crypto.NewOverlayFromEthereumAddress(attestedOverlay.Bytes(), networkID, nextBlockHash)
if !expectedRemoteBzzAddress.Equal(senderOverlay) { if !expectedRemoteBzzAddress.Equal(senderOverlay) {
err2 := m.storage.Put(peerOverlayKey(senderOverlay, incomingTx), &overlayVerification{ err2 := m.storage.Put(peerOverlayKey(senderOverlay, incomingTx), &overlayVerification{
......
...@@ -109,7 +109,7 @@ func TestMatchesSender(t *testing.T) { ...@@ -109,7 +109,7 @@ func TestMatchesSender(t *testing.T) {
} }
}) })
t.Run("sender matches", func(t *testing.T) { t.Run("sender matches signer type", func(t *testing.T) {
trxBlock := common.HexToHash("0x2") trxBlock := common.HexToHash("0x2")
nextBlockHeader := &types.Header{ nextBlockHeader := &types.Header{
...@@ -145,6 +145,52 @@ func TestMatchesSender(t *testing.T) { ...@@ -145,6 +145,52 @@ func TestMatchesSender(t *testing.T) {
} }
}) })
t.Run("sender matches data type", func(t *testing.T) {
trxBlock := common.HexToHash("0x2")
nextBlockHeader := &types.Header{
ParentHash: trxBlock,
}
overlayEth := common.HexToAddress("0xff")
signedTx := types.NewTransaction(nonce, recipient, value, estimatedGasLimit, suggestedGasPrice, overlayEth.Hash().Bytes())
trxReceipt := backendmock.WithTransactionReceiptFunc(func(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
return &types.Receipt{
BlockNumber: big.NewInt(0),
BlockHash: trxBlock,
}, nil
})
headerByNum := backendmock.WithHeaderbyNumberFunc(func(ctx context.Context, number *big.Int) (*types.Header, error) {
return nextBlockHeader, nil
})
txByHash := backendmock.WithTransactionByHashFunc(func(ctx context.Context, txHash common.Hash) (*types.Transaction, bool, error) {
return signedTx, false, nil
})
signer := &mockSigner{
addr: common.HexToAddress("0xee"),
}
matcher := transaction.NewMatcher(backendmock.New(trxReceipt, headerByNum, txByHash), signer, statestore.NewStateStore())
senderOverlay := crypto.NewOverlayFromEthereumAddress(overlayEth.Bytes(), 0, nextBlockHeader.Hash().Bytes())
_, err := matcher.Matches(context.Background(), trx, 0, senderOverlay)
if err != nil {
t.Fatalf("expected match. got %v", err)
}
senderOverlay = crypto.NewOverlayFromEthereumAddress(signer.addr.Bytes(), 0, nextBlockHeader.Hash().Bytes())
_, err = matcher.Matches(context.Background(), trx, 0, senderOverlay)
if err == nil {
t.Fatalf("matched signer for data tx")
}
})
t.Run("cached", func(t *testing.T) { t.Run("cached", func(t *testing.T) {
trxBlock := common.HexToHash("0x2") trxBlock := common.HexToHash("0x2")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment