diff --git a/promises/clearing.go b/promises/clearing.go index f7eb6cc..cb2b234 100644 --- a/promises/clearing.go +++ b/promises/clearing.go @@ -69,7 +69,7 @@ func (pc *PromiseClearing) ClearReceivedPromise(promise *ReceivedPromise) error copy(packedAddressAndSigns[10:32], addressAndSigns) var extraDataHash [32]byte - copy(extraDataHash[:], promise.ConsumerHash()) + copy(extraDataHash[:], promise.Extra.Hash()) _, err = pc.ClearPromise( packedAddressAndSigns, diff --git a/promises/clearing_test.go b/promises/clearing_test.go index 004d308..cd0e60a 100644 --- a/promises/clearing_test.go +++ b/promises/clearing_test.go @@ -55,6 +55,7 @@ func TestPromiseClearingEmitsClearedEvent(t *testing.T) { backend.Commit() promise := Promise{ + Extra: EmptyExtra{}, Receiver: receiver.Address, SeqNo: 1, Amount: 100, diff --git a/promises/promise.go b/promises/promise.go index 214112d..f042b0d 100644 --- a/promises/promise.go +++ b/promises/promise.go @@ -9,23 +9,33 @@ import ( "github.com/mysteriumnetwork/payments/identity" ) -type Promise struct { - ServiceConsumer common.Address - Receiver common.Address - SeqNo int64 - Amount int64 +type ExtraData interface { + Hash() []byte } -const issuerPrefix = "Issuer prefix:" +const emptyExtra = "emptyextra" + +type EmptyExtra struct { +} + +func (EmptyExtra) Hash() []byte { + return crypto.Keccak256([]byte(emptyExtra)) +} -func (p *Promise) ConsumerHash() []byte { - return crypto.Keccak256(p.ServiceConsumer.Bytes()) +var _ ExtraData = EmptyExtra{} + +type Promise struct { + Extra ExtraData + Receiver common.Address + SeqNo int64 + Amount int64 } +const issuerPrefix = "Issuer prefix:" + func (p *Promise) Bytes() []byte { slices := [][]byte{ - []byte(issuerPrefix), - p.ConsumerHash(), + p.Extra.Hash(), p.Receiver.Bytes(), abi.U256(big.NewInt(p.SeqNo)), abi.U256(big.NewInt(p.Amount)), @@ -42,13 +52,29 @@ type IssuedPromise struct { IssuerSignature []byte } +func (ip *IssuedPromise) Bytes() []byte { + return append([]byte(issuerPrefix), ip.Promise.Bytes()...) +} + +func (ip *IssuedPromise) IssuerAddress() (common.Address, error) { + publicKey, err := crypto.Ecrecover(crypto.Keccak256(ip.Bytes()), ip.IssuerSignature) + if err != nil { + return common.Address{}, err + } + pubKey, err := crypto.UnmarshalPubkey(publicKey) + if err != nil { + return common.Address{}, err + } + return crypto.PubkeyToAddress(*pubKey), nil +} + type ReceivedPromise struct { IssuedPromise ReceiverSignature []byte } func SignByPayer(promise *Promise, payer identity.Signer) (*IssuedPromise, error) { - signature, err := payer.Sign(promise.Bytes()) + signature, err := payer.Sign([]byte(issuerPrefix), promise.Bytes()) if err != nil { return nil, err } @@ -62,15 +88,10 @@ func SignByPayer(promise *Promise, payer identity.Signer) (*IssuedPromise, error const receiverPrefix = "Receiver prefix:" func SignByReceiver(promise *IssuedPromise, receiver identity.Signer) (*ReceivedPromise, error) { - publicKey, err := crypto.Ecrecover(crypto.Keccak256(promise.Bytes()), promise.IssuerSignature) - if err != nil { - return nil, err - } - pubKey, err := crypto.UnmarshalPubkey(publicKey) + payerAddr, err := promise.IssuerAddress() if err != nil { return nil, err } - payerAddr := crypto.PubkeyToAddress(*pubKey) sig, err := receiver.Sign([]byte(receiverPrefix), crypto.Keccak256(promise.Bytes()), payerAddr.Bytes()) return &ReceivedPromise{ *promise,