Skip to content

Commit

Permalink
Merge pull request #165 from vsbogd/use-signer-to-check-signature
Browse files Browse the repository at this point in the history
Use signer to check signature
  • Loading branch information
stellarspot authored Dec 4, 2018
2 parents c22b445 + 506fbb8 commit 038f929
Show file tree
Hide file tree
Showing 10 changed files with 57 additions and 32 deletions.
2 changes: 2 additions & 0 deletions blockchain/escrow.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ type MultiPartyEscrowChannel struct {
Value *big.Int
Nonce *big.Int
Expiration *big.Int
Signer common.Address
}

var zeroAddress = common.Address{}
Expand All @@ -102,6 +103,7 @@ func (processor *Processor) MultiPartyEscrowChannel(channelID *big.Int) (channel
Value: ch.Value,
Nonce: ch.Nonce,
Expiration: ch.Expiration,
Signer: ch.Signer,
}

log = log.WithField("channel", channel)
Expand Down
1 change: 1 addition & 0 deletions escrow/escrow.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ func (payment *paymentTransaction) Commit() error {
Recipient: payment.channel.Recipient,
FullAmount: payment.channel.FullAmount,
Expiration: payment.channel.Expiration,
Signer: payment.channel.Signer,
AuthorizedAmount: payment.payment.Amount,
Signature: payment.payment.Signature,
GroupID: payment.channel.GroupID,
Expand Down
24 changes: 14 additions & 10 deletions escrow/escrow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,9 @@ func (transaction *paymentTransactionMock) Rollback() error {
type PaymentChannelServiceSuite struct {
suite.Suite

senderPrivateKey *ecdsa.PrivateKey
senderAddress common.Address
signerPrivateKey *ecdsa.PrivateKey
signerAddress common.Address
recipientAddress common.Address
mpeContractAddress common.Address
memoryStorage *memoryStorage
Expand All @@ -90,8 +91,9 @@ type PaymentChannelServiceSuite struct {
}

func (suite *PaymentChannelServiceSuite) SetupSuite() {
suite.senderPrivateKey = GenerateTestPrivateKey()
suite.senderAddress = crypto.PubkeyToAddress(suite.senderPrivateKey.PublicKey)
suite.senderAddress = crypto.PubkeyToAddress(GenerateTestPrivateKey().PublicKey)
suite.signerPrivateKey = GenerateTestPrivateKey()
suite.signerAddress = crypto.PubkeyToAddress(suite.signerPrivateKey.PublicKey)
suite.recipientAddress = crypto.PubkeyToAddress(GenerateTestPrivateKey().PublicKey)
suite.mpeContractAddress = blockchain.HexToAddress("0xf25186b5081ff5ce73482ad761db0eb0d25abfbf")
suite.memoryStorage = NewMemStorage()
Expand Down Expand Up @@ -141,6 +143,7 @@ func (suite *PaymentChannelServiceSuite) mpeChannel() *blockchain.MultiPartyEscr
Value: big.NewInt(12345),
Nonce: big.NewInt(3),
Expiration: big.NewInt(100),
Signer: suite.signerAddress,
}
}

Expand All @@ -151,7 +154,7 @@ func (suite *PaymentChannelServiceSuite) payment() *Payment {
ChannelNonce: big.NewInt(3),
//MpeContractAddress: suite.mpeContractAddress,
}
SignTestPayment(payment, suite.senderPrivateKey)
SignTestPayment(payment, suite.signerPrivateKey)
return payment
}

Expand All @@ -170,6 +173,7 @@ func (suite *PaymentChannelServiceSuite) channel() *PaymentChannelData {
GroupID: [32]byte{123},
FullAmount: big.NewInt(12345),
Expiration: big.NewInt(100),
Signer: suite.signerAddress,
AuthorizedAmount: big.NewInt(0),
Signature: nil,
}
Expand Down Expand Up @@ -199,10 +203,10 @@ func (suite *PaymentChannelServiceSuite) TestPaymentTransaction() {
func (suite *PaymentChannelServiceSuite) TestPaymentParallelTransaction() {
paymentA := suite.payment()
paymentA.Amount = big.NewInt(13)
SignTestPayment(paymentA, suite.senderPrivateKey)
SignTestPayment(paymentA, suite.signerPrivateKey)
paymentB := suite.payment()
paymentB.Amount = big.NewInt(17)
SignTestPayment(paymentB, suite.senderPrivateKey)
SignTestPayment(paymentB, suite.signerPrivateKey)

transactionA, errA := suite.service.StartPaymentTransaction(paymentA)
transactionB, errB := suite.service.StartPaymentTransaction(paymentB)
Expand All @@ -221,10 +225,10 @@ func (suite *PaymentChannelServiceSuite) TestPaymentParallelTransaction() {
func (suite *PaymentChannelServiceSuite) TestPaymentSequentialTransaction() {
paymentA := suite.payment()
paymentA.Amount = big.NewInt(13)
SignTestPayment(paymentA, suite.senderPrivateKey)
SignTestPayment(paymentA, suite.signerPrivateKey)
paymentB := suite.payment()
paymentB.Amount = big.NewInt(17)
SignTestPayment(paymentB, suite.senderPrivateKey)
SignTestPayment(paymentB, suite.signerPrivateKey)

transactionA, errA := suite.service.StartPaymentTransaction(paymentA)
errAC := transactionA.Commit()
Expand All @@ -244,10 +248,10 @@ func (suite *PaymentChannelServiceSuite) TestPaymentSequentialTransaction() {
func (suite *PaymentChannelServiceSuite) TestPaymentSequentialTransactionAfterRollback() {
paymentA := suite.payment()
paymentA.Amount = big.NewInt(13)
SignTestPayment(paymentA, suite.senderPrivateKey)
SignTestPayment(paymentA, suite.signerPrivateKey)
paymentB := suite.payment()
paymentB.Amount = big.NewInt(13)
SignTestPayment(paymentB, suite.senderPrivateKey)
SignTestPayment(paymentB, suite.signerPrivateKey)

transactionA, errA := suite.service.StartPaymentTransaction(paymentA)
errAC := transactionA.Rollback()
Expand Down
7 changes: 5 additions & 2 deletions escrow/payment_channel_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ type PaymentChannelData struct {
// expressed in Ethereum block number. Since this block is added to
// blockchain Sender can withdraw tokens from channel.
Expiration *big.Int
// Signer is and address to be used to sign the payments. Usually it is
// equal to channel sender.
Signer common.Address

// service provider. This amount increments on price after each successful
// RPC call.
Expand All @@ -96,8 +99,8 @@ type PaymentChannelData struct {
}

func (data *PaymentChannelData) String() string {
return fmt.Sprintf("{ChannelID: %v, Nonce: %v, State: %v, Sender: %v, Recipient: %v, GroupId: %v, FullAmount: %v, Expiration: %v, AuthorizedAmount: %v, Signature: %v",
data.ChannelID, data.Nonce, data.State, blockchain.AddressToHex(&data.Sender), blockchain.AddressToHex(&data.Recipient), data.GroupID, data.FullAmount, data.Expiration, data.AuthorizedAmount, blockchain.BytesToBase64(data.Signature))
return fmt.Sprintf("{ChannelID: %v, Nonce: %v, State: %v, Sender: %v, Recipient: %v, GroupId: %v, FullAmount: %v, Expiration: %v, Signer: %v, AuthorizedAmount: %v, Signature: %v",
data.ChannelID, data.Nonce, data.State, blockchain.AddressToHex(&data.Sender), blockchain.AddressToHex(&data.Recipient), data.GroupID, data.FullAmount, data.Expiration, data.Signer, data.AuthorizedAmount, blockchain.BytesToBase64(data.Signature))
}

// PaymentChannelService interface is API for payment channel functionality.
Expand Down
1 change: 1 addition & 0 deletions escrow/payment_channel_storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ func (reader *BlockchainChannelReader) GetChannelStateFromBlockchain(key *Paymen
GroupID: ch.GroupId,
FullAmount: ch.Value,
Expiration: ch.Expiration,
Signer: ch.Signer,
AuthorizedAmount: big.NewInt(0),
Signature: nil,
}, true, nil
Expand Down
7 changes: 7 additions & 0 deletions escrow/payment_channel_storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type PaymentChannelStorageSuite struct {
suite.Suite

senderAddress common.Address
signerAddress common.Address
recipientAddress common.Address
memoryStorage *memoryStorage

Expand All @@ -34,6 +35,7 @@ type PaymentChannelStorageSuite struct {

func (suite *PaymentChannelStorageSuite) SetupSuite() {
suite.senderAddress = crypto.PubkeyToAddress(GenerateTestPrivateKey().PublicKey)
suite.signerAddress = crypto.PubkeyToAddress(GenerateTestPrivateKey().PublicKey)
suite.recipientAddress = crypto.PubkeyToAddress(GenerateTestPrivateKey().PublicKey)
suite.memoryStorage = NewMemStorage()

Expand Down Expand Up @@ -61,6 +63,7 @@ func (suite *PaymentChannelStorageSuite) channel() *PaymentChannelData {
GroupID: [32]byte{123},
FullAmount: big.NewInt(12345),
Expiration: big.NewInt(100),
Signer: suite.signerAddress,
AuthorizedAmount: big.NewInt(0),
Signature: nil,
}
Expand All @@ -83,12 +86,14 @@ type BlockchainChannelReaderSuite struct {

senderAddress common.Address
recipientAddress common.Address
signerAddress common.Address

reader BlockchainChannelReader
}

func (suite *BlockchainChannelReaderSuite) SetupSuite() {
suite.senderAddress = crypto.PubkeyToAddress(GenerateTestPrivateKey().PublicKey)
suite.signerAddress = crypto.PubkeyToAddress(GenerateTestPrivateKey().PublicKey)
suite.recipientAddress = crypto.PubkeyToAddress(GenerateTestPrivateKey().PublicKey)

suite.reader = BlockchainChannelReader{
Expand All @@ -115,6 +120,7 @@ func (suite *BlockchainChannelReaderSuite) mpeChannel() *blockchain.MultiPartyEs
Value: big.NewInt(12345),
Nonce: big.NewInt(3),
Expiration: big.NewInt(100),
Signer: suite.signerAddress,
}
}

Expand All @@ -127,6 +133,7 @@ func (suite *BlockchainChannelReaderSuite) channel() *PaymentChannelData {
GroupID: [32]byte{123},
FullAmount: big.NewInt(12345),
Expiration: big.NewInt(100),
Signer: suite.signerAddress,
AuthorizedAmount: big.NewInt(0),
Signature: nil,
}
Expand Down
4 changes: 2 additions & 2 deletions escrow/state_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ func (service *PaymentChannelStateService) GetChannelState(context context.Conte
return nil, fmt.Errorf("channel is not found, channelId: %v", channelID)
}

if channel.Sender != *sender {
return nil, errors.New("only channel sender can get latest channel state")
if channel.Signer != *sender {
return nil, errors.New("only channel signer can get latest channel state")
}

if channel.Signature == nil {
Expand Down
20 changes: 12 additions & 8 deletions escrow/state_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import (

type stateServiceTestType struct {
service PaymentChannelStateService
senderPrivateKey *ecdsa.PrivateKey
senderAddress common.Address
signerPrivateKey *ecdsa.PrivateKey
signerAddress common.Address
channelServiceMock *paymentChannelServiceMock

defaultChannelId *big.Int
Expand All @@ -26,8 +27,9 @@ type stateServiceTestType struct {

var stateServiceTest = func() stateServiceTestType {
channelServiceMock := &paymentChannelServiceMock{}
senderPrivateKey := GenerateTestPrivateKey()
senderAddress := crypto.PubkeyToAddress(senderPrivateKey.PublicKey)
senderAddress := crypto.PubkeyToAddress(GenerateTestPrivateKey().PublicKey)
signerPrivateKey := GenerateTestPrivateKey()
signerAddress := crypto.PubkeyToAddress(signerPrivateKey.PublicKey)

defaultChannelId := big.NewInt(42)
defaultSignature, err := hex.DecodeString("0504030201")
Expand All @@ -39,22 +41,24 @@ var stateServiceTest = func() stateServiceTestType {
service: PaymentChannelStateService{
channelService: channelServiceMock,
},
senderPrivateKey: senderPrivateKey,
senderAddress: senderAddress,
signerPrivateKey: signerPrivateKey,
signerAddress: signerAddress,
channelServiceMock: channelServiceMock,

defaultChannelId: defaultChannelId,
defaultChannelKey: &PaymentChannelKey{ID: defaultChannelId},
defaultChannelData: &PaymentChannelData{
ChannelID: defaultChannelId,
Sender: senderAddress,
Signer: signerAddress,
Signature: defaultSignature,
Nonce: big.NewInt(3),
AuthorizedAmount: big.NewInt(12345),
},
defaultRequest: &ChannelStateRequest{
ChannelId: bigIntToBytes(defaultChannelId),
Signature: getSignature(bigIntToBytes(defaultChannelId), senderPrivateKey),
Signature: getSignature(bigIntToBytes(defaultChannelId), signerPrivateKey),
},
defaultReply: &ChannelStateReply{
CurrentNonce: bigIntToBytes(big.NewInt(3)),
Expand Down Expand Up @@ -89,7 +93,7 @@ func TestGetChannelStateChannelIdIsNotPaddedByZero(t *testing.T) {
nil,
&ChannelStateRequest{
ChannelId: []byte{0xFF},
Signature: getSignature(bigIntToBytes(channelId), stateServiceTest.senderPrivateKey),
Signature: getSignature(bigIntToBytes(channelId), stateServiceTest.signerPrivateKey),
},
)

Expand Down Expand Up @@ -128,7 +132,7 @@ func TestGetChannelStateChannelNotFound(t *testing.T) {
nil,
&ChannelStateRequest{
ChannelId: bigIntToBytes(channelId),
Signature: getSignature(bigIntToBytes(channelId), stateServiceTest.senderPrivateKey),
Signature: getSignature(bigIntToBytes(channelId), stateServiceTest.signerPrivateKey),
},
)

Expand All @@ -153,7 +157,7 @@ func TestGetChannelStateIncorrectSender(t *testing.T) {
},
)

assert.Equal(t, errors.New("only channel sender can get latest channel state"), err)
assert.Equal(t, errors.New("only channel signer can get latest channel state"), err)
assert.Nil(t, reply)
}

Expand Down
6 changes: 3 additions & 3 deletions escrow/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ func (validator *ChannelPaymentValidator) Validate(payment *Payment, channel *Pa
}

log = log.WithField("signerAddress", blockchain.AddressToHex(signerAddress))
if *signerAddress != channel.Sender {
log.WithField("signerAddress", blockchain.AddressToHex(signerAddress)).Warn("Channel sender is not equal to payment signer")
return NewPaymentError(Unauthenticated, "payment is not signed by channel sender")
if *signerAddress != channel.Signer {
log.WithField("signerAddress", blockchain.AddressToHex(signerAddress)).Warn("Channel signer is not equal to payment signer")
return NewPaymentError(Unauthenticated, "payment is not signed by channel signer")
}
currentBlock, e := validator.currentBlock()
if e != nil {
Expand Down
17 changes: 10 additions & 7 deletions escrow/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ func GenerateTestPrivateKey() (privateKey *ecdsa.PrivateKey) {
type ValidationTestSuite struct {
suite.Suite

senderPrivateKey *ecdsa.PrivateKey
senderAddress common.Address
signerPrivateKey *ecdsa.PrivateKey
signerAddress common.Address
recipientAddress common.Address
mpeContractAddress common.Address

Expand All @@ -72,8 +73,9 @@ func TestValidationTestSuite(t *testing.T) {
}

func (suite *ValidationTestSuite) SetupSuite() {
suite.senderPrivateKey = GenerateTestPrivateKey()
suite.senderAddress = crypto.PubkeyToAddress(suite.senderPrivateKey.PublicKey)
suite.senderAddress = crypto.PubkeyToAddress(GenerateTestPrivateKey().PublicKey)
suite.signerPrivateKey = GenerateTestPrivateKey()
suite.signerAddress = crypto.PubkeyToAddress(suite.signerPrivateKey.PublicKey)
suite.recipientAddress = crypto.PubkeyToAddress(GenerateTestPrivateKey().PublicKey)
suite.mpeContractAddress = blockchain.HexToAddress("0xf25186b5081ff5ce73482ad761db0eb0d25abfbf")

Expand All @@ -90,7 +92,7 @@ func (suite *ValidationTestSuite) payment() *Payment {
ChannelNonce: big.NewInt(3),
MpeContractAddress: suite.mpeContractAddress,
}
SignTestPayment(payment, suite.senderPrivateKey)
SignTestPayment(payment, suite.signerPrivateKey)
return payment
}

Expand All @@ -103,6 +105,7 @@ func (suite *ValidationTestSuite) channel() *PaymentChannelData {
GroupID: [32]byte{123},
FullAmount: big.NewInt(12345),
Expiration: big.NewInt(100),
Signer: suite.signerAddress,
AuthorizedAmount: big.NewInt(12300),
Signature: nil,
}
Expand All @@ -120,7 +123,7 @@ func (suite *ValidationTestSuite) TestPaymentIsValid() {
func (suite *ValidationTestSuite) TestValidatePaymentChannelNonce() {
payment := suite.payment()
payment.ChannelNonce = big.NewInt(2)
SignTestPayment(payment, suite.senderPrivateKey)
SignTestPayment(payment, suite.signerPrivateKey)
channel := suite.channel()
channel.Nonce = big.NewInt(3)

Expand Down Expand Up @@ -153,7 +156,7 @@ func (suite *ValidationTestSuite) TestValidatePaymentIncorrectSigner() {

err := suite.validator.Validate(payment, suite.channel())

assert.Equal(suite.T(), NewPaymentError(Unauthenticated, "payment is not signed by channel sender"), err)
assert.Equal(suite.T(), NewPaymentError(Unauthenticated, "payment is not signed by channel signer"), err)
}

func (suite *ValidationTestSuite) TestValidatePaymentChannelCannotGetCurrentBlock() {
Expand Down Expand Up @@ -195,7 +198,7 @@ func (suite *ValidationTestSuite) TestValidatePaymentChannelExpirationThreshold(
func (suite *ValidationTestSuite) TestValidatePaymentAmountIsTooBig() {
payment := suite.payment()
payment.Amount = big.NewInt(12346)
SignTestPayment(payment, suite.senderPrivateKey)
SignTestPayment(payment, suite.signerPrivateKey)
channel := suite.channel()
channel.FullAmount = big.NewInt(12345)

Expand Down

0 comments on commit 038f929

Please sign in to comment.