package packet import ( "testing" "time" "git.quad4.io/Networks/Reticulum-Go/pkg/identity" ) func TestPacketReceiptCreation(t *testing.T) { testIdent, err := identity.NewIdentity() if err != nil { t.Fatalf("Failed to create identity: %v", err) } destHash := testIdent.Hash() data := []byte("test packet data") pkt := &Packet{ HeaderType: HeaderType1, PacketType: PacketTypeData, TransportType: 0, Context: ContextNone, ContextFlag: FlagUnset, Hops: 0, DestinationType: 0x00, DestinationHash: destHash, Data: data, CreateReceipt: true, } if err := pkt.Pack(); err != nil { t.Fatalf("Failed to pack packet: %v", err) } receipt := NewPacketReceipt(pkt) if receipt == nil { t.Fatal("Receipt creation failed") } if receipt.GetStatus() != RECEIPT_SENT { t.Errorf("Expected status SENT, got %d", receipt.GetStatus()) } hash := receipt.GetHash() if len(hash) == 0 { t.Error("Receipt hash is empty") } } func TestPacketReceiptTimeout(t *testing.T) { testIdent, err := identity.NewIdentity() if err != nil { t.Fatalf("Failed to create identity: %v", err) } destHash := testIdent.Hash() data := []byte("test data") pkt := &Packet{ HeaderType: HeaderType1, PacketType: PacketTypeData, TransportType: 0, Context: ContextNone, ContextFlag: FlagUnset, Hops: 0, DestinationType: 0x00, DestinationHash: destHash, Data: data, CreateReceipt: true, } if err := pkt.Pack(); err != nil { t.Fatalf("Failed to pack packet: %v", err) } receipt := NewPacketReceipt(pkt) receipt.SetTimeout(100 * time.Millisecond) time.Sleep(150 * time.Millisecond) if !receipt.IsTimedOut() { t.Error("Receipt should be timed out") } } func TestPacketReceiptProofValidation(t *testing.T) { testIdent, err := identity.NewIdentity() if err != nil { t.Fatalf("Failed to create identity: %v", err) } destHash := testIdent.Hash() data := []byte("test data") pkt := &Packet{ HeaderType: HeaderType1, PacketType: PacketTypeData, TransportType: 0, Context: ContextNone, ContextFlag: FlagUnset, Hops: 0, DestinationType: 0x00, DestinationHash: destHash, Data: data, CreateReceipt: true, } if err := pkt.Pack(); err != nil { t.Fatalf("Failed to pack packet: %v", err) } receipt := NewPacketReceipt(pkt) receipt.SetDestinationIdentity(testIdent) packetHash := pkt.GetHash() t.Logf("Packet hash: %x", packetHash) signature := testIdent.Sign(packetHash) t.Logf("PacketHash length: %d", len(packetHash)) t.Logf("Signature length: %d", len(signature)) t.Logf("EXPL_LENGTH constant: %d", EXPL_LENGTH) if testIdent.Verify(packetHash, signature) { t.Log("Direct verification succeeded") } else { t.Error("Direct verification failed") } proof := make([]byte, 0, EXPL_LENGTH) proof = append(proof, packetHash...) proof = append(proof, signature...) t.Logf("Proof length: %d", len(proof)) proofPacket := &Packet{ PacketType: PacketTypeProof, Data: proof, } if !receipt.ValidateProof(proof, proofPacket) { t.Errorf("Valid proof was rejected. Proof len=%d, expected=%d", len(proof), EXPL_LENGTH) } if receipt.GetStatus() != RECEIPT_DELIVERED { t.Errorf("Expected status DELIVERED, got %d", receipt.GetStatus()) } if !receipt.IsDelivered() { t.Error("Receipt should be marked as delivered") } } func TestPacketReceiptCallbacks(t *testing.T) { testIdent, err := identity.NewIdentity() if err != nil { t.Fatalf("Failed to create identity: %v", err) } destHash := testIdent.Hash() data := []byte("test data") pkt := &Packet{ HeaderType: HeaderType1, PacketType: PacketTypeData, TransportType: 0, Context: ContextNone, ContextFlag: FlagUnset, Hops: 0, DestinationType: 0x00, DestinationHash: destHash, Data: data, CreateReceipt: true, } if err := pkt.Pack(); err != nil { t.Fatalf("Failed to pack packet: %v", err) } receipt := NewPacketReceipt(pkt) receipt.SetDestinationIdentity(testIdent) deliveryCalled := make(chan bool, 1) receipt.SetDeliveryCallback(func(r *PacketReceipt) { deliveryCalled <- true }) packetHash := pkt.GetHash() signature := testIdent.Sign(packetHash) proof := make([]byte, 0, EXPL_LENGTH) proof = append(proof, packetHash...) proof = append(proof, signature...) proofPacket := &Packet{ PacketType: PacketTypeProof, Data: proof, } receipt.ValidateProof(proof, proofPacket) select { case <-deliveryCalled: // Success case <-time.After(100 * time.Millisecond): t.Error("Delivery callback was not called") } }